2 * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 * redistribution must be conditioned upon including a substantially
14 * similar Disclaimer requirement for further binary redistribution.
15 * 3. Neither the names of the above-listed copyright holders nor the names
16 * of any contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU General Public License ("GPL") version 2 as published by the Free
21 * Software Foundation.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
28 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
29 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
32 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34 * THE POSSIBILITY OF SUCH DAMAGES.
40 * ath statistics class.
42 #include <sys/types.h>
44 #include <sys/sockio.h>
45 #include <sys/socket.h>
47 #include <net/if_media.h>
48 #include <net/if_var.h>
59 #include "ieee80211_ioctl.h"
60 #include "ieee80211_radiotap.h"
61 #include "if_athioctl.h"
65 #define NOTPRESENT { 0, "", "" }
67 #define AFTER(prev) ((prev)+1)
69 static const struct fmt athstats[] = {
71 { 8, "input", "input", "data frames received" },
72 #define S_OUTPUT AFTER(S_INPUT)
73 { 8, "output", "output", "data frames transmit" },
74 #define S_TX_ALTRATE AFTER(S_OUTPUT)
75 { 7, "altrate", "altrate", "tx frames with an alternate rate" },
76 #define S_TX_SHORTRETRY AFTER(S_TX_ALTRATE)
77 { 7, "short", "short", "short on-chip tx retries" },
78 #define S_TX_LONGRETRY AFTER(S_TX_SHORTRETRY)
79 { 7, "long", "long", "long on-chip tx retries" },
80 #define S_TX_XRETRIES AFTER(S_TX_LONGRETRY)
81 { 6, "xretry", "xretry", "tx failed 'cuz too many retries" },
82 #define S_MIB AFTER(S_TX_XRETRIES)
83 { 5, "mib", "mib", "mib overflow interrupts" },
85 #define S_TX_LINEAR AFTER(S_MIB)
86 { 5, "txlinear", "txlinear", "tx linearized to cluster" },
87 #define S_BSTUCK AFTER(S_TX_LINEAR)
88 { 5, "bstuck", "bstuck", "stuck beacon conditions" },
89 #define S_INTRCOAL AFTER(S_BSTUCK)
90 { 5, "intrcoal", "intrcoal", "interrupts coalesced" },
91 #define S_RATE AFTER(S_INTRCOAL)
93 #define S_RATE AFTER(S_MIB)
95 { 4, "rate", "rate", "current transmit rate" },
96 #define S_WATCHDOG AFTER(S_RATE)
97 { 5, "wdog", "wdog", "watchdog timeouts" },
98 #define S_FATAL AFTER(S_WATCHDOG)
99 { 5, "fatal", "fatal", "hardware error interrupts" },
100 #define S_BMISS AFTER(S_FATAL)
101 { 5, "bmiss", "bmiss", "beacon miss interrupts" },
102 #define S_RXORN AFTER(S_BMISS)
103 { 5, "rxorn", "rxorn", "recv overrun interrupts" },
104 #define S_RXEOL AFTER(S_RXORN)
105 { 5, "rxeol", "rxeol", "recv eol interrupts" },
106 #define S_TXURN AFTER(S_RXEOL)
107 { 5, "txurn", "txurn", "txmit underrun interrupts" },
108 #define S_TX_MGMT AFTER(S_TXURN)
109 { 5, "txmgt", "txmgt", "tx management frames" },
110 #define S_TX_DISCARD AFTER(S_TX_MGMT)
111 { 5, "txdisc", "txdisc", "tx frames discarded prior to association" },
112 #define S_TX_INVALID AFTER(S_TX_DISCARD)
113 { 5, "txinv", "txinv", "tx invalid (19)" },
114 #define S_TX_QSTOP AFTER(S_TX_INVALID)
115 { 5, "qstop", "qstop", "tx stopped 'cuz no xmit buffer" },
116 #define S_TX_ENCAP AFTER(S_TX_QSTOP)
117 { 5, "txencode", "txencode", "tx encapsulation failed" },
118 #define S_TX_NONODE AFTER(S_TX_ENCAP)
119 { 5, "txnonode", "txnonode", "tx failed 'cuz no node" },
120 #define S_TX_NOMBUF AFTER(S_TX_NONODE)
121 { 5, "txnombuf", "txnombuf", "tx failed 'cuz mbuf allocation failed" },
123 #define S_TX_NOMCL AFTER(S_TX_NOMBUF)
124 { 5, "txnomcl", "txnomcl", "tx failed 'cuz cluster allocation failed" },
125 #define S_TX_FIFOERR AFTER(S_TX_NOMCL)
127 #define S_TX_FIFOERR AFTER(S_TX_NOMBUF)
129 { 5, "efifo", "efifo", "tx failed 'cuz FIFO underrun" },
130 #define S_TX_FILTERED AFTER(S_TX_FIFOERR)
131 { 5, "efilt", "efilt", "tx failed 'cuz destination filtered" },
132 #define S_TX_BADRATE AFTER(S_TX_FILTERED)
133 { 5, "txbadrate", "txbadrate", "tx failed 'cuz bogus xmit rate" },
134 #define S_TX_NOACK AFTER(S_TX_BADRATE)
135 { 5, "noack", "noack", "tx frames with no ack marked" },
136 #define S_TX_RTS AFTER(S_TX_NOACK)
137 { 5, "rts", "rts", "tx frames with rts enabled" },
138 #define S_TX_CTS AFTER(S_TX_RTS)
139 { 5, "cts", "cts", "tx frames with cts enabled" },
140 #define S_TX_SHORTPRE AFTER(S_TX_CTS)
141 { 5, "shpre", "shpre", "tx frames with short preamble" },
142 #define S_TX_PROTECT AFTER(S_TX_SHORTPRE)
143 { 5, "protect", "protect", "tx frames with 11g protection" },
144 #define S_RX_ORN AFTER(S_TX_PROTECT)
145 { 5, "rxorn", "rxorn", "rx failed 'cuz of desc overrun" },
146 #define S_RX_CRC_ERR AFTER(S_RX_ORN)
147 { 6, "crcerr", "crcerr", "rx failed 'cuz of bad CRC" },
148 #define S_RX_FIFO_ERR AFTER(S_RX_CRC_ERR)
149 { 5, "rxfifo", "rxfifo", "rx failed 'cuz of FIFO overrun" },
150 #define S_RX_CRYPTO_ERR AFTER(S_RX_FIFO_ERR)
151 { 5, "crypt", "crypt", "rx failed 'cuz decryption" },
152 #define S_RX_MIC_ERR AFTER(S_RX_CRYPTO_ERR)
153 { 4, "mic", "mic", "rx failed 'cuz MIC failure" },
154 #define S_RX_TOOSHORT AFTER(S_RX_MIC_ERR)
155 { 5, "rxshort", "rxshort", "rx failed 'cuz frame too short" },
156 #define S_RX_NOMBUF AFTER(S_RX_TOOSHORT)
157 { 5, "rxnombuf", "rxnombuf", "rx setup failed 'cuz no mbuf" },
158 #define S_RX_MGT AFTER(S_RX_NOMBUF)
159 { 5, "rxmgt", "rxmgt", "rx management frames" },
160 #define S_RX_CTL AFTER(S_RX_MGT)
161 { 5, "rxctl", "rxctl", "rx control frames" },
162 #define S_RX_PHY_ERR AFTER(S_RX_CTL)
163 { 7, "phyerr", "phyerr", "rx failed 'cuz of PHY err" },
164 #define S_RX_PHY_UNDERRUN AFTER(S_RX_PHY_ERR)
165 { 6, "phyund", "phyund", "transmit underrun" },
166 #define S_RX_PHY_TIMING AFTER(S_RX_PHY_UNDERRUN)
167 { 6, "phytim", "phytim", "timing error" },
168 #define S_RX_PHY_PARITY AFTER(S_RX_PHY_TIMING)
169 { 6, "phypar", "phypar", "illegal parity" },
170 #define S_RX_PHY_RATE AFTER(S_RX_PHY_PARITY)
171 { 6, "phyrate", "phyrate", "illegal rate" },
172 #define S_RX_PHY_LENGTH AFTER(S_RX_PHY_RATE)
173 { 6, "phylen", "phylen", "illegal length" },
174 #define S_RX_PHY_RADAR AFTER(S_RX_PHY_LENGTH)
175 { 6, "phyradar", "phyradar", "radar detect" },
176 #define S_RX_PHY_SERVICE AFTER(S_RX_PHY_RADAR)
177 { 6, "physervice", "physervice", "illegal service" },
178 #define S_RX_PHY_TOR AFTER(S_RX_PHY_SERVICE)
179 { 6, "phytor", "phytor", "transmit override receive" },
180 #define S_RX_PHY_OFDM_TIMING AFTER(S_RX_PHY_TOR)
181 { 6, "ofdmtim", "ofdmtim", "OFDM timing" },
182 #define S_RX_PHY_OFDM_SIGNAL_PARITY AFTER(S_RX_PHY_OFDM_TIMING)
183 { 6, "ofdmsig", "ofdmsig", "OFDM illegal parity" },
184 #define S_RX_PHY_OFDM_RATE_ILLEGAL AFTER(S_RX_PHY_OFDM_SIGNAL_PARITY)
185 { 6, "ofdmrate", "ofdmrate", "OFDM illegal rate" },
186 #define S_RX_PHY_OFDM_POWER_DROP AFTER(S_RX_PHY_OFDM_RATE_ILLEGAL)
187 { 6, "ofdmpow", "ofdmpow", "OFDM power drop" },
188 #define S_RX_PHY_OFDM_SERVICE AFTER(S_RX_PHY_OFDM_POWER_DROP)
189 { 6, "ofdmservice", "ofdmservice", "OFDM illegal service" },
190 #define S_RX_PHY_OFDM_RESTART AFTER(S_RX_PHY_OFDM_SERVICE)
191 { 6, "ofdmrestart", "ofdmrestart", "OFDM restart" },
192 #define S_RX_PHY_CCK_TIMING AFTER(S_RX_PHY_OFDM_RESTART)
193 { 6, "ccktim", "ccktim", "CCK timing" },
194 #define S_RX_PHY_CCK_HEADER_CRC AFTER(S_RX_PHY_CCK_TIMING)
195 { 6, "cckhead", "cckhead", "CCK header crc" },
196 #define S_RX_PHY_CCK_RATE_ILLEGAL AFTER(S_RX_PHY_CCK_HEADER_CRC)
197 { 6, "cckrate", "cckrate", "CCK illegal rate" },
198 #define S_RX_PHY_CCK_SERVICE AFTER(S_RX_PHY_CCK_RATE_ILLEGAL)
199 { 6, "cckservice", "cckservice", "CCK illegal service" },
200 #define S_RX_PHY_CCK_RESTART AFTER(S_RX_PHY_CCK_SERVICE)
201 { 6, "cckrestar", "cckrestar", "CCK restart" },
202 #define S_BE_NOMBUF AFTER(S_RX_PHY_CCK_RESTART)
203 { 4, "benombuf", "benombuf", "beacon setup failed 'cuz no mbuf" },
204 #define S_BE_XMIT AFTER(S_BE_NOMBUF)
205 { 7, "bexmit", "bexmit", "beacons transmitted" },
206 #define S_PER_CAL AFTER(S_BE_XMIT)
207 { 4, "pcal", "pcal", "periodic calibrations" },
208 #define S_PER_CALFAIL AFTER(S_PER_CAL)
209 { 4, "pcalf", "pcalf", "periodic calibration failures" },
210 #define S_PER_RFGAIN AFTER(S_PER_CALFAIL)
211 { 4, "prfga", "prfga", "rfgain value change" },
213 #define S_TDMA_UPDATE AFTER(S_PER_RFGAIN)
214 { 5, "tdmau", "tdmau", "TDMA slot timing updates" },
215 #define S_TDMA_TIMERS AFTER(S_TDMA_UPDATE)
216 { 5, "tdmab", "tdmab", "TDMA slot update set beacon timers" },
217 #define S_TDMA_TSF AFTER(S_TDMA_TIMERS)
218 { 5, "tdmat", "tdmat", "TDMA slot update set TSF" },
219 #define S_RATE_CALLS AFTER(S_TDMA_TSF)
221 #define S_RATE_CALLS AFTER(S_PER_RFGAIN)
223 { 5, "ratec", "ratec", "rate control checks" },
224 #define S_RATE_RAISE AFTER(S_RATE_CALLS)
225 { 5, "rate+", "rate+", "rate control raised xmit rate" },
226 #define S_RATE_DROP AFTER(S_RATE_RAISE)
227 { 5, "rate-", "rate-", "rate control dropped xmit rate" },
228 #define S_TX_RSSI AFTER(S_RATE_DROP)
229 { 4, "arssi", "arssi", "rssi of last ack" },
230 #define S_RX_RSSI AFTER(S_TX_RSSI)
231 { 4, "rssi", "rssi", "avg recv rssi" },
232 #define S_RX_NOISE AFTER(S_RX_RSSI)
233 { 5, "noise", "noise", "rx noise floor" },
234 #define S_BMISS_PHANTOM AFTER(S_RX_NOISE)
235 { 5, "bmissphantom", "bmissphantom", "phantom beacon misses" },
236 #define S_TX_RAW AFTER(S_BMISS_PHANTOM)
237 { 5, "txraw", "txraw", "tx frames through raw api" },
238 #define S_RX_TOOBIG AFTER(S_TX_RAW)
239 { 5, "rx2big", "rx2big", "rx failed 'cuz frame too large" },
241 #define S_CABQ_XMIT AFTER(S_RX_TOOBIG)
242 { 5, "cabxmit", "cabxmit", "cabq frames transmitted" },
243 #define S_CABQ_BUSY AFTER(S_CABQ_XMIT)
244 { 5, "cabqbusy", "cabqbusy", "cabq xmit overflowed beacon interval" },
245 #define S_TX_NODATA AFTER(S_CABQ_BUSY)
246 { 5, "txnodata", "txnodata", "tx discarded empty frame" },
247 #define S_TX_BUSDMA AFTER(S_TX_NODATA)
248 { 5, "txbusdma", "txbusdma", "tx failed for dma resrcs" },
249 #define S_RX_BUSDMA AFTER(S_TX_BUSDMA)
250 { 5, "rxbusdma", "rxbusdma", "rx setup failed for dma resrcs" },
251 #define S_FF_TXOK AFTER(S_RX_BUSDMA)
253 #define S_FF_TXOK AFTER(S_RX_PHY_UNDERRUN)
255 { 5, "fftxok", "fftxok", "fast frames xmit successfully" },
256 #define S_FF_TXERR AFTER(S_FF_TXOK)
257 { 5, "fftxerr", "fftxerr", "fast frames not xmit due to error" },
258 #define S_FF_RX AFTER(S_FF_TXERR)
259 { 5, "ffrx", "ffrx", "fast frames received" },
260 #define S_FF_FLUSH AFTER(S_FF_RX)
261 { 5, "ffflush", "ffflush", "fast frames flushed from staging q" },
262 #define S_TX_QFULL AFTER(S_FF_FLUSH)
263 { 5, "txqfull", "txqfull", "tx discarded 'cuz queue is full" },
264 #define S_ANT_DEFSWITCH AFTER(S_TX_QFULL)
265 { 5, "defsw", "defsw", "switched default/rx antenna" },
266 #define S_ANT_TXSWITCH AFTER(S_ANT_DEFSWITCH)
267 { 5, "txsw", "txsw", "tx used alternate antenna" },
268 #define S_ANT_TX0 AFTER(S_ANT_TXSWITCH)
269 { 8, "tx0", "ant0(tx)", "frames tx on antenna 0" },
270 #define S_ANT_TX1 AFTER(S_ANT_TX0)
271 { 8, "tx1", "ant1(tx)", "frames tx on antenna 1" },
272 #define S_ANT_TX2 AFTER(S_ANT_TX1)
273 { 8, "tx2", "ant2(tx)", "frames tx on antenna 2" },
274 #define S_ANT_TX3 AFTER(S_ANT_TX2)
275 { 8, "tx3", "ant3(tx)", "frames tx on antenna 3" },
276 #define S_ANT_TX4 AFTER(S_ANT_TX3)
277 { 8, "tx4", "ant4(tx)", "frames tx on antenna 4" },
278 #define S_ANT_TX5 AFTER(S_ANT_TX4)
279 { 8, "tx5", "ant5(tx)", "frames tx on antenna 5" },
280 #define S_ANT_TX6 AFTER(S_ANT_TX5)
281 { 8, "tx6", "ant6(tx)", "frames tx on antenna 6" },
282 #define S_ANT_TX7 AFTER(S_ANT_TX6)
283 { 8, "tx7", "ant7(tx)", "frames tx on antenna 7" },
284 #define S_ANT_RX0 AFTER(S_ANT_TX7)
285 { 8, "rx0", "ant0(rx)", "frames rx on antenna 0" },
286 #define S_ANT_RX1 AFTER(S_ANT_RX0)
287 { 8, "rx1", "ant1(rx)", "frames rx on antenna 1" },
288 #define S_ANT_RX2 AFTER(S_ANT_RX1)
289 { 8, "rx2", "ant2(rx)", "frames rx on antenna 2" },
290 #define S_ANT_RX3 AFTER(S_ANT_RX2)
291 { 8, "rx3", "ant3(rx)", "frames rx on antenna 3" },
292 #define S_ANT_RX4 AFTER(S_ANT_RX3)
293 { 8, "rx4", "ant4(rx)", "frames rx on antenna 4" },
294 #define S_ANT_RX5 AFTER(S_ANT_RX4)
295 { 8, "rx5", "ant5(rx)", "frames rx on antenna 5" },
296 #define S_ANT_RX6 AFTER(S_ANT_RX5)
297 { 8, "rx6", "ant6(rx)", "frames rx on antenna 6" },
298 #define S_ANT_RX7 AFTER(S_ANT_RX6)
299 { 8, "rx7", "ant7(rx)", "frames rx on antenna 7" },
300 #define S_TX_SIGNAL AFTER(S_ANT_RX7)
301 { 4, "asignal", "asig", "signal of last ack (dBm)" },
302 #define S_RX_SIGNAL AFTER(S_TX_SIGNAL)
303 { 4, "signal", "sig", "avg recv signal (dBm)" },
305 #define S_PHY_MIN S_RX_PHY_UNDERRUN
306 #define S_PHY_MAX S_RX_PHY_CCK_RESTART
307 #define S_LAST S_ANT_TX0
308 #define S_MAX S_ANT_RX7+1
311 struct ath_stats ath;
314 struct athstatfoo_p {
315 struct athstatfoo base;
320 struct _athstats cur;
321 struct _athstats total;
325 ath_setifname(struct athstatfoo *wf0, const char *ifname)
327 struct athstatfoo_p *wf = (struct athstatfoo_p *) wf0;
329 strncpy(wf->ifr.ifr_name, ifname, sizeof (wf->ifr.ifr_name));
333 ath_collect(struct athstatfoo_p *wf, struct _athstats *stats)
335 wf->ifr.ifr_data = (caddr_t) &stats->ath;
336 if (ioctl(wf->s, SIOCGATHSTATS, &wf->ifr) < 0)
337 err(1, wf->ifr.ifr_name);
341 ath_collect_cur(struct statfoo *sf)
343 struct athstatfoo_p *wf = (struct athstatfoo_p *) sf;
345 ath_collect(wf, &wf->cur);
349 ath_collect_tot(struct statfoo *sf)
351 struct athstatfoo_p *wf = (struct athstatfoo_p *) sf;
353 ath_collect(wf, &wf->total);
357 ath_update_tot(struct statfoo *sf)
359 struct athstatfoo_p *wf = (struct athstatfoo_p *) sf;
365 ath_get_curstat(struct statfoo *sf, int s, char b[], size_t bs)
367 struct athstatfoo_p *wf = (struct athstatfoo_p *) sf;
369 snprintf(b, bs, "%u", wf->cur.ath.ast_##x - wf->total.ath.ast_##x); return 1
371 snprintf(b, bs, "%u", wf->cur.ath.ast_rx_phy[x] - wf->total.ath.ast_rx_phy[x]); return 1
373 snprintf(b, bs, "%u", wf->cur.ath.ast_ant_tx[x] - wf->total.ath.ast_ant_tx[x]); return 1
375 snprintf(b, bs, "%u", wf->cur.ath.ast_ant_rx[x] - wf->total.ath.ast_ant_rx[x]); return 1
379 snprintf(b, bs, "%lu",
380 (wf->cur.ath.ast_rx_packets - wf->total.ath.ast_rx_packets) -
381 (wf->cur.ath.ast_rx_mgt - wf->total.ath.ast_rx_mgt));
384 snprintf(b, bs, "%lu",
385 wf->cur.ath.ast_tx_packets - wf->total.ath.ast_tx_packets);
388 snprintf(b, bs, "%uM", wf->cur.ath.ast_tx_rate / 2);
390 case S_WATCHDOG: STAT(watchdog);
391 case S_FATAL: STAT(hardware);
392 case S_BMISS: STAT(bmiss);
393 case S_BMISS_PHANTOM: STAT(bmiss_phantom);
395 case S_BSTUCK: STAT(bstuck);
397 case S_RXORN: STAT(rxorn);
398 case S_RXEOL: STAT(rxeol);
399 case S_TXURN: STAT(txurn);
400 case S_MIB: STAT(mib);
402 case S_INTRCOAL: STAT(intrcoal);
404 case S_TX_MGMT: STAT(tx_mgmt);
405 case S_TX_DISCARD: STAT(tx_discard);
406 case S_TX_QSTOP: STAT(tx_qstop);
407 case S_TX_ENCAP: STAT(tx_encap);
408 case S_TX_NONODE: STAT(tx_nonode);
409 case S_TX_NOMBUF: STAT(tx_nombuf);
411 case S_TX_NOMCL: STAT(tx_nomcl);
412 case S_TX_LINEAR: STAT(tx_linear);
413 case S_TX_NODATA: STAT(tx_nodata);
414 case S_TX_BUSDMA: STAT(tx_busdma);
416 case S_TX_XRETRIES: STAT(tx_xretries);
417 case S_TX_FIFOERR: STAT(tx_fifoerr);
418 case S_TX_FILTERED: STAT(tx_filtered);
419 case S_TX_SHORTRETRY: STAT(tx_shortretry);
420 case S_TX_LONGRETRY: STAT(tx_longretry);
421 case S_TX_BADRATE: STAT(tx_badrate);
422 case S_TX_NOACK: STAT(tx_noack);
423 case S_TX_RTS: STAT(tx_rts);
424 case S_TX_CTS: STAT(tx_cts);
425 case S_TX_SHORTPRE: STAT(tx_shortpre);
426 case S_TX_ALTRATE: STAT(tx_altrate);
427 case S_TX_PROTECT: STAT(tx_protect);
428 case S_RX_NOMBUF: STAT(rx_nombuf);
430 case S_RX_BUSDMA: STAT(rx_busdma);
432 case S_RX_ORN: STAT(rx_orn);
433 case S_RX_CRC_ERR: STAT(rx_crcerr);
434 case S_RX_FIFO_ERR: STAT(rx_fifoerr);
435 case S_RX_CRYPTO_ERR: STAT(rx_badcrypt);
436 case S_RX_MIC_ERR: STAT(rx_badmic);
437 case S_RX_PHY_ERR: STAT(rx_phyerr);
438 case S_RX_PHY_UNDERRUN: PHY(HAL_PHYERR_UNDERRUN);
439 case S_RX_PHY_TIMING: PHY(HAL_PHYERR_TIMING);
440 case S_RX_PHY_PARITY: PHY(HAL_PHYERR_PARITY);
441 case S_RX_PHY_RATE: PHY(HAL_PHYERR_RATE);
442 case S_RX_PHY_LENGTH: PHY(HAL_PHYERR_LENGTH);
443 case S_RX_PHY_RADAR: PHY(HAL_PHYERR_RADAR);
444 case S_RX_PHY_SERVICE: PHY(HAL_PHYERR_SERVICE);
445 case S_RX_PHY_TOR: PHY(HAL_PHYERR_TOR);
446 case S_RX_PHY_OFDM_TIMING: PHY(HAL_PHYERR_OFDM_TIMING);
447 case S_RX_PHY_OFDM_SIGNAL_PARITY: PHY(HAL_PHYERR_OFDM_SIGNAL_PARITY);
448 case S_RX_PHY_OFDM_RATE_ILLEGAL: PHY(HAL_PHYERR_OFDM_RATE_ILLEGAL);
449 case S_RX_PHY_OFDM_POWER_DROP: PHY(HAL_PHYERR_OFDM_POWER_DROP);
450 case S_RX_PHY_OFDM_SERVICE: PHY(HAL_PHYERR_OFDM_SERVICE);
451 case S_RX_PHY_OFDM_RESTART: PHY(HAL_PHYERR_OFDM_RESTART);
452 case S_RX_PHY_CCK_TIMING: PHY(HAL_PHYERR_CCK_TIMING);
453 case S_RX_PHY_CCK_HEADER_CRC: PHY(HAL_PHYERR_CCK_HEADER_CRC);
454 case S_RX_PHY_CCK_RATE_ILLEGAL: PHY(HAL_PHYERR_CCK_RATE_ILLEGAL);
455 case S_RX_PHY_CCK_SERVICE: PHY(HAL_PHYERR_CCK_SERVICE);
456 case S_RX_PHY_CCK_RESTART: PHY(HAL_PHYERR_CCK_RESTART);
457 case S_RX_TOOSHORT: STAT(rx_tooshort);
458 case S_RX_TOOBIG: STAT(rx_toobig);
459 case S_RX_MGT: STAT(rx_mgt);
460 case S_RX_CTL: STAT(rx_ctl);
462 snprintf(b, bs, "%d", wf->cur.ath.ast_tx_rssi);
465 snprintf(b, bs, "%d", wf->cur.ath.ast_rx_rssi);
467 case S_BE_XMIT: STAT(be_xmit);
468 case S_BE_NOMBUF: STAT(be_nombuf);
469 case S_PER_CAL: STAT(per_cal);
470 case S_PER_CALFAIL: STAT(per_calfail);
471 case S_PER_RFGAIN: STAT(per_rfgain);
473 case S_TDMA_UPDATE: STAT(tdma_update);
474 case S_TDMA_TIMERS: STAT(tdma_timers);
475 case S_TDMA_TSF: STAT(tdma_tsf);
477 case S_RATE_CALLS: STAT(rate_calls);
478 case S_RATE_RAISE: STAT(rate_raise);
479 case S_RATE_DROP: STAT(rate_drop);
480 case S_ANT_DEFSWITCH: STAT(ant_defswitch);
481 case S_ANT_TXSWITCH: STAT(ant_txswitch);
482 case S_ANT_TX0: TXANT(0);
483 case S_ANT_TX1: TXANT(1);
484 case S_ANT_TX2: TXANT(2);
485 case S_ANT_TX3: TXANT(3);
486 case S_ANT_TX4: TXANT(4);
487 case S_ANT_TX5: TXANT(5);
488 case S_ANT_TX6: TXANT(6);
489 case S_ANT_TX7: TXANT(7);
490 case S_ANT_RX0: RXANT(0);
491 case S_ANT_RX1: RXANT(1);
492 case S_ANT_RX2: RXANT(2);
493 case S_ANT_RX3: RXANT(3);
494 case S_ANT_RX4: RXANT(4);
495 case S_ANT_RX5: RXANT(5);
496 case S_ANT_RX6: RXANT(6);
497 case S_ANT_RX7: RXANT(7);
499 case S_CABQ_XMIT: STAT(cabq_xmit);
500 case S_CABQ_BUSY: STAT(cabq_busy);
502 case S_FF_TXOK: STAT(ff_txok);
503 case S_FF_TXERR: STAT(ff_txerr);
504 case S_FF_RX: STAT(ff_rx);
505 case S_FF_FLUSH: STAT(ff_flush);
506 case S_TX_QFULL: STAT(tx_qfull);
508 snprintf(b, bs, "%d", wf->cur.ath.ast_rx_noise);
511 snprintf(b, bs, "%d",
512 wf->cur.ath.ast_tx_rssi + wf->cur.ath.ast_rx_noise);
515 snprintf(b, bs, "%d",
516 wf->cur.ath.ast_rx_rssi + wf->cur.ath.ast_rx_noise);
528 ath_get_totstat(struct statfoo *sf, int s, char b[], size_t bs)
530 struct athstatfoo_p *wf = (struct athstatfoo_p *) sf;
532 snprintf(b, bs, "%u", wf->total.ath.ast_##x); return 1
534 snprintf(b, bs, "%u", wf->total.ath.ast_rx_phy[x]); return 1
536 snprintf(b, bs, "%u", wf->total.ath.ast_ant_tx[x]); return 1
538 snprintf(b, bs, "%u", wf->total.ath.ast_ant_rx[x]); return 1
542 snprintf(b, bs, "%lu",
543 wf->total.ath.ast_rx_packets - wf->total.ath.ast_rx_mgt);
546 snprintf(b, bs, "%lu", wf->total.ath.ast_tx_packets);
549 snprintf(b, bs, "%uM", wf->total.ath.ast_tx_rate / 2);
551 case S_WATCHDOG: STAT(watchdog);
552 case S_FATAL: STAT(hardware);
553 case S_BMISS: STAT(bmiss);
554 case S_BMISS_PHANTOM: STAT(bmiss_phantom);
556 case S_BSTUCK: STAT(bstuck);
558 case S_RXORN: STAT(rxorn);
559 case S_RXEOL: STAT(rxeol);
560 case S_TXURN: STAT(txurn);
561 case S_MIB: STAT(mib);
563 case S_INTRCOAL: STAT(intrcoal);
565 case S_TX_MGMT: STAT(tx_mgmt);
566 case S_TX_DISCARD: STAT(tx_discard);
567 case S_TX_QSTOP: STAT(tx_qstop);
568 case S_TX_ENCAP: STAT(tx_encap);
569 case S_TX_NONODE: STAT(tx_nonode);
570 case S_TX_NOMBUF: STAT(tx_nombuf);
572 case S_TX_NOMCL: STAT(tx_nomcl);
573 case S_TX_LINEAR: STAT(tx_linear);
574 case S_TX_NODATA: STAT(tx_nodata);
575 case S_TX_BUSDMA: STAT(tx_busdma);
577 case S_TX_XRETRIES: STAT(tx_xretries);
578 case S_TX_FIFOERR: STAT(tx_fifoerr);
579 case S_TX_FILTERED: STAT(tx_filtered);
580 case S_TX_SHORTRETRY: STAT(tx_shortretry);
581 case S_TX_LONGRETRY: STAT(tx_longretry);
582 case S_TX_BADRATE: STAT(tx_badrate);
583 case S_TX_NOACK: STAT(tx_noack);
584 case S_TX_RTS: STAT(tx_rts);
585 case S_TX_CTS: STAT(tx_cts);
586 case S_TX_SHORTPRE: STAT(tx_shortpre);
587 case S_TX_ALTRATE: STAT(tx_altrate);
588 case S_TX_PROTECT: STAT(tx_protect);
589 case S_RX_NOMBUF: STAT(rx_nombuf);
591 case S_RX_BUSDMA: STAT(rx_busdma);
593 case S_RX_ORN: STAT(rx_orn);
594 case S_RX_CRC_ERR: STAT(rx_crcerr);
595 case S_RX_FIFO_ERR: STAT(rx_fifoerr);
596 case S_RX_CRYPTO_ERR: STAT(rx_badcrypt);
597 case S_RX_MIC_ERR: STAT(rx_badmic);
598 case S_RX_PHY_ERR: STAT(rx_phyerr);
599 case S_RX_PHY_UNDERRUN: PHY(HAL_PHYERR_UNDERRUN);
600 case S_RX_PHY_TIMING: PHY(HAL_PHYERR_TIMING);
601 case S_RX_PHY_PARITY: PHY(HAL_PHYERR_PARITY);
602 case S_RX_PHY_RATE: PHY(HAL_PHYERR_RATE);
603 case S_RX_PHY_LENGTH: PHY(HAL_PHYERR_LENGTH);
604 case S_RX_PHY_RADAR: PHY(HAL_PHYERR_RADAR);
605 case S_RX_PHY_SERVICE: PHY(HAL_PHYERR_SERVICE);
606 case S_RX_PHY_TOR: PHY(HAL_PHYERR_TOR);
607 case S_RX_PHY_OFDM_TIMING: PHY(HAL_PHYERR_OFDM_TIMING);
608 case S_RX_PHY_OFDM_SIGNAL_PARITY: PHY(HAL_PHYERR_OFDM_SIGNAL_PARITY);
609 case S_RX_PHY_OFDM_RATE_ILLEGAL: PHY(HAL_PHYERR_OFDM_RATE_ILLEGAL);
610 case S_RX_PHY_OFDM_POWER_DROP: PHY(HAL_PHYERR_OFDM_POWER_DROP);
611 case S_RX_PHY_OFDM_SERVICE: PHY(HAL_PHYERR_OFDM_SERVICE);
612 case S_RX_PHY_OFDM_RESTART: PHY(HAL_PHYERR_OFDM_RESTART);
613 case S_RX_PHY_CCK_TIMING: PHY(HAL_PHYERR_CCK_TIMING);
614 case S_RX_PHY_CCK_HEADER_CRC: PHY(HAL_PHYERR_CCK_HEADER_CRC);
615 case S_RX_PHY_CCK_RATE_ILLEGAL: PHY(HAL_PHYERR_CCK_RATE_ILLEGAL);
616 case S_RX_PHY_CCK_SERVICE: PHY(HAL_PHYERR_CCK_SERVICE);
617 case S_RX_PHY_CCK_RESTART: PHY(HAL_PHYERR_CCK_RESTART);
618 case S_RX_TOOSHORT: STAT(rx_tooshort);
619 case S_RX_TOOBIG: STAT(rx_toobig);
620 case S_RX_MGT: STAT(rx_mgt);
621 case S_RX_CTL: STAT(rx_ctl);
623 snprintf(b, bs, "%d", wf->total.ath.ast_tx_rssi);
626 snprintf(b, bs, "%d", wf->total.ath.ast_rx_rssi);
628 case S_BE_XMIT: STAT(be_xmit);
629 case S_BE_NOMBUF: STAT(be_nombuf);
630 case S_PER_CAL: STAT(per_cal);
631 case S_PER_CALFAIL: STAT(per_calfail);
632 case S_PER_RFGAIN: STAT(per_rfgain);
634 case S_TDMA_UPDATE: STAT(tdma_update);
635 case S_TDMA_TIMERS: STAT(tdma_timers);
636 case S_TDMA_TSF: STAT(tdma_tsf);
638 case S_RATE_CALLS: STAT(rate_calls);
639 case S_RATE_RAISE: STAT(rate_raise);
640 case S_RATE_DROP: STAT(rate_drop);
641 case S_ANT_DEFSWITCH: STAT(ant_defswitch);
642 case S_ANT_TXSWITCH: STAT(ant_txswitch);
643 case S_ANT_TX0: TXANT(0);
644 case S_ANT_TX1: TXANT(1);
645 case S_ANT_TX2: TXANT(2);
646 case S_ANT_TX3: TXANT(3);
647 case S_ANT_TX4: TXANT(4);
648 case S_ANT_TX5: TXANT(5);
649 case S_ANT_TX6: TXANT(6);
650 case S_ANT_TX7: TXANT(7);
651 case S_ANT_RX0: RXANT(0);
652 case S_ANT_RX1: RXANT(1);
653 case S_ANT_RX2: RXANT(2);
654 case S_ANT_RX3: RXANT(3);
655 case S_ANT_RX4: RXANT(4);
656 case S_ANT_RX5: RXANT(5);
657 case S_ANT_RX6: RXANT(6);
658 case S_ANT_RX7: RXANT(7);
660 case S_CABQ_XMIT: STAT(cabq_xmit);
661 case S_CABQ_BUSY: STAT(cabq_busy);
663 case S_FF_TXOK: STAT(ff_txok);
664 case S_FF_TXERR: STAT(ff_txerr);
665 case S_FF_RX: STAT(ff_rx);
666 case S_FF_FLUSH: STAT(ff_flush);
667 case S_TX_QFULL: STAT(tx_qfull);
669 snprintf(b, bs, "%d", wf->total.ath.ast_rx_noise);
672 snprintf(b, bs, "%d",
673 wf->total.ath.ast_tx_rssi + wf->total.ath.ast_rx_noise);
676 snprintf(b, bs, "%d",
677 wf->total.ath.ast_rx_rssi + wf->total.ath.ast_rx_noise);
689 ath_print_verbose(struct statfoo *sf, FILE *fd)
691 struct athstatfoo_p *wf = (struct athstatfoo_p *) sf;
692 #define isphyerr(i) (S_PHY_MIN <= i && i <= S_PHY_MAX)
699 for (i = 0; i < S_LAST; i++) {
701 if (!isphyerr(i) && f->width > width)
704 for (i = 0; i < S_LAST; i++) {
705 if (ath_get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0")) {
710 fprintf(fd, "%s%-*s %s\n", indent, width, s, athstats[i].desc);
713 fprintf(fd, "Antenna profile:\n");
714 for (i = 0; i < 8; i++)
715 if (wf->total.ath.ast_ant_rx[i] || wf->total.ath.ast_ant_tx[i])
716 fprintf(fd, "[%u] tx %8u rx %8u\n", i,
717 wf->total.ath.ast_ant_tx[i],
718 wf->total.ath.ast_ant_rx[i]);
722 STATFOO_DEFINE_BOUNCE(athstatfoo)
725 athstats_new(const char *ifname, const char *fmtstring)
727 #define N(a) (sizeof(a) / sizeof(a[0]))
728 struct athstatfoo_p *wf;
730 wf = calloc(1, sizeof(struct athstatfoo_p));
732 statfoo_init(&wf->base.base, "athstats", athstats, N(athstats));
733 /* override base methods */
734 wf->base.base.collect_cur = ath_collect_cur;
735 wf->base.base.collect_tot = ath_collect_tot;
736 wf->base.base.get_curstat = ath_get_curstat;
737 wf->base.base.get_totstat = ath_get_totstat;
738 wf->base.base.update_tot = ath_update_tot;
739 wf->base.base.print_verbose = ath_print_verbose;
741 /* setup bounce functions for public methods */
742 STATFOO_BOUNCE(wf, athstatfoo);
744 /* setup our public methods */
745 wf->base.setifname = ath_setifname;
747 wf->base.setstamac = wlan_setstamac;
749 wf->s = socket(AF_INET, SOCK_DGRAM, 0);
753 ath_setifname(&wf->base, ifname);
754 wf->base.setfmt(&wf->base, fmtstring);