1 /*
2 * Copyright (c) 2012 Adrian Chadd <adrian@FreeBSD.org>
3 * All Rights Reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17 #include <sys/cdefs.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <errno.h>
23 #include <string.h>
24
25 #include <sys/types.h>
26 #include <sys/alq.h>
27 #include <sys/endian.h>
28
29 #include <dev/ath/if_ath_alq.h>
30
31 #if 1
32 #include "ar9300_ds.h"
33 #endif
34 #include "ar5210_ds.h"
35 #include "ar5211_ds.h"
36 #include "ar5212_ds.h"
37 #include "ar5416_ds.h"
38
39 #include "tdma.h"
40
41 #define AR5210_MAGIC 0x19980124
42 #define AR5211_MAGIC 0x19570405
43 #define AR5212_MAGIC 0x19541014
44 #define AR5416_MAGIC 0x20065416
45 #define AR9300_MAGIC 0x19741014
46
47 #define READBUF_SIZE 1024
48
49 struct if_ath_alq_init_state hdr;
50
51 static void
ath_alq_print_hdr(struct if_ath_alq_init_state * hdr)52 ath_alq_print_hdr(struct if_ath_alq_init_state *hdr)
53 {
54 printf("macVersion=%d.%d, PHY=%d, Magic=%08x\n",
55 be32toh(hdr->sc_mac_version),
56 be32toh(hdr->sc_mac_revision),
57 be32toh(hdr->sc_phy_rev),
58 be32toh(hdr->sc_hal_magic));
59 }
60
61 static void
ath_alq_print_intr_status(struct if_ath_alq_payload * a)62 ath_alq_print_intr_status(struct if_ath_alq_payload *a)
63 {
64 struct if_ath_alq_interrupt is;
65
66 /* XXX len check! */
67 memcpy(&is, &a->payload, sizeof(is));
68
69 printf("[%u.%06u] [%llu] INTR: status=0x%08x\n",
70 (unsigned int) be32toh(a->hdr.tstamp_sec),
71 (unsigned int) be32toh(a->hdr.tstamp_usec),
72 (unsigned long long) be64toh(a->hdr.threadid),
73 be32toh(is.intr_status));
74 }
75
76 static void
ath_alq_print_beacon_miss(struct if_ath_alq_payload * a)77 ath_alq_print_beacon_miss(struct if_ath_alq_payload *a)
78 {
79
80 printf("[%u.%06u] [%llu] BMISS\n",
81 (unsigned int) be32toh(a->hdr.tstamp_sec),
82 (unsigned int) be32toh(a->hdr.tstamp_usec),
83 (unsigned long long) be64toh(a->hdr.threadid));
84 }
85
86 static void
ath_alq_print_beacon_stuck(struct if_ath_alq_payload * a)87 ath_alq_print_beacon_stuck(struct if_ath_alq_payload *a)
88 {
89
90 printf("[%u.%06u] [%llu] BSTUCK\n",
91 (unsigned int) be32toh(a->hdr.tstamp_sec),
92 (unsigned int) be32toh(a->hdr.tstamp_usec),
93 (unsigned long long) be64toh(a->hdr.threadid));
94 }
95
96 static void
ath_alq_print_beacon_resume(struct if_ath_alq_payload * a)97 ath_alq_print_beacon_resume(struct if_ath_alq_payload *a)
98 {
99
100 printf("[%u.%06u] [%llu] BRESUME\n",
101 (unsigned int) be32toh(a->hdr.tstamp_sec),
102 (unsigned int) be32toh(a->hdr.tstamp_usec),
103 (unsigned long long) be64toh(a->hdr.threadid));
104 }
105
106 int
main(int argc,const char * argv[])107 main(int argc, const char *argv[])
108 {
109 const char *file = argv[1];
110 int fd;
111 struct if_ath_alq_payload *a;
112 int r;
113 char buf[READBUF_SIZE];
114 int buflen = 0;
115
116 if (argc < 2) {
117 printf("usage: %s <ahq log>\n", argv[0]);
118 exit(127);
119 }
120
121 fd = open(file, O_RDONLY);
122 if (fd < 0) {
123 perror("open");
124 exit(127);
125 }
126
127 /*
128 * The payload structure is now no longer a fixed
129 * size. So, hoops are jumped through. Really
130 * terrible, infficient hoops.
131 */
132 while (1) {
133 if (buflen < 512) { /* XXX Eww */
134 r = read(fd, buf + buflen, READBUF_SIZE - buflen);
135 if (r <= 0)
136 break;
137 buflen += r;
138 //printf("read %d bytes, buflen now %d\n", r, buflen);
139 }
140
141 a = (struct if_ath_alq_payload *) &buf[0];
142
143 /*
144 * XXX sanity check that len is within the left over
145 * size of buf.
146 */
147 if (be16toh(a->hdr.len) > buflen) {
148 fprintf(stderr, "%s: len=%d, buf=%d, tsk!\n",
149 argv[0], be16toh(a->hdr.len),
150 buflen);
151 break;
152 }
153
154 switch (be16toh(a->hdr.op)) {
155 case ATH_ALQ_INIT_STATE:
156 /* XXX should double check length! */
157 memcpy(&hdr, a->payload, sizeof(hdr));
158 ath_alq_print_hdr(&hdr);
159 break;
160 case ATH_ALQ_TDMA_BEACON_STATE:
161 ath_tdma_beacon_state(a);
162 break;
163 case ATH_ALQ_TDMA_TIMER_CONFIG:
164 ath_tdma_timer_config(a);
165 break;
166 case ATH_ALQ_TDMA_SLOT_CALC:
167 ath_tdma_slot_calc(a);
168 break;
169 case ATH_ALQ_TDMA_TSF_ADJUST:
170 ath_tdma_tsf_adjust(a);
171 break;
172 case ATH_ALQ_TDMA_TIMER_SET:
173 ath_tdma_timer_set(a);
174 break;
175 case ATH_ALQ_INTR_STATUS:
176 ath_alq_print_intr_status(a);
177 break;
178 case ATH_ALQ_MISSED_BEACON:
179 ath_alq_print_beacon_miss(a);
180 break;
181 case ATH_ALQ_STUCK_BEACON:
182 ath_alq_print_beacon_stuck(a);
183 break;
184 case ATH_ALQ_RESUME_BEACON:
185 ath_alq_print_beacon_resume(a);
186 break;
187 case ATH_ALQ_TX_FIFO_PUSH:
188 ath_alq_print_edma_tx_fifo_push(a);
189 break;
190 default:
191 if (be32toh(hdr.sc_hal_magic) == AR5210_MAGIC)
192 ar5210_alq_payload(a);
193 else if (be32toh(hdr.sc_hal_magic) == AR5211_MAGIC)
194 ar5211_alq_payload(a);
195 else if (be32toh(hdr.sc_hal_magic) == AR5212_MAGIC)
196 ar5212_alq_payload(a);
197 else if (be32toh(hdr.sc_hal_magic) == AR5416_MAGIC)
198 ar5416_alq_payload(a);
199 else if (be32toh(hdr.sc_hal_magic) == AR9300_MAGIC)
200 ar9300_alq_payload(a);
201 else
202 printf("[%d.%06d] [%lld] op: %d; len %d\n",
203 be32toh(a->hdr.tstamp_sec),
204 be32toh(a->hdr.tstamp_usec),
205 be64toh(a->hdr.threadid),
206 be16toh(a->hdr.op),
207 be16toh(a->hdr.len));
208 }
209
210 /*
211 * a.len is minus the header size, so..
212 */
213 buflen -= (be16toh(a->hdr.len)
214 + sizeof(struct if_ath_alq_hdr));
215 memmove(&buf[0],
216 &buf[be16toh(a->hdr.len) + sizeof(struct if_ath_alq_hdr)],
217 READBUF_SIZE - (be16toh(a->hdr.len)
218 + sizeof(struct if_ath_alq_hdr)));
219 //printf(" buflen is now %d\n", buflen);
220 }
221 close(fd);
222 }
223