ifa.c (23923B)
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 * IFA - In-band Flow Analyzer Monitoring Embedded Application APP interface 8 * Purpose: API to configure IFA embedded app interface. 9 */ 10 11 #if defined(INCLUDE_IFA) 12 13 #include <shared/bsl.h> 14 #include <soc/defs.h> 15 #include <soc/drv.h> 16 #include <soc/trident3.h> 17 #include <shared/alloc.h> 18 #include <shared/idxres_fl.h> 19 20 #include <bcm/module.h> 21 #include <bcm/types.h> 22 #include <bcm/error.h> 23 24 #include <bcm_int/esw/trident3.h> 25 #include <bcm_int/esw/xgs5.h> 26 #include <bcm_int/esw/switch.h> 27 #include <bcm_int/esw/ifa_feature.h> 28 #include <bcm_int/esw/ifa.h> 29 #include <bcm_int/esw_dispatch.h> 30 31 /* In-band Flow Analyzer global information */ 32 _bcm_int_ifa_info_t *ifa_global_info[BCM_MAX_NUM_UNITS] = {0}; 33 34 #ifdef BCM_WARM_BOOT_SUPPORT 35 STATIC int _bcm_td3_ifa_scache_alloc(int unit, int create); 36 STATIC int _bcm_td3_ifa_wb_recover(int unit); 37 #endif /* BCM_WARM_BOOT_SUPPORT */ 38 39 /* Initialize the IFA app. */ 40 int _bcm_td3_ifa_init(int unit) 41 { 42 /* Init the embedded app */ 43 int rv = BCM_E_NONE; 44 _bcm_int_ifa_info_t *ifa_info = IFA_INFO_GET(unit); 45 46 int ifa_enable = 0; 47 ifa_enable = soc_property_get(unit, spn_IFA_ENABLE, 0); 48 49 if (!ifa_enable) { 50 /* Silently return since ifa is not enabled */ 51 return BCM_E_NONE; 52 } 53 54 if (ifa_info != NULL) { 55 BCM_IF_ERROR_RETURN(_bcm_td3_ifa_detach(unit)); 56 ifa_info = NULL; 57 } 58 59 _BCM_IFA_ALLOC(ifa_info, _bcm_int_ifa_info_t, 60 sizeof(_bcm_int_ifa_info_t), "IFA INFO"); 61 if (ifa_info == NULL) { 62 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 63 "IFA: Failed to allocate memory"))); 64 return BCM_E_MEMORY; 65 } 66 ifa_global_info[unit] = ifa_info; 67 68 #ifdef BCM_WARM_BOOT_SUPPORT 69 if (SOC_WARM_BOOT(unit)) { 70 rv = _bcm_td3_ifa_wb_recover(unit); 71 if (!(ifa_info->status)) { 72 sal_free(ifa_info); 73 ifa_global_info[unit] = NULL; 74 return BCM_E_NONE; 75 } 76 } else { 77 rv = _bcm_td3_ifa_scache_alloc(unit, 1); 78 } 79 #endif /* BCM_WARM_BOOT_SUPPORT */ 80 81 /* 82 * Allocate DMA buffer 83 * 84 * DMA buffer will be used to send and receive 'long' messages 85 * between SDK Host and uController (BTE). 86 */ 87 ifa_info->dma_buffer_len = sizeof(shr_ifa_msg_ctrl_t); 88 ifa_info->dma_buffer = soc_cm_salloc(unit, ifa_info->dma_buffer_len, 89 "IFA DMA buffer allocate"); 90 if (!ifa_info->dma_buffer) { 91 BCM_IF_ERROR_RETURN(bcm_xgs5_ifa_eapp_detach(unit)); 92 return BCM_E_MEMORY; 93 } 94 sal_memset(ifa_info->dma_buffer, 0, ifa_info->dma_buffer_len); 95 96 rv = bcm_xgs5_ifa_eapp_init(unit); 97 return rv; 98 } 99 100 /* Shut down the IFA app. */ 101 int _bcm_td3_ifa_detach(int unit) 102 { 103 /* De-init the embedded app */ 104 int rv = BCM_E_NONE; 105 _bcm_int_ifa_info_t *ifa_info = IFA_INFO_GET(unit); 106 107 if (ifa_info == NULL) { 108 return BCM_E_NONE; 109 } 110 111 rv = bcm_xgs5_ifa_eapp_detach(unit); 112 if (BCM_FAILURE(rv)) { 113 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 114 "IFA: Failed to Detach"))); 115 return rv; 116 } 117 118 sal_free(ifa_info); 119 ifa_global_info[unit] = NULL; 120 121 return rv; 122 } 123 124 /* 125 * Function: 126 * _bcm_td3_ifa_collector_info_validate 127 * Purpose: 128 * Validate the collector params 129 * Parameters: 130 * unit - (IN) BCM device number 131 * collector - (IN) Collector data structure 132 * Returns: 133 * BCM_E_XXX - BCM error code. 134 */ 135 STATIC int 136 _bcm_td3_ifa_collector_info_validate(int unit, 137 bcm_ifa_collector_info_t *collector) 138 { 139 140 /* Only IPv4 over UDP is supported */ 141 if ((collector->transport_type != bcmIfaCollectorTransportTypeIpv4Udp) && 142 (collector->transport_type != bcmIfaCollectorTransportTypeIpv6Udp)) { 143 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 144 "IFA: Invalid Collector Transport Type"))); 145 return BCM_E_UNAVAIL; 146 } 147 148 /* Validate the export length */ 149 if (collector->mtu < BCM_IFA_MIN_COLLECTOR_ENCAP_LENGTH || 150 collector->mtu > SHR_IFA_MAX_COLLECTOR_ENCAP_LENGTH) { 151 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 152 "IFA: Invalid Collector Encap length configuration"))); 153 return BCM_E_PARAM; 154 } 155 156 return BCM_E_NONE; 157 } 158 159 /* 160 * Function: 161 * _bcm_td3_ifa_collector_set 162 * Purpose: 163 * Create a ifa collector with given collector info. 164 * Parameters: 165 * unit - (IN) BCM device number 166 * options - (IN) Collector modify options 167 * collector_info - (IN) Collector info 168 * Returns: 169 * BCM_E_XXX - BCM error code. 170 */ 171 int _bcm_td3_ifa_collector_set(int unit, 172 uint32 options, 173 bcm_ifa_collector_info_t *collector_info) 174 { 175 int rv = BCM_E_NONE; 176 bcm_ifa_collector_info_t old_collector_int_info; 177 _bcm_int_ifa_info_t *ifa_info = IFA_INFO_GET(unit); 178 179 if (ifa_info == NULL) { 180 return BCM_E_INIT; 181 } 182 183 if (options & BCM_IFA_COLLECTOR_DETACH) { 184 /* Detach the collector. */ 185 sal_memset(collector_info, 0, sizeof(bcm_ifa_collector_info_t)); 186 187 /* Inform IFA EAPP to detach collector */ 188 rv = bcm_xgs5_ifa_eapp_collector_set_msg(unit, 189 collector_info); 190 if (BCM_FAILURE(rv)) { 191 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 192 "IFA: collector detach uc message communication failed\n"))); 193 return rv; 194 } 195 return BCM_E_NONE; 196 } 197 198 /* 199 * Also verify that a collector with such an ID 200 * exists, else return BCM_E_NOT_FOUND 201 */ 202 if ((options & BCM_IFA_COLLECTOR_MODIFY) && 203 !(options & BCM_IFA_COLLECTOR_ADD)) { 204 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 205 "IFA: Invalid options set both ADD and MODIFY\n"))); 206 return BCM_E_PARAM; 207 } 208 209 /* Validate collector_info for any unsupported encap or 210 * export length etc. 211 */ 212 rv = _bcm_td3_ifa_collector_info_validate(unit, collector_info); 213 if (BCM_FAILURE(rv)) { 214 return rv; 215 } 216 217 if ((options & BCM_IFA_COLLECTOR_ADD) && 218 (options & BCM_IFA_COLLECTOR_MODIFY)) { 219 sal_memset(&old_collector_int_info, 0, sizeof(old_collector_int_info)); 220 rv = bcm_xgs5_ifa_collector_get(unit, 221 &old_collector_int_info); 222 if (BCM_FAILURE(rv)) { 223 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 224 "IFA: Collector get failed\n"))); 225 return rv; 226 } 227 } 228 229 /* ADD and Modify */ 230 if ((options & BCM_IFA_COLLECTOR_ADD) && 231 (options & BCM_IFA_COLLECTOR_MODIFY)) { 232 /* Modify the collector info in the list with ID. */ 233 rv = bcm_xgs5_ifa_collector_modify(unit, 234 collector_info); 235 } else { 236 rv = bcm_xgs5_ifa_collector_set(unit, 237 collector_info); 238 } 239 if (BCM_FAILURE(rv)) { 240 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 241 "IFA: collector set functionality failed \n"))); 242 return rv; 243 } 244 245 /* Inform IFA EAPP of the change/addition in/of collector information */ 246 rv = bcm_xgs5_ifa_eapp_collector_set_msg(unit, 247 collector_info); 248 if (BCM_FAILURE(rv)) { 249 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 250 "IFA: Collector set uc message communication failed\n"))); 251 return rv; 252 } 253 254 return BCM_E_NONE; 255 } 256 257 /* 258 * Function: 259 * _bcm_td3_ifa_collector_get 260 * Purpose: 261 * Get ifa collector information 262 * Parameters: 263 * unit - (IN) BCM device number 264 * collector_info - (OUT) Collector info 265 * Returns: 266 * BCM_E_XXX - BCM error code. 267 */ 268 int _bcm_td3_ifa_collector_get(int unit, 269 bcm_ifa_collector_info_t *collector_info) 270 { 271 int rv = BCM_E_NONE; 272 _bcm_int_ifa_info_t *ifa_info = IFA_INFO_GET(unit); 273 274 if (ifa_info == NULL) { 275 return BCM_E_INIT; 276 } 277 278 /* Ensure collector_info is not NULL */ 279 if (collector_info == NULL) { 280 return BCM_E_PARAM; 281 } 282 283 /* Get the collector info */ 284 rv = bcm_xgs5_ifa_collector_get(unit, collector_info); 285 return rv; 286 } 287 288 /* 289 * Function: 290 * _bcm_td3_ifa_config_set 291 * Purpose: 292 * Create a ifa collector with given collector info. 293 * Parameters: 294 * unit - (IN) BCM device number 295 * options - (IN) Configuration information modify options 296 * config_info - (IN) Configuration information 297 * Returns: 298 * BCM_E_XXX - BCM error code. 299 */ 300 int _bcm_td3_ifa_config_set(int unit, 301 uint32 options, 302 bcm_ifa_config_info_t *config_info) 303 { 304 int rv = BCM_E_NONE, reg_value; 305 uint16 max_len; 306 bcm_ifa_config_info_t old_config_info; 307 _bcm_int_ifa_info_t *ifa_info = IFA_INFO_GET(unit); 308 309 if (ifa_info == NULL) { 310 return BCM_E_INIT; 311 } 312 313 if (options & BCM_IFA_CONFIG_CLEAR) { 314 /* Clear the configuration info. */ 315 sal_memset(config_info, 0, sizeof(bcm_ifa_config_info_t)); 316 317 /* Inform IFA EAPP of the reset configuration information */ 318 rv = bcm_xgs5_ifa_eapp_config_info_msg(unit, config_info); 319 if (BCM_FAILURE(rv)) { 320 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 321 "IFA config clear uc message communication failed \n"))); 322 return rv; 323 } 324 return BCM_E_NONE; 325 } 326 327 if (config_info->hop_limit < 1) { 328 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 329 "IFA: Invalid Hoplimit: %d\n"), config_info->hop_limit)); 330 return BCM_E_PARAM; 331 } 332 333 if (config_info->max_payload_length < BCM_IFA_METADATA_HEADER_LENGTH) { 334 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 335 "IFA: Invalid max payload len: %d\n"), config_info->max_payload_length)); 336 return BCM_E_PARAM; 337 } 338 339 max_len = (config_info->hop_limit * BCM_IFA_METADATA_HEADER_LENGTH); 340 if (config_info->max_payload_length < max_len) { 341 max_len = config_info->max_payload_length; 342 } 343 max_len += BCM_IFA_MIN_RX_PACKET_LENGTH; 344 max_len += config_info->rx_packet_payload_length; 345 346 if (max_len > BCM_IFA_MAX_RX_PACKET_LENGTH) { 347 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 348 "IFA: support maximum rx packet length %d\n"), 349 BCM_IFA_MAX_RX_PACKET_LENGTH)); 350 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 351 "IFA: Hoplimit: %d max payload len: %d rx packet payload len: %d\n"), 352 config_info->hop_limit, config_info->max_payload_length, 353 config_info->rx_packet_payload_length)); 354 return BCM_E_PARAM; 355 } 356 357 #if defined(BCM_TRIDENT3_SUPPORT) 358 if (SOC_IS_TRIDENT3(unit)) { 359 if (((config_info->lb_port_1 > 66) && (config_info->lb_port_2 > 66)) || 360 ((config_info->lb_port_1 < 65) && (config_info->lb_port_2 < 65))) { 361 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 362 "IFA App should have one loopback port per Pipe\n"))); 363 return BCM_E_PARAM; 364 } 365 } 366 #endif /* BCM_TRIDENT3_SUPPORT */ 367 368 #if defined(BCM_MAVERICK2_SUPPORT) 369 if (SOC_IS_MAVERICK2(unit)) { 370 if (((config_info->lb_port_1 > 62) && (config_info->lb_port_2 > 62))) { 371 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 372 "IFA App should have one loopback port per Pipe\n"))); 373 return BCM_E_PARAM; 374 } 375 } 376 #endif /* BCM_MAVERICK2_SUPPORT */ 377 378 /* CANCUN INT header fields validation */ 379 BCM_IF_ERROR_RETURN(bcm_esw_switch_control_get(unit, 380 bcmSwitchIntMaxPayloadLength, ®_value)); 381 if (reg_value != config_info->max_payload_length) { 382 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 383 "INT HDR Maximum payload length field mismatch\n" \ 384 "Set bcmSwitchIntMaxPayloadLength to %d current value: %d\n"), 385 config_info->max_payload_length, reg_value)); 386 return BCM_E_PARAM; 387 } 388 389 BCM_IF_ERROR_RETURN(bcm_esw_switch_control_get(unit, 390 bcmSwitchIntProbeMarker1, ®_value)); 391 if (reg_value != config_info->probemarker_1) { 392 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 393 "INT HDR ProbeMarker1 field mismatch\n" \ 394 "Set bcmSwitchIntProbeMarker1 to %d current value: %d\n"), 395 config_info->probemarker_1, reg_value)); 396 return BCM_E_PARAM; 397 } 398 399 BCM_IF_ERROR_RETURN(bcm_esw_switch_control_get(unit, 400 bcmSwitchIntProbeMarker2, ®_value)); 401 if (reg_value != config_info->probemarker_2) { 402 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 403 "INT HDR ProbeMarker2 field mismatch\n" \ 404 "Set bcmSwitchIntProbeMarker2 to %d current value: %d\n"), 405 config_info->probemarker_2, reg_value)); 406 return BCM_E_PARAM; 407 } 408 409 BCM_IF_ERROR_RETURN(bcm_esw_switch_control_get(unit, 410 bcmSwitchIntL4DestPortEnable, ®_value)); 411 if (reg_value) { 412 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 413 "Disable UDP dst port based INT packet parse\n"))); 414 return BCM_E_PARAM; 415 } 416 417 BCM_IF_ERROR_RETURN(bcm_esw_switch_control_get(unit, 418 bcmSwitchIntProbeMarkerEnable, ®_value)); 419 if (!reg_value) { 420 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 421 "Enable prober_marker(UDF) based INT packet parse\n"))); 422 return BCM_E_PARAM; 423 } 424 425 /* 426 * Also verify that a collector with such an ID 427 * exists, else return BCM_E_NOT_FOUND 428 */ 429 if ((options & BCM_IFA_CONFIG_MODIFY) && 430 !(options & BCM_IFA_CONFIG_ADD)) { 431 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 432 "IFA: Invalid options set both ADD and MODIFY\n"))); 433 return BCM_E_PARAM; 434 } 435 436 if ((options & BCM_IFA_CONFIG_ADD) && 437 (options & BCM_IFA_CONFIG_MODIFY)) { 438 sal_memset(&old_config_info, 0, sizeof(old_config_info)); 439 rv = bcm_xgs5_ifa_config_get(unit, 440 &old_config_info); 441 if (BCM_FAILURE(rv)) { 442 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 443 "IFA: Configuration get failed\n"))); 444 return rv; 445 } 446 } 447 448 /* ADD and Modify. */ 449 if ((options & BCM_IFA_CONFIG_ADD) && 450 (options & BCM_IFA_CONFIG_MODIFY)) { 451 /* Modify the configuration info in the list with ID. */ 452 rv = bcm_xgs5_ifa_config_modify(unit, 453 config_info); 454 if (BCM_FAILURE(rv)) { 455 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 456 "IFA: Modify config set functionality failed \n"))); 457 return rv; 458 } 459 } else { 460 rv = bcm_xgs5_ifa_config_set(unit, 461 config_info); 462 if (BCM_FAILURE(rv)) { 463 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 464 "IFA: Add config set functionality failed \n"))); 465 return rv; 466 } 467 } 468 469 /* Inform IFA EAPP of the change/addition in/of configuration information */ 470 rv = bcm_xgs5_ifa_eapp_config_info_msg(unit, config_info); 471 if (BCM_FAILURE(rv)) { 472 LOG_ERROR(BSL_LS_BCM_IFA, (BSL_META_U(unit, 473 "IFA App Config set uc message communication failed \n"))); 474 return rv; 475 } 476 477 return BCM_E_NONE; 478 } 479 480 /* 481 * Function: 482 * _bcm_td3_ifa_config_get 483 * Purpose: 484 * Get ifa configuration information 485 * Parameters: 486 * unit - (IN) BCM device number 487 * config_info - (OUT) Configuration information info 488 * Returns: 489 * BCM_E_XXX - BCM error code. 490 */ 491 int _bcm_td3_ifa_config_get(int unit, 492 bcm_ifa_config_info_t *config_info) 493 { 494 int rv = BCM_E_NONE; 495 _bcm_int_ifa_info_t *ifa_info = IFA_INFO_GET(unit); 496 497 if (ifa_info == NULL) { 498 return BCM_E_INIT; 499 } 500 501 /* Ensure collector_info is not NULL */ 502 if (config_info == NULL) { 503 return BCM_E_PARAM; 504 } 505 506 /* Get the collector info */ 507 rv = bcm_xgs5_ifa_config_get(unit, config_info); 508 return rv; 509 } 510 511 /* 512 * Function: 513 * _bcm_td3_ifa_stat_get 514 * Purpose: 515 * Get ifa statistics information data 516 * Parameters: 517 * unit - (IN) BCM device number 518 * stat_data - (OUT) Statistics information data 519 * Returns: 520 * BCM_E_XXX - BCM error code. 521 */ 522 int _bcm_td3_ifa_stat_get(int unit, 523 bcm_ifa_stat_info_t *stat_data) 524 { 525 int rv = BCM_E_NONE; 526 _bcm_int_ifa_info_t *ifa_info = IFA_INFO_GET(unit); 527 528 if (ifa_info == NULL) { 529 return BCM_E_INIT; 530 } 531 532 /* Ensure stat_data is not NULL */ 533 if (stat_data == NULL) { 534 return BCM_E_PARAM; 535 } 536 537 /* Get the Stat info */ 538 rv = bcm_xgs5_ifa_eapp_stat_info_get_msg(unit, stat_data); 539 return rv; 540 } 541 542 /* 543 * Function: 544 * _bcm_td3_ifa_stat_set 545 * Purpose: 546 * Get ifa statistics information data 547 * Parameters: 548 * unit - (IN) BCM device number 549 * stat_data - (OUT) Statistics information data 550 * Returns: 551 * BCM_E_XXX - BCM error code. 552 */ 553 int _bcm_td3_ifa_stat_set(int unit, 554 bcm_ifa_stat_info_t *stat_data) 555 { 556 int rv = BCM_E_NONE; 557 _bcm_int_ifa_info_t *ifa_info = IFA_INFO_GET(unit); 558 559 if (ifa_info == NULL) { 560 return BCM_E_INIT; 561 } 562 563 /* Ensure stat_data is not NULL */ 564 if (stat_data == NULL) { 565 return BCM_E_PARAM; 566 } 567 568 /* Set the Stat info */ 569 rv = bcm_xgs5_ifa_eapp_stat_info_set_msg(unit, stat_data); 570 return rv; 571 } 572 573 #ifdef BCM_WARM_BOOT_SUPPORT 574 575 #define BCM_WB_IFA_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 576 #define BCM_WB_IFA_DEFAULT_VERSION BCM_WB_IFA_VERSION_1_0 577 578 #define IFA_SCACHE_WRITE(_scache, _val, _type) \ 579 do { \ 580 _type _tmp = (_type) (_val); \ 581 sal_memcpy((_scache), &(_tmp), sizeof(_type)); \ 582 (_scache) += sizeof(_type); \ 583 } while(0) 584 585 #define IFA_SCACHE_READ(_scache, _var, _type) \ 586 do { \ 587 _type _tmp; \ 588 sal_memcpy(&(_tmp), (_scache), sizeof(_type)); \ 589 (_scache) += sizeof(_type); \ 590 (_var) = (_tmp); \ 591 } while(0) 592 593 /* 594 * Function: 595 * _bcm_td3_ifa_scache_v0_size_get 596 * Purpose: 597 * Get the size required to sync IFA data to scache v0 598 * Parameters: 599 * unit - (IN) Device unit number 600 * Returns: 601 * Required size 602 */ 603 STATIC uint32 604 _bcm_td3_ifa_scache_v0_size_get(int unit) 605 { 606 uint32 size = 0; 607 608 /* IFA status */ 609 size += sizeof(uint32); 610 611 return size; 612 } 613 614 /* 615 * Function: 616 * _bcm_td3_ifa_scache_v0_sync 617 * Purpose: 618 * Sync IFA data to scache v0 619 * Parameters: 620 * unit - (IN) Device unit number 621 * scache - (IN) Pointer to current scache location 622 * Returns: 623 * BCM_E_XXX 624 */ 625 STATIC void 626 _bcm_td3_ifa_scache_v0_sync(int unit, uint8 **scache) 627 { 628 _bcm_int_ifa_info_t *ifa_info = IFA_INFO_GET(unit); 629 630 if (ifa_info == NULL) { 631 IFA_SCACHE_WRITE(*scache, 0, uint32); 632 return; 633 } 634 635 /* IFA status */ 636 IFA_SCACHE_WRITE(*scache, ifa_info->status, uint32); 637 } 638 639 /* 640 * Function: 641 * _bcm_td3_ifa_scache_v0_recover 642 * Purpose: 643 * Recover IFA data from scache v0 644 * Parameters: 645 * unit - (IN) Device unit number 646 * scache - (IN) Pointer to current scache location 647 * Returns: 648 * BCM_E_XXX 649 */ 650 STATIC int 651 _bcm_td3_ifa_scache_v0_recover(int unit, uint8 **scache) 652 { 653 _bcm_int_ifa_info_t *ifa_info = IFA_INFO_GET(unit); 654 655 /* IFA status */ 656 IFA_SCACHE_READ(*scache, ifa_info->status, uint32); 657 658 return BCM_E_NONE; 659 } 660 661 /* 662 * Function: 663 * _bcm_td3_ifa_scache_alloc 664 * Purpose: 665 * IFA WB scache alloc 666 * Parameters: 667 * unit - (IN) Unit number. 668 * create - (IN) 1 - Create, 0 - Realloc 669 * Returns: 670 * BCM_E_XXX 671 * Notes: 672 */ 673 STATIC int _bcm_td3_ifa_scache_alloc(int unit, int create) 674 { 675 uint32 cur_size = 0; 676 uint32 rqd_size = 0; 677 int rv = BCM_E_NONE; 678 soc_scache_handle_t scache_handle; 679 uint8 *scache = NULL; 680 681 rqd_size += _bcm_td3_ifa_scache_v0_size_get(unit); 682 683 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_IFA, 0); 684 685 if (create) { 686 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, 1, rqd_size, 687 &scache, BCM_WB_IFA_DEFAULT_VERSION, NULL); 688 BCM_IF_ERROR_RETURN(rv); 689 } else { 690 /* Get current size */ 691 rv = soc_scache_ptr_get(unit, scache_handle, &scache, &cur_size); 692 SOC_IF_ERROR_RETURN(rv); 693 694 if (rqd_size > cur_size) { 695 /* Request the extra size */ 696 rv = soc_scache_realloc(unit, scache_handle, rqd_size - cur_size); 697 SOC_IF_ERROR_RETURN(rv); 698 } 699 } 700 701 return BCM_E_NONE; 702 } 703 704 /* 705 * Function: 706 * _bcm_td3_ifa_sync 707 * Purpose: 708 * Warmboot scache sync 709 * Parameters: 710 * unit - (IN) Unit number. 711 * Returns: 712 * BCM_E_XXX 713 * Notes: 714 */ 715 int _bcm_td3_ifa_sync(int unit) 716 { 717 int stable_size; 718 soc_scache_handle_t scache_handle; 719 uint8 *scache = NULL; 720 721 /* Get IFA module storage size. */ 722 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 723 724 /* If level 2 store is not configured return from here. */ 725 if (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) || (stable_size == 0)) { 726 return BCM_E_NONE; 727 } 728 729 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_IFA, 0); 730 BCM_IF_ERROR_RETURN(_bcm_esw_scache_ptr_get(unit, scache_handle, 0, 0, 731 &scache, 0, NULL)); 732 if (NULL == scache) { 733 return BCM_E_INTERNAL; 734 } 735 736 /* Sync IFA scache v0 */ 737 _bcm_td3_ifa_scache_v0_sync(unit, &scache); 738 739 return BCM_E_NONE; 740 } 741 742 /* 743 * Function: 744 * _bcm_td3_ifa_wb_recover 745 * Purpose: 746 * IFA WB recovery 747 * Parameters: 748 * unit - (IN) Unit number. 749 * Returns: 750 * BCM_E_XXX 751 * Notes: 752 */ 753 STATIC int _bcm_td3_ifa_wb_recover(int unit) 754 { 755 int stable_size; /* Secondary storage size. */ 756 uint8 *scache = NULL; 757 soc_scache_handle_t scache_handle; 758 int rv = BCM_E_NONE; 759 uint16 recovered_ver = 0; 760 761 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 762 763 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 764 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_IFA, 0); 765 766 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, 0, 0, 767 &scache, BCM_WB_IFA_DEFAULT_VERSION, 768 &recovered_ver); 769 if (BCM_E_NOT_FOUND == rv) { 770 /* Upgrading from SDK release that does not have warmboot state */ 771 rv = _bcm_td3_ifa_scache_alloc(unit, 1); 772 return rv; 773 } else if (BCM_FAILURE(rv)) { 774 return rv; 775 } 776 777 if (NULL == scache) { 778 return BCM_E_NOT_FOUND; 779 } 780 } else { 781 return BCM_E_NONE; 782 } 783 784 /* Scache recovery */ 785 BCM_IF_ERROR_RETURN(_bcm_td3_ifa_scache_v0_recover(unit, &scache)); 786 787 /* Realloc any extra scache that may be needed */ 788 BCM_IF_ERROR_RETURN(_bcm_td3_ifa_scache_alloc(unit, 0)); 789 790 return rv; 791 } 792 #endif /* BCM_WARM_BOOT_SUPPORT */ 793 794 #else 795 typedef int bcm_make_iso_compilers_happy; 796 #endif /* INCLUDE_IFA */