openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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 */