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

vlan.c (14063B)


      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:    vlan.c
      8  * Purpose: Handle Greyhound2 specific vlan features:
      9  *          Manages VFI VLAN membership tables.
     10  */
     11 
     12 #include <soc/defs.h>
     13 #include <sal/core/libc.h>
     14 
     15 #if defined(BCM_GREYHOUND2_SUPPORT) && defined(INCLUDE_L3)
     16 #include <bcm_int/common/multicast.h>
     17 
     18 #include <bcm_int/esw/firebolt.h>
     19 #include <bcm_int/esw/greyhound2.h>
     20 
     21 /*
     22  * Function:
     23  *    bcmi_gh2_vfi_control_params_check
     24  * Purpose:
     25  *    Verifies if input parameters are valid for the operation on the device
     26  * Parameters:
     27  *    unit         - (IN) Unit number
     28  *    vid          - (IN) Vlan id
     29  *    valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK
     30  *    control      - (IN) Configuration structure
     31  * Returns:
     32  *    BCM_E_PARAM for errorneous inputs
     33  *    BCM_E_NONE  if all memebers in the structure are legal
     34  */
     35 STATIC int
     36 bcmi_gh2_vfi_control_params_check(
     37     int unit,
     38     bcm_vlan_t vid,
     39     uint32 valid_fields,
     40     bcm_vlan_control_vlan_t *control)
     41 {
     42     uint32 supported_fields = 0;
     43     uint32 supported_flags = 0;
     44 
     45     /*
     46      * VFI table in GH2-B0 supports only the following fields:
     47      *
     48      *  - L3_IIF           : Layer3 Incoming Interface to be assigned to the packet
     49      *  - UUC_UMC_BC_INDEX : Default unknown unicast/multicast/broadcast group
     50      *                       for this VFI
     51      */
     52     supported_fields = (BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK |
     53                         BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK |
     54                         BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK |
     55                         BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK);
     56 
     57     /*
     58      *  - IPMCV4_L2_ENABLE  : Enables L2-only forwarding of IPMCv4 packets
     59      *  - IPMCV6_L2_ENABLE  : Enables L2-only forwarding of IPMCv6 packets
     60      *  - IPMCV4_ENABLE     : IPMC Enable for IPV4 packets on the VFI
     61      *  - IPMCV6_ENABLE     : IPMC Enable for IPV6 packets on the VFI
     62      *  - IPV4_ENABLE       : Enables IPV4 Routing in this VFI
     63      *  - IPV6_ENABLE       : Enables IPV6 Routing in this VFI
     64      *  - L2_NON_UCAST_DROP : Drop all broadcast and multicast packets
     65      *  - L2_NON_UCAST_TOCPU: Copy all broadcast and multicast packets to CPU
     66      *  - L2_DA_MISS_DROP   : Drop packet thas miss L2 DA unicast, Do not flood
     67      *  - L2_DA_MISS_TOCPU  : Copy packet thas miss L2 DA unicast to the CPU
     68      *  - L2_SA_MISS_TOCPU  : Copy packet thas miss L2 SA unicast to the CPU
     69      *    Note: L2_SA_MISS_TOCPU shares the same flags with L2_DA_MISS_TOCPU
     70      */
     71     supported_flags = (BCM_VLAN_IP4_MCAST_L2_DISABLE |
     72                        BCM_VLAN_IP6_MCAST_L2_DISABLE |
     73                        BCM_VLAN_IP4_MCAST_DISABLE |
     74                        BCM_VLAN_IP6_MCAST_DISABLE |
     75                        BCM_VLAN_IP4_DISABLE |
     76                        BCM_VLAN_IP6_DISABLE |
     77                        BCM_VLAN_NON_UCAST_DROP |
     78                        BCM_VLAN_NON_UCAST_TOCPU |
     79                        BCM_VLAN_UNKNOWN_UCAST_DROP |
     80                        BCM_VLAN_UNKNOWN_UCAST_TOCPU);
     81 
     82     if (valid_fields != BCM_VLAN_CONTROL_VLAN_ALL_MASK) {
     83         if ((~supported_fields) & valid_fields) {
     84             return BCM_E_PARAM;
     85         }
     86     }
     87 
     88     if ((~supported_flags) & control->flags) {
     89         return BCM_E_PARAM;
     90     }
     91 
     92     VLAN_CHK_ID(unit, control->egress_vlan);
     93     if (!soc_feature(unit, soc_feature_vp_sharing)) {
     94         if (control->egress_vlan != BCM_VLAN_NONE) {
     95             return BCM_E_PARAM;
     96         }
     97     }
     98 
     99     return BCM_E_NONE;
    100 }
    101 
    102 /*
    103  * Function:
    104  *    bcmi_gh2_vlan_control_vpn_set
    105  * Purpose:
    106  *    Configures various controls on the VFI
    107  * Parameters:
    108  *    unit         - (IN) Unit number
    109  *    vid          - (IN) Vlan id
    110  *    valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK
    111  *    control      - (IN) Configuration structure
    112  * Return:
    113  *    BCM_E_XXX
    114  */
    115 int
    116 bcmi_gh2_vlan_control_vpn_set(
    117     int unit,
    118     bcm_vlan_t vid,
    119     uint32 valid_fields,
    120     bcm_vlan_control_vlan_t *control)
    121 {
    122     int rv = BCM_E_NONE;
    123     int vfi;
    124     int value;
    125     vfi_entry_t vfi_entry;
    126     soc_mem_t mem = VFIm;
    127 
    128     if (!soc_feature(unit, soc_feature_vxlan_lite_riot)) {
    129         return BCM_E_UNAVAIL;
    130     }
    131 
    132     /* Input parameters check */
    133     if (NULL == control) {
    134         return BCM_E_PARAM;
    135     }
    136 
    137     rv = bcmi_gh2_vfi_control_params_check(unit, vid, valid_fields, control);
    138     BCM_IF_ERROR_RETURN(rv);
    139 
    140     _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid);
    141 
    142     /* Read the VFI memory */
    143     SOC_IF_ERROR_RETURN(
    144         soc_mem_read(unit, mem, MEM_BLOCK_ANY, (int)vfi, &vfi_entry));
    145 
    146     /* Update VFI table per vlan_control INPUT */
    147 
    148     /*
    149      * VFI table in GH2-B0 supports only the following fields:
    150      *
    151      *  - L3_IIF           : Layer3 Incoming Interface to be assigned to the packet
    152      *  - UUC_UMC_BC_INDEX : Default unknown unicast/multicast/broadcast group
    153      *                       for this VFI
    154      */
    155     if (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK) {
    156         if ((control->ingress_if < 0) ||
    157             (control->ingress_if >= BCM_XGS3_L3_ING_IF_TBL_SIZE(unit))) {
    158             return BCM_E_PARAM;
    159         } else {
    160             value = control->ingress_if;
    161             soc_mem_field32_set(unit, mem, &vfi_entry, L3_IIFf, value);
    162         }
    163     }
    164 
    165     if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK ||
    166         valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK ||
    167         valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) {
    168         /* Unknown unicast/multicast/broadcast group share the same field */
    169         if (!(valid_fields &
    170             BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) ||
    171             !(valid_fields &
    172             BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) ||
    173             !(valid_fields &
    174             BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK)) {
    175             return BCM_E_PARAM;
    176         }
    177 
    178         if ((control->unknown_unicast_group !=
    179             control->unknown_multicast_group) ||
    180             (control->unknown_multicast_group !=
    181             control->broadcast_group)) {
    182             return BCM_E_PARAM;
    183         }
    184 
    185         if (_BCM_MULTICAST_IS_VXLAN(control->unknown_unicast_group)) {
    186             value = _BCM_MULTICAST_ID_GET(control->unknown_unicast_group);
    187             soc_mem_field32_set(unit, mem, &vfi_entry,
    188                                 UUC_UMC_BC_INDEXf, value);
    189         } else {
    190             return BCM_E_PARAM;
    191         }
    192     }
    193 
    194     /*
    195      *  - IPMCV4_L2_ENABLE  : Enables L2-only forwarding of IPMCv4 packets
    196      *  - IPMCV6_L2_ENABLE  : Enables L2-only forwarding of IPMCv6 packets
    197      *  - IPMCV4_ENABLE     : IPMC Enable for IPV4 packets on the VFI
    198      *  - IPMCV6_ENABLE     : IPMC Enable for IPV6 packets on the VFI
    199      *  - IPV4_ENABLE       : Enables IPV4 Routing in this VFI
    200      *  - IPV6_ENABLE       : Enables IPV6 Routing in this VFI
    201      *  - L2_NON_UCAST_DROP : Drop all broadcast and multicast packets
    202      *  - L2_NON_UCAST_TOCPU: Copy all broadcast and multicast packets to CPU
    203      *  - L2_DA_MISS_DROP   : Drop packet thas miss L2 DA unicast, Do not flood
    204      *  - L2_DA_MISS_TOCPU  : Copy packet thas miss L2 DA unicast to the CPU
    205      *  - L2_SA_MISS_TOCPU  : Copy packet thas miss L2 SA unicast to the CPU
    206      *    Note: L2_SA_MISS_TOCPU shares the same flags with L2_DA_MISS_TOCPU
    207      */
    208 
    209     /* Enable L2-only forwarding of IPMCv4/IPMCv6 packets on this VLAN */
    210     value = (control->flags & BCM_VLAN_IP4_MCAST_L2_DISABLE) ? 0 : 1;
    211     soc_mem_field32_set(unit, mem, &vfi_entry, IPMCV4_L2_ENABLEf, value);
    212     value = (control->flags & BCM_VLAN_IP6_MCAST_L2_DISABLE) ? 0 : 1;
    213     soc_mem_field32_set(unit, mem, &vfi_entry, IPMCV6_L2_ENABLEf, value);
    214 
    215 
    216     /* IPMC Enable IPv4/IPv6 packets on this VLAN */
    217     value = (control->flags & BCM_VLAN_IP4_MCAST_DISABLE) ? 0 : 1;
    218     soc_mem_field32_set(unit, mem, &vfi_entry, IPMCV4_ENABLEf, value);
    219     value = (control->flags & BCM_VLAN_IP6_MCAST_DISABLE) ? 0 : 1;
    220     soc_mem_field32_set(unit, mem, &vfi_entry, IPMCV6_ENABLEf, value);
    221 
    222 
    223     /* Enables IPV4/IPV6 Routing in this VFI */
    224     value = (control->flags & BCM_VLAN_IP4_DISABLE) ? 0 : 1;
    225     soc_mem_field32_set(unit, mem, &vfi_entry, IPV4_ENABLEf, value);
    226     value = (control->flags & BCM_VLAN_IP6_DISABLE) ? 0 : 1;
    227     soc_mem_field32_set(unit, mem, &vfi_entry, IPV6_ENABLEf, value);
    228 
    229 
    230     /* Drop non-unicast, broadcast or multicast packets that miss L2 lookup */
    231     value = (control->flags & BCM_VLAN_NON_UCAST_DROP) ? 1 : 0;
    232     soc_mem_field32_set(unit, mem, &vfi_entry, L2_NON_UCAST_DROPf, value);
    233 
    234     /*
    235      * Copy to cpu non-unicast, broadcast or multicast packets
    236      * that miss L2 lookup
    237      */
    238     value = (control->flags & BCM_VLAN_NON_UCAST_TOCPU) ? 1 : 0;
    239     soc_mem_field32_set(unit, mem, &vfi_entry, L2_NON_UCAST_TOCPUf, value);
    240 
    241     /* Drop packets that miss L2 lookup */
    242     value = (control->flags & BCM_VLAN_UNKNOWN_UCAST_DROP) ? 1 : 0;
    243     soc_mem_field32_set(unit, mem, &vfi_entry, L2_DA_MISS_DROPf, value);
    244 
    245     /* Copy to cpu packets that miss L2 lookup */
    246     value = (control->flags & BCM_VLAN_UNKNOWN_UCAST_TOCPU) ? 1 : 0;
    247     soc_mem_field32_set(unit, mem, &vfi_entry, L2_DA_MISS_TOCPUf, value);
    248     soc_mem_field32_set(unit, mem, &vfi_entry, L2_SA_MISS_TOCPUf, value);
    249 
    250     rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, vfi, &vfi_entry);
    251 
    252     return rv;
    253 }
    254 
    255 /*
    256  * Function:
    257  *    bcmi_gh2_vlan_control_vpn_get
    258  * Purpose:
    259  *    Reads VFI table and fills vlan_control
    260  * Parameters:
    261  *    unit         - (IN) Unit number
    262  *    vid          - (IN) Vlan id
    263  *    valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK
    264  *    control      - (OUT) Configuration structure
    265  * Return:
    266  *    BCM_E_XXX
    267  */
    268 int
    269 bcmi_gh2_vlan_control_vpn_get(
    270     int unit,
    271     bcm_vlan_t vid,
    272     uint32 valid_fields,
    273     bcm_vlan_control_vlan_t *control)
    274 {
    275     int rv = BCM_E_NONE;
    276     int vfi;
    277     int value;
    278     vfi_entry_t vfi_entry;
    279     soc_mem_t mem = VFIm;
    280 
    281     if (!soc_feature(unit, soc_feature_vxlan_lite_riot)) {
    282         return BCM_E_UNAVAIL;
    283     }
    284 
    285     /* Input parameters check */
    286     if (NULL == control) {
    287         return BCM_E_PARAM;
    288     }
    289 
    290     _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid);
    291 
    292     /* Read the VFI memory */
    293     SOC_IF_ERROR_RETURN(
    294         soc_mem_read(unit, mem, MEM_BLOCK_ANY, (int)vfi, &vfi_entry));
    295 
    296     /* Get L3 Ingress Interface ID */
    297     if (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK) {
    298         value = soc_mem_field32_get(unit, mem, &vfi_entry, L3_IIFf);
    299         control->ingress_if = value;
    300     }
    301 
    302     /* Get Unknown unicast/multicast/broadcast group ID */
    303     if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK ||
    304         valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK ||
    305         valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) {
    306         /* Unknown unicast/multicast/broadcast group share the same field */
    307         if (!(valid_fields &
    308             BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) ||
    309             !(valid_fields &
    310             BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) ||
    311             !(valid_fields &
    312             BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK)) {
    313             return BCM_E_PARAM;
    314         }
    315 
    316         value = soc_mem_field32_get(unit, mem, &vfi_entry, UUC_UMC_BC_INDEXf);
    317         _BCM_MULTICAST_GROUP_SET(control->unknown_unicast_group,
    318                                  _BCM_MULTICAST_TYPE_VXLAN, value);
    319         _BCM_MULTICAST_GROUP_SET(control->unknown_multicast_group,
    320                                  _BCM_MULTICAST_TYPE_VXLAN, value);
    321         _BCM_MULTICAST_GROUP_SET(control->broadcast_group,
    322                                  _BCM_MULTICAST_TYPE_VXLAN, value);
    323     }
    324 
    325     /* Enable L2-only forwarding of IPMCv4/IPMCv6 packets on this VLAN */
    326     value = soc_mem_field32_get(unit, mem, &vfi_entry, IPMCV4_L2_ENABLEf);
    327     if (value == 0) {
    328         control->flags |= BCM_VLAN_IP4_MCAST_L2_DISABLE;
    329     }
    330 
    331     value = soc_mem_field32_get(unit, mem, &vfi_entry, IPMCV6_L2_ENABLEf);
    332     if (value == 0) {
    333         control->flags |= BCM_VLAN_IP6_MCAST_L2_DISABLE;
    334     }
    335 
    336 
    337     /* IPMC Enable IPv4/IPv6 packets on this VLAN */
    338     value = soc_mem_field32_get(unit, mem, &vfi_entry, IPMCV4_ENABLEf);
    339     if (value == 0) {
    340         control->flags |= BCM_VLAN_IP4_MCAST_DISABLE;
    341     }
    342 
    343     value = soc_mem_field32_get(unit, mem, &vfi_entry, IPMCV6_ENABLEf);
    344     if (value == 0) {
    345         control->flags |= BCM_VLAN_IP6_MCAST_DISABLE;
    346     }
    347 
    348 
    349     /* Enables IPV4/IPV6 Routing in this VFI */
    350     value = soc_mem_field32_get(unit, mem, &vfi_entry, IPV4_ENABLEf);
    351     if (value == 0) {
    352         control->flags |= BCM_VLAN_IP4_DISABLE;
    353     }
    354 
    355     value = soc_mem_field32_get(unit, mem, &vfi_entry, IPV6_ENABLEf);
    356     if (value == 0) {
    357         control->flags |= BCM_VLAN_IP6_DISABLE;
    358     }
    359 
    360 
    361     /* Drop non-unicast, broadcast or multicast packets that miss L2 lookup */
    362     value = soc_mem_field32_get(unit, mem, &vfi_entry, L2_NON_UCAST_DROPf);
    363     if (value) {
    364         control->flags |= BCM_VLAN_NON_UCAST_DROP;
    365     }
    366 
    367     /*
    368      * Copy to cpu non-unicast, broadcast or multicast packets
    369      * that miss L2 lookup
    370      */
    371     value = soc_mem_field32_get(unit, mem, &vfi_entry, L2_NON_UCAST_TOCPUf);
    372     if (value) {
    373         control->flags |= BCM_VLAN_NON_UCAST_TOCPU;
    374     }
    375 
    376     /* Drop packets that miss L2 lookup */
    377     value = soc_mem_field32_get(unit, mem, &vfi_entry, L2_DA_MISS_DROPf);
    378     if (value) {
    379         control->flags |= BCM_VLAN_UNKNOWN_UCAST_DROP;
    380     }
    381 
    382     /* Copy to cpu packets that miss L2 lookup */
    383     value = soc_mem_field32_get(unit, mem, &vfi_entry, L2_DA_MISS_TOCPUf);
    384     if (value) {
    385         control->flags |= BCM_VLAN_UNKNOWN_UCAST_TOCPU;
    386     }
    387     value = soc_mem_field32_get(unit, mem, &vfi_entry, L2_SA_MISS_TOCPUf);
    388     if (value) {
    389         control->flags |= BCM_VLAN_UNKNOWN_UCAST_TOCPU;
    390     }
    391 
    392     return rv;
    393 }
    394 
    395 #endif /* BCM_GREYHOUND2_SUPPORT && INCLUDE_L3 */
    396