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