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

switch_match.c (46774B)


      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 
      8 #include <shared/bsl.h>
      9 #include <soc/debug.h>
     10 #include <soc/drv.h>
     11 #include <soc/scache.h>
     12 #include <soc/mem.h>
     13 #include <bcm/switch.h>
     14 #include <bcm/error.h>
     15 #include <bcm_int/esw/trx.h>
     16 #include <bcm_int/esw/switch.h>
     17 #include <bcm_int/esw/switch_match.h>
     18 #include <bcm_int/esw/hurricane3.h>
     19 #include <bcm_int/esw/greyhound2.h>
     20 
     21 #if defined(BCM_SWITCH_MATCH_SUPPORT)
     22 
     23 /*
     24  * Switch Match id encoding:
     25  * 4-bit bcm_switch_match_service_t (+encoding base) + 12-bit (reserved)
     26  * + 16-bit sw_idx
     27  */
     28 #define BCMI_MATCH_TYPE_ENCODING_BASE    (1)
     29 #define BCMI_MATCH_TYPE_SHIFT            (28)
     30 #define BCMI_MATCH_TYPE_MASK             (0xF)
     31 #define BCMI_MATCH_SW_IDX_MASK           (0xFFFF)
     32 
     33 /*
     34  * Translate between Match_ID and sw_idx & Switch Match Type
     35  * It represents the entry is used or not in intf_bitmap[match_service]
     36  * with the MARCO MATCH_INTF_GET/SET/CLR
     37  * Note:
     38  * The sw_idx is not the hardware index of register/memory.
     39  * There is a hw_idx which is mapping in the chip specific layer
     40  * which is a real HW index
     41  */
     42 #define MATCH_ID_TO_SW_IDX(_match_id_) \
     43         ((_match_id_) & BCMI_MATCH_SW_IDX_MASK)
     44 
     45 #define SW_IDX_TO_MATCH_ID(_sw_idx_, _service_type_) \
     46         ((_sw_idx_) | \
     47         (_service_type_ + BCMI_MATCH_TYPE_ENCODING_BASE) << BCMI_MATCH_TYPE_SHIFT)
     48 
     49 #define MATCH_TYPE_GET(_id_) \
     50         ((((_id_) >> BCMI_MATCH_TYPE_SHIFT) & BCMI_MATCH_TYPE_MASK) \
     51          - BCMI_MATCH_TYPE_ENCODING_BASE)
     52 
     53 #define MATCH_ID_IS_TYPE(_id_, _service_type_) \
     54         (MATCH_TYPE_GET(_id_) == (_service_type_))
     55 
     56 /*
     57  * Software book keeping for Switch Match related information
     58  */
     59 typedef struct bcmi_match_bk_s {
     60     SHR_BITDCL  *intf_bitmap[bcmSwitchMatchService__Count];
     61     sal_mutex_t match_mutex;
     62     int initialized;
     63     /* Switch match service platform-specific information */
     64     const bcmi_switch_match_dev_info_t *dev_info;
     65 } bcmi_match_bk_t;
     66 
     67 STATIC bcmi_match_bk_t bcmi_match_bk_info[BCM_MAX_NUM_UNITS];
     68 
     69 /* Flag to check first initialized status */
     70 STATIC uint8 bcmi_match_initialized_bool = FALSE;
     71 
     72 /* Switch match SW book keeping instance fetch/lock/unlock */
     73 #define MATCH_BK_INFO(_u_) (&bcmi_match_bk_info[(_u_)])
     74 
     75 #define MATCH_LOCK(_u_) \
     76         sal_mutex_take(MATCH_BK_INFO(_u_)->match_mutex, sal_mutex_FOREVER)
     77 
     78 #define MATCH_UNLOCK(_u_) \
     79         sal_mutex_give(MATCH_BK_INFO(_u_)->match_mutex)
     80 
     81 /*
     82  * Switch match usage bitmap operations
     83  */
     84 #define MATCH_INTF_GET(_u_, _intf_, _service_) \
     85         (SHR_BITGET(MATCH_BK_INFO(_u_)->intf_bitmap[(_service_)], (_intf_)))
     86 #define MATCH_INTF_SET(_u_, _intf_, _service_) \
     87         (SHR_BITSET(MATCH_BK_INFO(_u_)->intf_bitmap[(_service_)], (_intf_)))
     88 #define MATCH_INTF_CLR(_u_, _intf_, _service_) \
     89         (SHR_BITCLR(MATCH_BK_INFO(_u_)->intf_bitmap[(_service_)], (_intf_)))
     90 
     91 #define MATCH_DEVICE_INFO(_u_, _service_) \
     92         bcmi_match_bk_info[(_u_)].dev_info->service_info[(_service_)]
     93 
     94 #define MATCH_CHECK_INIT(_u_, _service_)                                      \
     95     do {                                                                      \
     96         if (((_u_) < 0) || ((_u_) >= BCM_MAX_NUM_UNITS)) {                    \
     97             return BCM_E_UNIT;                                                \
     98         }                                                                     \
     99         if (!soc_feature(unit, soc_feature_switch_match)) {                   \
    100             return BCM_E_UNAVAIL;                                             \
    101         }                                                                     \
    102         if (!bcmi_match_bk_info[(_u_)].initialized) {                         \
    103             LOG_ERROR(BSL_LS_BCM_SWITCH,                                      \
    104                       (BSL_META_U(unit,                                       \
    105                                   "Switch Match Error:"                       \
    106                                   " not initialized\n")));                    \
    107             return BCM_E_INIT;                                                \
    108         }                                                                     \
    109         if (!bcmi_match_bk_info[(_u_)].dev_info ||                            \
    110             !bcmi_match_bk_info[(_u_)].dev_info->service_info[(_service_)]) { \
    111             LOG_ERROR(BSL_LS_BCM_SWITCH,                                      \
    112                       (BSL_META_U(unit,                                       \
    113                                   "Switch Match Error:"                       \
    114                                   " not supported\n")));                      \
    115             return BCM_E_UNAVAIL;                                             \
    116         }                                                                     \
    117     } while (0)
    118 
    119 /* Parameter NULL error handling */
    120 #define MATCH_CHECK_NULL_PARAMETER(_u_, _parameter_)                          \
    121     do {                                                                      \
    122         if (NULL == (_parameter_)) {                                          \
    123             LOG_ERROR(BSL_LS_BCM_SWITCH,                                      \
    124                       (BSL_META_U((_u_),                                      \
    125                                   "Error: NULL parameter\n")));               \
    126             return BCM_E_PARAM;                                               \
    127         }                                                                     \
    128     } while (0)
    129 
    130 /* Device Information NULL error handling */
    131 #define MATCH_CHECK_NULL_DEV_INSTANCE(_u_, _instance_)                        \
    132     do {                                                                      \
    133         if (NULL == (_instance_)) {                                           \
    134             LOG_ERROR(BSL_LS_BCM_SWITCH,                                      \
    135                       (BSL_META_U((_u_),                                      \
    136                                   "Error: NULL chip specific function \n"))); \
    137             return BCM_E_UNAVAIL;                                             \
    138         }                                                                     \
    139     } while (0)
    140 
    141 /* Function Enter/Leave Tracing */
    142 #define MATCH_FUNCTION_TRACE(_u_, _str_)                                      \
    143     do {                                                                      \
    144         LOG_VERBOSE(BSL_LS_BCM_SWITCH,                                        \
    145                     (BSL_META_U((_u_),                                        \
    146                                 "%s: " _str_ "\n"), __FUNCTION__));           \
    147     } while (0)
    148 
    149 /*
    150  * Function:
    151  *   bcmi_switch_match_dev_info_init
    152  * Purpose:
    153  *   register switch match chip specific information
    154  * Parameters:
    155  *   unit - (IN) Unit being initialized
    156  * Returns:
    157  *   BCM_E_xxx
    158  */
    159 STATIC int
    160 bcmi_switch_match_dev_info_init(int unit)
    161 {
    162     bcm_error_t rv = BCM_E_UNAVAIL;
    163     bcm_switch_match_service_t match_service;
    164 
    165     MATCH_FUNCTION_TRACE(unit, "IN");
    166 
    167     /* Chip specific initialization */
    168 #if defined(BCM_HURRICANE3_SUPPORT)
    169     if (SOC_IS_HURRICANE3(unit)) {
    170         rv = bcmi_hr3_switch_match_dev_info_init(unit,
    171                 &(bcmi_match_bk_info[unit].dev_info));
    172     } else
    173 #endif /* BCM_HURRICANE3_SUPPORT */
    174 #if defined(BCM_GREYHOUND2_SUPPORT)
    175     if (SOC_IS_GREYHOUND2(unit)) {
    176         rv = bcmi_gh2_switch_match_dev_info_init(unit,
    177                 &(bcmi_match_bk_info[unit].dev_info));
    178     } else
    179 #endif /* BCM_GREYHOUND2_SUPPORT */
    180     {
    181         return BCM_E_UNAVAIL;
    182     }
    183 
    184     if (BCM_FAILURE(rv) || NULL == bcmi_match_bk_info[unit].dev_info) {
    185         /* No chip specific information initialized */
    186         LOG_WARN(BSL_LS_BCM_SWITCH,
    187                  (BSL_META_U(unit,
    188                              "Switch Match not supported:\n"
    189                              "dev_info_init failed.\n")));
    190         if (BCM_SUCCESS(rv)) {
    191             return BCM_E_UNAVAIL;
    192         }
    193         return rv;
    194     }
    195 
    196     /* Check if MATCH_DEVICE_INFO(unit, match_service) are all NULL */
    197     for (match_service = bcmSwitchMatchServiceMiml;
    198          match_service < bcmSwitchMatchService__Count;
    199          match_service++) {
    200         if (NULL != MATCH_DEVICE_INFO(unit, match_service)) {
    201             /* Found instance */
    202             return BCM_E_NONE;
    203         }
    204     }
    205 
    206     /* All MATCH_DEVICE_INFO(unit, match_service) are NULL */
    207     LOG_WARN(BSL_LS_BCM_SWITCH,
    208              (BSL_META_U(unit,
    209                          "Switch Match not supported:\n"
    210                          "platform initialized, but none "
    211                          "Switch Match services are available.\n")));
    212 
    213     MATCH_FUNCTION_TRACE(unit, "OUT");
    214     return BCM_E_UNAVAIL;
    215 }
    216 
    217 /*
    218  * Function:
    219  *    bcmi_switch_match_service_check
    220  * Purpose:
    221  *    Check the supported match service.
    222  * Parameters:
    223  *    unit - (IN) Unit number
    224  *    match_service - (IN) Match service type
    225  * Returns:
    226  *    BCM_E_xxx
    227  */
    228 STATIC int
    229 bcmi_switch_match_service_check(
    230     int unit,
    231     bcm_switch_match_service_t match_service)
    232 {
    233     MATCH_FUNCTION_TRACE(unit, "IN");
    234 
    235     if (!((match_service >= bcmSwitchMatchServiceMiml) &&
    236         (match_service < bcmSwitchMatchService__Count))) {
    237         LOG_WARN(BSL_LS_BCM_SWITCH,
    238                  (BSL_META_U(unit,
    239                              "Wrong Switch Match Service (%d)\n"),
    240                              match_service));
    241         return BCM_E_PARAM;
    242     }
    243 
    244     if ((match_service == bcmSwitchMatchServiceMiml) &&
    245         (soc_feature(unit, soc_feature_miml))) {
    246         return BCM_E_NONE;
    247     }
    248 
    249     if ((match_service == bcmSwitchMatchServiceCustomHeader) &&
    250         (soc_feature(unit, soc_feature_custom_header))) {
    251         return BCM_E_NONE;
    252     }
    253 
    254     if ((match_service == bcmSwitchMatchServicePrpHsrSupervision) &&
    255         ((soc_feature(unit, soc_feature_tsn_sr_hsr)) ||
    256         (soc_feature(unit, soc_feature_tsn_sr_prp)))) {
    257         return BCM_E_NONE;
    258     }
    259 
    260     if ((match_service == bcmSwitchMatchServiceDot1cbSupervision) &&
    261         (soc_feature(unit, soc_feature_tsn_sr_802_1cb))) {
    262         return BCM_E_NONE;
    263     }
    264 
    265     if ((match_service == bcmSwitchMatchServiceLinkLocal) &&
    266         (soc_feature(unit, soc_feature_tsn_sr))) {
    267         return BCM_E_NONE;
    268     }
    269 
    270     LOG_WARN(BSL_LS_BCM_SWITCH,
    271              (BSL_META_U(unit,
    272                          "Switch Match Service (%d) not supported\n"),
    273                          match_service));
    274 
    275     MATCH_FUNCTION_TRACE(unit, "OUT");
    276     return BCM_E_UNAVAIL;
    277 }
    278 
    279 /*
    280  * Function:
    281  *    bcmi_switch_match_control_check
    282  * Purpose:
    283  *    Check the supported match control type according to the match service.
    284  * Parameters:
    285  *    unit - (IN) Unit number
    286  *    match_service - (IN) Match service type
    287  *    control_type - (IN) Match control type
    288  * Returns:
    289  *    BCM_E_xxx
    290  */
    291 STATIC int
    292 bcmi_switch_match_control_check(
    293     int unit,
    294     bcm_switch_match_service_t match_service,
    295     bcm_switch_match_control_type_t control_type)
    296 {
    297     MATCH_FUNCTION_TRACE(unit, "IN");
    298 
    299     /* Parameter validation check */
    300     BCM_IF_ERROR_RETURN
    301         (bcmi_switch_match_service_check(unit, match_service));
    302 
    303     if (!((control_type >= bcmSwitchMatchControlPortEnable) &&
    304         (control_type < bcmSwitchMatchControl__Count))) {
    305         LOG_WARN(BSL_LS_BCM_SWITCH,
    306                  (BSL_META_U(unit,
    307                              "Wrong Switch Match Service Control Type (%d)\n"),
    308                              control_type));
    309         return BCM_E_PARAM;
    310     }
    311 
    312     if (match_service == bcmSwitchMatchServiceMiml) {
    313         if (control_type == bcmSwitchMatchControlPortEnable) {
    314             return BCM_E_NONE;
    315         }
    316     }
    317 
    318     if (match_service == bcmSwitchMatchServiceCustomHeader) {
    319         if (control_type == bcmSwitchMatchControlPortEnable ||
    320             control_type == bcmSwitchMatchControlMatchMask) {
    321             return BCM_E_NONE;
    322         }
    323     }
    324     LOG_WARN(BSL_LS_BCM_SWITCH,
    325              (BSL_META_U(unit,
    326                          "Wrong Switch Match Control\n")));
    327 
    328     MATCH_FUNCTION_TRACE(unit, "OUT");
    329     return BCM_E_UNAVAIL;
    330 }
    331 
    332 /*
    333  * Function:
    334  *    bcmi_switch_match_id_check
    335  * Purpose:
    336  *    Check match_id is valid
    337  * Parameters:
    338  *    unit - (IN) Unit number
    339  *    match_service - (IN) Match service type
    340  *    match_id - (IN) Match ID
    341  * Returns:
    342  *    BCM_E_xxx
    343  */
    344 STATIC int
    345 bcmi_switch_match_id_check(
    346     int unit,
    347     bcm_switch_match_service_t match_service,
    348     int match_id)
    349 {
    350     bcm_error_t rv = BCM_E_NONE;
    351     bcmi_match_bk_t *match_bk_info = NULL;
    352     const bcmi_switch_match_service_info_t *sm_dev_info = NULL;
    353     uint32 sw_idx = MATCH_ID_TO_SW_IDX(match_id);
    354     uint32 table_size;
    355 
    356     MATCH_FUNCTION_TRACE(unit, "IN");
    357 
    358     /* Parameter validation check */
    359     BCM_IF_ERROR_RETURN
    360         (bcmi_switch_match_service_check(unit, match_service));
    361 
    362     /* Initialization check */
    363     MATCH_CHECK_INIT(unit, match_service);
    364 
    365     if (!MATCH_ID_IS_TYPE(match_id, match_service)) {
    366         LOG_ERROR(BSL_LS_BCM_SWITCH,
    367                   (BSL_META_U(unit,
    368                               "match_id(0x%x) doesn't match "
    369                               "SwitchMatchService(%d)\n"),
    370                               match_id,
    371                               match_service));
    372         return BCM_E_PARAM;
    373     }
    374 
    375     /* Get chip specific assignment & bookkeeping structure */
    376     match_bk_info = MATCH_BK_INFO(unit);
    377     sm_dev_info = MATCH_DEVICE_INFO(unit, match_service);
    378 
    379     /* Check if the chip specific function existed */
    380     MATCH_CHECK_NULL_DEV_INSTANCE(
    381         unit, sm_dev_info->switch_match_table_size_get);
    382 
    383     rv = sm_dev_info->switch_match_table_size_get(unit, &table_size);
    384     if (BCM_FAILURE(rv)) {
    385         LOG_ERROR(BSL_LS_BCM_SWITCH,
    386                   (BSL_META_U(unit,
    387                               "Get table size failed(rv = %d)\n"),
    388                               rv));
    389         return rv;
    390     }
    391 
    392     /* Check if sw_idx excess the table size or not */
    393     if (sw_idx >= table_size) {
    394         return BCM_E_PARAM;
    395     }
    396 
    397     /* Check if the valid bitmap is NULL or not */
    398     if (NULL == match_bk_info->intf_bitmap[match_service]) {
    399         return BCM_E_UNAVAIL;
    400     }
    401 
    402     /* Check if the sw_idx is valid or not */
    403     if (!MATCH_INTF_GET(unit, sw_idx, match_service)) {
    404         LOG_ERROR(BSL_LS_BCM_SWITCH,
    405                   (BSL_META_U(unit,
    406                               "HW resource (sw_idx:%d) doesn't exist.\n"),
    407                               sw_idx));
    408         return BCM_E_NOT_FOUND;
    409     }
    410     MATCH_FUNCTION_TRACE(unit, "OUT");
    411     return BCM_E_NONE;
    412 }
    413 
    414 /*
    415  * Function:
    416  *      bcmi_switch_match_hw_id_get
    417  * Purpose:
    418  *      Get HW memory index with given map_id
    419  * Parameters:
    420  *      unit     - (IN) Unit number
    421  *      match_id - (IN) Match ID
    422  *      match_service - (OUT) Match service type
    423  *      hw_id - (OUT) Priority Map Type
    424  * Returns:
    425  *      BCM_E_xxx
    426  */
    427 int
    428 bcmi_switch_match_hw_id_get(
    429     int unit,
    430     int match_id,
    431     bcm_switch_match_service_t *match_service,
    432     uint32 *hw_id)
    433 {
    434     bcm_error_t rv = BCM_E_UNAVAIL;
    435     const bcmi_switch_match_service_info_t *sm_dev_info = NULL;
    436     uint32 sw_idx;
    437 
    438     MATCH_FUNCTION_TRACE(unit, "IN");
    439 
    440     /* Parameter NULL error handling */
    441     MATCH_CHECK_NULL_PARAMETER(unit, match_service);
    442     MATCH_CHECK_NULL_PARAMETER(unit, hw_id);
    443 
    444     *match_service = MATCH_TYPE_GET(match_id);
    445 
    446     /* Parameter validation check */
    447     BCM_IF_ERROR_RETURN
    448         (bcmi_switch_match_service_check(unit, *match_service));
    449 
    450     /* Initialization check */
    451     MATCH_CHECK_INIT(unit, *match_service);
    452 
    453     BCM_IF_ERROR_RETURN
    454         (bcmi_switch_match_id_check(unit, *match_service, match_id));
    455 
    456     sw_idx = MATCH_ID_TO_SW_IDX(match_id);
    457 
    458     sm_dev_info = MATCH_DEVICE_INFO(unit, *match_service);
    459 
    460     /* Check if the chip specific function existed */
    461     MATCH_CHECK_NULL_DEV_INSTANCE(
    462         unit, sm_dev_info->switch_match_hw_id_get);
    463 
    464     rv = sm_dev_info->switch_match_hw_id_get(unit, sw_idx, hw_id);
    465     if (BCM_FAILURE(rv)) {
    466         LOG_ERROR(BSL_LS_BCM_TSN,
    467                   (BSL_META_U(unit,
    468                               "HW operation failed(rv = %d)\n"),
    469                               rv));
    470         return rv;
    471     }
    472     MATCH_FUNCTION_TRACE(unit, "OUT");
    473     return BCM_E_NONE;
    474 }
    475 
    476 /*
    477  * Function:
    478  *      bcmi_switch_match_match_id_get
    479  * Purpose:
    480  *      Get map_id with given HW memory index
    481  * Parameters:
    482  *      unit     - (IN) Unit number
    483  *      match_service - (IN) Priority Map Type
    484  *      hw_id - (IN) HW memory index
    485  *      match_id - (OUT) Match ID
    486  * Returns:
    487  *      BCM_E_xxx
    488  */
    489 int
    490 bcmi_switch_match_match_id_get(
    491     int unit,
    492     bcm_switch_match_service_t match_service,
    493     uint32 hw_id,
    494     int *match_id)
    495 {
    496     bcm_error_t rv = BCM_E_UNAVAIL;
    497     const bcmi_switch_match_service_info_t *sm_dev_info = NULL;
    498     uint32 sw_idx;
    499 
    500     MATCH_FUNCTION_TRACE(unit, "IN");
    501 
    502     /* Parameter NULL error handling */
    503     MATCH_CHECK_NULL_PARAMETER(unit, match_id);
    504 
    505     /* Parameter validation check */
    506     BCM_IF_ERROR_RETURN
    507         (bcmi_switch_match_service_check(unit, match_service));
    508 
    509     sm_dev_info = MATCH_DEVICE_INFO(unit, match_service);
    510 
    511     /* Check if the chip specific function existed */
    512     MATCH_CHECK_NULL_DEV_INSTANCE(
    513         unit, sm_dev_info->switch_match_sw_idx_get);
    514 
    515     rv = sm_dev_info->switch_match_sw_idx_get(unit, hw_id, &sw_idx);
    516     if (BCM_FAILURE(rv)) {
    517         LOG_ERROR(BSL_LS_BCM_TSN,
    518                   (BSL_META_U(unit,
    519                               "HW operation failed(rv = %d)\n"),
    520                               rv));
    521         return rv;
    522     }
    523     *match_id = SW_IDX_TO_MATCH_ID(sw_idx, match_service);
    524 
    525     BCM_IF_ERROR_RETURN
    526         (bcmi_switch_match_id_check(unit, match_service, *match_id));
    527 
    528     MATCH_FUNCTION_TRACE(unit, "OUT");
    529     return BCM_E_NONE;
    530 }
    531 
    532 /*
    533  * Function:
    534  *   bcmi_switch_match_free_resources
    535  * Purpose:
    536  *   Free match bookkeeping resources associated with a given unit. This
    537  *   happens either during an error initializing or during a detach operation.
    538  * Parameters:
    539  *   unit - (IN) Unit number
    540  * Returns:
    541  *   none
    542  */
    543 STATIC void
    544 bcmi_switch_match_free_resources(int unit)
    545 {
    546     bcmi_match_bk_t *match_bk_info = MATCH_BK_INFO(unit);
    547     bcm_switch_match_service_t match_service;
    548 
    549     MATCH_FUNCTION_TRACE(unit, "IN");
    550     for (match_service = bcmSwitchMatchServiceMiml;
    551          match_service < bcmSwitchMatchService__Count;
    552          match_service++) {
    553         if (match_bk_info->intf_bitmap[match_service]) {
    554             sal_free(match_bk_info->intf_bitmap[match_service]);
    555             match_bk_info->intf_bitmap[match_service] = NULL;
    556         }
    557     }
    558 
    559     if (match_bk_info->match_mutex) {
    560         sal_mutex_destroy(match_bk_info->match_mutex);
    561         match_bk_info->match_mutex = NULL;
    562     }
    563     MATCH_FUNCTION_TRACE(unit, "OUT");
    564 }
    565 
    566 #ifdef BCM_WARM_BOOT_SUPPORT
    567 
    568 /*
    569  * Function:
    570  *   bcmi_switch_match_reinit
    571  * Purpose:
    572  *   Re-initialize the resource. Restore bookkeeping information.
    573  * Parameters:
    574  *   unit - (IN) Unit being initialized
    575  * Returns:
    576  *   BCM_E_XXX
    577  */
    578 STATIC int
    579 bcmi_switch_match_reinit(int unit)
    580 {
    581     int rv = BCM_E_UNAVAIL;
    582     uint32 table_size;
    583     uint32 sw_idx;
    584     const bcmi_switch_match_service_info_t *sm_dev_info = NULL;
    585     bcm_switch_match_service_t match_service;
    586 
    587     MATCH_FUNCTION_TRACE(unit, "IN");
    588 
    589     for (match_service = bcmSwitchMatchServiceMiml;
    590          match_service < bcmSwitchMatchService__Count;
    591          match_service++) {
    592 
    593         sm_dev_info = MATCH_DEVICE_INFO(unit, match_service);
    594 
    595         if (NULL == sm_dev_info) {
    596             /* Need to check all match_service */
    597             continue;
    598         }
    599 
    600         /* Check if the chip specific function existed */
    601         MATCH_CHECK_NULL_DEV_INSTANCE(
    602             unit, sm_dev_info->switch_match_table_size_get);
    603         MATCH_CHECK_NULL_DEV_INSTANCE(
    604             unit, sm_dev_info->switch_match_wb_hw_existed);
    605 
    606         rv = sm_dev_info->switch_match_table_size_get(unit, &table_size);
    607         if (BCM_FAILURE(rv)) {
    608             LOG_ERROR(BSL_LS_BCM_SWITCH,
    609                       (BSL_META_U(unit,
    610                                   "Get table size failed(rv = %d)\n"),
    611                                   rv));
    612             return rv;
    613         }
    614 
    615         /* Scan all sw_idx (0 ~ table_size) to check existed HW */
    616         for (sw_idx = 0; sw_idx < table_size; sw_idx++) {
    617             MATCH_INTF_CLR(unit, sw_idx, match_service);
    618 
    619             /* BCM_SUCCESS means HW(sw_idx) existed */
    620             rv = sm_dev_info->switch_match_wb_hw_existed(unit, sw_idx);
    621             if (BCM_SUCCESS(rv)) {
    622                 MATCH_INTF_SET(unit, sw_idx, match_service);
    623             }
    624         }
    625     }
    626     MATCH_FUNCTION_TRACE(unit, "OUT");
    627     /* Return BCM_E_NONE means that WB successfully */
    628     return BCM_E_NONE;
    629 }
    630 #endif /* BCM_WARM_BOOT_SUPPORT */
    631 
    632 /*
    633  * Function:
    634  *   bcmi_switch_match_coldboot_init
    635  * Purpose:
    636  *   Reset the HW to default status
    637  * Parameters:
    638  *   unit - (IN) unit number
    639  * Returns:
    640  *   BCM_E_XXX
    641  */
    642 STATIC int
    643 bcmi_switch_match_coldboot_init(int unit)
    644 {
    645     bcm_error_t rv = BCM_E_UNAVAIL;
    646     const bcmi_switch_match_service_info_t *sm_dev_info;
    647     bcm_switch_match_service_t match_service;
    648     uint32 table_size;
    649     uint32 sw_idx;
    650 
    651 #if defined(BCM_WARM_BOOT_SUPPORT)
    652     /* Warm boot should be false in cold boot case */
    653     if (SOC_WARM_BOOT(unit)) {
    654         return BCM_E_UNAVAIL;
    655     }
    656 #endif /* BCM_WARM_BOOT_SUPPORT */
    657 
    658     /* Reset all type to default value */
    659     for (match_service = bcmSwitchMatchServiceMiml;
    660          match_service < bcmSwitchMatchService__Count;
    661          match_service++) {
    662 
    663         sm_dev_info = MATCH_DEVICE_INFO(unit, match_service);
    664 
    665         /* Check if the chip specific function existed */
    666         if (NULL == sm_dev_info) {
    667             /* Maybe some chips only have some services */
    668             continue;
    669         }
    670         /* Check if the chip specific function existed */
    671         MATCH_CHECK_NULL_DEV_INSTANCE(
    672             unit, sm_dev_info->switch_match_table_size_get);
    673         MATCH_CHECK_NULL_DEV_INSTANCE(
    674             unit, sm_dev_info->switch_match_config_delete);
    675 
    676         rv = sm_dev_info->switch_match_table_size_get(unit, &table_size);
    677 
    678         for (sw_idx = 0;
    679              sw_idx < table_size;
    680              sw_idx++) {
    681             /* Use delete for reset HW to default value */
    682             rv = sm_dev_info->switch_match_config_delete(unit, sw_idx);
    683             if (BCM_FAILURE(rv)) {
    684                 LOG_ERROR(BSL_LS_BCM_SWITCH,
    685                           (BSL_META_U(unit,
    686                                       "coldboot fail(rv=%d) on "
    687                                       "Switch Match Service(%d)\n"),
    688                                       rv,
    689                                       match_service));
    690                 return rv;
    691             }
    692         }
    693     }
    694 
    695     return BCM_E_NONE;
    696 }
    697 
    698 /*
    699  * Function:
    700  *   bcmi_switch_match_detach
    701  * Purpose:
    702  *   Detach resource. Called when the module should de-initialize.
    703  * Parameters:
    704  *   unit - (IN) Unit being detached.
    705  * Returns:
    706  *   BCM_E_XXX
    707  */
    708 int
    709 bcmi_switch_match_detach(int unit)
    710 {
    711     MATCH_FUNCTION_TRACE(unit, "IN");
    712     if (bcmi_match_bk_info[unit].initialized) {
    713         bcmi_switch_match_free_resources(unit);
    714         bcmi_match_bk_info[unit].initialized = FALSE;
    715         bcmi_match_bk_info[unit].dev_info = NULL;
    716     }
    717     MATCH_FUNCTION_TRACE(unit, "OUT");
    718     return BCM_E_NONE;
    719 }
    720 
    721 /*
    722  * Function:
    723  *   bcmi_switch_match_init
    724  * Purpose:
    725  *   Initialize the resource.  Allocate bookkeeping information.
    726  * Parameters:
    727  *   unit - (IN) Unit being initialized
    728  * Returns:
    729  *   BCM_E_XXX
    730  */
    731 int
    732 bcmi_switch_match_init(int unit)
    733 {
    734     bcm_error_t rv = BCM_E_NONE;
    735     bcmi_match_bk_t *match_bk_info = NULL;
    736     const bcmi_switch_match_service_info_t *sm_dev_info = NULL;
    737     int i;
    738     uint32 table_size, shr_bitdcl_size;
    739     bcm_switch_match_service_t match_service;
    740 
    741     MATCH_FUNCTION_TRACE(unit, "IN");
    742 
    743     if (!soc_feature(unit, soc_feature_switch_match)) {
    744         return BCM_E_UNAVAIL;
    745     }
    746 
    747     /* Check if leading bits is enough for identifying different types*/
    748     assert((1 << (32 - BCMI_MATCH_TYPE_SHIFT - 1)) >= bcmSwitchMatchService__Count);
    749 
    750     /* Initial all unit with default value FALSE. */
    751     if (FALSE == bcmi_match_initialized_bool) {
    752         for (i = 0; i < BCM_MAX_NUM_UNITS; i++) {
    753             bcmi_match_bk_info[unit].initialized = FALSE;
    754             bcmi_match_bk_info[unit].dev_info = NULL;
    755         }
    756         bcmi_match_initialized_bool = TRUE;
    757     }
    758 
    759     /*
    760      * Check whether the unit is initialized or not
    761      * if it's initialized, and then free resource for later initialization.
    762      */
    763     BCM_IF_ERROR_RETURN
    764         (bcmi_switch_match_detach(unit));
    765 
    766     /* Initialize platform-specific functions related information */
    767     BCM_IF_ERROR_RETURN
    768         (bcmi_switch_match_dev_info_init(unit));
    769 
    770     /* Check if chip specific information is NULL or not */
    771     if (NULL == bcmi_match_bk_info[unit].dev_info) {
    772         return BCM_E_UNAVAIL;
    773     }
    774 
    775     /* Get chip specific assignment & bookkeeping structure */
    776     match_bk_info = MATCH_BK_INFO(unit);
    777 
    778     /* Create all match_id list */
    779     for (match_service = bcmSwitchMatchServiceMiml;
    780          match_service < bcmSwitchMatchService__Count;
    781          match_service++) {
    782 
    783         sm_dev_info = MATCH_DEVICE_INFO(unit, match_service);
    784 
    785         /* Check if the chip specific function existed */
    786         if (NULL == sm_dev_info) {
    787             /* Maybe some chips only have some services */
    788             continue;
    789         }
    790 
    791         /* Check if the chip specific function existed */
    792         MATCH_CHECK_NULL_DEV_INSTANCE(
    793             unit, sm_dev_info->switch_match_table_size_get);
    794 
    795         rv = sm_dev_info->switch_match_table_size_get(unit, &table_size);
    796         if (BCM_FAILURE(rv) || !(table_size > 0)) {
    797             LOG_ERROR(BSL_LS_BCM_SWITCH,
    798                       (BSL_META_U(unit,
    799                                   "Get table size failed(rv = %d)\n"),
    800                                   rv));
    801             /* Table size should > 0 */
    802             assert(table_size > 0);
    803             return rv;
    804         }
    805 
    806         /* Allocate usage bitmap */
    807         shr_bitdcl_size = SHR_BITALLOCSIZE(table_size);
    808         match_bk_info->intf_bitmap[match_service] =
    809             sal_alloc(shr_bitdcl_size, "Switch Map Valid intf_bitmap");
    810         if (match_bk_info->intf_bitmap[match_service] == NULL) {
    811             bcmi_switch_match_free_resources(unit);
    812             return BCM_E_MEMORY;
    813         }
    814         sal_memset(match_bk_info->intf_bitmap[match_service],
    815                    0, shr_bitdcl_size);
    816     }
    817 
    818     /* Create mutex */
    819     match_bk_info->match_mutex = sal_mutex_create("switch_match.lock");
    820     if (match_bk_info->match_mutex == NULL) {
    821         bcmi_switch_match_free_resources(unit);
    822         return BCM_E_MEMORY;
    823     }
    824 
    825 #ifdef BCM_WARM_BOOT_SUPPORT
    826     if (SOC_WARM_BOOT(unit)) {
    827         /* Warm Boot recovery */
    828         rv = bcmi_switch_match_reinit(unit);
    829         if (BCM_FAILURE(rv)) {
    830             BCM_IF_ERROR_RETURN
    831                 (bcmi_switch_match_detach(unit));
    832             return rv;
    833         }
    834     } else
    835 #endif /* BCM_WARM_BOOT_SUPPORT */
    836     {
    837         /* Cold Boot */
    838         rv = bcmi_switch_match_coldboot_init(unit);
    839         if (BCM_FAILURE(rv)) {
    840             bcmi_switch_match_detach(unit);
    841             LOG_ERROR(BSL_LS_BCM_SWITCH,
    842                       (BSL_META_U(unit,
    843                                   "Cold boot failed"
    844                                   "(rv = %d)\n"),
    845                                   rv));
    846             return rv;
    847         }
    848     }
    849     bcmi_match_bk_info[unit].initialized = TRUE;
    850 
    851     MATCH_FUNCTION_TRACE(unit, "OUT");
    852     return BCM_E_NONE;
    853 }
    854 
    855 /*
    856  * Function:
    857  *    bcmi_switch_match_config_add
    858  * Purpose:
    859  *    Add a match config to hardware.
    860  * Parameters:
    861  *    unit - (IN) Unit number
    862  *    match_service - (IN) Match service type
    863  *    config_info - (IN) Match configuration
    864  *    match_id - (OUT) Match ID
    865  * Returns:
    866  *    BCM_E_xxx
    867  */
    868 int
    869 bcmi_switch_match_config_add(
    870     int unit,
    871     bcm_switch_match_service_t match_service,
    872     bcm_switch_match_config_info_t *config_info,
    873     int *match_id)
    874 {
    875     bcm_error_t rv = BCM_E_NONE;
    876     const bcmi_switch_match_service_info_t *sm_dev_info = NULL;
    877     uint32 sw_idx;
    878 
    879     MATCH_FUNCTION_TRACE(unit, "IN");
    880 
    881     /* Parameter NULL error handling */
    882     MATCH_CHECK_NULL_PARAMETER(unit, config_info);
    883     MATCH_CHECK_NULL_PARAMETER(unit, match_id);
    884 
    885     /* Parameter validation check */
    886     BCM_IF_ERROR_RETURN
    887         (bcmi_switch_match_service_check(unit, match_service));
    888 
    889     /* Initialization check */
    890     MATCH_CHECK_INIT(unit, match_service);
    891 
    892     /* Get chip specific assignment & bookkeeping structure */
    893     sm_dev_info = MATCH_DEVICE_INFO(unit, match_service);
    894 
    895     /* Check if the chip specific function existed */
    896     MATCH_CHECK_NULL_DEV_INSTANCE(
    897         unit, sm_dev_info->switch_match_table_size_get);
    898     MATCH_CHECK_NULL_DEV_INSTANCE(
    899         unit, sm_dev_info->switch_match_config_add);
    900 
    901     MATCH_LOCK(unit);
    902 
    903     /* Check if there is any empty sw_idx */
    904     rv = sm_dev_info->switch_match_config_add(unit,
    905                                               config_info,
    906                                               &sw_idx);
    907     if (BCM_FAILURE(rv)) {
    908         MATCH_UNLOCK(unit);
    909         if (BCM_E_EXISTS == rv) {
    910             *match_id = SW_IDX_TO_MATCH_ID(sw_idx, match_service);
    911             return BCM_E_EXISTS;
    912         }
    913         LOG_ERROR(BSL_LS_BCM_SWITCH,
    914                   (BSL_META_U(unit,
    915                               "add to HW failed(rv = %d)\n"),
    916                               rv));
    917         return rv;
    918     }
    919 
    920     *match_id = SW_IDX_TO_MATCH_ID(sw_idx, match_service);
    921     /* Set current sw_idx to valid */
    922     MATCH_INTF_SET(unit, sw_idx, match_service);
    923 
    924     MATCH_UNLOCK(unit);
    925 
    926     MATCH_FUNCTION_TRACE(unit, "OUT");
    927     return BCM_E_NONE;
    928 }
    929 
    930 /*
    931  * Function:
    932  *    bcmi_switch_match_config_delete
    933  * Purpose:
    934  *    Delete a match config with the given match_id by removing it from
    935  *    hardware and deleting the associated software state info.
    936  * Parameters:
    937  *    unit - (IN) Unit number
    938  *    match_service - (IN) Match service type
    939  *    match_id - (IN) Match ID
    940  * Returns:
    941  *    BCM_E_xxx
    942  */
    943 int
    944 bcmi_switch_match_config_delete(
    945     int unit,
    946     bcm_switch_match_service_t match_service,
    947     int match_id)
    948 {
    949     int rv;
    950     uint32 sw_idx = MATCH_ID_TO_SW_IDX(match_id);
    951     const bcmi_switch_match_service_info_t *sm_dev_info;
    952 
    953     MATCH_FUNCTION_TRACE(unit, "IN");
    954 
    955     /* Parameter validation check */
    956     BCM_IF_ERROR_RETURN
    957         (bcmi_switch_match_service_check(unit, match_service));
    958 
    959     /* Initialization check */
    960     MATCH_CHECK_INIT(unit, match_service);
    961 
    962     BCM_IF_ERROR_RETURN
    963         (bcmi_switch_match_id_check(unit, match_service, match_id));
    964 
    965     sm_dev_info = MATCH_DEVICE_INFO(unit, match_service);
    966 
    967     /* Check if the chip specific function existed */
    968     MATCH_CHECK_NULL_DEV_INSTANCE(
    969         unit, sm_dev_info->switch_match_config_delete);
    970 
    971     MATCH_LOCK(unit);
    972     rv = sm_dev_info->switch_match_config_delete(unit,
    973                                                  sw_idx);
    974     if (BCM_FAILURE(rv)) {
    975         MATCH_UNLOCK(unit);
    976         LOG_ERROR(BSL_LS_BCM_SWITCH,
    977                   (BSL_META_U(unit,
    978                               "delete HW failed(rv = %d)\n"),
    979                               rv));
    980         return rv;
    981     }
    982 
    983     /* Clear the ID in software table */
    984     MATCH_INTF_CLR(unit, sw_idx, match_service);
    985 
    986     MATCH_UNLOCK(unit);
    987     MATCH_FUNCTION_TRACE(unit, "OUT");
    988     return BCM_E_NONE;
    989 }
    990 
    991 /*
    992  * Function:
    993  *    bcmi_switch_match_config_delete_all
    994  * Purpose:
    995  *    Delete all match config with the given match_service.
    996  * Parameters:
    997  *    unit - (IN) Unit number
    998  *    match_service - (IN) Match service type
    999  * Returns:
   1000  *    BCM_E_xxx
   1001  */
   1002 int
   1003 bcmi_switch_match_config_delete_all(
   1004     int unit,
   1005     bcm_switch_match_service_t match_service)
   1006 {
   1007     bcm_error_t rv = BCM_E_NONE;
   1008     const bcmi_switch_match_service_info_t *sm_dev_info = NULL;
   1009     uint32 table_size, sw_idx;
   1010 
   1011     MATCH_FUNCTION_TRACE(unit, "IN");
   1012 
   1013     /* Parameter validation check */
   1014     BCM_IF_ERROR_RETURN
   1015         (bcmi_switch_match_service_check(unit, match_service));
   1016 
   1017     /* Initialization check */
   1018     MATCH_CHECK_INIT(unit, match_service);
   1019 
   1020     /* Get chip specific assignment & bookkeeping structure */
   1021     sm_dev_info = MATCH_DEVICE_INFO(unit, match_service);
   1022 
   1023     /* Check if the chip specific function existed */
   1024     MATCH_CHECK_NULL_DEV_INSTANCE(
   1025         unit, sm_dev_info->switch_match_table_size_get);
   1026     MATCH_CHECK_NULL_DEV_INSTANCE(
   1027         unit, sm_dev_info->switch_match_config_delete);
   1028 
   1029     rv = sm_dev_info->switch_match_table_size_get(unit, &table_size);
   1030     if (BCM_FAILURE(rv)) {
   1031         LOG_ERROR(BSL_LS_BCM_SWITCH,
   1032                   (BSL_META_U(unit,
   1033                               "Get table size failed(rv = %d)\n"),
   1034                               rv));
   1035         return rv;
   1036     }
   1037 
   1038     MATCH_LOCK(unit);
   1039 
   1040     for (sw_idx = 0; sw_idx < table_size; sw_idx++) {
   1041         if (MATCH_INTF_GET(unit, sw_idx, match_service)) {
   1042 
   1043             rv = sm_dev_info->switch_match_config_delete(unit,
   1044                                                          sw_idx);
   1045             if (BCM_FAILURE(rv)) {
   1046                 MATCH_UNLOCK(unit);
   1047                 LOG_ERROR(BSL_LS_BCM_SWITCH,
   1048                           (BSL_META_U(unit,
   1049                                       "Delete HW failed(rv = %d)\n"),
   1050                                       rv));
   1051                 return rv;
   1052             }
   1053 
   1054             /* Clear the ID in software table */
   1055             MATCH_INTF_CLR(unit, sw_idx, match_service);
   1056         }
   1057     }
   1058 
   1059     MATCH_UNLOCK(unit);
   1060     MATCH_FUNCTION_TRACE(unit, "OUT");
   1061     return BCM_E_NONE;
   1062 }
   1063 
   1064 /*
   1065  * Function:
   1066  *    bcmi_switch_match_config_get
   1067  * Purpose:
   1068  *    Get the configuration of the match with the given match_id.
   1069  * Parameters:
   1070  *    unit - (IN) Unit number
   1071  *    match_service - (IN) Match service type
   1072  *    match_id - (IN) Match ID
   1073  *    config_info - (OUT) Match configuration
   1074  * Returns:
   1075  *    BCM_E_xxx
   1076  */
   1077 int
   1078 bcmi_switch_match_config_get(
   1079     int unit,
   1080     bcm_switch_match_service_t match_service,
   1081     int match_id,
   1082     bcm_switch_match_config_info_t *config_info)
   1083 {
   1084     int rv;
   1085     const bcmi_switch_match_service_info_t *sm_dev_info;
   1086     uint32 sw_idx;
   1087 
   1088     MATCH_FUNCTION_TRACE(unit, "IN");
   1089 
   1090     /* Parameter NULL error handling */
   1091     MATCH_CHECK_NULL_PARAMETER(unit, config_info);
   1092 
   1093     /* Parameter validation check */
   1094     BCM_IF_ERROR_RETURN
   1095         (bcmi_switch_match_service_check(unit, match_service));
   1096 
   1097     /* Initialization check */
   1098     MATCH_CHECK_INIT(unit, match_service);
   1099 
   1100     BCM_IF_ERROR_RETURN
   1101         (bcmi_switch_match_id_check(unit, match_service, match_id));
   1102 
   1103     sm_dev_info = MATCH_DEVICE_INFO(unit, match_service);
   1104 
   1105     /* Check if the chip specific function existed */
   1106     MATCH_CHECK_NULL_DEV_INSTANCE(
   1107         unit, sm_dev_info->switch_match_config_get);
   1108 
   1109     sw_idx = MATCH_ID_TO_SW_IDX(match_id);
   1110 
   1111     bcm_switch_match_config_info_t_init(config_info);
   1112 
   1113     MATCH_LOCK(unit);
   1114     rv = sm_dev_info->switch_match_config_get(unit,
   1115                                               sw_idx,
   1116                                               config_info);
   1117     if (BCM_FAILURE(rv)) {
   1118         MATCH_UNLOCK(unit);
   1119         LOG_ERROR(BSL_LS_BCM_SWITCH,
   1120                   (BSL_META_U(unit,
   1121                               "Read from HW failed(rv = %d)\n"),
   1122                               rv));
   1123         return rv;
   1124     }
   1125 
   1126     MATCH_UNLOCK(unit);
   1127     MATCH_FUNCTION_TRACE(unit, "OUT");
   1128     return BCM_E_NONE;
   1129 }
   1130 
   1131 /*
   1132  * Function:
   1133  *    bcmi_switch_match_config_set
   1134  * Purpose:
   1135  *    Set the configuration of the match with the given match_id.
   1136  * Parameters:
   1137  *    unit - (IN) Unit number
   1138  *    match_service - (IN) Match service type
   1139  *    match_id - (IN) Match ID
   1140  *    config_info - (IN) Match configuration
   1141  * Returns:
   1142  *    BCM_E_xxx
   1143  */
   1144 int
   1145 bcmi_switch_match_config_set(
   1146     int unit,
   1147     bcm_switch_match_service_t match_service,
   1148     int match_id,
   1149     bcm_switch_match_config_info_t *config_info)
   1150 {
   1151     int rv;
   1152     const bcmi_switch_match_service_info_t *sm_dev_info;
   1153     uint32 sw_idx;
   1154 
   1155     MATCH_FUNCTION_TRACE(unit, "IN");
   1156 
   1157     /* Parameter NULL error handling */
   1158     MATCH_CHECK_NULL_PARAMETER(unit, config_info);
   1159 
   1160     /* Parameter validation check */
   1161     BCM_IF_ERROR_RETURN
   1162         (bcmi_switch_match_service_check(unit, match_service));
   1163 
   1164     /* Initialization check */
   1165     MATCH_CHECK_INIT(unit, match_service);
   1166 
   1167     BCM_IF_ERROR_RETURN
   1168         (bcmi_switch_match_id_check(unit, match_service, match_id));
   1169 
   1170     sm_dev_info = MATCH_DEVICE_INFO(unit, match_service);
   1171 
   1172     /* Check if the chip specific function existed */
   1173     MATCH_CHECK_NULL_DEV_INSTANCE(
   1174         unit, sm_dev_info->switch_match_config_set);
   1175 
   1176     sw_idx = MATCH_ID_TO_SW_IDX(match_id);
   1177 
   1178     MATCH_LOCK(unit);
   1179     rv = sm_dev_info->switch_match_config_set(unit,
   1180                                               sw_idx,
   1181                                               config_info);
   1182     if (BCM_FAILURE(rv)) {
   1183         MATCH_UNLOCK(unit);
   1184         LOG_ERROR(BSL_LS_BCM_SWITCH,
   1185                   (BSL_META_U(unit,
   1186                               "Write to HW failed(rv = %d)\n"),
   1187                               rv));
   1188         return rv;
   1189     }
   1190 
   1191     MATCH_UNLOCK(unit);
   1192     MATCH_FUNCTION_TRACE(unit, "OUT");
   1193     return BCM_E_NONE;
   1194 }
   1195 
   1196 
   1197 /*
   1198  * Function:
   1199  *    bcmi_switch_match_config_traverse
   1200  * Purpose:
   1201  *    Traverse the created match config.
   1202  * Parameters:
   1203  *    unit - (IN) Unit number
   1204  *    match_service - (IN) Match service type
   1205  *    cb_fn - (IN) Traverse call back function
   1206  *    user_data - (IN) User data
   1207  * Returns:
   1208  *    BCM_E_xxx
   1209  */
   1210 int
   1211 bcmi_switch_match_config_traverse(
   1212     int unit,
   1213     bcm_switch_match_service_t match_service,
   1214     bcm_switch_match_config_traverse_cb cb_fn,
   1215     void *user_data)
   1216 {
   1217     bcm_error_t rv = BCM_E_NONE;
   1218     const bcmi_switch_match_service_info_t *sm_dev_info = NULL;
   1219     int sw_idx = 0;
   1220     int match_id;
   1221     uint32 table_size;
   1222     bcm_switch_match_config_info_t match_config;
   1223 
   1224     MATCH_FUNCTION_TRACE(unit, "IN");
   1225 
   1226     /* Parameter NULL error handling */
   1227     MATCH_CHECK_NULL_PARAMETER(unit, cb_fn);
   1228 
   1229     /* Parameter validation check */
   1230     BCM_IF_ERROR_RETURN
   1231         (bcmi_switch_match_service_check(unit, match_service));
   1232 
   1233     /* Initialization check */
   1234     MATCH_CHECK_INIT(unit, match_service);
   1235 
   1236     /* Get chip specific assignment & bookkeeping structure */
   1237     sm_dev_info = MATCH_DEVICE_INFO(unit, match_service);
   1238 
   1239 
   1240     /* Check if the chip specific function existed */
   1241     MATCH_CHECK_NULL_DEV_INSTANCE(
   1242         unit, sm_dev_info->switch_match_table_size_get);
   1243 
   1244     rv = sm_dev_info->switch_match_table_size_get(unit, &table_size);
   1245     if (BCM_FAILURE(rv)) {
   1246         LOG_ERROR(BSL_LS_BCM_SWITCH,
   1247                   (BSL_META_U(unit,
   1248                               "Get table size failed(rv = %d)\n"),
   1249                               rv));
   1250         return rv;
   1251     }
   1252 
   1253     MATCH_LOCK(unit);
   1254 
   1255     for (sw_idx = 0; sw_idx < table_size; sw_idx++) {
   1256         if (MATCH_INTF_GET(unit, sw_idx, match_service)) {
   1257             match_id = SW_IDX_TO_MATCH_ID(sw_idx, match_service);
   1258             /* Reset the config */
   1259             bcm_switch_match_config_info_t_init(&match_config);
   1260 
   1261             /* Get the config */
   1262             rv = bcmi_switch_match_config_get(unit,
   1263                                               match_service,
   1264                                               match_id,
   1265                                               &match_config);
   1266 
   1267             /* Doing the user cb function with config */
   1268             if (BCM_SUCCESS(rv)) {
   1269                 rv = cb_fn(unit, match_id, &match_config, user_data);
   1270                 if (BCM_FAILURE(rv)) {
   1271                     MATCH_UNLOCK(unit);
   1272                     return rv;
   1273                 }
   1274             }
   1275         }
   1276     }
   1277     MATCH_UNLOCK(unit);
   1278     MATCH_FUNCTION_TRACE(unit, "OUT");
   1279     return BCM_E_NONE;
   1280 }
   1281 
   1282 /*
   1283  * Function:
   1284  *    bcmi_switch_match_control_get
   1285  * Purpose:
   1286  *    Get the match related control information with given control service
   1287  *    and type.
   1288  * Parameters:
   1289  *    unit - (IN) Unit number
   1290  *    match_service - (IN) Match service type
   1291  *    control_type - (IN) Match control type
   1292  *    gport - (IN) gport number for port basis control.
   1293  *                 Otherwise, BCM_GPORT_INVALID.
   1294  *    control_info - (OUT) Match control information
   1295  * Returns:
   1296  *    BCM_E_xxx
   1297  */
   1298 int
   1299 bcmi_switch_match_control_get(
   1300     int unit,
   1301     bcm_switch_match_service_t match_service,
   1302     bcm_switch_match_control_type_t control_type,
   1303     bcm_gport_t gport,
   1304     bcm_switch_match_control_info_t *control_info)
   1305 {
   1306     int rv;
   1307     const bcmi_switch_match_service_info_t *sm_dev_info;
   1308 
   1309     MATCH_FUNCTION_TRACE(unit, "IN");
   1310 
   1311     /* Parameter NULL error handling */
   1312     MATCH_CHECK_NULL_PARAMETER(unit, control_info);
   1313 
   1314     /* Parameter validation check */
   1315     BCM_IF_ERROR_RETURN
   1316         (bcmi_switch_match_control_check(unit, match_service, control_type));
   1317 
   1318     /* Initialization check */
   1319     MATCH_CHECK_INIT(unit, match_service);
   1320 
   1321     sm_dev_info = MATCH_DEVICE_INFO(unit, match_service);
   1322 
   1323 
   1324     /* Check if the chip specific function existed */
   1325     MATCH_CHECK_NULL_DEV_INSTANCE(
   1326         unit, sm_dev_info->switch_match_control_get);
   1327 
   1328     MATCH_LOCK(unit);
   1329     bcm_switch_match_control_info_t_init(control_info);
   1330     rv = sm_dev_info->switch_match_control_get(unit,
   1331                                                control_type,
   1332                                                gport,
   1333                                                control_info);
   1334     if (BCM_FAILURE(rv)) {
   1335         MATCH_UNLOCK(unit);
   1336         LOG_ERROR(BSL_LS_BCM_SWITCH,
   1337                   (BSL_META_U(unit,
   1338                               "Read from HW failed(rv = %d)\n"),
   1339                               rv));
   1340         return rv;
   1341     }
   1342     MATCH_UNLOCK(unit);
   1343     MATCH_FUNCTION_TRACE(unit, "OUT");
   1344     return BCM_E_NONE;
   1345 }
   1346 
   1347 /*
   1348  * Function:
   1349  *    bcmi_switch_match_control_set
   1350  * Purpose:
   1351  *    Set the match related control information with given control type.
   1352  * Parameters:
   1353  *    unit - (IN) Unit number
   1354  *    match_service - (IN) Match service type
   1355  *    control_type - (IN) Match control type
   1356  *    gport - (IN) gport number for port basis control.
   1357  *                 Otherwise, BCM_GPORT_INVALID.
   1358  *    control_info - (IN) Match control information
   1359  * Returns:
   1360  *    BCM_E_xxx
   1361  */
   1362 int
   1363 bcmi_switch_match_control_set(
   1364     int unit,
   1365     bcm_switch_match_service_t match_service,
   1366     bcm_switch_match_control_type_t control_type,
   1367     bcm_gport_t gport,
   1368     bcm_switch_match_control_info_t *control_info)
   1369 {
   1370     int rv;
   1371     const bcmi_switch_match_service_info_t *sm_dev_info;
   1372 
   1373     MATCH_FUNCTION_TRACE(unit, "IN");
   1374 
   1375     /* Parameter NULL error handling */
   1376     MATCH_CHECK_NULL_PARAMETER(unit, control_info);
   1377 
   1378     /* Parameter validation check */
   1379     BCM_IF_ERROR_RETURN
   1380         (bcmi_switch_match_control_check(unit, match_service, control_type));
   1381 
   1382     /* Initialization check */
   1383     MATCH_CHECK_INIT(unit, match_service);
   1384 
   1385     sm_dev_info = MATCH_DEVICE_INFO(unit, match_service);
   1386 
   1387     /* Check if the chip specific function existed */
   1388     MATCH_CHECK_NULL_DEV_INSTANCE(
   1389         unit, sm_dev_info->switch_match_control_set);
   1390 
   1391     MATCH_LOCK(unit);
   1392     rv = sm_dev_info->switch_match_control_set(unit,
   1393                                                control_type,
   1394                                                gport,
   1395                                                control_info);
   1396     if (BCM_FAILURE(rv)) {
   1397         MATCH_UNLOCK(unit);
   1398         LOG_ERROR(BSL_LS_BCM_SWITCH,
   1399                   (BSL_META_U(unit,
   1400                               "Write to HW failed(rv = %d)\n"),
   1401                               rv));
   1402         return rv;
   1403     }
   1404     MATCH_UNLOCK(unit);
   1405     MATCH_FUNCTION_TRACE(unit, "OUT");
   1406     return BCM_E_NONE;
   1407 }
   1408 
   1409 /*
   1410  * Function:
   1411  *    bcmi_switch_match_control_traverse
   1412  * Purpose:
   1413  *    Traverse the match control information.
   1414  * Parameters:
   1415  *    unit - (IN) Unit number
   1416  *    match_service - (IN) Match service type
   1417  *    cb_fn - (IN) Traverse call back function
   1418  *    user_data - (IN) User data
   1419  * Returns:
   1420  *    BCM_E_xxx
   1421  */
   1422 int
   1423 bcmi_switch_match_control_traverse(
   1424     int unit,
   1425     bcm_switch_match_service_t match_service,
   1426     bcm_switch_match_control_traverse_cb cb_fn,
   1427     void *user_data)
   1428 {
   1429     bcm_error_t rv = BCM_E_NONE;
   1430     bcm_port_t port;
   1431     bcm_switch_match_control_info_t match_ctrl;
   1432 
   1433     MATCH_FUNCTION_TRACE(unit, "IN");
   1434 
   1435     /* Parameter NULL error handling */
   1436     MATCH_CHECK_NULL_PARAMETER(unit, cb_fn);
   1437 
   1438     /* Parameter validation check */
   1439     BCM_IF_ERROR_RETURN
   1440         (bcmi_switch_match_service_check(unit, match_service));
   1441 
   1442     /* Initialization check */
   1443     MATCH_CHECK_INIT(unit, match_service);
   1444 
   1445     MATCH_LOCK(unit);
   1446 
   1447     if (match_service == bcmSwitchMatchServiceMiml ||
   1448         match_service == bcmSwitchMatchServiceCustomHeader) {
   1449         /* Traverse all logical port with bcmSwitchMatchControlPortEnable */
   1450         PBMP_ALL_ITER(unit, port) {
   1451             bcm_switch_match_control_info_t_init(&match_ctrl);
   1452 
   1453             rv = bcmi_switch_match_control_get(unit,
   1454                                                match_service,
   1455                                                bcmSwitchMatchControlPortEnable,
   1456                                                port,
   1457                                                &match_ctrl);
   1458             if (BCM_SUCCESS(rv)) {
   1459                 rv = cb_fn(unit,
   1460                            bcmSwitchMatchControlPortEnable,
   1461                            port,
   1462                            &match_ctrl, user_data);
   1463                 if (BCM_FAILURE(rv)) {
   1464                     MATCH_UNLOCK(unit);
   1465                     return rv;
   1466                 }
   1467             }
   1468         }
   1469     }
   1470 
   1471     if (match_service == bcmSwitchMatchServiceCustomHeader) {
   1472 
   1473         /* Traverse bcmSwitchMatchControlMatchMask */
   1474         bcm_switch_match_control_info_t_init(&match_ctrl);
   1475         rv = bcmi_switch_match_control_get(unit,
   1476                                            match_service,
   1477                                            bcmSwitchMatchControlMatchMask,
   1478                                            BCM_GPORT_INVALID,
   1479                                            &match_ctrl);
   1480         if (BCM_SUCCESS(rv)) {
   1481             rv = cb_fn(unit,
   1482                        bcmSwitchMatchControlMatchMask,
   1483                        BCM_GPORT_INVALID,
   1484                        &match_ctrl,
   1485                        user_data);
   1486             if (BCM_FAILURE(rv)) {
   1487                 MATCH_UNLOCK(unit);
   1488                 return rv;
   1489             }
   1490         }
   1491     }
   1492     MATCH_UNLOCK(unit);
   1493     MATCH_FUNCTION_TRACE(unit, "OUT");
   1494     return BCM_E_NONE;
   1495 }
   1496 #endif /* BCM_SWITCH_MATCH_SUPPORT */
   1497