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

trunk.c (7674B)


      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 <soc/defs.h>
      9 #if defined(BCM_HERCULES_SUPPORT)
     10 #include <soc/drv.h>
     11 #include <soc/mem.h>
     12 
     13 #include <bcm/error.h>
     14 #include <bcm/trunk.h>
     15 
     16 #include <bcm_int/esw/mbcm.h>
     17 #include <bcm_int/esw/trunk.h>
     18 #include <bcm_int/esw/hercules.h>
     19 
     20 #include <bcm_int/esw_dispatch.h>
     21 
     22 /*
     23  * Purpose: Multiplexed trunking function for Hercules
     24  * Note: The parameters op and member are not used.
     25  */
     26 int
     27 bcm_hercules_trunk_modify(int unit, bcm_trunk_t tid,
     28 		       bcm_trunk_info_t *trunk_info,
     29                        int member_count,
     30                        bcm_trunk_member_t *member_array,
     31 		       trunk_private_t *t_info,
     32                        int op,
     33                        bcm_trunk_member_t *member)
     34 {
     35     int		i;
     36     bcm_port_t	port;
     37     uint32	algo, bmap, val, oval;
     38     uint32 ing_cntlr;
     39 
     40     ing_cntlr = ING_CTRLr;
     41 
     42     bmap = 0;
     43     for (i = 0; i < member_count; i++) {
     44         BCM_IF_ERROR_RETURN
     45             (bcm_esw_port_local_get(unit, member_array[i].gport, &port));
     46 	if (!IS_PORT(unit, port)) {
     47 	    return BCM_E_BADID;
     48 	}
     49 	bmap |= (1<<port);
     50     }
     51     if (trunk_info->psc <= 0) {
     52 	trunk_info->psc = BCM_TRUNK_PSC_DEFAULT;
     53 
     54         trunk_info->psc |= (BCM_TRUNK_PSC_MACSA | BCM_TRUNK_PSC_MACDA |
     55                           BCM_TRUNK_PSC_IPMACSA | BCM_TRUNK_PSC_IPMACDA);
     56     }
     57     switch (trunk_info->psc & 0xf) {
     58     case BCM_TRUNK_PSC_SRCDSTMAC:
     59 	algo = 0;
     60 	break;
     61     case BCM_TRUNK_PSC_REDUNDANT:
     62 	algo = 1;
     63 	break;
     64     default:
     65 	return BCM_E_PARAM;
     66     }
     67 
     68     val = 0;
     69     soc_reg_field_set(unit, ING_HGTRUNKr, &val, BMAPf, bmap);
     70     soc_reg_field_set(unit, ING_HGTRUNKr, &val, ALGORITHMf, algo);
     71 
     72     if (!algo) {
     73         if (trunk_info->psc & BCM_TRUNK_PSC_IPMACSA) {
     74             soc_reg_field_set(unit, ING_HGTRUNKr, &val, EN_IPMACSAf, 1);
     75         }
     76         if (trunk_info->psc & BCM_TRUNK_PSC_IPMACDA) {
     77             soc_reg_field_set(unit, ING_HGTRUNKr, &val, EN_IPMACDAf, 1);
     78         }
     79         if (trunk_info->psc & BCM_TRUNK_PSC_IPTYPE) {
     80             soc_reg_field_set(unit, ING_HGTRUNKr, &val, EN_IPTYPEf, 1);
     81         }
     82         if (trunk_info->psc & BCM_TRUNK_PSC_IPVID) {
     83             soc_reg_field_set(unit, ING_HGTRUNKr, &val, EN_IPVIDf, 1);
     84         }
     85         if (trunk_info->psc & BCM_TRUNK_PSC_IPDA) {
     86             soc_reg_field_set(unit, ING_HGTRUNKr, &val, EN_IPDAf, 1);
     87         }
     88         if (trunk_info->psc & BCM_TRUNK_PSC_IPSA) {
     89             soc_reg_field_set(unit, ING_HGTRUNKr, &val, EN_IPSAf, 1);
     90         }
     91         if (trunk_info->psc & BCM_TRUNK_PSC_L4SS) {
     92             soc_reg_field_set(unit, ING_HGTRUNKr, &val, EN_L4SSf, 1);
     93         }
     94         if (trunk_info->psc & BCM_TRUNK_PSC_L4DS) {
     95             soc_reg_field_set(unit, ING_HGTRUNKr, &val, EN_L4DSf, 1);
     96         }
     97         if (trunk_info->psc & BCM_TRUNK_PSC_MACSA) {
     98             soc_reg_field_set(unit, ING_HGTRUNKr, &val, EN_MACSAf, 1);
     99         }
    100         if (trunk_info->psc & BCM_TRUNK_PSC_MACDA) {
    101             soc_reg_field_set(unit, ING_HGTRUNKr, &val, EN_MACDAf, 1);
    102         }
    103         if (trunk_info->psc & BCM_TRUNK_PSC_TYPE) {
    104             soc_reg_field_set(unit, ING_HGTRUNKr, &val, EN_TYPEf, 1);
    105         }
    106         if (trunk_info->psc & BCM_TRUNK_PSC_VID) {
    107             soc_reg_field_set(unit, ING_HGTRUNKr, &val, EN_VIDf, 1);
    108         }
    109     }
    110 	
    111     PBMP_PORT_ITER(unit, port) {
    112 	SOC_IF_ERROR_RETURN(WRITE_ING_HGTRUNKr(unit, port, tid, val));
    113     }
    114 
    115     if (!algo) {
    116         int eqw[BCM_TRUNK_MAX_PORTCNT];
    117 
    118         sal_memset(eqw, 0, sizeof(eqw));
    119         BCM_IF_ERROR_RETURN(bcm_esw_trunk_pool_set(unit, -1, tid, 0, eqw));
    120     }
    121 
    122     if (bmap != 0) {
    123         PBMP_PORT_ITER(unit, port) {
    124             SOC_IF_ERROR_RETURN(soc_reg32_get(unit,
    125                                 ing_cntlr, port, 0, &val));
    126             oval = val;
    127             soc_reg_field_set(unit, ing_cntlr, &val, TRUNKENf, 1);
    128             if (val != oval) {
    129                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit,
    130                                 ing_cntlr, port, 0, val));
    131             }
    132         }
    133     }
    134     return BCM_E_NONE;
    135 }
    136 
    137 /*
    138  * Purpose: Multiplexed trunking function for Hercules
    139  */
    140 int
    141 bcm_hercules_trunk_destroy(int unit, bcm_trunk_t tid, trunk_private_t *t_info)
    142 {
    143     bcm_port_t	port;
    144 
    145     PBMP_PORT_ITER(unit, port) {
    146 	SOC_IF_ERROR_RETURN(WRITE_ING_HGTRUNKr(unit, port, tid, 0));
    147     }
    148     return BCM_E_NONE;
    149 }
    150 
    151 /*
    152  * Purpose: Multiplexed trunking function for Hercules
    153  */
    154 int
    155 bcm_hercules_trunk_get(int unit, bcm_trunk_t tid,
    156 		       bcm_trunk_info_t *t_data,
    157                        int member_max, 
    158                        bcm_trunk_member_t *member_array,
    159                        int *member_count,
    160 		       trunk_private_t *t_info)
    161 {
    162     bcm_port_t	port;
    163     uint32	val;
    164     bcm_pbmp_t	pbmp;
    165     bcm_module_t mod = 0;
    166     int         num_ports;
    167 
    168     PBMP_PORT_ITER(unit, port) {
    169 	SOC_IF_ERROR_RETURN(READ_ING_HGTRUNKr(unit, port, tid, &val));
    170 	break;
    171     }
    172 
    173     SOC_PBMP_CLEAR(pbmp);
    174     SOC_PBMP_WORD_SET(pbmp, 0,
    175 		      soc_reg_field_get(unit, ING_HGTRUNKr, val, BMAPf));
    176     num_ports = 0;
    177     PBMP_ITER(pbmp, port) {
    178         if (num_ports < member_max) {
    179             BCM_IF_ERROR_RETURN(_bcm_esw_trunk_gport_construct(unit, TRUE,
    180                         1, &port, &mod, &member_array[num_ports].gport));
    181         }
    182 	num_ports += 1;
    183     }
    184     *member_count = num_ports;
    185 	
    186     switch (soc_reg_field_get(unit, ING_HGTRUNKr, val, ALGORITHMf)) {
    187     case 0:
    188 	t_data->psc = BCM_TRUNK_PSC_SRCDSTMAC;
    189         if (soc_reg_field_get(unit, ING_HGTRUNKr, val, EN_IPMACSAf)) {
    190             t_data->psc |= BCM_TRUNK_PSC_IPMACSA;
    191         }
    192         if (soc_reg_field_get(unit, ING_HGTRUNKr, val, EN_IPMACDAf)) {
    193             t_data->psc |= BCM_TRUNK_PSC_IPMACDA;
    194         }
    195         if (soc_reg_field_get(unit, ING_HGTRUNKr, val, EN_IPTYPEf)) {
    196             t_data->psc |= BCM_TRUNK_PSC_IPTYPE;
    197         }
    198         if (soc_reg_field_get(unit, ING_HGTRUNKr, val, EN_IPVIDf)) {
    199             t_data->psc |= BCM_TRUNK_PSC_IPVID;
    200         }
    201         if (soc_reg_field_get(unit, ING_HGTRUNKr, val, EN_IPSAf)) {
    202             t_data->psc |= BCM_TRUNK_PSC_IPSA;
    203         }
    204         if (soc_reg_field_get(unit, ING_HGTRUNKr, val, EN_IPDAf)) {
    205             t_data->psc |= BCM_TRUNK_PSC_IPDA;
    206         }
    207         if (soc_reg_field_get(unit, ING_HGTRUNKr, val, EN_L4SSf)) {
    208             t_data->psc |= BCM_TRUNK_PSC_L4SS;
    209         }
    210         if (soc_reg_field_get(unit, ING_HGTRUNKr, val, EN_L4DSf)) {
    211             t_data->psc |= BCM_TRUNK_PSC_L4DS;
    212         }
    213         if (soc_reg_field_get(unit, ING_HGTRUNKr, val, EN_MACDAf)) {
    214             t_data->psc |= BCM_TRUNK_PSC_MACDA;
    215         }
    216         if (soc_reg_field_get(unit, ING_HGTRUNKr, val, EN_MACSAf)) {
    217             t_data->psc |= BCM_TRUNK_PSC_MACSA;
    218         }
    219         if (soc_reg_field_get(unit, ING_HGTRUNKr, val, EN_TYPEf)) {
    220             t_data->psc |= BCM_TRUNK_PSC_TYPE;
    221         }
    222         if (soc_reg_field_get(unit, ING_HGTRUNKr, val, EN_VIDf)) {
    223             t_data->psc |= BCM_TRUNK_PSC_VID;
    224         }
    225 	break;
    226     case 1:
    227 	t_data->psc = BCM_TRUNK_PSC_REDUNDANT;
    228 	break;
    229     default:
    230 	t_data->psc = -1;
    231 	break;
    232     }
    233     t_data->dlf_index = -1;
    234     t_data->mc_index = -1;
    235     t_data->ipmc_index = -1;
    236     return BCM_E_NONE;
    237 }
    238 
    239 /*
    240  * Purpose: Multiplexed trunking function for Hercules
    241  */
    242 int
    243 bcm_hercules_trunk_mcast_join(int unit, bcm_trunk_t tid, bcm_vlan_t vid,
    244                               sal_mac_addr_t mac, trunk_private_t *t_info)
    245 {
    246     return BCM_E_UNAVAIL;
    247 }
    248 #else /* BCM_HERCULES_SUPPORT */
    249 int _hercules_trunk_not_empty;
    250 #endif /* BCM_HERCULES_SUPPORT */
    251