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