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 51struct if_ath_alq_init_state hdr; 52 53static void 54ath_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 63static void 64ath_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 78static void 79ath_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 88static void 89ath_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 98static void 99ath_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 108int 109main(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 default: 190 if (be32toh(hdr.sc_hal_magic) == AR5210_MAGIC) 191 ar5210_alq_payload(a); 192 else if (be32toh(hdr.sc_hal_magic) == AR5211_MAGIC) 193 ar5211_alq_payload(a); 194 else if (be32toh(hdr.sc_hal_magic) == AR5212_MAGIC) 195 ar5212_alq_payload(a); 196 else if (be32toh(hdr.sc_hal_magic) == AR5416_MAGIC) 197 ar5416_alq_payload(a); 198#if 1 199 else if (be32toh(hdr.sc_hal_magic) == AR9300_MAGIC) 200 ar9300_alq_payload(a); 201#endif 202 else 203 printf("[%d.%06d] [%lld] op: %d; len %d\n", 204 be32toh(a->hdr.tstamp_sec), 205 be32toh(a->hdr.tstamp_usec), 206 be64toh(a->hdr.threadid), 207 be16toh(a->hdr.op), 208 be16toh(a->hdr.len)); 209 } 210 211 /* 212 * a.len is minus the header size, so.. 213 */ 214 buflen -= (be16toh(a->hdr.len) 215 + sizeof(struct if_ath_alq_hdr)); 216 memmove(&buf[0], 217 &buf[be16toh(a->hdr.len) + sizeof(struct if_ath_alq_hdr)], 218 READBUF_SIZE - (be16toh(a->hdr.len) 219 + sizeof(struct if_ath_alq_hdr))); 220 //printf(" buflen is now %d\n", buflen); 221 } 222 close(fd); 223} 224