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 (10979B)


      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  * Trunk CLI functions that are common for more than one chip architecture
      8  */
      9 
     10 #include <appl/diag/system.h>
     11 #include <appl/diag/parse.h>
     12 #include <shared/bsl.h>
     13 #include <bcm/error.h>
     14 #include <bcm/trunk.h>
     15 #include <bcm/port.h>
     16 #ifdef BCM_ESW_SUPPORT
     17 #include <bcm_int/esw/port.h>
     18 #endif
     19 #include <bcm/stack.h>
     20 #include <bcm/debug.h>
     21 
     22 
     23 
     24 
     25 static char *_pscnames[] = BCM_TRUNK_PSC_NAMES_INITIALIZER;
     26 
     27 static cmd_result_t
     28 _bcm_diag_trunk_show_range(int unit,
     29                            args_t *a,
     30                            int fp,
     31                            int first,
     32                            int last,
     33                            int *found)
     34 {
     35     bcm_trunk_t tid;
     36     bcm_trunk_info_t t_add_info;
     37     pbmp_t pbmp;
     38     char const *s;
     39     int i;
     40     int rv;
     41     bcm_trunk_member_t *member_array = NULL;
     42     bcm_module_t tm[BCM_TRUNK_MAX_PORTCNT];
     43     bcm_port_t   tp[BCM_TRUNK_MAX_PORTCNT];
     44     int member_count;
     45 
     46     member_array = sal_alloc(sizeof(bcm_trunk_member_t) * BCM_TRUNK_MAX_PORTCNT,
     47             "member array");
     48     if (NULL == member_array) {
     49         cli_out("%s: failed: %s\n",
     50                 ARG_CMD(a), bcm_errmsg(BCM_E_MEMORY));
     51         return CMD_FAIL;
     52     }
     53 
     54     sal_memset(tm, BCM_MODID_INVALID, sizeof(bcm_module_t)*BCM_TRUNK_MAX_PORTCNT);
     55     sal_memset(tp, -1, sizeof(bcm_port_t)*BCM_TRUNK_MAX_PORTCNT);
     56 
     57     for (tid = first; tid <= last; tid++) {
     58         rv = bcm_trunk_get(unit, tid, &t_add_info, BCM_TRUNK_MAX_PORTCNT,
     59                 member_array, &member_count);
     60 
     61         if (rv == BCM_E_NOT_FOUND) {
     62             /* Only show existing trunk groups */
     63             continue;
     64         }
     65 
     66         if (rv < 0) {
     67             cli_out("%s: trunk %d get failed: %s\n",
     68                     ARG_CMD(a), tid, bcm_errmsg(rv));
     69             sal_free(member_array);
     70             return CMD_FAIL;
     71         }
     72 
     73         if (fp) {
     74             /* Front panel trunk */
     75             rv = bcm_trunk_egress_get(unit, tid, &pbmp);
     76 
     77             if (rv == BCM_E_UNAVAIL) {
     78                 /*
     79                  * Certain devices don't have a egress port per trunk
     80                  * Instead it provides support to set this up on
     81                  * a per port basis for each trunk member port
     82                  * Ignore this on these devices.
     83                  */
     84                 rv = BCM_E_NONE;
     85                 SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
     86             }
     87             if (rv < 0) {
     88                 cli_out("%s: trunk %d egress get failed: %s\n",
     89                         ARG_CMD(a), tid, bcm_errmsg(rv));
     90                 sal_free(member_array);
     91                 return CMD_FAIL;
     92             }
     93         } else {
     94             /* Fabric trunk */
     95             
     96             SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
     97         }
     98 
     99         (*found) += 1;
    100         cli_out("trunk %d: (%s, %d ports)", tid,
    101                 fp ? "front panel" : "fabric",
    102                 member_count);
    103 
    104         if (member_count > 0) {
    105 #ifdef BCM_XGS_SUPPORT
    106             if (SOC_IS_XGS(unit)) {
    107                 for (i = 0; i < member_count; i++) {
    108                     int tgid, id;
    109                     bcm_module_t _tm;
    110                     bcm_port_t _tp;
    111                     rv = _bcm_esw_gport_resolve(unit, member_array[i].gport,
    112                             &tm[i],
    113                             &tp[i],
    114                             &tgid, &id);
    115                     if ((rv < 0) || (tgid != -1) || (id != -1)) {
    116                         sal_free(member_array);
    117                         return CMD_FAIL;
    118                     }
    119                     /* For devices that do not support Mod Map transformation,
    120                        we save and restore tm and tp up on UNAVAIL error */
    121                     _tm = tm[i];
    122                     _tp = tp[i];
    123                     rv = bcm_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
    124                             tm[i], tp[i],
    125                             &tm[i], &tp[i]);
    126                     if (rv == BCM_E_UNAVAIL) {
    127                         tm[i] = _tm;
    128                         tp[i] = _tp;
    129                     } else if (rv < 0) {
    130                         sal_free(member_array);
    131                         return CMD_FAIL;
    132                     }
    133                 }
    134             }
    135 #endif
    136             for (i = 0; i < member_count; i++) {
    137                 cli_out("%s%s",
    138                         i == 0 ? "=" : ",",
    139                         mod_port_name(unit, tm[i], tp[i]));
    140             }
    141 
    142             s = t_add_info.dlf_index < 0 ? "any" :
    143                 mod_port_name(unit,
    144                               tm[t_add_info.dlf_index],
    145                               tp[t_add_info.dlf_index]);
    146             cli_out(" dlf=%s", s);
    147             s = t_add_info.mc_index < 0 ? "any" :
    148                 mod_port_name(unit,
    149                               tm[t_add_info.mc_index],
    150                               tp[t_add_info.mc_index]);
    151             cli_out(" mc=%s", s);
    152             s = t_add_info.ipmc_index < 0 ? "any" :
    153                 mod_port_name(unit,
    154                               tm[t_add_info.ipmc_index],
    155                               tp[t_add_info.ipmc_index]);
    156             cli_out(" ipmc=%s", s);
    157             if ((t_add_info.psc & 0xf) <= 0 ||
    158                 (t_add_info.psc & 0xf) >= COUNTOF(_pscnames)) {
    159                 s= "unknown";
    160             } else {
    161                 s = _pscnames[t_add_info.psc&0xf];
    162             }
    163             cli_out(" psc=%s", s);
    164 #ifdef BCM_HERCULES15_SUPPORT
    165             if (SOC_IS_HERCULES15(unit)) {
    166                 cli_out("%s%s%s%s%s%s%s%s%s%s%s%s",
    167                         (t_add_info.psc & BCM_TRUNK_PSC_IPMACSA) ?
    168                         "+ipmacsa" : "",
    169                         (t_add_info.psc & BCM_TRUNK_PSC_IPMACDA) ?
    170                         "+ipmacda" : "",
    171                         (t_add_info.psc & BCM_TRUNK_PSC_IPTYPE) ?
    172                         "+iptype" : "",
    173                         (t_add_info.psc & BCM_TRUNK_PSC_IPVID) ?
    174                         "+ipvid" : "",
    175                         (t_add_info.psc & BCM_TRUNK_PSC_IPSA) ?
    176                         "+ipsa" : "",
    177                         (t_add_info.psc & BCM_TRUNK_PSC_IPDA) ?
    178                         "+ipda" : "",
    179                         (t_add_info.psc & BCM_TRUNK_PSC_L4SS) ?
    180                         "+l4ss" : "",
    181                         (t_add_info.psc & BCM_TRUNK_PSC_L4DS) ?
    182                         "+l4ds" : "",
    183                         (t_add_info.psc & BCM_TRUNK_PSC_MACSA) ?
    184                         "+macsa" : "",
    185                         (t_add_info.psc & BCM_TRUNK_PSC_MACDA) ?
    186                         "+macda" : "",
    187                         (t_add_info.psc & BCM_TRUNK_PSC_TYPE) ?
    188                         "+type" : "",
    189                         (t_add_info.psc & BCM_TRUNK_PSC_VID) ?
    190                         "+vid" : "");
    191             }
    192 #endif /* BCM_HERCULES15_SUPPORT */
    193             cli_out(" (0x%x)", t_add_info.psc);
    194         }
    195         cli_out("\n");
    196 
    197         if (SOC_PBMP_NEQ(pbmp, PBMP_ALL(unit))) {
    198             char	buf[FORMAT_PBMP_MAX];
    199             format_pbmp(unit, buf, sizeof (buf), pbmp);
    200             cli_out("trunk %d: egress ports=%s\n", tid, buf);
    201         }
    202     }
    203 
    204     sal_free(member_array);
    205     return CMD_OK;
    206 }
    207 
    208 cmd_result_t
    209 _bcm_diag_trunk_show(int unit, args_t *a)
    210 {
    211     cmd_result_t retCode = CMD_OK;
    212     int rv = BCM_E_FAIL;
    213     bcm_trunk_chip_info_t ti;
    214     parse_table_t pt;
    215     uint32 arg_tid = ~0;
    216     char const *c;
    217     int tid_min, tid_max, found;
    218     int tid_fp_min, tid_fp_max;
    219     int tid_fabric_min, tid_fabric_max;
    220     int num_fp_tids, num_fabric_tids, num_tids;
    221     int num_fp_ports, num_fabric_ports;
    222 
    223     if ((rv = bcm_trunk_chip_info_get(unit, &ti)) < 0) {
    224         cli_out("%s: %s\n", ARG_CMD(a), bcm_errmsg(rv));
    225         return CMD_FAIL;
    226     }
    227 
    228     num_fp_tids = ti.trunk_group_count;
    229     tid_fp_min = ti.trunk_id_min;
    230     tid_fp_max = ti.trunk_id_max;
    231     tid_fabric_min = ti.trunk_fabric_id_min;
    232     tid_fabric_max = ti.trunk_fabric_id_max;
    233     num_fp_ports = ti.trunk_ports_max;
    234     num_fabric_ports = ti.trunk_fabric_ports_max;
    235 
    236     if (tid_fabric_min >= 0) {
    237         num_fabric_tids = tid_fabric_max - tid_fabric_min + 1;
    238     } else {
    239         num_fabric_tids = 0;
    240     }
    241 
    242     num_tids = num_fp_tids + num_fabric_tids;
    243 
    244     if (num_tids) {
    245         cli_out("Device supports %d trunk groups:\n", num_tids);
    246         if (num_fp_tids > 0) {
    247             cli_out("  %d front panel trunks (%d..%d), %d ports/trunk\n",
    248                     num_fp_tids,
    249                     tid_fp_min,
    250                     tid_fp_max,
    251                     num_fp_ports);
    252         }
    253         if (num_fabric_tids > 0) {
    254             cli_out("  %d fabric trunks (%d..%d), %d ports/trunk\n",
    255                     num_fabric_tids,
    256                     tid_fabric_min,
    257                     tid_fabric_max,
    258                     num_fabric_ports);
    259         }
    260     }
    261 
    262     if ((c = ARG_CUR(a)) != NULL) {
    263         parse_table_init(unit, &pt);
    264         parse_table_add(&pt, "Id", PQ_DFL|PQ_INT, 0, &arg_tid, NULL);
    265         if (!parseEndOk( a, &pt, &retCode)) {
    266             return retCode;
    267         }
    268         if ((~0) == arg_tid) {
    269             /*
    270              *  We use ~0 as a wildcard internally, but we've been asked to
    271              *  match ID literally -1 (which happens to look the same).  Choose
    272              *  another invalid ID instead.
    273              */
    274             arg_tid = ~1;
    275         }
    276     }
    277 
    278     found = 0;
    279     if ((num_fp_tids > 0) &&
    280         (((~0) == arg_tid) || ((tid_fp_min <= arg_tid) &&
    281                               (tid_fp_max >= arg_tid)))) {
    282         if ((~0) != arg_tid) {
    283             tid_min = arg_tid;
    284             tid_max = arg_tid;
    285         } else {
    286             tid_min = tid_fp_min;
    287             tid_max = tid_fp_max;
    288         }
    289         retCode = _bcm_diag_trunk_show_range(unit,
    290                                              a,
    291                                              TRUE /* front panel */,
    292                                              tid_min,
    293                                              tid_max,
    294                                              &found);
    295     }
    296 
    297     if ((tid_fabric_min >= 0) &&
    298         (((~0) == arg_tid) || ((tid_fabric_min <= arg_tid) &&
    299                                (tid_fabric_max >= arg_tid)))) {
    300         if ((~0) != arg_tid) {
    301             tid_min = arg_tid;
    302             tid_max = arg_tid;
    303         } else {
    304             tid_min = tid_fabric_min;
    305             tid_max = tid_fabric_max;
    306         }
    307         retCode = _bcm_diag_trunk_show_range(unit,
    308                                              a,
    309                                              FALSE /* not front panel */,
    310                                              tid_min,
    311                                              tid_max,
    312                                              &found);
    313     }
    314 
    315     if (found == 0) {
    316         cli_out("[no matching trunks defined]\n");
    317     }
    318 
    319     return retCode;
    320 }
    321