1118824Sharti/* 2118824Sharti * Copyright (c) 2001-2003 3118824Sharti * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4118824Sharti * All rights reserved. 5118824Sharti * 6118824Sharti * Redistribution and use in source and binary forms, with or without 7118824Sharti * modification, are permitted provided that the following conditions 8118824Sharti * are met: 9118824Sharti * 1. Redistributions of source code must retain the above copyright 10118824Sharti * notice, this list of conditions and the following disclaimer. 11118824Sharti * 2. Redistributions in binary form must reproduce the above copyright 12118824Sharti * notice, this list of conditions and the following disclaimer in the 13118824Sharti * documentation and/or other materials provided with the distribution. 14118824Sharti * 15118824Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16118824Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17118824Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18118824Sharti * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19118824Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20118824Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21118824Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22118824Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23118824Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24118824Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25118824Sharti * SUCH DAMAGE. 26118824Sharti * 27118824Sharti * Author: Hartmut Brandt <harti@freebsd.org> 28118824Sharti */ 29118824Sharti#include <sys/cdefs.h> 30118824Sharti__FBSDID("$FreeBSD$"); 31118824Sharti 32118824Sharti#include <sys/types.h> 33118824Sharti#include <sys/sysctl.h> 34118824Sharti#include <sys/ioctl.h> 35118824Sharti#include <sys/socket.h> 36118824Sharti#include <sys/queue.h> 37118824Sharti#include <net/if.h> 38118824Sharti#include <net/if_mib.h> 39118824Sharti#include <net/if_types.h> 40118824Sharti#include <net/if_atm.h> 41118824Sharti#include <net/if_media.h> 42118824Sharti#include <netnatm/natm.h> 43118824Sharti#include <dev/utopia/utopia.h> 44118824Sharti#include <dev/utopia/suni.h> 45118824Sharti#include <dev/utopia/idtphy.h> 46118824Sharti 47118824Sharti#include "atmconfig.h" 48118824Sharti#include "private.h" 49118824Sharti#include "diag.h" 50118824Sharti 51118824Shartistatic void diag_list(int, char *[]); 52118824Shartistatic void diag_config(int, char *[]); 53118824Shartistatic void diag_vcc(int, char *[]); 54118824Shartistatic void diag_phy_show(int, char *[]); 55118824Shartistatic void diag_phy_set(int, char *[]); 56118824Shartistatic void diag_phy_print(int, char *[]); 57118824Shartistatic void diag_phy_stats(int, char *[]); 58118824Shartistatic void diag_stats(int, char *[]); 59118824Sharti 60227081Sedstatic const struct cmdtab diag_phy_tab[] = { 61118824Sharti { "show", NULL, diag_phy_show }, 62118824Sharti { "set", NULL, diag_phy_set }, 63118824Sharti { "stats", NULL, diag_phy_stats }, 64118824Sharti { "print", NULL, diag_phy_print }, 65118824Sharti { NULL, NULL, NULL }, 66118824Sharti}; 67118824Sharti 68118824Sharticonst struct cmdtab diag_tab[] = { 69118824Sharti { "list", NULL, diag_list }, 70118824Sharti { "config", NULL, diag_config }, 71118824Sharti { "phy", diag_phy_tab, NULL }, 72118824Sharti { "stats", NULL, diag_stats }, 73118824Sharti { "vcc", NULL, diag_vcc }, 74118824Sharti { NULL, NULL, NULL } 75118824Sharti}; 76118824Sharti 77118824Shartistatic const struct utopia_print suni_lite[] = { SUNI_PRINT_LITE }; 78118824Shartistatic const struct utopia_print suni_ultra[] = { SUNI_PRINT_ULTRA }; 79118824Shartistatic const struct utopia_print suni_622[] = { SUNI_PRINT_622 }; 80118824Shartistatic const struct utopia_print idt77105[] = { IDTPHY_PRINT_77105 }; 81118824Shartistatic const struct utopia_print idt77155[] = { IDTPHY_PRINT_77155 }; 82118824Sharti 83118824Shartistatic const struct { 84118824Sharti const struct utopia_print *tab; 85118824Sharti u_int len; 86118824Sharti u_int type; 87118824Sharti} phy_print[] = { 88118824Sharti { suni_lite, sizeof(suni_lite) / sizeof(suni_lite[0]), 89118824Sharti UTP_TYPE_SUNI_LITE }, 90118824Sharti { suni_ultra, sizeof(suni_ultra) / sizeof(suni_ultra[0]), 91118824Sharti UTP_TYPE_SUNI_ULTRA }, 92118824Sharti { suni_622, sizeof(suni_622) / sizeof(suni_622[0]), 93118824Sharti UTP_TYPE_SUNI_622 }, 94118824Sharti { idt77105, sizeof(idt77105) / sizeof(idt77105[0]), 95118824Sharti UTP_TYPE_IDT77105 }, 96118824Sharti { idt77155, sizeof(idt77155) / sizeof(idt77155[0]), 97118824Sharti UTP_TYPE_IDT77155 }, 98118824Sharti}; 99118824Sharti 100118824Shartistatic const u_int utopia_addreg[] = { UTP_REG_ADD }; 101118824Sharti 102118824Sharti/* 103118824Sharti * Driver statistics printing 104118824Sharti */ 105118824Shartistatic const char *const print_stats_pca200e[] = { 106118824Sharti "cmd_queue_full:", 107118824Sharti "get_stat_errors:", 108118824Sharti "clr_stat_errors:", 109118824Sharti "get_prom_errors:", 110118824Sharti "suni_reg_errors:", 111118824Sharti "tx_queue_full:", 112118824Sharti "tx_queue_almost_full:", 113118824Sharti "tx_pdu2big:", 114118824Sharti "tx_too_many_segs:", 115118824Sharti "tx_retry:", 116118824Sharti "fix_empty:", 117118824Sharti "fix_addr_copy:", 118118824Sharti "fix_addr_noext:", 119118824Sharti "fix_addr_ext:", 120118824Sharti "fix_len_noext:", 121118824Sharti "fix_len_copy:", 122118824Sharti "fix_len:", 123118824Sharti "rx_badvc:", 124118824Sharti "rx_closed:", 125118824Sharti NULL 126118824Sharti}; 127118824Shartistatic const char *const print_stats_he[] = { 128118824Sharti "tdprq_full:", 129118824Sharti "hbuf_error:", 130118824Sharti "crc_error:", 131118824Sharti "len_error:", 132118824Sharti "flow_closed:", 133118824Sharti "flow_drop:", 134118824Sharti "tpd_no_mem:", 135118824Sharti "rx_seg:", 136118824Sharti "empty_hbuf:", 137118824Sharti "short_aal5:", 138118824Sharti "badlen_aal5:", 139118824Sharti "bug_bad_isw:", 140118824Sharti "bug_no_irq_upd:", 141118824Sharti "itype_tbrq:", 142118824Sharti "itype_tpd:", 143118824Sharti "itype_rbps:", 144118824Sharti "itype_rbpl:", 145118824Sharti "itype_rbrq:", 146118824Sharti "itype_rbrqt:", 147118824Sharti "itype_unknown:", 148118824Sharti "itype_phys:", 149118824Sharti "itype_err:", 150118824Sharti "defrag:", 151118824Sharti "mcc:", 152118824Sharti "oec:", 153118824Sharti "dcc:", 154118824Sharti "cec:", 155121676Sharti "no_rcv_mbuf:", 156118824Sharti NULL 157118824Sharti}; 158118824Shartistatic const char *const print_stats_eni[] = { 159118824Sharti "ttrash:", 160118824Sharti "mfixaddr:", 161118824Sharti "mfixlen:", 162118824Sharti "mfixfail:", 163118824Sharti "txmbovr:", 164118824Sharti "dmaovr:", 165118824Sharti "txoutspace:", 166118824Sharti "txdtqout:", 167118824Sharti "launch:", 168118824Sharti "hwpull:", 169118824Sharti "swadd:", 170118824Sharti "rxqnotus:", 171118824Sharti "rxqus:", 172118824Sharti "rxdrqout:", 173118824Sharti "rxmbufout:", 174118824Sharti "txnomap:", 175118824Sharti "vtrash:", 176118824Sharti "otrash:", 177118824Sharti NULL 178118824Sharti}; 179118824Sharti 180118824Shartistatic const char *const print_stats_idt77211[] = { 181118824Sharti "need_copy:", 182118824Sharti "copy_failed:", 183118824Sharti "out_of_tbds:", 184118824Sharti "no_txmaps:", 185118824Sharti "tx_load_err:", 186118824Sharti "tx_qfull:", 187118824Sharti NULL 188118824Sharti}; 189118824Shartistatic const char *const print_stats_idt77252[] = { 190118824Sharti "raw_cells:", 191118824Sharti "raw_no_vcc:", 192118824Sharti "raw_no_buf:", 193118824Sharti "tx_qfull:", 194118824Sharti "tx_out_of_tbds:", 195118824Sharti "tx_out_of_maps:", 196118824Sharti "tx_load_err:", 197118824Sharti NULL 198118824Sharti}; 199125018Shartistatic const char *const print_stats_virtual[] = { 200125018Sharti "dummy:", 201125018Sharti NULL 202125018Sharti}; 203118824Shartistatic const char *const *const print_stats[] = { 204118824Sharti [ATM_DEVICE_UNKNOWN] = NULL, 205118824Sharti [ATM_DEVICE_PCA200E] = print_stats_pca200e, 206118824Sharti [ATM_DEVICE_HE155] = print_stats_he, 207118824Sharti [ATM_DEVICE_HE622] = print_stats_he, 208118824Sharti [ATM_DEVICE_ENI155P] = print_stats_eni, 209118824Sharti [ATM_DEVICE_ADP155P] = print_stats_eni, 210118824Sharti [ATM_DEVICE_FORELE25] = print_stats_idt77211, 211118824Sharti [ATM_DEVICE_FORELE155] = print_stats_idt77211, 212118824Sharti [ATM_DEVICE_NICSTAR25] = print_stats_idt77211, 213118824Sharti [ATM_DEVICE_NICSTAR155] = print_stats_idt77211, 214118824Sharti [ATM_DEVICE_IDTABR25] = print_stats_idt77252, 215118824Sharti [ATM_DEVICE_IDTABR155] = print_stats_idt77252, 216118824Sharti [ATM_DEVICE_PROATM25] = print_stats_idt77252, 217118824Sharti [ATM_DEVICE_PROATM155] = print_stats_idt77252, 218125018Sharti [ATM_DEVICE_VIRTUAL] = print_stats_virtual, 219118824Sharti}; 220118824Sharti 221118824Shartistruct diagif_list diagif_list = TAILQ_HEAD_INITIALIZER(diagif_list); 222118824Sharti 223118824Sharti/* 224118824Sharti * Fetch a phy sysctl 225118824Sharti */ 226125018Shartistatic int 227125018Shartiphy_fetch(const char *ifname, const char *var, void *val, size_t len, 228125018Sharti int err_fatal) 229118824Sharti{ 230118824Sharti char *str; 231118824Sharti 232118824Sharti if (asprintf(&str, "hw.atm.%s.phy_%s", ifname, var) == -1) 233118824Sharti err(1, NULL); 234126643Smarkm if (sysctlbyname(str, val, &len, NULL, 0) == -1) { 235125018Sharti if (err_fatal || errno != ENOENT) 236125018Sharti err(1, "%s", str); 237125018Sharti free(str); 238125018Sharti return (-1); 239125018Sharti } 240118824Sharti free(str); 241125018Sharti return (0); 242118824Sharti} 243118824Sharti 244118824Sharti/* 245118824Sharti * Fetch the list of all ATM network interfaces and their MIBs. 246118824Sharti */ 247118824Shartivoid 248118824Shartidiagif_fetch(void) 249118824Sharti{ 250118824Sharti size_t len; 251118824Sharti int count; 252118824Sharti int name[6]; 253118824Sharti struct ifmibdata mib; 254118824Sharti struct ifatm_mib atm; 255118824Sharti int idx; 256118824Sharti struct diagif *d; 257118824Sharti 258118824Sharti while ((d = TAILQ_FIRST(&diagif_list)) != NULL) { 259118824Sharti if (d->vtab != NULL) 260118824Sharti free(d->vtab); 261118824Sharti TAILQ_REMOVE(&diagif_list, d, link); 262118824Sharti free(d); 263118824Sharti } 264118824Sharti 265118824Sharti len = sizeof(count); 266118824Sharti if (sysctlbyname("net.link.generic.system.ifcount", &count, &len, 267118824Sharti NULL, 0) == -1) 268118824Sharti err(1, "ifcount"); 269118824Sharti 270118824Sharti name[0] = CTL_NET; 271118824Sharti name[1] = PF_LINK; 272118824Sharti name[2] = NETLINK_GENERIC; 273118824Sharti name[3] = IFMIB_IFDATA; 274118824Sharti 275118824Sharti for (idx = 1; idx <= count; idx++) { 276118824Sharti name[4] = idx; 277118824Sharti name[5] = IFDATA_GENERAL; 278118824Sharti len = sizeof(mib); 279118824Sharti if (sysctl(name, 6, &mib, &len, NULL, 0) == -1) 280118824Sharti err(1, "interface %d: general mib", idx); 281118824Sharti if (mib.ifmd_data.ifi_type == IFT_ATM) { 282118824Sharti name[5] = IFDATA_LINKSPECIFIC; 283118824Sharti len = sizeof(atm); 284118824Sharti if (sysctl(name, 6, &atm, &len, NULL, 0) == -1) 285118824Sharti err(1, "interface %d: ATM mib", idx); 286118824Sharti 287118824Sharti d = malloc(sizeof(*d)); 288118824Sharti if (d == NULL) 289118824Sharti err(1, NULL); 290118824Sharti bzero(d, sizeof(*d)); 291118824Sharti d->mib = atm; 292118824Sharti d->index = idx; 293118824Sharti strcpy(d->ifname, mib.ifmd_name); 294118824Sharti TAILQ_INSERT_TAIL(&diagif_list, d, link); 295118824Sharti 296125018Sharti if (phy_fetch(d->ifname, "type", &d->phy_type, 297125018Sharti sizeof(d->phy_type), 0) == 0) { 298125018Sharti d->phy_present = 1; 299125018Sharti phy_fetch(d->ifname, "loopback", 300125018Sharti &d->phy_loopback, 301125018Sharti sizeof(d->phy_loopback), 1); 302125018Sharti phy_fetch(d->ifname, "name", &d->phy_name, 303125018Sharti sizeof(d->phy_name), 1); 304125018Sharti phy_fetch(d->ifname, "state", &d->phy_state, 305125018Sharti sizeof(d->phy_state), 1); 306125018Sharti phy_fetch(d->ifname, "carrier", &d->phy_carrier, 307125018Sharti sizeof(d->phy_carrier), 1); 308125018Sharti } 309118824Sharti } 310118824Sharti } 311118824Sharti} 312118824Sharti 313118824Sharti/* 314118824Sharti * "<radix><bit>STRING\011<mask><pattern>STRING\012<mask><radix>STRING" 315118824Sharti */ 316118824Shartistatic char * 317118824Shartiprintb8(uint32_t val, const char *descr) 318118824Sharti{ 319118824Sharti static char buffer[1000]; 320118824Sharti char *ptr; 321118824Sharti int tmp = 0; 322118824Sharti u_char mask, pattern; 323118824Sharti 324118824Sharti if (*descr++ == '\010') 325118824Sharti sprintf(buffer, "%#o", val); 326118824Sharti else 327118824Sharti sprintf(buffer, "%#x", val); 328118824Sharti ptr = buffer + strlen(buffer); 329118824Sharti 330118824Sharti *ptr++ = '<'; 331118824Sharti while (*descr) { 332118824Sharti if (*descr == '\11') { 333118824Sharti descr++; 334118824Sharti mask = *descr++; 335118824Sharti pattern = *descr++; 336118824Sharti if ((val & mask) == pattern) { 337118824Sharti if (tmp++) 338118824Sharti *ptr++ = ','; 339118824Sharti while (*descr >= ' ') 340118824Sharti *ptr++ = *descr++; 341118824Sharti } else { 342118824Sharti while (*descr >= ' ') 343118824Sharti descr++; 344118824Sharti } 345118824Sharti } else if (*descr == '\12') { 346118824Sharti descr++; 347118824Sharti mask = *descr++; 348118824Sharti pattern = *descr++; 349118824Sharti if (tmp++) 350118824Sharti *ptr++ = ','; 351118824Sharti while (*descr >= ' ') 352118824Sharti *ptr++ = *descr++; 353118824Sharti *ptr++ = '='; 354118824Sharti if (pattern == 8) 355118824Sharti sprintf(ptr, "%#o", 356118824Sharti (val & mask) >> (ffs(mask)-1)); 357118824Sharti else if (pattern == 10) 358118824Sharti sprintf(ptr, "%u", 359118824Sharti (val & mask) >> (ffs(mask)-1)); 360118824Sharti else 361118824Sharti sprintf(ptr, "%#x", 362118824Sharti (val & mask) >> (ffs(mask)-1)); 363118824Sharti ptr += strlen(ptr); 364118824Sharti } else { 365118824Sharti if (val & (1 << (*descr++ - 1))) { 366118824Sharti if (tmp++) 367118824Sharti *ptr++ = ','; 368118824Sharti while (*descr >= ' ') 369118824Sharti *ptr++ = *descr++; 370118824Sharti } else { 371118824Sharti while (*descr >= ' ') 372118824Sharti descr++; 373118824Sharti } 374118824Sharti } 375118824Sharti } 376118824Sharti *ptr++ = '>'; 377118824Sharti *ptr++ = '\0'; 378118824Sharti 379118824Sharti return (buffer); 380118824Sharti} 381118824Sharti 382118824Sharti/* 383118824Sharti * "<radix><bit>STRING<bit>STRING" 384118824Sharti */ 385118824Shartistatic char * 386118824Shartiprintb(uint32_t val, const char *descr) 387118824Sharti{ 388118824Sharti static char buffer[1000]; 389118824Sharti char *ptr; 390118824Sharti int tmp = 0; 391118824Sharti 392118824Sharti if (*descr++ == '\010') 393118824Sharti sprintf(buffer, "%#o", val); 394118824Sharti else 395118824Sharti sprintf(buffer, "%#x", val); 396118824Sharti ptr = buffer + strlen(buffer); 397118824Sharti 398118824Sharti *ptr++ = '<'; 399118824Sharti while (*descr) { 400118824Sharti if (val & (1 << (*descr++ - 1))) { 401118824Sharti if (tmp++) 402118824Sharti *ptr++ = ','; 403118824Sharti while (*descr > ' ') 404118824Sharti *ptr++ = *descr++; 405118824Sharti } else { 406118824Sharti while (*descr > ' ') 407118824Sharti descr++; 408118824Sharti } 409118824Sharti } 410118824Sharti *ptr++ = '>'; 411118824Sharti *ptr++ = '\0'; 412118824Sharti 413118824Sharti return (buffer); 414118824Sharti} 415118824Sharti 416118824Sharti 417118824Shartistatic void 418118824Shartidiag_loop(int argc, char *argv[], const char *text, 419118824Sharti void (*func)(const struct diagif *)) 420118824Sharti{ 421118824Sharti int i; 422118824Sharti struct diagif *aif; 423118824Sharti 424118824Sharti heading_init(); 425118824Sharti if (argc > 0) { 426118824Sharti for (i = 0; i < argc; i++) { 427118824Sharti TAILQ_FOREACH(aif, &diagif_list, link) { 428118824Sharti if (strcmp(argv[i], aif->ifname) == 0) { 429228611Sdim heading("%s", text); 430118824Sharti (*func)(aif); 431118824Sharti break; 432118824Sharti } 433118824Sharti } 434118824Sharti if (aif == NULL) 435118824Sharti warnx("%s: no such ATM interface", argv[i]); 436118824Sharti } 437118824Sharti } else { 438118824Sharti TAILQ_FOREACH(aif, &diagif_list, link) { 439228611Sdim heading("%s", text); 440118824Sharti (*func)(aif); 441118824Sharti } 442118824Sharti } 443118824Sharti} 444118824Sharti 445118824Sharti/* 446118824Sharti * Print the config line for the given interface 447118824Sharti */ 448118824Shartistatic void 449118824Sharticonfig_line1(const struct diagif *aif) 450118824Sharti{ 451118824Sharti printf("%-6u%-9s%-8u%-5u%-6u%-5u%-6u%02x:%02x:%02x:%02x:%02x:%02x\n", 452118824Sharti aif->index, aif->ifname, aif->mib.pcr, (1 << aif->mib.vpi_bits) - 1, 453118824Sharti (1 << aif->mib.vci_bits) - 1, aif->mib.max_vpcs, aif->mib.max_vccs, 454118824Sharti aif->mib.esi[0], aif->mib.esi[1], aif->mib.esi[2], 455118824Sharti aif->mib.esi[3], aif->mib.esi[4], aif->mib.esi[5]); 456118824Sharti} 457118824Sharti 458118824Shartistatic void 459118824Sharticonfig_line2(const struct diagif *aif) 460118824Sharti{ 461118824Sharti u_int d, i; 462118824Sharti 463118824Sharti static const struct { 464118824Sharti const char *dev; 465118824Sharti const char *vendor; 466118824Sharti } devs[] = { 467118824Sharti ATM_DEVICE_NAMES 468118824Sharti }; 469118824Sharti static const struct { 470118824Sharti u_int media; 471118824Sharti const char *const name; 472118824Sharti } medias[] = IFM_SUBTYPE_ATM_DESCRIPTIONS; 473118824Sharti 474118824Sharti for (i = 0; medias[i].name; i++) 475118824Sharti if (aif->mib.media == medias[i].media) 476118824Sharti break; 477118824Sharti 478118824Sharti if ((d = aif->mib.device) >= sizeof(devs) / sizeof(devs[0])) 479118824Sharti d = 0; 480118824Sharti 481118824Sharti printf("%-6u%-9s%-12.11s%-13.12s%-8u%-6x%-6x %s\n", aif->index, 482118824Sharti aif->ifname, devs[d].vendor, devs[d].dev, aif->mib.serial, 483118824Sharti aif->mib.hw_version, aif->mib.sw_version, 484118824Sharti medias[i].name ? medias[i].name : "unknown"); 485118824Sharti} 486118824Sharti 487118824Shartistatic void 488118824Shartidiag_config(int argc, char *argv[]) 489118824Sharti{ 490118824Sharti int opt; 491118824Sharti 492118824Sharti static int hardware; 493118824Sharti static int atm; 494118824Sharti 495118824Sharti static const struct option opts[] = { 496118824Sharti { "hardware", OPT_SIMPLE, &hardware }, 497118824Sharti { "atm", OPT_SIMPLE, &atm }, 498118824Sharti { NULL, 0, NULL } 499118824Sharti }; 500118824Sharti 501118824Sharti static const char config_text1[] = 502118824Sharti "Interface Max Max\n" 503132502Sharti "Index Name PCR VPI VCI VPCs VCCs ESI\n"; 504118824Sharti static const char config_text2[] = 505118824Sharti "Interface Version\n" 506118824Sharti "Index Name Vendor Card " 507118824Sharti "Serial HW SW Media\n"; 508118824Sharti 509118824Sharti while ((opt = parse_options(&argc, &argv, opts)) != -1) 510118824Sharti switch (opt) { 511118824Sharti } 512118824Sharti 513118824Sharti diagif_fetch(); 514118824Sharti if (TAILQ_EMPTY(&diagif_list)) 515118824Sharti errx(1, "no ATM interfaces found"); 516118824Sharti 517118824Sharti if (!atm && !hardware) 518118824Sharti atm = 1; 519118824Sharti 520118824Sharti if (atm) 521118824Sharti diag_loop(argc, argv, config_text1, config_line1); 522118824Sharti if (hardware) 523118824Sharti diag_loop(argc, argv, config_text2, config_line2); 524118824Sharti 525118824Sharti} 526118824Sharti 527118824Shartistatic void 528118824Shartidiag_list(int argc, char *argv[]) 529118824Sharti{ 530118824Sharti int opt; 531118824Sharti struct diagif *aif; 532118824Sharti 533118824Sharti static const struct option opts[] = { 534118824Sharti { NULL, 0, NULL } 535118824Sharti }; 536118824Sharti 537118824Sharti while ((opt = parse_options(&argc, &argv, opts)) != -1) 538118824Sharti switch (opt) { 539118824Sharti } 540118824Sharti 541118824Sharti if (argc > 0) 542118824Sharti errx(1, "no arguments required for 'diag list'"); 543118824Sharti 544118824Sharti diagif_fetch(); 545118824Sharti if (TAILQ_EMPTY(&diagif_list)) 546118824Sharti errx(1, "no ATM interfaces found"); 547118824Sharti 548118824Sharti TAILQ_FOREACH(aif, &diagif_list, link) 549118824Sharti printf("%s ", aif->ifname); 550118824Sharti printf("\n"); 551118824Sharti} 552118824Sharti 553118824Sharti/* 554118824Sharti * Print the config line for the given interface 555118824Sharti */ 556118824Shartistatic void 557118824Shartiphy_show_line(const struct diagif *aif) 558118824Sharti{ 559125018Sharti printf("%-6u%-9s", aif->index, aif->ifname); 560125018Sharti if (aif->phy_present) 561125018Sharti printf("%-5u%-25s0x%-9x", aif->phy_type, 562125018Sharti aif->phy_name, aif->phy_loopback); 563125018Sharti printf("\n"); 564118824Sharti} 565118824Sharti 566118824Shartistatic void 567118824Shartidiag_phy_show(int argc, char *argv[]) 568118824Sharti{ 569118824Sharti int opt; 570118824Sharti 571118824Sharti static const struct option opts[] = { 572118824Sharti { NULL, 0, NULL } 573118824Sharti }; 574118824Sharti 575118824Sharti static const char phy_show_text[] = 576118824Sharti "Interface Phy\n" 577118824Sharti "Index Name Type Name Loopback State\n"; 578118824Sharti 579118824Sharti while ((opt = parse_options(&argc, &argv, opts)) != -1) 580118824Sharti switch (opt) { 581118824Sharti } 582118824Sharti 583118824Sharti diagif_fetch(); 584118824Sharti if (TAILQ_EMPTY(&diagif_list)) 585118824Sharti errx(1, "no ATM interfaces found"); 586118824Sharti 587118824Sharti diag_loop(argc, argv, phy_show_text, phy_show_line); 588118824Sharti} 589118824Sharti 590125018Sharti/* 591125018Sharti * Make sure the interface exists and has a phy 592125018Sharti */ 593125018Shartistatic struct diagif * 594125018Shartidiagif_get_phy(const char *arg) 595125018Sharti{ 596125018Sharti struct diagif *aif; 597125018Sharti 598125018Sharti diagif_fetch(); 599125018Sharti TAILQ_FOREACH(aif, &diagif_list, link) 600125018Sharti if (strcmp(aif->ifname, arg) == 0) 601125018Sharti break; 602125018Sharti if (aif == NULL) 603125018Sharti errx(1, "no such interface: %s", arg); 604125018Sharti if (!aif->phy_present) 605125018Sharti errx(1, "interface %s has no phy", arg); 606125018Sharti 607125018Sharti return (aif); 608125018Sharti} 609125018Sharti 610118824Shartistatic void 611118824Shartidiag_phy_set(int argc, char *argv[]) 612118824Sharti{ 613118824Sharti int opt; 614118824Sharti uint8_t reg[3]; 615118824Sharti u_long res; 616118824Sharti char *end; 617118824Sharti char *str; 618118824Sharti 619118824Sharti static const struct option opts[] = { 620118824Sharti { NULL, 0, NULL } 621118824Sharti }; 622118824Sharti 623118824Sharti while ((opt = parse_options(&argc, &argv, opts)) != -1) 624118824Sharti switch (opt) { 625118824Sharti } 626118824Sharti 627118824Sharti if (argc != 4) 628118824Sharti errx(1, "missing arguments for 'diag phy set'"); 629118824Sharti 630118824Sharti errno = 0; 631118824Sharti res = strtoul(argv[1], &end, 0); 632118824Sharti if (errno != 0) 633118824Sharti err(1, "register number"); 634118824Sharti if (*end != '\0') 635118824Sharti errx(1, "malformed register number '%s'", argv[1]); 636118824Sharti if (res > 0xff) 637118824Sharti errx(1, "register number too large"); 638118824Sharti reg[0] = res; 639118824Sharti 640118824Sharti errno = 0; 641118824Sharti res = strtoul(argv[2], &end, 0); 642118824Sharti if (errno != 0) 643118824Sharti err(1, "mask"); 644118824Sharti if (*end != '\0') 645118824Sharti errx(1, "malformed mask '%s'", argv[1]); 646118824Sharti if (res > 0xff) 647118824Sharti errx(1, "mask too large"); 648118824Sharti reg[1] = res; 649118824Sharti 650118824Sharti errno = 0; 651118824Sharti res = strtoul(argv[3], &end, 0); 652118824Sharti if (errno != 0) 653118824Sharti err(1, "value"); 654118824Sharti if (*end != '\0') 655118824Sharti errx(1, "malformed value '%s'", argv[1]); 656118824Sharti if (res > 0xff) 657118824Sharti errx(1, "value too large"); 658118824Sharti reg[2] = res; 659118824Sharti 660125018Sharti (void)diagif_get_phy(argv[0]); 661125018Sharti 662118824Sharti if (asprintf(&str, "hw.atm.%s.phy_regs", argv[0]) == -1) 663118824Sharti err(1, NULL); 664118824Sharti 665118824Sharti if (sysctlbyname(str, NULL, NULL, reg, 3 * sizeof(uint8_t))) 666118824Sharti err(1, "%s", str); 667118824Sharti 668118824Sharti free(str); 669118824Sharti} 670118824Sharti 671118824Shartistatic void 672118824Shartidiag_phy_print(int argc, char *argv[]) 673118824Sharti{ 674118824Sharti int opt; 675118824Sharti char *str; 676118824Sharti size_t len, len1; 677118824Sharti uint8_t *regs; 678118824Sharti u_int type, i; 679118824Sharti const struct utopia_print *p; 680118824Sharti 681118824Sharti static int numeric; 682118824Sharti 683118824Sharti static const struct option opts[] = { 684118824Sharti { "numeric", OPT_SIMPLE, &numeric }, 685118824Sharti { NULL, 0, NULL } 686118824Sharti }; 687118824Sharti 688118824Sharti while ((opt = parse_options(&argc, &argv, opts)) != -1) 689118824Sharti switch (opt) { 690118824Sharti } 691118824Sharti 692118824Sharti if (argc != 1) 693118824Sharti errx(1, "need device name for 'diag phy print'"); 694118824Sharti 695125018Sharti (void)diagif_get_phy(argv[0]); 696125018Sharti 697118824Sharti if (asprintf(&str, "hw.atm.%s.phy_regs", argv[0]) == -1) 698118824Sharti err(1, NULL); 699118824Sharti len = 0; 700118824Sharti if (sysctlbyname(str, NULL, &len, NULL, 0)) 701118824Sharti err(1, "'%s' not found", str); 702118824Sharti 703118824Sharti regs = malloc(len); 704118824Sharti if (regs == NULL) 705118824Sharti err(1, NULL); 706118824Sharti 707118824Sharti if (sysctlbyname(str, regs, &len, NULL, 0)) 708118824Sharti err(1, "'%s' not found", str); 709118824Sharti free(str); 710118824Sharti 711118824Sharti if (numeric) { 712118824Sharti for (i = 0; i < len; i++) { 713118824Sharti if (i % 16 == 0) 714118824Sharti printf("%02x: ", i); 715118824Sharti if (i % 16 == 8) 716118824Sharti printf(" "); 717118824Sharti printf(" %02x", regs[i]); 718118824Sharti if (i % 16 == 15) 719118824Sharti printf("\n"); 720118824Sharti } 721118824Sharti if (i % 16 != 0) 722118824Sharti printf("\n"); 723118824Sharti } else { 724118824Sharti if (asprintf(&str, "hw.atm.%s.phy_type", argv[0]) == -1) 725118824Sharti err(1, NULL); 726118824Sharti len1 = sizeof(type); 727118824Sharti if (sysctlbyname(str, &type, &len1, NULL, 0)) 728118824Sharti err(1, "'%s' not found", str); 729118824Sharti free(str); 730118824Sharti 731118824Sharti for (i = 0; i < sizeof(phy_print) / sizeof(phy_print[0]); i++) 732118824Sharti if (type == phy_print[i].type) 733118824Sharti break; 734118824Sharti if (i == sizeof(phy_print) / sizeof(phy_print[0])) 735118824Sharti errx(1, "unknown PHY chip type %u\n", type); 736118824Sharti 737118824Sharti for (p = phy_print[i].tab; 738118824Sharti p < phy_print[i].tab + phy_print[i].len; 739118824Sharti p++) { 740118824Sharti if (p->reg + utopia_addreg[p->type] > len) 741118824Sharti /* don't have this register */ 742118824Sharti continue; 743118824Sharti 744118824Sharti printf("%s:%*s", p->name, 40 - (int)strlen(p->name),""); 745118824Sharti 746118824Sharti switch (p->type) { 747118824Sharti 748118824Sharti case UTP_REGT_BITS: 749118824Sharti printf("%s\n", printb8(regs[p->reg], p->fmt)); 750118824Sharti break; 751118824Sharti 752118824Sharti case UTP_REGT_INT8: 753118824Sharti printf("%#x\n", regs[p->reg]); 754118824Sharti break; 755118824Sharti 756118824Sharti case UTP_REGT_INT10BITS: 757118824Sharti printf("%#x %s\n", regs[p->reg] | 758118824Sharti ((regs[p->reg + 1] & 0x3) << 8), 759118824Sharti printb8(regs[p->reg + 1], p->fmt)); 760118824Sharti break; 761118824Sharti 762118824Sharti case UTP_REGT_INT12: 763118824Sharti printf("%#x\n", regs[p->reg] | 764118824Sharti ((regs[p->reg + 1] & 0xf) << 8)); 765118824Sharti break; 766118824Sharti 767118824Sharti case UTP_REGT_INT16: 768118824Sharti printf("%#x\n", regs[p->reg] | 769118824Sharti (regs[p->reg + 1] << 8)); 770118824Sharti break; 771118824Sharti 772118824Sharti case UTP_REGT_INT19: 773118824Sharti printf("%#x\n", regs[p->reg] | 774118824Sharti (regs[p->reg + 1] << 8) | 775118824Sharti ((regs[p->reg + 2] & 0x7) << 16)); 776118824Sharti break; 777118824Sharti 778118824Sharti case UTP_REGT_INT20: 779118824Sharti printf("%#x\n", regs[p->reg] | 780118824Sharti (regs[p->reg + 1] << 8) | 781118824Sharti ((regs[p->reg + 2] & 0xf) << 16)); 782118824Sharti break; 783118824Sharti 784118824Sharti case UTP_REGT_INT21: 785118824Sharti printf("%#x\n", regs[p->reg] | 786118824Sharti (regs[p->reg + 1] << 8) | 787118824Sharti ((regs[p->reg + 2] & 0x1f) << 16)); 788118824Sharti break; 789118824Sharti 790118824Sharti default: 791118824Sharti abort(); 792118824Sharti } 793118824Sharti } 794118824Sharti } 795118824Sharti free(regs); 796118824Sharti} 797118824Sharti 798118824Shartistatic void 799118824Shartidiag_phy_stats(int argc, char *argv[]) 800118824Sharti{ 801118824Sharti int opt; 802118824Sharti size_t len; 803118824Sharti char *str; 804118824Sharti struct utopia_stats1 stats1; 805118824Sharti u_int foo; 806118824Sharti 807118824Sharti static int clear; 808118824Sharti 809118824Sharti static const struct option opts[] = { 810118824Sharti { "clear", OPT_SIMPLE, &clear }, 811118824Sharti { NULL, 0, NULL } 812118824Sharti }; 813118824Sharti 814118824Sharti while ((opt = parse_options(&argc, &argv, opts)) != -1) 815118824Sharti switch (opt) { 816118824Sharti } 817118824Sharti 818118824Sharti if (argc != 1) 819118824Sharti errx(1, "need device name for 'diag phy stats'"); 820118824Sharti 821125018Sharti (void)diagif_get_phy(argv[0]); 822125018Sharti 823118824Sharti if (asprintf(&str, "hw.atm.%s.phy_stats", argv[0]) == -1) 824118824Sharti err(1, NULL); 825118824Sharti 826118824Sharti len = sizeof(stats1); 827118824Sharti if (sysctlbyname(str, &stats1, &len, 828118824Sharti clear ? &foo : NULL, clear ? sizeof(foo) : 0)) 829118824Sharti err(1, "'%s' not found", str); 830118824Sharti if (len < sizeof(stats1.version)) 831118824Sharti errx(1, "phy statistics too short %zu", len); 832118824Sharti 833118824Sharti switch (stats1.version) { 834118824Sharti 835118824Sharti case 1: 836118824Sharti if (len != sizeof(stats1)) 837118824Sharti errx(1, "bad phy stats length %zu (expecting %zu)", 838118824Sharti len, sizeof(stats1)); 839118824Sharti break; 840118824Sharti 841118824Sharti default: 842118824Sharti errx(1, "unknown phy stats version %u", stats1.version); 843118824Sharti } 844118824Sharti 845118824Sharti free(str); 846118824Sharti 847118824Sharti printf("rx_sbip: %llu\n", (unsigned long long)stats1.rx_sbip); 848118824Sharti printf("rx_lbip: %llu\n", (unsigned long long)stats1.rx_lbip); 849118824Sharti printf("rx_lfebe: %llu\n", (unsigned long long)stats1.rx_lfebe); 850118824Sharti printf("rx_pbip: %llu\n", (unsigned long long)stats1.rx_pbip); 851118824Sharti printf("rx_pfebe: %llu\n", (unsigned long long)stats1.rx_pfebe); 852118824Sharti printf("rx_cells: %llu\n", (unsigned long long)stats1.rx_cells); 853118824Sharti printf("rx_corr: %llu\n", (unsigned long long)stats1.rx_corr); 854118824Sharti printf("rx_uncorr: %llu\n", (unsigned long long)stats1.rx_uncorr); 855118824Sharti printf("rx_symerr: %llu\n", (unsigned long long)stats1.rx_symerr); 856118824Sharti printf("tx_cells: %llu\n", (unsigned long long)stats1.tx_cells); 857118824Sharti} 858118824Sharti 859118824Sharti/* 860118824Sharti * Fetch the table of open vccs 861118824Sharti */ 862118824Shartivoid 863118824Shartidiagif_fetch_vcc(struct diagif *aif, int fd) 864118824Sharti{ 865118824Sharti struct ifreq ifr; 866118824Sharti 867118824Sharti if (aif->vtab != NULL) 868118824Sharti return; 869118824Sharti 870118824Sharti strncpy(ifr.ifr_name, aif->ifname, IFNAMSIZ); 871168726Smaxim ifr.ifr_name[IFNAMSIZ - 1] = '\0'; 872118824Sharti 873118824Sharti aif->vtab = malloc(sizeof(*aif->vtab) + sizeof(aif->vtab->vccs[0]) * 874118824Sharti aif->mib.max_vccs); 875118824Sharti if (aif->vtab == NULL) 876118824Sharti err(1, NULL); 877118824Sharti ifr.ifr_data = (caddr_t)aif->vtab; 878118824Sharti 879118824Sharti if (ioctl(fd, SIOCATMGVCCS, &ifr) == -1) 880118824Sharti err(1, "SIOCATMGVCCS"); 881118824Sharti} 882118824Sharti 883118824Sharti/* 884118824Sharti * Print the VCC table for this interface. 885118824Sharti */ 886118824Shartistatic void 887118824Shartiprint_channel(const struct diagif *aif) 888118824Sharti{ 889118824Sharti const struct atmio_vcc *v; 890118824Sharti 891118824Sharti static const char *const aal_tab[] = { 892148718Sstefanf [ATMIO_AAL_0] = "0", 893148718Sstefanf [ATMIO_AAL_34] = "3/4", 894148718Sstefanf [ATMIO_AAL_5] = "5", 895148718Sstefanf [ATMIO_AAL_RAW] = "raw", 896118824Sharti }; 897118824Sharti static const char *const traffic_tab[] = { 898148718Sstefanf [ATMIO_TRAFFIC_UBR] = "ubr", 899148718Sstefanf [ATMIO_TRAFFIC_CBR] = "cbr", 900148718Sstefanf [ATMIO_TRAFFIC_ABR] = "abr", 901148718Sstefanf [ATMIO_TRAFFIC_VBR] = "vbr", 902118824Sharti }; 903118824Sharti 904118824Sharti for (v = aif->vtab->vccs; v < &aif->vtab->vccs[aif->vtab->count]; v++) { 905118824Sharti printf("%-6u%-9s%-4u%-6u", aif->index, aif->ifname, 906118824Sharti v->vpi, v->vci); 907118824Sharti 908118824Sharti if (v->aal >= sizeof(aal_tab)/sizeof(aal_tab[0]) || 909118824Sharti aal_tab[v->aal] == NULL) 910118824Sharti printf("bad "); 911118824Sharti else 912118824Sharti printf("%-4s", aal_tab[v->aal]); 913118824Sharti 914118824Sharti if (v->traffic >= sizeof(traffic_tab)/sizeof(traffic_tab[0]) || 915118824Sharti traffic_tab[v->traffic] == NULL) 916118824Sharti printf("bad "); 917118824Sharti else 918118824Sharti printf("%-8s", traffic_tab[v->traffic]); 919118824Sharti 920118824Sharti printf("%-6u%-6u%s\n", v->rmtu, v->tmtu, 921118824Sharti printb(v->flags, ATMIO_FLAGS)); 922118824Sharti } 923118824Sharti} 924118824Sharti 925118824Sharti/* 926118824Sharti * Print the VCC table for this interface, traffic parameters. 927118824Sharti */ 928118824Shartistatic void 929118824Shartiprint_traffic(const struct diagif *aif) 930118824Sharti{ 931118824Sharti const struct atmio_vcc *v; 932118824Sharti 933118824Sharti for (v = aif->vtab->vccs; v < &aif->vtab->vccs[aif->vtab->count]; v++) { 934118824Sharti printf("%-6u%-9s%-4u%-6u", aif->index, aif->ifname, 935118824Sharti v->vpi, v->vci); 936118824Sharti 937118824Sharti switch (v->traffic) { 938118824Sharti 939118824Sharti case ATMIO_TRAFFIC_CBR: 940118824Sharti printf("%u", v->tparam.pcr); 941118824Sharti break; 942118824Sharti 943118824Sharti case ATMIO_TRAFFIC_UBR: 944118824Sharti printf("%-8u %u", v->tparam.pcr, 945118824Sharti v->tparam.mcr); 946118824Sharti break; 947118824Sharti 948118824Sharti case ATMIO_TRAFFIC_VBR: 949118824Sharti printf("%-8u%-8u%-8u", v->tparam.pcr, v->tparam.scr, 950118824Sharti v->tparam.mbs); 951118824Sharti break; 952118824Sharti 953118824Sharti case ATMIO_TRAFFIC_ABR: 954118824Sharti printf("%-8u %-8u", 955118824Sharti v->tparam.pcr, v->tparam.mcr); 956118824Sharti break; 957118824Sharti } 958118824Sharti printf("\n"); 959118824Sharti } 960118824Sharti} 961118824Sharti 962118824Sharti/* 963118824Sharti * Print the VCC table for this interface, ABR traffic parameters. 964118824Sharti */ 965118824Shartistatic void 966118824Shartiprint_abr(const struct diagif *aif) 967118824Sharti{ 968118824Sharti const struct atmio_vcc *v; 969118824Sharti 970118824Sharti for (v = aif->vtab->vccs; v < &aif->vtab->vccs[aif->vtab->count]; v++) { 971118824Sharti printf("%-6u%-9s%-4u%-6u", aif->index, aif->ifname, 972118824Sharti v->vpi, v->vci); 973118824Sharti 974118824Sharti if (v->traffic == ATMIO_TRAFFIC_ABR) { 975118824Sharti printf("%-8u%-8u%-4u%-4u%-5u%-5u%-5u%u", 976118824Sharti v->tparam.icr, v->tparam.tbe, v->tparam.nrm, 977118824Sharti v->tparam.trm, v->tparam.adtf, v->tparam.rif, 978118824Sharti v->tparam.rdf, v->tparam.cdf); 979118824Sharti } 980118824Sharti printf("\n"); 981118824Sharti } 982118824Sharti} 983118824Sharti 984118824Shartistatic void 985118824Shartidiag_vcc_loop(void (*func)(const struct diagif *), const char *text, 986118824Sharti int argc, char *argv[], int fd) 987118824Sharti{ 988118824Sharti struct diagif *aif; 989118824Sharti 990118824Sharti heading_init(); 991118824Sharti if (argc == 0) { 992118824Sharti TAILQ_FOREACH(aif, &diagif_list, link) { 993118824Sharti diagif_fetch_vcc(aif, fd); 994118824Sharti if (aif->vtab->count != 0) { 995228611Sdim heading("%s", text); 996118824Sharti (*func)(aif); 997118824Sharti } 998118824Sharti } 999118824Sharti 1000118824Sharti } else { 1001118824Sharti for (optind = 0; optind < argc; optind++) { 1002118824Sharti TAILQ_FOREACH(aif, &diagif_list, link) 1003118824Sharti if (strcmp(aif->ifname, argv[optind]) == 0) { 1004118824Sharti diagif_fetch_vcc(aif, fd); 1005118824Sharti if (aif->vtab->count != 0) { 1006228611Sdim heading("%s", text); 1007118824Sharti (*func)(aif); 1008118824Sharti } 1009118824Sharti break; 1010118824Sharti } 1011118824Sharti if (aif == NULL) 1012118824Sharti warnx("no such interface '%s'", argv[optind]); 1013118824Sharti } 1014118824Sharti } 1015118824Sharti} 1016118824Sharti 1017118824Shartistatic void 1018118824Shartidiag_vcc(int argc, char *argv[]) 1019118824Sharti{ 1020118824Sharti int opt, fd; 1021118824Sharti 1022118824Sharti static int channel, traffic, abr; 1023118824Sharti static const struct option opts[] = { 1024118824Sharti { "abr", OPT_SIMPLE, &abr }, 1025118824Sharti { "channel", OPT_SIMPLE, &channel }, 1026118824Sharti { "traffic", OPT_SIMPLE, &traffic }, 1027118824Sharti { NULL, 0, NULL } 1028118824Sharti }; 1029118824Sharti static const char head_channel[] = 1030118824Sharti "Interface\n" 1031118824Sharti "Index Name VPI VCI AAL Traffic RxMTU TxMTU Flags\n"; 1032118824Sharti static const char head_traffic[] = 1033118824Sharti "Interface Traffic parameters\n" 1034118824Sharti "Index Name VPI VCI PCR SCR MBS MCR\n"; 1035118824Sharti static const char head_abr[] = 1036118824Sharti "Interface ABR traffic parameters\n" 1037118824Sharti "Index Name VPI VCI ICR TBE NRM TRM ADTF RIF RDF " 1038118824Sharti "CDF\n"; 1039118824Sharti 1040118824Sharti while ((opt = parse_options(&argc, &argv, opts)) != -1) 1041118824Sharti switch (opt) { 1042118824Sharti } 1043118824Sharti 1044118824Sharti fd = socket(PF_NATM, SOCK_STREAM, PROTO_NATMAAL5); 1045118824Sharti if (fd < 0) 1046118824Sharti err(1, "socket"); 1047118824Sharti 1048118824Sharti diagif_fetch(); 1049118824Sharti if (TAILQ_EMPTY(&diagif_list)) 1050118824Sharti errx(1, "no ATM interfaces found"); 1051118824Sharti 1052118824Sharti if (!channel && !traffic && !abr) 1053118824Sharti channel = 1; 1054118824Sharti 1055118824Sharti if (channel) 1056118824Sharti diag_vcc_loop(print_channel, head_channel, argc, argv, fd); 1057118824Sharti if (traffic) 1058118824Sharti diag_vcc_loop(print_traffic, head_traffic, argc, argv, fd); 1059118824Sharti if (abr) 1060118824Sharti diag_vcc_loop(print_abr, head_abr, argc, argv, fd); 1061118824Sharti} 1062118824Sharti 1063118824Sharti/* 1064118824Sharti * Print driver-internal statistics 1065118824Sharti */ 1066118824Shartistatic void 1067118824Shartidiag_stats(int argc, char *argv[]) 1068118824Sharti{ 1069118824Sharti int opt; 1070118824Sharti char *str; 1071118824Sharti size_t len; 1072118824Sharti uint32_t *stats; 1073118824Sharti struct diagif *aif; 1074118824Sharti u_int i; 1075118824Sharti 1076118824Sharti static const struct option opts[] = { 1077118824Sharti { NULL, 0, NULL } 1078118824Sharti }; 1079118824Sharti 1080118824Sharti while ((opt = parse_options(&argc, &argv, opts)) != -1) 1081118824Sharti switch (opt) { 1082118824Sharti } 1083118824Sharti 1084118824Sharti if (argc != 1) 1085118824Sharti errx(1, "need one arg for 'diag stats'"); 1086118824Sharti 1087118824Sharti diagif_fetch(); 1088118824Sharti TAILQ_FOREACH(aif, &diagif_list, link) 1089118824Sharti if (strcmp(aif->ifname, argv[0]) == 0) 1090118824Sharti break; 1091118824Sharti 1092118824Sharti if (aif == NULL) 1093118824Sharti errx(1, "interface '%s' not found", argv[0]); 1094118824Sharti 1095118824Sharti if (asprintf(&str, "hw.atm.%s.istats", argv[0]) == -1) 1096118824Sharti err(1, NULL); 1097118824Sharti len = 0; 1098118824Sharti if (sysctlbyname(str, NULL, &len, NULL, 0)) 1099118824Sharti err(1, "'%s' not found", str); 1100118824Sharti 1101118824Sharti stats = malloc(len); 1102118824Sharti if (stats == NULL) 1103118824Sharti err(1, NULL); 1104118824Sharti 1105118824Sharti if (sysctlbyname(str, stats, &len, NULL, 0)) 1106118824Sharti err(1, "'%s' not found", str); 1107118824Sharti free(str); 1108118824Sharti 1109118824Sharti if (aif->mib.device >= sizeof(print_stats) / sizeof(print_stats[0]) || 1110118824Sharti print_stats[aif->mib.device] == NULL) 1111118824Sharti errx(1, "unknown stats format (%u)", aif->mib.device); 1112118824Sharti 1113118824Sharti for (i = 0; print_stats[aif->mib.device][i] != NULL; i++) { 1114118824Sharti if (i * sizeof(uint32_t) >= len) 1115118824Sharti errx(1, "debug info too short (version mismatch?)"); 1116118824Sharti printf("%-22s%u\n", print_stats[aif->mib.device][i], stats[i]); 1117118824Sharti } 1118118824Sharti free(stats); 1119118824Sharti 1120118824Sharti if (i != len / sizeof(uint32_t)) 1121118824Sharti errx(1, "debug info too long (version mismatch?)"); 1122118824Sharti} 1123