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

l2cache.c (10053B)


      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  * L2 Cache - Layer 2 BPDU and overflow address cache
      8  */
      9 
     10 #include <shared/bsl.h>
     11 
     12 #include <sal/core/libc.h>
     13 #include <shared/alloc.h>
     14 
     15 #include <bcm/types.h>
     16 
     17 #include <bcmx/l2.h>
     18 #include <bcmx/lport.h>
     19 #include <bcmx/bcmx.h>
     20 #include <bcmx/lplist.h>
     21 
     22 #include "bcmx_int.h"
     23 
     24 #define BCMX_L2_CACHE_INIT_CHECK    BCMX_READY_CHECK
     25 
     26 #define BCMX_L2_CACHE_ERROR_CHECK(_unit, _check, _rv)    \
     27     BCMX_ERROR_CHECK(_unit, _check, _rv)
     28 
     29 #define BCMX_L2_CACHE_SET_ERROR_CHECK(_unit, _check, _rv)    \
     30     BCMX_SET_ERROR_CHECK(_unit, _check, _rv)
     31 
     32 #define BCMX_L2_CACHE_DELETE_ERROR_CHECK(_unit, _check, _rv)    \
     33     BCMX_DELETE_ERROR_CHECK(_unit, _check, _rv)
     34 
     35 #define BCMX_L2_CACHE_GET_IS_VALID(_unit, _rv)    \
     36     BCMX_ERROR_IS_VALID(_unit, _rv)
     37 
     38 
     39 STATIC INLINE void
     40 _bcmx_l2_cache_addr_t_init(bcmx_l2_cache_addr_t *addr)
     41 {
     42     sal_memset(addr, 0, sizeof (*addr));
     43 }
     44 
     45 STATIC INLINE int
     46 _bcmx_l2_cache_addr_to_bcm(int bcm_unit,
     47                            bcm_l2_cache_addr_t *dest,
     48                            bcmx_l2_cache_addr_t *source)
     49 {
     50     uint32             flags = BCMX_DEST_CONVERT_NON_GPORT;
     51     _bcmx_dest_bcm_t   to_bcm;
     52     _bcmx_dest_bcmx_t  from_bcmx;
     53 
     54     bcm_l2_cache_addr_t_init(dest);
     55     dest->flags = source->flags;
     56     sal_memcpy(dest->mac, source->mac, sizeof(bcm_mac_t));
     57     sal_memcpy(dest->mac_mask, source->mac_mask, sizeof(bcm_mac_t));
     58     dest->vlan = source->vlan;
     59     dest->vlan_mask = source->vlan_mask;
     60     
     61     dest->src_port = source->src_port;
     62     dest->src_port_mask = source->src_port_mask;
     63     dest->lookup_class = source->lookup_class;
     64 
     65     /*
     66      * Convert to destination port list to bitmap if destination
     67      * is not a trunk and DESTPORTS flag is set
     68      */
     69     if (!(source->flags & BCM_L2_CACHE_TRUNK) &&
     70         (source->flags & BCM_L2_CACHE_DESTPORTS)) {
     71         BCM_PBMP_CLEAR(dest->dest_ports);
     72         BCMX_LPLIST_TO_PBMP(source->dest_ports, bcm_unit, dest->dest_ports);
     73 
     74     } else {
     75         /*
     76          * Convert destination data
     77          */
     78         _bcmx_dest_bcmx_t_init(&from_bcmx);
     79 
     80         /* Set flags and data to convert */
     81         if (source->flags & BCM_L2_CACHE_TRUNK) {
     82             flags |= BCMX_DEST_TRUNK;
     83         }
     84         from_bcmx.port  = source->dest_lport;
     85         from_bcmx.trunk = source->dest_trunk;
     86 
     87         /* Convert */
     88         BCM_IF_ERROR_RETURN(_bcmx_dest_to_bcm(&from_bcmx, &to_bcm, &flags));
     89 
     90         /* Set converted flags and data */
     91         if (flags & BCMX_DEST_TRUNK) {
     92             dest->flags |= BCM_L2_CACHE_TRUNK;
     93         } else if (flags & BCMX_DEST_DISCARD) {
     94             dest->flags |= BCM_L2_CACHE_DISCARD;
     95         }
     96 
     97         dest->dest_modid = to_bcm.module_id;
     98         dest->dest_port  = to_bcm.module_port;
     99         dest->dest_trunk = to_bcm.trunk;
    100     }
    101 
    102     dest->prio = source->prio;
    103 
    104     return BCM_E_NONE;
    105 }
    106 
    107 STATIC INLINE int
    108 _bcmx_l2_cache_addr_from_bcm(bcmx_l2_cache_addr_t *dest,
    109                              bcm_l2_cache_addr_t *source)
    110 {
    111     uint32             flags = BCMX_DEST_CONVERT_DEFAULT;
    112     _bcmx_dest_bcm_t   from_bcm;
    113     _bcmx_dest_bcmx_t  to_bcmx;
    114 
    115     _bcmx_l2_cache_addr_t_init(dest);
    116     dest->flags = source->flags;
    117     sal_memcpy(dest->mac, source->mac, sizeof(bcm_mac_t));
    118     sal_memcpy(dest->mac_mask, source->mac_mask, sizeof(bcm_mac_t));
    119     dest->vlan = source->vlan;
    120     dest->vlan_mask = source->vlan_mask;
    121     
    122     dest->src_port = source->src_port;
    123     dest->src_port_mask = source->src_port_mask;
    124     dest->lookup_class = source->lookup_class;
    125 
    126     /*
    127      * Convert bitmap to destination port list if destination
    128      * is not a trunk and DESTPORTS flag is set
    129      */
    130     if (!(source->flags & BCM_L2_CACHE_TRUNK) &&
    131         (source->flags & BCM_L2_CACHE_DESTPORTS)) {
    132         bcm_port_t port;
    133         bcmx_lport_t lport;
    134 
    135         bcmx_lplist_clear(&dest->dest_ports);
    136         BCM_PBMP_ITER(source->dest_ports, port) {
    137             BCM_IF_ERROR_RETURN
    138                 (_bcmx_dest_from_modid_port(&lport, source->dest_modid, port,
    139                                             BCMX_DEST_CONVERT_DEFAULT));
    140             BCMX_LPLIST_ADD(&dest->dest_ports, lport); 
    141         }
    142 
    143     } else {
    144         /*
    145          * Convert destination data
    146          */
    147         _bcmx_dest_bcm_t_init(&from_bcm);
    148 
    149         /* Set flags and data to convert */
    150         if (source->flags & BCM_L2_CACHE_TRUNK) {
    151             flags |= BCMX_DEST_TRUNK;
    152         }
    153         from_bcm.module_id   = source->dest_modid;
    154         from_bcm.module_port = source->dest_port;
    155         from_bcm.trunk       = source->dest_trunk;
    156 
    157         /* Convert */
    158         BCM_IF_ERROR_RETURN(_bcmx_dest_from_bcm(&to_bcmx, &from_bcm, &flags));
    159 
    160         /* Set converted flags and data */
    161         if (flags & BCMX_DEST_TRUNK) {
    162             dest->flags |= BCM_L2_CACHE_TRUNK;
    163         } else if (flags & BCMX_DEST_DISCARD) {
    164             dest->flags |= BCM_L2_CACHE_DISCARD;
    165         }
    166 
    167         dest->dest_lport = to_bcmx.port;
    168         dest->dest_trunk = to_bcmx.trunk;
    169     }
    170 
    171     dest->prio = source->prio;
    172 
    173     return BCM_E_NONE;
    174 }
    175 
    176 
    177 /*
    178  * Function:
    179  *      bcmx_l2_cache_init
    180  */
    181 
    182 int
    183 bcmx_l2_cache_init(void)
    184 {
    185     int rv = BCM_E_UNAVAIL, tmp_rv;
    186     int i, bcm_unit;
    187 
    188     BCMX_L2_CACHE_INIT_CHECK;
    189 
    190     BCMX_UNIT_ITER(bcm_unit, i) {
    191         tmp_rv = bcm_l2_cache_init(bcm_unit);
    192         BCM_IF_ERROR_RETURN(BCMX_L2_CACHE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    193     }
    194 
    195     return rv;
    196 }
    197 
    198 
    199 /*
    200  * Function:
    201  *      bcmx_l2_cache_addr_t_init
    202  */
    203 
    204 void
    205 bcmx_l2_cache_addr_t_init(bcmx_l2_cache_addr_t *addr)
    206 {
    207     if (addr != NULL) {
    208         _bcmx_l2_cache_addr_t_init(addr);
    209         bcmx_lplist_t_init(&addr->dest_ports);
    210     }
    211 }
    212 
    213 /*
    214  * Function:
    215  *      bcmx_l2_cache_addr_t_free
    216  * Purpose:
    217  *      Free memory allocated to bcmx_l2_cache_addr_t struct
    218  */
    219 void
    220 bcmx_l2_cache_addr_t_free(bcmx_l2_cache_addr_t *addr)
    221 {
    222     if (addr != NULL) {
    223         bcmx_lplist_free(&addr->dest_ports);
    224     }
    225 }
    226   
    227 
    228 /*
    229  * Function:
    230  *      bcmx_l2_cache_size_get
    231  */
    232 
    233 int
    234 bcmx_l2_cache_size_get(int *size)
    235 {
    236     int rv = BCM_E_UNAVAIL, tmp_rv;
    237     int i, bcm_unit;
    238     int tmp_size = 0, current_size = 0;
    239 
    240     BCMX_L2_CACHE_INIT_CHECK;
    241 
    242     BCMX_PARAM_NULL_CHECK(size);
    243 
    244     BCMX_UNIT_ITER(bcm_unit, i) {
    245         tmp_rv = bcm_l2_cache_size_get(bcm_unit, &tmp_size);
    246         if (BCMX_L2_CACHE_GET_IS_VALID(bcm_unit, tmp_rv)) {
    247             rv = tmp_rv;
    248             if (BCM_FAILURE(tmp_rv)) {
    249                 break;
    250             }
    251 
    252             /* Set current_size to the first non-zero cache size
    253                or the minimum of all valid cache sizes found. */
    254             if ((tmp_size > 0) &&
    255                 ((current_size == 0) || (tmp_size < current_size))) {
    256                 current_size = tmp_size;
    257             }
    258         }
    259     }
    260     *size = current_size;
    261 
    262     return rv;
    263 }
    264 
    265 
    266 /*
    267  * Function:
    268  *      bcmx_l2_cache_set
    269  */
    270 
    271 int
    272 bcmx_l2_cache_set(int index, bcmx_l2_cache_addr_t *addr, int *index_used)
    273 {
    274     int rv = BCM_E_UNAVAIL, tmp_rv;
    275     int i, bcm_unit;
    276     bcm_l2_cache_addr_t bcm_l2;
    277     int map_local_cpu;  /* Is local CPU port mapping required? */
    278     bcmx_lport_t cpu_lport;
    279 
    280     BCMX_L2_CACHE_INIT_CHECK;
    281 
    282     BCMX_PARAM_NULL_CHECK(addr);
    283     BCMX_PARAM_NULL_CHECK(index_used);
    284 
    285     /* Auto inser is not support across chips of different types */
    286     if (index < 0) {
    287         return BCM_E_PARAM;
    288     }
    289 
    290     map_local_cpu = ((!(addr->flags & BCM_L2_CACHE_TRUNK)) &&
    291                      (addr->dest_lport == BCMX_LPORT_LOCAL_CPU));
    292 
    293     BCMX_UNIT_ITER(bcm_unit, i) {
    294         if (_bcmx_l2_cache_addr_to_bcm(bcm_unit, &bcm_l2, addr) < 0) {
    295             LOG_WARN(BSL_LS_BCMX_COMMON,
    296                      (BSL_META("BCMX L2 CACHE WARN:  "
    297                                "Failed to convert "
    298                                "L2 Cache address to BCM\n")));
    299         } else {
    300             if (map_local_cpu) {
    301                 cpu_lport = BCMX_LPORT_LOCAL_CPU_GET(bcm_unit);
    302                 if (BCM_FAILURE
    303                     (_bcmx_dest_to_modid_port(cpu_lport,
    304                                               &bcm_l2.dest_modid,
    305                                               &bcm_l2.dest_port,
    306                                               BCMX_DEST_CONVERT_DEFAULT))) {
    307                     /* Skip if can't find local CPU port */
    308                     continue;
    309                 }
    310             }
    311             tmp_rv = bcm_l2_cache_set(bcm_unit, index, &bcm_l2, index_used);
    312 
    313             BCM_IF_ERROR_RETURN
    314                 (BCMX_L2_CACHE_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    315         }
    316     }
    317 
    318     *index_used = index;
    319 
    320     return rv;
    321 }
    322 
    323 
    324 /*
    325  * Function:
    326  *      bcmx_l2_cache_get
    327  */
    328 
    329 int 
    330 bcmx_l2_cache_get(int index, bcmx_l2_cache_addr_t *addr)
    331 {
    332     int rv;
    333     int i, bcm_unit;
    334     bcm_l2_cache_addr_t bcm_l2;
    335 
    336     BCMX_L2_CACHE_INIT_CHECK;
    337 
    338     BCMX_PARAM_NULL_CHECK(addr);
    339 
    340     BCMX_UNIT_ITER(bcm_unit, i) {
    341         rv = bcm_l2_cache_get(bcm_unit, index, &bcm_l2);
    342 
    343         if (BCMX_L2_CACHE_GET_IS_VALID(bcm_unit, rv)) {
    344             if (BCM_SUCCESS(rv)) {
    345                 rv = _bcmx_l2_cache_addr_from_bcm(addr, &bcm_l2);
    346             }
    347             return rv;
    348         }
    349     }
    350 
    351     return BCM_E_UNAVAIL;
    352 }
    353 
    354 
    355 /*
    356  * Function:
    357  *      bcmx_l2_cache_delete
    358  */
    359 
    360 int
    361 bcmx_l2_cache_delete(int index)
    362 {
    363     int rv = BCM_E_UNAVAIL, tmp_rv;
    364     int i, bcm_unit;
    365 
    366     BCMX_L2_CACHE_INIT_CHECK;
    367 
    368     BCMX_UNIT_ITER(bcm_unit, i) {
    369         tmp_rv = bcm_l2_cache_delete(bcm_unit, index);
    370         BCM_IF_ERROR_RETURN
    371             (BCMX_L2_CACHE_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    372     }
    373 
    374     return rv;
    375 }
    376 
    377 
    378 /*
    379  * Function:
    380  *      bcmx_l2_cache_delete_all
    381  */
    382 
    383 int
    384 bcmx_l2_cache_delete_all(void)
    385 {
    386     int rv = BCM_E_UNAVAIL, tmp_rv;
    387     int i, bcm_unit;
    388 
    389     BCMX_L2_CACHE_INIT_CHECK;
    390 
    391     BCMX_UNIT_ITER(bcm_unit, i) {
    392         tmp_rv = bcm_l2_cache_delete_all(bcm_unit);
    393         BCM_IF_ERROR_RETURN
    394             (BCMX_L2_CACHE_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    395     }
    396 
    397     return rv;
    398 }