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


      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 commands
      8  */
      9 
     10 #include <appl/diag/system.h>
     11 #include <appl/diag/parse.h>
     12 #include <appl/diag/dport.h>
     13 #include <shared/bsl.h>
     14 #include <bcm/error.h>
     15 #include <bcm/trunk.h>
     16 #include <bcm/port.h>
     17 #include <bcm/stack.h>
     18 #include <bcm/debug.h>
     19 
     20 
     21 
     22 cmd_result_t
     23 if_esw_trunk(int unit, args_t *a)
     24 {
     25     char 		*subcmd;
     26     bcm_trunk_t		tid = -1;
     27     bcm_pbmp_t 		pbmp;
     28     int 		r;
     29     int			psc;
     30     bcm_pbmp_t 	arg_pbmp;
     31     uint32       arg_rtag=0;
     32     uint32	arg_vlan=VLAN_ID_DEFAULT, arg_tid=0;
     33 #ifdef BCM_FIREBOLT_SUPPORT
     34     int          arg_hash=0;
     35 #endif /* BCM_FIREBOLT_SUPPORT */
     36     parse_table_t	pt;
     37     cmd_result_t	retCode;
     38     bcm_trunk_info_t    t_add_info;
     39     int			i, j, dport;
     40     sal_mac_addr_t	mac;
     41     vlan_id_t		vid;
     42     bcm_module_t    modid;
     43     
     44 
     45     if (!sh_check_attached(ARG_CMD(a), unit)) {
     46 	return CMD_FAIL;
     47     }
     48 
     49     if ((subcmd = ARG_GET(a)) == NULL) {
     50 	return CMD_USAGE;
     51     }
     52 
     53     BCM_PBMP_CLEAR(pbmp);
     54     BCM_PBMP_CLEAR(arg_pbmp);
     55 
     56     if (sal_strcasecmp(subcmd, "init") == 0) {
     57         r = bcm_trunk_init(unit);
     58         if (r < 0) {
     59             cli_out("%s: trunk init failed: %s\n", ARG_CMD(a), bcm_errmsg(r));
     60             return CMD_FAIL;
     61         }
     62 
     63 	return CMD_OK;
     64     }
     65 
     66     if (sal_strcasecmp(subcmd, "deinit") == 0) {
     67         r = bcm_trunk_detach(unit);
     68         if (r < 0) {
     69             cli_out("%s: trunk deinit failed: %s\n", ARG_CMD(a), bcm_errmsg(r));
     70             return CMD_FAIL;
     71         }
     72 
     73         return CMD_OK;
     74     }
     75 
     76     /* trunk show command */
     77     if (sal_strcasecmp(subcmd, "show") == 0) {
     78         return _bcm_diag_trunk_show(unit, a);
     79     }
     80 
     81     r = bcm_stk_my_modid_get(unit, &modid);
     82     if ((r < 0) && (r != BCM_E_UNAVAIL)) {
     83         cli_out("BCMX: Could not get mod id %d: %s\n", r, bcm_errmsg(r));
     84         return r;
     85     }
     86 
     87 
     88     if (r < 0) {  /* If unavailable, indicate unknown */
     89         modid = -1;
     90     }
     91 
     92     if (sal_strcasecmp(subcmd, "add") == 0) {
     93 	bcm_trunk_chip_info_t	ti;
     94         bcm_module_t tm, _tm;
     95         bcm_port_t   tp, _tp;
     96         bcm_trunk_member_t *member_array = NULL;
     97 
     98 	if ((r = bcm_trunk_chip_info_get(unit, &ti)) < 0) {
     99 	    cli_out("%s: %s\n", ARG_CMD(a), bcm_errmsg(r));
    100 	    return CMD_FAIL;
    101 	}
    102 
    103 	parse_table_init(unit, &pt);
    104         parse_table_add(&pt, "Id",   PQ_DFL|PQ_INT,  0, &arg_tid,  NULL);
    105         parse_table_add(&pt, "Rtag", PQ_DFL|PQ_INT,  0, &arg_rtag, NULL);
    106 	parse_table_add(&pt, "Pbmp", PQ_DFL|PQ_PBMP|PQ_BCM, 0, &arg_pbmp, NULL);
    107 
    108 	if (!parseEndOk(a, &pt, &retCode)) {
    109 	    return retCode;
    110         }
    111 
    112 	tid = arg_tid;
    113         psc = arg_rtag;
    114 	pbmp = arg_pbmp;
    115 
    116         member_array = sal_alloc(sizeof(bcm_trunk_member_t) *
    117                 BCM_TRUNK_MAX_PORTCNT, "member array");
    118         if (NULL == member_array) {
    119             cli_out("%s: ERROR: %s\n", ARG_CMD(a), bcm_errmsg(BCM_E_MEMORY));
    120             return CMD_FAIL;
    121         }
    122 	j = 0;
    123         /* coverity[overrun-local] */
    124         DPORT_BCM_PBMP_ITER(unit, pbmp, dport, i) {
    125             tm = (soc_feature(unit, soc_feature_mod1) && i > 31) ? modid + 1 : modid;
    126             tp = i;
    127             _tm = tm;
    128             _tp = tp;
    129             r = bcm_stk_modmap_map(unit, BCM_STK_MODMAP_GET, tm, tp,
    130                     &tm, &tp);
    131             if (r == BCM_E_UNAVAIL) {
    132                 tm = _tm;
    133                 tp = _tp;
    134             } else if (r < 0) {
    135                 sal_free(member_array);
    136                 return CMD_FAIL;
    137             }
    138             if (j >= BCM_TRUNK_MAX_PORTCNT) {
    139                 sal_free(member_array);
    140                 return CMD_FAIL;
    141             }
    142             bcm_trunk_member_t_init(&member_array[j]);
    143             if (BCM_GPORT_IS_SET(tp)) {
    144                 member_array[j].gport = tp;
    145             } else {
    146                 BCM_GPORT_MODPORT_SET(member_array[j].gport, tm, tp);
    147             }
    148             j += 1;
    149         };
    150         bcm_trunk_info_t_init(&t_add_info);
    151 	t_add_info.dlf_index = BCM_TRUNK_UNSPEC_INDEX;
    152 	t_add_info.mc_index = BCM_TRUNK_UNSPEC_INDEX;
    153 	t_add_info.ipmc_index = BCM_TRUNK_UNSPEC_INDEX;
    154         t_add_info.psc = psc;
    155 
    156         bcm_trunk_create(unit, BCM_TRUNK_FLAG_WITH_ID, &tid);
    157 	r = bcm_trunk_set(unit, tid, &t_add_info, j, member_array);
    158 
    159         if (r < 0) {
    160             bcm_trunk_destroy(unit, tid);
    161         }
    162         sal_free(member_array);
    163     } else if (sal_strcasecmp(subcmd, "remove") == 0) {
    164         bcm_module_t tm, _tm;
    165         bcm_port_t   tp, _tp;
    166         bcm_trunk_member_t *member_array = NULL;
    167         int member_count;
    168 
    169 	parse_table_init(unit, &pt);
    170         parse_table_add(&pt, "Id", PQ_DFL|PQ_INT, 0,
    171 			&arg_tid, NULL);
    172 	parse_table_add(&pt, "Pbmp", PQ_DFL|PQ_PBMP|PQ_BCM, (void *)(0),
    173 			&arg_pbmp, NULL);
    174 	if (!parseEndOk(a, &pt, &retCode)) {
    175 	    return retCode;
    176         }
    177 
    178         pbmp = arg_pbmp;
    179 	tid = arg_tid;
    180 
    181         member_array = sal_alloc(sizeof(bcm_trunk_member_t) *
    182                 BCM_TRUNK_MAX_PORTCNT, "member array");
    183         if (NULL == member_array) {
    184             cli_out("%s: ERROR: %s\n", ARG_CMD(a), bcm_errmsg(BCM_E_MEMORY));
    185             return CMD_FAIL;
    186         }
    187 	r = bcm_trunk_get(unit, tid, &t_add_info, BCM_TRUNK_MAX_PORTCNT,
    188                 member_array, &member_count);
    189 
    190 	if (r >= 0) {
    191             BCM_PBMP_CLEAR(pbmp);
    192             r = bcm_stk_my_modid_get(unit, &modid);
    193             if (r < 0) {
    194                 sal_free(member_array);
    195                 return CMD_FAIL;
    196             }
    197             for (i = 0; i < member_count; i++) {
    198                 if (BCM_GPORT_IS_DEVPORT(member_array[i].gport)) {
    199                     tm = modid;
    200                     tp = BCM_GPORT_DEVPORT_PORT_GET(member_array[i].gport);
    201                 } else if (BCM_GPORT_IS_MODPORT(member_array[i].gport)) {
    202                     tm = BCM_GPORT_MODPORT_MODID_GET(member_array[i].gport);
    203                     tp = BCM_GPORT_MODPORT_PORT_GET(member_array[i].gport);
    204                 } else {
    205                     sal_free(member_array);
    206                     return CMD_FAIL;
    207                 }
    208                 if ((tm != modid) && 
    209                     !soc_feature(unit, soc_feature_mod1))  {
    210                     tp +=32;
    211                 }
    212 	        BCM_PBMP_PORT_ADD(pbmp, tp);
    213             }
    214 	    BCM_PBMP_REMOVE(pbmp, arg_pbmp);
    215 
    216 	    j = 0;
    217             DPORT_BCM_PBMP_ITER(unit, pbmp, dport, i) {
    218                 tm = (soc_feature(unit, soc_feature_mod1) && i > 31) ? modid + 1: modid;
    219                 tp = i;
    220                 _tm = tm;
    221                 _tp = tp;
    222                 r = bcm_stk_modmap_map(unit, BCM_STK_MODMAP_GET, tm, tp, 
    223                         &tm, &tp); 
    224                 if (r == BCM_E_UNAVAIL) {
    225                     tm = _tm;
    226                     tp = _tp;
    227                 } else if (r < 0) {
    228                     sal_free(member_array);
    229                     return CMD_FAIL;
    230                 }
    231                 bcm_trunk_member_t_init(&member_array[j]);
    232                 if (BCM_GPORT_IS_SET(tp)) {
    233                     member_array[j].gport = tp;
    234                 } else {
    235                     BCM_GPORT_MODPORT_SET(member_array[j].gport, tm, tp);
    236                 }
    237                 j += 1;
    238             }
    239 
    240 	    if (j) {
    241                 r = bcm_trunk_set(unit, tid, &t_add_info, j, member_array);
    242 	    } else {
    243 		r = bcm_trunk_destroy(unit, tid);
    244             }
    245 	}
    246 
    247         sal_free(member_array);
    248     } else if (sal_strcasecmp(subcmd, "egress") == 0) {
    249 	parse_table_init(unit, &pt);
    250         parse_table_add(&pt, "Id", PQ_DFL|PQ_INT, 0, &arg_tid, NULL);
    251 	parse_table_add(&pt, "Pbmp", PQ_DFL|PQ_PBMP|PQ_BCM, (void *)(0),
    252                         &arg_pbmp, NULL);
    253         if (!parseEndOk( a, &pt, &retCode)) return retCode;
    254 	tid = arg_tid;
    255         BCM_PBMP_ASSIGN(pbmp, arg_pbmp);
    256 	r = bcm_trunk_egress_set(unit, tid, pbmp);
    257     } else if (sal_strcasecmp(subcmd, "mcast") == 0) {
    258 	parse_table_init(unit, &pt);
    259         parse_table_add(&pt, "Id", PQ_DFL|PQ_INT, 0, &arg_tid, NULL);
    260 	parse_table_add(&pt, "Mac", PQ_DFL|PQ_MAC, 0, (void *)mac, NULL);
    261 	parse_table_add(&pt, "Vlanid", 	PQ_DFL|PQ_HEX, 0, &arg_vlan, NULL);
    262 	if (!parseEndOk( a, &pt, &retCode)) {
    263 	    return retCode;
    264 	}
    265 
    266 	tid = arg_tid;
    267 	vid = arg_vlan;
    268 	r = bcm_trunk_mcast_join(unit, tid, vid, mac);
    269 #ifdef BCM_FIREBOLT_SUPPORT
    270     } else if (sal_strcasecmp(subcmd, "hash") == 0) {
    271         char *subcmd_s;
    272         bcm_port_t port, dport;
    273 
    274         if ((subcmd_s = ARG_GET(a)) == NULL) {
    275             return CMD_USAGE;
    276         }
    277 
    278         if (sal_strcasecmp(subcmd_s, "set") == 0) {
    279             parse_table_init(unit, &pt);
    280             parse_table_add(&pt, "Pbmp", PQ_DFL|PQ_PBMP|PQ_BCM, (void *)(0),
    281                             &arg_pbmp, NULL);
    282             parse_table_add(&pt, "HashValue", PQ_DFL|PQ_INT, 0, &arg_hash, NULL);
    283             if (!parseEndOk( a, &pt, &retCode)) {
    284                 return retCode;
    285             }
    286 
    287             /* coverity[overrun-local] */
    288             DPORT_BCM_PBMP_ITER(unit, arg_pbmp, dport, port) {
    289                r = bcm_port_trunk_index_set(unit, port, arg_hash);
    290             }
    291         } else if (sal_strcasecmp(subcmd_s, "get") == 0) {
    292             int hash;
    293 
    294             parse_table_init(unit, &pt);
    295             parse_table_add(&pt, "Pbmp", PQ_DFL|PQ_PBMP|PQ_BCM, (void *)(0),
    296                             &arg_pbmp, NULL);
    297             if (!parseEndOk( a, &pt, &retCode)) {
    298                 return retCode;
    299             }
    300             DPORT_BCM_PBMP_ITER(unit, arg_pbmp, dport, port) {
    301                r = bcm_port_trunk_index_get(unit, port, &hash);
    302 	       if (r >= 0) {
    303                    cli_out("port %s programmable hash set to %d\n",
    304                            BCM_PORT_NAME(unit, port), hash);
    305                }
    306             }
    307         } else {
    308             return CMD_USAGE;
    309         }
    310 #endif /* BCM_FIREBOLT_SUPPORT */
    311     } else if (sal_strcasecmp(subcmd, "psc") == 0) {
    312 	parse_table_init(unit, &pt);
    313         parse_table_add(&pt, "Id", PQ_DFL|PQ_INT, 0, &arg_tid, NULL);
    314         parse_table_add(&pt, "Rtag", PQ_DFL|PQ_INT, 0, &arg_rtag, NULL);
    315 	if (!parseEndOk(a, &pt, &retCode)) {
    316 	    return retCode;
    317         }
    318 
    319 	tid = arg_tid;
    320         psc = arg_rtag;
    321 
    322 	r = bcm_trunk_psc_set(unit, tid, psc);
    323     } else {
    324 	return CMD_USAGE;
    325     }
    326 
    327     if (r < 0) {
    328 	cli_out("%s: ERROR: %s\n", ARG_CMD(a), bcm_errmsg(r));
    329 	return CMD_FAIL;
    330     }
    331 
    332     return CMD_OK;
    333 }
    334 
    335 #ifdef BCM_HERCULES15_SUPPORT
    336 char trunkpool_cmd_usage[] =
    337     "\n\t"
    338     "trunkpool set [Id=<val>] [PortBitMap=<pbmp>] [Size=<val>]\n\t"
    339     "              [W0=<val>] [W1=<val>] ... [W7=<val>]\n\t"
    340     "           - Set trunk pool information\n\t"
    341     "trunkpool get [Id=<val>] [PortBitMap=<pbmp>]\n\t"
    342     "           - Get trunk pool information\n\t"
    343     "Note: Need to configure trunk before setting pool table.\n";
    344 
    345 cmd_result_t
    346 cmd_trunkpool(int unit, args_t *a)
    347 {
    348     char           *subcmd;
    349     parse_table_t  pt;
    350     cmd_result_t   retCode;
    351     bcm_pbmp_t pbmp;
    352     bcm_port_config_t pcfg;
    353     int     arg_psize=-1, arg_tid=0;
    354     int     weights[BCM_TRUNK_MAX_PORTCNT];
    355     bcm_trunk_info_t add_info;
    356     int            count[BCM_TRUNK_MAX_PORTCNT];
    357     int            i, port, dport, r, size;
    358     bcm_trunk_member_t *member_array = NULL;
    359     int            member_count;
    360     bcm_port_t     local_port;
    361 
    362     if (!sh_check_attached(ARG_CMD(a), unit)) {
    363         return CMD_FAIL;
    364     }
    365 
    366     if ((subcmd = ARG_GET(a)) == NULL) {
    367         return CMD_USAGE;
    368     }
    369 
    370     if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) {
    371         cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(a));
    372         return CMD_FAIL;
    373     }
    374 
    375     BCM_PBMP_CLEAR(pbmp);
    376     sal_memset(weights, 0, BCM_TRUNK_MAX_PORTCNT * sizeof(int));
    377 
    378     if (sal_strcasecmp(subcmd, "set") == 0) {
    379         parse_table_init(unit, &pt);
    380         parse_table_add(&pt, "PortBitMap", PQ_DFL|PQ_PBMP|PQ_BCM,
    381                         (void *)( 0), &pbmp, NULL);
    382         parse_table_add(&pt, "Id",   PQ_DFL|PQ_INT,
    383                         (void *)( 0), &arg_tid,  NULL);
    384         parse_table_add(&pt, "Size", PQ_DFL|PQ_INT,
    385                         (void *)( 0), &arg_psize, NULL);
    386         parse_table_add(&pt, "W0",      PQ_DFL|PQ_INT,
    387                         (void *)( 0), &weights[0], NULL);
    388         parse_table_add(&pt, "W1",      PQ_DFL|PQ_INT,
    389                         (void *)( 0), &weights[1], NULL);
    390         parse_table_add(&pt, "W2",      PQ_DFL|PQ_INT,
    391                         (void *)( 0), &weights[2], NULL);
    392         parse_table_add(&pt, "W3",      PQ_DFL|PQ_INT,
    393                         (void *)( 0), &weights[3], NULL);
    394         parse_table_add(&pt, "W4",      PQ_DFL|PQ_INT,
    395                         (void *)( 0), &weights[4], NULL);
    396         parse_table_add(&pt, "W5",      PQ_DFL|PQ_INT,
    397                         (void *)( 0), &weights[5], NULL);
    398         parse_table_add(&pt, "W6",      PQ_DFL|PQ_INT,
    399                         (void *)( 0), &weights[6], NULL);
    400         parse_table_add(&pt, "W7",      PQ_DFL|PQ_INT,
    401                         (void *)( 0), &weights[7], NULL);
    402 
    403         if (!parseEndOk(a, &pt, &retCode))
    404             return retCode;
    405 
    406         if (arg_psize < 0) {
    407             r = bcm_trunk_get(unit, arg_tid, &add_info,
    408                     0, NULL, &member_count);
    409             if (r >= 0) {
    410                 arg_psize = member_count;
    411             }
    412         }
    413 
    414         member_array = sal_alloc(sizeof(bcm_trunk_member_t) *
    415                 BCM_TRUNK_MAX_PORTCNT, "member array");
    416         if (NULL == member_array) {
    417             cli_out("ERROR: %s %s failed: %s\n",
    418                     ARG_CMD(a), subcmd, bcm_errmsg(BCM_E_MEMORY));
    419             return CMD_FAIL;
    420         }
    421         BCM_PBMP_AND(pbmp, pcfg.stack_ext);
    422         /* coverity[overrun-local] */
    423         DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) {
    424             r = bcm_trunk_pool_set(unit, port, arg_tid, arg_psize, weights);
    425             if (r < 0) {
    426                 cli_out("ERROR: %s %s port %s failed: %s\n",
    427                         ARG_CMD(a), subcmd, BCM_PORT_NAME(unit, port),
    428                         bcm_errmsg(r));
    429                 sal_free(member_array);
    430                 return CMD_FAIL;
    431             }
    432             cli_out("port %s trunk pool set:\n", BCM_PORT_NAME(unit, port));
    433             cli_out("     tid=%d   size=%d\n",arg_tid, arg_psize);
    434             r = bcm_trunk_get(unit, arg_tid, &add_info,
    435                     BCM_TRUNK_MAX_PORTCNT, member_array, &member_count);
    436             if (r >= 0) {
    437                 cli_out("     ");
    438                 for (i = 0; i < member_count; i++) {
    439                     r = bcm_port_local_get(unit, member_array[i].gport,
    440                             &local_port);
    441                     if (r >= 0) {
    442                         if (weights[local_port-1])
    443                             cli_out("W[%d]=%d ", local_port - 1,
    444                                     weights[local_port - 1]);
    445                     }
    446                 }
    447                 cli_out("\n");
    448             }
    449         }
    450         sal_free(member_array);
    451         return CMD_OK;
    452     }
    453 
    454     if (sal_strcasecmp(subcmd, "get") == 0) {
    455         parse_table_init(unit, &pt);
    456         parse_table_add(&pt, "PortBitMap", PQ_DFL|PQ_PBMP|PQ_BCM,
    457                         (void *)( 0), &pbmp, NULL);
    458         parse_table_add(&pt, "Id",   PQ_DFL|PQ_INT,
    459                         (void *)( 0), &arg_tid,  NULL);
    460         if (!parseEndOk(a, &pt, &retCode))
    461             return retCode;
    462 
    463         member_array = sal_alloc(sizeof(bcm_trunk_member_t) *
    464                 BCM_TRUNK_MAX_PORTCNT, "member array");
    465         if (NULL == member_array) {
    466             cli_out("ERROR: %s %s failed: %s\n",
    467                     ARG_CMD(a), subcmd, bcm_errmsg(BCM_E_MEMORY));
    468             return CMD_FAIL;
    469         }
    470 
    471         BCM_PBMP_AND(pbmp, pcfg.stack_ext);
    472         DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) {
    473             r = bcm_trunk_pool_get(unit, port, arg_tid, &size, count);
    474             if (r < 0) {
    475                 cli_out("ERROR: %s %s port %s failed: %s\n",
    476                         ARG_CMD(a), subcmd, BCM_PORT_NAME(unit, port),
    477                         bcm_errmsg(r));
    478                 sal_free(member_array);
    479                 return CMD_FAIL;
    480             }
    481             cli_out("port %s trunk pool get:\n", BCM_PORT_NAME(unit, port));
    482             cli_out("     tid=%d   size=%d\n",arg_tid, size);
    483             r = bcm_trunk_get(unit, arg_tid, &add_info,
    484                     BCM_TRUNK_MAX_PORTCNT, member_array, &member_count);
    485             if (r >= 0) {
    486                 cli_out("     ");
    487                 for (i = 0; i < member_count; i++) {
    488                     r = bcm_port_local_get(unit, member_array[i].gport,
    489                             &local_port);
    490                     if (r >= 0) {
    491                         if (count[local_port-1])
    492                             cli_out("TotalCount[%d]=%d ", local_port - 1,
    493                                     count[local_port - 1]);
    494                     }
    495                 }
    496                 cli_out("\n");
    497             }
    498         }
    499         sal_free(member_array);
    500         return CMD_OK;
    501     }
    502 
    503     return CMD_USAGE;
    504 }
    505 #endif /* BCM_HERCULES15_SUPPORT */