2 * Copyright (c) 2006 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Sepherosa Ziehau <sepherosa@gmail.com> and
6 * Sascha Wildner <swildner@gmail.com>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
18 * 3. Neither the name of The DragonFly Project nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific, prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * $DragonFly: src/usr.sbin/acxcontrol/Attic/acxcontrol.c,v 1.1 2006/04/01 02:55:36 sephe Exp $
38 #include <sys/types.h>
39 #include <sys/ioctl.h>
41 #include <sys/socket.h>
43 #include <sys/sysctl.h>
58 #define SIOCSLOADFW _IOW('i', 137, struct ifreq) /* load firmware */
59 #define SIOCGRADIO _IOW('i', 138, struct ifreq) /* get radio type */
60 #define SIOCGSTATS _IOW('i', 139, struct ifreq) /* get acx stats */
61 #define SIOCSKILLFW _IOW('i', 140, struct ifreq) /* free firmware */
62 #define SIOCGFWVER _IOW('i', 141, struct ifreq) /* get firmware ver */
63 #define SIOCGHWID _IOW('i', 142, struct ifreq) /* get hardware id */
65 #define RADIO_FW_FMT "radio%02x"
67 static int do_req(const char *, unsigned long, void *);
68 static void get_statistics(const char *);
69 static void kill_firmware(const char *);
70 static void load_firmware(const char *, const char *, int);
71 static void mmap_file(const char *, uint8_t **, int *);
72 static void usage(void);
81 struct firmware_head {
91 static const struct statistic tbl[] = {
92 { 1, "Invalid param in TX description" },
93 { 2, "No WEP key exists" },
94 { 3, "MSDU timeouts" },
95 { 4, "Excessive TX retries" },
96 { 5, "Buffer overflows" },
98 { 7, "Unknown errors" },
103 do_req(const char *iface, unsigned long req, void *data)
109 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
110 err(EX_OSERR, "Can't create socket");
112 memset(&ifr, 0, sizeof(ifr));
113 strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
115 error = ioctl(s, req, &ifr);
123 get_statistics(const char *iface)
127 const struct statistic *stt;
129 if (do_req(iface, SIOCGHWID, &i) == -1)
130 err(EX_OSERR, "Can't get hardware ID");
131 printf("Hardware ID 0x%x\n", i);
133 if (do_req(iface, SIOCGFWVER, &i) == -1)
134 err(EX_OSERR, "Can't get firmware version");
135 printf("Firmware Version 0x%x\n", i);
137 if (do_req(iface, SIOCGSTATS, &stats) == -1)
138 err(EX_OSERR, "Can't get statistics");
140 for (stt = tbl; stt->index != -1; stt++)
141 printf("%-30s %qd\n", stt->desc, stats[stt->index]);
145 kill_firmware(const char *iface)
147 if (do_req(iface, SIOCSKILLFW, NULL) == -1)
148 err(EX_OSERR, "Can't kill firmware");
152 load_firmware(const char *iface, const char *filename, int uncombined)
154 char radio_name[FILENAME_MAX];
157 memset(&fw, 0, sizeof(fw));
158 mmap_file(filename, &fw.base_fw, &fw.base_fw_len);
163 if (do_req(iface, SIOCGRADIO, &radio_type) == -1)
164 err(EX_OSERR, "Can't get radio type");
165 snprintf(radio_name, FILENAME_MAX, "%s/" RADIO_FW_FMT ".bin",
166 dirname(filename), radio_type);
167 mmap_file(radio_name, &fw.radio_fw, &fw.radio_fw_len);
170 do_req(iface, SIOCSLOADFW, &fw);
174 mmap_file(const char *filename, uint8_t **addr, int *len)
177 struct firmware_head *fwh;
182 fd = open(filename, O_RDONLY);
184 err(EX_OSERR, "Can't open %s", filename);
186 if (fstat(fd, &st) < 0)
187 err(EX_OSERR, "Can't stat %s", filename);
189 if (st.st_size <= sizeof(struct firmware_head))
190 err(EX_SOFTWARE, "%s is too short", filename);
192 fwh = mmap(NULL, st.st_size, PROT_READ, 0, fd, 0);
194 err(EX_OSERR, "Can't map %s into memory", filename);
196 if (fwh->fwh_len != st.st_size - sizeof(struct firmware_head))
197 err(EX_SOFTWARE, "%s length mismatch", filename);
200 for (i = 0, p = (uint8_t *)&fwh->fwh_len;
201 i < st.st_size - sizeof(fwh->fwh_cksum);
204 if (cksum != fwh->fwh_cksum)
205 err(EX_SOFTWARE, "%s checksum mismatch", filename);
207 *addr = (uint8_t *)(fwh + 1);
208 *len = st.st_size - sizeof(struct firmware_head);
216 fprintf(stderr, "usage: acxcontrol iface\n"
217 " acxcontrol iface -f file [-r]\n"
218 " acxcontrol iface -k\n");
223 main(int argc, char *argv[])
226 int noflag = 1, kflag = 0, rflag = 0;
227 const char *iface = NULL, *path = NULL;
229 if (argc > 1 && argv[1][0] != '-') {
234 while ((c = getopt(argc, argv, "f:i:kr")) != -1) {
259 if (kflag && ((path != NULL) || rflag))
263 kill_firmware(iface);
266 load_firmware(iface, path, rflag);
269 get_statistics(iface);