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 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 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 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 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 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 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