flowtracker.c (120792B)
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 * Flowtracker - Flow Tracking embedded APP interface 8 * Purpose: APIs to configure flowtracker embedded app interface. 9 */ 10 11 #if defined(INCLUDE_FLOWTRACKER) 12 13 #include <shared/bsl.h> 14 #include <soc/defs.h> 15 #include <soc/drv.h> 16 #include <soc/uc.h> 17 #include <shared/alloc.h> 18 #include <soc/shared/ft.h> 19 #include <soc/shared/ft_msg.h> 20 #include <soc/shared/ft_pack.h> 21 #include <soc/shared/shr_pkt.h> 22 23 24 #include <bcm/types.h> 25 #include <bcm/error.h> 26 27 #include <bcm_int/esw/flowtracker.h> 28 #include <bcm_int/esw/xgs5.h> 29 #include <bcm_int/common/rx.h> 30 #include <bcm_int/esw_dispatch.h> 31 #include <bcm_int/esw/collector.h> 32 33 34 /* List of flowtracker export templates info */ 35 _bcm_int_ft_export_template_info_t *ft_export_template_info_list[BCM_MAX_NUM_UNITS] = {0}; 36 /* List of flowtracker collector info*/ 37 _bcm_int_ft_collector_info_t *ft_collector_info_list[BCM_MAX_NUM_UNITS] = {0}; 38 _bcm_int_ft_v2_collector_info_t *ft_v2_collector_info_list[BCM_MAX_NUM_UNITS] = {0}; 39 _bcm_int_ft_v2_export_profile_info_t *ft_v2_export_profile_info_list[BCM_MAX_NUM_UNITS] = {0}; 40 41 /* List of flowtracker flow_group info*/ 42 _bcm_int_ft_flow_group_info_t *ft_flow_group_info_list[BCM_MAX_NUM_UNITS] = {0}; 43 44 /* List of flowtracker elph_profile info*/ 45 _bcm_int_ft_elph_profile_info_t *ft_elph_profile_info_list[BCM_MAX_NUM_UNITS] = {0}; 46 47 48 /****************************************************** 49 * * 50 * UTILITY FUNCTIONS * 51 */ 52 53 /* 54 * Functions: 55 * _bcm_xgs5_ft_<header>_get 56 * Purpose: 57 * The following set of _get() functions builds a given header for 58 * a given collector. 59 * Parameters: 60 * collector_info - (IN) Pointer to Collector information structure. 61 * <... other IN args ...> 62 * <header> - (OUT) Returns header. 63 * Returns: 64 * BCM_E_XXX 65 * Notes: 66 */ 67 STATIC int 68 _bcm_xgs5_ft_udp_header_get( 69 bcm_flowtracker_collector_info_t *collector_info, 70 shr_udp_header_t *udp) 71 { 72 /* Set UDP */ 73 sal_memset(udp, 0, sizeof(*udp)); 74 udp->src = collector_info->udp.src_port; 75 udp->dst = collector_info->udp.dst_port; 76 /* Do not set UDP length since this will be filled by 77 * EAPP. 78 */ 79 udp->length = 0; 80 udp->sum = 0; /* Calculated later */ 81 82 return BCM_E_NONE; 83 } 84 85 STATIC int 86 _bcm_xgs5_ft_v2_udp_header_get( 87 bcm_collector_info_t *collector_info, 88 shr_udp_header_t *udp) 89 { 90 /* Set UDP */ 91 sal_memset(udp, 0, sizeof(*udp)); 92 udp->src = collector_info->udp.src_port; 93 udp->dst = collector_info->udp.dst_port; 94 /* Do not set UDP length since this will be filled by 95 * EAPP. 96 */ 97 udp->length = 0; 98 udp->sum = 0; /* Calculated later */ 99 100 return BCM_E_NONE; 101 } 102 103 STATIC int 104 _bcm_xgs5_ft_ipv4_header_get(uint8 protocol, 105 uint8 tos, uint8 ttl, 106 bcm_ip_t src_ip_addr, bcm_ip_t dst_ip_addr, 107 shr_ipv4_header_t *ip) 108 { 109 uint8 buffer[SHR_IPV4_HEADER_LENGTH]; 110 111 sal_memset(ip, 0, sizeof(*ip)); 112 113 ip->version = SHR_IPV4_VERSION; 114 ip->h_length = SHR_IPV4_HEADER_LENGTH_WORDS; 115 ip->dscp = tos; 116 ip->ecn = 0; 117 /* Dont fill in length since length will be calculated by 118 * EAPP. 119 */ 120 ip->length = 0; 121 ip->id = 0; 122 ip->flags = 0; 123 ip->f_offset = 0; 124 ip->ttl = ttl; 125 ip->protocol = protocol; 126 ip->sum = 0; 127 ip->src = src_ip_addr; 128 ip->dst = dst_ip_addr; 129 130 /* Calculate IP header checksum */ 131 shr_ipv4_header_pack(buffer, ip); 132 ip->sum = 0; 133 134 return BCM_E_NONE; 135 } 136 137 138 STATIC int 139 _bcm_xgs5_ft_ip_headers_get(bcm_flowtracker_collector_info_t *collector_info, 140 uint16 *etype, 141 shr_ipv4_header_t *ipv4) 142 { 143 int ip_protocol; 144 145 ip_protocol = SHR_IP_PROTOCOL_UDP; 146 147 148 *etype = SHR_L2_ETYPE_IPV4; 149 150 BCM_IF_ERROR_RETURN 151 (_bcm_xgs5_ft_ipv4_header_get( ip_protocol, 152 collector_info->ipv4.dscp, 153 collector_info->ipv4.ttl, 154 collector_info->ipv4.src_ip, 155 collector_info->ipv4.dst_ip, 156 ipv4)); 157 158 return BCM_E_NONE; 159 } 160 161 STATIC int 162 _bcm_xgs5_ft_v2_ip_headers_get(bcm_collector_info_t *collector_info, 163 uint16 *etype, 164 shr_ipv4_header_t *ipv4) 165 { 166 int ip_protocol; 167 168 ip_protocol = SHR_IP_PROTOCOL_UDP; 169 170 171 *etype = SHR_L2_ETYPE_IPV4; 172 173 BCM_IF_ERROR_RETURN 174 (_bcm_xgs5_ft_ipv4_header_get(ip_protocol, 175 collector_info->ipv4.dscp, 176 collector_info->ipv4.ttl, 177 collector_info->ipv4.src_ip, 178 collector_info->ipv4.dst_ip, 179 ipv4)); 180 181 return BCM_E_NONE; 182 } 183 184 STATIC int 185 _bcm_xgs5_ft_l2_header_get(bcm_flowtracker_collector_info_t *collector_info, 186 uint16 etype, shr_l2_header_t *l2) 187 { 188 sal_memset(l2, 0, sizeof(*l2)); 189 190 /* Destination and Source MAC */ 191 sal_memcpy(l2->dst_mac, collector_info->eth.dst_mac, SHR_MAC_ADDR_LENGTH); 192 sal_memcpy(l2->src_mac, collector_info->eth.src_mac, SHR_MAC_ADDR_LENGTH); 193 194 /* 195 * VLAN Tag(s) 196 */ 197 if (collector_info->eth.vlan_tag_structure == BCM_FLOWTRACKER_COLLECTOR_ETH_HDR_UNTAGGED) { 198 /* Set to 0 to indicate untagged */ 199 l2->outer_vlan_tag.tpid = 0; 200 l2->inner_vlan_tag.tpid = 0; 201 } else { 202 /* Fill outer vlan */ 203 if ((collector_info->eth.vlan_tag_structure == BCM_FLOWTRACKER_COLLECTOR_ETH_HDR_SINGLE_TAGGED) || 204 (collector_info->eth.vlan_tag_structure == BCM_FLOWTRACKER_COLLECTOR_ETH_HDR_DOUBLE_TAGGED)) 205 { 206 l2->outer_vlan_tag.tpid = collector_info->eth.outer_tpid; 207 l2->outer_vlan_tag.tci.prio = BCM_VLAN_CTRL_PRIO(collector_info->eth.outer_vlan_tag); 208 l2->outer_vlan_tag.tci.cfi = BCM_VLAN_CTRL_CFI(collector_info->eth.outer_vlan_tag); 209 l2->outer_vlan_tag.tci.vid = BCM_VLAN_CTRL_ID(collector_info->eth.outer_vlan_tag); 210 } else { 211 return BCM_E_PARAM; 212 } 213 /* Fill inner vlan if double tagged */ 214 if (collector_info->eth.vlan_tag_structure == BCM_FLOWTRACKER_COLLECTOR_ETH_HDR_DOUBLE_TAGGED) { 215 l2->inner_vlan_tag.tpid = collector_info->eth.inner_tpid; 216 l2->inner_vlan_tag.tci.prio = BCM_VLAN_CTRL_PRIO(collector_info->eth.inner_vlan_tag); 217 l2->inner_vlan_tag.tci.cfi = BCM_VLAN_CTRL_CFI(collector_info->eth.inner_vlan_tag); 218 l2->inner_vlan_tag.tci.vid = BCM_VLAN_CTRL_ID(collector_info->eth.inner_vlan_tag); 219 } else { 220 l2->inner_vlan_tag.tpid = 0; /* Set to 0 to indicate not inner tagged */ 221 } 222 } 223 224 /* Ether Type */ 225 l2->etype = etype; 226 227 return BCM_E_NONE; 228 } 229 230 STATIC int 231 _bcm_xgs5_ft_v2_l2_header_get(bcm_collector_info_t *collector_info, 232 uint16 etype, shr_l2_header_t *l2) 233 { 234 sal_memset(l2, 0, sizeof(*l2)); 235 236 /* Destination and Source MAC */ 237 sal_memcpy(l2->dst_mac, collector_info->eth.dst_mac, SHR_MAC_ADDR_LENGTH); 238 sal_memcpy(l2->src_mac, collector_info->eth.src_mac, SHR_MAC_ADDR_LENGTH); 239 240 /* 241 * VLAN Tag(s) 242 */ 243 if (collector_info->eth.vlan_tag_structure == BCM_COLLECTOR_ETH_HDR_UNTAGGED) { 244 /* Set to 0 to indicate untagged */ 245 l2->outer_vlan_tag.tpid = 0; 246 l2->inner_vlan_tag.tpid = 0; 247 } else { 248 /* Fill outer vlan */ 249 if ((collector_info->eth.vlan_tag_structure == BCM_COLLECTOR_ETH_HDR_SINGLE_TAGGED) || 250 (collector_info->eth.vlan_tag_structure == BCM_COLLECTOR_ETH_HDR_DOUBLE_TAGGED)) 251 { 252 l2->outer_vlan_tag.tpid = collector_info->eth.outer_tpid; 253 l2->outer_vlan_tag.tci.prio = BCM_VLAN_CTRL_PRIO(collector_info->eth.outer_vlan_tag); 254 l2->outer_vlan_tag.tci.cfi = BCM_VLAN_CTRL_CFI(collector_info->eth.outer_vlan_tag); 255 l2->outer_vlan_tag.tci.vid = BCM_VLAN_CTRL_ID(collector_info->eth.outer_vlan_tag); 256 } else { 257 return BCM_E_PARAM; 258 } 259 /* Fill inner vlan if double tagged */ 260 if (collector_info->eth.vlan_tag_structure == BCM_COLLECTOR_ETH_HDR_DOUBLE_TAGGED) { 261 l2->inner_vlan_tag.tpid = collector_info->eth.inner_tpid; 262 l2->inner_vlan_tag.tci.prio = BCM_VLAN_CTRL_PRIO(collector_info->eth.inner_vlan_tag); 263 l2->inner_vlan_tag.tci.cfi = BCM_VLAN_CTRL_CFI(collector_info->eth.inner_vlan_tag); 264 l2->inner_vlan_tag.tci.vid = BCM_VLAN_CTRL_ID(collector_info->eth.inner_vlan_tag); 265 } else { 266 l2->inner_vlan_tag.tpid = 0; /* Set to 0 to indicate not inner tagged */ 267 } 268 } 269 270 /* Ether Type */ 271 l2->etype = etype; 272 273 return BCM_E_NONE; 274 } 275 276 /* 277 * Function: 278 * _bcm_xgs5_ft_eapp_collector_encap_build_pack 279 * Purpose: 280 * Builds and packs the Flowtracker export packet 281 * encapsulation for a given collector 282 * Parameters: 283 * unit - (IN) BCM device number 284 * collector_id - (IN) Collector Id 285 * collector_create_msg - (OUT) Message which contains the encapsulation. 286 * Returns: 287 * BCM_E_XXX 288 * Notes: 289 * The returning encapsulation includes only all the 290 * encapsulation headers and does not include 291 * the IPFIX control packet. 292 */ 293 STATIC int 294 _bcm_xgs5_ft_eapp_collector_encap_build_pack( 295 int unit, 296 int collector_id, 297 shr_ft_msg_ctrl_collector_create_t *collector_create_msg) 298 { 299 uint8 *buffer = collector_create_msg->encap; 300 uint8 *cur_ptr; 301 uint16 etype = 0; 302 shr_udp_header_t udp; 303 shr_ipv4_header_t ipv4; 304 shr_l2_header_t l2; 305 uint16 ip_offset = 0; 306 uint16 udp_offset = 0; 307 _bcm_int_ft_collector_info_t collector_int_info; 308 int rv; 309 310 311 sal_memset(&collector_int_info, 0, sizeof(collector_int_info)); 312 /* Get the collector info for this collector id */ 313 rv = _bcm_xgs5_ft_collector_list_collector_get(unit, collector_id, &collector_int_info); 314 315 /* Return BCM_E_NOT_FOUND if not found */ 316 if (BCM_FAILURE(rv)) { 317 return rv; 318 } 319 sal_memset(collector_create_msg, 0, sizeof(shr_ft_msg_ctrl_collector_create_t)); 320 collector_create_msg->id = collector_id; 321 collector_create_msg->mtu = collector_int_info.collector_info.max_packet_length; 322 323 sal_memset(&udp, 0, sizeof(udp)); 324 sal_memset(&ipv4, 0, sizeof(ipv4)); 325 sal_memset(&l2, 0, sizeof(l2)); 326 327 328 /* 329 * Get necessary headers/labels information. 330 * 331 * Following order is important since some headers/labels 332 * may depend on previous header/label information. 333 */ 334 if (collector_int_info.collector_info.transport_type == 335 bcmFlowtrackerCollectorTransportTypeIpfixIpv4Udp) { 336 BCM_IF_ERROR_RETURN 337 (_bcm_xgs5_ft_udp_header_get(&(collector_int_info.collector_info), &udp)); 338 } 339 340 if (collector_int_info.collector_info.transport_type == 341 bcmFlowtrackerCollectorTransportTypeIpfixIpv4Udp) { 342 BCM_IF_ERROR_RETURN 343 (_bcm_xgs5_ft_ip_headers_get(&(collector_int_info.collector_info), 344 &etype, 345 &ipv4)); 346 } 347 348 /* Always build L2 Header */ 349 BCM_IF_ERROR_RETURN 350 (_bcm_xgs5_ft_l2_header_get(&(collector_int_info.collector_info), 351 etype, &l2)); 352 353 /* 354 * Pack header/labels into given buffer (network packet format). 355 * 356 * Following packing order must be followed to correctly 357 * build the packet encapsulation. 358 */ 359 cur_ptr = buffer; 360 361 /* L2 Header is always present */ 362 cur_ptr = shr_l2_header_pack(cur_ptr, &l2); 363 364 if (collector_int_info.collector_info.transport_type == 365 bcmFlowtrackerCollectorTransportTypeIpfixIpv4Udp) { 366 /* 367 * IP offset 368 */ 369 ip_offset = cur_ptr - buffer; 370 371 cur_ptr = shr_ipv4_header_pack(cur_ptr, &ipv4); 372 } 373 374 if (collector_int_info.collector_info.transport_type == 375 bcmFlowtrackerCollectorTransportTypeIpfixIpv4Udp) { 376 /* 377 * UDP offset 378 */ 379 udp_offset = cur_ptr - buffer; 380 cur_ptr = shr_udp_header_pack(cur_ptr, &udp); 381 } 382 383 384 /* Set Flowtracker export pkt encapsulation length */ 385 collector_create_msg->encap_length = cur_ptr - buffer; 386 387 /* Set Flowtracker export pkt IP base offset */ 388 collector_create_msg->ip_offset = ip_offset; 389 390 /* Set Flowtracker export pkt IP Base checksum */ 391 collector_create_msg->ip_base_checksum = 392 shr_initial_chksum_get(SHR_IPV4_HEADER_LENGTH, buffer + ip_offset); 393 394 /* Set Flowtracker export pkt UDP Base checksum */ 395 if (collector_int_info.collector_info.transport_type == 396 bcmFlowtrackerCollectorTransportTypeIpfixIpv4Udp) { 397 collector_create_msg->udp_base_checksum = 398 shr_udp_initial_checksum_get(0, &ipv4, NULL, NULL, &udp); 399 } 400 /* Set Flowtracker export pkt UDP base offset */ 401 collector_create_msg->udp_offset = udp_offset; 402 403 404 return BCM_E_NONE; 405 } 406 407 /* 408 * Function: 409 * _bcm_xgs5_ft_v2_eapp_collector_encap_build_pack 410 * Purpose: 411 * Builds and packs the Flowtracker export packet 412 * encapsulation for a given collector 413 * Parameters: 414 * unit - (IN) BCM device number 415 * collector_id - (IN) Collector Id 416 * collector_create_msg - (OUT) Message which contains the encapsulation. 417 * Returns: 418 * BCM_E_XXX 419 * Notes: 420 * The returning encapsulation includes only all the 421 * encapsulation headers and does not include 422 * the IPFIX control packet. 423 */ 424 STATIC int 425 _bcm_xgs5_ft_v2_eapp_collector_encap_build_pack( 426 int unit, 427 bcm_collector_t collector_id, 428 int export_profile_id, 429 shr_ft_msg_ctrl_collector_create_t *collector_create_msg) 430 { 431 uint8 *buffer = collector_create_msg->encap; 432 uint8 *cur_ptr; 433 uint16 etype = 0; 434 shr_udp_header_t udp; 435 shr_ipv4_header_t ipv4; 436 shr_l2_header_t l2; 437 uint16 ip_offset = 0; 438 uint16 udp_offset = 0; 439 bcm_collector_info_t collector_info; 440 bcm_collector_export_profile_t export_profile_info; 441 int coll_int_id; 442 int rv; 443 444 /* Get the collector internal info for this collector id */ 445 rv = _bcm_xgs5_ft_v2_collector_list_collector_get(unit, collector_id, 446 &coll_int_id); 447 448 /* Return BCM_E_NOT_FOUND if not found */ 449 if (BCM_FAILURE(rv)) { 450 return rv; 451 } 452 453 /* Get the collector info */ 454 bcm_collector_info_t_init(&collector_info); 455 rv = bcm_esw_collector_get(unit, collector_id, &collector_info); 456 BCM_IF_ERROR_RETURN(rv); 457 458 459 /* Get the export profile info */ 460 bcm_collector_export_profile_t_init(&export_profile_info); 461 rv = bcm_esw_collector_export_profile_get(unit, 462 export_profile_id, 463 &export_profile_info); 464 BCM_IF_ERROR_RETURN(rv); 465 466 sal_memset(collector_create_msg, 0, sizeof(shr_ft_msg_ctrl_collector_create_t)); 467 collector_create_msg->id = coll_int_id; 468 collector_create_msg->mtu = export_profile_info.max_packet_length; 469 470 sal_memset(&udp, 0, sizeof(udp)); 471 sal_memset(&ipv4, 0, sizeof(ipv4)); 472 sal_memset(&l2, 0, sizeof(l2)); 473 474 475 /* 476 * Get necessary headers/labels information. 477 * 478 * Following order is important since some headers/labels 479 * may depend on previous header/label information. 480 */ 481 if (collector_info.transport_type == bcmCollectorTransportTypeIpv4Udp) { 482 BCM_IF_ERROR_RETURN 483 (_bcm_xgs5_ft_v2_udp_header_get(&collector_info, &udp)); 484 } 485 486 if (collector_info.transport_type == bcmCollectorTransportTypeIpv4Udp) { 487 BCM_IF_ERROR_RETURN 488 (_bcm_xgs5_ft_v2_ip_headers_get(&collector_info, 489 &etype, 490 &ipv4)); 491 } 492 493 /* Always build L2 Header */ 494 BCM_IF_ERROR_RETURN 495 (_bcm_xgs5_ft_v2_l2_header_get(&collector_info, etype, &l2)); 496 497 /* 498 * Pack header/labels into given buffer (network packet format). 499 * 500 * Following packing order must be followed to correctly 501 * build the packet encapsulation. 502 */ 503 cur_ptr = buffer; 504 505 /* L2 Header is always present */ 506 cur_ptr = shr_l2_header_pack(cur_ptr, &l2); 507 508 if (collector_info.transport_type == bcmCollectorTransportTypeIpv4Udp) { 509 /* 510 * IP offset 511 */ 512 ip_offset = cur_ptr - buffer; 513 514 cur_ptr = shr_ipv4_header_pack(cur_ptr, &ipv4); 515 } 516 517 if (collector_info.transport_type == bcmCollectorTransportTypeIpv4Udp) { 518 /* 519 * UDP offset 520 */ 521 udp_offset = cur_ptr - buffer; 522 cur_ptr = shr_udp_header_pack(cur_ptr, &udp); 523 } 524 525 526 /* Set Flowtracker export pkt encapsulation length */ 527 collector_create_msg->encap_length = cur_ptr - buffer; 528 529 /* Set Flowtracker export pkt IP base offset */ 530 collector_create_msg->ip_offset = ip_offset; 531 532 /* Set Flowtracker export pkt IP Base checksum */ 533 collector_create_msg->ip_base_checksum = 534 shr_initial_chksum_get(SHR_IPV4_HEADER_LENGTH, buffer + ip_offset); 535 536 /* Set Flowtracker export pkt UDP Base checksum */ 537 if (collector_info.transport_type == bcmCollectorTransportTypeIpv4Udp) { 538 collector_create_msg->udp_base_checksum = 539 shr_udp_initial_checksum_get(0, &ipv4, NULL, NULL, &udp); 540 } 541 /* Set Flowtracker export pkt UDP base offset */ 542 collector_create_msg->udp_offset = udp_offset; 543 544 if (export_profile_info.wire_format == bcmCollectorWireFormatProtoBuf) { 545 /* Set Flowtracker export pkt Component ID */ 546 collector_create_msg->component_id = collector_info.protobuf.component_id; 547 548 /* Set Flowtracker export pkt System ID length */ 549 collector_create_msg->system_id_length = collector_info.protobuf.system_id_length; 550 551 /* Set Flowtracker export pkt System ID */ 552 memcpy(&collector_create_msg->system_id, &collector_info.protobuf.system_id, 553 collector_info.protobuf.system_id_length); 554 } 555 556 return BCM_E_NONE; 557 } 558 559 /* 560 * Function: 561 * _bcm_xgs5_ft_eapp_template_encap_build_pack 562 * Purpose: 563 * Build the template set encap 564 * Parameters: 565 * template_int_info - (IN) Template Information 566 * encap_length - (OUT) Encap length 567 * encap - (OUT) Encap 568 * Returns: 569 * None 570 */ 571 STATIC void 572 _bcm_xgs5_ft_eapp_template_encap_build_pack( 573 int unit, 574 _bcm_int_ft_export_template_info_t *template_int_info, 575 uint16 *encap_length, uint8 *buf) 576 { 577 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 578 uint8 *cur_ptr = buf; 579 uint16 element_id; 580 int i; 581 582 /* 583 * +----------------------+------------------+ 584 * | Bits 0...15 | Bits 16...31 | 585 * +----------------------+------------------+ 586 * | Set ID = 2(Template) | Set Length | 587 * +----------------------+------------------+ 588 * | Template ID | Number of fields | 589 * +----------------------+------------------+ 590 * | Type | Field Length | 591 * +----------------------+------------------+ 592 * | Type | Field Length | 593 * +----------------------+------------------+ 594 * | Type | Field Length | 595 * +----------------------+------------------+ 596 */ 597 598 SHR_PKT_PACK_U16(cur_ptr, FT_INT_TEMPLATE_XMIT_SET_ID); 599 600 /* Skip over length */ 601 cur_ptr += 2; 602 603 SHR_PKT_PACK_U16(cur_ptr, template_int_info->set_id); 604 SHR_PKT_PACK_U16(cur_ptr, template_int_info->num_export_elements); 605 606 for (i = 0; i < template_int_info->num_export_elements; i++) { 607 if (template_int_info->elements[i].enterprise == 0) { 608 /* Non enterprise element, format below */ 609 /* 610 * +-+--------------------+------------------+ 611 * |0| 1...15 | 16...31 | 612 * +-+--------------------+------------------+ 613 * |0| Type | Field Length | 614 * +----------------------+------------------+ 615 */ 616 SHR_PKT_PACK_U16(cur_ptr, template_int_info->elements[i].id); 617 SHR_PKT_PACK_U16(cur_ptr, template_int_info->elements[i].data_size); 618 } else { 619 /* Enterprise specific */ 620 /* 621 * +-+--------------------+------------------+ 622 * |0| 1...15 | 16...31 | 623 * +-+--------------------+------------------+ 624 * |1| Type | Field Length | 625 * +----------------------+------------------+ 626 * | Enterprise number | 627 * +----------------------+------------------+ 628 */ 629 /* Set the enterprise bit */ 630 element_id = (1 << 15) | template_int_info->elements[i].id; 631 SHR_PKT_PACK_U16(cur_ptr, element_id); 632 SHR_PKT_PACK_U16(cur_ptr, template_int_info->elements[i].data_size); 633 SHR_PKT_PACK_U32(cur_ptr, ft_info->enterprise_number); 634 } 635 } 636 637 *encap_length = cur_ptr - buf; 638 } 639 /****************************************************** 640 * * 641 * EXPORT TEMPLATE LIST MANAGEMENT FUNCTIONS * 642 */ 643 644 /* 645 * Function: 646 * _bcm_xgs5_ft_template_list_template_add 647 * Purpose: 648 * Add a template to the template list. 649 * Parameters: 650 * unit - (IN) BCM device number 651 * template_id - (IN) The template ID 652 * template_int_info - (IN) Template info to be added 653 * Returns: 654 * BCM_E_XXX 655 */ 656 int 657 _bcm_xgs5_ft_template_list_template_add(int unit, 658 bcm_flowtracker_export_template_t template_id, 659 _bcm_int_ft_export_template_info_t *template_int_info) 660 { 661 _bcm_int_ft_export_template_info_t *template_info_list_node = 662 &(ft_export_template_info_list[unit][template_id]); 663 664 if (template_info_list_node->template_id != 0) { 665 /* Not free */ 666 return BCM_E_EXISTS; 667 } 668 669 template_int_info->template_id = template_id; 670 memcpy(template_info_list_node, template_int_info, 671 sizeof(_bcm_int_ft_export_template_info_t)); 672 673 674 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 675 (BSL_META_U(unit, 676 "FT(unit %d) Info: %s" 677 " (Template=0x%x).\n"), unit, __FUNCTION__, 678 template_id)); 679 return (BCM_E_NONE); 680 } 681 682 /* 683 * Function: 684 * _bcm_xgs5_ft_template_list_template_delete 685 * Purpose: 686 * Delete a template from the template list. 687 * Parameters: 688 * unit - (IN) BCM device number 689 * template_id - (IN) The template ID 690 * Returns: 691 * BCM_E_XXX 692 */ 693 int 694 _bcm_xgs5_ft_template_list_template_delete (int unit, 695 bcm_flowtracker_export_template_t template_id) 696 { 697 _bcm_int_ft_export_template_info_t *template_info_list_node = 698 &(ft_export_template_info_list[unit][template_id]); 699 700 if (template_info_list_node->template_id != template_id) { 701 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 702 (BSL_META_U(unit, 703 "FT(unit %d) Info: Template is not present"), unit)); 704 return (BCM_E_NOT_FOUND); 705 } 706 707 sal_memset(template_info_list_node, 0, 708 sizeof(_bcm_int_ft_export_template_info_t)); 709 710 return (BCM_E_NONE); 711 } 712 713 /* 714 * Function: 715 * _bcm_xgs5_ft_template_list_template_modify 716 * Purpose: 717 * Modfiy a template in the template list. 718 * Parameters: 719 * unit - (IN) BCM device number 720 * template_id - (IN) Template Id 721 * template_info - (IN) Template informatin. 722 * Returns: 723 * BCM_E_XXX 724 */ 725 int 726 _bcm_xgs5_ft_template_list_template_modify( 727 int unit, 728 bcm_flowtracker_export_template_t template_id, 729 _bcm_int_ft_export_template_info_t *template_info) 730 { 731 _bcm_int_ft_export_template_info_t *list_node = 732 &(ft_export_template_info_list[unit][template_id]); 733 734 if (list_node->template_id != template_id) { 735 /* Not found */ 736 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 737 (BSL_META_U(unit, 738 "FT(unit %d) Info: Template ID does not exist"), unit)); 739 return (BCM_E_NOT_FOUND); 740 } 741 742 sal_memcpy(list_node, template_info, 743 sizeof(_bcm_int_ft_export_template_info_t)); 744 745 return BCM_E_NONE; 746 } 747 748 /* 749 * Function: 750 * _bcm_xgs5_ft_template_list_template_get 751 * Purpose: 752 * Get a template from the template list. 753 * Parameters: 754 * unit - (IN) BCM device number 755 * template_id - (IN) The template ID 756 * template_info - (OUT) template information 757 * Returns: 758 * BCM_E_XXX 759 */ 760 int 761 _bcm_xgs5_ft_template_list_template_get (int unit, 762 bcm_flowtracker_export_template_t template_id, 763 _bcm_int_ft_export_template_info_t *template_info) 764 { 765 _bcm_int_ft_export_template_info_t *list_node = 766 &(ft_export_template_info_list[unit][template_id]); 767 768 if (list_node->template_id == template_id) { 769 sal_memcpy(template_info, list_node, sizeof(_bcm_int_ft_export_template_info_t)); 770 } else { 771 return (BCM_E_NOT_FOUND); 772 } 773 774 return BCM_E_NONE; 775 } 776 777 /* 778 * Function: 779 * _bcm_xgs5_ft_template_list_destroy 780 * Purpose: 781 * Destroy the template list. 782 * Parameters: 783 * unit - (IN) BCM device number 784 * Returns: 785 * BCM_E_XXX 786 */ 787 int 788 _bcm_xgs5_ft_template_list_destroy (int unit) 789 { 790 if (ft_export_template_info_list[unit] != NULL) { 791 sal_free(ft_export_template_info_list[unit]); 792 } 793 ft_export_template_info_list[unit] = NULL; 794 return BCM_E_NONE; 795 } 796 797 /* 798 * Function: 799 * _bcm_xgs5_ft_template_list_create 800 * Purpose: 801 * Create the template list. 802 * Parameters: 803 * unit - (IN) BCM device number 804 * Returns: 805 * BCM_E_XXX 806 */ 807 int 808 _bcm_xgs5_ft_template_list_create (int unit) 809 { 810 if (ft_export_template_info_list[unit] == NULL) { 811 /* Allocate template list */ 812 _BCM_FT_ALLOC(ft_export_template_info_list[unit], _bcm_int_ft_export_template_info_t, 813 sizeof(_bcm_int_ft_export_template_info_t) * 814 (BCM_INT_FT_MAX_TEMPLATES + BCM_INT_FT_TEMPLATE_START_ID), 815 "template list"); 816 } 817 818 if (ft_export_template_info_list[unit] == NULL) { 819 return BCM_E_MEMORY; 820 } 821 return BCM_E_NONE; 822 } 823 824 /****************************************************** 825 * * 826 * COLLECTOR LIST MANAGEMENT FUNCTIONS * 827 */ 828 829 /* 830 * Function: 831 * _bcm_xgs5_ft_collector_list_collector_add 832 * Purpose: 833 * Add a collector to the collector list. 834 * Parameters: 835 * unit - (IN) BCM device number 836 * collector_id - (IN) The collector ID 837 * collector_info - (IN) Collector informatin. 838 * Returns: 839 * BCM_E_XXX 840 */ 841 int 842 _bcm_xgs5_ft_collector_list_collector_add(int unit, 843 bcm_flowtracker_collector_t collector_id, 844 bcm_flowtracker_collector_info_t *collector_info) 845 { 846 _bcm_int_ft_collector_info_t *collector_info_list_node = 847 &(ft_collector_info_list[unit][collector_id]); 848 849 if (collector_info_list_node->collector_id != 0) { 850 return BCM_E_EXISTS; 851 } 852 collector_info_list_node->collector_id = collector_id; 853 854 sal_memcpy(&(collector_info_list_node->collector_info), collector_info, 855 sizeof(bcm_flowtracker_collector_info_t)); 856 857 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 858 (BSL_META_U(unit, 859 "FT(unit %d) Info: %s" 860 " (Collector=0x%x).\n"), unit, __FUNCTION__, 861 collector_id)); 862 return (BCM_E_NONE); 863 } 864 865 /* 866 * Function: 867 * _bcm_xgs5_ft_collector_list_collector_delete 868 * Purpose: 869 * Delete a collector from the collector list. 870 * Parameters: 871 * unit - (IN) BCM device number 872 * collector_id - (IN) The collector ID 873 * Returns: 874 * BCM_E_XXX 875 */ 876 int 877 _bcm_xgs5_ft_collector_list_collector_delete (int unit, 878 bcm_flowtracker_collector_t collector_id) 879 { 880 _bcm_int_ft_collector_info_t *collector_info_list_node = 881 &(ft_collector_info_list[unit][collector_id]); 882 883 if (collector_info_list_node->collector_id != collector_id) { 884 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 885 (BSL_META_U(unit, 886 "FT(unit %d) Info: collector ID does not exist"), unit)); 887 return (BCM_E_NOT_FOUND); 888 } 889 890 sal_memset(collector_info_list_node, 0, 891 sizeof(_bcm_int_ft_collector_info_t)); 892 893 return (BCM_E_NONE); 894 } 895 896 /* 897 * Function: 898 * _bcm_xgs5_ft_collector_list_collector_modify 899 * Purpose: 900 * Modfiy a collector in the collector list. 901 * Parameters: 902 * unit - (IN) BCM device number 903 * collector_id - (IN) The collector ID 904 * collector_info - (IN) Collector informatin. 905 * Returns: 906 * BCM_E_XXX 907 */ 908 int 909 _bcm_xgs5_ft_collector_list_collector_modify(int unit, 910 bcm_flowtracker_collector_t collector_id, 911 bcm_flowtracker_collector_info_t *collector_info) 912 { 913 _bcm_int_ft_collector_info_t *list_node = 914 &(ft_collector_info_list[unit][collector_id]); 915 916 if (list_node->collector_id != collector_id) { 917 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 918 (BSL_META_U(unit, 919 "FT(unit %d) Info: collector ID does not exist"), unit)); 920 return (BCM_E_NOT_FOUND); 921 } 922 923 sal_memcpy(&(list_node->collector_info), collector_info, 924 sizeof(bcm_flowtracker_collector_info_t)); 925 926 return BCM_E_NONE; 927 } 928 929 /* 930 * Function: 931 * _bcm_xgs5_ft_collector_list_collector_get 932 * Purpose: 933 * Get a collector from the collector list. 934 * Parameters: 935 * unit - (IN) BCM device number 936 * collector_id - (IN) The collector ID 937 * collector_info - (OUT) collector information 938 * Returns: 939 * BCM_E_XXX 940 */ 941 int 942 _bcm_xgs5_ft_collector_list_collector_get (int unit, 943 bcm_flowtracker_collector_t collector_id, 944 _bcm_int_ft_collector_info_t *collector_info) 945 { 946 _bcm_int_ft_collector_info_t *list_node = 947 &(ft_collector_info_list[unit][collector_id]); 948 949 if (list_node->collector_id != collector_id) { 950 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 951 (BSL_META_U(unit, 952 "FT(unit %d) Info: collector ID does not exist"), unit)); 953 return (BCM_E_NOT_FOUND); 954 } 955 956 sal_memcpy(collector_info, list_node, 957 sizeof(_bcm_int_ft_collector_info_t)); 958 959 960 return BCM_E_NONE; 961 } 962 963 /* 964 * Function: 965 * _bcm_xgs5_ft_collector_list_destroy 966 * Purpose: 967 * Destroy the collector list. 968 * Parameters: 969 * unit - (IN) BCM device number 970 * Returns: 971 * BCM_E_XXX 972 */ 973 int 974 _bcm_xgs5_ft_collector_list_destroy (int unit) 975 { 976 if (ft_collector_info_list[unit] != NULL) { 977 sal_free(ft_collector_info_list[unit]); 978 } 979 980 ft_collector_info_list[unit] = NULL; 981 return BCM_E_NONE; 982 } 983 984 /* 985 * Function: 986 * _bcm_xgs5_ft_collector_list_create 987 * Purpose: 988 * Create the collector list. 989 * Parameters: 990 * unit - (IN) BCM device number 991 * Returns: 992 * BCM_E_XXX 993 */ 994 int 995 _bcm_xgs5_ft_collector_list_create (int unit) 996 { 997 if (ft_collector_info_list[unit] == NULL) { 998 _BCM_FT_ALLOC(ft_collector_info_list[unit], _bcm_int_ft_collector_info_t, 999 sizeof(_bcm_int_ft_collector_info_t) * 1000 (BCM_INT_FT_MAX_COLLECTORS + BCM_INT_FT_COLLECTOR_START_ID), 1001 "collector list"); 1002 1003 } 1004 1005 if (ft_collector_info_list[unit] == NULL) { 1006 return BCM_E_MEMORY; 1007 } 1008 return BCM_E_NONE; 1009 } 1010 1011 /******************************************************* 1012 * * 1013 * FTv2 COLLECTOR LIST MANAGEMENT FUNCTIONS * 1014 */ 1015 1016 /* 1017 * Function: 1018 * _bcm_xgs5_ft_v2_collector_list_collector_add 1019 * Purpose: 1020 * Add a collector to the collector list. 1021 * Parameters: 1022 * unit - (IN) BCM device number 1023 * collector_id - (IN) The collector ID 1024 * coll_int_id - (IN) Collector internal Id 1025 * Returns: 1026 * BCM_E_XXX 1027 */ 1028 int 1029 _bcm_xgs5_ft_v2_collector_list_collector_add(int unit, 1030 bcm_collector_t collector_id, 1031 int coll_int_id) 1032 { 1033 _bcm_int_ft_v2_collector_info_t *collector_info = 1034 &(ft_v2_collector_info_list[unit][collector_id]); 1035 1036 if (collector_id > BCM_INT_COLLECTOR_COLLECTOR_END_ID) { 1037 return BCM_E_PARAM; 1038 } 1039 1040 if (collector_info->int_id != 0) { 1041 return BCM_E_EXISTS; 1042 } 1043 1044 collector_info->int_id = coll_int_id; 1045 1046 return (BCM_E_NONE); 1047 } 1048 1049 /* 1050 * Function: 1051 * _bcm_xgs5_ft_v2_collector_list_collector_delete 1052 * Purpose: 1053 * Delete a collector from the collector list. 1054 * Parameters: 1055 * unit - (IN) BCM device number 1056 * collector_id - (IN) The collector ID 1057 * Returns: 1058 * BCM_E_XXX 1059 */ 1060 int 1061 _bcm_xgs5_ft_v2_collector_list_collector_delete(int unit, 1062 bcm_collector_t collector_id) 1063 { 1064 _bcm_int_ft_v2_collector_info_t *collector_info = 1065 &(ft_v2_collector_info_list[unit][collector_id]); 1066 1067 if (collector_id > BCM_INT_COLLECTOR_COLLECTOR_END_ID) { 1068 return BCM_E_PARAM; 1069 } 1070 1071 if (collector_info->int_id == 0) { 1072 return BCM_E_NOT_FOUND; 1073 } 1074 1075 collector_info->int_id = 0; 1076 1077 return (BCM_E_NONE); 1078 } 1079 1080 1081 /* 1082 * Function: 1083 * _bcm_xgs5_ft_v2_collector_list_collector_get 1084 * Purpose: 1085 * Get a collector from the collector list. 1086 * Parameters: 1087 * unit - (IN) BCM device number 1088 * collector_id - (IN) The collector ID 1089 * collint_id - (OUT) Collector Internal Id 1090 * Returns: 1091 * BCM_E_XXX 1092 */ 1093 int 1094 _bcm_xgs5_ft_v2_collector_list_collector_get(int unit, 1095 bcm_collector_t collector_id, 1096 int *coll_int_id) 1097 { 1098 _bcm_int_ft_v2_collector_info_t *collector_info = 1099 &(ft_v2_collector_info_list[unit][collector_id]); 1100 1101 if (collector_id > BCM_INT_COLLECTOR_COLLECTOR_END_ID) { 1102 return BCM_E_PARAM; 1103 } 1104 1105 if (collector_info->int_id == 0) { 1106 return BCM_E_NOT_FOUND; 1107 } 1108 1109 *coll_int_id = collector_info->int_id; 1110 1111 return BCM_E_NONE; 1112 } 1113 1114 1115 1116 /* 1117 * Function: 1118 * _bcm_xgs5_ft_v2_collector_list_collector_in_use 1119 * Purpose: 1120 * Check if a collector is attached to any flow groups 1121 * Parameters: 1122 * unit - (IN) BCM device number 1123 * collector_id - (IN) The collector ID 1124 * coll_int_id - (OUT) Internal collector ID 1125 * Returns: 1126 * None 1127 */ 1128 void 1129 _bcm_xgs5_ft_v2_collector_list_collector_in_use(int unit, 1130 bcm_collector_t collector_id, 1131 int *in_use) 1132 { 1133 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 1134 _bcm_int_ft_flow_group_info_t *flow_group_info = NULL; 1135 int flow_group_id; 1136 1137 *in_use = 0; 1138 for (flow_group_id = BCM_INT_FT_GROUP_START_ID; 1139 flow_group_id < (BCM_INT_FT_GROUP_START_ID + ft_info->max_flow_groups); 1140 flow_group_id++) { 1141 flow_group_info = &(ft_flow_group_info_list[unit][flow_group_id]); 1142 1143 if (flow_group_info->flow_group_id != flow_group_id) { 1144 continue; 1145 } 1146 1147 if (flow_group_info->collector_id == collector_id) { 1148 *in_use = 1; 1149 return; 1150 } 1151 } 1152 } 1153 1154 /* 1155 * Function: 1156 * _bcm_xgs5_ft_v2_collector_list_destroy 1157 * Purpose: 1158 * Destroy the collector list. 1159 * Parameters: 1160 * unit - (IN) BCM device number 1161 * Returns: 1162 * BCM_E_XXX 1163 */ 1164 int 1165 _bcm_xgs5_ft_v2_collector_list_destroy(int unit) 1166 { 1167 if (ft_v2_collector_info_list[unit] != NULL) { 1168 sal_free(ft_v2_collector_info_list[unit]); 1169 } 1170 1171 ft_v2_collector_info_list[unit] = NULL; 1172 return BCM_E_NONE; 1173 } 1174 1175 /* 1176 * Function: 1177 * _bcm_xgs5_ft_v2_collector_list_create 1178 * Purpose: 1179 * Destroy the collector list. 1180 * Parameters: 1181 * unit - (IN) BCM device number 1182 * Returns: 1183 * BCM_E_XXX 1184 */ 1185 int 1186 _bcm_xgs5_ft_v2_collector_list_create(int unit) 1187 { 1188 if (ft_v2_collector_info_list[unit] == NULL) { 1189 _BCM_FT_ALLOC(ft_v2_collector_info_list[unit], _bcm_int_ft_v2_collector_info_t, 1190 sizeof(_bcm_int_ft_v2_collector_info_t) * 1191 (BCM_INT_COLLECTOR_COLLECTOR_START_ID + BCM_INT_COLLECTOR_MAX_COLLECTORS), 1192 "collector list"); 1193 1194 } 1195 1196 if (ft_v2_collector_info_list[unit] == NULL) { 1197 return BCM_E_MEMORY; 1198 } 1199 return BCM_E_NONE; 1200 } 1201 1202 /* 1203 * Function: 1204 * _bcm_xgs5_ft_v2_collector_list_export_profile_add 1205 * Purpose: 1206 * Add a export profile to the list. 1207 * Parameters: 1208 * unit - (IN) BCM device number 1209 * export_profile_id - (IN) Export profile Id 1210 * export_profile_int_id - (IN) Export profile Internal Id 1211 * Returns: 1212 * BCM_E_XXX 1213 */ 1214 int 1215 _bcm_xgs5_ft_v2_collector_list_export_profile_add(int unit, 1216 int export_profile_id, 1217 int export_profile_int_id) 1218 { 1219 _bcm_int_ft_v2_export_profile_info_t *export_profile_info = 1220 &(ft_v2_export_profile_info_list[unit][export_profile_id]); 1221 1222 if (export_profile_id > BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID) { 1223 return BCM_E_PARAM; 1224 } 1225 1226 if (export_profile_info->int_id != 0) { 1227 return BCM_E_EXISTS; 1228 } 1229 1230 export_profile_info->int_id = export_profile_int_id; 1231 1232 return (BCM_E_NONE); 1233 } 1234 1235 /* 1236 * Function: 1237 * _bcm_xgs5_ft_v2_collector_list_export_profile_delete 1238 * Purpose: 1239 * Delete an export profile from the list 1240 * Parameters: 1241 * unit - (IN) BCM device number 1242 * export_profile_id - (IN) export_profile ID 1243 * Returns: 1244 * BCM_E_XXX 1245 */ 1246 int 1247 _bcm_xgs5_ft_v2_collector_list_export_profile_delete(int unit, 1248 int export_profile_id) 1249 { 1250 _bcm_int_ft_v2_export_profile_info_t *export_profile_info = 1251 &(ft_v2_export_profile_info_list[unit][export_profile_id]); 1252 1253 if (export_profile_id > BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID) { 1254 return BCM_E_PARAM; 1255 } 1256 1257 if (export_profile_info->int_id == 0) { 1258 return BCM_E_NOT_FOUND; 1259 } 1260 1261 export_profile_info->int_id = 0; 1262 1263 return (BCM_E_NONE); 1264 } 1265 1266 1267 /* 1268 * Function: 1269 * _bcm_xgs5_ft_v2_collector_list_export_profile_get 1270 * Purpose: 1271 * Get a collector from the collector list. 1272 * Parameters: 1273 * unit - (IN) BCM device number 1274 * export_profile_id - (IN) export_profile ID 1275 * export_profile_int_id - (IN) export_profile internal ID 1276 * Returns: 1277 * BCM_E_XXX 1278 */ 1279 int 1280 _bcm_xgs5_ft_v2_collector_list_export_profile_get(int unit, 1281 int export_profile_id, 1282 int *export_profile_int_id) 1283 { 1284 _bcm_int_ft_v2_export_profile_info_t *export_profile_info = 1285 &(ft_v2_export_profile_info_list[unit][export_profile_id]); 1286 1287 if (export_profile_id > BCM_INT_COLLECTOR_EXPORT_PROFILE_END_ID) { 1288 return BCM_E_PARAM; 1289 } 1290 1291 if (export_profile_info->int_id == 0) { 1292 return BCM_E_NOT_FOUND; 1293 } 1294 1295 *export_profile_int_id = export_profile_info->int_id; 1296 1297 return BCM_E_NONE; 1298 } 1299 1300 1301 1302 /* 1303 * Function: 1304 * _bcm_xgs5_ft_v2_collector_list_export_profile_in_use 1305 * Purpose: 1306 * Check if a export_profile is attached to any flow groups 1307 * Parameters: 1308 * unit - (IN) BCM device number 1309 * export_profile_id - (IN) export_profile ID 1310 * in_use - (OUT) Indicates if the export profile is in use 1311 * Returns: 1312 * None 1313 */ 1314 void 1315 _bcm_xgs5_ft_v2_collector_list_export_profile_in_use(int unit, 1316 int export_profile_id, 1317 int *in_use) 1318 { 1319 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 1320 _bcm_int_ft_flow_group_info_t *flow_group_info = NULL; 1321 int flow_group_id; 1322 1323 *in_use = 0; 1324 for (flow_group_id = BCM_INT_FT_GROUP_START_ID; 1325 flow_group_id < (BCM_INT_FT_GROUP_START_ID + ft_info->max_flow_groups); 1326 flow_group_id++) { 1327 flow_group_info = &(ft_flow_group_info_list[unit][flow_group_id]); 1328 1329 if (flow_group_info->flow_group_id != flow_group_id) { 1330 continue; 1331 } 1332 1333 if (flow_group_info->export_profile_id == export_profile_id) { 1334 *in_use = 1; 1335 return; 1336 } 1337 } 1338 } 1339 1340 1341 /* 1342 * Function: 1343 * _bcm_xgs5_ft_v2_export_profile_list_destroy 1344 * Purpose: 1345 * Destroy the export_profile list. 1346 * Parameters: 1347 * unit - (IN) BCM device number 1348 * Returns: 1349 * BCM_E_XXX 1350 */ 1351 int 1352 _bcm_xgs5_ft_v2_collector_list_export_profile_destroy(int unit) 1353 { 1354 if (ft_v2_export_profile_info_list[unit] != NULL) { 1355 sal_free(ft_v2_export_profile_info_list[unit]); 1356 } 1357 1358 ft_v2_export_profile_info_list[unit] = NULL; 1359 return BCM_E_NONE; 1360 } 1361 1362 /* 1363 * Function: 1364 * _bcm_xgs5_ft_v2_export_profile_list_create 1365 * Purpose: 1366 * Destroy the export_profile list. 1367 * Parameters: 1368 * unit - (IN) BCM device number 1369 * Returns: 1370 * BCM_E_XXX 1371 */ 1372 int 1373 _bcm_xgs5_ft_v2_collector_list_export_profile_create(int unit) 1374 { 1375 if (ft_v2_export_profile_info_list[unit] == NULL) { 1376 _BCM_FT_ALLOC(ft_v2_export_profile_info_list[unit], _bcm_int_ft_v2_export_profile_info_t, 1377 sizeof(_bcm_int_ft_v2_export_profile_info_t) * 1378 (BCM_INT_COLLECTOR_EXPORT_PROFILE_START_ID + 1379 BCM_INT_COLLECTOR_MAX_EXPORT_PROFILES), 1380 "export_profile list"); 1381 1382 } 1383 1384 if (ft_v2_export_profile_info_list[unit] == NULL) { 1385 return BCM_E_MEMORY; 1386 } 1387 return BCM_E_NONE; 1388 } 1389 1390 /****************************************************** 1391 * * 1392 * FLOW GROUP LIST MANAGEMENT FUNCTIONS * 1393 */ 1394 1395 /* 1396 * Function: 1397 * _bcm_xgs5_ft_flow_group_list_flow_group_add 1398 * Purpose: 1399 * Add a flow_group to the flow_group list. 1400 * Parameters: 1401 * unit - (IN) BCM device number 1402 * flow_group_id - (IN) The flow_group ID 1403 * Returns: 1404 * BCM_E_XXX 1405 */ 1406 int 1407 _bcm_xgs5_ft_flow_group_list_flow_group_add(int unit, 1408 bcm_flowtracker_group_t flow_group_id) 1409 { 1410 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 1411 _bcm_int_ft_flow_group_info_t *flow_group_info_list_node = 1412 &(ft_flow_group_info_list[unit][flow_group_id]); 1413 1414 if (flow_group_info_list_node->flow_group_id != 0) { 1415 /* Not free */ 1416 return BCM_E_EXISTS; 1417 } 1418 1419 flow_group_info_list_node->flow_group_id = flow_group_id; 1420 if (ft_info->cfg_mode >= SHR_FT_CFG_MODE_V2) { 1421 flow_group_info_list_node->collector_id = 1422 BCM_INT_COLLECTOR_INVALID_COLLECTOR_ID; 1423 flow_group_info_list_node->export_profile_id = 1424 BCM_INT_COLLECTOR_INVALID_EXPORT_PROFILE_ID; 1425 } 1426 1427 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 1428 (BSL_META_U(unit, 1429 "FT(unit %d) Info: %s" 1430 " (Flow_group=0x%x).\n"), unit, __FUNCTION__, 1431 flow_group_id)); 1432 return (BCM_E_NONE); 1433 } 1434 1435 /* 1436 * Function: 1437 * _bcm_xgs5_ft_flow_group_list_flow_group_delete 1438 * Purpose: 1439 * Delete a flow_group from the flow_group list. 1440 * Parameters: 1441 * unit - (IN) BCM device number 1442 * flow_group_id - (IN) The flow_group ID 1443 * Returns: 1444 * BCM_E_XXX 1445 */ 1446 int 1447 _bcm_xgs5_ft_flow_group_list_flow_group_delete (int unit, 1448 bcm_flowtracker_group_t flow_group_id) 1449 { 1450 _bcm_int_ft_flow_group_info_t *flow_group_info_list_node = 1451 &(ft_flow_group_info_list[unit][flow_group_id]); 1452 1453 if (flow_group_info_list_node->flow_group_id != flow_group_id) { 1454 /* Not found */ 1455 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 1456 (BSL_META_U(unit, 1457 "FT(unit %d) Info: flow group ID does not exist"), unit)); 1458 return BCM_E_NOT_FOUND; 1459 } 1460 1461 sal_memset(flow_group_info_list_node, 0, 1462 sizeof(_bcm_int_ft_flow_group_info_t)); 1463 1464 return (BCM_E_NONE); 1465 } 1466 1467 /* 1468 * Function: 1469 * _bcm_xgs5_ft_flow_group_list_flow_group_modify 1470 * Purpose: 1471 * Modfiy a flow_group in the flow_group list. 1472 * Parameters: 1473 * unit - (IN) BCM device number 1474 * flow_group_id - (IN) The flow_group ID 1475 * flow_group_info - (IN) flow_group informatin. 1476 * Returns: 1477 * BCM_E_XXX 1478 */ 1479 int 1480 _bcm_xgs5_ft_flow_group_list_flow_group_modify( 1481 int unit, 1482 bcm_flowtracker_group_t flow_group_id, 1483 _bcm_int_ft_flow_group_info_t *flow_group_int_info) 1484 { 1485 _bcm_int_ft_flow_group_info_t *list_node = 1486 &(ft_flow_group_info_list[unit][flow_group_id]); 1487 1488 if (list_node->flow_group_id != flow_group_id) { 1489 /* Not found */ 1490 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 1491 (BSL_META_U(unit, 1492 "FT(unit %d) Info: flow_group ID does not exist"), unit)); 1493 return (BCM_E_NOT_FOUND); 1494 } 1495 1496 sal_memcpy(list_node, flow_group_int_info, 1497 sizeof(_bcm_int_ft_flow_group_info_t)); 1498 1499 1500 return BCM_E_NONE; 1501 } 1502 1503 /* 1504 * Function: 1505 * _bcm_xgs5_ft_flow_group_list_flow_group_get 1506 * Purpose: 1507 * Get a flow_group from the flow_group list. 1508 * Parameters: 1509 * unit - (IN) BCM device number 1510 * flow_group_id - (IN) The flow_group ID 1511 * flow_group_int_info - (OUT) flow_group information 1512 * Returns: 1513 * BCM_E_XXX 1514 */ 1515 int 1516 _bcm_xgs5_ft_flow_group_list_flow_group_get ( 1517 int unit, 1518 bcm_flowtracker_group_t flow_group_id, 1519 _bcm_int_ft_flow_group_info_t *flow_group_int_info) 1520 { 1521 _bcm_int_ft_flow_group_info_t *list_node = 1522 &(ft_flow_group_info_list[unit][flow_group_id]); 1523 1524 if (list_node->flow_group_id != flow_group_id) { 1525 /* Not found */ 1526 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 1527 (BSL_META_U(unit, 1528 "FT(unit %d) Info: flow_group ID does not exist"), unit)); 1529 return (BCM_E_NOT_FOUND); 1530 } 1531 sal_memcpy(flow_group_int_info, list_node, 1532 sizeof(_bcm_int_ft_flow_group_info_t)); 1533 1534 return BCM_E_NONE; 1535 } 1536 1537 /* 1538 * Function: 1539 * _bcm_xgs5_ft_flow_group_list_get_all_ids 1540 * Purpose: 1541 * Get list of flow group ids configured. 1542 * Parameters: 1543 * unit - (IN) BCM device number 1544 * flow_group_id_list - (OUT) The list of flow_group IDs. 1545 * The caller is expected to have allocated it 1546 * for max number of flow groups. 1547 * num_flow_groups - (OUT) The number of flow groups configured. 1548 * Returns: 1549 * BCM_E_XXX 1550 */ 1551 int 1552 _bcm_xgs5_ft_flow_group_list_get_all_ids( 1553 int unit, 1554 bcm_flowtracker_group_t *flow_group_id_list, 1555 int *num_flow_groups) 1556 { 1557 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 1558 _bcm_int_ft_flow_group_info_t *list_node = NULL; 1559 int flow_group_id = 0, cnt = 0; 1560 1561 for (flow_group_id = BCM_INT_FT_GROUP_START_ID; 1562 flow_group_id < (BCM_INT_FT_GROUP_START_ID + ft_info->max_flow_groups); 1563 flow_group_id++) { 1564 list_node = &(ft_flow_group_info_list[unit][flow_group_id]); 1565 /* Non zero flow_group_id indicates configured flow groups.*/ 1566 if (list_node->flow_group_id != 0) { 1567 flow_group_id_list[cnt] = list_node->flow_group_id; 1568 cnt++; 1569 } 1570 } 1571 *num_flow_groups = cnt; 1572 return BCM_E_NONE; 1573 } 1574 1575 /* 1576 * Function: 1577 * _bcm_xgs5_ft_flow_group_list_collector_in_use_check 1578 * Purpose: 1579 * Find if any flow group in the flow_group_list uses the passed collector. 1580 * Parameters: 1581 * unit - (IN) BCM device number 1582 * collector_id - (IN) collector_id 1583 * Returns: 1584 * BCM_E_EXISTS - If collector_id is used by any of the flow groups. 1585 * BCM_E_NONE - otherwise. 1586 */ 1587 int 1588 _bcm_xgs5_ft_flow_group_list_collector_in_use_check(int unit, 1589 bcm_flowtracker_collector_t collector_id) 1590 { 1591 _bcm_int_ft_flow_group_info_t *list_node = NULL; 1592 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 1593 int flow_group_id; 1594 1595 for (flow_group_id = BCM_INT_FT_GROUP_START_ID; 1596 flow_group_id < (BCM_INT_FT_GROUP_START_ID + ft_info->max_flow_groups); 1597 flow_group_id++) { 1598 list_node = &(ft_flow_group_info_list[unit][flow_group_id]); 1599 /* Valid flow group ids have non zero flow group ID. */ 1600 if (list_node->flow_group_id != 0) { 1601 if (list_node->collector_id == collector_id) { 1602 return BCM_E_EXISTS; 1603 } 1604 } 1605 } 1606 return BCM_E_NONE; 1607 } 1608 1609 /* 1610 * Function: 1611 * _bcm_xgs5_ft_flow_group_list_template_in_use_check 1612 * Purpose: 1613 * Find if any flow group in the flow_group_list uses the passed template. 1614 * Parameters: 1615 * unit - (IN) BCM device number 1616 * template_id - (IN) template_id 1617 * Returns: 1618 * BCM_E_EXISTS - If template_id is used by any of the flow groups. 1619 * BCM_E_NONE - otherwise. 1620 */ 1621 int 1622 _bcm_xgs5_ft_flow_group_list_template_in_use_check(int unit, 1623 bcm_flowtracker_export_template_t template_id) 1624 { 1625 _bcm_int_ft_flow_group_info_t *list_node = NULL; 1626 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 1627 int flow_group_id; 1628 1629 for (flow_group_id = BCM_INT_FT_GROUP_START_ID; 1630 flow_group_id < (BCM_INT_FT_GROUP_START_ID + ft_info->max_flow_groups); 1631 flow_group_id++) { 1632 list_node = &(ft_flow_group_info_list[unit][flow_group_id]); 1633 /* Valid flow group ids have non zero flow group ID. */ 1634 if (list_node->flow_group_id != 0) { 1635 if (list_node->template_id == template_id) { 1636 return BCM_E_EXISTS; 1637 } 1638 } 1639 } 1640 return BCM_E_NONE; 1641 } 1642 1643 /* 1644 * Function: 1645 * _bcm_xgs5_ft_flow_group_list_elph_profile_in_use_check 1646 * Purpose: 1647 * Find if any flow group in the flow_group_list uses the elephant profile 1648 * Parameters: 1649 * unit - (IN) BCM device number 1650 * profile_id - (IN) profile id 1651 * Returns: 1652 * BCM_E_EXISTS - If elephant profile id is used by any of the flow groups. 1653 * BCM_E_NONE - otherwise. 1654 */ 1655 int 1656 _bcm_xgs5_ft_flow_group_list_elph_profile_in_use_check(int unit, 1657 bcm_flowtracker_export_template_t profile_id) 1658 { 1659 _bcm_int_ft_flow_group_info_t *list_node = NULL; 1660 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 1661 int flow_group_id; 1662 1663 for (flow_group_id = BCM_INT_FT_GROUP_START_ID; 1664 flow_group_id < (BCM_INT_FT_GROUP_START_ID + ft_info->max_flow_groups); 1665 flow_group_id++) { 1666 list_node = &(ft_flow_group_info_list[unit][flow_group_id]); 1667 /* Valid flow group ids have non zero flow group ID. */ 1668 if (list_node->flow_group_id != 0) { 1669 if (list_node->elph_profile_id == profile_id) { 1670 return BCM_E_EXISTS; 1671 } 1672 } 1673 } 1674 return BCM_E_NONE; 1675 } 1676 1677 /* 1678 * Function: 1679 * _bcm_xgs5_ft_flow_group_list_destroy 1680 * Purpose: 1681 * Destroy the flow_group list. 1682 * Parameters: 1683 * unit - (IN) BCM device number 1684 * Returns: 1685 * BCM_E_XXX 1686 */ 1687 int 1688 _bcm_xgs5_ft_flow_group_list_destroy (int unit) 1689 { 1690 _bcm_int_ft_flow_group_info_t *list_node = NULL; 1691 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 1692 int flow_group_id; 1693 1694 if (ft_flow_group_info_list[unit] != NULL) { 1695 for (flow_group_id = BCM_INT_FT_GROUP_START_ID; 1696 flow_group_id < (BCM_INT_FT_GROUP_START_ID + ft_info->max_flow_groups); 1697 flow_group_id++) { 1698 list_node = &(ft_flow_group_info_list[unit][flow_group_id]); 1699 if (list_node->action_list != NULL) { 1700 sal_free(list_node->action_list); 1701 } 1702 } 1703 sal_free(ft_flow_group_info_list[unit]); 1704 } 1705 1706 ft_flow_group_info_list[unit] = NULL; 1707 1708 return BCM_E_NONE; 1709 } 1710 1711 1712 /* 1713 * Function: 1714 * _bcm_xgs5_ft_flow_group_list_create 1715 * Purpose: 1716 * Create the flow_group list. 1717 * Parameters: 1718 * unit - (IN) BCM device number 1719 * Returns: 1720 * BCM_E_XXX 1721 */ 1722 int 1723 _bcm_xgs5_ft_flow_group_list_create (int unit) 1724 { 1725 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 1726 1727 if (ft_flow_group_info_list[unit] == NULL) { 1728 _BCM_FT_ALLOC(ft_flow_group_info_list[unit], 1729 _bcm_int_ft_flow_group_info_t, 1730 sizeof(_bcm_int_ft_flow_group_info_t) * 1731 (ft_info->max_flow_groups + BCM_INT_FT_GROUP_START_ID), 1732 "Flow_group list"); 1733 } 1734 1735 if (ft_flow_group_info_list[unit] == NULL) { 1736 return BCM_E_MEMORY; 1737 } 1738 1739 return BCM_E_NONE; 1740 } 1741 1742 /******************************************************* 1743 * * 1744 * Elephant APIs * 1745 */ 1746 1747 /* 1748 * Function: 1749 * _bcm_xgs5_ft_elph_profile_list_add 1750 * Purpose: 1751 * Add a elephant profile to the list. 1752 * Parameters: 1753 * unit - (IN) BCM device number 1754 * id - (IN) Elephant profile ID 1755 * profile - (IN) Elephant profile 1756 * Returns: 1757 * BCM_E_XXX 1758 */ 1759 int 1760 _bcm_xgs5_ft_elph_profile_list_add(int unit, 1761 bcm_flowtracker_elephant_profile_t id, 1762 bcm_flowtracker_elephant_profile_info_t *profile) 1763 { 1764 _bcm_int_ft_elph_profile_info_t *elph_profile_int_info = 1765 &(ft_elph_profile_info_list[unit][id]); 1766 1767 elph_profile_int_info->id = id; 1768 1769 sal_memcpy(&(elph_profile_int_info->profile), profile, 1770 sizeof(bcm_flowtracker_elephant_profile_info_t)); 1771 1772 return BCM_E_NONE; 1773 } 1774 1775 /* 1776 * Function: 1777 * _bcm_xgs5_ft_elph_profile_list_get 1778 * Purpose: 1779 * Get a elephant profile from the list. 1780 * Parameters: 1781 * unit - (IN) BCM device number 1782 * id - (IN) Elephant profile ID 1783 * profile - (OUT) Elephant profile 1784 * Returns: 1785 * BCM_E_XXX 1786 */ 1787 int 1788 _bcm_xgs5_ft_elph_profile_list_get(int unit, 1789 bcm_flowtracker_elephant_profile_t id, 1790 _bcm_int_ft_elph_profile_info_t *profile) 1791 { 1792 _bcm_int_ft_elph_profile_info_t *list_node = 1793 &(ft_elph_profile_info_list[unit][id]); 1794 1795 if (list_node->id != id) { 1796 return BCM_E_NOT_FOUND; 1797 } 1798 sal_memcpy(profile, list_node, sizeof(_bcm_int_ft_elph_profile_info_t)); 1799 1800 return BCM_E_NONE; 1801 } 1802 1803 /* 1804 * Function: 1805 * _bcm_xgs5_ft_elph_profile_list_delete 1806 * Purpose: 1807 * Add a elephant profile to the list. 1808 * Parameters: 1809 * unit - (IN) BCM device number 1810 * id - (IN) Elephant profile ID 1811 * Returns: 1812 * BCM_E_XXX 1813 */ 1814 int 1815 _bcm_xgs5_ft_elph_profile_list_delete(int unit, 1816 bcm_flowtracker_elephant_profile_t id) 1817 { 1818 _bcm_int_ft_elph_profile_info_t *profile_int_info = 1819 &(ft_elph_profile_info_list[unit][id]); 1820 1821 if (profile_int_info->id != id) { 1822 return BCM_E_NOT_FOUND; 1823 } 1824 1825 sal_memset(profile_int_info, 0, sizeof(_bcm_int_ft_elph_profile_info_t)); 1826 1827 return BCM_E_NONE; 1828 } 1829 1830 /* 1831 * Function: 1832 * _bcm_xgs5_ft_elph_profile_list_create 1833 * Purpose: 1834 * Create the elephant profile list. 1835 * Parameters: 1836 * unit - (IN) BCM device number 1837 * Returns: 1838 * BCM_E_XXX 1839 */ 1840 int 1841 _bcm_xgs5_ft_elph_profile_list_create(int unit) 1842 { 1843 if (ft_elph_profile_info_list[unit] == NULL) { 1844 _BCM_FT_ALLOC(ft_elph_profile_info_list[unit], _bcm_int_ft_elph_profile_info_t, 1845 sizeof(_bcm_int_ft_elph_profile_info_t) * 1846 (BCM_INT_FT_ELPH_PROFILE_START_ID + BCM_INT_FT_MAX_ELEPHANT_PROFILES), 1847 "Elephant profile list"); 1848 } 1849 1850 if (ft_elph_profile_info_list[unit] == NULL) { 1851 return BCM_E_MEMORY; 1852 } 1853 1854 return BCM_E_NONE; 1855 } 1856 1857 /* 1858 * Function: 1859 * _bcm_xgs5_ft_elph_profile_destroy 1860 * Purpose: 1861 * Destroy the elephant profile list. 1862 * Parameters: 1863 * unit - (IN) BCM device number 1864 * Returns: 1865 * BCM_E_XXX 1866 */ 1867 int 1868 _bcm_xgs5_ft_elph_profile_list_destroy(int unit) 1869 { 1870 if (ft_elph_profile_info_list[unit] != NULL) { 1871 sal_free(ft_elph_profile_info_list[unit]); 1872 } 1873 ft_elph_profile_info_list[unit] = NULL; 1874 return BCM_E_NONE; 1875 } 1876 1877 /****************************************************** 1878 * * 1879 * FLOWTRACKER EMB APP MSGING FUNCTIONS * 1880 */ 1881 1882 /* 1883 * Function: 1884 * _bcm_xgs5_ft_convert_uc_error 1885 * Purpose: 1886 * Converts uController error code to corresponding BCM error code. 1887 * Parameters: 1888 * uc_rv - (IN) uController error code to convert. 1889 * Returns: 1890 * BCM_E_XXX - BCM error code. 1891 * Notes: 1892 */ 1893 STATIC int 1894 _bcm_xgs5_ft_convert_uc_error(uint32 uc_rv) 1895 { 1896 int rv = BCM_E_NONE; 1897 1898 switch(uc_rv) { 1899 case SHR_FT_UC_E_NONE: 1900 rv = BCM_E_NONE; 1901 break; 1902 case SHR_FT_UC_E_INTERNAL: 1903 rv = BCM_E_INTERNAL; 1904 break; 1905 case SHR_FT_UC_E_MEMORY: 1906 rv = BCM_E_MEMORY; 1907 break; 1908 case SHR_FT_UC_E_UNIT: 1909 rv = BCM_E_UNIT; 1910 break; 1911 case SHR_FT_UC_E_PARAM: 1912 rv = BCM_E_PARAM; 1913 break; 1914 case SHR_FT_UC_E_EMPTY: 1915 rv = BCM_E_EMPTY; 1916 break; 1917 case SHR_FT_UC_E_FULL: 1918 rv = BCM_E_FULL; 1919 break; 1920 case SHR_FT_UC_E_NOT_FOUND: 1921 rv = BCM_E_NOT_FOUND; 1922 break; 1923 case SHR_FT_UC_E_EXISTS: 1924 rv = BCM_E_EXISTS; 1925 break; 1926 case SHR_FT_UC_E_TIMEOUT: 1927 rv = BCM_E_TIMEOUT; 1928 break; 1929 case SHR_FT_UC_E_BUSY: 1930 rv = BCM_E_BUSY; 1931 break; 1932 case SHR_FT_UC_E_FAIL: 1933 rv = BCM_E_FAIL; 1934 break; 1935 case SHR_FT_UC_E_DISABLED: 1936 rv = BCM_E_DISABLED; 1937 break; 1938 case SHR_FT_UC_E_BADID: 1939 rv = BCM_E_BADID; 1940 break; 1941 case SHR_FT_UC_E_RESOURCE: 1942 rv = BCM_E_RESOURCE; 1943 break; 1944 case SHR_FT_UC_E_CONFIG: 1945 rv = BCM_E_CONFIG; 1946 break; 1947 case SHR_FT_UC_E_UNAVAIL: 1948 rv = BCM_E_UNAVAIL; 1949 break; 1950 case SHR_FT_UC_E_INIT: 1951 rv = BCM_E_INIT; 1952 break; 1953 case SHR_FT_UC_E_PORT: 1954 rv = BCM_E_PORT; 1955 break; 1956 default: 1957 rv = BCM_E_INTERNAL; 1958 break; 1959 } 1960 1961 return rv; 1962 } 1963 1964 STATIC int 1965 _bcm_xgs5_ft_msg_send_receive(int unit, uint8 s_subclass, 1966 uint16 s_len, uint32 s_data, 1967 uint8 r_subclass, uint16 *r_len, 1968 sal_usecs_t timeout) 1969 { 1970 int rv; 1971 mos_msg_data_t send, reply; 1972 uint32 uc_rv; 1973 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 1974 uint8 *dma_buffer; 1975 int dma_buffer_len; 1976 1977 1978 dma_buffer = ft_info->dma_buffer; 1979 dma_buffer_len = ft_info->dma_buffer_len; 1980 1981 sal_memset(&send, 0, sizeof(send)); 1982 sal_memset(&reply, 0, sizeof(reply)); 1983 send.s.mclass = MOS_MSG_CLASS_FT; 1984 send.s.subclass = s_subclass; 1985 send.s.len = bcm_htons(s_len); 1986 1987 /* 1988 * Set 'data' to DMA buffer address if a DMA operation is 1989 * required for send or receive. 1990 */ 1991 if (MOS_MSG_DMA_MSG(s_subclass) || 1992 MOS_MSG_DMA_MSG(r_subclass)) { 1993 send.s.data = bcm_htonl(soc_cm_l2p(unit, dma_buffer)); 1994 } else { 1995 send.s.data = bcm_htonl(s_data); 1996 } 1997 1998 /* Flush DMA memory */ 1999 if (MOS_MSG_DMA_MSG(s_subclass)) { 2000 soc_cm_sflush(unit, dma_buffer, s_len); 2001 } 2002 2003 /* Invalidate DMA memory to read */ 2004 if (MOS_MSG_DMA_MSG(r_subclass)) { 2005 soc_cm_sinval(unit, dma_buffer, dma_buffer_len); 2006 } 2007 2008 rv = soc_cmic_uc_msg_send_receive(unit, 0, 2009 &send, &reply, 2010 timeout); 2011 if (rv != SOC_E_NONE){ 2012 return BCM_E_INTERNAL; 2013 } 2014 2015 /* Convert FT uController error code to BCM */ 2016 uc_rv = bcm_ntohl(reply.s.data); 2017 rv = _bcm_xgs5_ft_convert_uc_error(uc_rv); 2018 2019 *r_len = bcm_ntohs(reply.s.len); 2020 2021 /*Check reply class and subclass*/ 2022 if((rv == SOC_E_NONE) && ((reply.s.mclass != MOS_MSG_CLASS_FT) || 2023 (reply.s.subclass != r_subclass))) 2024 { 2025 return BCM_E_INTERNAL; 2026 } 2027 return rv; 2028 } 2029 2030 /* 2031 * Function: 2032 * _bcm_xgs5_ft_eapp_send_features_exchange_msg 2033 * Purpose: 2034 * Exchange features with the EApp 2035 * Parameters: 2036 * unit - (IN) BCM device number 2037 * Returns: 2038 * BCM_E_XXX - BCM error code. 2039 */ 2040 STATIC int _bcm_xgs5_ft_eapp_send_features_exchange_msg(int unit) 2041 { 2042 shr_ft_msg_ctrl_sdk_features_t send_msg; 2043 shr_ft_msg_ctrl_uc_features_t rcv_msg; 2044 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 2045 uint16 buffer_len = 0, reply_len = 0; 2046 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2047 int rv; 2048 2049 sal_memset(&send_msg, 0, sizeof(send_msg)); 2050 sal_memset(&rcv_msg, 0, sizeof(rcv_msg)); 2051 2052 /* Populate the SDK features */ 2053 send_msg.cfg_mode = ft_info->cfg_mode; 2054 2055 /* Exchange supported features with the FW */ 2056 buffer_req = ft_info->dma_buffer; 2057 buffer_ptr = shr_ft_msg_ctrl_sdk_features_pack(buffer_req, &send_msg); 2058 buffer_len = buffer_ptr - buffer_req; 2059 2060 rv = _bcm_xgs5_ft_msg_send_receive(unit, 2061 MOS_MSG_SUBCLASS_FT_FEATURES_EXCHANGE, 2062 buffer_len, 0, 2063 MOS_MSG_SUBCLASS_FT_FEATURES_EXCHANGE_REPLY, 2064 &reply_len, 2065 SHR_FT_MAX_UC_MSG_TIMEOUT); 2066 2067 if (rv == BCM_E_UNAVAIL) { 2068 /* Older FW not supporting this message, assume default feature support */ 2069 ft_info->uc_features = (SHR_FT_UC_FEATURE_IPFIX_EXPORT | 2070 SHR_FT_UC_FEATURE_ELPH); 2071 if (ft_info->cfg_mode != SHR_FT_CFG_MODE_V1) { 2072 /* Only FTv1 is supported when working with older FW */ 2073 return BCM_E_CONFIG; 2074 } 2075 return BCM_E_NONE; 2076 } else if (rv != BCM_E_NONE) { 2077 return rv; 2078 } 2079 2080 buffer_req = ft_info->dma_buffer; 2081 buffer_ptr = shr_ft_msg_ctrl_uc_features_unpack(buffer_req, &rcv_msg); 2082 buffer_len = buffer_ptr - buffer_req; 2083 2084 if (buffer_len != reply_len) { 2085 return BCM_E_INTERNAL; 2086 } 2087 2088 /* Check if soc properties configured aligns with the app features */ 2089 if (ft_info->elph_mode && !(rcv_msg.features & SHR_FT_UC_FEATURE_ELPH)) { 2090 return BCM_E_CONFIG; 2091 } 2092 2093 ft_info->uc_features = rcv_msg.features; 2094 2095 return BCM_E_NONE; 2096 } 2097 2098 int _bcm_xgs5_ft_eapp_send_ctrl_init_msg (int unit) 2099 { 2100 shr_ft_msg_ctrl_init_t ctrl_init_msg; 2101 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 2102 int i = 0, pool; 2103 uint16 buffer_len = 0, reply_len = 0; 2104 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2105 2106 2107 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2108 return BCM_E_NONE; 2109 } 2110 2111 sal_memset(&ctrl_init_msg, 0, sizeof(ctrl_init_msg)); 2112 2113 ctrl_init_msg.max_groups = ft_info->max_flow_groups; 2114 ctrl_init_msg.num_pipes = ft_info->num_pipes; 2115 for (i = 0; i < ctrl_init_msg.num_pipes; i++) { 2116 ctrl_init_msg.pipe[i].max_flows = ft_info->pipe_info[i].max_flows; 2117 ctrl_init_msg.pipe[i].num_ctr_pools = ft_info->pipe_info[i].num_ctr_pools; 2118 for (pool = 0; pool < ctrl_init_msg.pipe[i].num_ctr_pools; pool++) { 2119 ctrl_init_msg.pipe[i].ctr_pools[pool] = 2120 ft_info->pipe_info[i].ctr_pools[pool]; 2121 ctrl_init_msg.pipe[i].ctr_pool_size[pool] = 2122 ft_info->pipe_info[i].ctr_pool_size[pool]; 2123 } 2124 } 2125 ctrl_init_msg.rx_channel = BCM_INT_FT_EAPP_RX_CHANNEL; 2126 ctrl_init_msg.max_export_pkt_length = ft_info->max_export_pkt_length; 2127 ctrl_init_msg.cur_time_secs = sal_time(); 2128 2129 /* Timer intervals */ 2130 ctrl_init_msg.export_interval_msecs = ft_info->export_interval; 2131 ctrl_init_msg.scan_interval_usecs = ft_info->scan_interval_usecs; 2132 ctrl_init_msg.age_timer_tick_msecs = BCM_INT_FT_AGING_INTERVAL_STEP_MSECS; 2133 2134 /* Initialization flags */ 2135 if (ft_info->flags & BCM_INT_FT_INFO_FLAGS_FLOW_START_TS) { 2136 ctrl_init_msg.flags |= SHR_FT_MSG_INIT_FLAGS_FLOW_START_TS; 2137 } 2138 if (ft_info->elph_mode) { 2139 ctrl_init_msg.flags |= SHR_FT_MSG_INIT_FLAGS_ELEPHANT; 2140 ctrl_init_msg.num_elph_profiles = BCM_INT_FT_MAX_ELEPHANT_PROFILES; 2141 } 2142 if (ft_info->flags & BCM_INT_FT_INFO_FLAGS_DROP_MONITOR) { 2143 ctrl_init_msg.flags |= SHR_FT_MSG_INIT_FLAGS_DROP_MONITOR; 2144 } 2145 ctrl_init_msg.fsp_reinject_max_length = ft_info->fsp_reinject_max_length; 2146 2147 buffer_req = ft_info->dma_buffer; 2148 buffer_ptr = shr_ft_msg_ctrl_init_pack(buffer_req, &ctrl_init_msg); 2149 buffer_len = buffer_ptr - buffer_req; 2150 2151 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_msg_send_receive(unit, MOS_MSG_SUBCLASS_FT_INIT, 2152 buffer_len, 0, 2153 MOS_MSG_SUBCLASS_FT_INIT_REPLY, &reply_len, 2154 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2155 return BCM_E_NONE; 2156 } 2157 2158 int _bcm_xgs5_ft_eapp_send_em_key_format_msg (int unit, 2159 shr_ft_msg_ctrl_em_key_format_t *em_key_format) 2160 { 2161 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 2162 uint16 buffer_len = 0, reply_len = 0; 2163 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2164 2165 2166 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2167 return BCM_E_NONE; 2168 } 2169 2170 buffer_req = ft_info->dma_buffer; 2171 buffer_ptr = shr_ft_msg_ctrl_em_key_format_pack(buffer_req, em_key_format); 2172 buffer_len = buffer_ptr - buffer_req; 2173 2174 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_msg_send_receive(unit, MOS_MSG_SUBCLASS_FT_EM_KEY_FORMAT, 2175 buffer_len, 0, 2176 MOS_MSG_SUBCLASS_FT_EM_KEY_FORMAT_REPLY, &reply_len, 2177 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2178 return BCM_E_NONE; 2179 } 2180 2181 int _bcm_xgs5_ft_eapp_send_em_group_create_msg(int unit, 2182 shr_ft_msg_ctrl_em_group_create_t *msg) 2183 { 2184 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 2185 uint16 buffer_len = 0, reply_len = 0; 2186 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2187 2188 buffer_req = ft_info->dma_buffer; 2189 buffer_ptr = shr_ft_msg_ctrl_em_group_create_pack(buffer_req, msg); 2190 buffer_len = buffer_ptr - buffer_req; 2191 2192 BCM_IF_ERROR_RETURN( 2193 _bcm_xgs5_ft_msg_send_receive(unit, 2194 MOS_MSG_SUBCLASS_FT_EM_GROUP_CREATE, 2195 buffer_len, 0, 2196 MOS_MSG_SUBCLASS_FT_EM_GROUP_CREATE_REPLY, 2197 &reply_len, 2198 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2199 return BCM_E_NONE; 2200 2201 } 2202 2203 int _bcm_xgs5_ft_eapp_send_em_group_delete_msg(int unit, 2204 int em_group_id) 2205 { 2206 uint16 reply_len = 0; 2207 2208 BCM_IF_ERROR_RETURN( 2209 _bcm_xgs5_ft_msg_send_receive(unit, MOS_MSG_SUBCLASS_FT_EM_GROUP_DELETE, 2210 em_group_id, 0, 2211 MOS_MSG_SUBCLASS_FT_EM_GROUP_DELETE_REPLY, 2212 &reply_len, 2213 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2214 return BCM_E_NONE; 2215 2216 } 2217 2218 int _bcm_xgs5_ft_eapp_send_flow_group_create_msg (int unit, 2219 bcm_flowtracker_group_t flow_group_id) 2220 { 2221 shr_ft_msg_ctrl_group_create_t group_create_msg; 2222 _bcm_int_ft_flow_group_info_t flow_group_int_info; 2223 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 2224 uint16 buffer_len = 0, reply_len = 0; 2225 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2226 int rv = BCM_E_NONE; 2227 2228 2229 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2230 return BCM_E_NONE; 2231 } 2232 2233 sal_memset(&flow_group_int_info, 0, sizeof(flow_group_int_info)); 2234 /* Get the flow group info for this group id */ 2235 rv = _bcm_xgs5_ft_flow_group_list_flow_group_get(unit, flow_group_id, &flow_group_int_info); 2236 2237 /* Return BCM_E_NOT_FOUND if not found */ 2238 if (BCM_FAILURE(rv)) { 2239 return rv; 2240 } 2241 2242 sal_memset(&group_create_msg, 0, sizeof(group_create_msg)); 2243 group_create_msg.group_idx = flow_group_id; 2244 group_create_msg.domain_id = ft_info->observation_domain_id; 2245 /* Creating group with 0 as flow limit, so that you dont learn until flow limit is set */ 2246 group_create_msg.flow_limit = 0; 2247 2248 /* Creating group with default number for aging time. */ 2249 group_create_msg.aging_interval_msecs = BCM_INT_FT_DEF_AGING_INTERVAL_MSECS; 2250 2251 buffer_req = ft_info->dma_buffer; 2252 buffer_ptr = shr_ft_msg_ctrl_group_create_pack(buffer_req, &group_create_msg); 2253 buffer_len = buffer_ptr - buffer_req; 2254 2255 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_msg_send_receive(unit, MOS_MSG_SUBCLASS_FT_GROUP_CREATE, 2256 buffer_len, 0, 2257 MOS_MSG_SUBCLASS_FT_GROUP_CREATE_REPLY, &reply_len, 2258 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2259 return BCM_E_NONE; 2260 } 2261 2262 int _bcm_xgs5_ft_eapp_send_flow_group_delete_msg (int unit, 2263 bcm_flowtracker_group_t flow_group_id) 2264 { 2265 uint16 reply_len = 0; 2266 2267 2268 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2269 return BCM_E_NONE; 2270 } 2271 2272 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_msg_send_receive(unit, MOS_MSG_SUBCLASS_FT_GROUP_DELETE, 2273 flow_group_id, 0, 2274 MOS_MSG_SUBCLASS_FT_GROUP_DELETE_REPLY, &reply_len, 2275 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2276 return BCM_E_NONE; 2277 } 2278 2279 /* NOTE: currently expecting only one flag out of multiple flags and its updated value 2280 * is expected. 2281 */ 2282 int _bcm_xgs5_ft_eapp_send_flow_group_update_msg (int unit, 2283 bcm_flowtracker_group_t flow_group_id, 2284 uint32 update_flags, uint32 update_value) 2285 { 2286 shr_ft_msg_ctrl_group_update_t group_update_msg; 2287 _bcm_int_ft_flow_group_info_t flow_group_int_info; 2288 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2289 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 2290 uint16 buffer_len = 0, reply_len = 0; 2291 int rv = BCM_E_NONE; 2292 2293 2294 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2295 return BCM_E_NONE; 2296 } 2297 2298 sal_memset(&flow_group_int_info, 0, sizeof(flow_group_int_info)); 2299 /* Get the flow group info for this group id */ 2300 rv = _bcm_xgs5_ft_flow_group_list_flow_group_get(unit, flow_group_id, &flow_group_int_info); 2301 2302 /* Return BCM_E_NOT_FOUND if not found */ 2303 if (BCM_FAILURE(rv)) { 2304 return rv; 2305 } 2306 2307 sal_memset(&group_update_msg, 0, sizeof(group_update_msg)); 2308 group_update_msg.group_idx = flow_group_id; 2309 group_update_msg.update = update_flags; 2310 group_update_msg.param0 = update_value; 2311 2312 buffer_req = ft_info->dma_buffer; 2313 buffer_ptr = shr_ft_msg_ctrl_group_update_pack(buffer_req, &group_update_msg); 2314 buffer_len = buffer_ptr - buffer_req; 2315 2316 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_msg_send_receive(unit, MOS_MSG_SUBCLASS_FT_GROUP_UPDATE, 2317 buffer_len, 0, 2318 MOS_MSG_SUBCLASS_FT_GROUP_UPDATE_REPLY, &reply_len, 2319 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2320 return BCM_E_NONE; 2321 } 2322 2323 /* NOTE: Currently we use flow group get msg to EAPP 2324 * only for getting flow_count. 2325 */ 2326 int _bcm_xgs5_ft_eapp_send_flow_group_get_msg (int unit, 2327 bcm_flowtracker_group_t flow_group_id, 2328 uint32 *flow_count) 2329 { 2330 shr_ft_msg_ctrl_group_get_t group_get_msg; 2331 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 2332 uint16 buffer_len = 0, reply_len = 0; 2333 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2334 2335 2336 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2337 return BCM_E_NONE; 2338 } 2339 2340 sal_memset(&group_get_msg, 0, sizeof(group_get_msg)); 2341 2342 2343 /* Do a group get for flow_group_id */ 2344 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_msg_send_receive(unit, MOS_MSG_SUBCLASS_FT_GROUP_GET, 2345 flow_group_id, 0, 2346 MOS_MSG_SUBCLASS_FT_GROUP_GET_REPLY, &reply_len, 2347 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2348 2349 buffer_req = ft_info->dma_buffer; 2350 buffer_ptr = shr_ft_msg_ctrl_group_get_unpack(buffer_req, &group_get_msg); 2351 buffer_len = buffer_ptr - buffer_req; 2352 2353 if (buffer_len != reply_len) { 2354 return BCM_E_INTERNAL; 2355 } 2356 2357 *flow_count = group_get_msg.flow_count; 2358 2359 return BCM_E_NONE; 2360 } 2361 2362 int _bcm_xgs5_ft_eapp_send_template_create_msg (int unit, 2363 bcm_flowtracker_export_template_t template_id) 2364 { 2365 _bcm_int_ft_export_template_info_t template_int_info; 2366 shr_ft_msg_ctrl_template_create_t template_create_msg; 2367 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 2368 uint16 buffer_len = 0, reply_len = 0; 2369 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2370 int rv = BCM_E_NONE; 2371 int i = 0; 2372 2373 2374 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2375 return BCM_E_NONE; 2376 } 2377 2378 sal_memset(&template_int_info, 0, sizeof(template_int_info)); 2379 /* Get the template info for this template id */ 2380 rv = _bcm_xgs5_ft_template_list_template_get(unit, template_id, &template_int_info); 2381 2382 /* Return BCM_E_NOT_FOUND if not found */ 2383 if (BCM_FAILURE(rv)) { 2384 return rv; 2385 } 2386 sal_memset(&template_create_msg, 0, sizeof(template_create_msg)); 2387 template_create_msg.id = template_id; 2388 template_create_msg.set_id = template_int_info.set_id; 2389 template_create_msg.num_info_elems = template_int_info.num_export_elements; 2390 2391 for (i = 0; i < template_create_msg.num_info_elems; i++) { 2392 template_create_msg.info_elems[i] = template_int_info.elements[i].element; 2393 template_create_msg.data_size[i] = template_int_info.elements[i].data_size; 2394 } 2395 2396 buffer_req = ft_info->dma_buffer; 2397 buffer_ptr = shr_ft_msg_ctrl_template_create_pack(buffer_req, &template_create_msg); 2398 buffer_len = buffer_ptr - buffer_req; 2399 2400 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_msg_send_receive(unit, MOS_MSG_SUBCLASS_FT_TEMPLATE_CREATE, 2401 buffer_len, 0, 2402 MOS_MSG_SUBCLASS_FT_TEMPLATE_CREATE_REPLY, &reply_len, 2403 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2404 return BCM_E_NONE; 2405 } 2406 2407 int _bcm_xgs5_ft_eapp_send_template_delete_msg (int unit, 2408 bcm_flowtracker_export_template_t template_id) 2409 { 2410 uint16 reply_len = 0; 2411 2412 2413 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2414 return BCM_E_NONE; 2415 } 2416 2417 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_msg_send_receive(unit, 2418 MOS_MSG_SUBCLASS_FT_TEMPLATE_DELETE, 2419 template_id, 0, 2420 MOS_MSG_SUBCLASS_FT_TEMPLATE_DELETE_REPLY, &reply_len, 2421 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2422 return BCM_E_NONE; 2423 } 2424 2425 int _bcm_xgs5_ft_eapp_send_collector_create_msg(int unit, 2426 int collector_id, 2427 int export_profile_id) 2428 { 2429 shr_ft_msg_ctrl_collector_create_t collector_create_msg; 2430 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2431 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 2432 uint16 buffer_len = 0, reply_len = 0; 2433 int rv = BCM_E_NONE; 2434 2435 2436 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2437 return BCM_E_NONE; 2438 } 2439 2440 if (ft_info->cfg_mode == SHR_FT_CFG_MODE_V1) { 2441 rv = _bcm_xgs5_ft_eapp_collector_encap_build_pack(unit, collector_id, 2442 &collector_create_msg); 2443 } else { 2444 rv = _bcm_xgs5_ft_v2_eapp_collector_encap_build_pack(unit, collector_id, 2445 export_profile_id, 2446 &collector_create_msg); 2447 } 2448 BCM_IF_ERROR_RETURN(rv); 2449 2450 /* Check if there is space to insert at least the headers */ 2451 if ((collector_create_msg.encap_length + 2452 BCM_INT_FT_IPFIX_MSG_HDR_LENGTH + 2453 BCM_INT_FT_SET_HDR_LENGTH + 2454 BCM_INT_FT_L2_CRC_LENGTH) > collector_create_msg.mtu) { 2455 return BCM_E_PARAM; 2456 } 2457 2458 buffer_req = ft_info->dma_buffer; 2459 buffer_ptr = shr_ft_msg_ctrl_collector_create_pack(buffer_req, &collector_create_msg); 2460 buffer_len = buffer_ptr - buffer_req; 2461 2462 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_msg_send_receive(unit, MOS_MSG_SUBCLASS_FT_COLLECTOR_CREATE, 2463 buffer_len, 0, 2464 MOS_MSG_SUBCLASS_FT_COLLECTOR_CREATE_REPLY, &reply_len, 2465 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2466 return BCM_E_NONE; 2467 } 2468 2469 int _bcm_xgs5_ft_eapp_send_collector_delete_msg (int unit, 2470 uint16 collector_id) 2471 { 2472 uint16 reply_len = 0; 2473 2474 2475 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2476 return BCM_E_NONE; 2477 } 2478 2479 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_msg_send_receive(unit, 2480 MOS_MSG_SUBCLASS_FT_COLLECTOR_DELETE, 2481 collector_id, 0, 2482 MOS_MSG_SUBCLASS_FT_COLLECTOR_DELETE_REPLY, &reply_len, 2483 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2484 return BCM_E_NONE; 2485 } 2486 2487 int _bcm_xgs5_ft_eapp_send_export_interval_update_msg (int unit, 2488 uint32 export_interval) 2489 { 2490 uint16 reply_len = 0; 2491 2492 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_msg_send_receive(unit, 2493 MOS_MSG_SUBCLASS_FT_EXPORT_INTERVAL_UPDATE, 2494 0, export_interval, 2495 MOS_MSG_SUBCLASS_FT_EXPORT_INTERVAL_UPDATE_REPLY, 2496 &reply_len, 2497 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2498 return BCM_E_NONE; 2499 } 2500 /* 2501 * Function: 2502 * _bcm_xgs5_ft_send_eapp_template_xmit_start 2503 * Purpose: 2504 * Start the template set transmit 2505 * Parameters: 2506 * unit - (IN) BCM device number 2507 * template_id - (IN) Template Id 2508 * collector_id - (IN) Collector Id 2509 * Returns: 2510 * BCM_E_XXX - BCM error code. 2511 */ 2512 int 2513 _bcm_xgs5_ft_eapp_send_template_xmit_start(int unit, 2514 bcm_flowtracker_export_template_t template_id, 2515 bcm_flowtracker_collector_t collector_id) 2516 { 2517 _bcm_int_ft_export_template_info_t template_int_info; 2518 shr_ft_msg_ctrl_template_xmit_t msg; 2519 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2520 uint8 *buffer_req = NULL; 2521 uint8 *buffer_ptr = NULL; 2522 uint16 buffer_len = 0; 2523 uint16 reply_len = 0; 2524 int rv = BCM_E_NONE; 2525 2526 2527 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2528 return BCM_E_NONE; 2529 } 2530 2531 sal_memset(&template_int_info, 0, sizeof(template_int_info)); 2532 2533 /* Get the template info for this template id */ 2534 rv = _bcm_xgs5_ft_template_list_template_get(unit, template_id, 2535 &template_int_info); 2536 if (BCM_FAILURE(rv)) { 2537 return rv; 2538 } 2539 2540 sal_memset(&msg, 0, sizeof(msg)); 2541 2542 /* Build the template encap */ 2543 _bcm_xgs5_ft_eapp_template_encap_build_pack(unit, 2544 &template_int_info, 2545 &(msg.encap_length), 2546 msg.encap); 2547 msg.template_id = template_id; 2548 msg.collector_id = collector_id; 2549 msg.interval_secs = template_int_info.interval_secs; 2550 msg.initial_burst = template_int_info.initial_burst; 2551 2552 buffer_req = ft_info->dma_buffer; 2553 buffer_ptr = shr_ft_msg_ctrl_template_xmit_pack(buffer_req, &msg); 2554 buffer_len = buffer_ptr - buffer_req; 2555 2556 BCM_IF_ERROR_RETURN( 2557 _bcm_xgs5_ft_msg_send_receive(unit, 2558 MOS_MSG_SUBCLASS_FT_TEMPLATE_XMIT, 2559 buffer_len, 0, 2560 MOS_MSG_SUBCLASS_FT_TEMPLATE_XMIT_REPLY, 2561 &reply_len, 2562 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2563 return BCM_E_NONE; 2564 } 2565 2566 /* 2567 * Function: 2568 * _bcm_xgs5_ft_eapp_send_group_actions_set_msg 2569 * Purpose: 2570 * Set actions on a group 2571 * Parameters: 2572 * unit - (IN) BCM device number 2573 * Returns: 2574 * BCM_E_XXX - BCM error code. 2575 */ 2576 int 2577 _bcm_xgs5_ft_eapp_send_group_actions_set_msg(int unit, 2578 shr_ft_msg_ctrl_group_actions_set_t *msg) 2579 { 2580 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2581 uint8 *buffer_req = NULL; 2582 uint8 *buffer_ptr = NULL; 2583 uint16 buffer_len = 0; 2584 uint16 reply_len = 0; 2585 2586 buffer_req = ft_info->dma_buffer; 2587 buffer_ptr = shr_ft_msg_ctrl_group_actions_set_pack(buffer_req, msg); 2588 buffer_len = buffer_ptr - buffer_req; 2589 2590 BCM_IF_ERROR_RETURN( 2591 _bcm_xgs5_ft_msg_send_receive(unit, 2592 MOS_MSG_SUBCLASS_FT_GROUP_ACTIONS_SET, 2593 buffer_len, 0, 2594 MOS_MSG_SUBCLASS_FT_GROUP_ACTIONS_SET_REPLY, 2595 &reply_len, 2596 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2597 2598 return BCM_E_NONE; 2599 } 2600 2601 /****************************************************** 2602 * * 2603 * FLOWTRACKER EMB APP APIs * 2604 */ 2605 2606 int bcm_xgs5_ft_eapp_init(int unit) 2607 { 2608 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2609 int rv = BCM_E_NONE; 2610 int uc = 0; 2611 2612 2613 if (!soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2614 /* Init the app */ 2615 if (!soc_uc_in_reset(unit, uc)) { 2616 rv = soc_cmic_uc_appl_init(unit, uc, MOS_MSG_CLASS_FT, 2617 SHR_FT_MAX_UC_MSG_TIMEOUT, 2618 FT_MSG_VERSION, FT_MSG_BASE_VERSION, 2619 NULL, NULL); 2620 if (SOC_E_NONE != rv) { 2621 BCM_IF_ERROR_RETURN(bcm_xgs5_ft_eapp_detach(unit)); 2622 return rv; 2623 } 2624 } else { 2625 BCM_IF_ERROR_RETURN(bcm_xgs5_ft_eapp_detach(unit)); 2626 return BCM_E_INIT; 2627 } 2628 } 2629 2630 /* 2631 * Allocate DMA buffer 2632 * 2633 * DMA buffer will be used to send and receive 'long' messages 2634 * between SDK Host and uController (BTE). 2635 */ 2636 ft_info->dma_buffer_len = sizeof(shr_ft_msg_ctrl_t); 2637 ft_info->dma_buffer = soc_cm_salloc(unit, ft_info->dma_buffer_len, 2638 "FT DMA buffer"); 2639 if (!ft_info->dma_buffer) { 2640 BCM_IF_ERROR_RETURN(bcm_xgs5_ft_eapp_detach(unit)); 2641 return BCM_E_MEMORY; 2642 } 2643 sal_memset(ft_info->dma_buffer, 0, ft_info->dma_buffer_len); 2644 2645 if (!SOC_WARM_BOOT(unit)) { 2646 /* Send the init config to UKERNEL */ 2647 rv = _bcm_xgs5_ft_eapp_send_ctrl_init_msg(unit); 2648 if (BCM_FAILURE(rv)) { 2649 BCM_IF_ERROR_RETURN(bcm_xgs5_ft_eapp_detach(unit)); 2650 return rv; 2651 } 2652 } 2653 2654 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_eapp_send_features_exchange_msg(unit)); 2655 2656 /* Create template list, collector list and flow group list */ 2657 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_template_list_create(unit)); 2658 if (ft_info->cfg_mode == SHR_FT_CFG_MODE_V1) { 2659 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_collector_list_create(unit)); 2660 } else { 2661 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_v2_collector_list_create(unit)); 2662 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_v2_collector_list_export_profile_create(unit)); 2663 } 2664 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_flow_group_list_create(unit)); 2665 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_elph_profile_list_create(unit)); 2666 2667 return BCM_E_NONE; 2668 } 2669 2670 int bcm_xgs5_ft_eapp_detach(int unit) 2671 { 2672 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2673 int rv = BCM_E_NONE; 2674 int uc = 0, status = 0; 2675 uint16 reply_len = 0; 2676 2677 2678 if (!soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2679 if (!SOC_WARM_BOOT(unit)) { 2680 /* Un Init the app */ 2681 SOC_IF_ERROR_RETURN(soc_uc_status(unit, uc, &status)); 2682 if (status) { 2683 rv = _bcm_xgs5_ft_msg_send_receive(unit, 2684 MOS_MSG_SUBCLASS_FT_SHUTDOWN, 2685 0, 0, 2686 MOS_MSG_SUBCLASS_FT_SHUTDOWN_REPLY, 2687 &reply_len, 2688 SHR_FT_MAX_UC_MSG_TIMEOUT); 2689 if (BCM_SUCCESS(rv) && (reply_len != 0)) { 2690 return BCM_E_INTERNAL; 2691 } 2692 } 2693 } 2694 } 2695 2696 /* 2697 * Free DMA buffer 2698 */ 2699 if (ft_info->dma_buffer != NULL) { 2700 soc_cm_sfree(unit, ft_info->dma_buffer); 2701 } 2702 2703 /* Free up template list, collector list and flow group list */ 2704 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_template_list_destroy(unit)); 2705 if (ft_info->cfg_mode == SHR_FT_CFG_MODE_V1) { 2706 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_collector_list_destroy(unit)); 2707 } else { 2708 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_v2_collector_list_destroy(unit)); 2709 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_v2_collector_list_export_profile_destroy(unit)); 2710 } 2711 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_flow_group_list_destroy(unit)); 2712 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_elph_profile_list_destroy(unit)); 2713 2714 return BCM_E_NONE; 2715 } 2716 2717 /* Drop reasons, DO NOT change the order */ 2718 static bcm_rx_reason_t ft_drop_reasons[] = { 2719 bcmRxReasonInvalid, 2720 bcmRxReasonL3SourceMiss, 2721 bcmRxReasonL3DestMiss, 2722 bcmRxReasonMcastMiss, 2723 bcmRxReasonIpMcastMiss, 2724 bcmRxReasonUnknownVlan, 2725 bcmRxReasonL3HeaderMismatch, 2726 bcmRxReasonDosAttack, 2727 bcmRxReasonMartianAddr, 2728 bcmRxReasonTunnelError, 2729 bcmRxReasonParityError, 2730 bcmRxReasonL3MtuFail, 2731 bcmRxReasonHigigHdrError, 2732 bcmRxReasonMcastIdxError, 2733 bcmRxReasonClassBasedMove, 2734 bcmRxReasonL3AddrBindFail, 2735 bcmRxReasonMplsLabelMiss, 2736 bcmRxReasonMplsInvalidAction, 2737 bcmRxReasonMplsInvalidPayload, 2738 bcmRxReasonTunnelObjectValidationFail, 2739 bcmRxReasonMplsSequenceNumber, 2740 bcmRxReasonL2NonUnicastMiss, 2741 bcmRxReasonNivPrioDrop, 2742 bcmRxReasonNivRpfFail, 2743 bcmRxReasonUnknownSubtendingPort, 2744 bcmRxReasonTunnelAdaptLookupMiss, 2745 bcmRxReasonPacketFlowSelectMiss, 2746 bcmRxReasonTunnelDecapEcnError, 2747 bcmRxReasonFailoverDrop, 2748 bcmRxReasonOtherLookupMiss, 2749 bcmRxReasonInvalidTpid, 2750 bcmRxReasonTunnelTtlError, 2751 bcmRxReasonMplsIllegalReservedLabel, 2752 bcmRxReasonL3HeaderError, 2753 bcmRxReasonL2HeaderError, 2754 bcmRxReasonTtl1, 2755 bcmRxReasonTtl, 2756 bcmRxReasonFcoeZoneCheckFail, 2757 bcmRxReasonIpmcInterfaceMismatch, 2758 bcmRxReasonMplsTtl, 2759 bcmRxReasonMplsUnknownAch, 2760 bcmRxReasonOAMError, 2761 bcmRxReasonL2GreSipMiss, 2762 bcmRxReasonL2GreVpnIdMiss, 2763 bcmRxReasonBfd, 2764 bcmRxReasonCongestionCnmProxyError, 2765 bcmRxReasonVxlanSipMiss, 2766 bcmRxReasonVxlanVpnIdMiss, 2767 bcmRxReasonNivInterfaceMiss, 2768 bcmRxReasonNivTagInvalid, 2769 bcmRxReasonNivTagDrop, 2770 bcmRxReasonNivUntagDrop, 2771 bcmRxReasonTrillInvalid, 2772 bcmRxReasonTrillMiss, 2773 bcmRxReasonTrillRpfFail, 2774 bcmRxReasonTrillTtl, 2775 bcmRxReasonNat, 2776 bcmRxReasonTcpUdpNatMiss, 2777 bcmRxReasonIcmpNatMiss, 2778 bcmRxReasonNatFragment, 2779 bcmRxReasonNatMiss 2780 }; 2781 2782 /* 2783 * Function: 2784 * _bcm_xgs5_ft_eapp_send_flow_group_flow_data_msg 2785 * Purpose: 2786 * Get flow data for a given flow key within the given flow group. 2787 * Parameters: 2788 * unit - (IN) BCM device number 2789 * flow_group_id - (IN) Flow group Id 2790 * flow_key - (IN) Five tuple that constitutes a flow 2791 * flow_data - (OUT) Data associated with the flow key 2792 * Returns: 2793 * BCM_E_XXX - BCM error code. 2794 */ 2795 int _bcm_xgs5_ft_eapp_send_flow_group_flow_data_get_msg( 2796 int unit, 2797 bcm_flowtracker_group_t flow_group_id, 2798 bcm_flowtracker_flow_key_t *flow_key, 2799 bcm_flowtracker_flow_data_t *flow_data) 2800 { 2801 shr_ft_msg_ctrl_group_flow_data_get_t send_msg; 2802 shr_ft_msg_ctrl_group_flow_data_get_reply_t reply_msg; 2803 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2804 uint8 *buffer_req = NULL; 2805 uint8 *buffer_ptr = NULL; 2806 uint16 buffer_len = 0, reply_len = 0; 2807 int i; 2808 bcm_rx_reason_t drop_reason; 2809 int rv = BCM_E_NONE; 2810 2811 2812 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2813 return BCM_E_NONE; 2814 } 2815 2816 sal_memset(&send_msg, 0, sizeof(send_msg)); 2817 send_msg.group_idx = flow_group_id; 2818 send_msg.src_ip = flow_key->src_ip.addr.ipv4_addr; 2819 send_msg.dst_ip = flow_key->dst_ip.addr.ipv4_addr; 2820 send_msg.l4_src_port = flow_key->l4_src_port; 2821 send_msg.l4_dst_port = flow_key->l4_dst_port; 2822 send_msg.ip_protocol = flow_key->ip_protocol; 2823 send_msg.inner_src_ip = flow_key->inner_src_ip.addr.ipv4_addr; 2824 send_msg.inner_dst_ip = flow_key->inner_dst_ip.addr.ipv4_addr; 2825 send_msg.inner_l4_src_port = flow_key->inner_l4_src_port; 2826 send_msg.inner_l4_dst_port = flow_key->inner_l4_dst_port; 2827 send_msg.inner_ip_protocol = flow_key->inner_ip_protocol; 2828 send_msg.vnid = flow_key->vxlan_network_id; 2829 send_msg.custom_length = SHR_FT_CUSTOM_KEY_MAX_LENGTH; 2830 sal_memcpy(send_msg.custom, flow_key->custom, send_msg.custom_length); 2831 send_msg.in_port = flow_key->in_port; 2832 2833 buffer_req = ft_info->dma_buffer; 2834 buffer_ptr = shr_ft_msg_ctrl_group_flow_data_get_pack(buffer_req, &send_msg); 2835 buffer_len = buffer_ptr - buffer_req; 2836 2837 BCM_IF_ERROR_RETURN( 2838 _bcm_xgs5_ft_msg_send_receive(unit, 2839 MOS_MSG_SUBCLASS_FT_GROUP_FLOW_DATA_GET, 2840 buffer_len, 0, 2841 MOS_MSG_SUBCLASS_FT_GROUP_FLOW_DATA_GET_REPLY, 2842 &reply_len, 2843 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2844 2845 buffer_req = ft_info->dma_buffer; 2846 buffer_ptr = shr_ft_msg_ctrl_group_flow_data_get_reply_unpack(buffer_req, &reply_msg); 2847 buffer_len = buffer_ptr - buffer_req; 2848 2849 if (buffer_len != reply_len) { 2850 return BCM_E_INTERNAL; 2851 } 2852 2853 COMPILER_64_SET(flow_data->packet_count, reply_msg.pkt_count_upper, 2854 reply_msg.pkt_count_lower); 2855 2856 COMPILER_64_SET(flow_data->byte_count, reply_msg.byte_count_upper, 2857 reply_msg.byte_count_lower); 2858 2859 COMPILER_64_SET(flow_data->flow_start_timestamp_msecs, 2860 reply_msg.flow_start_ts_upper, 2861 reply_msg.flow_start_ts_lower); 2862 2863 COMPILER_64_SET(flow_data->observation_timestamp_msecs, 2864 reply_msg.obs_ts_upper, reply_msg.obs_ts_lower); 2865 2866 /* Get the drop reasons */ 2867 BCM_RX_REASON_CLEAR_ALL(flow_data->pkt_drop_reasons); 2868 for (i = 0; i < reply_msg.num_drop_reasons; i++) { 2869 if (reply_msg.drop_reasons[i] == SHR_FT_DROP_RX_REASON_INVALID) { 2870 continue; 2871 } else if (reply_msg.drop_reasons[i] >= SHR_FT_DROP_RX_REASON_MAX_VALUE) { 2872 return BCM_E_PARAM; 2873 } 2874 2875 drop_reason = ft_drop_reasons[reply_msg.drop_reasons[i]]; 2876 BCM_RX_REASON_SET(flow_data->pkt_drop_reasons, drop_reason); 2877 } 2878 2879 return rv; 2880 } 2881 2882 /* 2883 * Function: 2884 * _bcm_xgs5_ft_eapp_send_ser_event_msg 2885 * Purpose: 2886 * Send SER event msg to app 2887 * Parameters: 2888 * unit - (IN) BCM device number 2889 * pipe - (IN) Pipe index 2890 * mem - (IN) Memory (EM) 2891 * index - (IN) Index 2892 * Returns: 2893 * BCM_E_XXX - BCM error code. 2894 */ 2895 int 2896 _bcm_xgs5_ft_eapp_send_ser_event_msg(int unit, int pipe, soc_mem_t mem, int index) 2897 { 2898 shr_ft_msg_ctrl_ser_event_t ser_event_msg; 2899 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2900 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 2901 uint16 buffer_len = 0, reply_len = 0; 2902 2903 2904 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2905 return BCM_E_NONE; 2906 } 2907 2908 sal_memset(&ser_event_msg, 0, sizeof(ser_event_msg)); 2909 ser_event_msg.pipe = pipe; 2910 ser_event_msg.mem = mem; 2911 ser_event_msg.index = index; 2912 2913 buffer_req = ft_info->dma_buffer; 2914 buffer_ptr = shr_ft_msg_ctrl_ser_event_pack(buffer_req, &ser_event_msg); 2915 buffer_len = buffer_ptr - buffer_req; 2916 2917 BCM_IF_ERROR_RETURN( 2918 _bcm_xgs5_ft_msg_send_receive(unit, MOS_MSG_SUBCLASS_FT_SER_EVENT, 2919 buffer_len, 0, 2920 MOS_MSG_SUBCLASS_FT_SER_EVENT_REPLY, 2921 &reply_len, 2922 SHR_FT_MAX_UC_MSG_TIMEOUT)); 2923 2924 return BCM_E_NONE; 2925 } 2926 2927 /* 2928 * Function: 2929 * _bcm_xgs5_ft_eapp_elph_filter_copy 2930 * Purpose: 2931 * Copy the filter cfg from API to app format 2932 * Parameters: 2933 * unit - (IN) BCM device number 2934 * src - (IN) Filter API format 2935 * dst - (OUT) Filter app format 2936 * Returns: 2937 * None 2938 */ 2939 STATIC void 2940 _bcm_xgs5_ft_eapp_elph_filter_copy(int unit, 2941 bcm_flowtracker_elephant_filter_t *src, 2942 shr_ft_msg_ctrl_elph_profile_filter_t *dst) 2943 { 2944 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2945 2946 COMPILER_64_TO_32_HI(dst->size_threshold_bytes_upper_32, 2947 src->size_threshold_bytes); 2948 2949 COMPILER_64_TO_32_LO(dst->size_threshold_bytes_lower_32, 2950 src->size_threshold_bytes); 2951 2952 /* Copy the rate thresholds, API configures it as kbits/sec, whereas app 2953 * expects it as bytes/100usec 2954 */ 2955 dst->rate_low_threshold = src->rate_low_threshold_kbits_sec / 80; 2956 dst->rate_high_threshold = src->rate_high_threshold_kbits_sec / 80; 2957 2958 /* Convert the monitoring interval to scan count */ 2959 dst->scan_count = src->monitor_interval_usecs / ft_info->scan_interval_usecs; 2960 2961 if (src->flags & BCM_FLOWTRACKER_ELEPHANT_FILTER_FLAGS_INCREASING_RATE) { 2962 dst->incr_rate = 1; 2963 } 2964 } 2965 2966 /* 2967 * Function: 2968 * _bcm_xgs5_ft_eapp_send_elph_profile_create_msg 2969 * Purpose: 2970 * Send Elephant profile create msg 2971 * Parameters: 2972 * unit - (IN) BCM device number 2973 * profile_id - (IN) Elephant profile Id 2974 * Returns: 2975 * BCM_E_XXX - BCM error code. 2976 */ 2977 int 2978 _bcm_xgs5_ft_eapp_send_elph_profile_create_msg(int unit, int profile_id) 2979 { 2980 shr_ft_msg_ctrl_elph_profile_create_t msg; 2981 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 2982 uint16 buffer_len = 0, reply_len = 0; 2983 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 2984 _bcm_int_ft_elph_profile_info_t profile_info; 2985 2986 sal_memset(&msg, 0, sizeof(msg)); 2987 msg.profile_idx = profile_id; 2988 2989 2990 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 2991 return BCM_E_NONE; 2992 } 2993 2994 BCM_IF_ERROR_RETURN(_bcm_xgs5_ft_elph_profile_list_get(unit, profile_id, 2995 &profile_info)); 2996 2997 /* App expects 2 promotion filters followed by a demotion filter always. 2998 * Dummy filters should have already been inserted by now in profile_info 2999 */ 3000 msg.num_filters = BCM_FLOWTRACKER_ELEPHANT_MAX_PROMOTION_FILTERS + 1; 3001 _bcm_xgs5_ft_eapp_elph_filter_copy(unit, 3002 &(profile_info.profile.promotion_filters[0]), 3003 &(msg.filters[0])); 3004 _bcm_xgs5_ft_eapp_elph_filter_copy(unit, 3005 &(profile_info.profile.promotion_filters[1]), 3006 &(msg.filters[1])); 3007 _bcm_xgs5_ft_eapp_elph_filter_copy(unit, 3008 &(profile_info.profile.demotion_filter), 3009 &(msg.filters[2])); 3010 3011 3012 buffer_req = ft_info->dma_buffer; 3013 buffer_ptr = shr_ft_msg_ctrl_elph_profile_create_pack(buffer_req, &msg); 3014 buffer_len = buffer_ptr - buffer_req; 3015 3016 BCM_IF_ERROR_RETURN( 3017 _bcm_xgs5_ft_msg_send_receive(unit, 3018 MOS_MSG_SUBCLASS_FT_ELPH_PROFILE_CREATE, 3019 buffer_len, 0, 3020 MOS_MSG_SUBCLASS_FT_ELPH_PROFILE_CREATE_REPLY, 3021 &reply_len, 3022 SHR_FT_MAX_UC_MSG_TIMEOUT)); 3023 3024 return BCM_E_NONE; 3025 } 3026 3027 /* 3028 * Function: 3029 * _bcm_xgs5_ft_eapp_send_elph_profile_delete_msg 3030 * Purpose: 3031 * Send Elephant profile delete msg 3032 * Parameters: 3033 * unit - (IN) BCM device number 3034 * profile_id - (IN) Elephant profile Id 3035 * Returns: 3036 * BCM_E_XXX - BCM error code. 3037 */ 3038 int 3039 _bcm_xgs5_ft_eapp_send_elph_profile_delete_msg(int unit, int profile_id) 3040 { 3041 uint16 reply_len = 0; 3042 3043 3044 if (soc_feature(unit, soc_feature_mv2_dummy_flowtracker)) { 3045 return BCM_E_NONE; 3046 } 3047 3048 BCM_IF_ERROR_RETURN( 3049 _bcm_xgs5_ft_msg_send_receive(unit, 3050 MOS_MSG_SUBCLASS_FT_ELPH_PROFILE_DELETE, 3051 profile_id, 0, 3052 MOS_MSG_SUBCLASS_FT_ELPH_PROFILE_DELETE_REPLY, 3053 &reply_len, 3054 SHR_FT_MAX_UC_MSG_TIMEOUT)); 3055 return BCM_E_NONE; 3056 } 3057 3058 3059 /****************************************************** 3060 * * 3061 * Debug functions * 3062 */ 3063 char *_bcm_xgs5_ft_template_element_str[bcmFlowtrackerExportElementTypeCount] = 3064 { 3065 "SrcIPv4", 3066 "DstIPv4", 3067 "Unknown", 3068 "Unknown", 3069 "L4SrcPort", 3070 "L4DstPort", 3071 "IPProtocol", 3072 "PktCount", 3073 "ByteCount", 3074 "Unknown", 3075 "Unknown", 3076 "Unknown", 3077 "ObservationTimeMsecs", 3078 "FlowStartTimeMsecs", 3079 "GroupId", 3080 "Unknown", 3081 "Unknown", 3082 "Unknown", 3083 "Unknown", 3084 "Unknown", 3085 "Unknown", 3086 "Unknown", 3087 "Unknown", 3088 "Unknown", 3089 "Unknown", 3090 "Unknown", 3091 "Unknown", 3092 "Unknown", 3093 "Unknown", 3094 "Unknown", 3095 "Unknown", 3096 "Unknown", 3097 "Unknown", 3098 "Unknown", 3099 "Unknown", 3100 "Unknown", 3101 "Unknown", 3102 "Unknown", 3103 "Unknown", 3104 "Unknown", 3105 "Unknown", 3106 "Unknown", 3107 "Unknown", 3108 "Unknown", 3109 "Unknown", 3110 }; 3111 3112 /* 3113 * Function: 3114 * _bcm_xgs5_ft_template_dump 3115 * Purpose: 3116 * Dump the template. 3117 * Parameters: 3118 * template_node - (IN) Template info. 3119 * Returns: 3120 * Nothing 3121 */ 3122 void 3123 _bcm_xgs5_ft_template_dump ( 3124 _bcm_int_ft_export_template_info_t *template_node) 3125 { 3126 int i; 3127 3128 LOG_CLI((BSL_META("Template ID = %d\r\n"),template_node->template_id)); 3129 LOG_CLI((BSL_META("\tSet ID = %u\r\n"), template_node->set_id)); 3130 LOG_CLI((BSL_META("\tNum of export elements = %d\r\n"), template_node->num_export_elements)); 3131 for (i = 0; i < template_node->num_export_elements; 3132 i++) { 3133 LOG_CLI((BSL_META("\t\tElement[%d]=%s\r\n"), i, 3134 _bcm_xgs5_ft_template_element_str[template_node->elements[i].element])); 3135 } 3136 } 3137 3138 /* 3139 * Function: 3140 * _bcm_xgs5_ft_template_list_dump 3141 * Purpose: 3142 * Dump the template list. 3143 * Parameters: 3144 * unit - (IN) BCM device number 3145 * Returns: 3146 * Nothing 3147 */ 3148 void 3149 _bcm_xgs5_ft_template_list_dump (int unit) 3150 { 3151 _bcm_int_ft_export_template_info_t *template_node = NULL; 3152 int i; 3153 3154 if (ft_export_template_info_list[unit] == NULL) { 3155 return; 3156 } 3157 3158 for (i = BCM_INT_FT_TEMPLATE_START_ID; i <= BCM_INT_FT_TEMPLATE_END_ID; i++) { 3159 template_node = &(ft_export_template_info_list[unit][i]); 3160 if (template_node->template_id != 0) { 3161 _bcm_xgs5_ft_template_dump(template_node); 3162 } 3163 } 3164 } 3165 3166 void 3167 _bcm_xgs5_ft_collector_encap_l2_dump( 3168 bcm_flowtracker_collector_eth_header_t *eth) 3169 { 3170 LOG_CLI((BSL_META("\t\tDST_MAC = %x:%x:%x:%x:%x:%x\r\n"), 3171 eth->dst_mac[0], 3172 eth->dst_mac[1], 3173 eth->dst_mac[2], 3174 eth->dst_mac[3], 3175 eth->dst_mac[4], 3176 eth->dst_mac[5])); 3177 LOG_CLI((BSL_META("\t\tSRC_MAC = %x:%x:%x:%x:%x:%x\r\n"), 3178 eth->src_mac[0], 3179 eth->src_mac[1], 3180 eth->src_mac[2], 3181 eth->src_mac[3], 3182 eth->src_mac[4], 3183 eth->src_mac[5])); 3184 LOG_CLI((BSL_META("\t\tVlan tag structure = %d\r\n"), 3185 eth->vlan_tag_structure)); 3186 LOG_CLI((BSL_META("\t\touter_tpid = %u\r\n"), 3187 eth->outer_tpid)); 3188 LOG_CLI((BSL_META("\t\tinner_tpid = %u\r\n"), 3189 eth->inner_tpid)); 3190 LOG_CLI((BSL_META("\t\touter_vlan_tag = %u\r\n"), 3191 eth->outer_vlan_tag)); 3192 LOG_CLI((BSL_META("\t\tinner_vlan_tag = %u\r\n"), 3193 eth->inner_vlan_tag)); 3194 } 3195 3196 void 3197 _bcm_xgs5_ft_collector_encap_ipv4_dump( 3198 bcm_flowtracker_collector_ipv4_header_t *ipv4) 3199 { 3200 LOG_CLI((BSL_META("\t\tsrc_ip = %x\r\n"), 3201 ipv4->src_ip)); 3202 LOG_CLI((BSL_META("\t\tdst_ip = %x\r\n"), 3203 ipv4->dst_ip)); 3204 LOG_CLI((BSL_META("\t\tdscp = %u\r\n"), 3205 ipv4->dscp)); 3206 LOG_CLI((BSL_META("\t\tttl = %u\r\n"), 3207 ipv4->ttl)); 3208 } 3209 3210 void 3211 _bcm_xgs5_ft_collector_encap_udp_dump( 3212 bcm_flowtracker_collector_udp_header_t *udp) 3213 { 3214 LOG_CLI((BSL_META("\t\tDst L4 port = %d\r\n"), 3215 udp->dst_port)); 3216 LOG_CLI((BSL_META("\t\tSrc L4 port = %d\r\n"), 3217 udp->src_port)); 3218 } 3219 3220 char *_bcm_xgs5_ft_collector_transport_type_str[bcmFlowtrackerCollectorTransportTypeCount] = 3221 { 3222 "IPv4 UDP", 3223 "IPv6 UDP", 3224 "Raw" 3225 }; 3226 3227 /* 3228 * Function: 3229 * _bcm_xgs5_ft_collector_dump 3230 * Purpose: 3231 * Dump the collector info. 3232 * Parameters: 3233 * unit - (IN) BCM device number 3234 * collector_node - (IN) Collector information. 3235 * Returns: 3236 * Nothing 3237 */ 3238 void 3239 _bcm_xgs5_ft_collector_dump ( 3240 _bcm_int_ft_collector_info_t *collector_node) 3241 { 3242 LOG_CLI((BSL_META("Collector ID = %d\r\n"),collector_node->collector_id)); 3243 LOG_CLI((BSL_META("\tTransport type = %s\r\n"), 3244 _bcm_xgs5_ft_collector_transport_type_str[collector_node->collector_info.transport_type])); 3245 LOG_CLI((BSL_META("\tEncap info:\r\n"))); 3246 _bcm_xgs5_ft_collector_encap_l2_dump(&(collector_node->collector_info.eth)); 3247 _bcm_xgs5_ft_collector_encap_ipv4_dump( 3248 &(collector_node->collector_info.ipv4)); 3249 _bcm_xgs5_ft_collector_encap_udp_dump(&(collector_node->collector_info.udp)); 3250 LOG_CLI((BSL_META("\tMax packet length = %u\r\n"), 3251 collector_node->collector_info.max_packet_length)); 3252 } 3253 /* 3254 * Function: 3255 * _bcm_xgs5_ft_collector_list_dump 3256 * Purpose: 3257 * Dump the collector list. 3258 * Parameters: 3259 * unit - (IN) BCM device number 3260 * Returns: 3261 * Nothing 3262 */ 3263 void 3264 _bcm_xgs5_ft_collector_list_dump (int unit) 3265 { 3266 _bcm_int_ft_collector_info_t *collector_node = NULL; 3267 int i; 3268 3269 if (ft_collector_info_list[unit] == NULL) { 3270 return; 3271 } 3272 3273 for (i = BCM_INT_FT_COLLECTOR_START_ID; i <= BCM_INT_FT_COLLECTOR_END_ID; i++) { 3274 collector_node = &(ft_collector_info_list[unit][i]); 3275 if (collector_node->collector_id != 0) { 3276 _bcm_xgs5_ft_collector_dump(collector_node); 3277 } 3278 } 3279 } 3280 3281 /* 3282 * Function: 3283 * _bcm_xgs5_ft_flow_group_dump 3284 * Purpose: 3285 * Dump the flow_group info. 3286 * Parameters: 3287 * flow_group_node - (IN) flow_group information. 3288 * Returns: 3289 * Nothing 3290 */ 3291 void 3292 _bcm_xgs5_ft_flow_group_dump ( 3293 int unit, 3294 _bcm_int_ft_flow_group_info_t *flow_group_node) 3295 { 3296 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 3297 3298 LOG_CLI((BSL_META("Flow group ID = %u\r\n"), 3299 flow_group_node->flow_group_id)); 3300 LOG_CLI((BSL_META("\tObservation domain ID = %u\r\n"), 3301 ft_info->observation_domain_id)); 3302 LOG_CLI((BSL_META("\tExport interval(us) = %u\r\n"), 3303 ft_info->export_interval)); 3304 LOG_CLI((BSL_META("\tAging interval(ms) = %u\r\n"), 3305 flow_group_node->aging_interval_msecs)); 3306 LOG_CLI((BSL_META("\tFlow limit = %u\r\n"),flow_group_node->flow_limit)); 3307 LOG_CLI((BSL_META("\tCollector ID = %u\r\n"),flow_group_node->collector_id)); 3308 LOG_CLI((BSL_META("\tTemplate ID = %u\r\n"),flow_group_node->template_id)); 3309 if (ft_info->elph_mode == TRUE) { 3310 LOG_CLI((BSL_META("\Elephant Profile ID = %u\r\n"), 3311 flow_group_node->elph_profile_id)); 3312 } 3313 } 3314 3315 /* 3316 * Function: 3317 * _bcm_xgs5_ft_flow_group_list_dump 3318 * Purpose: 3319 * Dump the flow_group list. 3320 * Parameters: 3321 * unit - (IN) BCM device number 3322 * Returns: 3323 * Nothing 3324 */ 3325 void 3326 _bcm_xgs5_ft_flow_group_list_dump (int unit) 3327 { 3328 _bcm_int_ft_flow_group_info_t *flow_group_node = NULL; 3329 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 3330 int i; 3331 3332 if (ft_flow_group_info_list[unit] == NULL) { 3333 return; 3334 } 3335 3336 for (i = BCM_INT_FT_GROUP_START_ID; 3337 i < (BCM_INT_FT_GROUP_START_ID + ft_info->max_flow_groups); i++) { 3338 flow_group_node = &(ft_flow_group_info_list[unit][i]); 3339 if (flow_group_node->flow_group_id != 0) { 3340 _bcm_xgs5_ft_flow_group_dump(unit, flow_group_node); 3341 } 3342 } 3343 } 3344 /* 3345 * Function: 3346 * _bcm_xgs5_ft_elph_profile_dump 3347 * Purpose: 3348 * Dump an elephant profile info. 3349 * Parameters: 3350 * elph_profile - (IN) Elephant profile information. 3351 * Returns: 3352 * Nothing 3353 */ 3354 void 3355 _bcm_xgs5_ft_elph_profile_dump(_bcm_int_ft_elph_profile_info_t *profile_info) 3356 { 3357 int i; 3358 3359 LOG_CLI((BSL_META("Profile Id = %d\r\n"), profile_info->id)); 3360 LOG_CLI((BSL_META("Num promotion filters = %d\r\n"), 3361 profile_info->profile.num_promotion_filters)); 3362 for (i = 0; i < profile_info->profile.num_promotion_filters; i++) { 3363 LOG_CLI((BSL_META("Promotion Filter : %d\r\n"), i)); 3364 LOG_CLI((BSL_META("\tFlags = 0x%08x\r\n"), 3365 profile_info->profile.promotion_filters[i].flags)); 3366 LOG_CLI((BSL_META("\tMonitor Interval = %u usecs\r\n"), 3367 profile_info->profile.promotion_filters[i].monitor_interval_usecs)); 3368 LOG_CLI((BSL_META("\tRate Low threshold = %u kbps\r\n"), 3369 profile_info->profile.promotion_filters[i].rate_low_threshold_kbits_sec)); 3370 LOG_CLI((BSL_META("\tRate High threshold = %u kbps\r\n"), 3371 profile_info->profile.promotion_filters[i].rate_high_threshold_kbits_sec)); 3372 LOG_CLI((BSL_META("\tSize threshold = {0x%x, 0x%x} bytes\r\n"), 3373 COMPILER_64_HI(profile_info->profile.promotion_filters[i].size_threshold_bytes), 3374 COMPILER_64_LO(profile_info->profile.promotion_filters[i].size_threshold_bytes))); 3375 } 3376 LOG_CLI((BSL_META("Demotion Filter : \r\n"))); 3377 LOG_CLI((BSL_META("\tFlags = 0x%08x\r\n"), 3378 profile_info->profile.demotion_filter.flags)); 3379 LOG_CLI((BSL_META("\tMonitor Interval = %u usecs\r\n"), 3380 profile_info->profile.demotion_filter.monitor_interval_usecs)); 3381 LOG_CLI((BSL_META("\tRate Low threshold = %u kbps\r\n"), 3382 profile_info->profile.demotion_filter.rate_low_threshold_kbits_sec)); 3383 LOG_CLI((BSL_META("\tRate High threshold = %u kbps\r\n"), 3384 profile_info->profile.demotion_filter.rate_high_threshold_kbits_sec)); 3385 LOG_CLI((BSL_META("\tSize threshold = {0x%x, 0x%x} bytes\r\n"), 3386 COMPILER_64_HI(profile_info->profile.demotion_filter.size_threshold_bytes), 3387 COMPILER_64_LO(profile_info->profile.demotion_filter.size_threshold_bytes))); 3388 3389 } 3390 3391 /* 3392 * Function: 3393 * _bcm_xgs5_ft_elph_profile_list_dump 3394 * Purpose: 3395 * Dump the elephant profile list. 3396 * Parameters: 3397 * unit - (IN) BCM device number 3398 * Returns: 3399 * None 3400 */ 3401 void 3402 _bcm_xgs5_ft_elph_profile_list_dump(int unit) 3403 { 3404 int i; 3405 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 3406 _bcm_int_ft_elph_profile_info_t *profile_int_info = NULL; 3407 3408 if (ft_info->elph_mode != TRUE) { 3409 return; 3410 } 3411 3412 LOG_CLI((BSL_META("Dumping elephant profile Info : \r\n"))); 3413 for (i = BCM_INT_FT_ELPH_PROFILE_START_ID; 3414 i <= BCM_INT_FT_ELPH_PROFILE_END_ID; i++) { 3415 3416 profile_int_info = &(ft_elph_profile_info_list[unit][i]); 3417 if (profile_int_info->id != i) { 3418 continue; 3419 } 3420 _bcm_xgs5_ft_elph_profile_dump(profile_int_info); 3421 } 3422 } 3423 3424 /* 3425 * Function: 3426 * _bcm_esw_flowtracker_dump_stats_learn 3427 * Purpose: 3428 * Dump the learn statistics 3429 * Parameters: 3430 * unit - (IN) BCM device number 3431 * Returns: 3432 * BCM_E_XXX - BCM error code. 3433 */ 3434 void _bcm_xgs5_flowtracker_dump_stats_learn(int unit) 3435 { 3436 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 3437 shr_ft_msg_ctrl_stats_learn_t msg; 3438 char *status[] = SHR_FT_LEARN_PKT_STATUS_NAMES; 3439 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 3440 uint16 buffer_len = 0, reply_len = 0; 3441 int max_status; 3442 int rv; 3443 int i = 0; 3444 3445 if (ft_info == NULL) { 3446 LOG_CLI((BSL_META("Flowtracker not enabled \r\n"))); 3447 return; 3448 } 3449 3450 sal_memset(&msg, 0, sizeof(msg)); 3451 3452 /* Get the statistics from the FW */ 3453 rv = _bcm_xgs5_ft_msg_send_receive(unit, 3454 MOS_MSG_SUBCLASS_FT_STATS_LEARN_GET, 3455 0, 0, 3456 MOS_MSG_SUBCLASS_FT_STATS_LEARN_GET_REPLY, 3457 &reply_len, 3458 SHR_FT_MAX_UC_MSG_TIMEOUT); 3459 3460 if (rv != BCM_E_NONE) { 3461 LOG_CLI((BSL_META("Messaging failure rv=%d\r\n"), rv)); 3462 return; 3463 } 3464 3465 buffer_req = ft_info->dma_buffer; 3466 buffer_ptr = shr_ft_msg_ctrl_stats_learn_get_unpack(buffer_req, &msg); 3467 buffer_len = buffer_ptr - buffer_req; 3468 3469 if (buffer_len != reply_len) { 3470 LOG_CLI((BSL_META("Messaging failure \r\n"))); 3471 return; 3472 } 3473 3474 /* Get the max status, they maybe different depending on SDK, FW version */ 3475 max_status = _BCM_FT_MIN(msg.num_status, SHR_FT_LEARN_PKT_MAX_STATUS); 3476 3477 LOG_CLI((BSL_META(" +------------------------+-------------+--------------------+ \n"))); 3478 LOG_CLI((BSL_META(" | Status | Count | Average (usec) | \n"))); 3479 LOG_CLI((BSL_META(" +------------------------+-------------+--------------------+ \n"))); 3480 for (i = 0; i < max_status; i++) { 3481 LOG_CLI((BSL_META(" | %s | %11u | %18u |\n"), 3482 status[i], msg.count[i], msg.avg_usecs[i])); 3483 LOG_CLI((BSL_META(" +------------------------+-------------+--------------------+ \n"))); 3484 } 3485 LOG_CLI((BSL_META("\n"))); 3486 3487 } 3488 3489 /* 3490 * Function: 3491 * _bcm_esw_flowtracker_dump_stats_export 3492 * Purpose: 3493 * Dump the export statistics 3494 * Parameters: 3495 * unit - (IN) BCM device number 3496 * Returns: 3497 * BCM_E_XXX - BCM error code. 3498 */ 3499 void _bcm_xgs5_flowtracker_dump_stats_export(int unit) 3500 { 3501 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 3502 shr_ft_msg_ctrl_stats_export_t msg; 3503 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 3504 uint16 buffer_len = 0, reply_len = 0; 3505 int rv; 3506 3507 if (ft_info == NULL) { 3508 LOG_CLI((BSL_META("Flowtracker not enabled \r\n"))); 3509 return; 3510 } 3511 3512 sal_memset(&msg, 0, sizeof(msg)); 3513 3514 /* Get the statistics from the FW */ 3515 rv = _bcm_xgs5_ft_msg_send_receive(unit, 3516 MOS_MSG_SUBCLASS_FT_STATS_EXPORT_GET, 3517 0, 0, 3518 MOS_MSG_SUBCLASS_FT_STATS_EXPORT_GET_REPLY, 3519 &reply_len, 3520 SHR_FT_MAX_UC_MSG_TIMEOUT); 3521 3522 if (rv != BCM_E_NONE) { 3523 LOG_CLI((BSL_META("Messaging failure rv=%d\r\n"), rv)); 3524 return; 3525 } 3526 3527 buffer_req = ft_info->dma_buffer; 3528 buffer_ptr = shr_ft_msg_ctrl_stats_export_get_unpack(buffer_req, &msg); 3529 buffer_len = buffer_ptr - buffer_req; 3530 3531 if (buffer_len != reply_len) { 3532 LOG_CLI((BSL_META("Messaging failure \r\n"))); 3533 return; 3534 } 3535 3536 LOG_CLI((BSL_META("Export packets : %u \n"), msg.num_pkts)); 3537 LOG_CLI((BSL_META("Export flows : %u \n"), msg.num_flows)); 3538 LOG_CLI((BSL_META("Export time stamp : %u \n"), msg.ts)); 3539 LOG_CLI((BSL_META("Sequence number : %u \n"), msg.seq_num)); 3540 LOG_CLI((BSL_META("\n"))); 3541 3542 return; 3543 } 3544 3545 /* 3546 * Function: 3547 * _bcm_esw_flowtracker_dump_stats_age 3548 * Purpose: 3549 * Dump the age statistics 3550 * Parameters: 3551 * unit - (IN) BCM device number 3552 * Returns: 3553 * BCM_E_XXX - BCM error code. 3554 */ 3555 void _bcm_xgs5_flowtracker_dump_stats_age(int unit) 3556 { 3557 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 3558 shr_ft_msg_ctrl_stats_age_t msg; 3559 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 3560 uint16 buffer_len = 0, reply_len = 0; 3561 int rv; 3562 3563 if (ft_info == NULL) { 3564 LOG_CLI((BSL_META("Flowtracker not enabled \r\n"))); 3565 return; 3566 } 3567 3568 if (ft_info->elph_mode == TRUE) { 3569 LOG_CLI((BSL_META("Cannot dump age stats in elephant mode \r\n"))); 3570 return; 3571 } 3572 3573 3574 sal_memset(&msg, 0, sizeof(msg)); 3575 3576 /* Get the statistics from the FW */ 3577 rv = _bcm_xgs5_ft_msg_send_receive(unit, 3578 MOS_MSG_SUBCLASS_FT_STATS_AGE_GET, 3579 0, 0, 3580 MOS_MSG_SUBCLASS_FT_STATS_AGE_GET_REPLY, 3581 &reply_len, 3582 SHR_FT_MAX_UC_MSG_TIMEOUT); 3583 3584 if (rv != BCM_E_NONE) { 3585 LOG_CLI((BSL_META("Messaging failure rv=%d\r\n"), rv)); 3586 return; 3587 } 3588 3589 buffer_req = ft_info->dma_buffer; 3590 buffer_ptr = shr_ft_msg_ctrl_stats_age_get_unpack(buffer_req, &msg); 3591 buffer_len = buffer_ptr - buffer_req; 3592 3593 if (buffer_len != reply_len) { 3594 LOG_CLI((BSL_META("Messaging failure \r\n"))); 3595 return; 3596 } 3597 3598 LOG_CLI((BSL_META("Num flows aged : %u \n"), msg.num_flows)); 3599 LOG_CLI((BSL_META("\n"))); 3600 3601 return; 3602 } 3603 3604 /* 3605 * Function: 3606 * _bcm_esw_flowtracker_dump_stats_elephant 3607 * Purpose: 3608 * Dump the elephant statistics 3609 * Parameters: 3610 * unit - (IN) BCM device number 3611 * Returns: 3612 * BCM_E_XXX - BCM error code. 3613 */ 3614 void _bcm_xgs5_flowtracker_dump_stats_elephant(int unit) 3615 { 3616 3617 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 3618 shr_ft_msg_ctrl_stats_elph_t msg; 3619 uint8 *buffer_req = NULL, *buffer_ptr = NULL; 3620 uint16 buffer_len = 0, reply_len = 0; 3621 char *states[SHR_FT_ELPH_FLOW_STATE_COUNT] = SHR_FT_ELPH_STATES; 3622 int num_states, num_actions; 3623 int i, j; 3624 int rv; 3625 3626 if (ft_info == NULL) { 3627 LOG_CLI((BSL_META("Flowtracker not enabled \r\n"))); 3628 return; 3629 } 3630 3631 if (ft_info->elph_mode != TRUE) { 3632 LOG_CLI((BSL_META("Not in elephant mode \r\n"))); 3633 return; 3634 } 3635 3636 3637 sal_memset(&msg, 0, sizeof(msg)); 3638 3639 /* Get the statistics from the FW */ 3640 rv = _bcm_xgs5_ft_msg_send_receive(unit, 3641 MOS_MSG_SUBCLASS_FT_STATS_ELPH_GET, 3642 0, 0, 3643 MOS_MSG_SUBCLASS_FT_STATS_ELPH_GET_REPLY, 3644 &reply_len, 3645 SHR_FT_MAX_UC_MSG_TIMEOUT); 3646 3647 if (rv != BCM_E_NONE) { 3648 LOG_CLI((BSL_META("Messaging failure rv=%d\r\n"), rv)); 3649 return; 3650 } 3651 3652 buffer_req = ft_info->dma_buffer; 3653 buffer_ptr = shr_ft_msg_ctrl_stats_elph_get_unpack(buffer_req, &msg); 3654 buffer_len = buffer_ptr - buffer_req; 3655 3656 if (buffer_len != reply_len) { 3657 LOG_CLI((BSL_META("Messaging failure \r\n"))); 3658 return; 3659 } 3660 3661 /* Take the minimum value to avoid any version difference issues */ 3662 num_states = _BCM_FT_MIN(msg.num_states, SHR_FT_ELPH_FLOW_STATE_COUNT); 3663 num_actions = _BCM_FT_MIN(msg.num_actions, SHR_FT_ELPH_ACTION_COUNT); 3664 3665 LOG_CLI((BSL_META(" +-------------------+------------+------------+------------+ \n"))); 3666 LOG_CLI((BSL_META(" | | None | Promote | Demote | \n"))); 3667 LOG_CLI((BSL_META(" +-------------------+------------+------------+------------+ \n"))); 3668 for (i = 0; i < num_states; i++) { 3669 LOG_CLI((BSL_META(" | %10s |"), states[i])); 3670 for (j = 0; j < num_actions; j++) { 3671 LOG_CLI((BSL_META(" %10u |"), msg.trans_count[i][j])); 3672 } 3673 LOG_CLI((BSL_META("\n"))); 3674 LOG_CLI((BSL_META(" +-------------------+------------+------------+------------+ \n"))); 3675 } 3676 LOG_CLI((BSL_META("\n"))); 3677 3678 return; 3679 } 3680 3681 3682 /* Dump routine for dumping flow group list, 3683 * collector list and template list. 3684 */ 3685 void _bcm_xgs5_flowtracker_sw_dump(int unit) 3686 { 3687 _bcm_int_ft_info_t *ft_info = FT_INFO_GET(unit); 3688 3689 if (ft_info == NULL) { 3690 return; 3691 } 3692 3693 _bcm_xgs5_ft_flow_group_list_dump(unit); 3694 _bcm_xgs5_ft_collector_list_dump(unit); 3695 _bcm_xgs5_ft_template_list_dump(unit); 3696 _bcm_xgs5_ft_elph_profile_list_dump(unit); 3697 _bcm_xgs5_flowtracker_dump_stats_learn(unit); 3698 _bcm_xgs5_flowtracker_dump_stats_export(unit); 3699 if (ft_info->elph_mode == TRUE) { 3700 _bcm_xgs5_flowtracker_dump_stats_elephant(unit); 3701 } else { 3702 _bcm_xgs5_flowtracker_dump_stats_age(unit); 3703 } 3704 } 3705 3706 #else /* INCLUDE_FLOWTRACKER */ 3707 int _bcm_xgs5_flowtracker_not_empty; 3708 #endif /* INCLUDE_FLOWTRACKER */