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

flow.c (33469B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        flow.c
      8  * Purpose:     Flex flow match APIs.
      9  */
     10 
     11 #if defined(INCLUDE_L3)
     12 #include <soc/drv.h>
     13 #include <soc/scache.h>
     14 
     15 #include <shared/bsl.h>
     16 #include <assert.h>
     17 #include <bcm/types.h>
     18 #include <bcm/error.h>
     19 #include <bcm/flow.h>
     20 #include <bcm_int/esw/flow.h>
     21 #include <soc/esw/flow_db.h>
     22 #include <bcm_int/esw_dispatch.h>
     23 
     24 /*
     25  * Function:
     26  *      bcm_esw_flow_vpn_create
     27  * Purpose:
     28  *      Create an L2/L3 VPN.  This is a service plane and is
     29  *      independent of the connectivity protocol.
     30  *   Parameters:
     31  *      unit        - (IN)  Unit ID.
     32  *      info    - (IN/OUT)  VPN structure
     33  */
     34 int bcm_esw_flow_vpn_create(int unit,
     35                             bcm_vpn_t *vpn,
     36                             bcm_flow_vpn_config_t *info)
     37 {
     38     int rv = BCM_E_UNAVAIL;
     39 #if defined(BCM_TRIDENT3_SUPPORT)
     40     if (soc_feature(unit,soc_feature_flex_flow)) {
     41          rv = bcmi_esw_flow_lock(unit);
     42          if (rv == BCM_E_NONE ) {
     43               rv = bcmi_esw_flow_vpn_create(unit, vpn, info);
     44               bcmi_esw_flow_unlock (unit);
     45          }    
     46     }
     47 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
     48 
     49     return rv;
     50 }
     51 
     52 /*
     53  * Function:
     54  *      bcm_esw_flow_vpn_destroy
     55  * Purpose:
     56  *      Delete L2/L3 VPN
     57  *   Parameters:
     58  *      unit   - (IN)  Unit ID.
     59  *      vpn    - (IN)  VPN Id
     60  */
     61 int bcm_esw_flow_vpn_destroy(int unit, bcm_vpn_t vpn)
     62 {
     63     int rv = BCM_E_UNAVAIL;
     64 
     65 #if defined(BCM_TRIDENT3_SUPPORT)
     66     if (soc_feature(unit,soc_feature_flex_flow)) {
     67         rv = bcmi_esw_flow_lock(unit);
     68         if (rv == BCM_E_NONE ) {
     69             rv = bcmi_esw_flow_vpn_destroy(unit, vpn);
     70             bcmi_esw_flow_unlock (unit);
     71         }    
     72     }
     73 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
     74 
     75     return rv;
     76 }
     77 
     78 /*
     79  * Function:
     80  *      bcm_esw_flow_vpn_destroy_all
     81  * Purpose:
     82  *      Delete all VPN's
     83  *   Parameters:
     84  *      unit   - (IN)  Unit ID.
     85  */
     86 int bcm_esw_flow_vpn_destroy_all(int unit)
     87 {
     88     int rv = BCM_E_UNAVAIL;
     89 
     90 #if defined(BCM_TRIDENT3_SUPPORT)
     91     if (soc_feature(unit,soc_feature_flex_flow)) {
     92         rv = bcmi_esw_flow_lock(unit);
     93         if (rv == BCM_E_NONE ) {
     94             rv = bcmi_esw_flow_vpn_destroy_all(unit);
     95             bcmi_esw_flow_unlock (unit);
     96         }    
     97     }
     98 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
     99 
    100     return rv;
    101 }
    102 
    103 /*
    104  * Function:
    105  *      bcm_esw_flow_vpn_get
    106  * Purpose:
    107  *      Get VPN properties
    108  *   Parameters:
    109  *      unit   - (IN)  Unit ID.
    110  *      vpn    - (IN)  VPN Id
    111  *      info    - (IN/OUT)  VPN structure
    112  */
    113 int bcm_esw_flow_vpn_get(int unit, bcm_vpn_t vpn,
    114                          bcm_flow_vpn_config_t *info)
    115 {
    116     int rv = BCM_E_UNAVAIL;
    117 
    118 #if defined(BCM_TRIDENT3_SUPPORT)
    119     if (soc_feature(unit,soc_feature_flex_flow)) {
    120         rv = bcmi_esw_flow_lock(unit);
    121         if (rv == BCM_E_NONE ) {
    122             rv = bcmi_esw_flow_vpn_get(unit, vpn, info);
    123             bcmi_esw_flow_unlock (unit);
    124         }    
    125     }
    126 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    127 
    128     return rv;
    129 }
    130 
    131 /*
    132  * Function:
    133  *      bcm_esw_flow_vpn_traverse
    134  * Purpose:
    135  *      Traverse VPN's
    136  *   Parameters:
    137  *      unit      - (IN)  Unit ID.
    138  *      cb        - (IN)  callback function
    139  *      user_data -  (IN) User context data
    140  */
    141 int bcm_esw_flow_vpn_traverse(int unit,
    142                               bcm_flow_vpn_traverse_cb cb,
    143                               void *user_data)
    144 {
    145     int rv = BCM_E_UNAVAIL;
    146 
    147 #if defined(BCM_TRIDENT3_SUPPORT)
    148     if (soc_feature(unit,soc_feature_flex_flow)) {
    149         rv = bcmi_esw_flow_lock(unit);
    150         if (rv == BCM_E_NONE ) {
    151             rv = bcmi_esw_flow_vpn_traverse(unit, cb, user_data);
    152             bcmi_esw_flow_unlock (unit);
    153         }    
    154     }
    155 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    156 
    157     return rv;
    158 }
    159 
    160 /*
    161  * Function:
    162  *      bcm_esw_flow_match_add
    163  * Description:
    164  *      Add a match rule to identify traffic flow with certain objects. 
    165  * These objects generally will be used in the switchs forwarding process. 
    166  * The matching rules comprise of packet fields and/or the port number the 
    167  * packet comes in.  The identified objects can be VFI,virtual port, interface 
    168  * id,  flexible objects specified by logical fields, or a combination of them.
    169  *
    170  * Parameters:
    171  *    Unit           (IN) Unit number
    172  *    info           (IN) Match info structure 
    173  *    num_of_fields  (IN) Number of logical fields
    174  *    field          (IN) logical field array 
    175  * Return Value:
    176  *      BCM_E_XXX
    177  * Notes:
    178  */
    179 
    180 int bcm_esw_flow_match_add(
    181     int unit,
    182     bcm_flow_match_config_t *info,
    183     uint32 num_of_fields,
    184     bcm_flow_logical_field_t *field)
    185 {
    186 #if defined(BCM_TRIDENT3_SUPPORT)
    187     if (soc_feature(unit,soc_feature_flex_flow)) {
    188         return bcmi_esw_flow_match_add(unit, info, num_of_fields, field);
    189     } else
    190 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    191     {
    192          return BCM_E_UNAVAIL;
    193     }
    194 }
    195 
    196 /*
    197  * Function:
    198  *      bcm_esw_flow_match_delete
    199  * Description:
    200  *      Delete a match rule for the given match_criteria. For the non-flex
    201  * match criteria, the logical field array is not used.
    202  *
    203  * Parameters:
    204  *    Unit           (IN) Unit number
    205  *    info           (IN) Match info structure
    206  *    num_of_fields  (IN) Number of logical fields
    207  *    field          (IN) logical field array
    208  * Return Value:
    209  *      BCM_E_XXX
    210  * Notes:
    211  */
    212 
    213 int bcm_esw_flow_match_delete(
    214     int unit,
    215     bcm_flow_match_config_t *info,
    216     uint32 num_of_fields,
    217     bcm_flow_logical_field_t *field)
    218 {
    219 #if defined(BCM_TRIDENT3_SUPPORT)
    220     if (soc_feature(unit,soc_feature_flex_flow)) {
    221         return bcmi_esw_flow_match_delete(unit, info, num_of_fields, field);
    222     } else
    223 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    224     {
    225          return BCM_E_UNAVAIL;
    226     }
    227 }
    228 
    229 /*
    230  * Function:
    231  *      bcm_esw_flow_match_get
    232  * Description:
    233  *      Get the match objects and attributes for the given match_criteria.
    234  *
    235  * Parameters:
    236  *    Unit           (IN) Unit number
    237  *    info           (IN/OUT) Match info structure
    238  *    num_of_fields  (IN) Number of logical fields
    239  *    field          (IN/OUT) logical field array
    240  * Return Value:
    241  *      BCM_E_XXX
    242  * Notes:
    243  */
    244 
    245 int bcm_esw_flow_match_get(
    246     int unit,
    247     bcm_flow_match_config_t *info,
    248     uint32 num_of_fields,
    249     bcm_flow_logical_field_t *field)
    250 {
    251 #if defined(BCM_TRIDENT3_SUPPORT)
    252     if (soc_feature(unit,soc_feature_flex_flow)) {
    253         return bcmi_esw_flow_match_get(unit, info, num_of_fields, field);
    254     } else
    255 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    256     {
    257          return BCM_E_UNAVAIL;
    258     }
    259 }
    260 
    261 /*
    262  * Function:
    263  *      bcm_esw_flow_match_traverse
    264  * Description:
    265  *      Traverse match rules.
    266  *
    267  * Parameters:
    268  *    Unit           (IN) Unit number
    269  *    info           (IN) Match info structure
    270  *    num_of_fields  (IN) Number of logical fields
    271  *    field          (IN) logical field array
    272  *    cb             (IN) user callback function
    273  *    user_data      (IN) User context data
    274  * Return Value:
    275  *      BCM_E_XXX
    276  * Notes:
    277  */
    278 
    279 int bcm_esw_flow_match_traverse(
    280     int unit,
    281     bcm_flow_match_traverse_cb cb,
    282     void *user_data)
    283 {
    284 #if defined(BCM_TRIDENT3_SUPPORT)
    285     if (soc_feature(unit,soc_feature_flex_flow)) {
    286         return bcmi_esw_flow_match_traverse(unit,cb,user_data);
    287     } else
    288 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    289     {
    290          return BCM_E_UNAVAIL;
    291     }
    292 }
    293 /*
    294  * Function:
    295  *      bcm_esw_flow_tunnel_initiator_create
    296  * Description:
    297  *      creates a tunnel header for packet encapsulation
    298  *
    299  * Parameters:
    300  *    Unit           (IN) Unit number
    301  *    info           (IN) tunnel config info structure
    302  *    num_of_fields  (IN) Number of logical fields
    303  *    field          (IN) logical field array
    304  * Return Value:
    305  *      BCM_E_XXX
    306  * Notes:
    307  */
    308 
    309 int bcm_esw_flow_tunnel_initiator_create(
    310     int unit,
    311     bcm_flow_tunnel_initiator_t *info,
    312     uint32 num_of_fields,
    313     bcm_flow_logical_field_t *field)
    314 {
    315 #if defined(BCM_TRIDENT3_SUPPORT)
    316     if (soc_feature(unit,soc_feature_flex_flow)) {
    317         return bcmi_esw_flow_tunnel_initiator_create(unit, info, 
    318                   num_of_fields, field);
    319     } else
    320 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    321     {
    322          return BCM_E_UNAVAIL;
    323     }
    324 }
    325 
    326 /*
    327  * Function:
    328  *      bcm_esw_flow_tunnel_initiator_destroy
    329  * Description:
    330  *      delete a tunnel header entry
    331  *
    332  * Parameters:
    333  *    Unit           (IN) Unit number
    334  *    flow_tunnel_id (IN) tunnel config info structure
    335  * Return Value:
    336  *      BCM_E_XXX
    337  * Notes:
    338  */ 
    339 
    340 int bcm_esw_flow_tunnel_initiator_destroy(
    341     int unit,
    342     bcm_gport_t flow_tunnel_id)
    343 {
    344 #if defined(BCM_TRIDENT3_SUPPORT)
    345     if (soc_feature(unit,soc_feature_flex_flow)) {
    346         return bcmi_esw_flow_tunnel_initiator_destroy(unit,flow_tunnel_id); 
    347     } else
    348 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    349     {
    350          return BCM_E_UNAVAIL;
    351     }
    352 }
    353 
    354 /*
    355  * Function:
    356  *      bcm_esw_flow_tunnel_initiator_get
    357  * Description:
    358  *      Get a tunnel header entry
    359  *
    360  * Parameters:
    361  *    Unit           (IN) Unit number
    362  *    info           (IN) tunnel config info structure
    363  *    num_of_fields  (IN) Number of logical fields
    364  *    field          (IN) logical field array
    365  * Return Value:
    366  *      BCM_E_XXX
    367  * Notes:
    368  */
    369 
    370 int bcm_esw_flow_tunnel_initiator_get(
    371     int unit,
    372     bcm_flow_tunnel_initiator_t *info,
    373     uint32 num_of_fields,
    374     bcm_flow_logical_field_t *field)
    375 {
    376 #if defined(BCM_TRIDENT3_SUPPORT)
    377     if (soc_feature(unit,soc_feature_flex_flow)) {
    378         return bcmi_esw_flow_tunnel_initiator_get(unit, info,
    379                   num_of_fields, field);
    380     } else
    381 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    382     {
    383          return BCM_E_UNAVAIL;
    384     }
    385 }
    386 
    387 /*
    388  * Function:
    389  *      bcm_esw_flow_tunnel_initiator_traverse
    390  * Description:
    391  *      Get a tunnel header entry
    392  *
    393  * Parameters:
    394  *    Unit           (IN) Unit number
    395  *    info           (IN) tunnel config info structure
    396  *    num_of_fields  (IN) Number of logical fields
    397  *    field          (IN) logical field array
    398  * Return Value:
    399  *      BCM_E_XXX
    400  * Notes:
    401  */
    402 
    403 int bcm_esw_flow_tunnel_initiator_traverse(
    404     int unit,
    405     bcm_flow_tunnel_initiator_traverse_cb cb,
    406     void *user_data)
    407 {
    408 #if defined(BCM_TRIDENT3_SUPPORT)
    409     if (soc_feature(unit,soc_feature_flex_flow)) {
    410         return bcmi_esw_flow_tunnel_initiator_traverse(unit, 
    411                   cb, user_data);
    412     } else
    413 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    414     {
    415          return BCM_E_UNAVAIL;
    416     }
    417 }
    418 
    419 /*
    420  * Function:
    421  *      bcm_esw_flow_tunnel_terminator_create
    422  * Description:
    423  *      creates a flow tunnel terminator match
    424  *
    425  * Parameters:
    426  *    Unit           (IN) Unit number
    427  *    info           (IN) tunnel config info structure
    428  *    num_of_fields  (IN) Number of logical fields
    429  *    field          (IN) logical field array
    430  * Return Value:
    431  *      BCM_E_XXX
    432  * Notes:
    433  */
    434 int bcm_esw_flow_tunnel_terminator_create(
    435     int unit,
    436     bcm_flow_tunnel_terminator_t *info,
    437     uint32 num_of_fields,
    438     bcm_flow_logical_field_t *field)
    439 {
    440 #if defined(BCM_TRIDENT3_SUPPORT)
    441     if (soc_feature(unit,soc_feature_flex_flow)) {
    442         return bcmi_esw_flow_tunnel_terminator_create(unit, info,
    443                     num_of_fields, field);
    444     } else
    445 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    446     {
    447          return BCM_E_UNAVAIL;
    448     }
    449 }
    450 
    451 /*
    452  * Function:
    453  *      bcm_esw_flow_tunnel_terminator_destroy
    454  * Description:
    455  *      delete a tunnel termination entry
    456  *
    457  * Parameters:
    458  *    Unit           (IN) Unit number
    459  *    info           (IN) tunnel config info structure
    460  *    num_of_fields  (IN) Number of logical fields
    461  *    field          (IN) logical field array
    462  * Return Value:
    463  *      BCM_E_XXX
    464  * Notes:
    465  */
    466 int bcm_esw_flow_tunnel_terminator_destroy(
    467     int unit,
    468     bcm_flow_tunnel_terminator_t *info,
    469     uint32 num_of_fields,
    470     bcm_flow_logical_field_t *field)
    471 {
    472 #if defined(BCM_TRIDENT3_SUPPORT)
    473     if (soc_feature(unit,soc_feature_flex_flow)) {
    474         return bcmi_esw_flow_tunnel_terminator_destroy(unit,
    475                info, num_of_fields, field);
    476     } else
    477 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    478     {
    479          return BCM_E_UNAVAIL;
    480     }
    481 }
    482 
    483 /*
    484  * Function:
    485  *      bcm_esw_flow_tunnel_terminator_get
    486  * Description:
    487  *      Get a tunnel termination entry
    488  *
    489  * Parameters:
    490  *    Unit           (IN) Unit number
    491  *    info           (IN) tunnel config info structure
    492  *    num_of_fields  (IN) Number of logical fields
    493  *    field          (IN) logical field array
    494  * Return Value:
    495  *      BCM_E_XXX
    496  * Notes:
    497  */
    498 int bcm_esw_flow_tunnel_terminator_get(
    499     int unit,
    500     bcm_flow_tunnel_terminator_t *info,
    501     uint32 num_of_fields,
    502     bcm_flow_logical_field_t *field)
    503 {
    504 #if defined(BCM_TRIDENT3_SUPPORT)
    505     if (soc_feature(unit,soc_feature_flex_flow)) {
    506         return bcmi_esw_flow_tunnel_terminator_get(unit, 
    507                info, num_of_fields, field);
    508     } else
    509 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    510     {
    511          return BCM_E_UNAVAIL;
    512     }
    513 }
    514 /*
    515  * Function:
    516  *      bcm_esw_flow_tunnel_terminator_traverse
    517  * Description:
    518  *      Get a tunnel termination entry
    519  *
    520  * Parameters:
    521  *    Unit           (IN)     Unit number
    522  *    cb             (IN)     Traverse function
    523  *    user_data      (IN/OUT) User Data
    524  * Return Value:
    525  *      BCM_E_XXX
    526  * Notes:
    527  */
    528 int bcm_esw_flow_tunnel_terminator_traverse(
    529     int unit,
    530     bcm_flow_tunnel_terminator_traverse_cb cb,
    531     void *user_data)
    532 {
    533 #if defined(BCM_TRIDENT3_SUPPORT)
    534     if (soc_feature(unit,soc_feature_flex_flow)) {
    535         return bcmi_esw_flow_tunnel_terminator_traverse(unit, 
    536                cb, user_data);
    537     } else
    538 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    539     {
    540          return BCM_E_UNAVAIL;
    541     }
    542 }
    543 
    544 /*
    545  * Function:
    546  *      bcm_esw_flow_port_encap_set
    547  * Description:
    548  *      For given DVP, bind the egress object and tunnel initiator with 
    549  * the DVP and program DVP related encap data for L2 tunnel. 
    550  *
    551  * Parameters:
    552  *    Unit           (IN) Unit number
    553  *    info           (IN) egress encap info structure
    554  *    num_of_fields  (IN) Number of logical fields
    555  *    field          (IN) logical field array
    556  * Return Value:
    557  *      BCM_E_XXX
    558  * Notes:
    559  */
    560 
    561 int bcm_esw_flow_port_encap_set(
    562     int unit,
    563     bcm_flow_port_encap_t *info,
    564     uint32 num_of_fields,
    565     bcm_flow_logical_field_t *field)
    566 {
    567 #if defined(BCM_TRIDENT3_SUPPORT)
    568     if (soc_feature(unit,soc_feature_flex_flow)) {
    569         return bcmi_esw_flow_port_encap_set(unit, info,
    570                   num_of_fields, field);
    571     } else
    572 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    573     {
    574          return BCM_E_UNAVAIL;
    575     }
    576 }
    577 
    578 /*
    579  * Function:
    580  *      bcm_esw_flow_port_encap_get
    581  * Description:
    582  *      Get the encap configuration info for the given DVP  
    583  *
    584  * Parameters:
    585  *    Unit           (IN) Unit number
    586  *    info           (IN/OUT) egress encap info structure
    587  *    num_of_fields  (IN) Number of logical fields
    588  *    field          (IN/OUT) logical field array
    589  * Return Value:
    590  *      BCM_E_XXX
    591  * Notes:
    592  */
    593 
    594 int bcm_esw_flow_port_encap_get(
    595     int unit,
    596     bcm_flow_port_encap_t *info,
    597     uint32 num_of_fields,
    598     bcm_flow_logical_field_t *field)
    599 {
    600 #if defined(BCM_TRIDENT3_SUPPORT)
    601     if (soc_feature(unit,soc_feature_flex_flow)) {
    602         return bcmi_esw_flow_port_encap_get(unit, info,
    603                   num_of_fields, field);
    604     } else
    605 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    606     {
    607          return BCM_E_UNAVAIL;
    608     }
    609 }
    610 
    611 /*
    612  * Function:
    613  *      bcm_esw_flow_encap_add
    614  * Description:
    615  *      add the object(key) based encapsulation data to the packet. The objects
    616  * can be VP,VFI,VRF,interface ID, specified by logical fields, or combination 
    617  * of them. The encapsulation data comprises of fields in the 
    618  * bcm_flow_encap_config_t and/or logical fields 
    619  *
    620  * Parameters:
    621  *    Unit           (IN) Unit number
    622  *    info           (IN) encap config info structure
    623  *    num_of_fields  (IN) Number of logical fields
    624  *    field          (IN) logical field array
    625  * Return Value:
    626  *      BCM_E_XXX
    627  * Notes:
    628  */
    629 
    630 int bcm_esw_flow_encap_add(
    631     int unit,
    632     bcm_flow_encap_config_t *info,
    633     uint32 num_of_fields,
    634     bcm_flow_logical_field_t *field)
    635 {
    636 #if defined(BCM_TRIDENT3_SUPPORT)
    637     if (soc_feature(unit,soc_feature_flex_flow)) {
    638         return bcmi_esw_flow_encap_add(unit, info,
    639                   num_of_fields, field);
    640     } else
    641 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    642     {
    643          return BCM_E_UNAVAIL;
    644     }
    645 }
    646 
    647 /*
    648  * Function:
    649  *      bcm_esw_flow_encap_delete
    650  * Description:
    651  *      Delete the object(key) based encapsulation data. 
    652  *
    653  * Parameters:
    654  *    Unit           (IN) Unit number
    655  *    info           (IN) encap config info structure
    656  *    num_of_fields  (IN) Number of logical fields
    657  *    field          (IN) logical field array
    658  * Return Value:
    659  *      BCM_E_XXX
    660  * Notes:
    661  */
    662 
    663 int bcm_esw_flow_encap_delete(
    664     int unit,
    665     bcm_flow_encap_config_t *info,
    666     uint32 num_of_fields,
    667     bcm_flow_logical_field_t *field)
    668 {
    669 #if defined(BCM_TRIDENT3_SUPPORT)
    670     if (soc_feature(unit,soc_feature_flex_flow)) {
    671         return bcmi_esw_flow_encap_delete(unit, info,
    672                   num_of_fields, field);
    673     } else
    674 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    675     {
    676          return BCM_E_UNAVAIL;
    677     }
    678 }
    679 
    680 /*
    681  * Function:
    682  *      bcm_esw_flow_encap_get
    683  * Description:
    684  *      Get the object(key) based encapsulation data.
    685  *
    686  * Parameters:
    687  *    Unit           (IN) Unit number
    688  *    info           (IN/OUT) encap config info structure
    689  *    num_of_fields  (IN) Number of logical fields
    690  *    field          (IN/OUT) logical field array
    691  * Return Value:
    692  *      BCM_E_XXX
    693  * Notes:
    694  */
    695 
    696 int bcm_esw_flow_encap_get(
    697     int unit,
    698     bcm_flow_encap_config_t *info,
    699     uint32 num_of_fields,
    700     bcm_flow_logical_field_t *field)
    701 {
    702 #if defined(BCM_TRIDENT3_SUPPORT)
    703     if (soc_feature(unit,soc_feature_flex_flow)) {
    704         return bcmi_esw_flow_encap_get(unit, info,
    705                   num_of_fields, field);
    706     } else
    707 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    708     {
    709          return BCM_E_UNAVAIL;
    710     }
    711 }
    712 
    713 /*
    714  * Function:
    715  *      bcm_esw_flow_encap_traverse
    716  * Description:
    717  *      Traverse the object(key) based encapsulation data entries.
    718  *
    719  * Parameters:
    720  *    Unit           (IN) Unit number
    721  *    info           (IN) encap config info structure
    722  *    num_of_fields  (IN) Number of logical fields
    723  *    field          (IN) logical field array
    724  *    cb             (IN) user callback function
    725  *    user_data      (IN) user context data
    726  * Return Value:
    727  *      BCM_E_XXX
    728  * Notes:
    729  */
    730 
    731 int bcm_esw_flow_encap_traverse(
    732     int unit,
    733     bcm_flow_encap_traverse_cb cb,
    734     void *user_data)
    735 {
    736 #if defined(BCM_TRIDENT3_SUPPORT)
    737     if (soc_feature(unit,soc_feature_flex_flow)) {
    738         return bcmi_esw_flow_encap_traverse(unit,cb,user_data);
    739     } else
    740 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    741     {
    742          return BCM_E_UNAVAIL;
    743     }
    744 }
    745 
    746 /*
    747  * Function:
    748  *    bcm_esw_flow_init
    749  * Purpose:
    750  *    Init  FLOW module
    751  * Parameters:
    752  *    IN :  unit
    753  * Returns:
    754  *    BCM_E_XXX
    755  */
    756 
    757 int
    758 bcm_esw_flow_init(int unit)
    759 {
    760 #if defined(BCM_TRIDENT3_SUPPORT)
    761     if (soc_feature(unit, soc_feature_flex_flow)) {
    762         return bcmi_esw_flow_init(unit);
    763     }    
    764 #endif /* BCM_TRIDENT3_SUPPORT */
    765     return BCM_E_UNAVAIL;
    766 }
    767 
    768  /* Function:
    769  *      bcm_esw_flow_cleanup
    770  * Purpose:
    771  *      Detach the FLOW module, clear all HW states
    772  * Parameters:
    773  *      unit     - Device Number
    774  * Returns:
    775  *      BCM_E_XXXX
    776  */
    777 
    778 int
    779 bcm_esw_flow_cleanup(int unit)
    780 {
    781 #if defined(BCM_TRIDENT3_SUPPORT)
    782     if (soc_feature(unit, soc_feature_flex_flow)) {
    783         return bcmi_esw_flow_cleanup(unit);
    784     }
    785 #endif /* BCM_TRIDENT3_SUPPORT */
    786     return BCM_E_UNAVAIL;
    787 }
    788 
    789 /*
    790  * Function:
    791  *      bcm_esw_flow_port_create
    792  * Purpose:
    793  *      Create and add a Access/Network Flow port to L2 VPN
    794  *   Parameters:
    795  *      unit        - (IN)  Unit ID.
    796  *      info    - (IN/OUT)  VP properties 
    797  */
    798 int
    799 bcm_esw_flow_port_create(int unit,
    800                         bcm_vpn_t l2vpn,
    801                         bcm_flow_port_t *flow_port)
    802 {
    803     int rv = BCM_E_UNAVAIL;
    804 #if defined(BCM_TRIDENT3_SUPPORT)
    805     if (soc_feature(unit, soc_feature_flex_flow)) {
    806          if (flow_port == NULL) {
    807             return BCM_E_PARAM;
    808          }    
    809          rv = bcmi_esw_flow_lock(unit);
    810          if ( rv == BCM_E_NONE ) {
    811               rv = bcmi_esw_flow_port_create(unit, l2vpn, flow_port);
    812               bcmi_esw_flow_unlock (unit);
    813          }    
    814     }    
    815 #endif
    816     return rv;
    817 }
    818 
    819  /* Function:
    820  *      bcm_esw_flow_port_destroy
    821  * Purpose:
    822  *      Destroy Access/Network FLOW port
    823  * Parameters:
    824  *      unit     - Device Number
    825  *      l2vpn   - FLOW VPN
    826  *      flow_port_id     - FLOW Gport Id
    827  * Returns:
    828  *      BCM_E_XXXX
    829  */
    830 
    831 int 
    832 bcm_esw_flow_port_destroy( int unit, bcm_vpn_t l2vpn, bcm_gport_t flow_port_id)
    833 {
    834     int rv = BCM_E_UNAVAIL;
    835 #if defined(BCM_TRIDENT3_SUPPORT)
    836     if (soc_feature(unit, soc_feature_flex_flow)) {
    837          rv = bcmi_esw_flow_lock(unit);
    838          if ( rv == BCM_E_NONE ) {
    839               rv = bcmi_esw_flow_port_destroy(unit, l2vpn, flow_port_id);
    840               bcmi_esw_flow_unlock (unit);
    841          }
    842     }
    843 #endif
    844     return rv;
    845 }
    846 
    847  /* Function:
    848  *      bcm_esw_flow_port_get
    849  * Purpose:
    850  *      Get Access/Network FLOW port info
    851  * Parameters:
    852  *      unit     - Device Number
    853  *      l2vpn   - FLOW VPN
    854  *      flow_port     - FLOW Gport
    855  * Returns:
    856  *      BCM_E_XXXX
    857  */
    858 
    859 int 
    860 bcm_esw_flow_port_get(int unit, bcm_vpn_t l2vpn, bcm_flow_port_t *flow_port)
    861 {
    862     int rv = BCM_E_UNAVAIL;
    863 #if defined(BCM_TRIDENT3_SUPPORT)
    864     if (soc_feature(unit, soc_feature_flex_flow)) {
    865          if (flow_port == NULL) {
    866             return BCM_E_PARAM;
    867          }
    868          rv = bcmi_esw_flow_lock(unit);
    869          if ( rv == BCM_E_NONE ) {
    870               rv = bcmi_esw_flow_port_get(unit, l2vpn, flow_port);
    871               bcmi_esw_flow_unlock (unit);
    872          }
    873     }
    874 #endif
    875     return rv;
    876 }
    877 
    878  /* Function:
    879  *      bcm_esw_flow_port_get_all
    880  * Purpose:
    881  *      Get all Access/Network FLOW port info
    882  * Parameters:
    883  *      unit     - (IN) Device Number
    884  *      l2vpn   - FLOW VPN
    885  *      port_max   - (IN) Maximum number of FLOW ports in array
    886  *      port_array - (OUT) Array of FLOW ports
    887  *      port_count - (OUT) Number of FLOW ports returned in array
    888  * Returns:
    889  *      BCM_E_XXXX
    890  */
    891 
    892 int 
    893 bcm_esw_flow_port_get_all(
    894     int unit, 
    895     bcm_vpn_t l2vpn, 
    896     int port_max, 
    897     bcm_flow_port_t *port_array, 
    898     int *port_count)
    899 {
    900     int rv = BCM_E_UNAVAIL;
    901 #if defined(BCM_TRIDENT3_SUPPORT)
    902     if (soc_feature(unit, soc_feature_flex_flow)) {
    903          if (port_count == NULL) {
    904             return BCM_E_PARAM;
    905          }
    906          rv = bcmi_esw_flow_lock(unit);
    907          if ( rv == BCM_E_NONE ) {
    908               rv = bcmi_esw_flow_port_get_all(unit, l2vpn, port_max, port_array, port_count);
    909               bcmi_esw_flow_unlock (unit);
    910          }
    911     }
    912 #endif
    913     return rv;
    914 }
    915 
    916 /*
    917  * Function:
    918  *      bcm_esw_flow_handle_get
    919  * Description:
    920  *      Get the handle for the flow name.
    921  * Parameters:
    922  *    Unit           (IN)     Unit number.
    923  *    flow_name      (IN)     Flow Name.
    924  *    handle         (IN/OUT) Flow Handle.
    925  * Return Value:
    926  *      BCM_E_XXX
    927  * Notes:
    928  */
    929 
    930 int bcm_esw_flow_handle_get(
    931     int unit,
    932     const char *flow_name,
    933     bcm_flow_handle_t *handle)
    934 {
    935 #if defined(BCM_TRIDENT3_SUPPORT)
    936     if (soc_feature(unit,soc_feature_flex_flow)) {
    937         return soc_flow_db_flow_handle_get(unit, flow_name, handle);
    938     } else
    939 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    940     {
    941          return BCM_E_UNAVAIL;
    942     }
    943 }
    944 
    945 /*
    946  * Function:
    947  *      bcm_esw_flow_option_id_get
    948  * Description:
    949  *      Get the option id for flow option name.
    950  * Parameters:
    951  *    Unit              (IN)     Unit number.
    952  *    handle            (IN)     Flow Handle.
    953  *    flow_option_name  (IN)     Flow Option Name.
    954  *    option_id         (IN/OUT) Flow Option ID.
    955  * Return Value:
    956  *      BCM_E_XXX
    957  * Notes:
    958  */
    959 
    960 int bcm_esw_flow_option_id_get(
    961     int unit,
    962     bcm_flow_handle_t flow_handle,
    963     const char *flow_option_name,
    964     bcm_flow_option_id_t *option_id)
    965 {
    966 #if defined(BCM_TRIDENT3_SUPPORT)
    967     if (soc_feature(unit,soc_feature_flex_flow)) {
    968         return soc_flow_db_flow_option_id_get(unit, flow_handle,
    969                                     flow_option_name,
    970                                     option_id);
    971     } else
    972 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
    973     {
    974          return BCM_E_UNAVAIL;
    975     }
    976 }
    977 
    978 /*
    979  * Function:
    980  *      bcm_esw_flow_field_id_get
    981  * Description:
    982  *      Get the field id for logical field name in a flow.
    983  * Parameters:
    984  *    Unit                (IN)     Unit number.
    985  *    flow_handle         (IN)     Flow Handle.
    986  *    flow_option_name    (IN)     Flow Option Name.
    987  *    option_id           (IN/OUT) Flow Option ID.
    988  * Return Value:
    989  *      BCM_E_XXX
    990  * Notes:
    991  */
    992 
    993 int bcm_esw_flow_logical_field_id_get(
    994     int unit,
    995     bcm_flow_handle_t flow_handle,
    996     const char *field_name,
    997     bcm_flow_field_id_t *field_id)
    998 {
    999 #if defined(BCM_TRIDENT3_SUPPORT)
   1000     if (soc_feature(unit,soc_feature_flex_flow)) {
   1001         return soc_flow_db_mem_view_logical_field_id_get(unit, flow_handle,
   1002                                                          field_name,
   1003                                                          field_id);
   1004     } else
   1005 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
   1006     {
   1007          return BCM_E_UNAVAIL;
   1008     }
   1009 }
   1010 
   1011 /*
   1012  * Function:
   1013  *      bcm_esw_flow_stat_object_get
   1014  * Purpose:
   1015  *      Get the accounting stat object associated
   1016  *          with the flex view of the  table.
   1017  * Parameters:
   1018  *      unit                  - (IN)     unit number.
   1019  *      flow_handle           - (IN)     flow handle.
   1020  *      flow_option_id        - (IN)     flow option id.
   1021  *      flow_function_type    - (IN)     flow function type.
   1022  *      stat object           - (IN/OUT) Stat accounting object.
   1023  *
   1024  * Returns:
   1025  *      BCM_E_XXX
   1026  *
   1027  * Notes:
   1028  */
   1029 int bcm_esw_flow_stat_object_get(int unit,
   1030                           bcm_flow_handle_t flow_handle,
   1031                           bcm_flow_option_id_t flow_option_id,
   1032                           bcm_flow_function_type_t function_type,
   1033                           bcm_stat_object_t *stat_object)
   1034 {
   1035 #if defined(BCM_TRIDENT3_SUPPORT)
   1036     if (soc_feature(unit,soc_feature_flex_flow)) {
   1037 
   1038         if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
   1039             return BCM_E_UNAVAIL;
   1040         }
   1041         return bcmi_esw_flow_stat_object_get(unit, flow_handle,
   1042                                  flow_option_id, function_type,
   1043                                   stat_object);
   1044 
   1045     } else
   1046 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
   1047     {
   1048         return BCM_E_UNAVAIL;
   1049     }
   1050 }
   1051 
   1052 /*
   1053  * Function:
   1054  *      bcm_esw_flow_stat_attach
   1055  * Purpose:
   1056  *      Attach counter entries to the given flex view table.
   1057  * Parameters:
   1058  *      unit                - (IN)     unit number.
   1059  *      flow_stat_info      - (IN)     flow stat config structure.
   1060  *      num_of_fields       - (IN)     number of logical fields.
   1061  *      field               - (IN)     logical fields.
   1062  *      stat_counter_id     - (IN)     stat counter id.
   1063  *
   1064  * Returns:
   1065  *      BCM_E_XXX
   1066  *
   1067  * Notes:
   1068  */
   1069 int bcm_esw_flow_stat_attach(int unit,
   1070                           bcm_flow_stat_info_t *flow_stat_info,
   1071                           uint32 num_of_fields,
   1072                           bcm_flow_logical_field_t *field,
   1073                           uint32 stat_counter_id)
   1074 {
   1075 #if defined(BCM_TRIDENT3_SUPPORT)
   1076     if (soc_feature(unit,soc_feature_flex_flow)) {
   1077         if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
   1078             return BCM_E_UNAVAIL;
   1079         }
   1080         if (NULL == flow_stat_info) {
   1081             return BCM_E_PARAM;
   1082         }
   1083         return bcmi_esw_flow_stat_attach(unit, flow_stat_info,
   1084                                          num_of_fields, field,
   1085                                          stat_counter_id);
   1086     } else
   1087 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
   1088     {
   1089         return BCM_E_UNAVAIL;
   1090     }
   1091 }
   1092 
   1093 /*
   1094  * Function:
   1095  *      bcm_esw_flow_stat_detach
   1096  * Purpose:
   1097  *      Detach counter entries to the given flex view table.
   1098  * Parameters:
   1099  *      unit                - (IN)     unit number.
   1100  *      flow_stat_info      - (IN)     flow stat config structure.
   1101  *      num_of_fields       - (IN)     number of logical fields.
   1102  *      field               - (IN)     logical fields.
   1103  *      stat_counter_id     - (IN)     stat counter id.
   1104  *
   1105  * Returns:
   1106  *      BCM_E_XXX
   1107  *
   1108  * Notes:
   1109  */
   1110 int bcm_esw_flow_stat_detach(int unit,
   1111                           bcm_flow_stat_info_t *flow_stat_info,
   1112                           uint32 num_of_fields,
   1113                           bcm_flow_logical_field_t *field,
   1114                           uint32 stat_counter_id)
   1115 {
   1116 #if defined(BCM_TRIDENT3_SUPPORT)
   1117     if (soc_feature(unit,soc_feature_flex_flow)) {
   1118         if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
   1119             return BCM_E_UNAVAIL;
   1120         }
   1121         if (NULL == flow_stat_info) {
   1122             return BCM_E_PARAM;
   1123         }
   1124         return  bcmi_esw_flow_stat_detach(unit, flow_stat_info,
   1125                                          num_of_fields, field, stat_counter_id);
   1126     } else
   1127 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
   1128     {
   1129         return BCM_E_UNAVAIL;
   1130     }
   1131 }
   1132 
   1133 /*
   1134  * Function:
   1135  *      bcm_esw_flow_stat_id_get
   1136  * Purpose:
   1137  *      Get Stat Counter if associated with flex view.
   1138  * Parameters:
   1139  *      unit                - (IN)     unit number.
   1140  *      flow_stat_info      - (IN)     flow stat config structure.
   1141  *      num_of_fields       - (IN)     number of logical fields.
   1142  *      field               - (IN)     logical fields.
   1143  *      stat_object         - (IN)     stat object.
   1144  *      stat_counter_id     - (IN/OUT) stat counter id.
   1145  *
   1146  * Returns:
   1147  *      BCM_E_XXX
   1148  *
   1149  * Notes:
   1150  */
   1151 int bcm_esw_flow_stat_id_get(int unit,
   1152                          bcm_flow_stat_info_t *flow_stat_info,
   1153                          uint32 num_of_fields,
   1154                          bcm_flow_logical_field_t *field,
   1155                          bcm_stat_object_t stat_object,
   1156                          uint32 *stat_counter_id)
   1157 {
   1158 #if defined(BCM_TRIDENT3_SUPPORT)
   1159     if (soc_feature(unit,soc_feature_flex_flow)) {
   1160         if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
   1161             return BCM_E_UNAVAIL;
   1162         }
   1163         if (NULL == flow_stat_info) {
   1164             return BCM_E_PARAM;
   1165         }
   1166         if (NULL == stat_counter_id) {
   1167             return BCM_E_PARAM;
   1168         }
   1169         return  bcmi_esw_flow_stat_id_get(unit, flow_stat_info,
   1170                                          num_of_fields, field,
   1171                                          stat_object,
   1172                                          stat_counter_id);
   1173     } else
   1174 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
   1175     {
   1176         return BCM_E_UNAVAIL;
   1177     }
   1178 }
   1179 
   1180 /*
   1181  * Function:
   1182  *      _bcm_esw_flow_port_source_vp_lag_set
   1183  * Purpose:
   1184  *      Set source VP LAG for a flow virtual port.
   1185  * Parameters:
   1186  *      unit      - (IN) SOC unit number.
   1187  *      gport     - (IN) flow virtual port GPORT ID.
   1188  *      vp_lag_vp - (IN) VP representing the VP LAG.
   1189  * Returns:
   1190  *      BCM_X_XXX
   1191  */
   1192 int
   1193 _bcm_esw_flow_port_source_vp_lag_set(
   1194     int unit, bcm_gport_t gport, int vp_lag_vp)
   1195 {
   1196     int rv = BCM_E_UNAVAIL;
   1197 
   1198 #if defined(BCM_TRIDENT3_SUPPORT)
   1199     if (soc_feature(unit, soc_feature_flex_flow) &&
   1200         soc_feature(unit, soc_feature_vp_lag)) {
   1201         if (!_SHR_GPORT_IS_FLOW_PORT(gport)) {
   1202             return BCM_E_PARAM;
   1203         }
   1204         rv = bcmi_esw_flow_match_svp_replace(unit, gport, vp_lag_vp);
   1205     } else
   1206 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
   1207     {
   1208         return BCM_E_UNAVAIL;
   1209     }
   1210 
   1211     return rv;
   1212 }
   1213 
   1214 /*
   1215  * Function:
   1216  *      _bcm_esw_flow_port_source_vp_lag_clear
   1217  * Purpose:
   1218  *      Set source VP LAG for a flow virtual port.
   1219  * Parameters:
   1220  *      unit      - (IN) SOC unit number.
   1221  *      gport     - (IN) flow virtual port GPORT ID.
   1222  *      vp_lag_vp - (IN) VP representing the VP LAG.
   1223  * Returns:
   1224  *      BCM_X_XXX
   1225  */
   1226 int
   1227 _bcm_esw_flow_port_source_vp_lag_clear(
   1228     int unit, bcm_gport_t gport, int vp_lag_vp)
   1229 {
   1230     int rv = BCM_E_UNAVAIL;
   1231 #if defined(BCM_TRIDENT3_SUPPORT)
   1232     int vp;
   1233 
   1234     if (soc_feature(unit, soc_feature_flex_flow) &&
   1235         soc_feature(unit, soc_feature_vp_lag)) {
   1236         if (!_SHR_GPORT_IS_FLOW_PORT(gport)) {
   1237             return BCM_E_PARAM;
   1238         }
   1239         vp = _SHR_GPORT_FLOW_PORT_ID_GET(gport);
   1240 
   1241         rv = bcmi_esw_flow_match_svp_replace(unit, gport, vp);
   1242     } else
   1243 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
   1244     {
   1245         return BCM_E_UNAVAIL;
   1246     }
   1247 
   1248     return rv;
   1249 }
   1250 
   1251 /*
   1252  * Function:
   1253  *      _bcm_esw_flow_port_source_vp_lag_get
   1254  * Purpose:
   1255  *      Set source VP LAG for a flow virtual port.
   1256  * Parameters:
   1257  *      unit      - (IN) SOC unit number.
   1258  *      gport     - (IN) flow virtual port GPORT ID.
   1259  *      vp_lag_vp - (IN) PTR of VP representing the VP LAG.
   1260  * Returns:
   1261  *      BCM_X_XXX
   1262  */
   1263 int
   1264 _bcm_esw_flow_port_source_vp_lag_get(
   1265     int unit, bcm_gport_t gport, int* vp_lag_vp)
   1266 {
   1267     int rv = BCM_E_UNAVAIL;
   1268 #if defined(BCM_TRIDENT3_SUPPORT)
   1269     if (soc_feature(unit, soc_feature_flex_flow) &&
   1270         soc_feature(unit, soc_feature_vp_lag)) {
   1271         if (!_SHR_GPORT_IS_FLOW_PORT(gport)) {
   1272             return BCM_E_PARAM;
   1273         }
   1274         rv = bcmi_esw_flow_match_svp_get(unit, gport, vp_lag_vp);
   1275     } else
   1276 #endif /* defined(BCM_TRIDENT3_SUPPORT) */
   1277     {
   1278         return BCM_E_UNAVAIL;
   1279     }
   1280 
   1281     return rv;
   1282 }
   1283 
   1284 #else   /* INCLUDE_L3 */
   1285  int bcm_esw_flow_not_empty;
   1286 #endif  /* INCLUDE_L3 */
   1287 
   1288