diff --git a/tools/tools/mwl/mwlstats/Makefile b/tools/tools/mwl/mwlstats/Makefile index b3e22d539ddd..144ddcc87bf8 100644 --- a/tools/tools/mwl/mwlstats/Makefile +++ b/tools/tools/mwl/mwlstats/Makefile @@ -1,11 +1,13 @@ # $FreeBSD$ PROG= mwlstats BINDIR= /usr/local/bin NO_MAN= -SRCS= main.c statfoo.c mwlstats.c +SRCS= main.c mwlstats.c +USEPRIVATELIB= +LDADD=-lbsdstat .include CFLAGS+= -I. diff --git a/tools/tools/mwl/mwlstats/mwlstats.c b/tools/tools/mwl/mwlstats/mwlstats.c index de4f9349c7cf..4b6234855791 100644 --- a/tools/tools/mwl/mwlstats/mwlstats.c +++ b/tools/tools/mwl/mwlstats/mwlstats.c @@ -1,578 +1,578 @@ /*- * Copyright (c) 2007 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $FreeBSD$ */ /* * mwl statistics class. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../../../sys/net80211/ieee80211_ioctl.h" #include "../../../../sys/net80211/ieee80211_radiotap.h" /* * Get Hardware Statistics. */ struct mwl_hal_hwstats { uint32_t TxRetrySuccesses; uint32_t TxMultipleRetrySuccesses; uint32_t TxFailures; uint32_t RTSSuccesses; uint32_t RTSFailures; uint32_t AckFailures; uint32_t RxDuplicateFrames; uint32_t FCSErrorCount; uint32_t TxWatchDogTimeouts; uint32_t RxOverflows; uint32_t RxFragErrors; uint32_t RxMemErrors; uint32_t PointerErrors; uint32_t TxUnderflows; uint32_t TxDone; uint32_t TxDoneBufTryPut; uint32_t TxDoneBufPut; uint32_t Wait4TxBuf; uint32_t TxAttempts; uint32_t TxSuccesses; uint32_t TxFragments; uint32_t TxMulticasts; uint32_t RxNonCtlPkts; uint32_t RxMulticasts; uint32_t RxUndecryptableFrames; uint32_t RxICVErrors; uint32_t RxExcludedFrames; }; #include "../../../../sys/dev/mwl/if_mwlioctl.h" #include "mwlstats.h" #define AFTER(prev) ((prev)+1) static const struct fmt mwlstats[] = { #define S_INPUT 0 { 8, "input", "input", "total frames received" }, #define S_RX_MCAST AFTER(S_INPUT) { 7, "rxmcast", "rxmcast", "rx multicast frames" }, #define S_RX_NONCTL AFTER(S_RX_MCAST) { 8, "rxnonctl", "rxnonctl" "rx non control frames" }, #define S_RX_MGT AFTER(S_RX_NONCTL) { 5, "rxmgt", "rxmgt", "rx management frames" }, #define S_RX_CTL AFTER(S_RX_MGT) { 5, "rxctl", "rxctl", "rx control frames" }, #define S_OUTPUT AFTER(S_RX_CTL) { 8, "output", "output", "total frames transmit" }, #define S_TX_MCAST AFTER(S_OUTPUT) { 7, "txmcast", "txmcast", "tx multicast frames" }, #define S_TX_MGMT AFTER(S_TX_MCAST) { 5, "txmgt", "txmgt", "tx management frames" }, #define S_TX_RETRY AFTER(S_TX_MGMT) { 7, "txretry", "txretry", "tx success with 1 retry" }, #define S_TX_MRETRY AFTER(S_TX_RETRY) { 8, "txmretry", "txmretry", "tx success with >1 retry" }, #define S_TX_RTSGOOD AFTER(S_TX_MRETRY) { 7, "rtsgood", "rtsgood", "RTS tx success" }, #define S_TX_RTSBAD AFTER(S_TX_RTSGOOD) { 6, "rtsbad", "rtsbad", "RTS tx failed" }, #define S_TX_NOACK AFTER(S_TX_RTSBAD) { 5, "noack", "noack", "tx failed because no ACK was received" }, #define S_RX_DUPLICATE AFTER(S_TX_NOACK) { 5, "rxdup", "rxdup", "rx discarded by f/w as dup" }, #define S_RX_FCS AFTER(S_RX_DUPLICATE) { 5, "rxfcs", "rxfcs", "rx discarded by f/w for bad FCS" }, #define S_TX_WATCHDOG AFTER(S_RX_FCS) { 7, "txwatch", "txwatch", "MAC tx hang (f/w recovery)" }, #define S_RX_OVERFLOW AFTER(S_TX_WATCHDOG) { 6, "rxover", "rxover", "no f/w buffer for rx" }, #define S_RX_FRAGERROR AFTER(S_RX_OVERFLOW) { 6, "rxfrag", "rxfrag", "rx failed in f/w due to defrag" }, #define S_RX_MEMERROR AFTER(S_RX_FRAGERROR) { 5, "rxmem", "rxmem", "rx failed in f/w 'cuz out of of memory" }, #define S_PTRERROR AFTER(S_RX_MEMERROR) { 6, "badptr", "badptr", "MAC internal pointer problem" }, #define S_TX_UNDERFLOW AFTER(S_PTRERROR) { 7, "txunder", "txunder", "tx failed in f/w 'cuz of underflow" }, #define S_TX_DONE AFTER(S_TX_UNDERFLOW) { 6, "txdone", "txdone", "MAC tx ops completed" }, #define S_TX_DONEBUFPUT AFTER(S_TX_DONE) { 9, "txdoneput", "txdoneput", "tx buffers returned by f/w to host" }, #define S_TX_WAIT4BUF AFTER(S_TX_DONEBUFPUT) { 6, "txwait", "txwait", "no f/w buffers available when supplied a tx descriptor" }, #define S_TX_ATTEMPTS AFTER(S_TX_WAIT4BUF) { 5, "txtry", "txtry", "tx descriptors processed by f/w" }, #define S_TX_SUCCESS AFTER(S_TX_ATTEMPTS) { 4, "txok", "txok", "tx attempts successful" }, #define S_TX_FRAGS AFTER(S_TX_SUCCESS) { 6, "txfrag", "txfrag", "tx attempts with fragmentation" }, #define S_RX_UNDECRYPT AFTER(S_TX_FRAGS) { 7, "rxcrypt", "rxcrypt", "rx failed in f/w 'cuz decrypt failed" }, #define S_RX_ICVERROR AFTER(S_RX_UNDECRYPT) { 5, "rxicv", "rxicv", "rx failed in f/w 'cuz ICV check" }, #define S_RX_EXCLUDE AFTER(S_RX_ICVERROR) { 8, "rxfilter", "rxfilter", "rx frames filtered in f/w" }, #define S_TX_LINEAR AFTER(S_RX_EXCLUDE) { 5, "txlinear", "txlinear", "tx linearized to cluster" }, #define S_TX_DISCARD AFTER(S_TX_LINEAR) { 5, "txdisc", "txdisc", "tx frames discarded prior to association" }, #define S_TX_QSTOP AFTER(S_TX_DISCARD) { 5, "qstop", "qstop", "tx stopped 'cuz no xmit buffer" }, #define S_TX_ENCAP AFTER(S_TX_QSTOP) { 5, "txencode", "txencode", "tx encapsulation failed" }, #define S_TX_NOMBUF AFTER(S_TX_ENCAP) { 5, "txnombuf", "txnombuf", "tx failed 'cuz mbuf allocation failed" }, #define S_TX_SHORTPRE AFTER(S_TX_NOMBUF) { 5, "shpre", "shpre", "tx frames with short preamble" }, #define S_TX_NOHEADROOM AFTER(S_TX_SHORTPRE) { 5, "nohead", "nohead", "tx frames discarded for lack of headroom" }, #define S_TX_BADFRAMETYPE AFTER(S_TX_NOHEADROOM) { 5, "badtxtype", "badtxtype", "tx frames discarded for invalid/unknown 802.11 frame type" }, #define S_RX_CRYPTO_ERR AFTER(S_TX_BADFRAMETYPE) { 5, "crypt", "crypt", "rx failed 'cuz decryption" }, #define S_RX_NOMBUF AFTER(S_RX_CRYPTO_ERR) { 5, "rxnombuf", "rxnombuf", "rx setup failed 'cuz no mbuf" }, #define S_RX_TKIPMIC AFTER(S_RX_NOMBUF) { 5, "rxtkipmic", "rxtkipmic", "rx failed 'cuz TKIP MIC error" }, #define S_RX_NODMABUF AFTER(S_RX_TKIPMIC) { 5, "rxnodmabuf", "rxnodmabuf", "rx failed 'cuz no DMA buffer available" }, #define S_RX_DMABUFMISSING AFTER(S_RX_NODMABUF) { 5, "rxdmabufmissing", "rxdmabufmissing", "rx descriptor with no DMA buffer attached" }, #define S_TX_NODATA AFTER(S_RX_DMABUFMISSING) { 5, "txnodata", "txnodata", "tx discarded empty frame" }, #define S_TX_BUSDMA AFTER(S_TX_NODATA) { 5, "txbusdma", "txbusdma", "tx failed for dma resources" }, #define S_RX_BUSDMA AFTER(S_TX_BUSDMA) { 5, "rxbusdma", "rxbusdma", "rx setup failed for dma resources" }, #define S_AMPDU_NOSTREAM AFTER(S_RX_BUSDMA) { 5, "ampdu_nostream","ampdu_nostream","ADDBA request failed 'cuz all BA streams in use" }, #define S_AMPDU_REJECT AFTER(S_AMPDU_NOSTREAM) { 5, "ampdu_reject","ampdu_reject","ADDBA request failed 'cuz station already has one BA stream" }, #define S_ADDBA_NOSTREAM AFTER(S_AMPDU_REJECT) { 5, "addba_nostream","addba_nostream","ADDBA response processed but no BA stream present" }, #define S_TX_TSO AFTER(S_ADDBA_NOSTREAM) { 8, "txtso", "tso", "tx frames using TSO" }, #define S_TSO_BADETH AFTER(S_TX_TSO) { 5, "tsoeth", "tsoeth", "TSO failed 'cuz ether header type not IPv4" }, #define S_TSO_NOHDR AFTER(S_TSO_BADETH) { 5, "tsonohdr", "tsonohdr", "TSO failed 'cuz header not in first mbuf" }, #define S_TSO_BADSPLIT AFTER(S_TSO_NOHDR) { 5, "tsobadsplit", "tsobadsplit", "TSO failed 'cuz payload split failed" }, #define S_BAWATCHDOG AFTER(S_TSO_BADSPLIT) { 5, "bawatchdog", "bawatchdog", "BA watchdog interrupts" }, #define S_BAWATCHDOG_NOTFOUND AFTER(S_BAWATCHDOG) { 5, "bawatchdog_notfound", "bawatchdog_notfound", "BA watchdog for unknown stream" }, #define S_BAWATCHDOG_EMPTY AFTER(S_BAWATCHDOG_NOTFOUND) { 5, "bawatchdog_empty", "bawatchdog_empty", "BA watchdog on all streams but none found" }, #define S_BAWATCHDOG_FAILED AFTER(S_BAWATCHDOG_EMPTY) { 5, "bawatchdog_failed", "bawatchdog_failed", "BA watchdog processing failed to get bitmap from f/w" }, #define S_RADARDETECT AFTER(S_BAWATCHDOG_FAILED) { 5, "radardetect", "radardetect", "radar detect interrupts" }, #define S_RATE AFTER(S_RADARDETECT) { 4, "rate", "rate", "rate of last transmit" }, #define S_TX_RSSI AFTER(S_RATE) { 4, "arssi", "arssi", "rssi of last ack" }, #define S_RX_RSSI AFTER(S_TX_RSSI) { 4, "rssi", "rssi", "avg recv rssi" }, #define S_RX_NOISE AFTER(S_RX_RSSI) { 5, "noise", "noise", "rx noise floor" }, #define S_TX_SIGNAL AFTER(S_RX_NOISE) { 4, "asignal", "asig", "signal of last ack (dBm)" }, #define S_RX_SIGNAL AFTER(S_TX_SIGNAL) { 4, "signal", "sig", "avg recv signal (dBm)" }, #define S_ANT_TX0 AFTER(S_RX_SIGNAL) { 8, "tx0", "ant0(tx)", "frames tx on antenna 0" }, #define S_ANT_TX1 (S_RX_SIGNAL+2) { 8, "tx1", "ant1(tx)", "frames tx on antenna 1" }, #define S_ANT_TX2 (S_RX_SIGNAL+3) { 8, "tx2", "ant2(tx)", "frames tx on antenna 2" }, #define S_ANT_TX3 (S_RX_SIGNAL+4) { 8, "tx3", "ant3(tx)", "frames tx on antenna 3" }, #define S_ANT_RX0 AFTER(S_ANT_TX3) { 8, "rx0", "ant0(rx)", "frames rx on antenna 0" }, #define S_ANT_RX1 (S_ANT_TX3+2) { 8, "rx1", "ant1(rx)", "frames rx on antenna 1" }, #define S_ANT_RX2 (S_ANT_TX3+3) { 8, "rx2", "ant2(rx)", "frames rx on antenna 2" }, #define S_ANT_RX3 (S_ANT_TX3+4) { 8, "rx3", "ant3(rx)", "frames rx on antenna 3" }, }; /* NB: this intentionally avoids per-antenna stats */ #define S_LAST (S_RX_SIGNAL+1) struct mwlstatfoo_p { struct mwlstatfoo base; int s; struct ifreq ifr; struct mwl_stats cur; struct mwl_stats total; }; static void mwl_setifname(struct mwlstatfoo *wf0, const char *ifname) { struct mwlstatfoo_p *wf = (struct mwlstatfoo_p *) wf0; strncpy(wf->ifr.ifr_name, ifname, sizeof (wf->ifr.ifr_name)); } static void mwl_collect(struct mwlstatfoo_p *wf, struct mwl_stats *stats) { wf->ifr.ifr_data = (caddr_t) stats; if (ioctl(wf->s, SIOCGMVSTATS, &wf->ifr) < 0) err(1, wf->ifr.ifr_name); } static void -mwl_collect_cur(struct statfoo *sf) +mwl_collect_cur(struct bsdstat *sf) { struct mwlstatfoo_p *wf = (struct mwlstatfoo_p *) sf; mwl_collect(wf, &wf->cur); } static void -mwl_collect_tot(struct statfoo *sf) +mwl_collect_tot(struct bsdstat *sf) { struct mwlstatfoo_p *wf = (struct mwlstatfoo_p *) sf; mwl_collect(wf, &wf->total); } static void -mwl_update_tot(struct statfoo *sf) +mwl_update_tot(struct bsdstat *sf) { struct mwlstatfoo_p *wf = (struct mwlstatfoo_p *) sf; wf->total = wf->cur; } static void setrate(char b[], size_t bs, uint8_t rate) { if (rate & IEEE80211_RATE_MCS) snprintf(b, bs, "MCS%u", rate & IEEE80211_RATE_VAL); else if (rate & 1) snprintf(b, bs, "%u.5M", rate / 2); else snprintf(b, bs, "%uM", rate / 2); } static int -mwl_get_curstat(struct statfoo *sf, int s, char b[], size_t bs) +mwl_get_curstat(struct bsdstat *sf, int s, char b[], size_t bs) { struct mwlstatfoo_p *wf = (struct mwlstatfoo_p *) sf; #define STAT(x) \ snprintf(b, bs, "%u", wf->cur.mst_##x - wf->total.mst_##x); return 1 #define HWSTAT(x) \ snprintf(b, bs, "%u", wf->cur.hw_stats.x - wf->total.hw_stats.x); return 1 #define RXANT(x) \ snprintf(b, bs, "%u", wf->cur.mst_ant_rx[x] - wf->total.mst_ant_rx[x]); return 1 #define TXANT(x) \ snprintf(b, bs, "%u", wf->cur.mst_ant_tx[x] - wf->total.mst_ant_tx[x]); return 1 switch (s) { case S_INPUT: snprintf(b, bs, "%lu", (u_long)( (wf->cur.mst_rx_packets - wf->total.mst_rx_packets))); return 1; case S_OUTPUT: snprintf(b, bs, "%lu", (u_long)( wf->cur.mst_tx_packets - wf->total.mst_tx_packets)); return 1; case S_RATE: setrate(b, bs, wf->cur.mst_tx_rate); return 1; case S_TX_RETRY: HWSTAT(TxRetrySuccesses); case S_TX_MRETRY: HWSTAT(TxMultipleRetrySuccesses); case S_TX_RTSGOOD: HWSTAT(RTSSuccesses); case S_TX_RTSBAD: HWSTAT(RTSFailures); case S_TX_NOACK: HWSTAT(AckFailures); case S_RX_DUPLICATE: HWSTAT(RxDuplicateFrames); case S_RX_FCS: HWSTAT(FCSErrorCount); case S_TX_WATCHDOG: HWSTAT(TxWatchDogTimeouts); case S_RX_OVERFLOW: HWSTAT(RxOverflows); case S_RX_FRAGERROR: HWSTAT(RxFragErrors); case S_RX_MEMERROR: HWSTAT(RxMemErrors); case S_PTRERROR: HWSTAT(PointerErrors); case S_TX_UNDERFLOW: HWSTAT(TxUnderflows); case S_TX_DONE: HWSTAT(TxDone); case S_TX_DONEBUFPUT: HWSTAT(TxDoneBufPut); case S_TX_WAIT4BUF: HWSTAT(Wait4TxBuf); case S_TX_ATTEMPTS: HWSTAT(TxAttempts); case S_TX_SUCCESS: HWSTAT(TxSuccesses); case S_TX_FRAGS: HWSTAT(TxFragments); case S_TX_MCAST: HWSTAT(TxMulticasts); case S_RX_NONCTL: HWSTAT(RxNonCtlPkts); case S_RX_MCAST: HWSTAT(RxMulticasts); case S_RX_UNDECRYPT: HWSTAT(RxUndecryptableFrames); case S_RX_ICVERROR: HWSTAT(RxICVErrors); case S_RX_EXCLUDE: HWSTAT(RxExcludedFrames); case S_TX_MGMT: STAT(tx_mgmt); case S_TX_DISCARD: STAT(tx_discard); case S_TX_QSTOP: STAT(tx_qstop); case S_TX_ENCAP: STAT(tx_encap); case S_TX_NOMBUF: STAT(tx_nombuf); case S_TX_LINEAR: STAT(tx_linear); case S_TX_NODATA: STAT(tx_nodata); case S_TX_BUSDMA: STAT(tx_busdma); case S_TX_SHORTPRE: STAT(tx_shortpre); case S_TX_NOHEADROOM: STAT(tx_noheadroom); case S_TX_BADFRAMETYPE: STAT(tx_badframetype); case S_RX_CRYPTO_ERR: STAT(rx_crypto); case S_RX_TKIPMIC: STAT(rx_tkipmic); case S_RX_NODMABUF: STAT(rx_nodmabuf); case S_RX_DMABUFMISSING:STAT(rx_dmabufmissing); case S_RX_NOMBUF: STAT(rx_nombuf); case S_RX_BUSDMA: STAT(rx_busdma); case S_AMPDU_NOSTREAM: STAT(ampdu_nostream); case S_AMPDU_REJECT: STAT(ampdu_reject); case S_ADDBA_NOSTREAM: STAT(addba_nostream); case S_TX_TSO: STAT(tx_tso); case S_TSO_BADETH: STAT(tso_badeth); case S_TSO_NOHDR: STAT(tso_nohdr); case S_TSO_BADSPLIT: STAT(tso_badsplit); case S_BAWATCHDOG: STAT(bawatchdog); case S_BAWATCHDOG_NOTFOUND:STAT(bawatchdog_notfound); case S_BAWATCHDOG_EMPTY: STAT(bawatchdog_empty); case S_BAWATCHDOG_FAILED:STAT(bawatchdog_failed); case S_RADARDETECT: STAT(radardetect); case S_RX_RSSI: snprintf(b, bs, "%d", wf->cur.mst_rx_rssi); return 1; case S_ANT_TX0: TXANT(0); case S_ANT_TX1: TXANT(1); case S_ANT_TX2: TXANT(2); case S_ANT_TX3: TXANT(3); case S_ANT_RX0: RXANT(0); case S_ANT_RX1: RXANT(1); case S_ANT_RX2: RXANT(2); case S_ANT_RX3: RXANT(3); case S_RX_NOISE: snprintf(b, bs, "%d", wf->cur.mst_rx_noise); return 1; case S_RX_SIGNAL: snprintf(b, bs, "%d", wf->cur.mst_rx_rssi + wf->cur.mst_rx_noise); return 1; } b[0] = '\0'; return 0; #undef RXANT #undef TXANT #undef HWSTAT #undef STAT } static int -mwl_get_totstat(struct statfoo *sf, int s, char b[], size_t bs) +mwl_get_totstat(struct bsdstat *sf, int s, char b[], size_t bs) { struct mwlstatfoo_p *wf = (struct mwlstatfoo_p *) sf; #define STAT(x) \ snprintf(b, bs, "%u", wf->total.mst_##x); return 1 #define HWSTAT(x) \ snprintf(b, bs, "%u", wf->total.hw_stats.x); return 1 #define TXANT(x) \ snprintf(b, bs, "%u", wf->total.mst_ant_tx[x]); return 1 #define RXANT(x) \ snprintf(b, bs, "%u", wf->total.mst_ant_rx[x]); return 1 switch (s) { case S_INPUT: snprintf(b, bs, "%lu", (u_long)wf->total.mst_rx_packets); return 1; case S_OUTPUT: snprintf(b, bs, "%lu", (u_long) wf->total.mst_tx_packets); return 1; case S_RATE: setrate(b, bs, wf->total.mst_tx_rate); return 1; case S_TX_RETRY: HWSTAT(TxRetrySuccesses); case S_TX_MRETRY: HWSTAT(TxMultipleRetrySuccesses); case S_TX_RTSGOOD: HWSTAT(RTSSuccesses); case S_TX_RTSBAD: HWSTAT(RTSFailures); case S_TX_NOACK: HWSTAT(AckFailures); case S_RX_DUPLICATE: HWSTAT(RxDuplicateFrames); case S_RX_FCS: HWSTAT(FCSErrorCount); case S_TX_WATCHDOG: HWSTAT(TxWatchDogTimeouts); case S_RX_OVERFLOW: HWSTAT(RxOverflows); case S_RX_FRAGERROR: HWSTAT(RxFragErrors); case S_RX_MEMERROR: HWSTAT(RxMemErrors); case S_PTRERROR: HWSTAT(PointerErrors); case S_TX_UNDERFLOW: HWSTAT(TxUnderflows); case S_TX_DONE: HWSTAT(TxDone); case S_TX_DONEBUFPUT: HWSTAT(TxDoneBufPut); case S_TX_WAIT4BUF: HWSTAT(Wait4TxBuf); case S_TX_ATTEMPTS: HWSTAT(TxAttempts); case S_TX_SUCCESS: HWSTAT(TxSuccesses); case S_TX_FRAGS: HWSTAT(TxFragments); case S_TX_MCAST: HWSTAT(TxMulticasts); case S_RX_NONCTL: HWSTAT(RxNonCtlPkts); case S_RX_MCAST: HWSTAT(RxMulticasts); case S_RX_UNDECRYPT: HWSTAT(RxUndecryptableFrames); case S_RX_ICVERROR: HWSTAT(RxICVErrors); case S_RX_EXCLUDE: HWSTAT(RxExcludedFrames); case S_TX_MGMT: STAT(tx_mgmt); case S_TX_DISCARD: STAT(tx_discard); case S_TX_QSTOP: STAT(tx_qstop); case S_TX_ENCAP: STAT(tx_encap); case S_TX_NOMBUF: STAT(tx_nombuf); case S_TX_LINEAR: STAT(tx_linear); case S_TX_NODATA: STAT(tx_nodata); case S_TX_BUSDMA: STAT(tx_busdma); case S_TX_SHORTPRE: STAT(tx_shortpre); case S_TX_NOHEADROOM: STAT(tx_noheadroom); case S_TX_BADFRAMETYPE: STAT(tx_badframetype); case S_RX_CRYPTO_ERR: STAT(rx_crypto); case S_RX_TKIPMIC: STAT(rx_tkipmic); case S_RX_NODMABUF: STAT(rx_nodmabuf); case S_RX_DMABUFMISSING:STAT(rx_dmabufmissing); case S_RX_NOMBUF: STAT(rx_nombuf); case S_RX_BUSDMA: STAT(rx_busdma); case S_AMPDU_NOSTREAM: STAT(ampdu_nostream); case S_AMPDU_REJECT: STAT(ampdu_reject); case S_ADDBA_NOSTREAM: STAT(addba_nostream); case S_TX_TSO: STAT(tx_tso); case S_TSO_BADETH: STAT(tso_badeth); case S_TSO_NOHDR: STAT(tso_nohdr); case S_TSO_BADSPLIT: STAT(tso_badsplit); case S_BAWATCHDOG: STAT(bawatchdog); case S_BAWATCHDOG_NOTFOUND:STAT(bawatchdog_notfound); case S_BAWATCHDOG_EMPTY: STAT(bawatchdog_empty); case S_BAWATCHDOG_FAILED:STAT(bawatchdog_failed); case S_RADARDETECT: STAT(radardetect); case S_RX_RSSI: snprintf(b, bs, "%d", wf->total.mst_rx_rssi); return 1; case S_ANT_TX0: TXANT(0); case S_ANT_TX1: TXANT(1); case S_ANT_TX2: TXANT(2); case S_ANT_TX3: TXANT(3); case S_ANT_RX0: RXANT(0); case S_ANT_RX1: RXANT(1); case S_ANT_RX2: RXANT(2); case S_ANT_RX3: RXANT(3); case S_RX_NOISE: snprintf(b, bs, "%d", wf->total.mst_rx_noise); return 1; case S_RX_SIGNAL: snprintf(b, bs, "%d", wf->total.mst_rx_rssi + wf->total.mst_rx_noise); return 1; } b[0] = '\0'; return 0; #undef RXANT #undef TXANT #undef HWSTAT #undef STAT } static void -mwl_print_verbose(struct statfoo *sf, FILE *fd) +mwl_print_verbose(struct bsdstat *sf, FILE *fd) { struct mwlstatfoo_p *wf = (struct mwlstatfoo_p *) sf; const struct fmt *f; char s[32]; const char *indent; int i, width; width = 0; for (i = 0; i < S_LAST; i++) { f = &sf->stats[i]; if (f->width > width) width = f->width; } for (i = 0; i < S_LAST; i++) { f = &sf->stats[i]; if (mwl_get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0")) { indent = ""; fprintf(fd, "%s%-*s %s\n", indent, width, s, f->desc); } } fprintf(fd, "Antenna profile:\n"); for (i = 0; i < 4; i++) if (wf->total.mst_ant_rx[i] || wf->total.mst_ant_tx[i]) fprintf(fd, "[%u] tx %8u rx %8u\n", i, wf->total.mst_ant_tx[i], wf->total.mst_ant_rx[i]); } -STATFOO_DEFINE_BOUNCE(mwlstatfoo) +BSDSTAT_DEFINE_BOUNCE(mwlstatfoo) struct mwlstatfoo * mwlstats_new(const char *ifname, const char *fmtstring) { #define N(a) (sizeof(a) / sizeof(a[0])) struct mwlstatfoo_p *wf; wf = calloc(1, sizeof(struct mwlstatfoo_p)); if (wf != NULL) { - statfoo_init(&wf->base.base, "mwlstats", mwlstats, N(mwlstats)); + bsdstat_init(&wf->base.base, "mwlstats", mwlstats, N(mwlstats)); /* override base methods */ wf->base.base.collect_cur = mwl_collect_cur; wf->base.base.collect_tot = mwl_collect_tot; wf->base.base.get_curstat = mwl_get_curstat; wf->base.base.get_totstat = mwl_get_totstat; wf->base.base.update_tot = mwl_update_tot; wf->base.base.print_verbose = mwl_print_verbose; /* setup bounce functions for public methods */ - STATFOO_BOUNCE(wf, mwlstatfoo); + BSDSTAT_BOUNCE(wf, mwlstatfoo); /* setup our public methods */ wf->base.setifname = mwl_setifname; #if 0 wf->base.setstamac = wlan_setstamac; #endif wf->s = socket(AF_INET, SOCK_DGRAM, 0); if (wf->s < 0) err(1, "socket"); mwl_setifname(&wf->base, ifname); wf->base.setfmt(&wf->base, fmtstring); } return &wf->base; #undef N } diff --git a/tools/tools/mwl/mwlstats/mwlstats.h b/tools/tools/mwl/mwlstats/mwlstats.h index 60ff4bb49411..7d8902e5f14e 100644 --- a/tools/tools/mwl/mwlstats/mwlstats.h +++ b/tools/tools/mwl/mwlstats/mwlstats.h @@ -1,52 +1,52 @@ /*- * Copyright (c) 2007 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $FreeBSD$ */ #ifndef _MWLSTATS_H_ #define _MWLSTATS_H_ -#include "statfoo.h" +#include "bsdstat.h" /* * mv statistics class. */ struct mwlstatfoo { - struct statfoo base; + struct bsdstat base; - STATFOO_DECL_METHODS(struct mwlstatfoo *); + BSDSTAT_DECL_METHODS(struct mwlstatfoo *); /* set the network interface name for collection */ void (*setifname)(struct mwlstatfoo *, const char *ifname); /* set the mac address of the associated station/ap */ void (*setstamac)(struct mwlstatfoo *, const uint8_t mac[]); }; struct mwlstatfoo *mwlstats_new(const char *ifname, const char *fmtstring); #endif /* _MWLSTATS_H_ */ diff --git a/tools/tools/mwl/mwlstats/statfoo.c b/tools/tools/mwl/mwlstats/statfoo.c deleted file mode 100644 index 0fa0c37c8a67..000000000000 --- a/tools/tools/mwl/mwlstats/statfoo.c +++ /dev/null @@ -1,184 +0,0 @@ -/*- - * Copyright (c) 2007 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGES. - * - * $FreeBSD$ - */ - -#include -#include - -#include "statfoo.h" - -static void -statfoo_setfmt(struct statfoo *sf, const char *fmt0) -{ -#define N(a) (sizeof(a)/sizeof(a[0])) - char fmt[4096]; - char *fp, *tok; - int i, j; - - j = 0; - strlcpy(fmt, fmt0, sizeof(fmt)); - for (fp = fmt; (tok = strsep(&fp, ", ")) != NULL;) { - for (i = 0; i < sf->nstats; i++) - if (strcasecmp(tok, sf->stats[i].name) == 0) - break; - if (i >= sf->nstats) { - fprintf(stderr, "%s: unknown statistic name \"%s\" " - "skipped\n", sf->name, tok); - continue; - } - if (j+3 > sizeof(sf->fmts)) { - fprintf(stderr, "%s: not enough room for all stats; " - "stopped at %s\n", sf->name, tok); - break; - } - if (j != 0) - sf->fmts[j++] = ' '; - sf->fmts[j++] = 0x80 | i; - } - sf->fmts[j] = '\0'; -#undef N -} - -static void -statfoo_collect(struct statfoo *sf) -{ - fprintf(stderr, "%s: don't know how to collect data\n", sf->name); -} - -static void -statfoo_update_tot(struct statfoo *sf) -{ - fprintf(stderr, "%s: don't know how to update total data\n", sf->name); -} - -static int -statfoo_get(struct statfoo *sf, int s, char b[], size_t bs) -{ - fprintf(stderr, "%s: don't know how to get stat #%u\n", sf->name, s); - return 0; -} - -static void -statfoo_print_header(struct statfoo *sf, FILE *fd) -{ - const unsigned char *cp; - - for (cp = sf->fmts; *cp != '\0'; cp++) { - if (*cp & 0x80) { - const struct fmt *f = &sf->stats[*cp &~ 0x80]; - fprintf(fd, "%*s", f->width, f->label); - } else - putc(*cp, fd); - } - putc('\n', fd); -} - -static void -statfoo_print_current(struct statfoo *sf, FILE *fd) -{ - char buf[32]; - const unsigned char *cp; - - for (cp = sf->fmts; *cp != '\0'; cp++) { - if (*cp & 0x80) { - const struct fmt *f = &sf->stats[*cp &~ 0x80]; - if (sf->get_curstat(sf, *cp &~ 0x80, buf, sizeof(buf))) - fprintf(fd, "%*s", f->width, buf); - } else - putc(*cp, fd); - } - putc('\n', fd); -} - -static void -statfoo_print_total(struct statfoo *sf, FILE *fd) -{ - char buf[32]; - const unsigned char *cp; - - for (cp = sf->fmts; *cp != '\0'; cp++) { - if (*cp & 0x80) { - const struct fmt *f = &sf->stats[*cp &~ 0x80]; - if (sf->get_totstat(sf, *cp &~ 0x80, buf, sizeof(buf))) - fprintf(fd, "%*s", f->width, buf); - } else - putc(*cp, fd); - } - putc('\n', fd); -} - -static void -statfoo_print_verbose(struct statfoo *sf, FILE *fd) -{ - char s[32]; - int i; - - for (i = 0; i < sf->nstats; i++) { - if (sf->get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0")) - fprintf(fd, "%s %s\n", s, sf->stats[i].desc); - } -} - -static void -statfoo_print_fields(struct statfoo *sf, FILE *fd) -{ - int i, w, width; - - width = 0; - for (i = 0; i < sf->nstats; i++) { - w = strlen(sf->stats[i].name); - if (w > width) - width = w; - } - for (i = 0; i < sf->nstats; i++) { - const struct fmt *f = &sf->stats[i]; - if (f->width != 0) - fprintf(fd, "%-*s %s\n", width, f->name, f->desc); - } -} - -void -statfoo_init(struct statfoo *sf, const char *name, const struct fmt *stats, int nstats) -{ - sf->name = name; - sf->stats = stats; - sf->nstats = nstats; - sf->setfmt = statfoo_setfmt; - sf->collect_cur = statfoo_collect; - sf->collect_tot = statfoo_collect; - sf->update_tot = statfoo_update_tot; - sf->get_curstat = statfoo_get; - sf->get_totstat = statfoo_get; - sf->print_header = statfoo_print_header; - sf->print_current = statfoo_print_current; - sf->print_total = statfoo_print_total; - sf->print_verbose = statfoo_print_verbose; - sf->print_fields = statfoo_print_fields; -} diff --git a/tools/tools/mwl/mwlstats/statfoo.h b/tools/tools/mwl/mwlstats/statfoo.h deleted file mode 100644 index 4575946bceed..000000000000 --- a/tools/tools/mwl/mwlstats/statfoo.h +++ /dev/null @@ -1,127 +0,0 @@ -/*- - * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGES. - * - * $FreeBSD$ - */ - -#ifndef _STATFOO_H_ -#define _STATFOO_H_ -/* - * Base class for managing+displaying periodically collected statistics. - */ - -/* - * Statistic definition/description. The are defined - * for stats that correspond 1-1 w/ a collected stat - * and for stats that are calculated indirectly. - */ -struct fmt { - int width; /* printed field width */ - const char* name; /* stat field name referenced by user */ - const char* label; /* printed header label */ - const char* desc; /* verbose description */ -}; - -#define STATFOO_DECL_METHODS(_p) \ - /* set the format of the statistics to display */ \ - void (*setfmt)(_p, const char *); \ - /* collect+store ``current statistics'' */ \ - void (*collect_cur)(_p); \ - /* collect+store ``total statistics'' */ \ - void (*collect_tot)(_p); \ - /* update ``total statistics'' if necessary from current */ \ - void (*update_tot)(_p); \ - /* format a statistic from the current stats */ \ - int (*get_curstat)(_p, int, char [], size_t); \ - /* format a statistic from the total stats */ \ - int (*get_totstat)(_p, int, char [], size_t); \ - /* print field headers terminated by a \n */ \ - void (*print_header)(_p, FILE *); \ - /* print current statistics terminated by a \n */ \ - void (*print_current)(_p, FILE *); \ - /* print total statistics terminated by a \n */ \ - void (*print_total)(_p, FILE *); \ - /* print total statistics in a verbose (1 stat/line) format */ \ - void (*print_verbose)(_p, FILE *); \ - /* print available statistics */ \ - void (*print_fields)(_p, FILE *) - -/* - * Statistics base class. This class is not usable; only - * classes derived from it are useful. - */ -struct statfoo { - const char *name; /* statistics name, e.g. wlanstats */ - const struct fmt *stats; /* statistics in class */ - int nstats; /* number of stats */ - unsigned char fmts[4096]; /* private: compiled stats to display */ - - STATFOO_DECL_METHODS(struct statfoo *); -}; - -void statfoo_init(struct statfoo *, const char *name, - const struct fmt *stats, int nstats); - -#define STATFOO_DEFINE_BOUNCE(_t) \ -static void _t##_setfmt(struct _t *wf, const char *fmt0) \ - { wf->base.setfmt(&wf->base, fmt0); } \ -static void _t##_collect_cur(struct _t *wf) \ - { wf->base.collect_cur(&wf->base); } \ -static void _t##_collect_tot(struct _t *wf) \ - { wf->base.collect_tot(&wf->base); } \ -static void _t##_update_tot(struct _t *wf) \ - { wf->base.update_tot(&wf->base); } \ -static int _t##_get_curstat(struct _t *wf, int s, char b[], size_t bs) \ - { return wf->base.get_curstat(&wf->base, s, b, bs); } \ -static int _t##_get_totstat(struct _t *wf, int s, char b[], size_t bs) \ - { return wf->base.get_totstat(&wf->base, s, b, bs); } \ -static void _t##_print_header(struct _t *wf, FILE *fd) \ - { wf->base.print_header(&wf->base, fd); } \ -static void _t##_print_current(struct _t *wf, FILE *fd) \ - { wf->base.print_current(&wf->base, fd); } \ -static void _t##_print_total(struct _t *wf, FILE *fd) \ - { wf->base.print_total(&wf->base, fd); } \ -static void _t##_print_verbose(struct _t *wf, FILE *fd) \ - { wf->base.print_verbose(&wf->base, fd); } \ -static void _t##_print_fields(struct _t *wf, FILE *fd) \ - { wf->base.print_fields(&wf->base, fd); } - -#define STATFOO_BOUNCE(_p, _t) do { \ - _p->base.setfmt = _t##_setfmt; \ - _p->base.collect_cur = _t##_collect_cur; \ - _p->base.collect_tot = _t##_collect_tot; \ - _p->base.update_tot = _t##_update_tot; \ - _p->base.get_curstat = _t##_get_curstat; \ - _p->base.get_totstat = _t##_get_totstat; \ - _p->base.print_header = _t##_print_header; \ - _p->base.print_current = _t##_print_current; \ - _p->base.print_total = _t##_print_total; \ - _p->base.print_verbose = _t##_print_verbose; \ - _p->base.print_fields = _t##_print_fields; \ -} while (0) -#endif /* _STATFOO_H_ */