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 __FBSDID("$FreeBSD$"); 19 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <unistd.h> 23 #include <fcntl.h> 24 #include <errno.h> 25 #include <string.h> 26 27 #include <sys/types.h> 28 #include <sys/alq.h> 29 #include <sys/endian.h> 30 31 #include <dev/ath/if_ath_alq.h> 32 33 #if 1 34 #include "ar9300_ds.h" 35 #endif 36 #include "ar5210_ds.h" 37 #include "ar5211_ds.h" 38 #include "ar5212_ds.h" 39 #include "ar5416_ds.h" 40 41 #include "tdma.h" 42 43 #define AR5210_MAGIC 0x19980124 44 #define AR5211_MAGIC 0x19570405 45 #define AR5212_MAGIC 0x19541014 46 #define AR5416_MAGIC 0x20065416 47 #define AR9300_MAGIC 0x19741014 48 49 #define READBUF_SIZE 1024 50 51 struct if_ath_alq_init_state hdr; 52 53 static void 54 ath_alq_print_hdr(struct if_ath_alq_init_state *hdr) 55 { 56 printf("macVersion=%d.%d, PHY=%d, Magic=%08x\n", 57 be32toh(hdr->sc_mac_version), 58 be32toh(hdr->sc_mac_revision), 59 be32toh(hdr->sc_phy_rev), 60 be32toh(hdr->sc_hal_magic)); 61 } 62 63 static void 64 ath_alq_print_intr_status(struct if_ath_alq_payload *a) 65 { 66 struct if_ath_alq_interrupt is; 67 68 /* XXX len check! */ 69 memcpy(&is, &a->payload, sizeof(is)); 70 71 printf("[%u.%06u] [%llu] INTR: status=0x%08x\n", 72 (unsigned int) be32toh(a->hdr.tstamp_sec), 73 (unsigned int) be32toh(a->hdr.tstamp_usec), 74 (unsigned long long) be64toh(a->hdr.threadid), 75 be32toh(is.intr_status)); 76 } 77 78 static void 79 ath_alq_print_beacon_miss(struct if_ath_alq_payload *a) 80 { 81 82 printf("[%u.%06u] [%llu] BMISS\n", 83 (unsigned int) be32toh(a->hdr.tstamp_sec), 84 (unsigned int) be32toh(a->hdr.tstamp_usec), 85 (unsigned long long) be64toh(a->hdr.threadid)); 86 } 87 88 static void 89 ath_alq_print_beacon_stuck(struct if_ath_alq_payload *a) 90 { 91 92 printf("[%u.%06u] [%llu] BSTUCK\n", 93 (unsigned int) be32toh(a->hdr.tstamp_sec), 94 (unsigned int) be32toh(a->hdr.tstamp_usec), 95 (unsigned long long) be64toh(a->hdr.threadid)); 96 } 97 98 static void 99 ath_alq_print_beacon_resume(struct if_ath_alq_payload *a) 100 { 101 102 printf("[%u.%06u] [%llu] BRESUME\n", 103 (unsigned int) be32toh(a->hdr.tstamp_sec), 104 (unsigned int) be32toh(a->hdr.tstamp_usec), 105 (unsigned long long) be64toh(a->hdr.threadid)); 106 } 107 108 int 109 main(int argc, const char *argv[]) 110 { 111 const char *file = argv[1]; 112 int fd; 113 struct if_ath_alq_payload *a; 114 int r; 115 char buf[READBUF_SIZE]; 116 int buflen = 0; 117 118 if (argc < 2) { 119 printf("usage: %s <ahq log>\n", argv[0]); 120 exit(127); 121 } 122 123 fd = open(file, O_RDONLY); 124 if (fd < 0) { 125 perror("open"); 126 exit(127); 127 } 128 129 /* 130 * The payload structure is now no longer a fixed 131 * size. So, hoops are jumped through. Really 132 * terrible, infficient hoops. 133 */ 134 while (1) { 135 if (buflen < 512) { /* XXX Eww */ 136 r = read(fd, buf + buflen, READBUF_SIZE - buflen); 137 if (r <= 0) 138 break; 139 buflen += r; 140 //printf("read %d bytes, buflen now %d\n", r, buflen); 141 } 142 143 a = (struct if_ath_alq_payload *) &buf[0]; 144 145 /* 146 * XXX sanity check that len is within the left over 147 * size of buf. 148 */ 149 if (be16toh(a->hdr.len) > buflen) { 150 fprintf(stderr, "%s: len=%d, buf=%d, tsk!\n", 151 argv[0], be16toh(a->hdr.len), 152 buflen); 153 break; 154 } 155 156 switch (be16toh(a->hdr.op)) { 157 case ATH_ALQ_INIT_STATE: 158 /* XXX should double check length! */ 159 memcpy(&hdr, a->payload, sizeof(hdr)); 160 ath_alq_print_hdr(&hdr); 161 break; 162 case ATH_ALQ_TDMA_BEACON_STATE: 163 ath_tdma_beacon_state(a); 164 break; 165 case ATH_ALQ_TDMA_TIMER_CONFIG: 166 ath_tdma_timer_config(a); 167 break; 168 case ATH_ALQ_TDMA_SLOT_CALC: 169 ath_tdma_slot_calc(a); 170 break; 171 case ATH_ALQ_TDMA_TSF_ADJUST: 172 ath_tdma_tsf_adjust(a); 173 break; 174 case ATH_ALQ_TDMA_TIMER_SET: 175 ath_tdma_timer_set(a); 176 break; 177 case ATH_ALQ_INTR_STATUS: 178 ath_alq_print_intr_status(a); 179 break; 180 case ATH_ALQ_MISSED_BEACON: 181 ath_alq_print_beacon_miss(a); 182 break; 183 case ATH_ALQ_STUCK_BEACON: 184 ath_alq_print_beacon_stuck(a); 185 break; 186 case ATH_ALQ_RESUME_BEACON: 187 ath_alq_print_beacon_resume(a); 188 break; 189 case ATH_ALQ_TX_FIFO_PUSH: 190 ath_alq_print_edma_tx_fifo_push(a); 191 break; 192 default: 193 if (be32toh(hdr.sc_hal_magic) == AR5210_MAGIC) 194 ar5210_alq_payload(a); 195 else if (be32toh(hdr.sc_hal_magic) == AR5211_MAGIC) 196 ar5211_alq_payload(a); 197 else if (be32toh(hdr.sc_hal_magic) == AR5212_MAGIC) 198 ar5212_alq_payload(a); 199 else if (be32toh(hdr.sc_hal_magic) == AR5416_MAGIC) 200 ar5416_alq_payload(a); 201 else if (be32toh(hdr.sc_hal_magic) == AR9300_MAGIC) 202 ar9300_alq_payload(a); 203 else 204 printf("[%d.%06d] [%lld] op: %d; len %d\n", 205 be32toh(a->hdr.tstamp_sec), 206 be32toh(a->hdr.tstamp_usec), 207 be64toh(a->hdr.threadid), 208 be16toh(a->hdr.op), 209 be16toh(a->hdr.len)); 210 } 211 212 /* 213 * a.len is minus the header size, so.. 214 */ 215 buflen -= (be16toh(a->hdr.len) 216 + sizeof(struct if_ath_alq_hdr)); 217 memmove(&buf[0], 218 &buf[be16toh(a->hdr.len) + sizeof(struct if_ath_alq_hdr)], 219 READBUF_SIZE - (be16toh(a->hdr.len) 220 + sizeof(struct if_ath_alq_hdr))); 221 //printf(" buflen is now %d\n", buflen); 222 } 223 close(fd); 224 } 225