From c6ad5a0c00fc134814d463ab7e380c6d1403a70d Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Wed, 6 Feb 2008 08:21:22 +0000 Subject: [PATCH] - Use firmware(9) for acx(4) and revoke acx(4)'s private ioctls - Nuke acxcontrol(8) - Update acx(4) manpage --- share/man/man4/acx.4 | 27 +++- sys/dev/netif/acx/acx100.c | 6 +- sys/dev/netif/acx/acx111.c | 6 +- sys/dev/netif/acx/if_acx.c | 219 +++++++++++++++++++------------ sys/dev/netif/acx/if_acxvar.h | 27 +++- usr.sbin/Makefile | 3 +- usr.sbin/acxcontrol/Makefile | 7 - usr.sbin/acxcontrol/acxcontrol.8 | 82 ------------ usr.sbin/acxcontrol/acxcontrol.c | 272 --------------------------------------- 9 files changed, 189 insertions(+), 460 deletions(-) delete mode 100644 usr.sbin/acxcontrol/Makefile delete mode 100644 usr.sbin/acxcontrol/acxcontrol.8 delete mode 100644 usr.sbin/acxcontrol/acxcontrol.c diff --git a/share/man/man4/acx.4 b/share/man/man4/acx.4 index b1ea47bf2..bfaaf72a7 100644 --- a/share/man/man4/acx.4 +++ b/share/man/man4/acx.4 @@ -28,9 +28,9 @@ .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $DragonFly: src/share/man/man4/acx.4,v 1.11 2007/10/27 18:25:39 swildner Exp $ +.\" $DragonFly: src/share/man/man4/acx.4,v 1.12 2008/02/06 08:21:22 sephe Exp $ .\" -.Dd September 15, 2007 +.Dd February 6, 2008 .Dt ACX 4 .Os .Sh NAME @@ -76,9 +76,23 @@ The following per-interface variables are implemented in the branch of the .Xr sysctl 3 MIB. -.Bl -tag -width ".Va msdu_lifetime" +.Bl -tag -width ".Va combined_radio_fw" .It Va msdu_lifetime MSDU life time. +.It Va long_retry_limit +Long retry limit. +.It Va scan_dwell +Channel dwell time during scanning (unit: milliseconds) +.It Va combined_radio_fw +The base and radio firmwares are combined in one image file. +By default, +it is set to 1 for ACX111 parts and 0 for ACX100A and ACX100B parts. +.It Va free_fw +Set to non-zero value to free the loaded firmwares. +This does not affect a running device. +Firmwares will be reloaded from +.Pa /etc/firmware/acx +when device is brought up next time. .El .Sh HARDWARE The following cards are among those supported by the @@ -115,16 +129,15 @@ An archive with firmware files that are known to work can be found at: http://leaf.dragonflybsd.org/~sephe/acx/acx_fw.tbz .Ed .Pp -See -.Xr acxcontrol 8 -for more information on loading firmware. +The firmware files have to reside in +.Pa /etc/firmware/acx +and will be loaded when the interface is brought up. .Sh SEE ALSO .Xr arp 4 , .Xr cardbus 4 , .Xr ifmedia 4 , .Xr pci 4 , .Xr wlan_ratectl 4 , -.Xr acxcontrol 8 , .Xr hostapd 8 , .Xr ifconfig 8 , .Xr sysctl 8 , diff --git a/sys/dev/netif/acx/acx100.c b/sys/dev/netif/acx/acx100.c index cd2e16c22..5fa3df624 100644 --- a/sys/dev/netif/acx/acx100.c +++ b/sys/dev/netif/acx/acx100.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/netif/acx/acx100.c,v 1.11 2008/01/15 09:01:13 sephe Exp $ + * $DragonFly: src/sys/dev/netif/acx/acx100.c,v 1.12 2008/02/06 08:21:22 sephe Exp $ */ #include @@ -306,6 +306,7 @@ acx100_set_param(device_t dev) { struct acx_softc *sc = device_get_softc(dev); struct ieee80211com *ic = &sc->sc_ic; + struct acx_firmware *fw = &sc->sc_firmware; sc->chip_mem1_rid = PCIR_BAR(1); sc->chip_mem2_rid = PCIR_BAR(2); @@ -342,6 +343,9 @@ acx100_set_param(device_t dev) sc->chip_tx_complete = acx100_tx_complete; sc->chip_set_bss_join_param = acx100_set_bss_join_param; sc->chip_proc_wep_rxbuf = acx100_proc_wep_rxbuf; + + fw->combined_radio_fw = 0; + fw->fwdir = "100"; } static int diff --git a/sys/dev/netif/acx/acx111.c b/sys/dev/netif/acx/acx111.c index 0561ced9a..ed0a75352 100644 --- a/sys/dev/netif/acx/acx111.c +++ b/sys/dev/netif/acx/acx111.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/netif/acx/acx111.c,v 1.12 2008/01/15 09:01:13 sephe Exp $ + * $DragonFly: src/sys/dev/netif/acx/acx111.c,v 1.13 2008/02/06 08:21:22 sephe Exp $ */ #include @@ -346,6 +346,7 @@ acx111_set_param(device_t dev) { struct acx_softc *sc = device_get_softc(dev); struct ieee80211com *ic = &sc->sc_ic; + struct acx_firmware *fw = &sc->sc_firmware; sc->chip_mem1_rid = PCIR_BAR(0); sc->chip_mem2_rid = PCIR_BAR(1); @@ -378,6 +379,9 @@ acx111_set_param(device_t dev) sc->chip_init = acx111_init; sc->chip_write_config = acx111_write_config; sc->chip_set_bss_join_param = acx111_set_bss_join_param; + + fw->combined_radio_fw = 1; + fw->fwdir = "111"; } static int diff --git a/sys/dev/netif/acx/if_acx.c b/sys/dev/netif/acx/if_acx.c index 908055760..e0c7fd075 100644 --- a/sys/dev/netif/acx/if_acx.c +++ b/sys/dev/netif/acx/if_acx.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/netif/acx/if_acx.c,v 1.24 2008/02/06 05:06:08 sephe Exp $ + * $DragonFly: src/sys/dev/netif/acx/if_acx.c,v 1.25 2008/02/06 08:21:22 sephe Exp $ */ /* @@ -76,6 +76,7 @@ #include #include #include +#include #include #include #include @@ -107,13 +108,6 @@ #include #include -#define SIOCSLOADFW _IOW('i', 137, struct ifreq) /* load firmware */ -#define SIOCGRADIO _IOW('i', 138, struct ifreq) /* get radio type */ -#define SIOCGSTATS _IOW('i', 139, struct ifreq) /* get acx stats */ -#define SIOCSKILLFW _IOW('i', 140, struct ifreq) /* free firmware */ -#define SIOCGFWVER _IOW('i', 141, struct ifreq) /* get firmware ver */ -#define SIOCGHWID _IOW('i', 142, struct ifreq) /* get hardware id */ - static int acx_probe(device_t); static int acx_attach(device_t); static int acx_detach(device_t); @@ -158,8 +152,10 @@ static int acx_set_beacon_tmplt(struct acx_softc *, static int acx_read_eeprom(struct acx_softc *, uint32_t, uint8_t *); static int acx_read_phyreg(struct acx_softc *, uint32_t, uint8_t *); -static int acx_copyin_firmware(struct acx_softc *, struct ifreq *); +static int acx_alloc_firmware(struct acx_softc *); static void acx_free_firmware(struct acx_softc *); +static int acx_setup_firmware(struct acx_softc *, struct fw_image *, + const uint8_t **, int *); static int acx_load_firmware(struct acx_softc *, uint32_t, const uint8_t *, int); static int acx_load_radio_firmware(struct acx_softc *, const uint8_t *, @@ -174,6 +170,7 @@ static int acx_media_change(struct ifnet *); static int acx_newstate(struct ieee80211com *, enum ieee80211_state, int); static int acx_sysctl_msdu_lifetime(SYSCTL_HANDLER_ARGS); +static int acx_sysctl_free_firmware(SYSCTL_HANDLER_ARGS); const struct ieee80211_rateset acx_rates_11b = { 5, { 2, 4, 11, 22, 44 } }; @@ -410,6 +407,21 @@ acx_attach(device_t dev) &sc->sc_scan_dwell, 0, "Scan channel dwell time (ms)"); /* + * Nodes for firmware operation + */ + SYSCTL_ADD_INT(&sc->sc_sysctl_ctx, + SYSCTL_CHILDREN(sc->sc_sysctl_tree), OID_AUTO, + "combined_radio_fw", CTLFLAG_RW, + &sc->sc_firmware.combined_radio_fw, 0, + "Radio and base firmwares are combined"); + SYSCTL_ADD_PROC(&sc->sc_sysctl_ctx, + SYSCTL_CHILDREN(sc->sc_sysctl_tree), + OID_AUTO, "free_fw", + CTLTYPE_INT | CTLFLAG_RW, + sc, 0, acx_sysctl_free_firmware, "I", + "Free firmware"); + + /* * Nodes for statistics */ SYSCTL_ADD_UQUAD(&sc->sc_sysctl_ctx, @@ -594,11 +606,9 @@ acx_init(void *arg) if (error) return; - if (fw->base_fw == NULL) { - error = EINVAL; - if_printf(ifp, "base firmware is not loaded yet\n"); + error = acx_alloc_firmware(sc); + if (error) return; - } error = acx_init_tx_ring(sc); if (error) { @@ -1014,35 +1024,6 @@ acx_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr) req = (struct ifreq *)data; switch (cmd) { - case SIOCSLOADFW: - error = suser_cred(cr, NULL_CRED_OKAY); - if (error) - break; - - error = acx_copyin_firmware(sc, req); - break; - case SIOCSKILLFW: - error = suser_cred(cr, NULL_CRED_OKAY); - if (error) - break; - acx_free_firmware(sc); - break; - case SIOCGRADIO: - error = copyout(&sc->sc_radio_type, req->ifr_data, - sizeof(sc->sc_radio_type)); - break; - case SIOCGFWVER: - error = copyout(&sc->sc_firmware_ver, req->ifr_data, - sizeof(sc->sc_firmware_ver)); - break; - case SIOCGHWID: - error = copyout(&sc->sc_hardware_id, req->ifr_data, - sizeof(sc->sc_hardware_id)); - break; - case SIOCGSTATS: - error = copyout(&sc->sc_stats, req->ifr_data, - sizeof(sc->sc_stats)); - break; case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { if ((ifp->if_flags & IFF_RUNNING)) { @@ -1685,56 +1666,104 @@ acx_write_phyreg(struct acx_softc *sc, uint32_t reg, uint8_t val) } static int -acx_copyin_firmware(struct acx_softc *sc, struct ifreq *req) +acx_alloc_firmware(struct acx_softc *sc) { - struct acx_firmware ufw, *kfw; - uint8_t *base_fw, *radio_fw; - int error; + struct acx_firmware *fw = &sc->sc_firmware; + char filename[64]; + int error = 0; + + if (fw->base_fw_image == NULL) { + if (fw->combined_radio_fw) { + ksnprintf(filename, sizeof(filename), + ACX_BASE_RADIO_FW_PATH, + fw->fwdir, sc->sc_radio_type); + } else { + ksnprintf(filename, sizeof(filename), + ACX_BASE_FW_PATH, fw->fwdir); + } + fw->base_fw_image = firmware_image_load(filename, NULL); + if (fw->base_fw_image == NULL) { + if_printf(&sc->sc_ic.ic_if, "load %s base fw failed\n", + filename); + error = EIO; + goto back; + } + + error = acx_setup_firmware(sc, fw->base_fw_image, + &fw->base_fw, &fw->base_fw_len); + if (error) + goto back; + } - kfw = &sc->sc_firmware; - base_fw = NULL; - radio_fw = NULL; + if (!fw->combined_radio_fw && fw->radio_fw_image == NULL) { + ksnprintf(filename, sizeof(filename), ACX_RADIO_FW_PATH, + fw->fwdir, sc->sc_radio_type); + fw->radio_fw_image = firmware_image_load(filename, NULL); + if (fw->radio_fw_image == NULL) { + if_printf(&sc->sc_ic.ic_if, "load %s radio fw failed\n", + filename); + error = EIO; + goto back; + } - error = copyin(req->ifr_data, &ufw, sizeof(ufw)); + error = acx_setup_firmware(sc, fw->radio_fw_image, + &fw->radio_fw, &fw->radio_fw_len); + } +back: if (error) - return error; + acx_free_firmware(sc); + return error; +} + +static int +acx_setup_firmware(struct acx_softc *sc, struct fw_image *img, + const uint8_t **ptr, int *len) +{ + const struct acx_firmware_hdr *hdr; + const uint8_t *p; + uint32_t cksum; + int i; + + *ptr = NULL; + *len = 0; /* - * For combined base firmware, there is no radio firmware. - * But base firmware must exist. + * Make sure that the firmware image contains more than just a header */ - if (ufw.base_fw_len <= 0 || ufw.radio_fw_len < 0) + if (img->fw_imglen <= sizeof(*hdr)) { + if_printf(&sc->sc_ic.ic_if, "%s is invalid image, " + "size %u (too small)\n", + img->fw_name, img->fw_imglen); return EINVAL; - - base_fw = kmalloc(ufw.base_fw_len, M_DEVBUF, M_INTWAIT); - error = copyin(ufw.base_fw, base_fw, ufw.base_fw_len); - if (error) - goto fail; - - if (ufw.radio_fw_len > 0) { - radio_fw = kmalloc(ufw.radio_fw_len, M_DEVBUF, M_INTWAIT); - error = copyin(ufw.radio_fw, radio_fw, ufw.radio_fw_len); - if (error) - goto fail; } + hdr = (const struct acx_firmware_hdr *)img->fw_image; - kfw->base_fw_len = ufw.base_fw_len; - if (kfw->base_fw != NULL) - kfree(kfw->base_fw, M_DEVBUF); - kfw->base_fw = base_fw; + /* + * Verify length + */ + if (hdr->fwh_len != img->fw_imglen - sizeof(*hdr)) { + if_printf(&sc->sc_ic.ic_if, "%s is invalid image, " + "size in hdr %u and image size %u mismatches\n", + img->fw_name, hdr->fwh_len, img->fw_imglen); + return EINVAL; + } - kfw->radio_fw_len = ufw.radio_fw_len; - if (kfw->radio_fw != NULL) - kfree(kfw->radio_fw, M_DEVBUF); - kfw->radio_fw = radio_fw; + /* + * Verify cksum + */ + cksum = 0; + for (i = 0, p = (const uint8_t *)&hdr->fwh_len; + i < img->fw_imglen - sizeof(hdr->fwh_cksum); ++i, ++p) + cksum += *p; + if (cksum != hdr->fwh_cksum) { + if_printf(&sc->sc_ic.ic_if, "%s is invalid image, " + "checksum mismatch\n", img->fw_name); + return EINVAL; + } + *ptr = ((const uint8_t *)img->fw_image + sizeof(*hdr)); + *len = img->fw_imglen - sizeof(*hdr); return 0; -fail: - if (base_fw != NULL) - kfree(base_fw, M_DEVBUF); - if (radio_fw != NULL) - kfree(radio_fw, M_DEVBUF); - return error; } static void @@ -1742,13 +1771,15 @@ acx_free_firmware(struct acx_softc *sc) { struct acx_firmware *fw = &sc->sc_firmware; - if (fw->base_fw != NULL) { - kfree(fw->base_fw, M_DEVBUF); + if (fw->base_fw_image != NULL) { + firmware_image_unload(fw->base_fw_image); + fw->base_fw_image = NULL; fw->base_fw = NULL; fw->base_fw_len = 0; } - if (fw->radio_fw != NULL) { - kfree(fw->radio_fw, M_DEVBUF); + if (fw->radio_fw_image != NULL) { + firmware_image_unload(fw->radio_fw_image); + fw->radio_fw_image = NULL; fw->radio_fw = NULL; fw->radio_fw_len = 0; } @@ -2592,6 +2623,28 @@ back: } static int +acx_sysctl_free_firmware(SYSCTL_HANDLER_ARGS) +{ + struct acx_softc *sc = arg1; + struct ifnet *ifp = &sc->sc_ic.ic_if; + int error = 0, v; + + lwkt_serialize_enter(ifp->if_serializer); + + v = 0; + error = sysctl_handle_int(oidp, &v, 0, req); + if (error || req->newptr == NULL) + goto back; + if (v == 0) /* Do nothing */ + goto back; + + acx_free_firmware(sc); +back: + lwkt_serialize_exit(ifp->if_serializer); + return error; +} + +static int acx_media_change(struct ifnet *ifp) { int error; diff --git a/sys/dev/netif/acx/if_acxvar.h b/sys/dev/netif/acx/if_acxvar.h index 32322125b..cf45911ed 100644 --- a/sys/dev/netif/acx/if_acxvar.h +++ b/sys/dev/netif/acx/if_acxvar.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/netif/acx/if_acxvar.h,v 1.11 2008/01/15 09:01:13 sephe Exp $ + * $DragonFly: src/sys/dev/netif/acx/if_acxvar.h,v 1.12 2008/02/06 08:21:22 sephe Exp $ */ #ifndef _IF_ACXVAR_H @@ -286,12 +286,22 @@ struct acx_buf_data { int tx_used_count; }; +struct acx_firmware_hdr { + uint32_t fwh_cksum; + uint32_t fwh_len; +} __packed; + struct acx_firmware { - uint8_t *base_fw; - int base_fw_len; + struct fw_image *base_fw_image; + const uint8_t *base_fw; + int base_fw_len; - uint8_t *radio_fw; - int radio_fw_len; + struct fw_image *radio_fw_image; + const uint8_t *radio_fw; + int radio_fw_len; + + int combined_radio_fw; + const char *fwdir; }; struct acx_config { @@ -435,6 +445,9 @@ struct acx_softc { struct sysctl_ctx_list sc_sysctl_ctx; struct sysctl_oid *sc_sysctl_tree; + /* + * TX rate control + */ struct ieee80211_onoe_param sc_onoe_param; struct ieee80211_amrr_param sc_amrr_param; int sc_long_retry_limit; @@ -489,6 +502,10 @@ struct acx_softc { #define ACX_RADIO_TYPE_UNKN17 0x17 #define ACX_RADIO_TYPE_UNKN19 0x19 +#define ACX_BASE_FW_PATH "acx/%s/wlangen.bin" +#define ACX_RADIO_FW_PATH "acx/%s/radio%02x.bin" +#define ACX_BASE_RADIO_FW_PATH "acx/%s/FwRad%02x.bin" + extern const struct ieee80211_rateset acx_rates_11b; extern const struct ieee80211_rateset acx_rates_11g; diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 2fbdeca42..f26cf1b35 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -1,6 +1,6 @@ # From: @(#)Makefile 5.20 (Berkeley) 6/12/93 # $FreeBSD: src/usr.sbin/Makefile,v 1.183.2.14 2003/04/16 11:01:51 ru Exp $ -# $DragonFly: src/usr.sbin/Makefile,v 1.42 2008/02/01 13:52:41 sephe Exp $ +# $DragonFly: src/usr.sbin/Makefile,v 1.43 2008/02/06 08:21:22 sephe Exp $ .include "../sys/platform/${MACHINE_PLATFORM}/Makefile.inc" @@ -10,7 +10,6 @@ SUBDIR= 802_11 \ ac \ accton \ acpi \ - acxcontrol \ adduser \ amd \ ancontrol \ diff --git a/usr.sbin/acxcontrol/Makefile b/usr.sbin/acxcontrol/Makefile deleted file mode 100644 index 51217ac6f..000000000 --- a/usr.sbin/acxcontrol/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# $DragonFly: src/usr.sbin/acxcontrol/Attic/Makefile,v 1.1 2006/04/01 02:55:36 sephe Exp $ -# -PROG = acxcontrol -MAN = acxcontrol.8 -WARNS ?= 6 - -.include diff --git a/usr.sbin/acxcontrol/acxcontrol.8 b/usr.sbin/acxcontrol/acxcontrol.8 deleted file mode 100644 index fe8b166c9..000000000 --- a/usr.sbin/acxcontrol/acxcontrol.8 +++ /dev/null @@ -1,82 +0,0 @@ -.\" -.\" Copyright (c) 2006 The DragonFly Project. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in -.\" the documentation and/or other materials provided with the -.\" distribution. -.\" 3. Neither the name of The DragonFly Project nor the names of its -.\" contributors may be used to endorse or promote products derived -.\" from this software without specific, prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, -.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $DragonFly: src/usr.sbin/acxcontrol/Attic/acxcontrol.8,v 1.1 2006/04/01 02:55:36 sephe Exp $ -.\" -.Dd March 24, 2006 -.Os -.Dt ACXCONTROL 8 -.Sh NAME -.Nm acxcontrol -.Nd configure Texas Instruments ACX100/TNETW1130(ACX111) network adapters -.Sh SYNOPSIS -.Nm -.Op Fl i -.Ar iface -.Nm -.Op Fl i -.Ar iface Fl f Ar file Op Fl r -.Nm -.Op Fl i -.Ar iface Fl k -.Sh DESCRIPTION -The -.Nm -utility controls the operation of Texas Instruments ACX100/TNETW1130(ACX111) -networking devices via the -.Xr acx 4 -driver. -.Pp -In order to configure IEEE 802.11 parameters use -.Xr ifconfig 8 . -.Sh OPTIONS -The options are as follows: -.Bl -tag -width indent -.It Oo Fl i Oc Ar iface -Displays adapter's internal statistics. -.It Oo Fl i Oc Ar iface Fl f Ar file Op Fl r -Download firmware binary image to the adapter. -The -.Fl r -option must be specified if the adapter needs an additional radio firmware. -.It Oo Fl i Oc Ar iface Fl k -Kill the firmware and reset the adapter. -.El -.Sh SEE ALSO -.Xr acx 4 , -.Xr ifconfig 8 -.Sh AUTHORS -.An -nosplit -The -.Nm -utility and its man page were written by -.An Sepherosa Ziehau Aq sepherosa@gmail.com -and -.An Sascha Wildner Aq swildner@gmail.com . diff --git a/usr.sbin/acxcontrol/acxcontrol.c b/usr.sbin/acxcontrol/acxcontrol.c deleted file mode 100644 index 1e29e3902..000000000 --- a/usr.sbin/acxcontrol/acxcontrol.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (c) 2006 The DragonFly Project. All rights reserved. - * - * This code is derived from software contributed to The DragonFly Project - * by Sepherosa Ziehau and - * Sascha Wildner - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name of The DragonFly Project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific, prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $DragonFly: src/usr.sbin/acxcontrol/Attic/acxcontrol.c,v 1.1 2006/04/01 02:55:36 sephe Exp $ - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SIOCSLOADFW _IOW('i', 137, struct ifreq) /* load firmware */ -#define SIOCGRADIO _IOW('i', 138, struct ifreq) /* get radio type */ -#define SIOCGSTATS _IOW('i', 139, struct ifreq) /* get acx stats */ -#define SIOCSKILLFW _IOW('i', 140, struct ifreq) /* free firmware */ -#define SIOCGFWVER _IOW('i', 141, struct ifreq) /* get firmware ver */ -#define SIOCGHWID _IOW('i', 142, struct ifreq) /* get hardware id */ - -#define RADIO_FW_FMT "radio%02x" - -static int do_req(const char *, unsigned long, void *); -static void get_statistics(const char *); -static void kill_firmware(const char *); -static void load_firmware(const char *, const char *, int); -static void mmap_file(const char *, uint8_t **, int *); -static void usage(void); - -struct firmware { - uint8_t *base_fw; - int base_fw_len; - uint8_t *radio_fw; - int radio_fw_len; -}; - -struct firmware_head { - uint32_t fwh_cksum; - uint32_t fwh_len; -}; - -struct statistic { - int index; - const char *desc; -}; - -static const struct statistic tbl[] = { - { 1, "Invalid param in TX description" }, - { 2, "No WEP key exists" }, - { 3, "MSDU timeouts" }, - { 4, "Excessive TX retries" }, - { 5, "Buffer overflows" }, - { 6, "DMA errors" }, - { 7, "Unknown errors" }, - { -1, NULL } -}; - -static int -do_req(const char *iface, unsigned long req, void *data) -{ - int s; - struct ifreq ifr; - int error; - - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - err(EX_OSERR, "Can't create socket"); - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); - ifr.ifr_data = data; - error = ioctl(s, req, &ifr); - - close(s); - - return error; -} - -static void -get_statistics(const char *iface) -{ - uint32_t i; - uint64_t stats[16]; - const struct statistic *stt; - - if (do_req(iface, SIOCGHWID, &i) == -1) - err(EX_OSERR, "Can't get hardware ID"); - printf("Hardware ID 0x%x\n", i); - - if (do_req(iface, SIOCGFWVER, &i) == -1) - err(EX_OSERR, "Can't get firmware version"); - printf("Firmware Version 0x%x\n", i); - - if (do_req(iface, SIOCGSTATS, &stats) == -1) - err(EX_OSERR, "Can't get statistics"); - - for (stt = tbl; stt->index != -1; stt++) - printf("%-30s %qd\n", stt->desc, stats[stt->index]); -} - -static void -kill_firmware(const char *iface) -{ - if (do_req(iface, SIOCSKILLFW, NULL) == -1) - err(EX_OSERR, "Can't kill firmware"); -} - -static void -load_firmware(const char *iface, const char *filename, int uncombined) -{ - char radio_name[FILENAME_MAX]; - struct firmware fw; - - memset(&fw, 0, sizeof(fw)); - mmap_file(filename, &fw.base_fw, &fw.base_fw_len); - - if (uncombined) { - uint8_t radio_type; - - if (do_req(iface, SIOCGRADIO, &radio_type) == -1) - err(EX_OSERR, "Can't get radio type"); - snprintf(radio_name, FILENAME_MAX, "%s/" RADIO_FW_FMT ".bin", - dirname(filename), radio_type); - mmap_file(radio_name, &fw.radio_fw, &fw.radio_fw_len); - } - - do_req(iface, SIOCSLOADFW, &fw); -} - -static void -mmap_file(const char *filename, uint8_t **addr, int *len) -{ - struct stat st; - struct firmware_head *fwh; - uint32_t cksum; - uint8_t *p; - int i, fd; - - fd = open(filename, O_RDONLY); - if (fd < 0) - err(EX_OSERR, "Can't open %s", filename); - - if (fstat(fd, &st) < 0) - err(EX_OSERR, "Can't stat %s", filename); - - if (st.st_size <= sizeof(struct firmware_head)) - err(EX_SOFTWARE, "%s is too short", filename); - - fwh = mmap(NULL, st.st_size, PROT_READ, 0, fd, 0); - if (fwh == NULL) - err(EX_OSERR, "Can't map %s into memory", filename); - - if (fwh->fwh_len != st.st_size - sizeof(struct firmware_head)) - err(EX_SOFTWARE, "%s length mismatch", filename); - - cksum = 0; - for (i = 0, p = (uint8_t *)&fwh->fwh_len; - i < st.st_size - sizeof(fwh->fwh_cksum); - ++i, ++p) - cksum += *p; - if (cksum != fwh->fwh_cksum) - err(EX_SOFTWARE, "%s checksum mismatch", filename); - - *addr = (uint8_t *)(fwh + 1); - *len = st.st_size - sizeof(struct firmware_head); - - close(fd); -} - -static void -usage(void) -{ - fprintf(stderr, "usage: acxcontrol iface\n" - " acxcontrol iface -f file [-r]\n" - " acxcontrol iface -k\n"); - exit(EX_USAGE); -} - -int -main(int argc, char *argv[]) -{ - int c; - int noflag = 1, kflag = 0, rflag = 0; - const char *iface = NULL, *path = NULL; - - if (argc > 1 && argv[1][0] != '-') { - iface = argv[1]; - optind++; - } - - while ((c = getopt(argc, argv, "f:i:kr")) != -1) { - if (c != 'i') - noflag = 0; - - switch (c) { - case 'f': - path = optarg; - break; - case 'i': - iface = optarg; - break; - case 'k': - kflag = 1; - break; - case 'r': - rflag = 1; - break; - default: - usage(); - } - } - - if (iface == NULL) - usage(); - - if (kflag && ((path != NULL) || rflag)) - usage(); - - if (kflag) - kill_firmware(iface); - - if (path != NULL) - load_firmware(iface, path, rflag); - - if (noflag) - get_statistics(iface); - - return EX_OK; -} -- 2.11.4.GIT