diff options
author | rwatson <rwatson@FreeBSD.org> | 2009-04-17 09:42:26 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2009-04-17 09:42:26 +0000 |
commit | 711c3bad4df664fafea20bc76ab6c8b815207e47 (patch) | |
tree | 6c69b62ad4b8337aed9f627b6ad0d958b7610bca /sys/legacy/dev | |
parent | 48b4c9024916af1f0376ae60e320aa80d9b7aab3 (diff) | |
download | FreeBSD-src-711c3bad4df664fafea20bc76ab6c8b815207e47.zip FreeBSD-src-711c3bad4df664fafea20bc76ab6c8b815207e47.tar.gz |
Remove legacy versions of USB network interface drivers relying on
IFF_NEEDSGIANT, as that is no longer supported.
Diffstat (limited to 'sys/legacy/dev')
-rw-r--r-- | sys/legacy/dev/usb/if_aue.c | 1498 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_auereg.h | 294 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_axe.c | 1428 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_axereg.h | 254 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_cdce.c | 771 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_cdcereg.h | 79 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_cue.c | 1074 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_cuereg.h | 168 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_kue.c | 1024 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_kuereg.h | 161 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_rue.c | 1393 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_ruereg.h | 226 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_rum.c | 2560 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_rumreg.h | 235 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_rumvar.h | 161 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_udav.c | 1962 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_udavreg.h | 210 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_ural.c | 2505 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_uralreg.h | 210 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_uralvar.h | 157 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_zyd.c | 3126 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_zydfw.h | 1144 | ||||
-rw-r--r-- | sys/legacy/dev/usb/if_zydreg.h | 1322 |
23 files changed, 0 insertions, 21962 deletions
diff --git a/sys/legacy/dev/usb/if_aue.c b/sys/legacy/dev/usb/if_aue.c deleted file mode 100644 index 1c6d8a3..0000000 --- a/sys/legacy/dev/usb/if_aue.c +++ /dev/null @@ -1,1498 +0,0 @@ -/*- - * Copyright (c) 1997, 1998, 1999, 2000 - * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. - * - * Copyright (c) 2006 - * Alfred Perlstein <alfred@freebsd.org>. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * ADMtek AN986 Pegasus and AN8511 Pegasus II USB to ethernet driver. - * Datasheet is available from http://www.admtek.com.tw. - * - * Written by Bill Paul <wpaul@ee.columbia.edu> - * Electrical Engineering Department - * Columbia University, New York City - * - * SMP locking by Alfred Perlstein <alfred@freebsd.org>. - * RED Inc. - */ - -/* - * The Pegasus chip uses four USB "endpoints" to provide 10/100 ethernet - * support: the control endpoint for reading/writing registers, burst - * read endpoint for packet reception, burst write for packet transmission - * and one for "interrupts." The chip uses the same RX filter scheme - * as the other ADMtek ethernet parts: one perfect filter entry for the - * the station address and a 64-bit multicast hash table. The chip supports - * both MII and HomePNA attachments. - * - * Since the maximum data transfer speed of USB is supposed to be 12Mbps, - * you're never really going to get 100Mbps speeds from this device. I - * think the idea is to allow the device to connect to 10 or 100Mbps - * networks, not necessarily to provide 100Mbps performance. Also, since - * the controller uses an external PHY chip, it's possible that board - * designers might simply choose a 10Mbps PHY. - * - * Registers are accessed using usbd_do_request(). Packet transfers are - * done using usbd_transfer() and friends. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/sockio.h> -#include <sys/mbuf.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/kdb.h> -#include <sys/lock.h> -#include <sys/module.h> -#include <sys/socket.h> -#include <sys/sx.h> -#include <sys/taskqueue.h> - -#include <net/if.h> -#include <net/if_arp.h> -#include <net/ethernet.h> -#include <net/if_dl.h> -#include <net/if_media.h> -#include <net/if_types.h> - -#include <net/bpf.h> - -#include <sys/bus.h> -#include <machine/bus.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdivar.h> -#include "usbdevs.h" -#include <dev/usb/usb_ethersubr.h> - -#include <dev/mii/mii.h> -#include <dev/mii/miivar.h> - -#include <dev/usb/if_auereg.h> - -MODULE_DEPEND(aue, usb, 1, 1, 1); -MODULE_DEPEND(aue, ether, 1, 1, 1); -MODULE_DEPEND(aue, miibus, 1, 1, 1); - -/* "device miibus" required. See GENERIC if you get errors here. */ -#include "miibus_if.h" - -/* - * Various supported device vendors/products. - */ -struct aue_type { - struct usb_devno aue_dev; - u_int16_t aue_flags; -#define LSYS 0x0001 /* use Linksys reset */ -#define PNA 0x0002 /* has Home PNA */ -#define PII 0x0004 /* Pegasus II chip */ -}; - -static const struct aue_type aue_devs[] = { - {{ USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460B}, PII }, - {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX1}, PNA|PII }, - {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX2}, PII }, - {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE1000}, LSYS }, - {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX4}, PNA }, - {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX5}, PNA }, - {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX6}, PII }, - {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX7}, PII }, - {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX8}, PII }, - {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX9}, PNA }, - {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX10}, 0 }, - {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_DSB650TX_PNA}, 0 }, - {{ USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_USB320_EC}, 0 }, - {{ USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SS1001}, PII }, - {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS}, PNA }, - {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII}, PII }, - {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_2}, PII }, - {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_3}, PII }, - {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_4}, PII }, - {{ USB_VENDOR_AEI, USB_PRODUCT_AEI_FASTETHERNET}, PII }, - {{ USB_VENDOR_ALLIEDTELESYN, USB_PRODUCT_ALLIEDTELESYN_ATUSB100}, PII }, - {{ USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC110T}, PII }, - {{ USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2LAN}, PII }, - {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100}, 0 }, - {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBLP100}, PNA }, - {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBEL100}, 0 }, - {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBE100}, PII }, - {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TX}, 0 }, - {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXS},PII }, - {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX4}, LSYS|PII }, - {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX1}, LSYS }, - {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX}, LSYS }, - {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX_PNA}, PNA }, - {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX3}, LSYS|PII }, - {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX2}, LSYS|PII }, - {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650}, LSYS }, - {{ USB_VENDOR_ELCON, USB_PRODUCT_ELCON_PLAN}, PNA|PII }, - {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSB20}, PII }, - {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX0}, 0 }, - {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX1}, LSYS }, - {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX2}, 0 }, - {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX3}, LSYS }, - {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBLTX}, PII }, - {{ USB_VENDOR_ELSA, USB_PRODUCT_ELSA_USB2ETHERNET}, 0 }, - {{ USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNBR402W}, 0 }, - {{ USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_UF100}, PII }, - {{ USB_VENDOR_HP, USB_PRODUCT_HP_HN210E}, PII }, - {{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTX}, 0 }, - {{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTXS}, PII }, - {{ USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_KNU101TX}, 0 }, - {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX1}, LSYS|PII }, - {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T}, LSYS }, - {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100TX}, LSYS }, - {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100H1}, LSYS|PNA }, - {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TA}, LSYS }, - {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX2}, LSYS|PII }, - {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX1}, 0 }, - {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX5}, 0 }, - {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUA2TX5}, PII }, - {{ USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110}, PII }, - {{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA101}, PII }, - {{ USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM}, PII }, - {{ USB_VENDOR_SIIG2, USB_PRODUCT_SIIG2_USBTOETHER}, PII }, - {{ USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTNIC},PII }, - {{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB}, 0 }, - {{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2206USB}, PII }, - {{ USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100}, 0 }, - {{ USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB110}, PII }, -}; -#define aue_lookup(v, p) ((const struct aue_type *)usb_lookup(aue_devs, v, p)) - -static device_probe_t aue_match; -static device_attach_t aue_attach; -static device_detach_t aue_detach; -static device_shutdown_t aue_shutdown; -static miibus_readreg_t aue_miibus_readreg; -static miibus_writereg_t aue_miibus_writereg; -static miibus_statchg_t aue_miibus_statchg; - -static void aue_reset_pegasus_II(struct aue_softc *sc); -static int aue_encap(struct aue_softc *, struct mbuf *, int); -#ifdef AUE_INTR_PIPE -static void aue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); -#endif -static void aue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void aue_rxeof_thread(struct aue_softc *sc); -static void aue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void aue_txeof_thread(struct aue_softc *); -static void aue_task_sched(struct aue_softc *, int); -static void aue_task(void *xsc, int pending); -static void aue_tick(void *); -static void aue_rxstart(struct ifnet *); -static void aue_rxstart_thread(struct aue_softc *); -static void aue_start(struct ifnet *); -static void aue_start_thread(struct aue_softc *); -static int aue_ioctl(struct ifnet *, u_long, caddr_t); -static void aue_init(void *); -static void aue_init_body(struct aue_softc *); -static void aue_stop(struct aue_softc *); -static void aue_watchdog(struct aue_softc *); -static int aue_ifmedia_upd(struct ifnet *); -static void aue_ifmedia_sts(struct ifnet *, struct ifmediareq *); - -static void aue_eeprom_getword(struct aue_softc *, int, u_int16_t *); -static void aue_read_eeprom(struct aue_softc *, caddr_t, int, int, int); - -static void aue_setmulti(struct aue_softc *); -static void aue_reset(struct aue_softc *); - -static int aue_csr_read_1(struct aue_softc *, int); -static int aue_csr_write_1(struct aue_softc *, int, int); -static int aue_csr_read_2(struct aue_softc *, int); -static int aue_csr_write_2(struct aue_softc *, int, int); - -static device_method_t aue_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, aue_match), - DEVMETHOD(device_attach, aue_attach), - DEVMETHOD(device_detach, aue_detach), - DEVMETHOD(device_shutdown, aue_shutdown), - - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - - /* MII interface */ - DEVMETHOD(miibus_readreg, aue_miibus_readreg), - DEVMETHOD(miibus_writereg, aue_miibus_writereg), - DEVMETHOD(miibus_statchg, aue_miibus_statchg), - - { 0, 0 } -}; - -static driver_t aue_driver = { - "aue", - aue_methods, - sizeof(struct aue_softc) -}; - -static devclass_t aue_devclass; - -DRIVER_MODULE(aue, uhub, aue_driver, aue_devclass, usbd_driver_load, 0); -DRIVER_MODULE(miibus, aue, miibus_driver, miibus_devclass, 0, 0); - -#define AUE_SETBIT(sc, reg, x) \ - aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x)) - -#define AUE_CLRBIT(sc, reg, x) \ - aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x)) - -static int -aue_csr_read_1(struct aue_softc *sc, int reg) -{ - usb_device_request_t req; - usbd_status err; - u_int8_t val = 0; - - AUE_SXASSERTLOCKED(sc); - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = AUE_UR_READREG; - USETW(req.wValue, 0); - USETW(req.wIndex, reg); - USETW(req.wLength, 1); - - err = usbd_do_request(sc->aue_udev, &req, &val); - - if (err) { - return (0); - } - - return (val); -} - -static int -aue_csr_read_2(struct aue_softc *sc, int reg) -{ - usb_device_request_t req; - usbd_status err; - u_int16_t val = 0; - - AUE_SXASSERTLOCKED(sc); - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = AUE_UR_READREG; - USETW(req.wValue, 0); - USETW(req.wIndex, reg); - USETW(req.wLength, 2); - - err = usbd_do_request(sc->aue_udev, &req, &val); - - if (err) { - return (0); - } - - return (val); -} - -static int -aue_csr_write_1(struct aue_softc *sc, int reg, int val) -{ - usb_device_request_t req; - usbd_status err; - - AUE_SXASSERTLOCKED(sc); - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = AUE_UR_WRITEREG; - USETW(req.wValue, val); - USETW(req.wIndex, reg); - USETW(req.wLength, 1); - - err = usbd_do_request(sc->aue_udev, &req, &val); - - if (err) { - return (-1); - } - - return (0); -} - -static int -aue_csr_write_2(struct aue_softc *sc, int reg, int val) -{ - usb_device_request_t req; - usbd_status err; - - AUE_SXASSERTLOCKED(sc); - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = AUE_UR_WRITEREG; - USETW(req.wValue, val); - USETW(req.wIndex, reg); - USETW(req.wLength, 2); - - err = usbd_do_request(sc->aue_udev, &req, &val); - - if (err) { - return (-1); - } - - return (0); -} - -/* - * Read a word of data stored in the EEPROM at address 'addr.' - */ -static void -aue_eeprom_getword(struct aue_softc *sc, int addr, u_int16_t *dest) -{ - int i; - u_int16_t word = 0; - - aue_csr_write_1(sc, AUE_EE_REG, addr); - aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ); - - for (i = 0; i < AUE_TIMEOUT; i++) { - if (aue_csr_read_1(sc, AUE_EE_CTL) & AUE_EECTL_DONE) - break; - } - - if (i == AUE_TIMEOUT) { - printf("aue%d: EEPROM read timed out\n", - sc->aue_unit); - } - - word = aue_csr_read_2(sc, AUE_EE_DATA); - *dest = word; - - return; -} - -/* - * Read a sequence of words from the EEPROM. - */ -static void -aue_read_eeprom(struct aue_softc *sc, caddr_t dest, int off, int cnt, int swap) -{ - int i; - u_int16_t word = 0, *ptr; - - for (i = 0; i < cnt; i++) { - aue_eeprom_getword(sc, off + i, &word); - ptr = (u_int16_t *)(dest + (i * 2)); - if (swap) - *ptr = ntohs(word); - else - *ptr = word; - } - - return; -} - -static int -aue_miibus_readreg(device_t dev, int phy, int reg) -{ - struct aue_softc *sc = device_get_softc(dev); - int i; - u_int16_t val = 0; - - /* - * The Am79C901 HomePNA PHY actually contains - * two transceivers: a 1Mbps HomePNA PHY and a - * 10Mbps full/half duplex ethernet PHY with - * NWAY autoneg. However in the ADMtek adapter, - * only the 1Mbps PHY is actually connected to - * anything, so we ignore the 10Mbps one. It - * happens to be configured for MII address 3, - * so we filter that out. - */ - if (sc->aue_vendor == USB_VENDOR_ADMTEK && - sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) { - if (phy == 3) - return (0); -#ifdef notdef - if (phy != 1) - return (0); -#endif - } - - aue_csr_write_1(sc, AUE_PHY_ADDR, phy); - aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_READ); - - for (i = 0; i < AUE_TIMEOUT; i++) { - if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE) - break; - } - - if (i == AUE_TIMEOUT) { - printf("aue%d: MII read timed out\n", sc->aue_unit); - } - - val = aue_csr_read_2(sc, AUE_PHY_DATA); - - return (val); -} - -static int -aue_miibus_writereg(device_t dev, int phy, int reg, int data) -{ - struct aue_softc *sc = device_get_softc(dev); - int i; - - if (phy == 3) - return (0); - - aue_csr_write_2(sc, AUE_PHY_DATA, data); - aue_csr_write_1(sc, AUE_PHY_ADDR, phy); - aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_WRITE); - - for (i = 0; i < AUE_TIMEOUT; i++) { - if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE) - break; - } - - if (i == AUE_TIMEOUT) { - printf("aue%d: MII read timed out\n", - sc->aue_unit); - } - - return(0); -} - -static void -aue_miibus_statchg(device_t dev) -{ - struct aue_softc *sc = device_get_softc(dev); - struct mii_data *mii = GET_MII(sc); - - AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB); - if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) { - AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL); - } else { - AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL); - } - - if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) - AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX); - else - AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX); - - AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB); - - /* - * Set the LED modes on the LinkSys adapter. - * This turns on the 'dual link LED' bin in the auxmode - * register of the Broadcom PHY. - */ - if (sc->aue_flags & LSYS) { - u_int16_t auxmode; - auxmode = aue_miibus_readreg(dev, 0, 0x1b); - aue_miibus_writereg(dev, 0, 0x1b, auxmode | 0x04); - } - - return; -} - -#define AUE_BITS 6 - -static void -aue_setmulti(struct aue_softc *sc) -{ - struct ifnet *ifp; - struct ifmultiaddr *ifma; - u_int32_t h = 0, i; - u_int8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - - AUE_SXASSERTLOCKED(sc); - ifp = sc->aue_ifp; - - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { - AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); - return; - } - - AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); - - /* now program new ones */ - IF_ADDR_LOCK(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) - { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - h = ether_crc32_le(LLADDR((struct sockaddr_dl *) - ifma->ifma_addr), ETHER_ADDR_LEN) & ((1 << AUE_BITS) - 1); - hashtbl[(h >> 3)] |= 1 << (h & 0x7); - } - IF_ADDR_UNLOCK(ifp); - - /* write the hashtable */ - for (i = 0; i < 8; i++) - aue_csr_write_1(sc, AUE_MAR0 + i, hashtbl[i]); - - return; -} - -static void -aue_reset_pegasus_II(struct aue_softc *sc) -{ - /* Magic constants taken from Linux driver. */ - aue_csr_write_1(sc, AUE_REG_1D, 0); - aue_csr_write_1(sc, AUE_REG_7B, 2); -#if 0 - if ((sc->aue_flags & HAS_HOME_PNA) && mii_mode) - aue_csr_write_1(sc, AUE_REG_81, 6); - else -#endif - aue_csr_write_1(sc, AUE_REG_81, 2); -} - -static void -aue_reset(struct aue_softc *sc) -{ - int i; - - AUE_SXASSERTLOCKED(sc); - AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_RESETMAC); - - for (i = 0; i < AUE_TIMEOUT; i++) { - if (!(aue_csr_read_1(sc, AUE_CTL1) & AUE_CTL1_RESETMAC)) - break; - } - - if (i == AUE_TIMEOUT) - printf("aue%d: reset failed\n", sc->aue_unit); - - /* - * The PHY(s) attached to the Pegasus chip may be held - * in reset until we flip on the GPIO outputs. Make sure - * to set the GPIO pins high so that the PHY(s) will - * be enabled. - * - * Note: We force all of the GPIO pins low first, *then* - * enable the ones we want. - */ - aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0); - aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0|AUE_GPIO_SEL1); - - if (sc->aue_flags & LSYS) { - /* Grrr. LinkSys has to be different from everyone else. */ - aue_csr_write_1(sc, AUE_GPIO0, - AUE_GPIO_SEL0 | AUE_GPIO_SEL1); - aue_csr_write_1(sc, AUE_GPIO0, - AUE_GPIO_SEL0 | AUE_GPIO_SEL1 | AUE_GPIO_OUT0); - } - - if (sc->aue_flags & PII) - aue_reset_pegasus_II(sc); - - /* Wait a little while for the chip to get its brains in order. */ - DELAY(10000); - - return; -} - -/* - * Probe for a Pegasus chip. - */ -static int -aue_match(device_t self) -{ - struct usb_attach_arg *uaa = device_get_ivars(self); - - if (uaa->iface != NULL) - return (UMATCH_NONE); - - /* - * Belkin USB Bluetooth dongles of the F8T012xx1 model series conflict - * with older Belkin USB2LAN adapters. Skip if_aue if we detect one of - * the devices that look like Bluetooth adapters. - */ - if (uaa->vendor == USB_VENDOR_BELKIN && - uaa->product == USB_PRODUCT_BELKIN_F8T012 && uaa->release == 0x0413) - return (UMATCH_NONE); - - return (aue_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); -} - -/* - * Attach the interface. Allocate softc structures, do ifmedia - * setup and ethernet/BPF attach. - */ -static int -aue_attach(device_t self) -{ - struct aue_softc *sc = device_get_softc(self); - struct usb_attach_arg *uaa = device_get_ivars(self); - u_char eaddr[ETHER_ADDR_LEN]; - struct ifnet *ifp; - usbd_interface_handle iface; - usbd_status err; - usb_interface_descriptor_t *id; - usb_endpoint_descriptor_t *ed; - int i; - - sc->aue_dev = self; - sc->aue_udev = uaa->device; - sc->aue_unit = device_get_unit(self); - - if (usbd_set_config_no(sc->aue_udev, AUE_CONFIG_NO, 0)) { - device_printf(self, "getting interface handle failed\n"); - return ENXIO; - } - - err = usbd_device2interface_handle(uaa->device, AUE_IFACE_IDX, &iface); - if (err) { - device_printf(self, "getting interface handle failed\n"); - return ENXIO; - } - - sc->aue_iface = iface; - sc->aue_flags = aue_lookup(uaa->vendor, uaa->product)->aue_flags; - - sc->aue_product = uaa->product; - sc->aue_vendor = uaa->vendor; - - id = usbd_get_interface_descriptor(sc->aue_iface); - - /* Find endpoints. */ - for (i = 0; i < id->bNumEndpoints; i++) { - ed = usbd_interface2endpoint_descriptor(iface, i); - if (ed == NULL) { - device_printf(self, "couldn't get ep %d\n", i); - return ENXIO; - } - if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->aue_ed[AUE_ENDPT_RX] = ed->bEndpointAddress; - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->aue_ed[AUE_ENDPT_TX] = ed->bEndpointAddress; - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { - sc->aue_ed[AUE_ENDPT_INTR] = ed->bEndpointAddress; - } - } - - mtx_init(&sc->aue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); - sx_init(&sc->aue_sx, device_get_nameunit(self)); - TASK_INIT(&sc->aue_task, 0, aue_task, sc); - usb_ether_task_init(self, 0, &sc->aue_taskqueue); - AUE_SXLOCK(sc); - - /* Reset the adapter. */ - aue_reset(sc); - - /* - * Get station address from the EEPROM. - */ - aue_read_eeprom(sc, (caddr_t)&eaddr, 0, 3, 0); - - ifp = sc->aue_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(self, "can not if_alloc()\n"); - AUE_SXUNLOCK(sc); - mtx_destroy(&sc->aue_mtx); - sx_destroy(&sc->aue_sx); - usb_ether_task_destroy(&sc->aue_taskqueue); - return ENXIO; - } - ifp->if_softc = sc; - if_initname(ifp, "aue", sc->aue_unit); - ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = aue_ioctl; - ifp->if_start = aue_start; - ifp->if_init = aue_init; - IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); - ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; - IFQ_SET_READY(&ifp->if_snd); - - /* - * Do MII setup. - * NOTE: Doing this causes child devices to be attached to us, - * which we would normally disconnect at in the detach routine - * using device_delete_child(). However the USB code is set up - * such that when this driver is removed, all children devices - * are removed as well. In effect, the USB code ends up detaching - * all of our children for us, so we don't have to do is ourselves - * in aue_detach(). It's important to point this out since if - * we *do* try to detach the child devices ourselves, we will - * end up getting the children deleted twice, which will crash - * the system. - */ - if (mii_phy_probe(self, &sc->aue_miibus, - aue_ifmedia_upd, aue_ifmedia_sts)) { - device_printf(self, "MII without any PHY!\n"); - if_free(ifp); - AUE_SXUNLOCK(sc); - mtx_destroy(&sc->aue_mtx); - sx_destroy(&sc->aue_sx); - usb_ether_task_destroy(&sc->aue_taskqueue); - return ENXIO; - } - - sc->aue_qdat.ifp = ifp; - sc->aue_qdat.if_rxstart = aue_rxstart; - - /* - * Call MI attach routine. - */ - ether_ifattach(ifp, eaddr); - usb_register_netisr(); - sc->aue_dying = 0; - sc->aue_link = 1; - - AUE_SXUNLOCK(sc); - return 0; -} - -static int -aue_detach(device_t dev) -{ - struct aue_softc *sc; - struct ifnet *ifp; - - sc = device_get_softc(dev); - AUE_SXLOCK(sc); - ifp = sc->aue_ifp; - ether_ifdetach(ifp); - sc->aue_dying = 1; - AUE_SXUNLOCK(sc); - callout_drain(&sc->aue_tick_callout); - usb_ether_task_drain(&sc->aue_taskqueue, &sc->aue_task); - usb_ether_task_destroy(&sc->aue_taskqueue); - if_free(ifp); - - if (sc->aue_ep[AUE_ENDPT_TX] != NULL) - usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_TX]); - if (sc->aue_ep[AUE_ENDPT_RX] != NULL) - usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_RX]); -#ifdef AUE_INTR_PIPE - if (sc->aue_ep[AUE_ENDPT_INTR] != NULL) - usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_INTR]); -#endif - - mtx_destroy(&sc->aue_mtx); - sx_destroy(&sc->aue_sx); - - return (0); -} - -static void -aue_rxstart(struct ifnet *ifp) -{ - struct aue_softc *sc = ifp->if_softc; - aue_task_sched(sc, AUE_TASK_RXSTART); -} - -static void -aue_rxstart_thread(struct aue_softc *sc) -{ - struct ue_chain *c; - struct ifnet *ifp; - - ifp = sc->aue_ifp; - - sc = ifp->if_softc; - AUE_SXASSERTLOCKED(sc); - c = &sc->aue_cdata.ue_rx_chain[sc->aue_cdata.ue_rx_prod]; - - c->ue_mbuf = usb_ether_newbuf(); - if (c->ue_mbuf == NULL) { - device_printf(sc->aue_dev, "no memory for rx list -- packet " - "dropped!\n"); - ifp->if_ierrors++; - AUE_UNLOCK(sc); - return; - } - - /* Setup new transfer. */ - usbd_setup_xfer(c->ue_xfer, sc->aue_ep[AUE_ENDPT_RX], - c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, aue_rxeof); - usbd_transfer(c->ue_xfer); - - return; -} - -/* - * A frame has been uploaded: pass the resulting mbuf chain up to - * the higher level protocols. - */ -static void -aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct ue_chain *c = priv; - c->ue_status = status; - aue_task_sched(c->ue_sc, AUE_TASK_RXEOF); -} - -static void -aue_rxeof_thread(struct aue_softc *sc) -{ - struct ue_chain *c = &(sc->aue_cdata.ue_rx_chain[0]); - struct mbuf *m; - struct ifnet *ifp; - int total_len = 0; - struct aue_rxpkt r; - usbd_status status = c->ue_status; - - - AUE_SXASSERTLOCKED(sc); - ifp = sc->aue_ifp; - - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - return; - } - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - return; - } - if (usbd_ratecheck(&sc->aue_rx_notice)) - device_printf(sc->aue_dev, "usb error on rx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]); - goto done; - } - - usbd_get_xfer_status(c->ue_xfer, NULL, NULL, &total_len, NULL); - - if (total_len <= 4 + ETHER_CRC_LEN) { - ifp->if_ierrors++; - goto done; - } - - m = c->ue_mbuf; - bcopy(mtod(m, char *) + total_len - 4, (char *)&r, sizeof(r)); - - /* Turn off all the non-error bits in the rx status word. */ - r.aue_rxstat &= AUE_RXSTAT_MASK; - - if (r.aue_rxstat) { - ifp->if_ierrors++; - goto done; - } - - /* No errors; receive the packet. */ - total_len -= (4 + ETHER_CRC_LEN); - - ifp->if_ipackets++; - m->m_pkthdr.rcvif = (void *)&sc->aue_qdat; - m->m_pkthdr.len = m->m_len = total_len; - - /* Put the packet on the special USB input queue. */ - usb_ether_input(m); - return; -done: - - /* Setup new transfer. */ - usbd_setup_xfer(c->ue_xfer, sc->aue_ep[AUE_ENDPT_RX], - c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, aue_rxeof); - usbd_transfer(c->ue_xfer); - - return; -} - -/* - * A frame was downloaded to the chip. It's safe for us to clean up - * the list buffers. - */ - -static void -aue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct ue_chain *c = priv; - c->ue_status = status; - aue_task_sched(c->ue_sc, AUE_TASK_TXEOF); -} - -static void -aue_txeof_thread(struct aue_softc *sc) -{ - struct ue_chain *c = &(sc->aue_cdata.ue_tx_chain[0]); - struct ifnet *ifp; - usbd_status err, status; - - AUE_SXASSERTLOCKED(sc); - status = c->ue_status; - ifp = sc->aue_ifp; - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - return; - } - device_printf(sc->aue_dev, "usb error on tx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_TX]); - return; - } - - sc->aue_timer = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err); - - if (c->ue_mbuf != NULL) { - c->ue_mbuf->m_pkthdr.rcvif = ifp; - usb_tx_done(c->ue_mbuf); - c->ue_mbuf = NULL; - } - - if (err) - ifp->if_oerrors++; - else - ifp->if_opackets++; - - return; -} - -static void -aue_tick(void *xsc) -{ - struct aue_softc *sc = xsc; - - aue_task_sched(sc, AUE_TASK_TICK); -} - -static void -aue_tick_thread(struct aue_softc *sc) -{ - struct ifnet *ifp; - struct mii_data *mii; - - AUE_SXASSERTLOCKED(sc); - ifp = sc->aue_ifp; - /* - * If a timer is set (non-zero) then decrement it - * and if it hits zero, then call the watchdog routine. - */ - if (sc->aue_timer != 0 && --sc->aue_timer == 0) { - aue_watchdog(sc); - } - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - return; - } - - mii = GET_MII(sc); - if (mii == NULL) { - goto resched; - } - - mii_tick(mii); - if (!sc->aue_link && mii->mii_media_status & IFM_ACTIVE && - IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { - sc->aue_link++; - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - aue_start_thread(sc); - } -resched: - (void) callout_reset(&sc->aue_tick_callout, hz, aue_tick, sc); - return; -} - -static int -aue_encap(struct aue_softc *sc, struct mbuf *m, int idx) -{ - int total_len; - struct ue_chain *c; - usbd_status err; - - AUE_SXASSERTLOCKED(sc); - - c = &sc->aue_cdata.ue_tx_chain[idx]; - - /* - * Copy the mbuf data into a contiguous buffer, leaving two - * bytes at the beginning to hold the frame length. - */ - m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf + 2); - c->ue_mbuf = m; - - total_len = m->m_pkthdr.len + 2; - - /* - * The ADMtek documentation says that the packet length is - * supposed to be specified in the first two bytes of the - * transfer, however it actually seems to ignore this info - * and base the frame size on the bulk transfer length. - */ - c->ue_buf[0] = (u_int8_t)m->m_pkthdr.len; - c->ue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8); - - usbd_setup_xfer(c->ue_xfer, sc->aue_ep[AUE_ENDPT_TX], - c, c->ue_buf, total_len, USBD_FORCE_SHORT_XFER, - 10000, aue_txeof); - - /* Transmit */ - err = usbd_transfer(c->ue_xfer); - if (err != USBD_IN_PROGRESS) { - aue_stop(sc); - return (EIO); - } - - sc->aue_cdata.ue_tx_cnt++; - - return (0); -} - - -static void -aue_start(struct ifnet *ifp) -{ - struct aue_softc *sc = ifp->if_softc; - aue_task_sched(sc, AUE_TASK_START); -} - -static void -aue_start_thread(struct aue_softc *sc) -{ - struct ifnet *ifp = sc->aue_ifp; - struct mbuf *m_head = NULL; - - AUE_SXASSERTLOCKED(sc); - - if (!sc->aue_link) { - return; - } - - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) { - return; - } - - IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) { - return; - } - - if (aue_encap(sc, m_head, 0)) { - IFQ_DRV_PREPEND(&ifp->if_snd, m_head); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - return; - } - - /* - * If there's a BPF listener, bounce a copy of this frame - * to him. - */ - BPF_MTAP(ifp, m_head); - - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - - /* - * Set a timeout in case the chip goes out to lunch. - */ - sc->aue_timer = 5; - - return; -} - -static void -aue_init(void *xsc) -{ - struct aue_softc *sc = xsc; - - AUE_SXLOCK(sc); - aue_init_body(sc); - AUE_SXUNLOCK(sc); -} - -static void -aue_init_body(struct aue_softc *sc) -{ - struct ifnet *ifp = sc->aue_ifp; - struct mii_data *mii = GET_MII(sc); - struct ue_chain *c; - usbd_status err; - int i; - - AUE_SXASSERTLOCKED(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - return; - } - - /* - * Cancel pending I/O and free all RX/TX buffers. - */ - aue_reset(sc); - - /* Set MAC address */ - for (i = 0; i < ETHER_ADDR_LEN; i++) - aue_csr_write_1(sc, AUE_PAR0 + i, IF_LLADDR(sc->aue_ifp)[i]); - - /* If we want promiscuous mode, set the allframes bit. */ - if (ifp->if_flags & IFF_PROMISC) - AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); - else - AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); - - /* Init TX ring. */ - if (usb_ether_tx_list_init(sc, &sc->aue_cdata, - sc->aue_udev) == ENOBUFS) { - device_printf(sc->aue_dev, "tx list init failed\n"); - return; - } - - /* Init RX ring. */ - if (usb_ether_rx_list_init(sc, &sc->aue_cdata, - sc->aue_udev) == ENOBUFS) { - device_printf(sc->aue_dev, "rx list init failed\n"); - return; - } - - - /* Load the multicast filter. */ - aue_setmulti(sc); - - /* Enable RX and TX */ - aue_csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND | AUE_CTL0_RX_ENB); - AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_TX_ENB); - AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_EP3_CLR); - - mii_mediachg(mii); - - /* Open RX and TX pipes. */ - err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_RX], - USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_RX]); - if (err) { - device_printf(sc->aue_dev, "open rx pipe failed: %s\n", - usbd_errstr(err)); - return; - } - err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_TX], - USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_TX]); - if (err) { - device_printf(sc->aue_dev, "open tx pipe failed: %s\n", - usbd_errstr(err)); - return; - } - - - /* Start up the receive pipe. */ - for (i = 0; i < UE_RX_LIST_CNT; i++) { - c = &sc->aue_cdata.ue_rx_chain[i]; - usbd_setup_xfer(c->ue_xfer, sc->aue_ep[AUE_ENDPT_RX], - c, mtod(c->ue_mbuf, char *), UE_BUFSZ, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, aue_rxeof); - usbd_transfer(c->ue_xfer); - } - - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - callout_init(&sc->aue_tick_callout, CALLOUT_MPSAFE); - (void) callout_reset(&sc->aue_tick_callout, hz, aue_tick, sc); - return; -} - -/* - * Set media options. - */ -static int -aue_ifmedia_upd(struct ifnet *ifp) -{ - struct aue_softc *sc = ifp->if_softc; - struct mii_data *mii = GET_MII(sc); - - sc->aue_link = 0; - if (mii->mii_instance) { - struct mii_softc *miisc; - LIST_FOREACH(miisc, &mii->mii_phys, mii_list) - mii_phy_reset(miisc); - } - mii_mediachg(mii); - sc->aue_link = 1; - - return (0); -} - -/* - * Report current media status. - */ -static void -aue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) -{ - struct aue_softc *sc = ifp->if_softc; - struct mii_data *mii = GET_MII(sc); - - mii_pollstat(mii); - ifmr->ifm_active = mii->mii_media_active; - ifmr->ifm_status = mii->mii_media_status; - - return; -} - -static int -aue_ioctl(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct aue_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; - struct mii_data *mii; - int error = 0; - - /* - * This prevents recursion in the interface while it's - * being torn down. - */ - if (sc->aue_dying) - return(0); - - AUE_GIANTLOCK(); - - switch(command) { - case SIOCSIFFLAGS: - AUE_SXLOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING && - ifp->if_flags & IFF_PROMISC && - !(sc->aue_if_flags & IFF_PROMISC)) { - AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - sc->aue_if_flags & IFF_PROMISC) { - AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); - } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - aue_init_body(sc); - } - sc->aue_dying = 0; - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - aue_stop(sc); - } - sc->aue_if_flags = ifp->if_flags; - AUE_SXUNLOCK(sc); - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - AUE_SXLOCK(sc); - aue_setmulti(sc); - AUE_SXUNLOCK(sc); - break; - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: - AUE_SXLOCK(sc); - mii = GET_MII(sc); - error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); - AUE_SXUNLOCK(sc); - break; - default: - error = ether_ioctl(ifp, command, data); - break; - } - - AUE_GIANTUNLOCK(); - - return (error); -} - -static void -aue_watchdog(struct aue_softc *sc) -{ - struct ifnet *ifp = sc->aue_ifp; - struct ue_chain *c; - usbd_status stat; - - AUE_SXASSERTLOCKED(sc); - ifp->if_oerrors++; - device_printf(sc->aue_dev, "watchdog timeout\n"); - - c = &sc->aue_cdata.ue_tx_chain[0]; - usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat); - c->ue_status = stat; - aue_txeof_thread(sc); - - if (!IFQ_IS_EMPTY(&ifp->if_snd)) - aue_start_thread(sc); - return; -} - -/* - * Stop the adapter and free any mbufs allocated to the - * RX and TX lists. - */ -static void -aue_stop(struct aue_softc *sc) -{ - usbd_status err; - struct ifnet *ifp; - - AUE_SXASSERTLOCKED(sc); - ifp = sc->aue_ifp; - sc->aue_timer = 0; - - aue_csr_write_1(sc, AUE_CTL0, 0); - aue_csr_write_1(sc, AUE_CTL1, 0); - aue_reset(sc); - sc->aue_dying = 1; - - /* Stop transfers. */ - if (sc->aue_ep[AUE_ENDPT_RX] != NULL) { - err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_RX]); - if (err) { - device_printf(sc->aue_dev, - "abort rx pipe failed: %s\n", usbd_errstr(err)); - } - err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_RX]); - if (err) { - device_printf(sc->aue_dev, - "close rx pipe failed: %s\n", usbd_errstr(err)); - } - sc->aue_ep[AUE_ENDPT_RX] = NULL; - } - - if (sc->aue_ep[AUE_ENDPT_TX] != NULL) { - err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_TX]); - if (err) { - device_printf(sc->aue_dev, - "abort tx pipe failed: %s\n", usbd_errstr(err)); - } - err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_TX]); - if (err) { - device_printf(sc->aue_dev, - "close tx pipe failed: %s\n", usbd_errstr(err)); - } - sc->aue_ep[AUE_ENDPT_TX] = NULL; - } - -#ifdef AUE_INTR_PIPE - if (sc->aue_ep[AUE_ENDPT_INTR] != NULL) { - err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_INTR]); - if (err) { - device_printf(sc->aue_dev, - "abort intr pipe failed: %s\n", usbd_errstr(err)); - } - err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_INTR]); - if (err) { - device_printf(sc->aue_dev, - "close intr pipe failed: %s\n", usbd_errstr(err)); - } - sc->aue_ep[AUE_ENDPT_INTR] = NULL; - } -#endif - - /* Free RX resources. */ - usb_ether_rx_list_free(&sc->aue_cdata); - /* Free TX resources. */ - usb_ether_tx_list_free(&sc->aue_cdata); - -#ifdef AUE_INTR_PIPE - free(sc->aue_cdata.ue_ibuf, M_USBDEV); - sc->aue_cdata.ue_ibuf = NULL; -#endif - - sc->aue_link = 0; - - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - - return; -} - -/* - * Stop all chip I/O so that the kernel's probe routines don't - * get confused by errant DMAs when rebooting. - */ -static int -aue_shutdown(device_t dev) -{ - struct aue_softc *sc; - - sc = device_get_softc(dev); - AUE_SXLOCK(sc); - sc->aue_dying++; - aue_reset(sc); - aue_stop(sc); - AUE_SXUNLOCK(sc); - - return (0); -} - -static void -aue_task_sched(struct aue_softc *sc, int task) -{ - - AUE_LOCK(sc); - sc->aue_deferedtasks |= task; - usb_ether_task_enqueue(&sc->aue_taskqueue, &sc->aue_task); - AUE_UNLOCK(sc); -} - -/* - * We defer all interrupt operations to this function. - * - * This allows us to do more complex operations, such as synchronous - * usb io that normally would not be allowed from interrupt context. - */ -static void -aue_task(void *arg, int pending) -{ - struct aue_softc *sc = arg; - int tasks; - - for ( ;; ) { - AUE_LOCK(sc); - tasks = sc->aue_deferedtasks; - sc->aue_deferedtasks = 0; - AUE_UNLOCK(sc); - - if (tasks == 0) - break; - - AUE_GIANTLOCK(); // XXX: usb not giant safe - AUE_SXLOCK(sc); - if (sc->aue_dying) { - AUE_SXUNLOCK(sc); - break; - } - if ((tasks & AUE_TASK_TICK) != 0) { - aue_tick_thread(sc); - } - if ((tasks & AUE_TASK_START) != 0) { - aue_start_thread(sc); - } - if ((tasks & AUE_TASK_RXSTART) != 0) { - aue_rxstart_thread(sc); - } - if ((tasks & AUE_TASK_RXEOF) != 0) { - aue_rxeof_thread(sc); - } - if ((tasks & AUE_TASK_TXEOF) != 0) { - aue_txeof_thread(sc); - } - AUE_SXUNLOCK(sc); - AUE_GIANTUNLOCK(); // XXX: usb not giant safe - } -} - diff --git a/sys/legacy/dev/usb/if_auereg.h b/sys/legacy/dev/usb/if_auereg.h deleted file mode 100644 index 18cc0f4..0000000 --- a/sys/legacy/dev/usb/if_auereg.h +++ /dev/null @@ -1,294 +0,0 @@ -/*- - * Copyright (c) 1997, 1998, 1999 - * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. - * - * Copyright (c) 2006 - * Alfred Perlstein <alfred@freebsd.org>. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD - * 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. - * - * $FreeBSD$ - */ - -/* - * Register definitions for ADMtek Pegasus AN986 USB to Ethernet - * chip. The Pegasus uses a total of four USB endpoints: the control - * endpoint (0), a bulk read endpoint for receiving packets (1), - * a bulk write endpoint for sending packets (2) and an interrupt - * endpoint for passing RX and TX status (3). Endpoint 0 is used - * to read and write the ethernet module's registers. All registers - * are 8 bits wide. - * - * Packet transfer is done in 64 byte chunks. The last chunk in a - * transfer is denoted by having a length less that 64 bytes. For - * the RX case, the data includes an optional RX status word. - */ - -#ifndef AUEREG_H -#define AUEREG_H - -#define AUE_UR_READREG 0xF0 -#define AUE_UR_WRITEREG 0xF1 - -#define AUE_CONFIG_NO 1 -#define AUE_IFACE_IDX 0 - -/* - * Note that while the ADMtek technically has four - * endpoints, the control endpoint (endpoint 0) is - * regarded as special by the USB code and drivers - * don't have direct access to it. (We access it - * using usbd_do_request() when reading/writing - * registers.) Consequently, our endpoint indexes - * don't match those in the ADMtek Pegasus manual: - * we consider the RX data endpoint to be index 0 - * and work up from there. - */ -#define AUE_ENDPT_RX 0x0 -#define AUE_ENDPT_TX 0x1 -#define AUE_ENDPT_INTR 0x2 -#define AUE_ENDPT_MAX 0x3 - -#define AUE_INTR_PKTLEN 0x8 - -#define AUE_CTL0 0x00 -#define AUE_CTL1 0x01 -#define AUE_CTL2 0x02 -#define AUE_MAR0 0x08 -#define AUE_MAR1 0x09 -#define AUE_MAR2 0x0A -#define AUE_MAR3 0x0B -#define AUE_MAR4 0x0C -#define AUE_MAR5 0x0D -#define AUE_MAR6 0x0E -#define AUE_MAR7 0x0F -#define AUE_MAR AUE_MAR0 -#define AUE_PAR0 0x10 -#define AUE_PAR1 0x11 -#define AUE_PAR2 0x12 -#define AUE_PAR3 0x13 -#define AUE_PAR4 0x14 -#define AUE_PAR5 0x15 -#define AUE_PAR AUE_PAR0 -#define AUE_PAUSE0 0x18 -#define AUE_PAUSE1 0x19 -#define AUE_PAUSE AUE_PAUSE0 -#define AUE_RX_FLOWCTL_CNT 0x1A -#define AUE_RX_FLOWCTL_FIFO 0x1B -#define AUE_REG_1D 0x1D -#define AUE_EE_REG 0x20 -#define AUE_EE_DATA0 0x21 -#define AUE_EE_DATA1 0x22 -#define AUE_EE_DATA AUE_EE_DATA0 -#define AUE_EE_CTL 0x23 -#define AUE_PHY_ADDR 0x25 -#define AUE_PHY_DATA0 0x26 -#define AUE_PHY_DATA1 0x27 -#define AUE_PHY_DATA AUE_PHY_DATA0 -#define AUE_PHY_CTL 0x28 -#define AUE_USB_STS 0x2A -#define AUE_TXSTAT0 0x2B -#define AUE_TXSTAT1 0x2C -#define AUE_TXSTAT AUE_TXSTAT0 -#define AUE_RXSTAT 0x2D -#define AUE_PKTLOST0 0x2E -#define AUE_PKTLOST1 0x2F -#define AUE_PKTLOST AUE_PKTLOST0 - -#define AUE_REG_7B 0x7B -#define AUE_GPIO0 0x7E -#define AUE_GPIO1 0x7F -#define AUE_REG_81 0x81 - -#define AUE_CTL0_INCLUDE_RXCRC 0x01 -#define AUE_CTL0_ALLMULTI 0x02 -#define AUE_CTL0_STOP_BACKOFF 0x04 -#define AUE_CTL0_RXSTAT_APPEND 0x08 -#define AUE_CTL0_WAKEON_ENB 0x10 -#define AUE_CTL0_RXPAUSE_ENB 0x20 -#define AUE_CTL0_RX_ENB 0x40 -#define AUE_CTL0_TX_ENB 0x80 - -#define AUE_CTL1_HOMELAN 0x04 -#define AUE_CTL1_RESETMAC 0x08 -#define AUE_CTL1_SPEEDSEL 0x10 /* 0 = 10mbps, 1 = 100mbps */ -#define AUE_CTL1_DUPLEX 0x20 /* 0 = half, 1 = full */ -#define AUE_CTL1_DELAYHOME 0x40 - -#define AUE_CTL2_EP3_CLR 0x01 /* reading EP3 clrs status regs */ -#define AUE_CTL2_RX_BADFRAMES 0x02 -#define AUE_CTL2_RX_PROMISC 0x04 -#define AUE_CTL2_LOOPBACK 0x08 -#define AUE_CTL2_EEPROMWR_ENB 0x10 -#define AUE_CTL2_EEPROM_LOAD 0x20 - -#define AUE_EECTL_WRITE 0x01 -#define AUE_EECTL_READ 0x02 -#define AUE_EECTL_DONE 0x04 - -#define AUE_PHYCTL_PHYREG 0x1F -#define AUE_PHYCTL_WRITE 0x20 -#define AUE_PHYCTL_READ 0x40 -#define AUE_PHYCTL_DONE 0x80 - -#define AUE_USBSTS_SUSPEND 0x01 -#define AUE_USBSTS_RESUME 0x02 - -#define AUE_TXSTAT0_JABTIMO 0x04 -#define AUE_TXSTAT0_CARLOSS 0x08 -#define AUE_TXSTAT0_NOCARRIER 0x10 -#define AUE_TXSTAT0_LATECOLL 0x20 -#define AUE_TXSTAT0_EXCESSCOLL 0x40 -#define AUE_TXSTAT0_UNDERRUN 0x80 - -#define AUE_TXSTAT1_PKTCNT 0x0F -#define AUE_TXSTAT1_FIFO_EMPTY 0x40 -#define AUE_TXSTAT1_FIFO_FULL 0x80 - -#define AUE_RXSTAT_OVERRUN 0x01 -#define AUE_RXSTAT_PAUSE 0x02 - -#define AUE_GPIO_IN0 0x01 -#define AUE_GPIO_OUT0 0x02 -#define AUE_GPIO_SEL0 0x04 -#define AUE_GPIO_IN1 0x08 -#define AUE_GPIO_OUT1 0x10 -#define AUE_GPIO_SEL1 0x20 - -struct aue_intrpkt { - u_int8_t aue_txstat0; - u_int8_t aue_txstat1; - u_int8_t aue_rxstat; - u_int8_t aue_rxlostpkt0; - u_int8_t aue_rxlostpkt1; - u_int8_t aue_wakeupstat; - u_int8_t aue_rsvd; -}; - -struct aue_rxpkt { - u_int16_t aue_pktlen; - u_int8_t aue_rxstat; -}; - -#define AUE_RXSTAT_MCAST 0x01 -#define AUE_RXSTAT_GIANT 0x02 -#define AUE_RXSTAT_RUNT 0x04 -#define AUE_RXSTAT_CRCERR 0x08 -#define AUE_RXSTAT_DRIBBLE 0x10 -#define AUE_RXSTAT_MASK 0x1E - -#define AUE_INC(x, y) (x) = (x + 1) % y - -struct aue_softc { -#if defined(__FreeBSD__) -#define GET_MII(sc) (device_get_softc((sc)->aue_miibus)) -#elif defined(__NetBSD__) -#define GET_MII(sc) (&(sc)->aue_mii) -#elif defined(__OpenBSD__) -#define GET_MII(sc) (&(sc)->aue_mii) -#endif - struct ifnet *aue_ifp; - device_t aue_dev; - device_t aue_miibus; - usbd_device_handle aue_udev; - usbd_interface_handle aue_iface; - u_int16_t aue_vendor; - u_int16_t aue_product; - int aue_ed[AUE_ENDPT_MAX]; - usbd_pipe_handle aue_ep[AUE_ENDPT_MAX]; - int aue_unit; - u_int8_t aue_link; - int aue_timer; - int aue_if_flags; - struct ue_cdata aue_cdata; - struct callout aue_tick_callout; - struct usb_taskqueue aue_taskqueue; - struct task aue_task; - struct mtx aue_mtx; - struct sx aue_sx; - u_int16_t aue_flags; - char aue_dying; - struct timeval aue_rx_notice; - struct usb_qdat aue_qdat; - int aue_deferedtasks; -}; - -#if 0 -/* - * Some debug code to make sure we don't take a blocking lock in - * interrupt context. - */ -#include <sys/types.h> -#include <sys/proc.h> -#include <sys/kdb.h> - -#define AUE_DUMPSTATE(tag) aue_dumpstate(__func__, tag) - -static inline void -aue_dumpstate(const char *func, const char *tag) -{ - if ((curthread->td_pflags & TDP_NOSLEEPING) || - (curthread->td_pflags & TDP_ITHREAD)) { - kdb_backtrace(); - printf("%s: %s sleep: %sok ithread: %s\n", func, tag, - curthread->td_pflags & TDP_NOSLEEPING ? "not" : "", - curthread->td_pflags & TDP_ITHREAD ? "yes" : "no"); - } -} -#else -#define AUE_DUMPSTATE(tag) -#endif - -#define AUE_LOCK(_sc) mtx_lock(&(_sc)->aue_mtx) -#define AUE_UNLOCK(_sc) mtx_unlock(&(_sc)->aue_mtx) -#define AUE_SXLOCK(_sc) \ - do { AUE_DUMPSTATE("sxlock"); sx_xlock(&(_sc)->aue_sx); } while(0) -#define AUE_SXUNLOCK(_sc) sx_xunlock(&(_sc)->aue_sx) -#define AUE_SXASSERTLOCKED(_sc) sx_assert(&(_sc)->aue_sx, SX_XLOCKED) -#define AUE_SXASSERTUNLOCKED(_sc) sx_assert(&(_sc)->aue_sx, SX_UNLOCKED) - -#define AUE_TIMEOUT 1000 -#define AUE_MIN_FRAMELEN 60 -#define AUE_INTR_INTERVAL 100 /* ms */ - -/* - * These bits are used to notify the task about pending events. - * The names correspond to the interrupt context routines that would - * be normally called. (example: AUE_TASK_WATCHDOG -> aue_watchdog()) - */ -#define AUE_TASK_WATCHDOG 0x0001 -#define AUE_TASK_TICK 0x0002 -#define AUE_TASK_START 0x0004 -#define AUE_TASK_RXSTART 0x0008 -#define AUE_TASK_RXEOF 0x0010 -#define AUE_TASK_TXEOF 0x0020 - -#define AUE_GIANTLOCK() mtx_lock(&Giant); -#define AUE_GIANTUNLOCK() mtx_unlock(&Giant); - -#endif /* !AUEREG_H */ diff --git a/sys/legacy/dev/usb/if_axe.c b/sys/legacy/dev/usb/if_axe.c deleted file mode 100644 index 65da32b..0000000 --- a/sys/legacy/dev/usb/if_axe.c +++ /dev/null @@ -1,1428 +0,0 @@ -/*- - * Copyright (c) 1997, 1998, 1999, 2000-2003 - * Bill Paul <wpaul@windriver.com>. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver. - * Used in the LinkSys USB200M and various other adapters. - * - * Manuals available from: - * http://www.asix.com.tw/datasheet/mac/Ax88172.PDF - * Note: you need the manual for the AX88170 chip (USB 1.x ethernet - * controller) to find the definitions for the RX control register. - * http://www.asix.com.tw/datasheet/mac/Ax88170.PDF - * - * Written by Bill Paul <wpaul@windriver.com> - * Senior Engineer - * Wind River Systems - */ - -/* - * The AX88172 provides USB ethernet supports at 10 and 100Mbps. - * It uses an external PHY (reference designs use a RealTek chip), - * and has a 64-bit multicast hash filter. There is some information - * missing from the manual which one needs to know in order to make - * the chip function: - * - * - You must set bit 7 in the RX control register, otherwise the - * chip won't receive any packets. - * - You must initialize all 3 IPG registers, or you won't be able - * to send any packets. - * - * Note that this device appears to only support loading the station - * address via autload from the EEPROM (i.e. there's no way to manaully - * set it). - * - * (Adam Weinberger wanted me to name this driver if_gir.c.) - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/endian.h> -#include <sys/sockio.h> -#include <sys/mbuf.h> -#include <sys/malloc.h> -#include <sys/lock.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/socket.h> -#include <sys/sx.h> - -#include <net/if.h> -#include <net/if_arp.h> -#include <net/ethernet.h> -#include <net/if_dl.h> -#include <net/if_media.h> -#include <net/if_types.h> - -#include <net/bpf.h> - -#include <sys/bus.h> -#include <machine/bus.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdivar.h> -#include "usbdevs.h" -#include <dev/usb/usb_ethersubr.h> - -#include <dev/mii/mii.h> -#include <dev/mii/miivar.h> - -/* "device miibus" required. See GENERIC if you get errors here. */ -#include "miibus_if.h" - -/* - * AXE_178_MAX_FRAME_BURST - * max frame burst size for Ax88178 and Ax88772 - * 0 2048 bytes - * 1 4096 bytes - * 2 8192 bytes - * 3 16384 bytes - * use the largest your system can handle without usb stalling. - * - * NB: 88772 parts appear to generate lots of input errors with - * a 2K rx buffer and 8K is only slightly faster than 4K on an - * EHCI port on a T42 so change at your own risk. - */ -#define AXE_178_MAX_FRAME_BURST 1 - -#include <dev/usb/if_axereg.h> - -/* - * Various supported device vendors/products. - */ -const struct axe_type axe_devs[] = { - { { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UF200}, 0 }, - { { USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2}, 0 }, - { { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ETHERNET}, AX772 }, - { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172}, 0 }, - { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772}, AX772 }, - { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178}, AX178 }, - { { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T}, 0 }, - { { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055 }, AX178 }, - { { USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR}, 0}, - { { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB200MV2}, AX772 }, - { { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB2_TX }, 0}, - { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100}, 0 }, - { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1 }, AX772 }, - { { USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E}, 0 }, - { { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETGUS2 }, AX178 }, - { { USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1}, 0 }, - { { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M}, 0 }, - { { USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB1000 }, AX178 }, - { { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX}, 0 }, - { { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120}, 0 }, - { { USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01PLUS }, AX772 }, - { { USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GU1000T }, AX178 }, - { { USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL}, 0 }, - { { USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029}, 0 }, - { { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028 }, AX178 } -}; - -#define axe_lookup(v, p) ((const struct axe_type *)usb_lookup(axe_devs, v, p)) - -static device_probe_t axe_match; -static device_attach_t axe_attach; -static device_detach_t axe_detach; -static device_shutdown_t axe_shutdown; -static miibus_readreg_t axe_miibus_readreg; -static miibus_writereg_t axe_miibus_writereg; -static miibus_statchg_t axe_miibus_statchg; - -static int axe_encap(struct axe_softc *, struct mbuf *, int); -static void axe_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void axe_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void axe_tick(void *); -static void axe_tick_task(void *); -static void axe_start(struct ifnet *); -static int axe_ioctl(struct ifnet *, u_long, caddr_t); -static void axe_init(void *); -static void axe_stop(struct axe_softc *); -static void axe_watchdog(struct ifnet *); -static int axe_cmd(struct axe_softc *, int, int, int, void *); -static int axe_ifmedia_upd(struct ifnet *); -static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *); - -static void axe_setmulti(struct axe_softc *); - -static device_method_t axe_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, axe_match), - DEVMETHOD(device_attach, axe_attach), - DEVMETHOD(device_detach, axe_detach), - DEVMETHOD(device_shutdown, axe_shutdown), - - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - - /* MII interface */ - DEVMETHOD(miibus_readreg, axe_miibus_readreg), - DEVMETHOD(miibus_writereg, axe_miibus_writereg), - DEVMETHOD(miibus_statchg, axe_miibus_statchg), - - { 0, 0 } -}; - -static driver_t axe_driver = { - "axe", - axe_methods, - sizeof(struct axe_softc) -}; - -static devclass_t axe_devclass; - -DRIVER_MODULE(axe, uhub, axe_driver, axe_devclass, usbd_driver_load, 0); -DRIVER_MODULE(miibus, axe, miibus_driver, miibus_devclass, 0, 0); -MODULE_DEPEND(axe, usb, 1, 1, 1); -MODULE_DEPEND(axe, miibus, 1, 1, 1); - -static int -axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf) -{ - usb_device_request_t req; - usbd_status err; - - AXE_SLEEPLOCKASSERT(sc); - if (sc->axe_dying) - return(0); - - if (AXE_CMD_DIR(cmd)) - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - else - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = AXE_CMD_CMD(cmd); - USETW(req.wValue, val); - USETW(req.wIndex, index); - USETW(req.wLength, AXE_CMD_LEN(cmd)); - - err = usbd_do_request(sc->axe_udev, &req, buf); - - if (err) - return(-1); - - return(0); -} - -static int -axe_miibus_readreg(device_t dev, int phy, int reg) -{ - struct axe_softc *sc = device_get_softc(dev); - usbd_status err; - u_int16_t val; - - if (sc->axe_dying) - return(0); - - AXE_SLEEPLOCKASSERT(sc); -#ifdef notdef - /* - * The chip tells us the MII address of any supported - * PHYs attached to the chip, so only read from those. - */ - - if (sc->axe_phyaddrs[0] != AXE_NOPHY && phy != sc->axe_phyaddrs[0]) - return (0); - - if (sc->axe_phyaddrs[1] != AXE_NOPHY && phy != sc->axe_phyaddrs[1]) - return (0); -#endif - if (sc->axe_phyaddrs[0] != 0xFF && sc->axe_phyaddrs[0] != phy) - return (0); - - AXE_LOCK(sc); - axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); - err = axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, (void *)&val); - axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); - AXE_UNLOCK(sc); - - if (err) { - device_printf(sc->axe_dev, "read PHY failed\n"); - return(-1); - } - - if (val && val != 0xffff) - sc->axe_phyaddrs[0] = phy; - - return (le16toh(val)); -} - -static int -axe_miibus_writereg(device_t dev, int phy, int reg, int val) -{ - struct axe_softc *sc = device_get_softc(dev); - usbd_status err; - - if (sc->axe_dying) - return(0); - - AXE_SLEEPLOCKASSERT(sc); - AXE_LOCK(sc); - axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); - val = htole32(val); - err = axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, (void *)&val); - axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); - AXE_UNLOCK(sc); - - if (err) { - device_printf(sc->axe_dev, "write PHY failed\n"); - return(-1); - } - - return (0); -} - -static void -axe_miibus_statchg(device_t dev) -{ - struct axe_softc *sc = device_get_softc(dev); - struct mii_data *mii = GET_MII(sc); - int val, err; - - val = (mii->mii_media_active & IFM_GMASK) == IFM_FDX ? - AXE_MEDIA_FULL_DUPLEX : 0; - if (sc->axe_flags & (AX178|AX772)) { - val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC; - - switch (IFM_SUBTYPE(mii->mii_media_active)) { - case IFM_1000_T: - val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK; - break; - case IFM_100_TX: - val |= AXE_178_MEDIA_100TX; - break; - case IFM_10_T: - /* doesn't need to be handled */ - break; - } - } - err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL); - if (err) - device_printf(dev, "media change failed, error %d\n", err); -} - -/* - * Set media options. - */ -static int -axe_ifmedia_upd(struct ifnet *ifp) -{ - struct axe_softc *sc = ifp->if_softc; - struct mii_data *mii = GET_MII(sc); - - sc->axe_link = 0; - if (mii->mii_instance) { - struct mii_softc *miisc; - LIST_FOREACH(miisc, &mii->mii_phys, mii_list) - mii_phy_reset(miisc); - } - mii_mediachg(mii); - - return (0); -} - -/* - * Report current media status. - */ -static void -axe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) -{ - struct axe_softc *sc = ifp->if_softc; - struct mii_data *mii = GET_MII(sc); - - mii_pollstat(mii); - ifmr->ifm_active = mii->mii_media_active; - ifmr->ifm_status = mii->mii_media_status; - - return; -} - -static void -axe_setmulti(struct axe_softc *sc) -{ - struct ifnet *ifp; - struct ifmultiaddr *ifma; - u_int32_t h = 0; - u_int16_t rxmode; - u_int8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - - ifp = sc->axe_ifp; - - AXE_LOCK(sc); - axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, (void *)&rxmode); - rxmode = le16toh(rxmode); - - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { - rxmode |= AXE_RXCMD_ALLMULTI; - axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); - AXE_UNLOCK(sc); - return; - } else - rxmode &= ~AXE_RXCMD_ALLMULTI; - - IF_ADDR_LOCK(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) - { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - h = ether_crc32_be(LLADDR((struct sockaddr_dl *) - ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; - hashtbl[h / 8] |= 1 << (h % 8); - } - IF_ADDR_UNLOCK(ifp); - - axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, (void *)&hashtbl); - axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); - AXE_UNLOCK(sc); - - return; -} - -static void -axe_ax88178_init(struct axe_softc *sc) -{ - int gpio0 = 0, phymode = 0; - u_int16_t eeprom; - - axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL); - /* XXX magic */ - axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom); - eeprom = le16toh(eeprom); - axe_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL); - - /* if EEPROM is invalid we have to use to GPIO0 */ - if (eeprom == 0xffff) { - phymode = 0; - gpio0 = 1; - } else { - phymode = eeprom & 7; - gpio0 = (eeprom & 0x80) ? 0 : 1; - } - - axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x008c, NULL); - usbd_delay_ms(sc->axe_udev, 40); - if ((eeprom >> 8) != 1) { - axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL); - usbd_delay_ms(sc->axe_udev, 30); - - axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x001c, NULL); - usbd_delay_ms(sc->axe_udev, 300); - - axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL); - usbd_delay_ms(sc->axe_udev, 30); - } else { - axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x0004, NULL); - usbd_delay_ms(sc->axe_udev, 30); - axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x000c, NULL); - usbd_delay_ms(sc->axe_udev, 30); - } - - /* soft reset */ - axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 0, NULL); - usbd_delay_ms(sc->axe_udev, 150); - axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, - AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL); - usbd_delay_ms(sc->axe_udev, 150); - axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); -} - -static void -axe_ax88772_init(struct axe_softc *sc) -{ - axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL); - usbd_delay_ms(sc->axe_udev, 40); - - if (sc->axe_phyaddrs[1] == AXE_INTPHY) { - /* ask for embedded PHY */ - axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL); - usbd_delay_ms(sc->axe_udev, 10); - - /* power down and reset state, pin reset state */ - axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); - usbd_delay_ms(sc->axe_udev, 60); - - /* power down/reset state, pin operating state */ - axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, - AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); - usbd_delay_ms(sc->axe_udev, 150); - - /* power up, reset */ - axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL); - - /* power up, operating */ - axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, - AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL); - } else { - /* ask for external PHY */ - axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x00, NULL); - usbd_delay_ms(sc->axe_udev, 10); - - /* power down/reset state, pin operating state */ - axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, - AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); - } - - usbd_delay_ms(sc->axe_udev, 150); - axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); -} - -static void -axe_reset(struct axe_softc *sc) -{ - if (sc->axe_dying) - return; - - if (usbd_set_config_no(sc->axe_udev, AXE_CONFIG_NO, 1) || - usbd_device2interface_handle(sc->axe_udev, AXE_IFACE_IDX, - &sc->axe_iface)) { - device_printf(sc->axe_dev, "getting interface handle failed\n"); - } - - /* Wait a little while for the chip to get its brains in order. */ - DELAY(1000); - return; -} - -/* - * Probe for a AX88172 chip. - */ -static int -axe_match(device_t self) -{ - struct usb_attach_arg *uaa = device_get_ivars(self); - - if (!uaa->iface) - return(UMATCH_NONE); - return (axe_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); -} - -/* - * Attach the interface. Allocate softc structures, do ifmedia - * setup and ethernet/BPF attach. - */ -static int -axe_attach(device_t self) -{ - struct axe_softc *sc = device_get_softc(self); - struct usb_attach_arg *uaa = device_get_ivars(self); - const struct axe_type *type; - u_char eaddr[ETHER_ADDR_LEN]; - struct ifnet *ifp; - usb_interface_descriptor_t *id; - usb_endpoint_descriptor_t *ed; - int i; - - sc->axe_udev = uaa->device; - sc->axe_dev = self; - type = axe_lookup(uaa->vendor, uaa->product); - if (type != NULL) - sc->axe_flags = type->axe_flags; - - if (usbd_set_config_no(sc->axe_udev, AXE_CONFIG_NO, 1)) { - device_printf(sc->axe_dev, "getting interface handle failed\n"); - return ENXIO; - } - - usb_init_task(&sc->axe_tick_task, axe_tick_task, sc); - - if (usbd_device2interface_handle(uaa->device, - AXE_IFACE_IDX, &sc->axe_iface)) { - device_printf(sc->axe_dev, "getting interface handle failed\n"); - return ENXIO; - } - - sc->axe_boundary = 64; - if (sc->axe_flags & (AX178|AX772)) { - if (sc->axe_udev->speed == USB_SPEED_HIGH) { - sc->axe_bufsz = AXE_178_MAX_BUFSZ; - sc->axe_boundary = 512; - } else - sc->axe_bufsz = AXE_178_MIN_BUFSZ; - } else - sc->axe_bufsz = AXE_172_BUFSZ; -{ /* XXX debug */ -device_printf(sc->axe_dev, "%s, bufsz %d, boundary %d\n", - sc->axe_flags & AX178 ? "AX88178" : - sc->axe_flags & AX772 ? "AX88772" : "AX88172", - sc->axe_bufsz, sc->axe_boundary); -} - - id = usbd_get_interface_descriptor(sc->axe_iface); - - /* Find endpoints. */ - for (i = 0; i < id->bNumEndpoints; i++) { - ed = usbd_interface2endpoint_descriptor(sc->axe_iface, i); - if (!ed) { - device_printf(sc->axe_dev, "couldn't get ep %d\n", i); - return ENXIO; - } - if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->axe_ed[AXE_ENDPT_RX] = ed->bEndpointAddress; - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->axe_ed[AXE_ENDPT_TX] = ed->bEndpointAddress; - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { - sc->axe_ed[AXE_ENDPT_INTR] = ed->bEndpointAddress; - } - } - - mtx_init(&sc->axe_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); - sx_init(&sc->axe_sleeplock, device_get_nameunit(self)); - AXE_SLEEPLOCK(sc); - AXE_LOCK(sc); - - /* We need the PHYID for the init dance in some cases */ - axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, (void *)&sc->axe_phyaddrs); - - if (sc->axe_flags & AX178) - axe_ax88178_init(sc); - else if (sc->axe_flags & AX772) - axe_ax88772_init(sc); - - /* - * Get station address. - */ - if (sc->axe_flags & (AX178|AX772)) - axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, &eaddr); - else - axe_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, &eaddr); - - /* - * Fetch IPG values. - */ - axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, (void *)&sc->axe_ipgs); - - /* - * Work around broken adapters that appear to lie about - * their PHY addresses. - */ - sc->axe_phyaddrs[0] = sc->axe_phyaddrs[1] = 0xFF; - - ifp = sc->axe_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(sc->axe_dev, "can not if_alloc()\n"); - AXE_UNLOCK(sc); - AXE_SLEEPUNLOCK(sc); - sx_destroy(&sc->axe_sleeplock); - mtx_destroy(&sc->axe_mtx); - return ENXIO; - } - ifp->if_softc = sc; - if_initname(ifp, "axe", device_get_unit(sc->axe_dev)); - ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSGIANT; - ifp->if_ioctl = axe_ioctl; - ifp->if_start = axe_start; - ifp->if_watchdog = axe_watchdog; - ifp->if_init = axe_init; - IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); - ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; - IFQ_SET_READY(&ifp->if_snd); - - if (mii_phy_probe(self, &sc->axe_miibus, - axe_ifmedia_upd, axe_ifmedia_sts)) { - device_printf(sc->axe_dev, "MII without any PHY!\n"); - if_free(ifp); - AXE_UNLOCK(sc); - AXE_SLEEPUNLOCK(sc); - sx_destroy(&sc->axe_sleeplock); - mtx_destroy(&sc->axe_mtx); - return ENXIO; - } - - /* - * Call MI attach routine. - */ - - ether_ifattach(ifp, eaddr); - callout_handle_init(&sc->axe_stat_ch); - usb_register_netisr(); - - sc->axe_dying = 0; - - AXE_UNLOCK(sc); - AXE_SLEEPUNLOCK(sc); - - return 0; -} - -static int -axe_detach(device_t dev) -{ - struct axe_softc *sc; - struct ifnet *ifp; - - sc = device_get_softc(dev); - AXE_LOCK(sc); - ifp = sc->axe_ifp; - - sc->axe_dying = 1; - untimeout(axe_tick, sc, sc->axe_stat_ch); - usb_rem_task(sc->axe_udev, &sc->axe_tick_task); - - ether_ifdetach(ifp); - if_free(ifp); - - if (sc->axe_ep[AXE_ENDPT_TX] != NULL) - usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_TX]); - if (sc->axe_ep[AXE_ENDPT_RX] != NULL) - usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_RX]); - if (sc->axe_ep[AXE_ENDPT_INTR] != NULL) - usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]); - - AXE_UNLOCK(sc); - sx_destroy(&sc->axe_sleeplock); - mtx_destroy(&sc->axe_mtx); - - return(0); -} - -static int -axe_rx_list_init(struct axe_softc *sc) -{ - struct axe_cdata *cd; - struct axe_chain *c; - int i; - - cd = &sc->axe_cdata; - for (i = 0; i < AXE_RX_LIST_CNT; i++) { - c = &cd->axe_rx_chain[i]; - c->axe_sc = sc; - c->axe_idx = i; - c->axe_mbuf = NULL; - if (c->axe_xfer == NULL) { - c->axe_xfer = usbd_alloc_xfer(sc->axe_udev); - if (c->axe_xfer == NULL) - return (ENOBUFS); - c->axe_buf = usbd_alloc_buffer(c->axe_xfer, - sc->axe_bufsz); - if (c->axe_buf == NULL) { - usbd_free_xfer(c->axe_xfer); - return (ENOBUFS); - } - } - } - - return (0); -} - -static void -axe_rx_list_free(struct axe_softc *sc) -{ - int i; - - for (i = 0; i < AXE_RX_LIST_CNT; i++) { - if (sc->axe_cdata.axe_rx_chain[i].axe_mbuf != NULL) { - m_freem(sc->axe_cdata.axe_rx_chain[i].axe_mbuf); - sc->axe_cdata.axe_rx_chain[i].axe_mbuf = NULL; - } - if (sc->axe_cdata.axe_rx_chain[i].axe_xfer != NULL) { - usbd_free_xfer(sc->axe_cdata.axe_rx_chain[i].axe_xfer); - sc->axe_cdata.axe_rx_chain[i].axe_xfer = NULL; - } - } -} - -static int -axe_tx_list_init(struct axe_softc *sc) -{ - struct axe_cdata *cd; - struct axe_chain *c; - int i; - - cd = &sc->axe_cdata; - for (i = 0; i < AXE_TX_LIST_CNT; i++) { - c = &cd->axe_tx_chain[i]; - c->axe_sc = sc; - c->axe_idx = i; - c->axe_mbuf = NULL; - if (c->axe_xfer == NULL) { - c->axe_xfer = usbd_alloc_xfer(sc->axe_udev); - if (c->axe_xfer == NULL) - return (ENOBUFS); - c->axe_buf = usbd_alloc_buffer(c->axe_xfer, - sc->axe_bufsz); - if (c->axe_buf == NULL) { - usbd_free_xfer(c->axe_xfer); - return (ENOBUFS); - } - } - } - - return (0); -} - -static void -axe_tx_list_free(struct axe_softc *sc) -{ - int i; - - /* Free TX resources. */ - for (i = 0; i < AXE_TX_LIST_CNT; i++) { - if (sc->axe_cdata.axe_tx_chain[i].axe_mbuf != NULL) { - m_freem(sc->axe_cdata.axe_tx_chain[i].axe_mbuf); - sc->axe_cdata.axe_tx_chain[i].axe_mbuf = NULL; - } - if (sc->axe_cdata.axe_tx_chain[i].axe_xfer != NULL) { - usbd_free_xfer(sc->axe_cdata.axe_tx_chain[i].axe_xfer); - sc->axe_cdata.axe_tx_chain[i].axe_xfer = NULL; - } - } -} - -/* - * A frame has been uploaded: pass the resulting mbuf chain up to - * the higher level protocols. - */ -static void -axe_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct axe_softc *sc; - struct axe_chain *c = (struct axe_chain *) priv; - struct mbuf *m; - u_char *buf; - struct ifnet *ifp; - struct axe_sframe_hdr *hdr; - int total_len = 0; - int pktlen = 0; - - sc = c->axe_sc; - AXE_LOCK(sc); - ifp = sc->axe_ifp; - - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - AXE_UNLOCK(sc); - return; - } - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - AXE_UNLOCK(sc); - return; - } - if (usbd_ratecheck(&sc->axe_rx_notice)) - device_printf(sc->axe_dev, "usb error on rx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall(sc->axe_ep[AXE_ENDPT_RX]); - goto done; - } - - usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); - - buf = c->axe_buf; - - do { - if (sc->axe_flags & (AX178|AX772)) { - if (total_len < sizeof(struct axe_sframe_hdr)) { - ifp->if_ierrors++; - goto done; - } - if ((pktlen % 2) != 0) - pktlen++; - buf += pktlen; - - hdr = (struct axe_sframe_hdr *) buf; - total_len -= sizeof(struct axe_sframe_hdr); - if ((hdr->len ^ hdr->ilen) != 0xffff) { - ifp->if_ierrors++; - goto done; - } - pktlen = le16toh(hdr->len); - if (pktlen > total_len) { - ifp->if_ierrors++; - goto done; - } - - buf += sizeof(struct axe_sframe_hdr); - total_len -= pktlen + (pktlen % 2); - } else { - pktlen = total_len; - total_len = 0; - } - - if (pktlen < sizeof(struct ether_header)) { - ifp->if_ierrors++; - goto done; - } - m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (m == NULL) { - ifp->if_ierrors++; - goto done; - } - m->m_data += ETHER_ALIGN; - memcpy(mtod(m, void *), buf, pktlen); - m->m_pkthdr.len = m->m_len = pktlen; - m->m_pkthdr.rcvif = ifp; - - ifp->if_input(ifp, m); - ifp->if_ipackets++; - } while (total_len > 0); - /* fall thru... */ -done: - /* Setup new transfer. */ - usbd_setup_xfer(xfer, sc->axe_ep[AXE_ENDPT_RX], - c, c->axe_buf, sc->axe_bufsz, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, axe_rxeof); - usbd_transfer(xfer); - AXE_UNLOCK(sc); - - return; -} - -/* - * A frame was downloaded to the chip. It's safe for us to clean up - * the list buffers. - */ - -static void -axe_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct axe_softc *sc; - struct axe_chain *c; - struct ifnet *ifp; - usbd_status err; - - c = priv; - sc = c->axe_sc; - AXE_LOCK(sc); - ifp = sc->axe_ifp; - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - AXE_UNLOCK(sc); - return; - } - device_printf(sc->axe_dev, "usb error on tx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall(sc->axe_ep[AXE_ENDPT_TX]); - AXE_UNLOCK(sc); - return; - } - - ifp->if_timer = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &err); - - if (c->axe_mbuf != NULL) { - m_freem(c->axe_mbuf); - c->axe_mbuf = NULL; - } - - if (err) - ifp->if_oerrors++; - else - ifp->if_opackets++; - - AXE_UNLOCK(sc); - - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - axe_start(ifp); - - return; -} - -static void -axe_tick(void *xsc) -{ - struct axe_softc *sc = xsc; - - if (sc == NULL) - return; - if (sc->axe_dying) - return; - - /* Perform periodic stuff in process context */ - usb_add_task(sc->axe_udev, &sc->axe_tick_task, USB_TASKQ_DRIVER); -} - -static void -axe_tick_task(void *xsc) -{ - struct axe_softc *sc; - struct ifnet *ifp; - struct mii_data *mii; - - sc = xsc; - - if (sc == NULL) - return; - - AXE_SLEEPLOCK(sc); - AXE_LOCK(sc); - - ifp = sc->axe_ifp; - mii = GET_MII(sc); - if (mii == NULL) { - AXE_UNLOCK(sc); - AXE_SLEEPUNLOCK(sc); - return; - } - - mii_tick(mii); - if (!sc->axe_link && mii->mii_media_status & IFM_ACTIVE && - IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { - sc->axe_link++; - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - axe_start(ifp); - } - - sc->axe_stat_ch = timeout(axe_tick, sc, hz); - - AXE_UNLOCK(sc); - AXE_SLEEPUNLOCK(sc); - - return; -} - -static int -axe_encap(struct axe_softc *sc, struct mbuf *m, int idx) -{ - struct axe_chain *c; - usbd_status err; - struct axe_sframe_hdr hdr; - int length; - - c = &sc->axe_cdata.axe_tx_chain[idx]; - - /* - * Copy the mbuf data into a contiguous buffer, leaving two - * bytes at the beginning to hold the frame length. - */ - if (sc->axe_flags & (AX178|AX772)) { - hdr.len = htole16(m->m_pkthdr.len); - hdr.ilen = ~hdr.len; - - memcpy(c->axe_buf, &hdr, sizeof(hdr)); - length = sizeof(hdr); - - m_copydata(m, 0, m->m_pkthdr.len, c->axe_buf + length); - length += m->m_pkthdr.len; - - if ((length % sc->axe_boundary) == 0) { - hdr.len = 0; - hdr.ilen = 0xffff; - memcpy(c->axe_buf + length, &hdr, sizeof(hdr)); - length += sizeof(hdr); - } - } else { - m_copydata(m, 0, m->m_pkthdr.len, c->axe_buf); - length = m->m_pkthdr.len; - } - c->axe_mbuf = m; - - usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_TX], - c, c->axe_buf, length, USBD_FORCE_SHORT_XFER, 10000, axe_txeof); - - /* Transmit */ - err = usbd_transfer(c->axe_xfer); - if (err != USBD_IN_PROGRESS) { - /* XXX probably don't want to sleep here */ - AXE_SLEEPLOCK(sc); - axe_stop(sc); - AXE_SLEEPUNLOCK(sc); - return(EIO); - } - - sc->axe_cdata.axe_tx_cnt++; - - return(0); -} - -static void -axe_start(struct ifnet *ifp) -{ - struct axe_softc *sc; - struct mbuf *m_head = NULL; - - sc = ifp->if_softc; - AXE_LOCK(sc); - - if (!sc->axe_link) { - AXE_UNLOCK(sc); - return; - } - - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) { - AXE_UNLOCK(sc); - return; - } - - IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) { - AXE_UNLOCK(sc); - return; - } - - if (axe_encap(sc, m_head, 0)) { - IFQ_DRV_PREPEND(&ifp->if_snd, m_head); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - AXE_UNLOCK(sc); - return; - } - - /* - * If there's a BPF listener, bounce a copy of this frame - * to him. - */ - BPF_MTAP(ifp, m_head); - - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - - /* - * Set a timeout in case the chip goes out to lunch. - */ - ifp->if_timer = 5; - AXE_UNLOCK(sc); - - return; -} - -static void -axe_init(void *xsc) -{ - struct axe_softc *sc = xsc; - struct ifnet *ifp = sc->axe_ifp; - struct axe_chain *c; - usbd_status err; - int i; - int rxmode; - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - return; - - AXE_SLEEPLOCK(sc); - AXE_LOCK(sc); - - /* - * Cancel pending I/O and free all RX/TX buffers. - */ - - axe_reset(sc); - -#ifdef notdef - /* Set MAC address */ - axe_mac(sc, IF_LLADDR(sc->axe_ifp), 1); -#endif - - /* Enable RX logic. */ - - /* Init TX ring. */ - if (axe_tx_list_init(sc) == ENOBUFS) { - device_printf(sc->axe_dev, "tx list init failed\n"); - AXE_UNLOCK(sc); - AXE_SLEEPUNLOCK(sc); - return; - } - - /* Init RX ring. */ - if (axe_rx_list_init(sc) == ENOBUFS) { - device_printf(sc->axe_dev, "rx list init failed\n"); - AXE_UNLOCK(sc); - AXE_SLEEPUNLOCK(sc); - return; - } - - /* Set transmitter IPG values */ - if (sc->axe_flags & (AX178|AX772)) { - axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->axe_ipgs[2], - (sc->axe_ipgs[1]<<8) | sc->axe_ipgs[0], NULL); - } else { - axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->axe_ipgs[0], NULL); - axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->axe_ipgs[1], NULL); - axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL); - } - - /* Enable receiver, set RX mode */ - rxmode = AXE_RXCMD_MULTICAST|AXE_RXCMD_ENABLE; - if (sc->axe_flags & (AX178|AX772)) { - if (sc->axe_bufsz == AXE_178_MAX_BUFSZ) - rxmode |= AXE_178_RXCMD_MFB; - } else - rxmode |= AXE_172_RXCMD_UNICAST; - - /* If we want promiscuous mode, set the allframes bit. */ - if (ifp->if_flags & IFF_PROMISC) - rxmode |= AXE_RXCMD_PROMISC; - - if (ifp->if_flags & IFF_BROADCAST) - rxmode |= AXE_RXCMD_BROADCAST; - - axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); - - /* Load the multicast filter. */ - axe_setmulti(sc); - - /* Open RX and TX pipes. */ - err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_RX], - USBD_EXCLUSIVE_USE, &sc->axe_ep[AXE_ENDPT_RX]); - if (err) { - device_printf(sc->axe_dev, "open rx pipe failed: %s\n", - usbd_errstr(err)); - AXE_UNLOCK(sc); - AXE_SLEEPUNLOCK(sc); - return; - } - - err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_TX], - USBD_EXCLUSIVE_USE, &sc->axe_ep[AXE_ENDPT_TX]); - if (err) { - device_printf(sc->axe_dev, "open tx pipe failed: %s\n", - usbd_errstr(err)); - AXE_UNLOCK(sc); - AXE_SLEEPUNLOCK(sc); - return; - } - - /* Start up the receive pipe. */ - for (i = 0; i < AXE_RX_LIST_CNT; i++) { - c = &sc->axe_cdata.axe_rx_chain[i]; - usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_RX], - c, c->axe_buf, sc->axe_bufsz, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, axe_rxeof); - usbd_transfer(c->axe_xfer); - } - - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - AXE_UNLOCK(sc); - AXE_SLEEPUNLOCK(sc); - - sc->axe_stat_ch = timeout(axe_tick, sc, hz); - - return; -} - -static int -axe_ioctl(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct axe_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; - struct mii_data *mii; - u_int16_t rxmode; - int error = 0; - - switch(command) { - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING && - ifp->if_flags & IFF_PROMISC && - !(sc->axe_if_flags & IFF_PROMISC)) { - AXE_SLEEPLOCK(sc); - AXE_LOCK(sc); - axe_cmd(sc, AXE_CMD_RXCTL_READ, - 0, 0, (void *)&rxmode); - rxmode = le16toh(rxmode); - rxmode |= AXE_RXCMD_PROMISC; - axe_cmd(sc, AXE_CMD_RXCTL_WRITE, - 0, rxmode, NULL); - AXE_UNLOCK(sc); - axe_setmulti(sc); - AXE_SLEEPUNLOCK(sc); - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - sc->axe_if_flags & IFF_PROMISC) { - AXE_SLEEPLOCK(sc); - AXE_LOCK(sc); - axe_cmd(sc, AXE_CMD_RXCTL_READ, - 0, 0, (void *)&rxmode); - rxmode = le16toh(rxmode); - rxmode &= ~AXE_RXCMD_PROMISC; - axe_cmd(sc, AXE_CMD_RXCTL_WRITE, - 0, rxmode, NULL); - AXE_UNLOCK(sc); - axe_setmulti(sc); - AXE_SLEEPUNLOCK(sc); - } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - axe_init(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - AXE_SLEEPLOCK(sc); - axe_stop(sc); - AXE_SLEEPUNLOCK(sc); - } - } - sc->axe_if_flags = ifp->if_flags; - error = 0; - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - AXE_SLEEPLOCK(sc); - axe_setmulti(sc); - AXE_SLEEPUNLOCK(sc); - error = 0; - break; - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: - AXE_SLEEPLOCK(sc); - mii = GET_MII(sc); - error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); - AXE_SLEEPUNLOCK(sc); - break; - - default: - error = ether_ioctl(ifp, command, data); - break; - } - - return(error); -} - -static void -axe_watchdog(struct ifnet *ifp) -{ - struct axe_softc *sc; - struct axe_chain *c; - usbd_status stat; - - sc = ifp->if_softc; - AXE_LOCK(sc); - - ifp->if_oerrors++; - device_printf(sc->axe_dev, "watchdog timeout\n"); - - c = &sc->axe_cdata.axe_tx_chain[0]; - usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &stat); - axe_txeof(c->axe_xfer, c, stat); - - AXE_UNLOCK(sc); - - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - axe_start(ifp); - - return; -} - -/* - * Stop the adapter and free any mbufs allocated to the - * RX and TX lists. - */ -static void -axe_stop(struct axe_softc *sc) -{ - usbd_status err; - struct ifnet *ifp; - - AXE_SLEEPLOCKASSERT(sc); - AXE_LOCK(sc); - - ifp = sc->axe_ifp; - ifp->if_timer = 0; - - untimeout(axe_tick, sc, sc->axe_stat_ch); - - /* Stop transfers. */ - if (sc->axe_ep[AXE_ENDPT_RX] != NULL) { - err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_RX]); - if (err) { - device_printf(sc->axe_dev, "abort rx pipe failed: %s\n", - usbd_errstr(err)); - } - err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_RX]); - if (err) { - device_printf(sc->axe_dev, "close rx pipe failed: %s\n", - usbd_errstr(err)); - } - sc->axe_ep[AXE_ENDPT_RX] = NULL; - } - - if (sc->axe_ep[AXE_ENDPT_TX] != NULL) { - err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_TX]); - if (err) { - device_printf(sc->axe_dev, "abort tx pipe failed: %s\n", - usbd_errstr(err)); - } - err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_TX]); - if (err) { - device_printf(sc->axe_dev, "close tx pipe failed: %s\n", - usbd_errstr(err)); - } - sc->axe_ep[AXE_ENDPT_TX] = NULL; - } - - if (sc->axe_ep[AXE_ENDPT_INTR] != NULL) { - err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]); - if (err) { - device_printf(sc->axe_dev, - "abort intr pipe failed: %s\n", usbd_errstr(err)); - } - err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_INTR]); - if (err) { - device_printf(sc->axe_dev, - "close intr pipe failed: %s\n", usbd_errstr(err)); - } - sc->axe_ep[AXE_ENDPT_INTR] = NULL; - } - - axe_reset(sc); - - /* Free RX resources. */ - axe_rx_list_free(sc); - /* Free TX resources. */ - axe_tx_list_free(sc); - - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - sc->axe_link = 0; - AXE_UNLOCK(sc); - - return; -} - -/* - * Stop all chip I/O so that the kernel's probe routines don't - * get confused by errant DMAs when rebooting. - */ -static int -axe_shutdown(device_t dev) -{ - struct axe_softc *sc; - - sc = device_get_softc(dev); - - AXE_SLEEPLOCK(sc); - axe_stop(sc); - AXE_SLEEPUNLOCK(sc); - - return (0); -} diff --git a/sys/legacy/dev/usb/if_axereg.h b/sys/legacy/dev/usb/if_axereg.h deleted file mode 100644 index 4503b19..0000000 --- a/sys/legacy/dev/usb/if_axereg.h +++ /dev/null @@ -1,254 +0,0 @@ -/*- - * Copyright (c) 1997, 1998, 1999, 2000-2003 - * Bill Paul <wpaul@windriver.com>. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD - * 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. - * - * $FreeBSD$ - */ - -/* - * Definitions for the ASIX Electronics AX88172 to ethernet controller. - */ - - -/* - * Vendor specific commands - * ASIX conveniently doesn't document the 'set NODEID' command in their - * datasheet (thanks a lot guys). - * To make handling these commands easier, I added some extra data - * which is decided by the axe_cmd() routine. Commands are encoded - * in 16 bites, with the format: LDCC. L and D are both nibbles in - * the high byte. L represents the data length (0 to 15) and D - * represents the direction (0 for vendor read, 1 for vendor write). - * CC is the command byte, as specified in the manual. - */ - -#define AXE_CMD_DIR(x) (((x) & 0x0F00) >> 8) -#define AXE_CMD_LEN(x) (((x) & 0xF000) >> 12) -#define AXE_CMD_CMD(x) ((x) & 0x00FF) - -#define AXE_172_CMD_READ_RXTX_SRAM 0x2002 -#define AXE_182_CMD_READ_RXTX_SRAM 0x8002 -#define AXE_172_CMD_WRITE_RX_SRAM 0x0103 -#define AXE_172_CMD_WRITE_TX_SRAM 0x0104 -#define AXE_182_CMD_WRITE_RXTX_SRAM 0x8103 -#define AXE_CMD_MII_OPMODE_SW 0x0106 -#define AXE_CMD_MII_READ_REG 0x2007 -#define AXE_CMD_MII_WRITE_REG 0x2108 -#define AXE_CMD_MII_READ_OPMODE 0x1009 -#define AXE_CMD_MII_OPMODE_HW 0x010A -#define AXE_CMD_SROM_READ 0x200B -#define AXE_CMD_SROM_WRITE 0x010C -#define AXE_CMD_SROM_WR_ENABLE 0x010D -#define AXE_CMD_SROM_WR_DISABLE 0x010E -#define AXE_CMD_RXCTL_READ 0x200F -#define AXE_CMD_RXCTL_WRITE 0x0110 -#define AXE_CMD_READ_IPG012 0x3011 -#define AXE_172_CMD_WRITE_IPG0 0x0112 -#define AXE_172_CMD_WRITE_IPG1 0x0113 -#define AXE_172_CMD_WRITE_IPG2 0x0114 -#define AXE_178_CMD_WRITE_IPG012 0x0112 -#define AXE_CMD_READ_MCAST 0x8015 -#define AXE_CMD_WRITE_MCAST 0x8116 -#define AXE_172_CMD_READ_NODEID 0x6017 -#define AXE_172_CMD_WRITE_NODEID 0x6118 -#define AXE_178_CMD_READ_NODEID 0x6013 -#define AXE_178_CMD_WRITE_NODEID 0x6114 -#define AXE_CMD_READ_PHYID 0x2019 -#define AXE_172_CMD_READ_MEDIA 0x101A -#define AXE_178_CMD_READ_MEDIA 0x201A -#define AXE_CMD_WRITE_MEDIA 0x011B -#define AXE_CMD_READ_MONITOR_MODE 0x101C -#define AXE_CMD_WRITE_MONITOR_MODE 0x011D -#define AXE_CMD_READ_GPIO 0x101E -#define AXE_CMD_WRITE_GPIO 0x011F -#define AXE_CMD_SW_RESET_REG 0x0120 -#define AXE_CMD_SW_PHY_STATUS 0x0021 -#define AXE_CMD_SW_PHY_SELECT 0x0122 - -#define AXE_SW_RESET_CLEAR 0x00 -#define AXE_SW_RESET_RR 0x01 -#define AXE_SW_RESET_RT 0x02 -#define AXE_SW_RESET_PRTE 0x04 -#define AXE_SW_RESET_PRL 0x08 -#define AXE_SW_RESET_BZ 0x10 -#define AXE_SW_RESET_IPRL 0x20 -#define AXE_SW_RESET_IPPD 0x40 - -/* AX88178 documentation says to always write this bit... */ -#define AXE_178_RESET_MAGIC 0x40 - -#define AXE_178_MEDIA_GMII 0x0001 -#define AXE_MEDIA_FULL_DUPLEX 0x0002 -#define AXE_172_MEDIA_TX_ABORT_ALLOW 0x0004 -/* AX88178/88772 documentation says to always write 1 to bit 2 */ -#define AXE_178_MEDIA_MAGIC 0x0004 -/* AX88772 documentation says to always write 0 to bit 3 */ -#define AXE_178_MEDIA_ENCK 0x0008 -#define AXE_172_MEDIA_FLOW_CONTROL_EN 0x0010 -#define AXE_178_MEDIA_RXFLOW_CONTROL_EN 0x0010 -#define AXE_178_MEDIA_TXFLOW_CONTROL_EN 0x0020 -#define AXE_178_MEDIA_JUMBO_EN 0x0040 -#define AXE_178_MEDIA_LTPF_ONLY 0x0080 -#define AXE_178_MEDIA_RX_EN 0x0100 -#define AXE_178_MEDIA_100TX 0x0200 -#define AXE_178_MEDIA_SBP 0x0800 -#define AXE_178_MEDIA_SUPERMAC 0x1000 - -#define AXE_RXCMD_PROMISC 0x0001 -#define AXE_RXCMD_ALLMULTI 0x0002 -#define AXE_172_RXCMD_UNICAST 0x0004 -#define AXE_178_RXCMD_KEEP_INVALID_CRC 0x0004 -#define AXE_RXCMD_BROADCAST 0x0008 -#define AXE_RXCMD_MULTICAST 0x0010 -#define AXE_178_RXCMD_AP 0x0020 -#define AXE_RXCMD_ENABLE 0x0080 -#define AXE_178_RXCMD_MFB_2048 0x0000 /* 2K max frame burst */ -#define AXE_178_RXCMD_MFB_4096 0x0100 /* 4K max frame burst */ -#define AXE_178_RXCMD_MFB_8192 0x0200 /* 8K max frame burst */ -#define AXE_178_RXCMD_MFB_16384 0x0300 /* 16K max frame burst*/ - -#define AXE_NOPHY 0xE0 -#define AXE_INTPHY 0x10 - -#define AXE_TIMEOUT 1000 -#define AXE_172_BUFSZ 1536 -#define AXE_178_MIN_BUFSZ 2048 -#define AXE_MIN_FRAMELEN 60 -#define AXE_RX_FRAMES 1 -#define AXE_TX_FRAMES 1 - -#if AXE_178_MAX_FRAME_BURST == 0 -#define AXE_178_RXCMD_MFB AXE_178_RXCMD_MFB_2048 -#define AXE_178_MAX_BUFSZ 2048 -#elif AXE_178_MAX_FRAME_BURST == 1 -#define AXE_178_RXCMD_MFB AXE_178_RXCMD_MFB_4096 -#define AXE_178_MAX_BUFSZ 4096 -#elif AXE_178_MAX_FRAME_BURST == 2 -#define AXE_178_RXCMD_MFB AXE_178_RXCMD_MFB_8192 -#define AXE_178_MAX_BUFSZ 8192 -#else -#define AXE_178_RXCMD_MFB AXE_178_RXCMD_MFB_16384 -#define AXE_178_MAX_BUFSZ 16384 -#endif - -#define AXE_RX_LIST_CNT 1 -#define AXE_TX_LIST_CNT 1 - -struct axe_chain { - struct axe_softc *axe_sc; - usbd_xfer_handle axe_xfer; - char *axe_buf; - struct mbuf *axe_mbuf; - int axe_accum; - int axe_idx; -}; - -struct axe_cdata { - struct axe_chain axe_tx_chain[AXE_TX_LIST_CNT]; - struct axe_chain axe_rx_chain[AXE_RX_LIST_CNT]; - int axe_tx_prod; - int axe_tx_cons; - int axe_tx_cnt; - int axe_rx_prod; -}; - -#define AXE_CTL_READ 0x01 -#define AXE_CTL_WRITE 0x02 - -#define AXE_CONFIG_NO 1 -#define AXE_IFACE_IDX 0 - -/* - * The interrupt endpoint is currently unused - * by the ASIX part. - */ -#define AXE_ENDPT_RX 0x0 -#define AXE_ENDPT_TX 0x1 -#define AXE_ENDPT_INTR 0x2 -#define AXE_ENDPT_MAX 0x3 - -struct axe_sframe_hdr { - uint16_t len; - uint16_t ilen; -} __packed; - -struct axe_type { - struct usb_devno axe_dev; - uint32_t axe_flags; -#define AX172 0x0000 /* AX88172 */ -#define AX178 0x0001 /* AX88178 */ -#define AX772 0x0002 /* AX88772 */ -}; - -#define AXE_INC(x, y) (x) = (x + 1) % y - -struct axe_softc { -#if defined(__FreeBSD__) -#define GET_MII(sc) (device_get_softc((sc)->axe_miibus)) -#elif defined(__NetBSD__) -#define GET_MII(sc) (&(sc)->axe_mii) -#elif defined(__OpenBSD__) -#define GET_MII(sc) (&(sc)->axe_mii) -#endif - struct ifnet *axe_ifp; - device_t axe_miibus; - device_t axe_dev; - usbd_device_handle axe_udev; - usbd_interface_handle axe_iface; - u_int16_t axe_vendor; - u_int16_t axe_product; - u_int16_t axe_flags; - int axe_ed[AXE_ENDPT_MAX]; - usbd_pipe_handle axe_ep[AXE_ENDPT_MAX]; - int axe_if_flags; - struct axe_cdata axe_cdata; - struct callout_handle axe_stat_ch; - struct mtx axe_mtx; - struct sx axe_sleeplock; - char axe_dying; - int axe_link; - unsigned char axe_ipgs[3]; - unsigned char axe_phyaddrs[2]; - struct timeval axe_rx_notice; - struct usb_task axe_tick_task; - int axe_bufsz; - int axe_boundary; -}; - -#if 0 -#define AXE_LOCK(_sc) mtx_lock(&(_sc)->axe_mtx) -#define AXE_UNLOCK(_sc) mtx_unlock(&(_sc)->axe_mtx) -#else -#define AXE_LOCK(_sc) -#define AXE_UNLOCK(_sc) -#endif -#define AXE_SLEEPLOCK(_sc) sx_xlock(&(_sc)->axe_sleeplock) -#define AXE_SLEEPUNLOCK(_sc) sx_xunlock(&(_sc)->axe_sleeplock) -#define AXE_SLEEPLOCKASSERT(_sc) sx_assert(&(_sc)->axe_sleeplock, SX_XLOCKED) diff --git a/sys/legacy/dev/usb/if_cdce.c b/sys/legacy/dev/usb/if_cdce.c deleted file mode 100644 index d41a54f..0000000 --- a/sys/legacy/dev/usb/if_cdce.c +++ /dev/null @@ -1,771 +0,0 @@ -/* $NetBSD: if_cdce.c,v 1.4 2004/10/24 12:50:54 augustss Exp $ */ - -/* - * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com> - * Copyright (c) 2003-2005 Craig Boston - * Copyright (c) 2004 Daniel Hartmeier - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul, THE VOICES IN HIS HEAD OR - * THE 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. - */ - -/* - * USB Communication Device Class (Ethernet Networking Control Model) - * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/sockio.h> -#include <sys/mbuf.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/socket.h> -#include <sys/endian.h> - -#include <net/if.h> -#include <net/if_arp.h> -#include <net/ethernet.h> -#include <net/if_types.h> -#include <net/if_media.h> - -#include <net/bpf.h> - -#include <sys/bus.h> -#include <machine/bus.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdivar.h> -#include <dev/usb/usb_ethersubr.h> - -#include <dev/usb/usbcdc.h> -#include "usbdevs.h" -#include <dev/usb/if_cdcereg.h> - -static device_probe_t cdce_match; -static device_attach_t cdce_attach; -static device_detach_t cdce_detach; -static device_shutdown_t cdce_shutdown; - -static device_method_t cdce_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, cdce_match), - DEVMETHOD(device_attach, cdce_attach), - DEVMETHOD(device_detach, cdce_detach), - DEVMETHOD(device_shutdown, cdce_shutdown), - - { 0, 0 } -}; - -static driver_t cdce_driver = { - "cdce", - cdce_methods, - sizeof(struct cdce_softc) -}; - -static devclass_t cdce_devclass; - -DRIVER_MODULE(cdce, uhub, cdce_driver, cdce_devclass, usbd_driver_load, 0); -MODULE_VERSION(cdce, 0); -MODULE_DEPEND(cdce, usb, 1, 1, 1); - -static int cdce_encap(struct cdce_softc *, struct mbuf *, int); -static void cdce_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void cdce_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void cdce_start(struct ifnet *); -static int cdce_ioctl(struct ifnet *, u_long, caddr_t); -static void cdce_init(void *); -static void cdce_reset(struct cdce_softc *); -static void cdce_stop(struct cdce_softc *); -static void cdce_rxstart(struct ifnet *); -static int cdce_ifmedia_upd(struct ifnet *ifp); -static void cdce_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr); - -static const struct cdce_type cdce_devs[] = { - {{ USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632 }, CDCE_NO_UNION }, - {{ USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250 }, CDCE_NO_UNION }, - {{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX }, CDCE_NO_UNION }, - {{ USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00 }, CDCE_NO_UNION }, - {{ USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN }, CDCE_ZAURUS | CDCE_NO_UNION }, - {{ USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN2 }, CDCE_ZAURUS | CDCE_NO_UNION }, - {{ USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_ETHERNETGADGET }, CDCE_NO_UNION }, - {{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501 }, CDCE_NO_UNION }, - {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500 }, CDCE_ZAURUS }, - {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600 }, CDCE_ZAURUS | CDCE_NO_UNION }, - {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLA300 }, CDCE_ZAURUS | CDCE_NO_UNION }, - {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC700 }, CDCE_ZAURUS | CDCE_NO_UNION }, - {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC750 }, CDCE_ZAURUS | CDCE_NO_UNION }, -}; -#define cdce_lookup(v, p) ((const struct cdce_type *)usb_lookup(cdce_devs, v, p)) - -static int -cdce_match(device_t self) -{ - struct usb_attach_arg *uaa = device_get_ivars(self); - usb_interface_descriptor_t *id; - - if (uaa->iface == NULL) - return (UMATCH_NONE); - - id = usbd_get_interface_descriptor(uaa->iface); - if (id == NULL) - return (UMATCH_NONE); - - if (cdce_lookup(uaa->vendor, uaa->product) != NULL) - return (UMATCH_VENDOR_PRODUCT); - - if (id->bInterfaceClass == UICLASS_CDC && id->bInterfaceSubClass == - UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL) - return (UMATCH_IFACECLASS_GENERIC); - - return (UMATCH_NONE); -} - -static int -cdce_attach(device_t self) -{ - struct cdce_softc *sc = device_get_softc(self); - struct usb_attach_arg *uaa = device_get_ivars(self); - struct ifnet *ifp; - usbd_device_handle dev = uaa->device; - const struct cdce_type *t; - usb_interface_descriptor_t *id; - usb_endpoint_descriptor_t *ed; - const usb_cdc_union_descriptor_t *ud; - usb_config_descriptor_t *cd; - int data_ifcno; - int i, j, numalts; - u_char eaddr[ETHER_ADDR_LEN]; - const usb_cdc_ethernet_descriptor_t *ue; - char eaddr_str[USB_MAX_STRING_LEN]; - - sc->cdce_dev = self; - sc->cdce_udev = uaa->device; - - t = cdce_lookup(uaa->vendor, uaa->product); - if (t) - sc->cdce_flags = t->cdce_flags; - - if (sc->cdce_flags & CDCE_NO_UNION) - sc->cdce_data_iface = uaa->iface; - else { - ud = (const usb_cdc_union_descriptor_t *)usb_find_desc(sc->cdce_udev, - UDESC_CS_INTERFACE, UDESCSUB_CDC_UNION); - if (ud == NULL) { - device_printf(sc->cdce_dev, "no union descriptor\n"); - return ENXIO; - } - data_ifcno = ud->bSlaveInterface[0]; - - for (i = 0; i < uaa->nifaces; i++) { - if (uaa->ifaces[i] != NULL) { - id = usbd_get_interface_descriptor( - uaa->ifaces[i]); - if (id != NULL && id->bInterfaceNumber == - data_ifcno) { - sc->cdce_data_iface = uaa->ifaces[i]; - uaa->ifaces[i] = NULL; - } - } - } - } - - if (sc->cdce_data_iface == NULL) { - device_printf(sc->cdce_dev, "no data interface\n"); - return ENXIO; - } - - /* - * <quote> - * The Data Class interface of a networking device shall have a minimum - * of two interface settings. The first setting (the default interface - * setting) includes no endpoints and therefore no networking traffic is - * exchanged whenever the default interface setting is selected. One or - * more additional interface settings are used for normal operation, and - * therefore each includes a pair of endpoints (one IN, and one OUT) to - * exchange network traffic. Select an alternate interface setting to - * initialize the network aspects of the device and to enable the - * exchange of network traffic. - * </quote> - * - * Some devices, most notably cable modems, include interface settings - * that have no IN or OUT endpoint, therefore loop through the list of all - * available interface settings looking for one with both IN and OUT - * endpoints. - */ - id = usbd_get_interface_descriptor(sc->cdce_data_iface); - cd = usbd_get_config_descriptor(sc->cdce_udev); - numalts = usbd_get_no_alts(cd, id->bInterfaceNumber); - - for (j = 0; j < numalts; j++) { - if (usbd_set_interface(sc->cdce_data_iface, j)) { - device_printf(sc->cdce_dev, - "setting alternate interface failed\n"); - return ENXIO; - } - /* Find endpoints. */ - id = usbd_get_interface_descriptor(sc->cdce_data_iface); - sc->cdce_bulkin_no = sc->cdce_bulkout_no = -1; - for (i = 0; i < id->bNumEndpoints; i++) { - ed = usbd_interface2endpoint_descriptor(sc->cdce_data_iface, i); - if (!ed) { - device_printf(sc->cdce_dev, - "could not read endpoint descriptor\n"); - return ENXIO; - } - if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->cdce_bulkin_no = ed->bEndpointAddress; - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->cdce_bulkout_no = ed->bEndpointAddress; - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { - /* XXX: CDC spec defines an interrupt pipe, but it is not - * needed for simple host-to-host applications. */ - } else { - device_printf(sc->cdce_dev, - "unexpected endpoint\n"); - } - } - /* If we found something, try and use it... */ - if ((sc->cdce_bulkin_no != -1) && (sc->cdce_bulkout_no != -1)) - break; - } - - if (sc->cdce_bulkin_no == -1) { - device_printf(sc->cdce_dev, "could not find data bulk in\n"); - return ENXIO; - } - if (sc->cdce_bulkout_no == -1 ) { - device_printf(sc->cdce_dev, "could not find data bulk out\n"); - return ENXIO; - } - - mtx_init(&sc->cdce_mtx, device_get_nameunit(sc->cdce_dev), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); - ifmedia_init(&sc->cdce_ifmedia, 0, cdce_ifmedia_upd, cdce_ifmedia_sts); - CDCE_LOCK(sc); - - ue = (const usb_cdc_ethernet_descriptor_t *)usb_find_desc(dev, - UDESC_INTERFACE, UDESCSUB_CDC_ENF); - if (!ue || usbd_get_string(dev, ue->iMacAddress, eaddr_str, - sizeof(eaddr_str))) { - /* Fake MAC address */ - device_printf(sc->cdce_dev, "faking MAC address\n"); - eaddr[0]= 0x2a; - memcpy(&eaddr[1], &ticks, sizeof(u_int32_t)); - eaddr[5] = (u_int8_t)device_get_unit(sc->cdce_dev); - } else { - int i; - - memset(eaddr, 0, ETHER_ADDR_LEN); - for (i = 0; i < ETHER_ADDR_LEN * 2; i++) { - int c = eaddr_str[i]; - - if ('0' <= c && c <= '9') - c -= '0'; - else - c -= 'A' - 10; - c &= 0xf; - if (c % 2 == 0) - c <<= 4; - eaddr[i / 2] |= c; - } - } - - ifp = GET_IFP(sc) = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(sc->cdce_dev, "can not if_alloc()\n"); - CDCE_UNLOCK(sc); - mtx_destroy(&sc->cdce_mtx); - return ENXIO; - } - ifp->if_softc = sc; - if_initname(ifp, "cdce", device_get_unit(sc->cdce_dev)); - ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSGIANT; - ifp->if_ioctl = cdce_ioctl; - ifp->if_output = ether_output; - ifp->if_start = cdce_start; - ifp->if_init = cdce_init; - ifp->if_baudrate = 11000000; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; - - sc->q.ifp = ifp; - sc->q.if_rxstart = cdce_rxstart; - - /* No IFM type for 11Mbps USB, so go with 10baseT */ - ifmedia_add(&sc->cdce_ifmedia, IFM_ETHER | IFM_10_T, 0, 0); - ifmedia_set(&sc->cdce_ifmedia, IFM_ETHER | IFM_10_T); - - ether_ifattach(ifp, eaddr); - usb_register_netisr(); - - CDCE_UNLOCK(sc); - - usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->cdce_udev, - sc->cdce_dev); - - return 0; -} - -static int -cdce_detach(device_t self) -{ - struct cdce_softc *sc = device_get_softc(self); - struct ifnet *ifp; - - CDCE_LOCK(sc); - sc->cdce_dying = 1; - ifp = GET_IFP(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - cdce_shutdown(sc->cdce_dev); - - ether_ifdetach(ifp); - if_free(ifp); - ifmedia_removeall(&sc->cdce_ifmedia); - CDCE_UNLOCK(sc); - mtx_destroy(&sc->cdce_mtx); - - usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->cdce_udev, - sc->cdce_dev); - - return (0); -} - -static void -cdce_start(struct ifnet *ifp) -{ - struct cdce_softc *sc; - struct mbuf *m_head = NULL; - - sc = ifp->if_softc; - CDCE_LOCK(sc); - - - if (sc->cdce_dying || - ifp->if_drv_flags & IFF_DRV_OACTIVE || - !(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - CDCE_UNLOCK(sc); - return; - } - - IF_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) { - CDCE_UNLOCK(sc); - return; - } - - if (cdce_encap(sc, m_head, 0)) { - IF_PREPEND(&ifp->if_snd, m_head); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - CDCE_UNLOCK(sc); - return; - } - - BPF_MTAP(ifp, m_head); - - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - - CDCE_UNLOCK(sc); - - return; -} - -static int -cdce_encap(struct cdce_softc *sc, struct mbuf *m, int idx) -{ - struct ue_chain *c; - usbd_status err; - int extra = 0; - - c = &sc->cdce_cdata.ue_tx_chain[idx]; - - m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf); - if (sc->cdce_flags & CDCE_ZAURUS) { - /* Zaurus wants a 32-bit CRC appended to every frame */ - u_int32_t crc; - - crc = htole32(crc32(c->ue_buf, m->m_pkthdr.len)); - bcopy(&crc, c->ue_buf + m->m_pkthdr.len, 4); - extra = 4; - } - c->ue_mbuf = m; - - usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkout_pipe, c, c->ue_buf, - m->m_pkthdr.len + extra, 0, 10000, cdce_txeof); - err = usbd_transfer(c->ue_xfer); - if (err != USBD_IN_PROGRESS) { - cdce_stop(sc); - return (EIO); - } - - sc->cdce_cdata.ue_tx_cnt++; - - return (0); -} - -static void -cdce_stop(struct cdce_softc *sc) -{ - usbd_status err; - struct ifnet *ifp; - - CDCE_LOCK(sc); - - cdce_reset(sc); - - ifp = GET_IFP(sc); - ifp->if_timer = 0; - - if (sc->cdce_bulkin_pipe != NULL) { - err = usbd_abort_pipe(sc->cdce_bulkin_pipe); - if (err) - device_printf(sc->cdce_dev, - "abort rx pipe failed: %s\n", usbd_errstr(err)); - err = usbd_close_pipe(sc->cdce_bulkin_pipe); - if (err) - device_printf(sc->cdce_dev, - "close rx pipe failed: %s\n", usbd_errstr(err)); - sc->cdce_bulkin_pipe = NULL; - } - - if (sc->cdce_bulkout_pipe != NULL) { - err = usbd_abort_pipe(sc->cdce_bulkout_pipe); - if (err) - device_printf(sc->cdce_dev, - "abort tx pipe failed: %s\n", usbd_errstr(err)); - err = usbd_close_pipe(sc->cdce_bulkout_pipe); - if (err) - device_printf(sc->cdce_dev, - "close tx pipe failed: %s\n", usbd_errstr(err)); - sc->cdce_bulkout_pipe = NULL; - } - - usb_ether_rx_list_free(&sc->cdce_cdata); - usb_ether_tx_list_free(&sc->cdce_cdata); - - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - CDCE_UNLOCK(sc); - - return; -} - -static int -cdce_shutdown(device_t dev) -{ - struct cdce_softc *sc; - - sc = device_get_softc(dev); - cdce_stop(sc); - - return (0); -} - -static int -cdce_ioctl(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct cdce_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; - int error = 0; - - if (sc->cdce_dying) - return (ENXIO); - - switch(command) { - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - cdce_init(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - cdce_stop(sc); - } - error = 0; - break; - - case SIOCSIFMEDIA: - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &sc->cdce_ifmedia, command); - break; - - default: - error = ether_ioctl(ifp, command, data); - break; - } - - return (error); -} - -static void -cdce_reset(struct cdce_softc *sc) -{ - /* XXX Maybe reset the bulk pipes here? */ - return; -} - -static void -cdce_init(void *xsc) -{ - struct cdce_softc *sc = xsc; - struct ifnet *ifp = GET_IFP(sc); - struct ue_chain *c; - usbd_status err; - int i; - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - return; - - CDCE_LOCK(sc); - cdce_reset(sc); - - if (usb_ether_tx_list_init(sc, &sc->cdce_cdata, - sc->cdce_udev) == ENOBUFS) { - device_printf(sc->cdce_dev, "tx list init failed\n"); - CDCE_UNLOCK(sc); - return; - } - - if (usb_ether_rx_list_init(sc, &sc->cdce_cdata, - sc->cdce_udev) == ENOBUFS) { - device_printf(sc->cdce_dev, "rx list init failed\n"); - CDCE_UNLOCK(sc); - return; - } - - /* Maybe set multicast / broadcast here??? */ - - err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkin_no, - USBD_EXCLUSIVE_USE, &sc->cdce_bulkin_pipe); - if (err) { - device_printf(sc->cdce_dev, "open rx pipe failed: %s\n", - usbd_errstr(err)); - CDCE_UNLOCK(sc); - return; - } - - err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkout_no, - USBD_EXCLUSIVE_USE, &sc->cdce_bulkout_pipe); - if (err) { - device_printf(sc->cdce_dev, "open tx pipe failed: %s\n", - usbd_errstr(err)); - CDCE_UNLOCK(sc); - return; - } - - for (i = 0; i < UE_RX_LIST_CNT; i++) { - c = &sc->cdce_cdata.ue_rx_chain[i]; - usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkin_pipe, c, - mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, cdce_rxeof); - usbd_transfer(c->ue_xfer); - } - - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - CDCE_UNLOCK(sc); - - return; -} - -static void -cdce_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct ue_chain *c = priv; - struct cdce_softc *sc = c->ue_sc; - struct ifnet *ifp; - struct mbuf *m; - int total_len = 0; - - CDCE_LOCK(sc); - ifp = GET_IFP(sc); - - if (sc->cdce_dying || !(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - CDCE_UNLOCK(sc); - return; - } - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - CDCE_UNLOCK(sc); - return; - } - if (sc->cdce_rxeof_errors == 0) - device_printf(sc->cdce_dev, "usb error on rx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async(sc->cdce_bulkin_pipe); - DELAY(sc->cdce_rxeof_errors * 10000); - sc->cdce_rxeof_errors++; - goto done; - } - - sc->cdce_rxeof_errors = 0; - - usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); - - if (sc->cdce_flags & CDCE_ZAURUS) - total_len -= 4; /* Strip off CRC added by Zaurus */ - - m = c->ue_mbuf; - - if (total_len < sizeof(struct ether_header)) { - ifp->if_ierrors++; - goto done; - } - - ifp->if_ipackets++; - m->m_pkthdr.rcvif = (struct ifnet *)&sc->q; - m->m_pkthdr.len = m->m_len = total_len; - - /* Put the packet on the special USB input queue. */ - usb_ether_input(m); - CDCE_UNLOCK(sc); - - return; - -done: - /* Setup new transfer. */ - usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkin_pipe, c, - mtod(c->ue_mbuf, char *), - UE_BUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, - cdce_rxeof); - usbd_transfer(c->ue_xfer); - CDCE_UNLOCK(sc); - - return; -} - -static void -cdce_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct ue_chain *c = priv; - struct cdce_softc *sc = c->ue_sc; - struct ifnet *ifp; - usbd_status err; - - CDCE_LOCK(sc); - ifp = GET_IFP(sc); - - if (sc->cdce_dying || - !(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - CDCE_UNLOCK(sc); - return; - } - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - CDCE_UNLOCK(sc); - return; - } - ifp->if_oerrors++; - device_printf(sc->cdce_dev, "usb error on tx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async(sc->cdce_bulkout_pipe); - CDCE_UNLOCK(sc); - return; - } - - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err); - - if (c->ue_mbuf != NULL) { - c->ue_mbuf->m_pkthdr.rcvif = ifp; - usb_tx_done(c->ue_mbuf); - c->ue_mbuf = NULL; - } - - if (err) - ifp->if_oerrors++; - else - ifp->if_opackets++; - - CDCE_UNLOCK(sc); - - return; -} - -static void -cdce_rxstart(struct ifnet *ifp) -{ - struct cdce_softc *sc; - struct ue_chain *c; - - sc = ifp->if_softc; - CDCE_LOCK(sc); - - if (sc->cdce_dying || !(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - CDCE_UNLOCK(sc); - return; - } - - c = &sc->cdce_cdata.ue_rx_chain[sc->cdce_cdata.ue_rx_prod]; - - c->ue_mbuf = usb_ether_newbuf(); - if (c->ue_mbuf == NULL) { - device_printf(sc->cdce_dev, "no memory for rx list " - "-- packet dropped!\n"); - ifp->if_ierrors++; - CDCE_UNLOCK(sc); - return; - } - - usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkin_pipe, c, - mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, cdce_rxeof); - usbd_transfer(c->ue_xfer); - - CDCE_UNLOCK(sc); - return; -} - -static int -cdce_ifmedia_upd(struct ifnet *ifp) -{ - - /* no-op, cdce has only 1 possible media type */ - return 0; -} - -static void -cdce_ifmedia_sts(struct ifnet * const ifp, struct ifmediareq *req) -{ - - req->ifm_status = IFM_AVALID | IFM_ACTIVE; - req->ifm_active = IFM_ETHER | IFM_10_T; -} diff --git a/sys/legacy/dev/usb/if_cdcereg.h b/sys/legacy/dev/usb/if_cdcereg.h deleted file mode 100644 index e658eab..0000000 --- a/sys/legacy/dev/usb/if_cdcereg.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2003-2005 Craig Boston - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul, THE VOICES IN HIS HEAD OR - * THE 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. - * - * $FreeBSD$ - */ - -#ifndef _USB_IF_CDCEREG_H_ -#define _USB_IF_CDCEREG_H_ - -struct cdce_type { - struct usb_devno cdce_dev; - u_int16_t cdce_flags; -#define CDCE_ZAURUS 1 -#define CDCE_NO_UNION 2 -}; - -struct cdce_softc { - struct ifnet *cdce_ifp; -#define GET_IFP(sc) ((sc)->cdce_ifp) - struct ifmedia cdce_ifmedia; - - usbd_device_handle cdce_udev; - usbd_interface_handle cdce_data_iface; - int cdce_bulkin_no; - usbd_pipe_handle cdce_bulkin_pipe; - int cdce_bulkout_no; - usbd_pipe_handle cdce_bulkout_pipe; - char cdce_dying; - device_t cdce_dev; - - struct ue_cdata cdce_cdata; - struct timeval cdce_rx_notice; - int cdce_rxeof_errors; - - u_int16_t cdce_flags; - - struct mtx cdce_mtx; - - struct usb_qdat q; -}; - -/* We are still under Giant */ -#if 0 -#define CDCE_LOCK(_sc) mtx_lock(&(_sc)->cdce_mtx) -#define CDCE_UNLOCK(_sc) mtx_unlock(&(_sc)->cdce_mtx) -#else -#define CDCE_LOCK(_sc) -#define CDCE_UNLOCK(_sc) -#endif - -#endif /* _USB_IF_CDCEREG_H_ */ diff --git a/sys/legacy/dev/usb/if_cue.c b/sys/legacy/dev/usb/if_cue.c deleted file mode 100644 index cd3a543..0000000 --- a/sys/legacy/dev/usb/if_cue.c +++ /dev/null @@ -1,1074 +0,0 @@ -/*- - * Copyright (c) 1997, 1998, 1999, 2000 - * Bill Paul <wpaul@ee.columbia.edu>. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * CATC USB-EL1210A USB to ethernet driver. Used in the CATC Netmate - * adapters and others. - * - * Written by Bill Paul <wpaul@ee.columbia.edu> - * Electrical Engineering Department - * Columbia University, New York City - */ - -/* - * The CATC USB-EL1210A provides USB ethernet support at 10Mbps. The - * RX filter uses a 512-bit multicast hash table, single perfect entry - * for the station address, and promiscuous mode. Unlike the ADMtek - * and KLSI chips, the CATC ASIC supports read and write combining - * mode where multiple packets can be transfered using a single bulk - * transaction, which helps performance a great deal. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/sockio.h> -#include <sys/mbuf.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/socket.h> - -#include <net/if.h> -#include <net/if_arp.h> -#include <net/ethernet.h> -#include <net/if_dl.h> -#include <net/if_types.h> - -#include <net/bpf.h> - -#include <sys/bus.h> -#include <machine/bus.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdivar.h> -#include "usbdevs.h" -#include <dev/usb/usb_ethersubr.h> - -#include <dev/usb/if_cuereg.h> - -/* - * Various supported device vendors/products. - */ -static struct cue_type cue_devs[] = { - { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE }, - { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2 }, - { USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTLINK }, - /* Belkin F5U111 adapter covered by NETMATE entry */ - { 0, 0 } -}; - -static device_probe_t cue_match; -static device_attach_t cue_attach; -static device_detach_t cue_detach; -static device_shutdown_t cue_shutdown; - -static int cue_encap(struct cue_softc *, struct mbuf *, int); -static void cue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void cue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void cue_tick(void *); -static void cue_rxstart(struct ifnet *); -static void cue_start(struct ifnet *); -static int cue_ioctl(struct ifnet *, u_long, caddr_t); -static void cue_init(void *); -static void cue_stop(struct cue_softc *); -static void cue_watchdog(struct ifnet *); - -static void cue_setmulti(struct cue_softc *); -static uint32_t cue_mchash(const uint8_t *); -static void cue_reset(struct cue_softc *); - -static int cue_csr_read_1(struct cue_softc *, int); -static int cue_csr_write_1(struct cue_softc *, int, int); -static int cue_csr_read_2(struct cue_softc *, int); -#ifdef notdef -static int cue_csr_write_2(struct cue_softc *, int, int); -#endif -static int cue_mem(struct cue_softc *, int, int, void *, int); -static int cue_getmac(struct cue_softc *, void *); - -static device_method_t cue_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, cue_match), - DEVMETHOD(device_attach, cue_attach), - DEVMETHOD(device_detach, cue_detach), - DEVMETHOD(device_shutdown, cue_shutdown), - - { 0, 0 } -}; - -static driver_t cue_driver = { - "cue", - cue_methods, - sizeof(struct cue_softc) -}; - -static devclass_t cue_devclass; - -DRIVER_MODULE(cue, uhub, cue_driver, cue_devclass, usbd_driver_load, 0); -MODULE_DEPEND(cue, usb, 1, 1, 1); -MODULE_DEPEND(cue, ether, 1, 1, 1); - -#define CUE_SETBIT(sc, reg, x) \ - cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) | (x)) - -#define CUE_CLRBIT(sc, reg, x) \ - cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) & ~(x)) - -static int -cue_csr_read_1(struct cue_softc *sc, int reg) -{ - usb_device_request_t req; - usbd_status err; - u_int8_t val = 0; - - if (sc->cue_dying) - return(0); - - CUE_LOCK(sc); - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = CUE_CMD_READREG; - USETW(req.wValue, 0); - USETW(req.wIndex, reg); - USETW(req.wLength, 1); - - err = usbd_do_request(sc->cue_udev, &req, &val); - - CUE_UNLOCK(sc); - - if (err) - return(0); - - return(val); -} - -static int -cue_csr_read_2(struct cue_softc *sc, int reg) -{ - usb_device_request_t req; - usbd_status err; - u_int16_t val = 0; - - if (sc->cue_dying) - return(0); - - CUE_LOCK(sc); - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = CUE_CMD_READREG; - USETW(req.wValue, 0); - USETW(req.wIndex, reg); - USETW(req.wLength, 2); - - err = usbd_do_request(sc->cue_udev, &req, &val); - - CUE_UNLOCK(sc); - - if (err) - return(0); - - return(val); -} - -static int -cue_csr_write_1(struct cue_softc *sc, int reg, int val) -{ - usb_device_request_t req; - usbd_status err; - - if (sc->cue_dying) - return(0); - - CUE_LOCK(sc); - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = CUE_CMD_WRITEREG; - USETW(req.wValue, val); - USETW(req.wIndex, reg); - USETW(req.wLength, 0); - - err = usbd_do_request(sc->cue_udev, &req, NULL); - - CUE_UNLOCK(sc); - - if (err) - return(-1); - - return(0); -} - -#ifdef notdef -static int -cue_csr_write_2(struct cue_softc *sc, int reg, int val) -{ - usb_device_request_t req; - usbd_status err; - - if (sc->cue_dying) - return(0); - - CUE_LOCK(sc); - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = CUE_CMD_WRITEREG; - USETW(req.wValue, val); - USETW(req.wIndex, reg); - USETW(req.wLength, 0); - - err = usbd_do_request(sc->cue_udev, &req, NULL); - - CUE_UNLOCK(sc); - - if (err) - return(-1); - - return(0); -} -#endif - -static int -cue_mem(struct cue_softc *sc, int cmd, int addr, void *buf, int len) -{ - usb_device_request_t req; - usbd_status err; - - if (sc->cue_dying) - return(0); - - CUE_LOCK(sc); - - if (cmd == CUE_CMD_READSRAM) - req.bmRequestType = UT_READ_VENDOR_DEVICE; - else - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = cmd; - USETW(req.wValue, 0); - USETW(req.wIndex, addr); - USETW(req.wLength, len); - - err = usbd_do_request(sc->cue_udev, &req, buf); - - CUE_UNLOCK(sc); - - if (err) - return(-1); - - return(0); -} - -static int -cue_getmac(struct cue_softc *sc, void *buf) -{ - usb_device_request_t req; - usbd_status err; - - if (sc->cue_dying) - return(0); - - CUE_LOCK(sc); - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = CUE_CMD_GET_MACADDR; - USETW(req.wValue, 0); - USETW(req.wIndex, 0); - USETW(req.wLength, ETHER_ADDR_LEN); - - err = usbd_do_request(sc->cue_udev, &req, buf); - - CUE_UNLOCK(sc); - - if (err) { - device_printf(sc->cue_dev, "read MAC address failed\n"); - return(-1); - } - - return(0); -} - -#define CUE_BITS 9 - -static uint32_t -cue_mchash(const uint8_t *addr) -{ - uint32_t crc; - - /* Compute CRC for the address value. */ - crc = ether_crc32_le(addr, ETHER_ADDR_LEN); - - return (crc & ((1 << CUE_BITS) - 1)); -} - -static void -cue_setmulti(struct cue_softc *sc) -{ - struct ifnet *ifp; - struct ifmultiaddr *ifma; - u_int32_t h = 0, i; - - ifp = sc->cue_ifp; - - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { - for (i = 0; i < CUE_MCAST_TABLE_LEN; i++) - sc->cue_mctab[i] = 0xFF; - cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, - &sc->cue_mctab, CUE_MCAST_TABLE_LEN); - return; - } - - /* first, zot all the existing hash bits */ - for (i = 0; i < CUE_MCAST_TABLE_LEN; i++) - sc->cue_mctab[i] = 0; - - /* now program new ones */ - IF_ADDR_LOCK(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) - { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - h = cue_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); - sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); - } - IF_ADDR_UNLOCK(ifp); - - /* - * Also include the broadcast address in the filter - * so we can receive broadcast frames. - */ - if (ifp->if_flags & IFF_BROADCAST) { - h = cue_mchash(ifp->if_broadcastaddr); - sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); - } - - cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, - &sc->cue_mctab, CUE_MCAST_TABLE_LEN); - - return; -} - -static void -cue_reset(struct cue_softc *sc) -{ - usb_device_request_t req; - usbd_status err; - - if (sc->cue_dying) - return; - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = CUE_CMD_RESET; - USETW(req.wValue, 0); - USETW(req.wIndex, 0); - USETW(req.wLength, 0); - err = usbd_do_request(sc->cue_udev, &req, NULL); - if (err) - device_printf(sc->cue_dev, "reset failed\n"); - - /* Wait a little while for the chip to get its brains in order. */ - DELAY(1000); - return; -} - -/* - * Probe for a Pegasus chip. - */ -static int -cue_match(device_t self) -{ - struct usb_attach_arg *uaa = device_get_ivars(self); - struct cue_type *t; - - if (!uaa->iface) - return(UMATCH_NONE); - - t = cue_devs; - while(t->cue_vid) { - if (uaa->vendor == t->cue_vid && - uaa->product == t->cue_did) { - return(UMATCH_VENDOR_PRODUCT); - } - t++; - } - - return(UMATCH_NONE); -} - -/* - * Attach the interface. Allocate softc structures, do ifmedia - * setup and ethernet/BPF attach. - */ -static int -cue_attach(device_t self) -{ - struct cue_softc *sc = device_get_softc(self); - struct usb_attach_arg *uaa = device_get_ivars(self); - u_char eaddr[ETHER_ADDR_LEN]; - struct ifnet *ifp; - usb_interface_descriptor_t *id; - usb_endpoint_descriptor_t *ed; - int i; - - sc->cue_dev = self; - sc->cue_iface = uaa->iface; - sc->cue_udev = uaa->device; - - if (usbd_set_config_no(sc->cue_udev, CUE_CONFIG_NO, 0)) { - device_printf(sc->cue_dev, "getting interface handle failed\n"); - return ENXIO; - } - - id = usbd_get_interface_descriptor(uaa->iface); - - /* Find endpoints. */ - for (i = 0; i < id->bNumEndpoints; i++) { - ed = usbd_interface2endpoint_descriptor(uaa->iface, i); - if (!ed) { - device_printf(sc->cue_dev, "couldn't get ep %d\n", i); - return ENXIO; - } - if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->cue_ed[CUE_ENDPT_RX] = ed->bEndpointAddress; - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->cue_ed[CUE_ENDPT_TX] = ed->bEndpointAddress; - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { - sc->cue_ed[CUE_ENDPT_INTR] = ed->bEndpointAddress; - } - } - - mtx_init(&sc->cue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); - CUE_LOCK(sc); - -#ifdef notdef - /* Reset the adapter. */ - cue_reset(sc); -#endif - /* - * Get station address. - */ - cue_getmac(sc, &eaddr); - - ifp = sc->cue_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(sc->cue_dev, "can not if_alloc()\n"); - CUE_UNLOCK(sc); - mtx_destroy(&sc->cue_mtx); - return ENXIO; - } - ifp->if_softc = sc; - if_initname(ifp, "cue", device_get_unit(sc->cue_dev)); - ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSGIANT; - ifp->if_ioctl = cue_ioctl; - ifp->if_start = cue_start; - ifp->if_watchdog = cue_watchdog; - ifp->if_init = cue_init; - ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; - - sc->cue_qdat.ifp = ifp; - sc->cue_qdat.if_rxstart = cue_rxstart; - - /* - * Call MI attach routine. - */ - ether_ifattach(ifp, eaddr); - callout_handle_init(&sc->cue_stat_ch); - usb_register_netisr(); - sc->cue_dying = 0; - - CUE_UNLOCK(sc); - return 0; -} - -static int -cue_detach(device_t dev) -{ - struct cue_softc *sc; - struct ifnet *ifp; - - sc = device_get_softc(dev); - CUE_LOCK(sc); - ifp = sc->cue_ifp; - - sc->cue_dying = 1; - untimeout(cue_tick, sc, sc->cue_stat_ch); - ether_ifdetach(ifp); - if_free(ifp); - - if (sc->cue_ep[CUE_ENDPT_TX] != NULL) - usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]); - if (sc->cue_ep[CUE_ENDPT_RX] != NULL) - usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_RX]); - if (sc->cue_ep[CUE_ENDPT_INTR] != NULL) - usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]); - - CUE_UNLOCK(sc); - mtx_destroy(&sc->cue_mtx); - - return(0); -} - -static void -cue_rxstart(struct ifnet *ifp) -{ - struct cue_softc *sc; - struct ue_chain *c; - - sc = ifp->if_softc; - CUE_LOCK(sc); - c = &sc->cue_cdata.ue_rx_chain[sc->cue_cdata.ue_rx_prod]; - - c->ue_mbuf = usb_ether_newbuf(); - if (c->ue_mbuf == NULL) { - device_printf(sc->cue_dev, "no memory for rx list " - "-- packet dropped!\n"); - ifp->if_ierrors++; - CUE_UNLOCK(sc); - return; - } - - /* Setup new transfer. */ - usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_RX], - c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, cue_rxeof); - usbd_transfer(c->ue_xfer); - CUE_UNLOCK(sc); - - return; -} - -/* - * A frame has been uploaded: pass the resulting mbuf chain up to - * the higher level protocols. - */ -static void -cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct cue_softc *sc; - struct ue_chain *c; - struct mbuf *m; - struct ifnet *ifp; - int total_len = 0; - u_int16_t len; - - c = priv; - sc = c->ue_sc; - CUE_LOCK(sc); - ifp = sc->cue_ifp; - - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - CUE_UNLOCK(sc); - return; - } - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - CUE_UNLOCK(sc); - return; - } - if (usbd_ratecheck(&sc->cue_rx_notice)) - device_printf(sc->cue_dev, "usb error on rx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_RX]); - goto done; - } - - usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); - - m = c->ue_mbuf; - len = *mtod(m, u_int16_t *); - - /* No errors; receive the packet. */ - total_len = len; - - if (len < sizeof(struct ether_header)) { - ifp->if_ierrors++; - goto done; - } - - ifp->if_ipackets++; - m_adj(m, sizeof(u_int16_t)); - m->m_pkthdr.rcvif = (void *)&sc->cue_qdat; - m->m_pkthdr.len = m->m_len = total_len; - - /* Put the packet on the special USB input queue. */ - usb_ether_input(m); - CUE_UNLOCK(sc); - - return; -done: - /* Setup new transfer. */ - usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_RX], - c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, cue_rxeof); - usbd_transfer(c->ue_xfer); - CUE_UNLOCK(sc); - - return; -} - -/* - * A frame was downloaded to the chip. It's safe for us to clean up - * the list buffers. - */ - -static void -cue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct cue_softc *sc; - struct ue_chain *c; - struct ifnet *ifp; - usbd_status err; - - c = priv; - sc = c->ue_sc; - CUE_LOCK(sc); - ifp = sc->cue_ifp; - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - CUE_UNLOCK(sc); - return; - } - device_printf(sc->cue_dev, "usb error on tx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_TX]); - CUE_UNLOCK(sc); - return; - } - - ifp->if_timer = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err); - - if (c->ue_mbuf != NULL) { - c->ue_mbuf->m_pkthdr.rcvif = ifp; - usb_tx_done(c->ue_mbuf); - c->ue_mbuf = NULL; - } - - if (err) - ifp->if_oerrors++; - else - ifp->if_opackets++; - - CUE_UNLOCK(sc); - - return; -} - -static void -cue_tick(void *xsc) -{ - struct cue_softc *sc; - struct ifnet *ifp; - - sc = xsc; - - if (sc == NULL) - return; - - CUE_LOCK(sc); - - ifp = sc->cue_ifp; - - ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_SINGLECOLL); - ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_MULTICOLL); - ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_EXCESSCOLL); - - if (cue_csr_read_2(sc, CUE_RX_FRAMEERR)) - ifp->if_ierrors++; - - sc->cue_stat_ch = timeout(cue_tick, sc, hz); - - CUE_UNLOCK(sc); - - return; -} - -static int -cue_encap(struct cue_softc *sc, struct mbuf *m, int idx) -{ - int total_len; - struct ue_chain *c; - usbd_status err; - - c = &sc->cue_cdata.ue_tx_chain[idx]; - - /* - * Copy the mbuf data into a contiguous buffer, leaving two - * bytes at the beginning to hold the frame length. - */ - m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf + 2); - c->ue_mbuf = m; - - total_len = m->m_pkthdr.len + 2; - - /* The first two bytes are the frame length */ - c->ue_buf[0] = (u_int8_t)m->m_pkthdr.len; - c->ue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8); - - usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_TX], - c, c->ue_buf, total_len, 0, 10000, cue_txeof); - - /* Transmit */ - err = usbd_transfer(c->ue_xfer); - if (err != USBD_IN_PROGRESS) { - cue_stop(sc); - return(EIO); - } - - sc->cue_cdata.ue_tx_cnt++; - - return(0); -} - -static void -cue_start(struct ifnet *ifp) -{ - struct cue_softc *sc; - struct mbuf *m_head = NULL; - - sc = ifp->if_softc; - CUE_LOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) { - CUE_UNLOCK(sc); - return; - } - - IF_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) { - CUE_UNLOCK(sc); - return; - } - - if (cue_encap(sc, m_head, 0)) { - IF_PREPEND(&ifp->if_snd, m_head); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - CUE_UNLOCK(sc); - return; - } - - /* - * If there's a BPF listener, bounce a copy of this frame - * to him. - */ - BPF_MTAP(ifp, m_head); - - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - - /* - * Set a timeout in case the chip goes out to lunch. - */ - ifp->if_timer = 5; - CUE_UNLOCK(sc); - - return; -} - -static void -cue_init(void *xsc) -{ - struct cue_softc *sc = xsc; - struct ifnet *ifp = sc->cue_ifp; - struct ue_chain *c; - usbd_status err; - int i; - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - return; - - CUE_LOCK(sc); - - /* - * Cancel pending I/O and free all RX/TX buffers. - */ -#ifdef foo - cue_reset(sc); -#endif - - /* Set MAC address */ - for (i = 0; i < ETHER_ADDR_LEN; i++) - cue_csr_write_1(sc, CUE_PAR0 - i, IF_LLADDR(sc->cue_ifp)[i]); - - /* Enable RX logic. */ - cue_csr_write_1(sc, CUE_ETHCTL, CUE_ETHCTL_RX_ON|CUE_ETHCTL_MCAST_ON); - - /* If we want promiscuous mode, set the allframes bit. */ - if (ifp->if_flags & IFF_PROMISC) { - CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); - } else { - CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); - } - - /* Init TX ring. */ - if (usb_ether_tx_list_init(sc, &sc->cue_cdata, - sc->cue_udev) == ENOBUFS) { - device_printf(sc->cue_dev, "tx list init failed\n"); - CUE_UNLOCK(sc); - return; - } - - /* Init RX ring. */ - if (usb_ether_rx_list_init(sc, &sc->cue_cdata, - sc->cue_udev) == ENOBUFS) { - device_printf(sc->cue_dev, "rx list init failed\n"); - CUE_UNLOCK(sc); - return; - } - - /* Load the multicast filter. */ - cue_setmulti(sc); - - /* - * Set the number of RX and TX buffers that we want - * to reserve inside the ASIC. - */ - cue_csr_write_1(sc, CUE_RX_BUFPKTS, CUE_RX_FRAMES); - cue_csr_write_1(sc, CUE_TX_BUFPKTS, CUE_TX_FRAMES); - - /* Set advanced operation modes. */ - cue_csr_write_1(sc, CUE_ADVANCED_OPMODES, - CUE_AOP_EMBED_RXLEN|0x01); /* 1 wait state */ - - /* Program the LED operation. */ - cue_csr_write_1(sc, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK); - - /* Open RX and TX pipes. */ - err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_RX], - USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_RX]); - if (err) { - device_printf(sc->cue_dev, "open rx pipe failed: %s\n", - usbd_errstr(err)); - CUE_UNLOCK(sc); - return; - } - err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_TX], - USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_TX]); - if (err) { - device_printf(sc->cue_dev, "open tx pipe failed: %s\n", - usbd_errstr(err)); - CUE_UNLOCK(sc); - return; - } - - /* Start up the receive pipe. */ - for (i = 0; i < UE_RX_LIST_CNT; i++) { - c = &sc->cue_cdata.ue_rx_chain[i]; - usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_RX], - c, mtod(c->ue_mbuf, char *), UE_BUFSZ, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, cue_rxeof); - usbd_transfer(c->ue_xfer); - } - - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - CUE_UNLOCK(sc); - - sc->cue_stat_ch = timeout(cue_tick, sc, hz); - - return; -} - -static int -cue_ioctl(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct cue_softc *sc = ifp->if_softc; - int error = 0; - - CUE_LOCK(sc); - - switch(command) { - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING && - ifp->if_flags & IFF_PROMISC && - !(sc->cue_if_flags & IFF_PROMISC)) { - CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); - cue_setmulti(sc); - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - sc->cue_if_flags & IFF_PROMISC) { - CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); - cue_setmulti(sc); - } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - cue_init(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - cue_stop(sc); - } - sc->cue_if_flags = ifp->if_flags; - error = 0; - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - cue_setmulti(sc); - error = 0; - break; - default: - error = ether_ioctl(ifp, command, data); - break; - } - - CUE_UNLOCK(sc); - - return(error); -} - -static void -cue_watchdog(struct ifnet *ifp) -{ - struct cue_softc *sc; - struct ue_chain *c; - usbd_status stat; - - sc = ifp->if_softc; - CUE_LOCK(sc); - - ifp->if_oerrors++; - device_printf(sc->cue_dev, "watchdog timeout\n"); - - c = &sc->cue_cdata.ue_tx_chain[0]; - usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat); - cue_txeof(c->ue_xfer, c, stat); - - if (ifp->if_snd.ifq_head != NULL) - cue_start(ifp); - CUE_UNLOCK(sc); - - return; -} - -/* - * Stop the adapter and free any mbufs allocated to the - * RX and TX lists. - */ -static void -cue_stop(struct cue_softc *sc) -{ - usbd_status err; - struct ifnet *ifp; - - CUE_LOCK(sc); - - ifp = sc->cue_ifp; - ifp->if_timer = 0; - - cue_csr_write_1(sc, CUE_ETHCTL, 0); - cue_reset(sc); - untimeout(cue_tick, sc, sc->cue_stat_ch); - - /* Stop transfers. */ - if (sc->cue_ep[CUE_ENDPT_RX] != NULL) { - err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_RX]); - if (err) { - device_printf(sc->cue_dev, "abort rx pipe failed: %s\n", - usbd_errstr(err)); - } - err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_RX]); - if (err) { - device_printf(sc->cue_dev, "close rx pipe failed: %s\n", - usbd_errstr(err)); - } - sc->cue_ep[CUE_ENDPT_RX] = NULL; - } - - if (sc->cue_ep[CUE_ENDPT_TX] != NULL) { - err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]); - if (err) { - device_printf(sc->cue_dev, "abort tx pipe failed: %s\n", - usbd_errstr(err)); - } - err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_TX]); - if (err) { - device_printf(sc->cue_dev, "close tx pipe failed: %s\n", - usbd_errstr(err)); - } - sc->cue_ep[CUE_ENDPT_TX] = NULL; - } - - if (sc->cue_ep[CUE_ENDPT_INTR] != NULL) { - err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]); - if (err) { - device_printf(sc->cue_dev, "abort intr pipe failed: %s\n", - usbd_errstr(err)); - } - err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_INTR]); - if (err) { - device_printf(sc->cue_dev, "close intr pipe failed: %s\n", - usbd_errstr(err)); - } - sc->cue_ep[CUE_ENDPT_INTR] = NULL; - } - - /* Free RX resources. */ - usb_ether_rx_list_free(&sc->cue_cdata); - /* Free TX resources. */ - usb_ether_tx_list_free(&sc->cue_cdata); - - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - CUE_UNLOCK(sc); - - return; -} - -/* - * Stop all chip I/O so that the kernel's probe routines don't - * get confused by errant DMAs when rebooting. - */ -static int -cue_shutdown(device_t dev) -{ - struct cue_softc *sc; - - sc = device_get_softc(dev); - - CUE_LOCK(sc); - cue_reset(sc); - cue_stop(sc); - CUE_UNLOCK(sc); - - return (0); -} diff --git a/sys/legacy/dev/usb/if_cuereg.h b/sys/legacy/dev/usb/if_cuereg.h deleted file mode 100644 index 4c81653..0000000 --- a/sys/legacy/dev/usb/if_cuereg.h +++ /dev/null @@ -1,168 +0,0 @@ -/*- - * Copyright (c) 1997, 1998, 1999, 2000 - * Bill Paul <wpaul@ee.columbia.edu>. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD - * 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. - * - * $FreeBSD$ - */ - -/* - * Definitions for the CATC Netmate II USB to ethernet controller. - */ - - -/* - * Vendor specific control commands. - */ -#define CUE_CMD_RESET 0xF4 -#define CUE_CMD_GET_MACADDR 0xF2 -#define CUE_CMD_WRITEREG 0xFA -#define CUE_CMD_READREG 0xFB -#define CUE_CMD_READSRAM 0xF1 -#define CUE_CMD_WRITESRAM 0xFC - -/* - * Internal registers - */ -#define CUE_TX_BUFCNT 0x20 -#define CUE_RX_BUFCNT 0x21 -#define CUE_ADVANCED_OPMODES 0x22 -#define CUE_TX_BUFPKTS 0x23 -#define CUE_RX_BUFPKTS 0x24 -#define CUE_RX_MAXCHAIN 0x25 - -#define CUE_ETHCTL 0x60 -#define CUE_ETHSTS 0x61 -#define CUE_PAR5 0x62 -#define CUE_PAR4 0x63 -#define CUE_PAR3 0x64 -#define CUE_PAR2 0x65 -#define CUE_PAR1 0x66 -#define CUE_PAR0 0x67 - -/* Error counters, all 16 bits wide. */ -#define CUE_TX_SINGLECOLL 0x69 -#define CUE_TX_MULTICOLL 0x6B -#define CUE_TX_EXCESSCOLL 0x6D -#define CUE_RX_FRAMEERR 0x6F - -#define CUE_LEDCTL 0x81 - -/* Advenced operating mode register */ -#define CUE_AOP_SRAMWAITS 0x03 -#define CUE_AOP_EMBED_RXLEN 0x08 -#define CUE_AOP_RXCOMBINE 0x10 -#define CUE_AOP_TXCOMBINE 0x20 -#define CUE_AOP_EVEN_PKT_READS 0x40 -#define CUE_AOP_LOOPBK 0x80 - -/* Ethernet control register */ -#define CUE_ETHCTL_RX_ON 0x01 -#define CUE_ETHCTL_LINK_POLARITY 0x02 -#define CUE_ETHCTL_LINK_FORCE_OK 0x04 -#define CUE_ETHCTL_MCAST_ON 0x08 -#define CUE_ETHCTL_PROMISC 0x10 - -/* Ethernet status register */ -#define CUE_ETHSTS_NO_CARRIER 0x01 -#define CUE_ETHSTS_LATECOLL 0x02 -#define CUE_ETHSTS_EXCESSCOLL 0x04 -#define CUE_ETHSTS_TXBUF_AVAIL 0x08 -#define CUE_ETHSTS_BAD_POLARITY 0x10 -#define CUE_ETHSTS_LINK_OK 0x20 - -/* LED control register */ -#define CUE_LEDCTL_BLINK_1X 0x00 -#define CUE_LEDCTL_BLINK_2X 0x01 -#define CUE_LEDCTL_BLINK_QUARTER_ON 0x02 -#define CUE_LEDCTL_BLINK_QUARTER_OFF 0x03 -#define CUE_LEDCTL_OFF 0x04 -#define CUE_LEDCTL_FOLLOW_LINK 0x08 - -/* - * Address in ASIC's internal SRAM where the - * multicast hash table lives. The table is 64 bytes long, - * giving us a 512-bit table. We have to set the bit that - * corresponds to the broadcast address in order to enable - * reception of broadcast frames. - */ -#define CUE_MCAST_TABLE_ADDR 0xFA80 -#define CUE_MCAST_TABLE_LEN 64 - -#define CUE_TIMEOUT 1000 -#define CUE_MIN_FRAMELEN 60 -#define CUE_RX_FRAMES 1 -#define CUE_TX_FRAMES 1 - -#define CUE_CTL_READ 0x01 -#define CUE_CTL_WRITE 0x02 - -#define CUE_CONFIG_NO 1 - -/* - * The interrupt endpoint is currently unused - * by the KLSI part. - */ -#define CUE_ENDPT_RX 0x0 -#define CUE_ENDPT_TX 0x1 -#define CUE_ENDPT_INTR 0x2 -#define CUE_ENDPT_MAX 0x3 - -struct cue_type { - u_int16_t cue_vid; - u_int16_t cue_did; -}; - -#define CUE_INC(x, y) (x) = (x + 1) % y - -struct cue_softc { - struct ifnet *cue_ifp; - device_t cue_dev; - usbd_device_handle cue_udev; - usbd_interface_handle cue_iface; - int cue_ed[CUE_ENDPT_MAX]; - usbd_pipe_handle cue_ep[CUE_ENDPT_MAX]; - u_int8_t cue_mctab[CUE_MCAST_TABLE_LEN]; - int cue_if_flags; - u_int16_t cue_rxfilt; - struct ue_cdata cue_cdata; - struct callout_handle cue_stat_ch; - struct mtx cue_mtx; - char cue_dying; - struct timeval cue_rx_notice; - struct usb_qdat cue_qdat; -}; - -#if 0 -#define CUE_LOCK(_sc) mtx_lock(&(_sc)->cue_mtx) -#define CUE_UNLOCK(_sc) mtx_unlock(&(_sc)->cue_mtx) -#else -#define CUE_LOCK(_sc) -#define CUE_UNLOCK(_sc) -#endif diff --git a/sys/legacy/dev/usb/if_kue.c b/sys/legacy/dev/usb/if_kue.c deleted file mode 100644 index f68eaa8..0000000 --- a/sys/legacy/dev/usb/if_kue.c +++ /dev/null @@ -1,1024 +0,0 @@ -/*- - * Copyright (c) 1997, 1998, 1999, 2000 - * Bill Paul <wpaul@ee.columbia.edu>. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Kawasaki LSI KL5KUSB101B USB to ethernet adapter driver. - * - * Written by Bill Paul <wpaul@ee.columbia.edu> - * Electrical Engineering Department - * Columbia University, New York City - */ - -/* - * The KLSI USB to ethernet adapter chip contains an USB serial interface, - * ethernet MAC and embedded microcontroller (called the QT Engine). - * The chip must have firmware loaded into it before it will operate. - * Packets are passed between the chip and host via bulk transfers. - * There is an interrupt endpoint mentioned in the software spec, however - * it's currently unused. This device is 10Mbps half-duplex only, hence - * there is no media selection logic. The MAC supports a 128 entry - * multicast filter, though the exact size of the filter can depend - * on the firmware. Curiously, while the software spec describes various - * ethernet statistics counters, my sample adapter and firmware combination - * claims not to support any statistics counters at all. - * - * Note that once we load the firmware in the device, we have to be - * careful not to load it again: if you restart your computer but - * leave the adapter attached to the USB controller, it may remain - * powered on and retain its firmware. In this case, we don't need - * to load the firmware a second time. - * - * Special thanks to Rob Furr for providing an ADS Technologies - * adapter for development and testing. No monkeys were harmed during - * the development of this driver. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/sockio.h> -#include <sys/mbuf.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/socket.h> - -#include <net/if.h> -#include <net/if_arp.h> -#include <net/ethernet.h> -#include <net/if_dl.h> -#include <net/if_media.h> -#include <net/if_types.h> - -#include <net/bpf.h> - -#include <sys/bus.h> -#include <machine/bus.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdivar.h> -#include "usbdevs.h" -#include <dev/usb/usb_ethersubr.h> - -#include <dev/usb/if_kuereg.h> -#include <dev/usb/kue_fw.h> - -MODULE_DEPEND(kue, usb, 1, 1, 1); -MODULE_DEPEND(kue, ether, 1, 1, 1); - -/* - * Various supported device vendors/products. - */ -static struct kue_type kue_devs[] = { - { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250 }, - { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460 }, - { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_URE450 }, - { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT }, - { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BTX }, - { USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101 }, - { USB_VENDOR_ASANTE, USB_PRODUCT_ASANTE_EA }, - { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T }, - { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_DSB650C }, - { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T }, - { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C }, - { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45 }, - { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX1 }, - { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX2 }, - { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT }, - { USB_VENDOR_JATON, USB_PRODUCT_JATON_EDA }, - { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_XX1 }, - { USB_VENDOR_KLSI, USB_PRODUCT_AOX_USB101 }, - { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT }, - { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BTN }, - { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T }, - { USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_EA }, - { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101 }, - { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101X }, - { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET }, - { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2 }, - { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET3 }, - { USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA8 }, - { USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA9 }, - { USB_VENDOR_PORTSMITH, USB_PRODUCT_PORTSMITH_EEA }, - { USB_VENDOR_SHARK, USB_PRODUCT_SHARK_PA }, - { USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_U2E }, - { USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_GPE }, - { USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB }, - { 0, 0 } -}; - -static device_probe_t kue_match; -static device_attach_t kue_attach; -static device_detach_t kue_detach; -static device_shutdown_t kue_shutdown; -static int kue_encap(struct kue_softc *, struct mbuf *, int); -static void kue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void kue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void kue_start(struct ifnet *); -static void kue_rxstart(struct ifnet *); -static int kue_ioctl(struct ifnet *, u_long, caddr_t); -static void kue_init(void *); -static void kue_stop(struct kue_softc *); -static void kue_watchdog(struct ifnet *); - -static void kue_setmulti(struct kue_softc *); -static void kue_reset(struct kue_softc *); - -static usbd_status kue_do_request(usbd_device_handle, - usb_device_request_t *, void *); -static usbd_status kue_ctl(struct kue_softc *, int, u_int8_t, - u_int16_t, char *, int); -static usbd_status kue_setword(struct kue_softc *, u_int8_t, u_int16_t); -static int kue_load_fw(struct kue_softc *); - -static device_method_t kue_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, kue_match), - DEVMETHOD(device_attach, kue_attach), - DEVMETHOD(device_detach, kue_detach), - DEVMETHOD(device_shutdown, kue_shutdown), - - { 0, 0 } -}; - -static driver_t kue_driver = { - "kue", - kue_methods, - sizeof(struct kue_softc) -}; - -static devclass_t kue_devclass; - -DRIVER_MODULE(kue, uhub, kue_driver, kue_devclass, usbd_driver_load, 0); - -/* - * We have a custom do_request function which is almost like the - * regular do_request function, except it has a much longer timeout. - * Why? Because we need to make requests over the control endpoint - * to download the firmware to the device, which can take longer - * than the default timeout. - */ -static usbd_status -kue_do_request(usbd_device_handle dev, usb_device_request_t *req, void *data) -{ - usbd_xfer_handle xfer; - usbd_status err; - - xfer = usbd_alloc_xfer(dev); - usbd_setup_default_xfer(xfer, dev, 0, 500000, req, - data, UGETW(req->wLength), USBD_SHORT_XFER_OK, 0); - err = usbd_sync_transfer(xfer); - usbd_free_xfer(xfer); - return(err); -} - -static usbd_status -kue_setword(struct kue_softc *sc, u_int8_t breq, u_int16_t word) -{ - usbd_device_handle dev; - usb_device_request_t req; - usbd_status err; - - if (sc->kue_dying) - return(USBD_NORMAL_COMPLETION); - - dev = sc->kue_udev; - - KUE_LOCK(sc); - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - - req.bRequest = breq; - USETW(req.wValue, word); - USETW(req.wIndex, 0); - USETW(req.wLength, 0); - - err = kue_do_request(dev, &req, NULL); - - KUE_UNLOCK(sc); - - return(err); -} - -static usbd_status -kue_ctl(struct kue_softc *sc, int rw, u_int8_t breq, u_int16_t val, - char *data, int len) -{ - usbd_device_handle dev; - usb_device_request_t req; - usbd_status err; - - dev = sc->kue_udev; - - if (sc->kue_dying) - return(USBD_NORMAL_COMPLETION); - - KUE_LOCK(sc); - - if (rw == KUE_CTL_WRITE) - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - else - req.bmRequestType = UT_READ_VENDOR_DEVICE; - - req.bRequest = breq; - USETW(req.wValue, val); - USETW(req.wIndex, 0); - USETW(req.wLength, len); - - err = kue_do_request(dev, &req, data); - - KUE_UNLOCK(sc); - - return(err); -} - -static int -kue_load_fw(struct kue_softc *sc) -{ - usbd_status err; - usb_device_descriptor_t *dd; - int hwrev; - - dd = &sc->kue_udev->ddesc; - hwrev = UGETW(dd->bcdDevice); - - /* - * First, check if we even need to load the firmware. - * If the device was still attached when the system was - * rebooted, it may already have firmware loaded in it. - * If this is the case, we don't need to do it again. - * And in fact, if we try to load it again, we'll hang, - * so we have to avoid this condition if we don't want - * to look stupid. - * - * We can test this quickly by checking the bcdRevision - * code. The NIC will return a different revision code if - * it's probed while the firmware is still loaded and - * running. - */ - if (hwrev == 0x0202) - return(0); - - /* Load code segment */ - err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, - 0, kue_code_seg, sizeof(kue_code_seg)); - if (err) { - device_printf(sc->kue_dev, "failed to load code segment: %s\n", - usbd_errstr(err)); - return(ENXIO); - } - - /* Load fixup segment */ - err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, - 0, kue_fix_seg, sizeof(kue_fix_seg)); - if (err) { - device_printf(sc->kue_dev, "failed to load fixup segment: %s\n", - usbd_errstr(err)); - return(ENXIO); - } - - /* Send trigger command. */ - err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN, - 0, kue_trig_seg, sizeof(kue_trig_seg)); - if (err) { - device_printf(sc->kue_dev, "failed to load trigger segment: %s\n", - usbd_errstr(err)); - return(ENXIO); - } - - return(0); -} - -static void -kue_setmulti(struct kue_softc *sc) -{ - struct ifnet *ifp; - struct ifmultiaddr *ifma; - int i = 0; - - ifp = sc->kue_ifp; - - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { - sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI; - sc->kue_rxfilt &= ~KUE_RXFILT_MULTICAST; - kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt); - return; - } - - sc->kue_rxfilt &= ~KUE_RXFILT_ALLMULTI; - - IF_ADDR_LOCK(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) - { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - /* - * If there are too many addresses for the - * internal filter, switch over to allmulti mode. - */ - if (i == KUE_MCFILTCNT(sc)) - break; - bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), - KUE_MCFILT(sc, i), ETHER_ADDR_LEN); - i++; - } - IF_ADDR_UNLOCK(ifp); - - if (i == KUE_MCFILTCNT(sc)) - sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI; - else { - sc->kue_rxfilt |= KUE_RXFILT_MULTICAST; - kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MCAST_FILTERS, - i, sc->kue_mcfilters, i * ETHER_ADDR_LEN); - } - - kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt); - - return; -} - -/* - * Issue a SET_CONFIGURATION command to reset the MAC. This should be - * done after the firmware is loaded into the adapter in order to - * bring it into proper operation. - */ -static void -kue_reset(struct kue_softc *sc) -{ - if (usbd_set_config_no(sc->kue_udev, KUE_CONFIG_NO, 0) || - usbd_device2interface_handle(sc->kue_udev, KUE_IFACE_IDX, - &sc->kue_iface)) { - device_printf(sc->kue_dev, "getting interface handle failed\n"); - } - - /* Wait a little while for the chip to get its brains in order. */ - DELAY(1000); - return; -} - -/* - * Probe for a KLSI chip. - */ -static int -kue_match(device_t self) -{ - struct usb_attach_arg *uaa = device_get_ivars(self); - struct kue_type *t; - - if (!uaa->iface) - return(UMATCH_NONE); - - t = kue_devs; - while (t->kue_vid) { - if (uaa->vendor == t->kue_vid && uaa->product == t->kue_did) - return (UMATCH_VENDOR_PRODUCT); - t++; - } - return (UMATCH_NONE); -} - -/* - * Attach the interface. Allocate softc structures, do - * setup and ethernet/BPF attach. - */ -static int -kue_attach(device_t self) -{ - struct kue_softc *sc = device_get_softc(self); - struct usb_attach_arg *uaa = device_get_ivars(self); - struct ifnet *ifp; - usbd_status err; - usb_interface_descriptor_t *id; - usb_endpoint_descriptor_t *ed; - int i; - - sc->kue_dev = self; - sc->kue_iface = uaa->iface; - sc->kue_udev = uaa->device; - - id = usbd_get_interface_descriptor(uaa->iface); - - /* Find endpoints. */ - for (i = 0; i < id->bNumEndpoints; i++) { - ed = usbd_interface2endpoint_descriptor(uaa->iface, i); - if (!ed) { - device_printf(sc->kue_dev, "couldn't get ep %d\n", i); - return ENXIO; - } - if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->kue_ed[KUE_ENDPT_RX] = ed->bEndpointAddress; - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->kue_ed[KUE_ENDPT_TX] = ed->bEndpointAddress; - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { - sc->kue_ed[KUE_ENDPT_INTR] = ed->bEndpointAddress; - } - } - - mtx_init(&sc->kue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); - KUE_LOCK(sc); - - /* Load the firmware into the NIC. */ - if (kue_load_fw(sc)) { - KUE_UNLOCK(sc); - mtx_destroy(&sc->kue_mtx); - return ENXIO; - } - - /* Reset the adapter. */ - kue_reset(sc); - - /* Read ethernet descriptor */ - err = kue_ctl(sc, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR, - 0, (char *)&sc->kue_desc, sizeof(sc->kue_desc)); - - sc->kue_mcfilters = malloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN, - M_USBDEV, M_NOWAIT); - - ifp = sc->kue_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(sc->kue_dev, "can not if_alloc()\n"); - KUE_UNLOCK(sc); - mtx_destroy(&sc->kue_mtx); - return ENXIO; - } - ifp->if_softc = sc; - if_initname(ifp, "kue", device_get_unit(sc->kue_dev)); - ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSGIANT; - ifp->if_ioctl = kue_ioctl; - ifp->if_start = kue_start; - ifp->if_watchdog = kue_watchdog; - ifp->if_init = kue_init; - ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; - - sc->kue_qdat.ifp = ifp; - sc->kue_qdat.if_rxstart = kue_rxstart; - - /* - * Call MI attach routine. - */ - ether_ifattach(ifp, sc->kue_desc.kue_macaddr); - usb_register_netisr(); - sc->kue_dying = 0; - - KUE_UNLOCK(sc); - - return 0; -} - -static int -kue_detach(device_t dev) -{ - struct kue_softc *sc; - struct ifnet *ifp; - - sc = device_get_softc(dev); - KUE_LOCK(sc); - ifp = sc->kue_ifp; - - sc->kue_dying = 1; - - if (ifp != NULL) { - ether_ifdetach(ifp); - if_free(ifp); - } - - if (sc->kue_ep[KUE_ENDPT_TX] != NULL) - usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_TX]); - if (sc->kue_ep[KUE_ENDPT_RX] != NULL) - usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_RX]); - if (sc->kue_ep[KUE_ENDPT_INTR] != NULL) - usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_INTR]); - - if (sc->kue_mcfilters != NULL) - free(sc->kue_mcfilters, M_USBDEV); - - KUE_UNLOCK(sc); - mtx_destroy(&sc->kue_mtx); - - return(0); -} - -static void -kue_rxstart(struct ifnet *ifp) -{ - struct kue_softc *sc; - struct ue_chain *c; - - sc = ifp->if_softc; - KUE_LOCK(sc); - c = &sc->kue_cdata.ue_rx_chain[sc->kue_cdata.ue_rx_prod]; - - c->ue_mbuf = usb_ether_newbuf(); - if (c->ue_mbuf == NULL) { - device_printf(sc->kue_dev, "no memory for rx list " - "-- packet dropped!\n"); - ifp->if_ierrors++; - KUE_UNLOCK(sc); - return; - } - - /* Setup new transfer. */ - usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_RX], - c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, kue_rxeof); - usbd_transfer(c->ue_xfer); - - KUE_UNLOCK(sc); - - return; -} - -/* - * A frame has been uploaded: pass the resulting mbuf chain up to - * the higher level protocols. - */ -static void kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, - usbd_status status) -{ - struct kue_softc *sc; - struct ue_chain *c; - struct mbuf *m; - struct ifnet *ifp; - int total_len = 0; - u_int16_t len; - - c = priv; - sc = c->ue_sc; - KUE_LOCK(sc); - ifp = sc->kue_ifp; - - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - KUE_UNLOCK(sc); - return; - } - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - KUE_UNLOCK(sc); - return; - } - if (usbd_ratecheck(&sc->kue_rx_notice)) - device_printf(sc->kue_dev, "usb error on rx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_RX]); - goto done; - } - - usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); - m = c->ue_mbuf; - if (total_len <= 1) - goto done; - - len = *mtod(m, u_int16_t *); - m_adj(m, sizeof(u_int16_t)); - - /* No errors; receive the packet. */ - total_len = len; - - if (len < sizeof(struct ether_header)) { - ifp->if_ierrors++; - goto done; - } - - ifp->if_ipackets++; - m->m_pkthdr.rcvif = (void *)&sc->kue_qdat; - m->m_pkthdr.len = m->m_len = total_len; - - /* Put the packet on the special USB input queue. */ - usb_ether_input(m); - KUE_UNLOCK(sc); - - return; -done: - - /* Setup new transfer. */ - usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_RX], - c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, kue_rxeof); - usbd_transfer(c->ue_xfer); - KUE_UNLOCK(sc); - - return; -} - -/* - * A frame was downloaded to the chip. It's safe for us to clean up - * the list buffers. - */ - -static void -kue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct kue_softc *sc; - struct ue_chain *c; - struct ifnet *ifp; - usbd_status err; - - c = priv; - sc = c->ue_sc; - KUE_LOCK(sc); - - ifp = sc->kue_ifp; - ifp->if_timer = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - KUE_UNLOCK(sc); - return; - } - device_printf(sc->kue_dev, "usb error on tx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_TX]); - KUE_UNLOCK(sc); - return; - } - - usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err); - - if (c->ue_mbuf != NULL) { - c->ue_mbuf->m_pkthdr.rcvif = ifp; - usb_tx_done(c->ue_mbuf); - c->ue_mbuf = NULL; - } - - if (err) - ifp->if_oerrors++; - else - ifp->if_opackets++; - - KUE_UNLOCK(sc); - - return; -} - -static int -kue_encap(struct kue_softc *sc, struct mbuf *m, int idx) -{ - int total_len; - struct ue_chain *c; - usbd_status err; - - c = &sc->kue_cdata.ue_tx_chain[idx]; - - /* - * Copy the mbuf data into a contiguous buffer, leaving two - * bytes at the beginning to hold the frame length. - */ - m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf + 2); - c->ue_mbuf = m; - - total_len = m->m_pkthdr.len + 2; - total_len += 64 - (total_len % 64); - - /* Frame length is specified in the first 2 bytes of the buffer. */ - c->ue_buf[0] = (u_int8_t)m->m_pkthdr.len; - c->ue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8); - - usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_TX], - c, c->ue_buf, total_len, 0, 10000, kue_txeof); - - /* Transmit */ - err = usbd_transfer(c->ue_xfer); - if (err != USBD_IN_PROGRESS) { - kue_stop(sc); - return(EIO); - } - - sc->kue_cdata.ue_tx_cnt++; - - return(0); -} - -static void -kue_start(struct ifnet *ifp) -{ - struct kue_softc *sc; - struct mbuf *m_head = NULL; - - sc = ifp->if_softc; - KUE_LOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) { - KUE_UNLOCK(sc); - return; - } - - IF_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) { - KUE_UNLOCK(sc); - return; - } - - if (kue_encap(sc, m_head, 0)) { - IF_PREPEND(&ifp->if_snd, m_head); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - KUE_UNLOCK(sc); - return; - } - - /* - * If there's a BPF listener, bounce a copy of this frame - * to him. - */ - BPF_MTAP(ifp, m_head); - - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - - /* - * Set a timeout in case the chip goes out to lunch. - */ - ifp->if_timer = 5; - KUE_UNLOCK(sc); - - return; -} - -static void -kue_init(void *xsc) -{ - struct kue_softc *sc = xsc; - struct ifnet *ifp = sc->kue_ifp; - struct ue_chain *c; - usbd_status err; - int i; - - KUE_LOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - KUE_UNLOCK(sc); - return; - } - - /* Set MAC address */ - kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MAC, - 0, IF_LLADDR(sc->kue_ifp), ETHER_ADDR_LEN); - - sc->kue_rxfilt = KUE_RXFILT_UNICAST|KUE_RXFILT_BROADCAST; - - /* If we want promiscuous mode, set the allframes bit. */ - if (ifp->if_flags & IFF_PROMISC) - sc->kue_rxfilt |= KUE_RXFILT_PROMISC; - - kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt); - - /* I'm not sure how to tune these. */ -#ifdef notdef - /* - * Leave this one alone for now; setting it - * wrong causes lockups on some machines/controllers. - */ - kue_setword(sc, KUE_CMD_SET_SOFS, 1); -#endif - kue_setword(sc, KUE_CMD_SET_URB_SIZE, 64); - - /* Init TX ring. */ - if (usb_ether_tx_list_init(sc, &sc->kue_cdata, - sc->kue_udev) == ENOBUFS) { - device_printf(sc->kue_dev, "tx list init failed\n"); - KUE_UNLOCK(sc); - return; - } - - /* Init RX ring. */ - if (usb_ether_rx_list_init(sc, &sc->kue_cdata, - sc->kue_udev) == ENOBUFS) { - device_printf(sc->kue_dev, "rx list init failed\n"); - KUE_UNLOCK(sc); - return; - } - - /* Load the multicast filter. */ - kue_setmulti(sc); - - /* Open RX and TX pipes. */ - err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_RX], - USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_RX]); - if (err) { - device_printf(sc->kue_dev, "open rx pipe failed: %s\n", - usbd_errstr(err)); - KUE_UNLOCK(sc); - return; - } - - err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_TX], - USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_TX]); - if (err) { - device_printf(sc->kue_dev, "open tx pipe failed: %s\n", - usbd_errstr(err)); - KUE_UNLOCK(sc); - return; - } - - /* Start up the receive pipe. */ - for (i = 0; i < UE_RX_LIST_CNT; i++) { - c = &sc->kue_cdata.ue_rx_chain[i]; - usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_RX], - c, mtod(c->ue_mbuf, char *), UE_BUFSZ, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, kue_rxeof); - usbd_transfer(c->ue_xfer); - } - - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - KUE_UNLOCK(sc); - - return; -} - -static int -kue_ioctl(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct kue_softc *sc = ifp->if_softc; - int error = 0; - - KUE_LOCK(sc); - - switch(command) { - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING && - ifp->if_flags & IFF_PROMISC && - !(sc->kue_if_flags & IFF_PROMISC)) { - sc->kue_rxfilt |= KUE_RXFILT_PROMISC; - kue_setword(sc, KUE_CMD_SET_PKT_FILTER, - sc->kue_rxfilt); - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - sc->kue_if_flags & IFF_PROMISC) { - sc->kue_rxfilt &= ~KUE_RXFILT_PROMISC; - kue_setword(sc, KUE_CMD_SET_PKT_FILTER, - sc->kue_rxfilt); - } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - kue_init(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - kue_stop(sc); - } - sc->kue_if_flags = ifp->if_flags; - error = 0; - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - kue_setmulti(sc); - error = 0; - break; - default: - error = ether_ioctl(ifp, command, data); - break; - } - - KUE_UNLOCK(sc); - - return(error); -} - -static void -kue_watchdog(struct ifnet *ifp) -{ - struct kue_softc *sc; - struct ue_chain *c; - usbd_status stat; - - sc = ifp->if_softc; - KUE_LOCK(sc); - ifp->if_oerrors++; - device_printf(sc->kue_dev, "watchdog timeout\n"); - - c = &sc->kue_cdata.ue_tx_chain[0]; - usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat); - kue_txeof(c->ue_xfer, c, stat); - - if (ifp->if_snd.ifq_head != NULL) - kue_start(ifp); - KUE_UNLOCK(sc); - - return; -} - -/* - * Stop the adapter and free any mbufs allocated to the - * RX and TX lists. - */ -static void -kue_stop(struct kue_softc *sc) -{ - usbd_status err; - struct ifnet *ifp; - - KUE_LOCK(sc); - ifp = sc->kue_ifp; - ifp->if_timer = 0; - - /* Stop transfers. */ - if (sc->kue_ep[KUE_ENDPT_RX] != NULL) { - err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_RX]); - if (err) { - device_printf(sc->kue_dev, "abort rx pipe failed: %s\n", - usbd_errstr(err)); - } - err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_RX]); - if (err) { - device_printf(sc->kue_dev, "close rx pipe failed: %s\n", - usbd_errstr(err)); - } - sc->kue_ep[KUE_ENDPT_RX] = NULL; - } - - if (sc->kue_ep[KUE_ENDPT_TX] != NULL) { - err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_TX]); - if (err) { - device_printf(sc->kue_dev, "abort tx pipe failed: %s\n", - usbd_errstr(err)); - } - err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_TX]); - if (err) { - device_printf(sc->kue_dev, "close tx pipe failed: %s\n", - usbd_errstr(err)); - } - sc->kue_ep[KUE_ENDPT_TX] = NULL; - } - - if (sc->kue_ep[KUE_ENDPT_INTR] != NULL) { - err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_INTR]); - if (err) { - device_printf(sc->kue_dev, "abort intr pipe failed: %s\n", - usbd_errstr(err)); - } - err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_INTR]); - if (err) { - device_printf(sc->kue_dev, "close intr pipe failed: %s\n", - usbd_errstr(err)); - } - sc->kue_ep[KUE_ENDPT_INTR] = NULL; - } - - /* Free RX resources. */ - usb_ether_rx_list_free(&sc->kue_cdata); - /* Free TX resources. */ - usb_ether_tx_list_free(&sc->kue_cdata); - - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - KUE_UNLOCK(sc); - - return; -} - -/* - * Stop all chip I/O so that the kernel's probe routines don't - * get confused by errant DMAs when rebooting. - */ -static int -kue_shutdown(device_t dev) -{ - struct kue_softc *sc; - - sc = device_get_softc(dev); - - kue_stop(sc); - - return (0); -} diff --git a/sys/legacy/dev/usb/if_kuereg.h b/sys/legacy/dev/usb/if_kuereg.h deleted file mode 100644 index 595eaa7..0000000 --- a/sys/legacy/dev/usb/if_kuereg.h +++ /dev/null @@ -1,161 +0,0 @@ -/*- - * Copyright (c) 1997, 1998, 1999, 2000 - * Bill Paul <wpaul@ee.columbia.edu>. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD - * 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. - * - * $FreeBSD$ - */ - -/* - * Definitions for the KLSI KL5KUSB101B USB to ethernet controller. - * The KLSI part is controlled via vendor control requests, the structure - * of which depend a bit on the firmware running on the internal - * microcontroller. The one exception is the 'send scan data' command, - * which is used to load the firmware. - */ - -#define KUE_CMD_GET_ETHER_DESCRIPTOR 0x00 -#define KUE_CMD_SET_MCAST_FILTERS 0x01 -#define KUE_CMD_SET_PKT_FILTER 0x02 -#define KUE_CMD_GET_ETHERSTATS 0x03 -#define KUE_CMD_GET_GPIO 0x04 -#define KUE_CMD_SET_GPIO 0x05 -#define KUE_CMD_SET_MAC 0x06 -#define KUE_CMD_GET_MAC 0x07 -#define KUE_CMD_SET_URB_SIZE 0x08 -#define KUE_CMD_SET_SOFS 0x09 -#define KUE_CMD_SET_EVEN_PKTS 0x0A -#define KUE_CMD_SEND_SCAN 0xFF - -struct kue_ether_desc { - u_int8_t kue_len; - u_int8_t kue_rsvd0; - u_int8_t kue_rsvd1; - u_int8_t kue_macaddr[ETHER_ADDR_LEN]; - u_int8_t kue_etherstats[4]; - u_int8_t kue_maxseg[2]; - u_int8_t kue_mcastfilt[2]; - u_int8_t kue_rsvd2; -}; - -#define KUE_ETHERSTATS(x) \ - (*(u_int32_t *)&(x)->kue_desc.kue_etherstats) -#define KUE_MAXSEG(x) \ - (*(u_int16_t *)&(x)->kue_desc.kue_maxseg) -#define KUE_MCFILTCNT(x) \ - ((*(u_int16_t *)&(x)->kue_desc.kue_mcastfilt) & 0x7FFF) -#define KUE_MCFILT(x, y) \ - (char *)&(sc->kue_mcfilters[y * ETHER_ADDR_LEN]) - -#define KUE_STAT_TX_OK 0x00000001 -#define KUE_STAT_RX_OK 0x00000002 -#define KUE_STAT_TX_ERR 0x00000004 -#define KUE_STAT_RX_ERR 0x00000008 -#define KUE_STAT_RX_NOBUF 0x00000010 -#define KUE_STAT_TX_UCAST_BYTES 0x00000020 -#define KUE_STAT_TX_UCAST_FRAMES 0x00000040 -#define KUE_STAT_TX_MCAST_BYTES 0x00000080 -#define KUE_STAT_TX_MCAST_FRAMES 0x00000100 -#define KUE_STAT_TX_BCAST_BYTES 0x00000200 -#define KUE_STAT_TX_BCAST_FRAMES 0x00000400 -#define KUE_STAT_RX_UCAST_BYTES 0x00000800 -#define KUE_STAT_RX_UCAST_FRAMES 0x00001000 -#define KUE_STAT_RX_MCAST_BYTES 0x00002000 -#define KUE_STAT_RX_MCAST_FRAMES 0x00004000 -#define KUE_STAT_RX_BCAST_BYTES 0x00008000 -#define KUE_STAT_RX_BCAST_FRAMES 0x00010000 -#define KUE_STAT_RX_CRCERR 0x00020000 -#define KUE_STAT_TX_QUEUE_LENGTH 0x00040000 -#define KUE_STAT_RX_ALIGNERR 0x00080000 -#define KUE_STAT_TX_SINGLECOLL 0x00100000 -#define KUE_STAT_TX_MULTICOLL 0x00200000 -#define KUE_STAT_TX_DEFERRED 0x00400000 -#define KUE_STAT_TX_MAXCOLLS 0x00800000 -#define KUE_STAT_RX_OVERRUN 0x01000000 -#define KUE_STAT_TX_UNDERRUN 0x02000000 -#define KUE_STAT_TX_SQE_ERR 0x04000000 -#define KUE_STAT_TX_CARRLOSS 0x08000000 -#define KUE_STAT_RX_LATECOLL 0x10000000 - -#define KUE_RXFILT_PROMISC 0x0001 -#define KUE_RXFILT_ALLMULTI 0x0002 -#define KUE_RXFILT_UNICAST 0x0004 -#define KUE_RXFILT_BROADCAST 0x0008 -#define KUE_RXFILT_MULTICAST 0x0010 - -#define KUE_TIMEOUT 1000 -#define KUE_MIN_FRAMELEN 60 - -#define KUE_CTL_READ 0x01 -#define KUE_CTL_WRITE 0x02 - -#define KUE_CONFIG_NO 1 -#define KUE_IFACE_IDX 0 - -/* - * The interrupt endpoint is currently unused - * by the KLSI part. - */ -#define KUE_ENDPT_RX 0x0 -#define KUE_ENDPT_TX 0x1 -#define KUE_ENDPT_INTR 0x2 -#define KUE_ENDPT_MAX 0x3 - -struct kue_type { - u_int16_t kue_vid; - u_int16_t kue_did; -}; - -#define KUE_INC(x, y) (x) = (x + 1) % y - -struct kue_softc { - struct ifnet *kue_ifp; - device_t kue_dev; - usbd_device_handle kue_udev; - usbd_interface_handle kue_iface; - struct kue_ether_desc kue_desc; - int kue_ed[KUE_ENDPT_MAX]; - usbd_pipe_handle kue_ep[KUE_ENDPT_MAX]; - int kue_if_flags; - u_int16_t kue_rxfilt; - u_int8_t *kue_mcfilters; - struct ue_cdata kue_cdata; - struct mtx kue_mtx; - char kue_dying; - struct timeval kue_rx_notice; - struct usb_qdat kue_qdat; -}; - -#if 0 -#define KUE_LOCK(_sc) mtx_lock(&(_sc)->kue_mtx) -#define KUE_UNLOCK(_sc) mtx_unlock(&(_sc)->kue_mtx) -#else -#define KUE_LOCK(_sc) -#define KUE_UNLOCK(_sc) -#endif diff --git a/sys/legacy/dev/usb/if_rue.c b/sys/legacy/dev/usb/if_rue.c deleted file mode 100644 index 4449f7d..0000000 --- a/sys/legacy/dev/usb/if_rue.c +++ /dev/null @@ -1,1393 +0,0 @@ -/*- - * Copyright (c) 2001-2003, Shunsuke Akiyama <akiyama@FreeBSD.org>. - * Copyright (c) 1997, 1998, 1999, 2000 Bill Paul <wpaul@ee.columbia.edu>. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - */ -/*- - * Copyright (c) 1997, 1998, 1999, 2000 - * Bill Paul <wpaul@ee.columbia.edu>. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD - * 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * RealTek RTL8150 USB to fast ethernet controller driver. - * Datasheet is available from - * ftp://ftp.realtek.com.tw/lancard/data_sheet/8150/. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/sockio.h> -#include <sys/mbuf.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/socket.h> -#include <sys/sysctl.h> - -#include <net/if.h> -#include <net/if_arp.h> -#include <net/ethernet.h> -#include <net/if_dl.h> -#include <net/if_media.h> -#include <net/if_types.h> - -#include <net/bpf.h> - -#include <sys/bus.h> -#include <machine/bus.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdivar.h> -#include "usbdevs.h" -#include <dev/usb/usb_ethersubr.h> - -#include <dev/mii/mii.h> -#include <dev/mii/miivar.h> - -#include <dev/usb/if_ruereg.h> - -/* "device miibus" required. See GENERIC if you get errors here. */ -#include "miibus_if.h" - -#ifdef USB_DEBUG -static int ruedebug = 0; -SYSCTL_NODE(_hw_usb, OID_AUTO, rue, CTLFLAG_RW, 0, "USB rue"); -SYSCTL_INT(_hw_usb_rue, OID_AUTO, debug, CTLFLAG_RW, - &ruedebug, 0, "rue debug level"); - -#define DPRINTFN(n, x) do { \ - if (ruedebug > (n)) \ - printf x; \ - } while (0); -#else -#define DPRINTFN(n, x) -#endif -#define DPRINTF(x) DPRINTFN(0, x) - -/* - * Various supported device vendors/products. - */ - -static struct rue_type rue_devs[] = { - { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_USBKR100 }, - { 0, 0 } -}; - -static device_probe_t rue_match; -static device_attach_t rue_attach; -static device_detach_t rue_detach; -static device_shutdown_t rue_shutdown; -static miibus_readreg_t rue_miibus_readreg; -static miibus_writereg_t rue_miibus_writereg; -static miibus_statchg_t rue_miibus_statchg; - -static int rue_encap(struct rue_softc *, struct mbuf *, int); -#ifdef RUE_INTR_PIPE -static void rue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); -#endif -static void rue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void rue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void rue_tick(void *); -static void rue_tick_task(void *); -static void rue_rxstart(struct ifnet *); -static void rue_start(struct ifnet *); -static int rue_ioctl(struct ifnet *, u_long, caddr_t); -static void rue_init(void *); -static void rue_stop(struct rue_softc *); -static void rue_watchdog(struct ifnet *); -static int rue_ifmedia_upd(struct ifnet *); -static void rue_ifmedia_sts(struct ifnet *, struct ifmediareq *); - -static void rue_setmulti(struct rue_softc *); -static void rue_reset(struct rue_softc *); - -static int rue_read_mem(struct rue_softc *, u_int16_t, void *, u_int16_t); -static int rue_write_mem(struct rue_softc *, u_int16_t, void *, u_int16_t); -static int rue_csr_read_1(struct rue_softc *, int); -static int rue_csr_write_1(struct rue_softc *, int, u_int8_t); -static int rue_csr_read_2(struct rue_softc *, int); -static int rue_csr_write_2(struct rue_softc *, int, u_int16_t); -static int rue_csr_write_4(struct rue_softc *, int, u_int32_t); - -static device_method_t rue_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, rue_match), - DEVMETHOD(device_attach, rue_attach), - DEVMETHOD(device_detach, rue_detach), - DEVMETHOD(device_shutdown, rue_shutdown), - - /* Bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - - /* MII interface */ - DEVMETHOD(miibus_readreg, rue_miibus_readreg), - DEVMETHOD(miibus_writereg, rue_miibus_writereg), - DEVMETHOD(miibus_statchg, rue_miibus_statchg), - - { 0, 0 } -}; - -static driver_t rue_driver = { - "rue", - rue_methods, - sizeof(struct rue_softc) -}; - -static devclass_t rue_devclass; - -DRIVER_MODULE(rue, uhub, rue_driver, rue_devclass, usbd_driver_load, 0); -DRIVER_MODULE(miibus, rue, miibus_driver, miibus_devclass, 0, 0); -MODULE_DEPEND(rue, usb, 1, 1, 1); -MODULE_DEPEND(rue, ether, 1, 1, 1); -MODULE_DEPEND(rue, miibus, 1, 1, 1); - -#define RUE_SETBIT(sc, reg, x) \ - rue_csr_write_1(sc, reg, rue_csr_read_1(sc, reg) | (x)) - -#define RUE_CLRBIT(sc, reg, x) \ - rue_csr_write_1(sc, reg, rue_csr_read_1(sc, reg) & ~(x)) - -#define RUE_SETBIT_2(sc, reg, x) \ - rue_csr_write_2(sc, reg, rue_csr_read_2(sc, reg) | (x)) - -#define RUE_CLRBIT_2(sc, reg, x) \ - rue_csr_write_2(sc, reg, rue_csr_read_2(sc, reg) & ~(x)) - -static int -rue_read_mem(struct rue_softc *sc, u_int16_t addr, void *buf, u_int16_t len) -{ - usb_device_request_t req; - usbd_status err; - - if (sc->rue_dying) - return (0); - - RUE_LOCK(sc); - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = UR_SET_ADDRESS; - USETW(req.wValue, addr); - USETW(req.wIndex, 0); - USETW(req.wLength, len); - - err = usbd_do_request(sc->rue_udev, &req, buf); - - RUE_UNLOCK(sc); - - if (err) { - device_printf(sc->rue_dev, "control pipe read failed: %s\n", - usbd_errstr(err)); - return (-1); - } - - return (0); -} - -static int -rue_write_mem(struct rue_softc *sc, u_int16_t addr, void *buf, u_int16_t len) -{ - usb_device_request_t req; - usbd_status err; - - if (sc->rue_dying) - return (0); - - RUE_LOCK(sc); - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = UR_SET_ADDRESS; - USETW(req.wValue, addr); - USETW(req.wIndex, 0); - USETW(req.wLength, len); - - err = usbd_do_request(sc->rue_udev, &req, buf); - - RUE_UNLOCK(sc); - - if (err) { - device_printf(sc->rue_dev, "control pipe write failed: %s\n", - usbd_errstr(err)); - return (-1); - } - - return (0); -} - -static int -rue_csr_read_1(struct rue_softc *sc, int reg) -{ - int err; - u_int8_t val = 0; - - err = rue_read_mem(sc, reg, &val, 1); - - if (err) - return (0); - - return (val); -} - -static int -rue_csr_read_2(struct rue_softc *sc, int reg) -{ - int err; - u_int16_t val = 0; - uWord w; - - USETW(w, val); - err = rue_read_mem(sc, reg, &w, 2); - val = UGETW(w); - - if (err) - return (0); - - return (val); -} - -static int -rue_csr_write_1(struct rue_softc *sc, int reg, u_int8_t val) -{ - int err; - - err = rue_write_mem(sc, reg, &val, 1); - - if (err) - return (-1); - - return (0); -} - -static int -rue_csr_write_2(struct rue_softc *sc, int reg, u_int16_t val) -{ - int err; - uWord w; - - USETW(w, val); - err = rue_write_mem(sc, reg, &w, 2); - - if (err) - return (-1); - - return (0); -} - -static int -rue_csr_write_4(struct rue_softc *sc, int reg, u_int32_t val) -{ - int err; - uDWord dw; - - USETDW(dw, val); - err = rue_write_mem(sc, reg, &dw, 4); - - if (err) - return (-1); - - return (0); -} - -static int -rue_miibus_readreg(device_t dev, int phy, int reg) -{ - struct rue_softc *sc = device_get_softc(dev); - int rval; - int ruereg; - - if (phy != 0) /* RTL8150 supports PHY == 0, only */ - return (0); - - switch (reg) { - case MII_BMCR: - ruereg = RUE_BMCR; - break; - case MII_BMSR: - ruereg = RUE_BMSR; - break; - case MII_ANAR: - ruereg = RUE_ANAR; - break; - case MII_ANER: - ruereg = RUE_AER; - break; - case MII_ANLPAR: - ruereg = RUE_ANLP; - break; - case MII_PHYIDR1: - case MII_PHYIDR2: - return (0); - break; - default: - if (RUE_REG_MIN <= reg && reg <= RUE_REG_MAX) { - rval = rue_csr_read_1(sc, reg); - return (rval); - } - device_printf(sc->rue_dev, "bad phy register\n"); - return (0); - } - - rval = rue_csr_read_2(sc, ruereg); - - return (rval); -} - -static int -rue_miibus_writereg(device_t dev, int phy, int reg, int data) -{ - struct rue_softc *sc = device_get_softc(dev); - int ruereg; - - if (phy != 0) /* RTL8150 supports PHY == 0, only */ - return (0); - - switch (reg) { - case MII_BMCR: - ruereg = RUE_BMCR; - break; - case MII_BMSR: - ruereg = RUE_BMSR; - break; - case MII_ANAR: - ruereg = RUE_ANAR; - break; - case MII_ANER: - ruereg = RUE_AER; - break; - case MII_ANLPAR: - ruereg = RUE_ANLP; - break; - case MII_PHYIDR1: - case MII_PHYIDR2: - return (0); - break; - default: - if (RUE_REG_MIN <= reg && reg <= RUE_REG_MAX) { - rue_csr_write_1(sc, reg, data); - return (0); - } - device_printf(sc->rue_dev, "bad phy register\n"); - return (0); - } - rue_csr_write_2(sc, ruereg, data); - - return (0); -} - -static void -rue_miibus_statchg(device_t dev) -{ - /* - * When the code below is enabled the card starts doing weird - * things after link going from UP to DOWN and back UP. - * - * Looks like some of register writes below messes up PHY - * interface. - * - * No visible regressions were found after commenting this code - * out, so that disable it for good. - */ -#if 0 - struct rue_softc *sc = device_get_softc(dev); - struct mii_data *mii = GET_MII(sc); - int bmcr; - - RUE_CLRBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE)); - - bmcr = rue_csr_read_2(sc, RUE_BMCR); - - if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) - bmcr |= RUE_BMCR_SPD_SET; - else - bmcr &= ~RUE_BMCR_SPD_SET; - - if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) - bmcr |= RUE_BMCR_DUPLEX; - else - bmcr &= ~RUE_BMCR_DUPLEX; - - rue_csr_write_2(sc, RUE_BMCR, bmcr); - - RUE_SETBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE)); -#endif -} - -/* - * Program the 64-bit multicast hash filter. - */ - -static void -rue_setmulti(struct rue_softc *sc) -{ - struct ifnet *ifp; - int h = 0; - u_int32_t hashes[2] = { 0, 0 }; - struct ifmultiaddr *ifma; - u_int32_t rxcfg; - int mcnt = 0; - - ifp = sc->rue_ifp; - - rxcfg = rue_csr_read_2(sc, RUE_RCR); - - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { - rxcfg |= (RUE_RCR_AAM | RUE_RCR_AAP); - rxcfg &= ~RUE_RCR_AM; - rue_csr_write_2(sc, RUE_RCR, rxcfg); - rue_csr_write_4(sc, RUE_MAR0, 0xFFFFFFFF); - rue_csr_write_4(sc, RUE_MAR4, 0xFFFFFFFF); - return; - } - - /* first, zot all the existing hash bits */ - rue_csr_write_4(sc, RUE_MAR0, 0); - rue_csr_write_4(sc, RUE_MAR4, 0); - - /* now program new ones */ - IF_ADDR_LOCK(ifp); - TAILQ_FOREACH (ifma, &ifp->if_multiaddrs, ifma_link) - { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - h = ether_crc32_be(LLADDR((struct sockaddr_dl *) - ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; - if (h < 32) - hashes[0] |= (1 << h); - else - hashes[1] |= (1 << (h - 32)); - mcnt++; - } - IF_ADDR_UNLOCK(ifp); - - if (mcnt) - rxcfg |= RUE_RCR_AM; - else - rxcfg &= ~RUE_RCR_AM; - - rxcfg &= ~(RUE_RCR_AAM | RUE_RCR_AAP); - - rue_csr_write_2(sc, RUE_RCR, rxcfg); - rue_csr_write_4(sc, RUE_MAR0, hashes[0]); - rue_csr_write_4(sc, RUE_MAR4, hashes[1]); -} - -static void -rue_reset(struct rue_softc *sc) -{ - int i; - - rue_csr_write_1(sc, RUE_CR, RUE_CR_SOFT_RST); - - for (i = 0; i < RUE_TIMEOUT; i++) { - DELAY(500); - if (!(rue_csr_read_1(sc, RUE_CR) & RUE_CR_SOFT_RST)) - break; - } - if (i == RUE_TIMEOUT) - device_printf(sc->rue_dev, "reset never completed!\n"); - - DELAY(10000); -} - -/* - * Probe for a RTL8150 chip. - */ - -static int -rue_match(device_t self) -{ - struct usb_attach_arg *uaa = device_get_ivars(self); - struct rue_type *t; - - if (uaa->iface == NULL) - return (UMATCH_NONE); - - t = rue_devs; - while (t->rue_vid) { - if (uaa->vendor == t->rue_vid && - uaa->product == t->rue_did) { - return (UMATCH_VENDOR_PRODUCT); - } - t++; - } - - return (UMATCH_NONE); -} - -/* - * Attach the interface. Allocate softc structures, do ifmedia - * setup and ethernet/BPF attach. - */ - -static int -rue_attach(device_t self) -{ - struct rue_softc *sc = device_get_softc(self); - struct usb_attach_arg *uaa = device_get_ivars(self); - u_char eaddr[ETHER_ADDR_LEN]; - struct ifnet *ifp; - usbd_interface_handle iface; - usbd_status err; - usb_interface_descriptor_t *id; - usb_endpoint_descriptor_t *ed; - int i; - struct rue_type *t; - - sc->rue_dev = self; - sc->rue_udev = uaa->device; - - if (usbd_set_config_no(sc->rue_udev, RUE_CONFIG_NO, 0)) { - device_printf(sc->rue_dev, "getting interface handle failed\n"); - goto error; - } - - usb_init_task(&sc->rue_tick_task, rue_tick_task, sc); - - err = usbd_device2interface_handle(uaa->device, RUE_IFACE_IDX, &iface); - if (err) { - device_printf(sc->rue_dev, "getting interface handle failed\n"); - goto error; - } - - sc->rue_iface = iface; - - t = rue_devs; - while (t->rue_vid) { - if (uaa->vendor == t->rue_vid && - uaa->product == t->rue_did) { - sc->rue_info = t; - break; - } - t++; - } - - id = usbd_get_interface_descriptor(sc->rue_iface); - - /* Find endpoints */ - for (i = 0; i < id->bNumEndpoints; i++) { - ed = usbd_interface2endpoint_descriptor(iface, i); - if (ed == NULL) { - device_printf(sc->rue_dev, "couldn't get ep %d\n", i); - goto error; - } - if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->rue_ed[RUE_ENDPT_RX] = ed->bEndpointAddress; - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->rue_ed[RUE_ENDPT_TX] = ed->bEndpointAddress; - } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { - sc->rue_ed[RUE_ENDPT_INTR] = ed->bEndpointAddress; - } - } - - mtx_init(&sc->rue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); - RUE_LOCK(sc); - - /* Reset the adapter */ - rue_reset(sc); - - /* Get station address from the EEPROM */ - err = rue_read_mem(sc, RUE_EEPROM_IDR0, - (caddr_t)&eaddr, ETHER_ADDR_LEN); - if (err) { - device_printf(sc->rue_dev, "couldn't get station address\n"); - goto error1; - } - - ifp = sc->rue_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(sc->rue_dev, "can not if_alloc()\n"); - goto error1; - } - ifp->if_softc = sc; - if_initname(ifp, "rue", device_get_unit(sc->rue_dev)); - ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSGIANT; - ifp->if_ioctl = rue_ioctl; - ifp->if_start = rue_start; - ifp->if_watchdog = rue_watchdog; - ifp->if_init = rue_init; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; - - /* MII setup */ - if (mii_phy_probe(self, &sc->rue_miibus, - rue_ifmedia_upd, rue_ifmedia_sts)) { - device_printf(sc->rue_dev, "MII without any PHY!\n"); - goto error2; - } - - sc->rue_qdat.ifp = ifp; - sc->rue_qdat.if_rxstart = rue_rxstart; - - /* Call MI attach routine */ - ether_ifattach(ifp, eaddr); - callout_handle_init(&sc->rue_stat_ch); - usb_register_netisr(); - sc->rue_dying = 0; - - RUE_UNLOCK(sc); - return 0; - - error2: - if_free(ifp); - error1: - RUE_UNLOCK(sc); - mtx_destroy(&sc->rue_mtx); - error: - return ENXIO; -} - -static int -rue_detach(device_t dev) -{ - struct rue_softc *sc; - struct ifnet *ifp; - - sc = device_get_softc(dev); - RUE_LOCK(sc); - ifp = sc->rue_ifp; - - sc->rue_dying = 1; - untimeout(rue_tick, sc, sc->rue_stat_ch); - usb_rem_task(sc->rue_udev, &sc->rue_tick_task); - ether_ifdetach(ifp); - if_free(ifp); - - if (sc->rue_ep[RUE_ENDPT_TX] != NULL) - usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_TX]); - if (sc->rue_ep[RUE_ENDPT_RX] != NULL) - usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_RX]); -#ifdef RUE_INTR_PIPE - if (sc->rue_ep[RUE_ENDPT_INTR] != NULL) - usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_INTR]); -#endif - - RUE_UNLOCK(sc); - mtx_destroy(&sc->rue_mtx); - - return (0); -} - -#ifdef RUE_INTR_PIPE -static void -rue_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct rue_softc *sc = priv; - struct ifnet *ifp; - struct rue_intrpkt *p; - - RUE_LOCK(sc); - ifp = sc->rue_ifp; - - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - RUE_UNLOCK(sc); - return; - } - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - RUE_UNLOCK(sc); - return; - } - device_printf(sc->rue_dev, "usb error on intr: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall(sc->rue_ep[RUE_ENDPT_INTR]); - RUE_UNLOCK(sc); - return; - } - - usbd_get_xfer_status(xfer, NULL, (void **)&p, NULL, NULL); - - ifp->if_ierrors += p->rue_rxlost_cnt; - ifp->if_ierrors += p->rue_crcerr_cnt; - ifp->if_collisions += p->rue_col_cnt; - - RUE_UNLOCK(sc); -} -#endif - -static void -rue_rxstart(struct ifnet *ifp) -{ - struct rue_softc *sc; - struct ue_chain *c; - - sc = ifp->if_softc; - RUE_LOCK(sc); - c = &sc->rue_cdata.ue_rx_chain[sc->rue_cdata.ue_rx_prod]; - - c->ue_mbuf = usb_ether_newbuf(); - if (c->ue_mbuf == NULL) { - printf("%s: no memory for rx list " - "-- packet dropped!\n", device_get_nameunit(sc->rue_dev)); - ifp->if_ierrors++; - RUE_UNLOCK(sc); - return; - } - - /* Setup new transfer. */ - usbd_setup_xfer(c->ue_xfer, sc->rue_ep[RUE_ENDPT_RX], - c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, rue_rxeof); - usbd_transfer(c->ue_xfer); - - RUE_UNLOCK(sc); -} - -/* - * A frame has been uploaded: pass the resulting mbuf chain up to - * the higher level protocols. - */ - -static void -rue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct ue_chain *c = priv; - struct rue_softc *sc = c->ue_sc; - struct mbuf *m; - struct ifnet *ifp; - int total_len = 0; - struct rue_rxpkt r; - - if (sc->rue_dying) - return; - RUE_LOCK(sc); - ifp = sc->rue_ifp; - - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - RUE_UNLOCK(sc); - return; - } - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - RUE_UNLOCK(sc); - return; - } - if (usbd_ratecheck(&sc->rue_rx_notice)) - device_printf(sc->rue_dev, "usb error on rx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall(sc->rue_ep[RUE_ENDPT_RX]); - goto done; - } - - usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); - - if (total_len <= ETHER_CRC_LEN) { - ifp->if_ierrors++; - goto done; - } - - m = c->ue_mbuf; - bcopy(mtod(m, char *) + total_len - 4, (char *)&r, sizeof (r)); - - /* Check recieve packet was valid or not */ - if ((r.rue_rxstat & RUE_RXSTAT_VALID) == 0) { - ifp->if_ierrors++; - goto done; - } - - /* No errors; receive the packet. */ - total_len -= ETHER_CRC_LEN; - - ifp->if_ipackets++; - m->m_pkthdr.rcvif = (void *)&sc->rue_qdat; - m->m_pkthdr.len = m->m_len = total_len; - - /* Put the packet on the special USB input queue. */ - usb_ether_input(m); - - RUE_UNLOCK(sc); - return; - - done: - /* Setup new transfer. */ - usbd_setup_xfer(xfer, sc->rue_ep[RUE_ENDPT_RX], - c, mtod(c->ue_mbuf, char *), UE_BUFSZ, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rue_rxeof); - usbd_transfer(xfer); - RUE_UNLOCK(sc); -} - -/* - * A frame was downloaded to the chip. It's safe for us to clean up - * the list buffers. - */ - -static void -rue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct ue_chain *c = priv; - struct rue_softc *sc = c->ue_sc; - struct ifnet *ifp; - usbd_status err; - - RUE_LOCK(sc); - - ifp = sc->rue_ifp; - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { - RUE_UNLOCK(sc); - return; - } - device_printf(sc->rue_dev, "usb error on tx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall(sc->rue_ep[RUE_ENDPT_TX]); - RUE_UNLOCK(sc); - return; - } - - ifp->if_timer = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err); - - if (c->ue_mbuf != NULL) { - c->ue_mbuf->m_pkthdr.rcvif = ifp; - usb_tx_done(c->ue_mbuf); - c->ue_mbuf = NULL; - } - - if (err) - ifp->if_oerrors++; - else - ifp->if_opackets++; - - RUE_UNLOCK(sc); -} - -static void -rue_tick(void *xsc) -{ - struct rue_softc *sc = xsc; - - if (sc == NULL) - return; - if (sc->rue_dying) - return; - - /* Perform periodic stuff in process context */ - usb_add_task(sc->rue_udev, &sc->rue_tick_task, USB_TASKQ_DRIVER); -} - -static void -rue_tick_task(void *xsc) -{ - struct rue_softc *sc = xsc; - struct ifnet *ifp; - struct mii_data *mii; - - if (sc == NULL) - return; - - RUE_LOCK(sc); - - ifp = sc->rue_ifp; - mii = GET_MII(sc); - if (mii == NULL) { - RUE_UNLOCK(sc); - return; - } - - mii_tick(mii); - if (!sc->rue_link && mii->mii_media_status & IFM_ACTIVE && - IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { - sc->rue_link++; - if (ifp->if_snd.ifq_head != NULL) - rue_start(ifp); - } - - sc->rue_stat_ch = timeout(rue_tick, sc, hz); - - RUE_UNLOCK(sc); -} - -static int -rue_encap(struct rue_softc *sc, struct mbuf *m, int idx) -{ - int total_len; - struct ue_chain *c; - usbd_status err; - - c = &sc->rue_cdata.ue_tx_chain[idx]; - - /* - * Copy the mbuf data into a contiguous buffer - */ - m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf); - c->ue_mbuf = m; - - total_len = m->m_pkthdr.len; - - /* - * This is an undocumented behavior. - * RTL8150 chip doesn't send frame length smaller than - * RUE_MIN_FRAMELEN (60) byte packet. - */ - if (total_len < RUE_MIN_FRAMELEN) - total_len = RUE_MIN_FRAMELEN; - - usbd_setup_xfer(c->ue_xfer, sc->rue_ep[RUE_ENDPT_TX], - c, c->ue_buf, total_len, USBD_FORCE_SHORT_XFER, - 10000, rue_txeof); - - /* Transmit */ - err = usbd_transfer(c->ue_xfer); - if (err != USBD_IN_PROGRESS) { - rue_stop(sc); - return (EIO); - } - - sc->rue_cdata.ue_tx_cnt++; - - return (0); -} - -static void -rue_start(struct ifnet *ifp) -{ - struct rue_softc *sc = ifp->if_softc; - struct mbuf *m_head = NULL; - - RUE_LOCK(sc); - - if (!sc->rue_link) { - RUE_UNLOCK(sc); - return; - } - - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) { - RUE_UNLOCK(sc); - return; - } - - IF_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) { - RUE_UNLOCK(sc); - return; - } - - if (rue_encap(sc, m_head, 0)) { - IF_PREPEND(&ifp->if_snd, m_head); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - RUE_UNLOCK(sc); - return; - } - - /* - * If there's a BPF listener, bounce a copy of this frame - * to him. - */ - BPF_MTAP(ifp, m_head); - - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - - /* - * Set a timeout in case the chip goes out to lunch. - */ - ifp->if_timer = 5; - - RUE_UNLOCK(sc); -} - -static void -rue_init(void *xsc) -{ - struct rue_softc *sc = xsc; - struct ifnet *ifp = sc->rue_ifp; - struct mii_data *mii = GET_MII(sc); - struct ue_chain *c; - usbd_status err; - int i; - int rxcfg; - - RUE_LOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - RUE_UNLOCK(sc); - return; - } - - /* - * Cancel pending I/O and free all RX/TX buffers. - */ - rue_reset(sc); - - /* Set MAC address */ - rue_write_mem(sc, RUE_IDR0, IF_LLADDR(sc->rue_ifp), - ETHER_ADDR_LEN); - - /* Init TX ring. */ - if (usb_ether_tx_list_init(sc, &sc->rue_cdata, - sc->rue_udev) == ENOBUFS) { - device_printf(sc->rue_dev, "tx list init failed\n"); - RUE_UNLOCK(sc); - return; - } - - /* Init RX ring. */ - if (usb_ether_rx_list_init(sc, &sc->rue_cdata, - sc->rue_udev) == ENOBUFS) { - device_printf(sc->rue_dev, "rx list init failed\n"); - RUE_UNLOCK(sc); - return; - } - -#ifdef RUE_INTR_PIPE - sc->rue_cdata.ue_ibuf = malloc(RUE_INTR_PKTLEN, M_USBDEV, M_NOWAIT); -#endif - - /* - * Set the initial TX and RX configuration. - */ - rue_csr_write_1(sc, RUE_TCR, RUE_TCR_CONFIG); - - rxcfg = RUE_RCR_CONFIG; - - /* Set capture broadcast bit to capture broadcast frames. */ - if (ifp->if_flags & IFF_BROADCAST) - rxcfg |= RUE_RCR_AB; - else - rxcfg &= ~RUE_RCR_AB; - - /* If we want promiscuous mode, set the allframes bit. */ - if (ifp->if_flags & IFF_PROMISC) - rxcfg |= RUE_RCR_AAP; - else - rxcfg &= ~RUE_RCR_AAP; - - rue_csr_write_2(sc, RUE_RCR, rxcfg); - - /* Load the multicast filter. */ - rue_setmulti(sc); - - /* Enable RX and TX */ - rue_csr_write_1(sc, RUE_CR, (RUE_CR_TE | RUE_CR_RE | RUE_CR_EP3CLREN)); - - mii_mediachg(mii); - - /* Open RX and TX pipes. */ - err = usbd_open_pipe(sc->rue_iface, sc->rue_ed[RUE_ENDPT_RX], - USBD_EXCLUSIVE_USE, &sc->rue_ep[RUE_ENDPT_RX]); - if (err) { - device_printf(sc->rue_dev, "open rx pipe failed: %s\n", - usbd_errstr(err)); - RUE_UNLOCK(sc); - return; - } - err = usbd_open_pipe(sc->rue_iface, sc->rue_ed[RUE_ENDPT_TX], - USBD_EXCLUSIVE_USE, &sc->rue_ep[RUE_ENDPT_TX]); - if (err) { - device_printf(sc->rue_dev, "open tx pipe failed: %s\n", - usbd_errstr(err)); - RUE_UNLOCK(sc); - return; - } - -#ifdef RUE_INTR_PIPE - err = usbd_open_pipe_intr(sc->rue_iface, sc->rue_ed[RUE_ENDPT_INTR], - USBD_SHORT_XFER_OK, - &sc->rue_ep[RUE_ENDPT_INTR], sc, - sc->rue_cdata.ue_ibuf, RUE_INTR_PKTLEN, - rue_intr, RUE_INTR_INTERVAL); - if (err) { - device_printf(sc->rue_dev, "open intr pipe failed: %s\n", - usbd_errstr(err)); - RUE_UNLOCK(sc); - return; - } -#endif - - /* Start up the receive pipe. */ - for (i = 0; i < UE_RX_LIST_CNT; i++) { - c = &sc->rue_cdata.ue_rx_chain[i]; - usbd_setup_xfer(c->ue_xfer, sc->rue_ep[RUE_ENDPT_RX], - c, mtod(c->ue_mbuf, char *), UE_BUFSZ, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rue_rxeof); - usbd_transfer(c->ue_xfer); - } - - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - sc->rue_stat_ch = timeout(rue_tick, sc, hz); - - RUE_UNLOCK(sc); -} - -/* - * Set media options. - */ - -static int -rue_ifmedia_upd(struct ifnet *ifp) -{ - struct rue_softc *sc = ifp->if_softc; - struct mii_data *mii = GET_MII(sc); - - sc->rue_link = 0; - if (mii->mii_instance) { - struct mii_softc *miisc; - LIST_FOREACH (miisc, &mii->mii_phys, mii_list) - mii_phy_reset(miisc); - } - mii_mediachg(mii); - - return (0); -} - -/* - * Report current media status. - */ - -static void -rue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) -{ - struct rue_softc *sc = ifp->if_softc; - struct mii_data *mii = GET_MII(sc); - - mii_pollstat(mii); - ifmr->ifm_active = mii->mii_media_active; - ifmr->ifm_status = mii->mii_media_status; -} - -static int -rue_ioctl(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct rue_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; - struct mii_data *mii; - int error = 0; - - RUE_LOCK(sc); - - switch (command) { - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING && - ifp->if_flags & IFF_PROMISC && - !(sc->rue_if_flags & IFF_PROMISC)) { - RUE_SETBIT_2(sc, RUE_RCR, - (RUE_RCR_AAM | RUE_RCR_AAP)); - rue_setmulti(sc); - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - sc->rue_if_flags & IFF_PROMISC) { - RUE_CLRBIT_2(sc, RUE_RCR, - (RUE_RCR_AAM | RUE_RCR_AAP)); - rue_setmulti(sc); - } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - rue_init(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rue_stop(sc); - } - sc->rue_if_flags = ifp->if_flags; - error = 0; - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - rue_setmulti(sc); - error = 0; - break; - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: - mii = GET_MII(sc); - error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); - break; - default: - error = ether_ioctl(ifp, command, data); - break; - } - - RUE_UNLOCK(sc); - - return (error); -} - -static void -rue_watchdog(struct ifnet *ifp) -{ - struct rue_softc *sc = ifp->if_softc; - struct ue_chain *c; - usbd_status stat; - - RUE_LOCK(sc); - - ifp->if_oerrors++; - device_printf(sc->rue_dev, "watchdog timeout\n"); - - c = &sc->rue_cdata.ue_tx_chain[0]; - usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat); - rue_txeof(c->ue_xfer, c, stat); - - if (ifp->if_snd.ifq_head != NULL) - rue_start(ifp); - - RUE_UNLOCK(sc); -} - -/* - * Stop the adapter and free any mbufs allocated to the - * RX and TX lists. - */ - -static void -rue_stop(struct rue_softc *sc) -{ - usbd_status err; - struct ifnet *ifp; - - RUE_LOCK(sc); - - ifp = sc->rue_ifp; - ifp->if_timer = 0; - - rue_csr_write_1(sc, RUE_CR, 0x00); - rue_reset(sc); - - untimeout(rue_tick, sc, sc->rue_stat_ch); - - /* Stop transfers. */ - if (sc->rue_ep[RUE_ENDPT_RX] != NULL) { - err = usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_RX]); - if (err) { - device_printf(sc->rue_dev, "abort rx pipe failed: %s\n", - usbd_errstr(err)); - } - err = usbd_close_pipe(sc->rue_ep[RUE_ENDPT_RX]); - if (err) { - device_printf(sc->rue_dev, "close rx pipe failed: %s\n", - usbd_errstr(err)); - } - sc->rue_ep[RUE_ENDPT_RX] = NULL; - } - - if (sc->rue_ep[RUE_ENDPT_TX] != NULL) { - err = usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_TX]); - if (err) { - device_printf(sc->rue_dev, "abort tx pipe failed: %s\n", - usbd_errstr(err)); - } - err = usbd_close_pipe(sc->rue_ep[RUE_ENDPT_TX]); - if (err) { - device_printf(sc->rue_dev, "close tx pipe failed: %s\n", - usbd_errstr(err)); - } - sc->rue_ep[RUE_ENDPT_TX] = NULL; - } - -#ifdef RUE_INTR_PIPE - if (sc->rue_ep[RUE_ENDPT_INTR] != NULL) { - err = usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_INTR]); - if (err) { - device_printf(sc->rue_dev, "abort intr pipe failed: %s\n", - usbd_errstr(err)); - } - err = usbd_close_pipe(sc->rue_ep[RUE_ENDPT_INTR]); - if (err) { - device_printf(sc->rue_dev, "close intr pipe failed: %s\n", - usbd_errstr(err)); - } - sc->rue_ep[RUE_ENDPT_INTR] = NULL; - } -#endif - - /* Free RX resources. */ - usb_ether_rx_list_free(&sc->rue_cdata); - /* Free TX resources. */ - usb_ether_tx_list_free(&sc->rue_cdata); - -#ifdef RUE_INTR_PIPE - free(sc->rue_cdata.ue_ibuf, M_USBDEV); - sc->rue_cdata.ue_ibuf = NULL; -#endif - - sc->rue_link = 0; - - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - - RUE_UNLOCK(sc); -} - -/* - * Stop all chip I/O so that the kernel's probe routines don't - * get confused by errant DMAs when rebooting. - */ - -static int -rue_shutdown(device_t dev) -{ - struct rue_softc *sc; - - sc = device_get_softc(dev); - - sc->rue_dying++; - RUE_LOCK(sc); - rue_reset(sc); - rue_stop(sc); - RUE_UNLOCK(sc); - - return (0); -} diff --git a/sys/legacy/dev/usb/if_ruereg.h b/sys/legacy/dev/usb/if_ruereg.h deleted file mode 100644 index da6470f..0000000 --- a/sys/legacy/dev/usb/if_ruereg.h +++ /dev/null @@ -1,226 +0,0 @@ -/*- - * Copyright (c) 2001-2003, Shunsuke Akiyama <akiyama@FreeBSD.org>. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * $FreeBSD$ - */ - -#ifndef _IF_RUEREG_H_ -#define _IF_RUEREG_H_ - -#define RUE_INTR_PIPE 1 /* Use INTR PIPE */ - -#define RUE_CONFIG_NO 1 -#define RUE_IFACE_IDX 0 - -#define RUE_ENDPT_RX 0x0 -#define RUE_ENDPT_TX 0x1 -#define RUE_ENDPT_INTR 0x2 -#define RUE_ENDPT_MAX 0x3 - -#define RUE_INTR_PKTLEN 0x8 - -#define RUE_TIMEOUT 1000 -#define ETHER_ALIGN 2 -#define RUE_MIN_FRAMELEN 60 -#define RUE_INTR_INTERVAL 100 /* ms */ - -/* - * Registers - */ - -#define RUE_IDR0 0x0120 -#define RUE_IDR1 0x0121 -#define RUE_IDR2 0x0122 -#define RUE_IDR3 0x0123 -#define RUE_IDR4 0x0124 -#define RUE_IDR5 0x0125 - -#define RUE_MAR0 0x0126 -#define RUE_MAR1 0x0127 -#define RUE_MAR2 0x0128 -#define RUE_MAR3 0x0129 -#define RUE_MAR4 0x012A -#define RUE_MAR5 0x012B -#define RUE_MAR6 0x012C -#define RUE_MAR7 0x012D - -#define RUE_CR 0x012E /* B, R/W */ -#define RUE_CR_SOFT_RST 0x10 -#define RUE_CR_RE 0x08 -#define RUE_CR_TE 0x04 -#define RUE_CR_EP3CLREN 0x02 - -#define RUE_TCR 0x012F /* B, R/W */ -#define RUE_TCR_TXRR1 0x80 -#define RUE_TCR_TXRR0 0x40 -#define RUE_TCR_IFG1 0x10 -#define RUE_TCR_IFG0 0x08 -#define RUE_TCR_NOCRC 0x01 -#define RUE_TCR_CONFIG (RUE_TCR_TXRR1|RUE_TCR_TXRR0|RUE_TCR_IFG1|RUE_TCR_IFG0) - -#define RUE_RCR 0x0130 /* W, R/W */ -#define RUE_RCR_TAIL 0x80 -#define RUE_RCR_AER 0x40 -#define RUE_RCR_AR 0x20 -#define RUE_RCR_AM 0x10 -#define RUE_RCR_AB 0x08 -#define RUE_RCR_AD 0x04 -#define RUE_RCR_AAM 0x02 -#define RUE_RCR_AAP 0x01 -#define RUE_RCR_CONFIG (RUE_RCR_TAIL|RUE_RCR_AD) - -#define RUE_TSR 0x0132 -#define RUE_RSR 0x0133 -#define RUE_CON0 0x0135 -#define RUE_CON1 0x0136 -#define RUE_MSR 0x0137 -#define RUE_PHYADD 0x0138 -#define RUE_PHYDAT 0x0139 - -#define RUE_PHYCNT 0x013B /* B, R/W */ -#define RUE_PHYCNT_PHYOWN 0x40 -#define RUE_PHYCNT_RWCR 0x20 - -#define RUE_GPPC 0x013D -#define RUE_WAKECNT 0x013E - -#define RUE_BMCR 0x0140 -#define RUE_BMCR_SPD_SET 0x2000 -#define RUE_BMCR_DUPLEX 0x0100 - -#define RUE_BMSR 0x0142 - -#define RUE_ANAR 0x0144 /* W, R/W */ -#define RUE_ANAR_PAUSE 0x0400 - -#define RUE_ANLP 0x0146 /* W, R/O */ -#define RUE_ANLP_PAUSE 0x0400 - -#define RUE_AER 0x0148 - -#define RUE_NWAYT 0x014A -#define RUE_CSCR 0x014C - -#define RUE_CRC0 0x014E -#define RUE_CRC1 0x0150 -#define RUE_CRC2 0x0152 -#define RUE_CRC3 0x0154 -#define RUE_CRC4 0x0156 - -#define RUE_BYTEMASK0 0x0158 -#define RUE_BYTEMASK1 0x0160 -#define RUE_BYTEMASK2 0x0168 -#define RUE_BYTEMASK3 0x0170 -#define RUE_BYTEMASK4 0x0178 - -#define RUE_PHY1 0x0180 -#define RUE_PHY2 0x0184 - -#define RUE_TW1 0x0186 - -#define RUE_REG_MIN 0x0120 -#define RUE_REG_MAX 0x0189 - -/* - * EEPROM address declarations - */ - -#define RUE_EEPROM_BASE 0x1200 - -#define RUE_EEPROM_IDR0 (RUE_EEPROM_BASE + 0x02) -#define RUE_EEPROM_IDR1 (RUE_EEPROM_BASE + 0x03) -#define RUE_EEPROM_IDR2 (RUE_EEPROM_BASE + 0x03) -#define RUE_EEPROM_IDR3 (RUE_EEPROM_BASE + 0x03) -#define RUE_EEPROM_IDR4 (RUE_EEPROM_BASE + 0x03) -#define RUE_EEPROM_IDR5 (RUE_EEPROM_BASE + 0x03) - -#define RUE_EEPROM_INTERVAL (RUE_EEPROM_BASE + 0x17) - -struct rue_intrpkt { - u_int8_t rue_tsr; - u_int8_t rue_rsr; - u_int8_t rue_gep_msr; - u_int8_t rue_waksr; - u_int8_t rue_txok_cnt; - u_int8_t rue_rxlost_cnt; - u_int8_t rue_crcerr_cnt; - u_int8_t rue_col_cnt; -}; - -struct rue_rxpkt { - u_int16_t rue_pktlen : 12; - u_int16_t rue_rxstat : 4; -}; - -#define RUE_RXSTAT_VALID 0x01 -#define RUE_RXSTAT_RUNT 0x02 -#define RUE_RXSTAT_PMATCH 0x04 -#define RUE_RXSTAT_MCAST 0x08 - -#define RUE_RXSTAT_MASK RUE_RXSTAT_VALID - -struct rue_type { - u_int16_t rue_vid; - u_int16_t rue_did; -}; - -struct rue_softc { - struct ifnet *rue_ifp; - device_t rue_dev; - device_t rue_miibus; - usbd_device_handle rue_udev; - usbd_interface_handle rue_iface; - struct rue_type *rue_info; - int rue_ed[RUE_ENDPT_MAX]; - usbd_pipe_handle rue_ep[RUE_ENDPT_MAX]; - int rue_unit; - u_int8_t rue_link; - int rue_if_flags; - struct ue_cdata rue_cdata; - struct callout_handle rue_stat_ch; - struct mtx rue_mtx; - char rue_dying; - struct timeval rue_rx_notice; - struct usb_qdat rue_qdat; - struct usb_task rue_tick_task; -}; - -#if defined(__FreeBSD__) -#define GET_MII(sc) (device_get_softc((sc)->rue_miibus)) -#elif defined(__NetBSD__) -#define GET_MII(sc) (&(sc)->rue_mii) -#elif defined(__OpenBSD__) -#define GET_MII(sc) (&(sc)->rue_mii) -#endif - -#if 0 -#define RUE_LOCK(_sc) mtx_lock(&(_sc)->rue_mtx) -#define RUE_UNLOCK(_sc) mtx_unlock(&(_sc)->rue_mtx) -#else -#define RUE_LOCK(_sc) -#define RUE_UNLOCK(_sc) -#endif - -#endif /* _IF_RUEREG_H_ */ diff --git a/sys/legacy/dev/usb/if_rum.c b/sys/legacy/dev/usb/if_rum.c deleted file mode 100644 index c0c7cb6..0000000 --- a/sys/legacy/dev/usb/if_rum.c +++ /dev/null @@ -1,2560 +0,0 @@ -/* $FreeBSD$ */ - -/*- - * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr> - * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/*- - * Ralink Technology RT2501USB/RT2601USB chipset driver - * http://www.ralinktech.com.tw/ - */ - -#include <sys/param.h> -#include <sys/sysctl.h> -#include <sys/sockio.h> -#include <sys/mbuf.h> -#include <sys/kernel.h> -#include <sys/socket.h> -#include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/endian.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <net/bpf.h> -#include <net/if.h> -#include <net/if_arp.h> -#include <net/ethernet.h> -#include <net/if_dl.h> -#include <net/if_media.h> -#include <net/if_types.h> - -#include <net80211/ieee80211_var.h> -#include <net80211/ieee80211_amrr.h> -#include <net80211/ieee80211_phy.h> -#include <net80211/ieee80211_radiotap.h> -#include <net80211/ieee80211_regdomain.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include "usbdevs.h" - -#include <dev/usb/if_rumreg.h> -#include <dev/usb/if_rumvar.h> -#include <dev/usb/rt2573_ucode.h> - -#ifdef USB_DEBUG -#define DPRINTF(x) do { if (rumdebug > 0) printf x; } while (0) -#define DPRINTFN(n, x) do { if (rumdebug >= (n)) printf x; } while (0) -int rumdebug = 0; -SYSCTL_NODE(_hw_usb, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum"); -SYSCTL_INT(_hw_usb_rum, OID_AUTO, debug, CTLFLAG_RW, &rumdebug, 0, - "rum debug level"); -#else -#define DPRINTF(x) -#define DPRINTFN(n, x) -#endif - -/* various supported device vendors/products */ -static const struct usb_devno rum_devs[] = { - { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM }, - { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2 }, - { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_3 }, - { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_4 }, - { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700 }, - { USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GO }, - { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_1 }, - { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_2 }, - { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050A }, - { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050V3 }, - { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GC }, - { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GR }, - { USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU2 }, - { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GL }, - { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GPX }, - { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CWD854F }, - { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RT2573 }, - { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWLG122C1 }, - { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA1340 }, - { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA111 }, - { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA110 }, - { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB01GS }, - { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWI05GS }, - { USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT2573 }, - { USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_RT2573 }, - { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254LB }, - { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP }, - { USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G }, - { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_G54HP }, - { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HP }, - { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HG }, - { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_1 }, - { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2 }, - { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3 }, - { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_4 }, - { USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RT2573 }, - { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54HP }, - { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54MINI2 }, - { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMM }, - { USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573 }, - { USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_2 }, - { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573 }, - { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573_2 }, - { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2671 }, - { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113R2 }, - { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL172 }, - { USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2573 }, - { USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573 } -}; - -MODULE_DEPEND(rum, wlan, 1, 1, 1); -MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1); -MODULE_DEPEND(rum, usb, 1, 1, 1); - -static struct ieee80211vap *rum_vap_create(struct ieee80211com *, - const char name[IFNAMSIZ], int unit, int opmode, - int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]); -static void rum_vap_delete(struct ieee80211vap *); -static int rum_alloc_tx_list(struct rum_softc *); -static void rum_free_tx_list(struct rum_softc *); -static int rum_alloc_rx_list(struct rum_softc *); -static void rum_free_rx_list(struct rum_softc *); -static void rum_task(void *); -static void rum_scantask(void *); -static int rum_newstate(struct ieee80211vap *, - enum ieee80211_state, int); -static void rum_txeof(usbd_xfer_handle, usbd_private_handle, - usbd_status); -static void rum_rxeof(usbd_xfer_handle, usbd_private_handle, - usbd_status); -static void rum_setup_tx_desc(struct rum_softc *, - struct rum_tx_desc *, uint32_t, uint16_t, int, - int); -static int rum_tx_mgt(struct rum_softc *, struct mbuf *, - struct ieee80211_node *); -static int rum_tx_raw(struct rum_softc *, struct mbuf *, - struct ieee80211_node *, - const struct ieee80211_bpf_params *); -static int rum_tx_data(struct rum_softc *, struct mbuf *, - struct ieee80211_node *); -static void rum_start(struct ifnet *); -static void rum_watchdog(void *); -static int rum_ioctl(struct ifnet *, u_long, caddr_t); -static void rum_eeprom_read(struct rum_softc *, uint16_t, void *, - int); -static uint32_t rum_read(struct rum_softc *, uint16_t); -static void rum_read_multi(struct rum_softc *, uint16_t, void *, - int); -static void rum_write(struct rum_softc *, uint16_t, uint32_t); -static void rum_write_multi(struct rum_softc *, uint16_t, void *, - size_t); -static void rum_bbp_write(struct rum_softc *, uint8_t, uint8_t); -static uint8_t rum_bbp_read(struct rum_softc *, uint8_t); -static void rum_rf_write(struct rum_softc *, uint8_t, uint32_t); -static void rum_select_antenna(struct rum_softc *); -static void rum_enable_mrr(struct rum_softc *); -static void rum_set_txpreamble(struct rum_softc *); -static void rum_set_basicrates(struct rum_softc *); -static void rum_select_band(struct rum_softc *, - struct ieee80211_channel *); -static void rum_set_chan(struct rum_softc *, - struct ieee80211_channel *); -static void rum_enable_tsf_sync(struct rum_softc *); -static void rum_update_slot(struct ifnet *); -static void rum_set_bssid(struct rum_softc *, const uint8_t *); -static void rum_set_macaddr(struct rum_softc *, const uint8_t *); -static void rum_update_promisc(struct rum_softc *); -static const char *rum_get_rf(int); -static void rum_read_eeprom(struct rum_softc *); -static int rum_bbp_init(struct rum_softc *); -static void rum_init_locked(struct rum_softc *); -static void rum_init(void *); -static void rum_stop(void *); -static int rum_load_microcode(struct rum_softc *, const u_char *, - size_t); -static int rum_prepare_beacon(struct rum_softc *, - struct ieee80211vap *); -static int rum_raw_xmit(struct ieee80211_node *, struct mbuf *, - const struct ieee80211_bpf_params *); -static struct ieee80211_node *rum_node_alloc(struct ieee80211vap *, - const uint8_t mac[IEEE80211_ADDR_LEN]); -static void rum_newassoc(struct ieee80211_node *, int); -static void rum_scan_start(struct ieee80211com *); -static void rum_scan_end(struct ieee80211com *); -static void rum_set_channel(struct ieee80211com *); -static int rum_get_rssi(struct rum_softc *, uint8_t); -static void rum_amrr_start(struct rum_softc *, - struct ieee80211_node *); -static void rum_amrr_timeout(void *); -static void rum_amrr_update(usbd_xfer_handle, usbd_private_handle, - usbd_status); - -static const struct { - uint32_t reg; - uint32_t val; -} rum_def_mac[] = { - { RT2573_TXRX_CSR0, 0x025fb032 }, - { RT2573_TXRX_CSR1, 0x9eaa9eaf }, - { RT2573_TXRX_CSR2, 0x8a8b8c8d }, - { RT2573_TXRX_CSR3, 0x00858687 }, - { RT2573_TXRX_CSR7, 0x2e31353b }, - { RT2573_TXRX_CSR8, 0x2a2a2a2c }, - { RT2573_TXRX_CSR15, 0x0000000f }, - { RT2573_MAC_CSR6, 0x00000fff }, - { RT2573_MAC_CSR8, 0x016c030a }, - { RT2573_MAC_CSR10, 0x00000718 }, - { RT2573_MAC_CSR12, 0x00000004 }, - { RT2573_MAC_CSR13, 0x00007f00 }, - { RT2573_SEC_CSR0, 0x00000000 }, - { RT2573_SEC_CSR1, 0x00000000 }, - { RT2573_SEC_CSR5, 0x00000000 }, - { RT2573_PHY_CSR1, 0x000023b0 }, - { RT2573_PHY_CSR5, 0x00040a06 }, - { RT2573_PHY_CSR6, 0x00080606 }, - { RT2573_PHY_CSR7, 0x00000408 }, - { RT2573_AIFSN_CSR, 0x00002273 }, - { RT2573_CWMIN_CSR, 0x00002344 }, - { RT2573_CWMAX_CSR, 0x000034aa } -}; - -static const struct { - uint8_t reg; - uint8_t val; -} rum_def_bbp[] = { - { 3, 0x80 }, - { 15, 0x30 }, - { 17, 0x20 }, - { 21, 0xc8 }, - { 22, 0x38 }, - { 23, 0x06 }, - { 24, 0xfe }, - { 25, 0x0a }, - { 26, 0x0d }, - { 32, 0x0b }, - { 34, 0x12 }, - { 37, 0x07 }, - { 39, 0xf8 }, - { 41, 0x60 }, - { 53, 0x10 }, - { 54, 0x18 }, - { 60, 0x10 }, - { 61, 0x04 }, - { 62, 0x04 }, - { 75, 0xfe }, - { 86, 0xfe }, - { 88, 0xfe }, - { 90, 0x0f }, - { 99, 0x00 }, - { 102, 0x16 }, - { 107, 0x04 } -}; - -static const struct rfprog { - uint8_t chan; - uint32_t r1, r2, r3, r4; -} rum_rf5226[] = { - { 1, 0x00b03, 0x001e1, 0x1a014, 0x30282 }, - { 2, 0x00b03, 0x001e1, 0x1a014, 0x30287 }, - { 3, 0x00b03, 0x001e2, 0x1a014, 0x30282 }, - { 4, 0x00b03, 0x001e2, 0x1a014, 0x30287 }, - { 5, 0x00b03, 0x001e3, 0x1a014, 0x30282 }, - { 6, 0x00b03, 0x001e3, 0x1a014, 0x30287 }, - { 7, 0x00b03, 0x001e4, 0x1a014, 0x30282 }, - { 8, 0x00b03, 0x001e4, 0x1a014, 0x30287 }, - { 9, 0x00b03, 0x001e5, 0x1a014, 0x30282 }, - { 10, 0x00b03, 0x001e5, 0x1a014, 0x30287 }, - { 11, 0x00b03, 0x001e6, 0x1a014, 0x30282 }, - { 12, 0x00b03, 0x001e6, 0x1a014, 0x30287 }, - { 13, 0x00b03, 0x001e7, 0x1a014, 0x30282 }, - { 14, 0x00b03, 0x001e8, 0x1a014, 0x30284 }, - - { 34, 0x00b03, 0x20266, 0x36014, 0x30282 }, - { 38, 0x00b03, 0x20267, 0x36014, 0x30284 }, - { 42, 0x00b03, 0x20268, 0x36014, 0x30286 }, - { 46, 0x00b03, 0x20269, 0x36014, 0x30288 }, - - { 36, 0x00b03, 0x00266, 0x26014, 0x30288 }, - { 40, 0x00b03, 0x00268, 0x26014, 0x30280 }, - { 44, 0x00b03, 0x00269, 0x26014, 0x30282 }, - { 48, 0x00b03, 0x0026a, 0x26014, 0x30284 }, - { 52, 0x00b03, 0x0026b, 0x26014, 0x30286 }, - { 56, 0x00b03, 0x0026c, 0x26014, 0x30288 }, - { 60, 0x00b03, 0x0026e, 0x26014, 0x30280 }, - { 64, 0x00b03, 0x0026f, 0x26014, 0x30282 }, - - { 100, 0x00b03, 0x0028a, 0x2e014, 0x30280 }, - { 104, 0x00b03, 0x0028b, 0x2e014, 0x30282 }, - { 108, 0x00b03, 0x0028c, 0x2e014, 0x30284 }, - { 112, 0x00b03, 0x0028d, 0x2e014, 0x30286 }, - { 116, 0x00b03, 0x0028e, 0x2e014, 0x30288 }, - { 120, 0x00b03, 0x002a0, 0x2e014, 0x30280 }, - { 124, 0x00b03, 0x002a1, 0x2e014, 0x30282 }, - { 128, 0x00b03, 0x002a2, 0x2e014, 0x30284 }, - { 132, 0x00b03, 0x002a3, 0x2e014, 0x30286 }, - { 136, 0x00b03, 0x002a4, 0x2e014, 0x30288 }, - { 140, 0x00b03, 0x002a6, 0x2e014, 0x30280 }, - - { 149, 0x00b03, 0x002a8, 0x2e014, 0x30287 }, - { 153, 0x00b03, 0x002a9, 0x2e014, 0x30289 }, - { 157, 0x00b03, 0x002ab, 0x2e014, 0x30281 }, - { 161, 0x00b03, 0x002ac, 0x2e014, 0x30283 }, - { 165, 0x00b03, 0x002ad, 0x2e014, 0x30285 } -}, rum_rf5225[] = { - { 1, 0x00b33, 0x011e1, 0x1a014, 0x30282 }, - { 2, 0x00b33, 0x011e1, 0x1a014, 0x30287 }, - { 3, 0x00b33, 0x011e2, 0x1a014, 0x30282 }, - { 4, 0x00b33, 0x011e2, 0x1a014, 0x30287 }, - { 5, 0x00b33, 0x011e3, 0x1a014, 0x30282 }, - { 6, 0x00b33, 0x011e3, 0x1a014, 0x30287 }, - { 7, 0x00b33, 0x011e4, 0x1a014, 0x30282 }, - { 8, 0x00b33, 0x011e4, 0x1a014, 0x30287 }, - { 9, 0x00b33, 0x011e5, 0x1a014, 0x30282 }, - { 10, 0x00b33, 0x011e5, 0x1a014, 0x30287 }, - { 11, 0x00b33, 0x011e6, 0x1a014, 0x30282 }, - { 12, 0x00b33, 0x011e6, 0x1a014, 0x30287 }, - { 13, 0x00b33, 0x011e7, 0x1a014, 0x30282 }, - { 14, 0x00b33, 0x011e8, 0x1a014, 0x30284 }, - - { 34, 0x00b33, 0x01266, 0x26014, 0x30282 }, - { 38, 0x00b33, 0x01267, 0x26014, 0x30284 }, - { 42, 0x00b33, 0x01268, 0x26014, 0x30286 }, - { 46, 0x00b33, 0x01269, 0x26014, 0x30288 }, - - { 36, 0x00b33, 0x01266, 0x26014, 0x30288 }, - { 40, 0x00b33, 0x01268, 0x26014, 0x30280 }, - { 44, 0x00b33, 0x01269, 0x26014, 0x30282 }, - { 48, 0x00b33, 0x0126a, 0x26014, 0x30284 }, - { 52, 0x00b33, 0x0126b, 0x26014, 0x30286 }, - { 56, 0x00b33, 0x0126c, 0x26014, 0x30288 }, - { 60, 0x00b33, 0x0126e, 0x26014, 0x30280 }, - { 64, 0x00b33, 0x0126f, 0x26014, 0x30282 }, - - { 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 }, - { 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 }, - { 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 }, - { 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 }, - { 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 }, - { 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 }, - { 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 }, - { 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 }, - { 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 }, - { 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 }, - { 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 }, - - { 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 }, - { 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 }, - { 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 }, - { 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 }, - { 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 } -}; - -static int -rum_match(device_t self) -{ - struct usb_attach_arg *uaa = device_get_ivars(self); - - if (uaa->iface != NULL) - return UMATCH_NONE; - - return (usb_lookup(rum_devs, uaa->vendor, uaa->product) != NULL) ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE; -} - -static int -rum_attach(device_t self) -{ - struct rum_softc *sc = device_get_softc(self); - struct usb_attach_arg *uaa = device_get_ivars(self); - struct ieee80211com *ic; - struct ifnet *ifp; - const uint8_t *ucode = NULL; - usb_interface_descriptor_t *id; - usb_endpoint_descriptor_t *ed; - usbd_status error; - int i, ntries, size; - uint8_t bands; - uint32_t tmp; - - sc->sc_udev = uaa->device; - sc->sc_dev = self; - - if (usbd_set_config_no(sc->sc_udev, RT2573_CONFIG_NO, 0) != 0) { - device_printf(self, "could not set configuration no\n"); - return ENXIO; - } - - /* get the first interface handle */ - error = usbd_device2interface_handle(sc->sc_udev, RT2573_IFACE_INDEX, - &sc->sc_iface); - if (error != 0) { - device_printf(self, "could not get interface handle\n"); - return ENXIO; - } - - /* - * Find endpoints. - */ - id = usbd_get_interface_descriptor(sc->sc_iface); - - sc->sc_rx_no = sc->sc_tx_no = -1; - for (i = 0; i < id->bNumEndpoints; i++) { - ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); - if (ed == NULL) { - device_printf(self, - "no endpoint descriptor for iface %d\n", i); - return ENXIO; - } - - if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) - sc->sc_rx_no = ed->bEndpointAddress; - else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) - sc->sc_tx_no = ed->bEndpointAddress; - } - if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) { - device_printf(self, "missing endpoint\n"); - return ENXIO; - } - - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(self, "can not if_alloc()\n"); - return ENXIO; - } - ic = ifp->if_l2com; - - mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); - - usb_init_task(&sc->sc_task, rum_task, sc); - usb_init_task(&sc->sc_scantask, rum_scantask, sc); - callout_init(&sc->watchdog_ch, 0); - - /* retrieve RT2573 rev. no */ - for (ntries = 0; ntries < 1000; ntries++) { - if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0) - break; - DELAY(1000); - } - if (ntries == 1000) { - device_printf(self, "timeout waiting for chip to settle\n"); - goto bad; - } - - /* retrieve MAC address and various other things from EEPROM */ - rum_read_eeprom(sc); - - device_printf(self, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n", - tmp, rum_get_rf(sc->rf_rev)); - - ucode = rt2573_ucode; - size = sizeof rt2573_ucode; - error = rum_load_microcode(sc, ucode, size); - if (error != 0) { - device_printf(self, "could not load 8051 microcode\n"); - goto bad; - } - - ifp->if_softc = sc; - if_initname(ifp, "rum", device_get_unit(sc->sc_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSGIANT; /* USB stack is still under Giant lock */ - ifp->if_init = rum_init; - ifp->if_ioctl = rum_ioctl; - ifp->if_start = rum_start; - IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); - ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; - ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ - - /* set device capabilities */ - ic->ic_caps = - IEEE80211_C_STA /* station mode supported */ - | IEEE80211_C_IBSS /* IBSS mode supported */ - | IEEE80211_C_MONITOR /* monitor mode supported */ - | IEEE80211_C_HOSTAP /* HostAp mode supported */ - | IEEE80211_C_TXPMGT /* tx power management */ - | IEEE80211_C_SHPREAMBLE /* short preamble supported */ - | IEEE80211_C_SHSLOT /* short slot time supported */ - | IEEE80211_C_BGSCAN /* bg scanning supported */ - | IEEE80211_C_WPA /* 802.11i */ - ; - - bands = 0; - setbit(&bands, IEEE80211_MODE_11B); - setbit(&bands, IEEE80211_MODE_11G); - if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226) - setbit(&bands, IEEE80211_MODE_11A); - ieee80211_init_channels(ic, NULL, &bands); - - ieee80211_ifattach(ic); - ic->ic_newassoc = rum_newassoc; - ic->ic_raw_xmit = rum_raw_xmit; - ic->ic_node_alloc = rum_node_alloc; - ic->ic_scan_start = rum_scan_start; - ic->ic_scan_end = rum_scan_end; - ic->ic_set_channel = rum_set_channel; - - ic->ic_vap_create = rum_vap_create; - ic->ic_vap_delete = rum_vap_delete; - - sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); - - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap)); - - sc->sc_rxtap_len = sizeof sc->sc_rxtap; - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT); - - sc->sc_txtap_len = sizeof sc->sc_txtap; - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT); - - if (bootverbose) - ieee80211_announce(ic); - - return 0; -bad: - mtx_destroy(&sc->sc_mtx); - if_free(ifp); - return ENXIO; -} - -static int -rum_detach(device_t self) -{ - struct rum_softc *sc = device_get_softc(self); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - rum_stop(sc); - bpfdetach(ifp); - ieee80211_ifdetach(ic); - - usb_rem_task(sc->sc_udev, &sc->sc_task); - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - callout_stop(&sc->watchdog_ch); - - if (sc->amrr_xfer != NULL) { - usbd_free_xfer(sc->amrr_xfer); - sc->amrr_xfer = NULL; - } - - if (sc->sc_rx_pipeh != NULL) { - usbd_abort_pipe(sc->sc_rx_pipeh); - usbd_close_pipe(sc->sc_rx_pipeh); - } - if (sc->sc_tx_pipeh != NULL) { - usbd_abort_pipe(sc->sc_tx_pipeh); - usbd_close_pipe(sc->sc_tx_pipeh); - } - - rum_free_rx_list(sc); - rum_free_tx_list(sc); - - if_free(ifp); - mtx_destroy(&sc->sc_mtx); - - return 0; -} - -static struct ieee80211vap * -rum_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]) -{ - struct rum_vap *rvp; - struct ieee80211vap *vap; - - if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ - return NULL; - rvp = (struct rum_vap *) malloc(sizeof(struct rum_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (rvp == NULL) - return NULL; - vap = &rvp->vap; - /* enable s/w bmiss handling for sta mode */ - ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); - - /* override state transition machine */ - rvp->newstate = vap->iv_newstate; - vap->iv_newstate = rum_newstate; - - callout_init(&rvp->amrr_ch, 0); - ieee80211_amrr_init(&rvp->amrr, vap, - IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, - IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, - 1000 /* 1 sec */); - - /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); - ic->ic_opmode = opmode; - return vap; -} - -static void -rum_vap_delete(struct ieee80211vap *vap) -{ - struct rum_vap *rvp = RUM_VAP(vap); - - callout_stop(&rvp->amrr_ch); - ieee80211_amrr_cleanup(&rvp->amrr); - ieee80211_vap_detach(vap); - free(rvp, M_80211_VAP); -} - -static int -rum_alloc_tx_list(struct rum_softc *sc) -{ - struct rum_tx_data *data; - int i, error; - - sc->tx_queued = sc->tx_cur = 0; - - for (i = 0; i < RUM_TX_LIST_COUNT; i++) { - data = &sc->tx_data[i]; - - data->sc = sc; - - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { - device_printf(sc->sc_dev, - "could not allocate tx xfer\n"); - error = ENOMEM; - goto fail; - } - data->buf = usbd_alloc_buffer(data->xfer, - RT2573_TX_DESC_SIZE + MCLBYTES); - if (data->buf == NULL) { - device_printf(sc->sc_dev, - "could not allocate tx buffer\n"); - error = ENOMEM; - goto fail; - } - /* clean Tx descriptor */ - bzero(data->buf, RT2573_TX_DESC_SIZE); - } - - return 0; - -fail: rum_free_tx_list(sc); - return error; -} - -static void -rum_free_tx_list(struct rum_softc *sc) -{ - struct rum_tx_data *data; - int i; - - for (i = 0; i < RUM_TX_LIST_COUNT; i++) { - data = &sc->tx_data[i]; - - if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); - data->xfer = NULL; - } - - if (data->ni != NULL) { - ieee80211_free_node(data->ni); - data->ni = NULL; - } - } -} - -static int -rum_alloc_rx_list(struct rum_softc *sc) -{ - struct rum_rx_data *data; - int i, error; - - for (i = 0; i < RUM_RX_LIST_COUNT; i++) { - data = &sc->rx_data[i]; - - data->sc = sc; - - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { - device_printf(sc->sc_dev, - "could not allocate rx xfer\n"); - error = ENOMEM; - goto fail; - } - if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) { - device_printf(sc->sc_dev, - "could not allocate rx buffer\n"); - error = ENOMEM; - goto fail; - } - - data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (data->m == NULL) { - device_printf(sc->sc_dev, - "could not allocate rx mbuf\n"); - error = ENOMEM; - goto fail; - } - - data->buf = mtod(data->m, uint8_t *); - } - - return 0; - -fail: rum_free_rx_list(sc); - return error; -} - -static void -rum_free_rx_list(struct rum_softc *sc) -{ - struct rum_rx_data *data; - int i; - - for (i = 0; i < RUM_RX_LIST_COUNT; i++) { - data = &sc->rx_data[i]; - - if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); - data->xfer = NULL; - } - if (data->m != NULL) { - m_freem(data->m); - data->m = NULL; - } - } -} - -static void -rum_task(void *arg) -{ - struct rum_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct rum_vap *rvp = RUM_VAP(vap); - const struct ieee80211_txparam *tp; - enum ieee80211_state ostate; - struct ieee80211_node *ni; - uint32_t tmp; - - ostate = vap->iv_state; - - RUM_LOCK(sc); - - switch (sc->sc_state) { - case IEEE80211_S_INIT: - if (ostate == IEEE80211_S_RUN) { - /* abort TSF synchronization */ - tmp = rum_read(sc, RT2573_TXRX_CSR9); - rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); - } - break; - - case IEEE80211_S_RUN: - ni = vap->iv_bss; - - if (vap->iv_opmode != IEEE80211_M_MONITOR) { - rum_update_slot(ic->ic_ifp); - rum_enable_mrr(sc); - rum_set_txpreamble(sc); - rum_set_basicrates(sc); - rum_set_bssid(sc, ni->ni_bssid); - } - - if (vap->iv_opmode == IEEE80211_M_HOSTAP || - vap->iv_opmode == IEEE80211_M_IBSS) - rum_prepare_beacon(sc, vap); - - if (vap->iv_opmode != IEEE80211_M_MONITOR) - rum_enable_tsf_sync(sc); - - /* enable automatic rate adaptation */ - tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; - if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) - rum_amrr_start(sc, ni); - break; - default: - break; - } - - RUM_UNLOCK(sc); - - IEEE80211_LOCK(ic); - rvp->newstate(vap, sc->sc_state, sc->sc_arg); - if (vap->iv_newstate_cb != NULL) - vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); - IEEE80211_UNLOCK(ic); -} - -static int -rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct rum_vap *rvp = RUM_VAP(vap); - struct ieee80211com *ic = vap->iv_ic; - struct rum_softc *sc = ic->ic_ifp->if_softc; - - usb_rem_task(sc->sc_udev, &sc->sc_task); - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - callout_stop(&rvp->amrr_ch); - - /* do it in a process context */ - sc->sc_state = nstate; - sc->sc_arg = arg; - - if (nstate == IEEE80211_S_INIT) { - rvp->newstate(vap, nstate, arg); - return 0; - } else { - usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); - return EINPROGRESS; - } -} - -static void -rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct rum_tx_data *data = priv; - struct rum_softc *sc = data->sc; - struct ifnet *ifp = sc->sc_ifp; - - if (data->m != NULL && data->m->m_flags & M_TXCB) - ieee80211_process_callback(data->ni, data->m, 0/*XXX*/); - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) - return; - - device_printf(sc->sc_dev, "could not transmit buffer: %s\n", - usbd_errstr(status)); - - if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async(sc->sc_tx_pipeh); - - ifp->if_oerrors++; - return; - } - - m_freem(data->m); - data->m = NULL; - ieee80211_free_node(data->ni); - data->ni = NULL; - - sc->tx_queued--; - ifp->if_opackets++; - - DPRINTFN(10, ("tx done\n")); - - sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - rum_start(ifp); -} - -static void -rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct rum_rx_data *data = priv; - struct rum_softc *sc = data->sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct rum_rx_desc *desc; - struct ieee80211_node *ni; - struct mbuf *mnew, *m; - int len, rssi; - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) - return; - - if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh); - goto skip; - } - - usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); - - if (len < RT2573_RX_DESC_SIZE + sizeof (struct ieee80211_frame_min)) { - DPRINTF(("%s: xfer too short %d\n", - device_get_nameunit(sc->sc_dev), len)); - ifp->if_ierrors++; - goto skip; - } - - desc = (struct rum_rx_desc *)data->buf; - - if (le32toh(desc->flags) & RT2573_RX_CRC_ERROR) { - /* - * This should not happen since we did not request to receive - * those frames when we filled RT2573_TXRX_CSR0. - */ - DPRINTFN(5, ("CRC error\n")); - ifp->if_ierrors++; - goto skip; - } - - mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (mnew == NULL) { - ifp->if_ierrors++; - goto skip; - } - - m = data->m; - data->m = mnew; - data->buf = mtod(data->m, uint8_t *); - - /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; - m->m_data = (caddr_t)(desc + 1); - m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; - - rssi = rum_get_rssi(sc, desc->rssi); - - if (bpf_peers_present(ifp->if_bpf)) { - struct rum_rx_radiotap_header *tap = &sc->sc_rxtap; - - tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; - tap->wr_rate = ieee80211_plcp2rate(desc->rate, - (desc->flags & htole32(RT2573_RX_OFDM)) ? - IEEE80211_T_OFDM : IEEE80211_T_CCK); - tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); - tap->wr_antenna = sc->rx_ant; - tap->wr_antsignal = rssi; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); - } - - ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); - if (ni != NULL) { - /* Error happened during RSSI conversion. */ - if (rssi < 0) - rssi = -30; /* XXX ignored by net80211 */ - (void) ieee80211_input(ni, m, rssi, RT2573_NOISE_FLOOR, 0); - ieee80211_free_node(ni); - } else - (void) ieee80211_input_all(ic, m, rssi, RT2573_NOISE_FLOOR, 0); - - DPRINTFN(15, ("rx done\n")); - -skip: /* setup a new transfer */ - usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof); - usbd_transfer(xfer); -} - -static uint8_t -rum_plcp_signal(int rate) -{ - switch (rate) { - /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ - case 12: return 0xb; - case 18: return 0xf; - case 24: return 0xa; - case 36: return 0xe; - case 48: return 0x9; - case 72: return 0xd; - case 96: return 0x8; - case 108: return 0xc; - - /* CCK rates (NB: not IEEE std, device-specific) */ - case 2: return 0x0; - case 4: return 0x1; - case 11: return 0x2; - case 22: return 0x3; - } - return 0xff; /* XXX unsupported/unknown rate */ -} - -static void -rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, - uint32_t flags, uint16_t xflags, int len, int rate) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - uint16_t plcp_length; - int remainder; - - desc->flags = htole32(flags); - desc->flags |= htole32(RT2573_TX_VALID); - desc->flags |= htole32(len << 16); - - desc->xflags = htole16(xflags); - - desc->wme = htole16(RT2573_QID(0) | RT2573_AIFSN(2) | - RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10)); - - /* setup PLCP fields */ - desc->plcp_signal = rum_plcp_signal(rate); - desc->plcp_service = 4; - - len += IEEE80211_CRC_LEN; - if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) { - desc->flags |= htole32(RT2573_TX_OFDM); - - plcp_length = len & 0xfff; - desc->plcp_length_hi = plcp_length >> 6; - desc->plcp_length_lo = plcp_length & 0x3f; - } else { - plcp_length = (16 * len + rate - 1) / rate; - if (rate == 22) { - remainder = (16 * len) % 22; - if (remainder != 0 && remainder < 7) - desc->plcp_service |= RT2573_PLCP_LENGEXT; - } - desc->plcp_length_hi = plcp_length >> 8; - desc->plcp_length_lo = plcp_length & 0xff; - - if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) - desc->plcp_signal |= 0x08; - } -} - -#define RUM_TX_TIMEOUT 5000 - -static int -rum_sendprot(struct rum_softc *sc, - const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) -{ - struct ieee80211com *ic = ni->ni_ic; - const struct ieee80211_frame *wh; - struct rum_tx_desc *desc; - struct rum_tx_data *data; - struct mbuf *mprot; - int protrate, ackrate, pktlen, flags, isshort; - uint16_t dur; - usbd_status error; - - KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, - ("protection %d", prot)); - - wh = mtod(m, const struct ieee80211_frame *); - pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; - - protrate = ieee80211_ctl_rate(sc->sc_rates, rate); - ackrate = ieee80211_ack_rate(sc->sc_rates, rate); - - isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; - dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort); - + ieee80211_ack_duration(sc->sc_rates, rate, isshort); - flags = RT2573_TX_MORE_FRAG; - if (prot == IEEE80211_PROT_RTSCTS) { - /* NB: CTS is the same size as an ACK */ - dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort); - flags |= RT2573_TX_NEED_ACK; - mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); - } else { - mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); - } - if (mprot == NULL) { - /* XXX stat + msg */ - return ENOBUFS; - } - data = &sc->tx_data[sc->tx_cur]; - desc = (struct rum_tx_desc *)data->buf; - - data->m = mprot; - data->ni = ieee80211_ref_node(ni); - m_copydata(mprot, 0, mprot->m_pkthdr.len, - data->buf + RT2573_TX_DESC_SIZE); - rum_setup_tx_desc(sc, desc, flags, 0, mprot->m_pkthdr.len, protrate); - - usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, - /* NB: no roundup necessary */ - RT2573_TX_DESC_SIZE + mprot->m_pkthdr.len, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof); - - error = usbd_transfer(data->xfer); - if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { - data->m = NULL; - data->ni = NULL; - return error; - } - - sc->tx_queued++; - sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT; - - return 0; -} - -static int -rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct rum_tx_desc *desc; - struct rum_tx_data *data; - struct ieee80211_frame *wh; - const struct ieee80211_txparam *tp; - struct ieee80211_key *k; - uint32_t flags = 0; - uint16_t dur; - usbd_status error; - int xferlen; - - data = &sc->tx_data[sc->tx_cur]; - data->m = m0; - data->ni = ni; - desc = (struct rum_tx_desc *)data->buf; - - wh = mtod(m0, struct ieee80211_frame *); - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ni, m0); - if (k == NULL) { - m_freem(m0); - return ENOBUFS; - } - wh = mtod(m0, struct ieee80211_frame *); - } - - tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; - - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - flags |= RT2573_TX_NEED_ACK; - - dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate, - ic->ic_flags & IEEE80211_F_SHPREAMBLE); - *(uint16_t *)wh->i_dur = htole16(dur); - - /* tell hardware to add timestamp for probe responses */ - if ((wh->i_fc[0] & - (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == - (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)) - flags |= RT2573_TX_TIMESTAMP; - } - - if (bpf_peers_present(ifp->if_bpf)) { - struct rum_tx_radiotap_header *tap = &sc->sc_txtap; - - tap->wt_flags = 0; - tap->wt_rate = tp->mgmtrate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - tap->wt_antenna = sc->tx_ant; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); - } - - m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE); - rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, tp->mgmtrate); - - /* align end on a 4-bytes boundary */ - xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3; - - /* - * No space left in the last URB to store the extra 4 bytes, force - * sending of another URB. - */ - if ((xferlen % 64) == 0) - xferlen += 4; - - DPRINTFN(10, ("sending mgt frame len=%d rate=%d xfer len=%d\n", - m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, tp->mgmtrate, xferlen)); - - usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof); - - error = usbd_transfer(data->xfer); - if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { - m_freem(m0); - data->m = NULL; - data->ni = NULL; - return error; - } - - sc->tx_queued++; - sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT; - - return 0; -} - -static int -rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, - const struct ieee80211_bpf_params *params) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct rum_tx_desc *desc; - struct rum_tx_data *data; - uint32_t flags; - usbd_status error; - int xferlen, rate; - - KASSERT(params != NULL, ("no raw xmit params")); - - data = &sc->tx_data[sc->tx_cur]; - desc = (struct rum_tx_desc *)data->buf; - - rate = params->ibp_rate0 & IEEE80211_RATE_VAL; - /* XXX validate */ - if (rate == 0) { - m_freem(m0); - return EINVAL; - } - flags = 0; - if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) - flags |= RT2573_TX_NEED_ACK; - if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) { - error = rum_sendprot(sc, m0, ni, - params->ibp_flags & IEEE80211_BPF_RTS ? - IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY, - rate); - if (error) { - m_freem(m0); - return error; - } - flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS; - } - - if (bpf_peers_present(ifp->if_bpf)) { - struct rum_tx_radiotap_header *tap = &sc->sc_txtap; - - tap->wt_flags = 0; - tap->wt_rate = rate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - tap->wt_antenna = sc->tx_ant; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); - } - - data->m = m0; - data->ni = ni; - - m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE); - /* XXX need to setup descriptor ourself */ - rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate); - - /* align end on a 4-bytes boundary */ - xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3; - - /* - * No space left in the last URB to store the extra 4 bytes, force - * sending of another URB. - */ - if ((xferlen % 64) == 0) - xferlen += 4; - - DPRINTFN(10, ("sending raw frame len=%u rate=%u xfer len=%u\n", - m0->m_pkthdr.len, rate, xferlen)); - - usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, - xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, - rum_txeof); - - error = usbd_transfer(data->xfer); - if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) - return error; - - sc->tx_queued++; - sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT; - - return 0; -} - -static int -rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct rum_tx_desc *desc; - struct rum_tx_data *data; - struct ieee80211_frame *wh; - const struct ieee80211_txparam *tp; - struct ieee80211_key *k; - uint32_t flags = 0; - uint16_t dur; - usbd_status error; - int rate, xferlen; - - wh = mtod(m0, struct ieee80211_frame *); - - tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) - rate = tp->mcastrate; - else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) - rate = tp->ucastrate; - else { - (void) ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn); - rate = ni->ni_txrate; - } - - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ni, m0); - if (k == NULL) { - m_freem(m0); - return ENOBUFS; - } - - /* packet header may have moved, reset our local pointer */ - wh = mtod(m0, struct ieee80211_frame *); - } - - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - int prot = IEEE80211_PROT_NONE; - if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) - prot = IEEE80211_PROT_RTSCTS; - else if ((ic->ic_flags & IEEE80211_F_USEPROT) && - ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) - prot = ic->ic_protmode; - if (prot != IEEE80211_PROT_NONE) { - error = rum_sendprot(sc, m0, ni, prot, rate); - if (error) { - m_freem(m0); - return error; - } - flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS; - } - } - - data = &sc->tx_data[sc->tx_cur]; - desc = (struct rum_tx_desc *)data->buf; - - data->m = m0; - data->ni = ni; - - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - flags |= RT2573_TX_NEED_ACK; - flags |= RT2573_TX_MORE_FRAG; - - dur = ieee80211_ack_duration(sc->sc_rates, rate, - ic->ic_flags & IEEE80211_F_SHPREAMBLE); - *(uint16_t *)wh->i_dur = htole16(dur); - } - - if (bpf_peers_present(ifp->if_bpf)) { - struct rum_tx_radiotap_header *tap = &sc->sc_txtap; - - tap->wt_flags = 0; - tap->wt_rate = rate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - tap->wt_antenna = sc->tx_ant; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); - } - - m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE); - rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate); - - /* align end on a 4-bytes boundary */ - xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3; - - /* - * No space left in the last URB to store the extra 4 bytes, force - * sending of another URB. - */ - if ((xferlen % 64) == 0) - xferlen += 4; - - DPRINTFN(10, ("sending frame len=%d rate=%d xfer len=%d\n", - m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate, xferlen)); - - usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof); - - error = usbd_transfer(data->xfer); - if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { - m_freem(m0); - data->m = NULL; - data->ni = NULL; - return error; - } - - sc->tx_queued++; - sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT; - - return 0; -} - -static void -rum_start(struct ifnet *ifp) -{ - struct rum_softc *sc = ifp->if_softc; - struct ieee80211_node *ni; - struct mbuf *m; - - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - if (sc->tx_queued >= RUM_TX_LIST_COUNT-1) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - m = ieee80211_encap(ni, m); - if (m == NULL) { - ieee80211_free_node(ni); - continue; - } - if (rum_tx_data(sc, m, ni) != 0) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - break; - } - sc->sc_tx_timer = 5; - callout_reset(&sc->watchdog_ch, hz, rum_watchdog, sc); - } -} - -static void -rum_watchdog(void *arg) -{ - struct rum_softc *sc = arg; - - RUM_LOCK(sc); - - if (sc->sc_tx_timer > 0) { - if (--sc->sc_tx_timer == 0) { - device_printf(sc->sc_dev, "device timeout\n"); - /*rum_init(ifp); XXX needs a process context! */ - sc->sc_ifp->if_oerrors++; - RUM_UNLOCK(sc); - return; - } - callout_reset(&sc->watchdog_ch, hz, rum_watchdog, sc); - } - - RUM_UNLOCK(sc); -} - -static int -rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) -{ - struct rum_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; - - switch (cmd) { - case SIOCSIFFLAGS: - RUM_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - rum_init(sc); - startall = 1; - } else - rum_update_promisc(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rum_stop(sc); - } - RUM_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - return error; -} - -static void -rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len) -{ - usb_device_request_t req; - usbd_status error; - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = RT2573_READ_EEPROM; - USETW(req.wValue, 0); - USETW(req.wIndex, addr); - USETW(req.wLength, len); - - error = usbd_do_request(sc->sc_udev, &req, buf); - if (error != 0) { - device_printf(sc->sc_dev, "could not read EEPROM: %s\n", - usbd_errstr(error)); - } -} - -static uint32_t -rum_read(struct rum_softc *sc, uint16_t reg) -{ - uint32_t val; - - rum_read_multi(sc, reg, &val, sizeof val); - - return le32toh(val); -} - -static void -rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len) -{ - usb_device_request_t req; - usbd_status error; - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = RT2573_READ_MULTI_MAC; - USETW(req.wValue, 0); - USETW(req.wIndex, reg); - USETW(req.wLength, len); - - error = usbd_do_request(sc->sc_udev, &req, buf); - if (error != 0) { - device_printf(sc->sc_dev, - "could not multi read MAC register: %s\n", - usbd_errstr(error)); - } -} - -static void -rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val) -{ - uint32_t tmp = htole32(val); - - rum_write_multi(sc, reg, &tmp, sizeof tmp); -} - -static void -rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len) -{ - usb_device_request_t req; - usbd_status error; - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = RT2573_WRITE_MULTI_MAC; - USETW(req.wValue, 0); - USETW(req.wIndex, reg); - USETW(req.wLength, len); - - error = usbd_do_request(sc->sc_udev, &req, buf); - if (error != 0) { - device_printf(sc->sc_dev, - "could not multi write MAC register: %s\n", - usbd_errstr(error)); - } -} - -static void -rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val) -{ - uint32_t tmp; - int ntries; - - for (ntries = 0; ntries < 5; ntries++) { - if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) - break; - } - if (ntries == 5) { - device_printf(sc->sc_dev, "could not write to BBP\n"); - return; - } - - tmp = RT2573_BBP_BUSY | (reg & 0x7f) << 8 | val; - rum_write(sc, RT2573_PHY_CSR3, tmp); -} - -static uint8_t -rum_bbp_read(struct rum_softc *sc, uint8_t reg) -{ - uint32_t val; - int ntries; - - for (ntries = 0; ntries < 5; ntries++) { - if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) - break; - } - if (ntries == 5) { - device_printf(sc->sc_dev, "could not read BBP\n"); - return 0; - } - - val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8; - rum_write(sc, RT2573_PHY_CSR3, val); - - for (ntries = 0; ntries < 100; ntries++) { - val = rum_read(sc, RT2573_PHY_CSR3); - if (!(val & RT2573_BBP_BUSY)) - return val & 0xff; - DELAY(1); - } - - device_printf(sc->sc_dev, "could not read BBP\n"); - return 0; -} - -static void -rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val) -{ - uint32_t tmp; - int ntries; - - for (ntries = 0; ntries < 5; ntries++) { - if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY)) - break; - } - if (ntries == 5) { - device_printf(sc->sc_dev, "could not write to RF\n"); - return; - } - - tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | (val & 0xfffff) << 2 | - (reg & 3); - rum_write(sc, RT2573_PHY_CSR4, tmp); - - /* remember last written value in sc */ - sc->rf_regs[reg] = val; - - DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff)); -} - -static void -rum_select_antenna(struct rum_softc *sc) -{ - uint8_t bbp4, bbp77; - uint32_t tmp; - - bbp4 = rum_bbp_read(sc, 4); - bbp77 = rum_bbp_read(sc, 77); - - /* TBD */ - - /* make sure Rx is disabled before switching antenna */ - tmp = rum_read(sc, RT2573_TXRX_CSR0); - rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX); - - rum_bbp_write(sc, 4, bbp4); - rum_bbp_write(sc, 77, bbp77); - - rum_write(sc, RT2573_TXRX_CSR0, tmp); -} - -/* - * Enable multi-rate retries for frames sent at OFDM rates. - * In 802.11b/g mode, allow fallback to CCK rates. - */ -static void -rum_enable_mrr(struct rum_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - uint32_t tmp; - - tmp = rum_read(sc, RT2573_TXRX_CSR4); - - tmp &= ~RT2573_MRR_CCK_FALLBACK; - if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) - tmp |= RT2573_MRR_CCK_FALLBACK; - tmp |= RT2573_MRR_ENABLED; - - rum_write(sc, RT2573_TXRX_CSR4, tmp); -} - -static void -rum_set_txpreamble(struct rum_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - uint32_t tmp; - - tmp = rum_read(sc, RT2573_TXRX_CSR4); - - tmp &= ~RT2573_SHORT_PREAMBLE; - if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) - tmp |= RT2573_SHORT_PREAMBLE; - - rum_write(sc, RT2573_TXRX_CSR4, tmp); -} - -static void -rum_set_basicrates(struct rum_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - /* update basic rate set */ - if (ic->ic_curmode == IEEE80211_MODE_11B) { - /* 11b basic rates: 1, 2Mbps */ - rum_write(sc, RT2573_TXRX_CSR5, 0x3); - } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) { - /* 11a basic rates: 6, 12, 24Mbps */ - rum_write(sc, RT2573_TXRX_CSR5, 0x150); - } else { - /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */ - rum_write(sc, RT2573_TXRX_CSR5, 0xf); - } -} - -/* - * Reprogram MAC/BBP to switch to a new band. Values taken from the reference - * driver. - */ -static void -rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c) -{ - uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104; - uint32_t tmp; - - /* update all BBP registers that depend on the band */ - bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c; - bbp35 = 0x50; bbp97 = 0x48; bbp98 = 0x48; - if (IEEE80211_IS_CHAN_5GHZ(c)) { - bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c; - bbp35 += 0x10; bbp97 += 0x10; bbp98 += 0x10; - } - if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) || - (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) { - bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10; - } - - sc->bbp17 = bbp17; - rum_bbp_write(sc, 17, bbp17); - rum_bbp_write(sc, 96, bbp96); - rum_bbp_write(sc, 104, bbp104); - - if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) || - (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) { - rum_bbp_write(sc, 75, 0x80); - rum_bbp_write(sc, 86, 0x80); - rum_bbp_write(sc, 88, 0x80); - } - - rum_bbp_write(sc, 35, bbp35); - rum_bbp_write(sc, 97, bbp97); - rum_bbp_write(sc, 98, bbp98); - - tmp = rum_read(sc, RT2573_PHY_CSR0); - tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ); - if (IEEE80211_IS_CHAN_2GHZ(c)) - tmp |= RT2573_PA_PE_2GHZ; - else - tmp |= RT2573_PA_PE_5GHZ; - rum_write(sc, RT2573_PHY_CSR0, tmp); -} - -static void -rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - const struct rfprog *rfprog; - uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT; - int8_t power; - u_int i, chan; - - chan = ieee80211_chan2ieee(ic, c); - if (chan == 0 || chan == IEEE80211_CHAN_ANY) - return; - - /* select the appropriate RF settings based on what EEPROM says */ - rfprog = (sc->rf_rev == RT2573_RF_5225 || - sc->rf_rev == RT2573_RF_2527) ? rum_rf5225 : rum_rf5226; - - /* find the settings for this channel (we know it exists) */ - for (i = 0; rfprog[i].chan != chan; i++); - - power = sc->txpow[i]; - if (power < 0) { - bbp94 += power; - power = 0; - } else if (power > 31) { - bbp94 += power - 31; - power = 31; - } - - /* - * If we are switching from the 2GHz band to the 5GHz band or - * vice-versa, BBP registers need to be reprogrammed. - */ - if (c->ic_flags != ic->ic_curchan->ic_flags) { - rum_select_band(sc, c); - rum_select_antenna(sc); - } - ic->ic_curchan = c; - - rum_rf_write(sc, RT2573_RF1, rfprog[i].r1); - rum_rf_write(sc, RT2573_RF2, rfprog[i].r2); - rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7); - rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10); - - rum_rf_write(sc, RT2573_RF1, rfprog[i].r1); - rum_rf_write(sc, RT2573_RF2, rfprog[i].r2); - rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7 | 1); - rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10); - - rum_rf_write(sc, RT2573_RF1, rfprog[i].r1); - rum_rf_write(sc, RT2573_RF2, rfprog[i].r2); - rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7); - rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10); - - DELAY(10); - - /* enable smart mode for MIMO-capable RFs */ - bbp3 = rum_bbp_read(sc, 3); - - bbp3 &= ~RT2573_SMART_MODE; - if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_2527) - bbp3 |= RT2573_SMART_MODE; - - rum_bbp_write(sc, 3, bbp3); - - if (bbp94 != RT2573_BBPR94_DEFAULT) - rum_bbp_write(sc, 94, bbp94); -} - -/* - * Enable TSF synchronization and tell h/w to start sending beacons for IBSS - * and HostAP operating modes. - */ -static void -rum_enable_tsf_sync(struct rum_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - uint32_t tmp; - - if (vap->iv_opmode != IEEE80211_M_STA) { - /* - * Change default 16ms TBTT adjustment to 8ms. - * Must be done before enabling beacon generation. - */ - rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8); - } - - tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000; - - /* set beacon interval (in 1/16ms unit) */ - tmp |= vap->iv_bss->ni_intval * 16; - - tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT; - if (vap->iv_opmode == IEEE80211_M_STA) - tmp |= RT2573_TSF_MODE(1); - else - tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON; - - rum_write(sc, RT2573_TXRX_CSR9, tmp); -} - -static void -rum_update_slot(struct ifnet *ifp) -{ - struct rum_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - uint8_t slottime; - uint32_t tmp; - - slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; - - tmp = rum_read(sc, RT2573_MAC_CSR9); - tmp = (tmp & ~0xff) | slottime; - rum_write(sc, RT2573_MAC_CSR9, tmp); - - DPRINTF(("setting slot time to %uus\n", slottime)); -} - -static void -rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid) -{ - uint32_t tmp; - - tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24; - rum_write(sc, RT2573_MAC_CSR4, tmp); - - tmp = bssid[4] | bssid[5] << 8 | RT2573_ONE_BSSID << 16; - rum_write(sc, RT2573_MAC_CSR5, tmp); -} - -static void -rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr) -{ - uint32_t tmp; - - tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24; - rum_write(sc, RT2573_MAC_CSR2, tmp); - - tmp = addr[4] | addr[5] << 8 | 0xff << 16; - rum_write(sc, RT2573_MAC_CSR3, tmp); -} - -static void -rum_update_promisc(struct rum_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - uint32_t tmp; - - tmp = rum_read(sc, RT2573_TXRX_CSR0); - - tmp &= ~RT2573_DROP_NOT_TO_ME; - if (!(ifp->if_flags & IFF_PROMISC)) - tmp |= RT2573_DROP_NOT_TO_ME; - - rum_write(sc, RT2573_TXRX_CSR0, tmp); - - DPRINTF(("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? - "entering" : "leaving")); -} - -static const char * -rum_get_rf(int rev) -{ - switch (rev) { - case RT2573_RF_2527: return "RT2527 (MIMO XR)"; - case RT2573_RF_2528: return "RT2528"; - case RT2573_RF_5225: return "RT5225 (MIMO XR)"; - case RT2573_RF_5226: return "RT5226"; - default: return "unknown"; - } -} - -static void -rum_read_eeprom(struct rum_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - uint16_t val; -#ifdef RUM_DEBUG - int i; -#endif - - /* read MAC address */ - rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, ic->ic_myaddr, 6); - - rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2); - val = le16toh(val); - sc->rf_rev = (val >> 11) & 0x1f; - sc->hw_radio = (val >> 10) & 0x1; - sc->rx_ant = (val >> 4) & 0x3; - sc->tx_ant = (val >> 2) & 0x3; - sc->nb_ant = val & 0x3; - - DPRINTF(("RF revision=%d\n", sc->rf_rev)); - - rum_eeprom_read(sc, RT2573_EEPROM_CONFIG2, &val, 2); - val = le16toh(val); - sc->ext_5ghz_lna = (val >> 6) & 0x1; - sc->ext_2ghz_lna = (val >> 4) & 0x1; - - DPRINTF(("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n", - sc->ext_2ghz_lna, sc->ext_5ghz_lna)); - - rum_eeprom_read(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET, &val, 2); - val = le16toh(val); - if ((val & 0xff) != 0xff) - sc->rssi_2ghz_corr = (int8_t)(val & 0xff); /* signed */ - - /* Only [-10, 10] is valid */ - if (sc->rssi_2ghz_corr < -10 || sc->rssi_2ghz_corr > 10) - sc->rssi_2ghz_corr = 0; - - rum_eeprom_read(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET, &val, 2); - val = le16toh(val); - if ((val & 0xff) != 0xff) - sc->rssi_5ghz_corr = (int8_t)(val & 0xff); /* signed */ - - /* Only [-10, 10] is valid */ - if (sc->rssi_5ghz_corr < -10 || sc->rssi_5ghz_corr > 10) - sc->rssi_5ghz_corr = 0; - - if (sc->ext_2ghz_lna) - sc->rssi_2ghz_corr -= 14; - if (sc->ext_5ghz_lna) - sc->rssi_5ghz_corr -= 14; - - DPRINTF(("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n", - sc->rssi_2ghz_corr, sc->rssi_5ghz_corr)); - - rum_eeprom_read(sc, RT2573_EEPROM_FREQ_OFFSET, &val, 2); - val = le16toh(val); - if ((val & 0xff) != 0xff) - sc->rffreq = val & 0xff; - - DPRINTF(("RF freq=%d\n", sc->rffreq)); - - /* read Tx power for all a/b/g channels */ - rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14); - /* XXX default Tx power for 802.11a channels */ - memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14); -#ifdef RUM_DEBUG - for (i = 0; i < 14; i++) - DPRINTF(("Channel=%d Tx power=%d\n", i + 1, sc->txpow[i])); -#endif - - /* read default values for BBP registers */ - rum_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16); -#ifdef RUM_DEBUG - for (i = 0; i < 14; i++) { - if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff) - continue; - DPRINTF(("BBP R%d=%02x\n", sc->bbp_prom[i].reg, - sc->bbp_prom[i].val)); - } -#endif -} - -static int -rum_bbp_init(struct rum_softc *sc) -{ -#define N(a) (sizeof (a) / sizeof ((a)[0])) - int i, ntries; - - /* wait for BBP to be ready */ - for (ntries = 0; ntries < 100; ntries++) { - const uint8_t val = rum_bbp_read(sc, 0); - if (val != 0 && val != 0xff) - break; - DELAY(1000); - } - if (ntries == 100) { - device_printf(sc->sc_dev, "timeout waiting for BBP\n"); - return EIO; - } - - /* initialize BBP registers to default values */ - for (i = 0; i < N(rum_def_bbp); i++) - rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val); - - /* write vendor-specific BBP values (from EEPROM) */ - for (i = 0; i < 16; i++) { - if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff) - continue; - rum_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val); - } - - return 0; -#undef N -} - -static void -rum_init_locked(struct rum_softc *sc) -{ -#define N(a) (sizeof (a) / sizeof ((a)[0])) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct rum_rx_data *data; - uint32_t tmp; - usbd_status error; - int i, ntries; - - rum_stop(sc); - - /* initialize MAC registers to default values */ - for (i = 0; i < N(rum_def_mac); i++) - rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val); - - /* set host ready */ - rum_write(sc, RT2573_MAC_CSR1, 3); - rum_write(sc, RT2573_MAC_CSR1, 0); - - /* wait for BBP/RF to wakeup */ - for (ntries = 0; ntries < 1000; ntries++) { - if (rum_read(sc, RT2573_MAC_CSR12) & 8) - break; - rum_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */ - DELAY(1000); - } - if (ntries == 1000) { - device_printf(sc->sc_dev, - "timeout waiting for BBP/RF to wakeup\n"); - goto fail; - } - - if ((error = rum_bbp_init(sc)) != 0) - goto fail; - - /* select default channel */ - rum_select_band(sc, ic->ic_curchan); - rum_select_antenna(sc); - rum_set_chan(sc, ic->ic_curchan); - - /* clear STA registers */ - rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta); - - IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); - rum_set_macaddr(sc, ic->ic_myaddr); - - /* initialize ASIC */ - rum_write(sc, RT2573_MAC_CSR1, 4); - - /* - * Allocate xfer for AMRR statistics requests. - */ - sc->amrr_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->amrr_xfer == NULL) { - device_printf(sc->sc_dev, "could not allocate AMRR xfer\n"); - goto fail; - } - - /* - * Open Tx and Rx USB bulk pipes. - */ - error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE, - &sc->sc_tx_pipeh); - if (error != 0) { - device_printf(sc->sc_dev, "could not open Tx pipe: %s\n", - usbd_errstr(error)); - goto fail; - } - error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE, - &sc->sc_rx_pipeh); - if (error != 0) { - device_printf(sc->sc_dev, "could not open Rx pipe: %s\n", - usbd_errstr(error)); - goto fail; - } - - /* - * Allocate Tx and Rx xfer queues. - */ - error = rum_alloc_tx_list(sc); - if (error != 0) { - device_printf(sc->sc_dev, "could not allocate Tx list\n"); - goto fail; - } - error = rum_alloc_rx_list(sc); - if (error != 0) { - device_printf(sc->sc_dev, "could not allocate Rx list\n"); - goto fail; - } - - /* - * Start up the receive pipe. - */ - for (i = 0; i < RUM_RX_LIST_COUNT; i++) { - data = &sc->rx_data[i]; - - usbd_setup_xfer(data->xfer, sc->sc_rx_pipeh, data, data->buf, - MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof); - usbd_transfer(data->xfer); - } - - /* update Rx filter */ - tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff; - - tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR; - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR | - RT2573_DROP_ACKCTS; - if (ic->ic_opmode != IEEE80211_M_HOSTAP) - tmp |= RT2573_DROP_TODS; - if (!(ifp->if_flags & IFF_PROMISC)) - tmp |= RT2573_DROP_NOT_TO_ME; - } - rum_write(sc, RT2573_TXRX_CSR0, tmp); - - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; - return; - -fail: rum_stop(sc); -#undef N -} - -static void -rum_init(void *priv) -{ - struct rum_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - RUM_LOCK(sc); - rum_init_locked(sc); - RUM_UNLOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ieee80211_start_all(ic); /* start all vap's */ -} - -static void -rum_stop(void *priv) -{ - struct rum_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - uint32_t tmp; - - sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - - /* disable Rx */ - tmp = rum_read(sc, RT2573_TXRX_CSR0); - rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX); - - /* reset ASIC */ - rum_write(sc, RT2573_MAC_CSR1, 3); - rum_write(sc, RT2573_MAC_CSR1, 0); - - if (sc->amrr_xfer != NULL) { - usbd_free_xfer(sc->amrr_xfer); - sc->amrr_xfer = NULL; - } - - if (sc->sc_rx_pipeh != NULL) { - usbd_abort_pipe(sc->sc_rx_pipeh); - usbd_close_pipe(sc->sc_rx_pipeh); - sc->sc_rx_pipeh = NULL; - } - if (sc->sc_tx_pipeh != NULL) { - usbd_abort_pipe(sc->sc_tx_pipeh); - usbd_close_pipe(sc->sc_tx_pipeh); - sc->sc_tx_pipeh = NULL; - } - - rum_free_rx_list(sc); - rum_free_tx_list(sc); -} - -static int -rum_load_microcode(struct rum_softc *sc, const u_char *ucode, size_t size) -{ - usb_device_request_t req; - uint16_t reg = RT2573_MCU_CODE_BASE; - usbd_status error; - - /* copy firmware image into NIC */ - for (; size >= 4; reg += 4, ucode += 4, size -= 4) - rum_write(sc, reg, UGETDW(ucode)); - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = RT2573_MCU_CNTL; - USETW(req.wValue, RT2573_MCU_RUN); - USETW(req.wIndex, 0); - USETW(req.wLength, 0); - - error = usbd_do_request(sc->sc_udev, &req, NULL); - if (error != 0) { - device_printf(sc->sc_dev, "could not run firmware: %s\n", - usbd_errstr(error)); - } - return error; -} - -static int -rum_prepare_beacon(struct rum_softc *sc, struct ieee80211vap *vap) -{ - struct ieee80211com *ic = vap->iv_ic; - const struct ieee80211_txparam *tp; - struct rum_tx_desc desc; - struct mbuf *m0; - - m0 = ieee80211_beacon_alloc(vap->iv_bss, &RUM_VAP(vap)->bo); - if (m0 == NULL) { - return ENOBUFS; - } - - tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; - rum_setup_tx_desc(sc, &desc, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ, - m0->m_pkthdr.len, tp->mgmtrate); - - /* copy the first 24 bytes of Tx descriptor into NIC memory */ - rum_write_multi(sc, RT2573_HW_BEACON_BASE0, (uint8_t *)&desc, 24); - - /* copy beacon header and payload into NIC memory */ - rum_write_multi(sc, RT2573_HW_BEACON_BASE0 + 24, mtod(m0, uint8_t *), - m0->m_pkthdr.len); - - m_freem(m0); - - return 0; -} - -static int -rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, - const struct ieee80211_bpf_params *params) -{ - struct ifnet *ifp = ni->ni_ic->ic_ifp; - struct rum_softc *sc = ifp->if_softc; - - /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - m_freem(m); - ieee80211_free_node(ni); - return ENETDOWN; - } - if (sc->tx_queued >= RUM_TX_LIST_COUNT-1) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - m_freem(m); - ieee80211_free_node(ni); - return EIO; - } - - ifp->if_opackets++; - - if (params == NULL) { - /* - * Legacy path; interpret frame contents to decide - * precisely how to send the frame. - */ - if (rum_tx_mgt(sc, m, ni) != 0) - goto bad; - } else { - /* - * Caller supplied explicit parameters to use in - * sending the frame. - */ - if (rum_tx_raw(sc, m, ni, params) != 0) - goto bad; - } - sc->sc_tx_timer = 5; - callout_reset(&sc->watchdog_ch, hz, rum_watchdog, sc); - - return 0; -bad: - ifp->if_oerrors++; - ieee80211_free_node(ni); - return EIO; -} - -static void -rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct rum_vap *rvp = RUM_VAP(vap); - - /* clear statistic registers (STA_CSR0 to STA_CSR5) */ - rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta); - - ieee80211_amrr_node_init(&rvp->amrr, &RUM_NODE(ni)->amn, ni); - - callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, vap); -} - -static void -rum_amrr_timeout(void *arg) -{ - struct ieee80211vap *vap = arg; - struct rum_softc *sc = vap->iv_ic->ic_ifp->if_softc; - usb_device_request_t req; - - /* - * Asynchronously read statistic registers (cleared by read). - */ - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = RT2573_READ_MULTI_MAC; - USETW(req.wValue, 0); - USETW(req.wIndex, RT2573_STA_CSR0); - USETW(req.wLength, sizeof sc->sta); - - usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, vap, - USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof sc->sta, 0, - rum_amrr_update); - (void)usbd_transfer(sc->amrr_xfer); -} - -static void -rum_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv, - usbd_status status) -{ - struct ieee80211vap *vap = priv; - struct rum_vap *rvp = RUM_VAP(vap); - struct ifnet *ifp = vap->iv_ic->ic_ifp; - struct rum_softc *sc = ifp->if_softc; - int ok, fail; - - if (status != USBD_NORMAL_COMPLETION) { - device_printf(sc->sc_dev, "could not retrieve Tx statistics - " - "cancelling automatic rate control\n"); - return; - } - - ok = (le32toh(sc->sta[4]) >> 16) + /* TX ok w/o retry */ - (le32toh(sc->sta[5]) & 0xffff); /* TX ok w/ retry */ - fail = (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */ - - ieee80211_amrr_tx_update(&RUM_NODE(vap->iv_bss)->amn, - ok+fail, ok, (le32toh(sc->sta[5]) & 0xffff) + fail); - - ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */ - - callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, vap); -} - -/* ARGUSED */ -static struct ieee80211_node * -rum_node_alloc(struct ieee80211vap *vap __unused, - const uint8_t mac[IEEE80211_ADDR_LEN] __unused) -{ - struct rum_node *rn; - - rn = malloc(sizeof(struct rum_node), M_80211_NODE, M_NOWAIT | M_ZERO); - return rn != NULL ? &rn->ni : NULL; -} - -static void -rum_newassoc(struct ieee80211_node *ni, int isnew) -{ - struct ieee80211vap *vap = ni->ni_vap; - - ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni); -} - -static void -rum_scan_start(struct ieee80211com *ic) -{ - struct rum_softc *sc = ic->ic_ifp->if_softc; - - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - - /* do it in a process context */ - sc->sc_scan_action = RUM_SCAN_START; - usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER); -} - -static void -rum_scan_end(struct ieee80211com *ic) -{ - struct rum_softc *sc = ic->ic_ifp->if_softc; - - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - - /* do it in a process context */ - sc->sc_scan_action = RUM_SCAN_END; - usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER); -} - -static void -rum_set_channel(struct ieee80211com *ic) -{ - struct rum_softc *sc = ic->ic_ifp->if_softc; - - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - - /* do it in a process context */ - sc->sc_scan_action = RUM_SET_CHANNEL; - usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER); - - sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); -} - -static void -rum_scantask(void *arg) -{ - struct rum_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - uint32_t tmp; - - RUM_LOCK(sc); - - switch (sc->sc_scan_action) { - case RUM_SCAN_START: - /* abort TSF synchronization */ - tmp = rum_read(sc, RT2573_TXRX_CSR9); - rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); - rum_set_bssid(sc, ifp->if_broadcastaddr); - break; - - case RUM_SCAN_END: - rum_enable_tsf_sync(sc); - /* XXX keep local copy */ - rum_set_bssid(sc, vap->iv_bss->ni_bssid); - break; - - case RUM_SET_CHANNEL: - mtx_lock(&Giant); - rum_set_chan(sc, ic->ic_curchan); - mtx_unlock(&Giant); - break; - - default: - panic("unknown scan action %d\n", sc->sc_scan_action); - /* NEVER REACHED */ - break; - } - - RUM_UNLOCK(sc); -} - -static int -rum_get_rssi(struct rum_softc *sc, uint8_t raw) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - int lna, agc, rssi; - - lna = (raw >> 5) & 0x3; - agc = raw & 0x1f; - - if (lna == 0) { - /* - * No RSSI mapping - * - * NB: Since RSSI is relative to noise floor, -1 is - * adequate for caller to know error happened. - */ - return -1; - } - - rssi = (2 * agc) - RT2573_NOISE_FLOOR; - - if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { - rssi += sc->rssi_2ghz_corr; - - if (lna == 1) - rssi -= 64; - else if (lna == 2) - rssi -= 74; - else if (lna == 3) - rssi -= 90; - } else { - rssi += sc->rssi_5ghz_corr; - - if (!sc->ext_5ghz_lna && lna != 1) - rssi += 4; - - if (lna == 1) - rssi -= 64; - else if (lna == 2) - rssi -= 86; - else if (lna == 3) - rssi -= 100; - } - return rssi; -} - -static device_method_t rum_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, rum_match), - DEVMETHOD(device_attach, rum_attach), - DEVMETHOD(device_detach, rum_detach), - - { 0, 0 } -}; - -static driver_t rum_driver = { - "rum", - rum_methods, - sizeof(struct rum_softc) -}; - -static devclass_t rum_devclass; - -DRIVER_MODULE(rum, uhub, rum_driver, rum_devclass, usbd_driver_load, 0); diff --git a/sys/legacy/dev/usb/if_rumreg.h b/sys/legacy/dev/usb/if_rumreg.h deleted file mode 100644 index 75a51bc..0000000 --- a/sys/legacy/dev/usb/if_rumreg.h +++ /dev/null @@ -1,235 +0,0 @@ -/* $FreeBSD$ */ - -/*- - * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini@free.fr> - * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define RT2573_NOISE_FLOOR -95 - -#define RT2573_TX_DESC_SIZE (sizeof (struct rum_tx_desc)) -#define RT2573_RX_DESC_SIZE (sizeof (struct rum_rx_desc)) - -#define RT2573_CONFIG_NO 1 -#define RT2573_IFACE_INDEX 0 - -#define RT2573_MCU_CNTL 0x01 -#define RT2573_WRITE_MAC 0x02 -#define RT2573_READ_MAC 0x03 -#define RT2573_WRITE_MULTI_MAC 0x06 -#define RT2573_READ_MULTI_MAC 0x07 -#define RT2573_READ_EEPROM 0x09 -#define RT2573_WRITE_LED 0x0a - -/* - * Control and status registers. - */ -#define RT2573_AIFSN_CSR 0x0400 -#define RT2573_CWMIN_CSR 0x0404 -#define RT2573_CWMAX_CSR 0x0408 -#define RT2573_MCU_CODE_BASE 0x0800 -#define RT2573_HW_BEACON_BASE0 0x2400 -#define RT2573_MAC_CSR0 0x3000 -#define RT2573_MAC_CSR1 0x3004 -#define RT2573_MAC_CSR2 0x3008 -#define RT2573_MAC_CSR3 0x300c -#define RT2573_MAC_CSR4 0x3010 -#define RT2573_MAC_CSR5 0x3014 -#define RT2573_MAC_CSR6 0x3018 -#define RT2573_MAC_CSR7 0x301c -#define RT2573_MAC_CSR8 0x3020 -#define RT2573_MAC_CSR9 0x3024 -#define RT2573_MAC_CSR10 0x3028 -#define RT2573_MAC_CSR11 0x302c -#define RT2573_MAC_CSR12 0x3030 -#define RT2573_MAC_CSR13 0x3034 -#define RT2573_MAC_CSR14 0x3038 -#define RT2573_MAC_CSR15 0x303c -#define RT2573_TXRX_CSR0 0x3040 -#define RT2573_TXRX_CSR1 0x3044 -#define RT2573_TXRX_CSR2 0x3048 -#define RT2573_TXRX_CSR3 0x304c -#define RT2573_TXRX_CSR4 0x3050 -#define RT2573_TXRX_CSR5 0x3054 -#define RT2573_TXRX_CSR6 0x3058 -#define RT2573_TXRX_CSR7 0x305c -#define RT2573_TXRX_CSR8 0x3060 -#define RT2573_TXRX_CSR9 0x3064 -#define RT2573_TXRX_CSR10 0x3068 -#define RT2573_TXRX_CSR11 0x306c -#define RT2573_TXRX_CSR12 0x3070 -#define RT2573_TXRX_CSR13 0x3074 -#define RT2573_TXRX_CSR14 0x3078 -#define RT2573_TXRX_CSR15 0x307c -#define RT2573_PHY_CSR0 0x3080 -#define RT2573_PHY_CSR1 0x3084 -#define RT2573_PHY_CSR2 0x3088 -#define RT2573_PHY_CSR3 0x308c -#define RT2573_PHY_CSR4 0x3090 -#define RT2573_PHY_CSR5 0x3094 -#define RT2573_PHY_CSR6 0x3098 -#define RT2573_PHY_CSR7 0x309c -#define RT2573_SEC_CSR0 0x30a0 -#define RT2573_SEC_CSR1 0x30a4 -#define RT2573_SEC_CSR2 0x30a8 -#define RT2573_SEC_CSR3 0x30ac -#define RT2573_SEC_CSR4 0x30b0 -#define RT2573_SEC_CSR5 0x30b4 -#define RT2573_STA_CSR0 0x30c0 -#define RT2573_STA_CSR1 0x30c4 -#define RT2573_STA_CSR2 0x30c8 -#define RT2573_STA_CSR3 0x30cc -#define RT2573_STA_CSR4 0x30d0 -#define RT2573_STA_CSR5 0x30d4 - - -/* possible flags for register RT2573_MAC_CSR1 */ -#define RT2573_RESET_ASIC (1 << 0) -#define RT2573_RESET_BBP (1 << 1) -#define RT2573_HOST_READY (1 << 2) - -/* possible flags for register MAC_CSR5 */ -#define RT2573_ONE_BSSID 3 - -/* possible flags for register TXRX_CSR0 */ -/* Tx filter flags are in the low 16 bits */ -#define RT2573_AUTO_TX_SEQ (1 << 15) -/* Rx filter flags are in the high 16 bits */ -#define RT2573_DISABLE_RX (1 << 16) -#define RT2573_DROP_CRC_ERROR (1 << 17) -#define RT2573_DROP_PHY_ERROR (1 << 18) -#define RT2573_DROP_CTL (1 << 19) -#define RT2573_DROP_NOT_TO_ME (1 << 20) -#define RT2573_DROP_TODS (1 << 21) -#define RT2573_DROP_VER_ERROR (1 << 22) -#define RT2573_DROP_MULTICAST (1 << 23) -#define RT2573_DROP_BROADCAST (1 << 24) -#define RT2573_DROP_ACKCTS (1 << 25) - -/* possible flags for register TXRX_CSR4 */ -#define RT2573_SHORT_PREAMBLE (1 << 18) -#define RT2573_MRR_ENABLED (1 << 19) -#define RT2573_MRR_CCK_FALLBACK (1 << 22) - -/* possible flags for register TXRX_CSR9 */ -#define RT2573_TSF_TICKING (1 << 16) -#define RT2573_TSF_MODE(x) (((x) & 0x3) << 17) -/* TBTT stands for Target Beacon Transmission Time */ -#define RT2573_ENABLE_TBTT (1 << 19) -#define RT2573_GENERATE_BEACON (1 << 20) - -/* possible flags for register PHY_CSR0 */ -#define RT2573_PA_PE_2GHZ (1 << 16) -#define RT2573_PA_PE_5GHZ (1 << 17) - -/* possible flags for register PHY_CSR3 */ -#define RT2573_BBP_READ (1 << 15) -#define RT2573_BBP_BUSY (1 << 16) -/* possible flags for register PHY_CSR4 */ -#define RT2573_RF_20BIT (20 << 24) -#define RT2573_RF_BUSY (1 << 31) - -/* LED values */ -#define RT2573_LED_RADIO (1 << 8) -#define RT2573_LED_G (1 << 9) -#define RT2573_LED_A (1 << 10) -#define RT2573_LED_ON 0x1e1e -#define RT2573_LED_OFF 0x0 - -#define RT2573_MCU_RUN (1 << 3) - -#define RT2573_SMART_MODE (1 << 0) - -#define RT2573_BBPR94_DEFAULT 6 - -#define RT2573_BBP_WRITE (1 << 15) - -/* dual-band RF */ -#define RT2573_RF_5226 1 -#define RT2573_RF_5225 3 -/* single-band RF */ -#define RT2573_RF_2528 2 -#define RT2573_RF_2527 4 - -#define RT2573_BBP_VERSION 0 - -struct rum_tx_desc { - uint32_t flags; -#define RT2573_TX_BURST (1 << 0) -#define RT2573_TX_VALID (1 << 1) -#define RT2573_TX_MORE_FRAG (1 << 2) -#define RT2573_TX_NEED_ACK (1 << 3) -#define RT2573_TX_TIMESTAMP (1 << 4) -#define RT2573_TX_OFDM (1 << 5) -#define RT2573_TX_IFS_SIFS (1 << 6) -#define RT2573_TX_LONG_RETRY (1 << 7) - - uint16_t wme; -#define RT2573_QID(v) (v) -#define RT2573_AIFSN(v) ((v) << 4) -#define RT2573_LOGCWMIN(v) ((v) << 8) -#define RT2573_LOGCWMAX(v) ((v) << 12) - - uint16_t xflags; -#define RT2573_TX_HWSEQ (1 << 12) - - uint8_t plcp_signal; - uint8_t plcp_service; -#define RT2573_PLCP_LENGEXT 0x80 - - uint8_t plcp_length_lo; - uint8_t plcp_length_hi; - - uint32_t iv; - uint32_t eiv; - - uint8_t offset; - uint8_t qid; - uint8_t txpower; -#define RT2573_DEFAULT_TXPOWER 0 - - uint8_t reserved; -} __packed; - -struct rum_rx_desc { - uint32_t flags; -#define RT2573_RX_BUSY (1 << 0) -#define RT2573_RX_DROP (1 << 1) -#define RT2573_RX_CRC_ERROR (1 << 6) -#define RT2573_RX_OFDM (1 << 7) - - uint8_t rate; - uint8_t rssi; - uint8_t reserved1; - uint8_t offset; - uint32_t iv; - uint32_t eiv; - uint32_t reserved2[2]; -} __packed; - -#define RT2573_RF1 0 -#define RT2573_RF2 2 -#define RT2573_RF3 1 -#define RT2573_RF4 3 - -#define RT2573_EEPROM_MACBBP 0x0000 -#define RT2573_EEPROM_ADDRESS 0x0004 -#define RT2573_EEPROM_ANTENNA 0x0020 -#define RT2573_EEPROM_CONFIG2 0x0022 -#define RT2573_EEPROM_BBP_BASE 0x0026 -#define RT2573_EEPROM_TXPOWER 0x0046 -#define RT2573_EEPROM_FREQ_OFFSET 0x005e -#define RT2573_EEPROM_RSSI_2GHZ_OFFSET 0x009a -#define RT2573_EEPROM_RSSI_5GHZ_OFFSET 0x009c diff --git a/sys/legacy/dev/usb/if_rumvar.h b/sys/legacy/dev/usb/if_rumvar.h deleted file mode 100644 index 59980c0..0000000 --- a/sys/legacy/dev/usb/if_rumvar.h +++ /dev/null @@ -1,161 +0,0 @@ -/* $FreeBSD$ */ - -/*- - * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini@free.fr> - * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define RUM_RX_LIST_COUNT 1 -#define RUM_TX_LIST_COUNT 8 - -struct rum_rx_radiotap_header { - struct ieee80211_radiotap_header wr_ihdr; - uint8_t wr_flags; - uint8_t wr_rate; - uint16_t wr_chan_freq; - uint16_t wr_chan_flags; - uint8_t wr_antenna; - uint8_t wr_antsignal; -}; - -#define RT2573_RX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_FLAGS) | \ - (1 << IEEE80211_RADIOTAP_RATE) | \ - (1 << IEEE80211_RADIOTAP_CHANNEL) | \ - (1 << IEEE80211_RADIOTAP_ANTENNA) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)) - -struct rum_tx_radiotap_header { - struct ieee80211_radiotap_header wt_ihdr; - uint8_t wt_flags; - uint8_t wt_rate; - uint16_t wt_chan_freq; - uint16_t wt_chan_flags; - uint8_t wt_antenna; -}; - -#define RT2573_TX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_FLAGS) | \ - (1 << IEEE80211_RADIOTAP_RATE) | \ - (1 << IEEE80211_RADIOTAP_CHANNEL) | \ - (1 << IEEE80211_RADIOTAP_ANTENNA)) - -struct rum_softc; - -struct rum_tx_data { - struct rum_softc *sc; - usbd_xfer_handle xfer; - uint8_t *buf; - struct mbuf *m; - struct ieee80211_node *ni; -}; - -struct rum_rx_data { - struct rum_softc *sc; - usbd_xfer_handle xfer; - uint8_t *buf; - struct mbuf *m; -}; - -struct rum_node { - struct ieee80211_node ni; - struct ieee80211_amrr_node amn; -}; -#define RUM_NODE(ni) ((struct rum_node *)(ni)) - -struct rum_vap { - struct ieee80211vap vap; - struct ieee80211_beacon_offsets bo; - struct ieee80211_amrr amrr; - struct callout amrr_ch; - - int (*newstate)(struct ieee80211vap *, - enum ieee80211_state, int); -}; -#define RUM_VAP(vap) ((struct rum_vap *)(vap)) - -struct rum_softc { - struct ifnet *sc_ifp; - const struct ieee80211_rate_table *sc_rates; - - device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; - - int sc_rx_no; - int sc_tx_no; - - uint8_t rf_rev; - uint8_t rffreq; - - usbd_xfer_handle amrr_xfer; - - usbd_pipe_handle sc_rx_pipeh; - usbd_pipe_handle sc_tx_pipeh; - - enum ieee80211_state sc_state; - int sc_arg; - struct usb_task sc_task; - - struct usb_task sc_scantask; - int sc_scan_action; -#define RUM_SCAN_START 0 -#define RUM_SCAN_END 1 -#define RUM_SET_CHANNEL 2 - - struct rum_rx_data rx_data[RUM_RX_LIST_COUNT]; - struct rum_tx_data tx_data[RUM_TX_LIST_COUNT]; - int tx_queued; - int tx_cur; - - struct mtx sc_mtx; - - struct callout watchdog_ch; - - int sc_tx_timer; - - uint32_t sta[6]; - uint32_t rf_regs[4]; - uint8_t txpow[44]; - - struct { - uint8_t val; - uint8_t reg; - } __packed bbp_prom[16]; - - int hw_radio; - int rx_ant; - int tx_ant; - int nb_ant; - int ext_2ghz_lna; - int ext_5ghz_lna; - int rssi_2ghz_corr; - int rssi_5ghz_corr; - uint8_t bbp17; - - struct rum_rx_radiotap_header sc_rxtap; - int sc_rxtap_len; - - struct rum_tx_radiotap_header sc_txtap; - int sc_txtap_len; -}; - -#if 0 -#define RUM_LOCK(sc) mtx_lock(&(sc)->sc_mtx) -#define RUM_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) -#else -#define RUM_LOCK(sc) do { ((sc) = (sc)); mtx_lock(&Giant); } while (0) -#define RUM_UNLOCK(sc) mtx_unlock(&Giant) -#endif diff --git a/sys/legacy/dev/usb/if_udav.c b/sys/legacy/dev/usb/if_udav.c deleted file mode 100644 index e13170e..0000000 --- a/sys/legacy/dev/usb/if_udav.c +++ /dev/null @@ -1,1962 +0,0 @@ -/* $NetBSD: if_udav.c,v 1.2 2003/09/04 15:17:38 tsutsui Exp $ */ -/* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */ -/* $FreeBSD$ */ -/*- - * Copyright (c) 2003 - * Shingo WATANABE <nabe@nabechan.org>. 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 author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - */ - -/* - * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY) - * The spec can be found at the following url. - * http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-P01-930914.pdf - */ - -/* - * TODO: - * Interrupt Endpoint support - * External PHYs - * powerhook() support? - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "opt_inet.h" -#if defined(__NetBSD__) -#include "opt_ns.h" -#endif -#if defined(__NetBSD__) -#include "bpfilter.h" -#endif -#if defined(__FreeBSD__) -#define NBPFILTER 1 -#endif -#if defined(__NetBSD__) -#include "rnd.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/lock.h> -#include <sys/mbuf.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/socket.h> -#if defined(__FreeBSD__) -#include <sys/types.h> -#include <sys/lockmgr.h> -#include <sys/sockio.h> -#endif - -#if defined(__NetBSD__) -#include <sys/device.h> -#endif - -#if defined(NRND) && NRND > 0 -#include <sys/rnd.h> -#endif - -#include <net/if.h> -#include <net/if_arp.h> -#include <net/if_dl.h> -#include <net/if_media.h> -#include <net/ethernet.h> -#include <net/if_types.h> - -#if NBPFILTER > 0 -#include <net/bpf.h> -#endif -#if defined(__NetBSD__) -#ifndef BPF_MTAP -#define BPF_MTAP(_ifp, _m) do { \ - if ((_ifp)->if_bpf)) { \ - bpf_mtap((_ifp)->if_bpf, (_m)) ; \ - } \ -} while (0) -#endif -#endif - -#if defined(__NetBSD__) -#include <net/if_ether.h> -#ifdef INET -#include <netinet/in.h> -#include <netinet/if_inarp.h> -#endif /* INET */ -#elif defined(__FreeBSD__) /* defined(__NetBSD__) */ -#include <netinet/in.h> -#include <netinet/if_ether.h> -#endif /* defined(__FreeBSD__) */ - -#if defined(__NetBSD__) -#ifdef NS -#include <netns/ns.h> -#include <netns/ns_if.h> -#endif -#endif /* defined (__NetBSD__) */ - -#include <sys/bus.h> -#include <machine/bus.h> - -#include <dev/mii/mii.h> -#include <dev/mii/miivar.h> - -#include <dev/usb/usb_port.h> -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include "usbdevs.h" -#include <dev/usb/usbdivar.h> -#include <dev/usb/usb_ethersubr.h> - -#include <dev/usb/if_udavreg.h> - -#if defined(__FreeBSD__) -MODULE_DEPEND(udav, usb, 1, 1, 1); -MODULE_DEPEND(udav, ether, 1, 1, 1); -MODULE_DEPEND(udav, miibus, 1, 1, 1); -#endif - -/* "device miibus" required. See GENERIC if you get errors here. */ -#include "miibus_if.h" - -#if !defined(__FreeBSD__) -/* Function declarations */ -USB_DECLARE_DRIVER(udav); -#endif - -#if defined(__FreeBSD__) -static device_probe_t udav_match; -static device_attach_t udav_attach; -static device_detach_t udav_detach; -static device_shutdown_t udav_shutdown; -static miibus_readreg_t udav_miibus_readreg; -static miibus_writereg_t udav_miibus_writereg; -static miibus_statchg_t udav_miibus_statchg; -#endif - -static int udav_openpipes(struct udav_softc *); -static void udav_start(struct ifnet *); -static int udav_send(struct udav_softc *, struct mbuf *, int); -static void udav_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -#if defined(__FreeBSD__) -static void udav_rxstart(struct ifnet *ifp); -#endif -static void udav_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void udav_tick(void *); -static void udav_tick_task(void *); -static int udav_ioctl(struct ifnet *, u_long, caddr_t); -static void udav_stop_task(struct udav_softc *); -static void udav_stop(struct ifnet *, int); -static void udav_watchdog(struct ifnet *); -static int udav_ifmedia_change(struct ifnet *); -static void udav_ifmedia_status(struct ifnet *, struct ifmediareq *); -static void udav_lock_mii(struct udav_softc *); -static void udav_unlock_mii(struct udav_softc *); -#if defined(__NetBSD__) -static int udav_miibus_readreg(device_t, int, int); -static void udav_miibus_writereg(device_t, int, int, int); -static void udav_miibus_statchg(device_t); -static int udav_init(struct ifnet *); -#elif defined(__FreeBSD__) -static void udav_init(void *); -#endif -static void udav_setmulti(struct udav_softc *); -static void udav_reset(struct udav_softc *); - -static int udav_csr_read(struct udav_softc *, int, void *, int); -static int udav_csr_write(struct udav_softc *, int, void *, int); -static int udav_csr_read1(struct udav_softc *, int); -static int udav_csr_write1(struct udav_softc *, int, unsigned char); - -#if 0 -static int udav_mem_read(struct udav_softc *, int, void *, int); -static int udav_mem_write(struct udav_softc *, int, void *, int); -static int udav_mem_write1(struct udav_softc *, int, unsigned char); -#endif - -#if defined(__FreeBSD__) -static device_method_t udav_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, udav_match), - DEVMETHOD(device_attach, udav_attach), - DEVMETHOD(device_detach, udav_detach), - DEVMETHOD(device_shutdown, udav_shutdown), - - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - - /* MII interface */ - DEVMETHOD(miibus_readreg, udav_miibus_readreg), - DEVMETHOD(miibus_writereg, udav_miibus_writereg), - DEVMETHOD(miibus_statchg, udav_miibus_statchg), - - { 0, 0 } -}; - -static driver_t udav_driver = { - "udav", - udav_methods, - sizeof(struct udav_softc) -}; - -static devclass_t udav_devclass; - -DRIVER_MODULE(udav, uhub, udav_driver, udav_devclass, usbd_driver_load, 0); -DRIVER_MODULE(miibus, udav, miibus_driver, miibus_devclass, 0, 0); - -#endif /* defined(__FreeBSD__) */ - -/* Macros */ -#ifdef UDAV_DEBUG -#define DPRINTF(x) if (udavdebug) printf x -#define DPRINTFN(n,x) if (udavdebug >= (n)) printf x -int udavdebug = 0; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -#define delay(d) DELAY(d) - -#define UDAV_SETBIT(sc, reg, x) \ - udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x)) - -#define UDAV_CLRBIT(sc, reg, x) \ - udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x)) - -static const struct udav_type { - struct usb_devno udav_dev; - u_int16_t udav_flags; -#define UDAV_EXT_PHY 0x0001 -} udav_devs [] = { - /* Corega USB-TXC */ - {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC }, 0}, - /* ShanTou ST268 USB NIC */ - {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268 }, 0}, - /* ShanTou DM9601 USB NIC */ - {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601}, 0}, -}; -#define udav_lookup(v, p) ((const struct udav_type *)usb_lookup(udav_devs, v, p)) - - -/* Probe */ -static int -udav_match(device_t self) -{ - struct usb_attach_arg *uaa = device_get_ivars(self); - - if (uaa->iface != NULL) - return (UMATCH_NONE); - - return (udav_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); -} - -/* Attach */ -static int -udav_attach(device_t self) -{ - USB_ATTACH_START(udav, sc, uaa); - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; - usbd_status err; - usb_interface_descriptor_t *id; - usb_endpoint_descriptor_t *ed; - const char *devname ; - struct ifnet *ifp; -#if defined(__NetBSD__) - struct mii_data *mii; -#endif - u_char eaddr[ETHER_ADDR_LEN]; - int i; -#if defined(__NetBSD__) - int s; -#endif - - sc->sc_dev = self; - devname = device_get_nameunit(self); - /* Move the device into the configured state. */ - err = usbd_set_config_no(dev, UDAV_CONFIG_NO, 1); - if (err) { - printf("%s: setting config no failed\n", devname); - goto bad; - } - - usb_init_task(&sc->sc_tick_task, udav_tick_task, sc); - lockinit(&sc->sc_mii_lock, PZERO, "udavmii", 0, 0); - usb_init_task(&sc->sc_stop_task, (void (*)(void *)) udav_stop_task, sc); - - /* get control interface */ - err = usbd_device2interface_handle(dev, UDAV_IFACE_INDEX, &iface); - if (err) { - printf("%s: failed to get interface, err=%s\n", devname, - usbd_errstr(err)); - goto bad; - } - - sc->sc_udev = dev; - sc->sc_ctl_iface = iface; - sc->sc_flags = udav_lookup(uaa->vendor, uaa->product)->udav_flags; - - /* get interface descriptor */ - id = usbd_get_interface_descriptor(sc->sc_ctl_iface); - - /* find endpoints */ - sc->sc_bulkin_no = sc->sc_bulkout_no = sc->sc_intrin_no = -1; - for (i = 0; i < id->bNumEndpoints; i++) { - ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i); - if (ed == NULL) { - printf("%s: couldn't get endpoint %d\n", devname, i); - goto bad; - } - if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && - UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) - sc->sc_bulkin_no = ed->bEndpointAddress; /* RX */ - else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && - UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) - sc->sc_bulkout_no = ed->bEndpointAddress; /* TX */ - else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT && - UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) - sc->sc_intrin_no = ed->bEndpointAddress; /* Status */ - } - - if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1 || - sc->sc_intrin_no == -1) { - printf("%s: missing endpoint\n", devname); - goto bad; - } - -#if defined(__FreeBSD__) - mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); -#endif -#if defined(__NetBSD__) - s = splnet(); -#elif defined(__FreeBSD__) - UDAV_LOCK(sc); -#endif - - /* reset the adapter */ - udav_reset(sc); - - /* Get Ethernet Address */ - err = udav_csr_read(sc, UDAV_PAR, (void *)eaddr, ETHER_ADDR_LEN); - if (err) { - printf("%s: read MAC address failed\n", devname); -#if defined(__NetBSD__) - splx(s); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); - mtx_destroy(&sc->sc_mtx); -#endif - goto bad; - } - - /* Print Ethernet Address */ - printf("%s: Ethernet address %s\n", devname, ether_sprintf(eaddr)); - - /* initialize interface infomation */ -#if defined(__FreeBSD__) - ifp = GET_IFP(sc) = if_alloc(IFT_ETHER); - if (ifp == NULL) { - printf("%s: can not if_alloc\n", devname); - UDAV_UNLOCK(sc); - mtx_destroy(&sc->sc_mtx); - goto bad; - } -#else - ifp = GET_IFP(sc); -#endif - ifp->if_softc = sc; - ifp->if_mtu = ETHERMTU; -#if defined(__NetBSD__) - strncpy(ifp->if_xname, devname, IFNAMSIZ); -#elif defined(__FreeBSD__) - if_initname(ifp, "udav", device_get_unit(self)); -#endif - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSGIANT; - ifp->if_start = udav_start; - ifp->if_ioctl = udav_ioctl; - ifp->if_watchdog = udav_watchdog; - ifp->if_init = udav_init; -#if defined(__NetBSD__) - ifp->if_stop = udav_stop; -#endif -#if defined(__FreeBSD__) - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; -#endif -#if defined(__NetBSD__) - IFQ_SET_READY(&ifp->if_snd); -#endif - - -#if defined(__NetBSD__) - /* - * Do ifmedia setup. - */ - mii = &sc->sc_mii; - mii->mii_ifp = ifp; - mii->mii_readreg = udav_miibus_readreg; - mii->mii_writereg = udav_miibus_writereg; - mii->mii_statchg = udav_miibus_statchg; - mii->mii_flags = MIIF_AUTOTSLEEP; - ifmedia_init(&mii->mii_media, 0, - udav_ifmedia_change, udav_ifmedia_status); - mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); - if (LIST_FIRST(&mii->mii_phys) == NULL) { - ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL); - ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE); - } else - ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); - - /* attach the interface */ - if_attach(ifp); - Ether_ifattach(ifp, eaddr); -#elif defined(__FreeBSD__) - if (mii_phy_probe(self, &sc->sc_miibus, - udav_ifmedia_change, udav_ifmedia_status)) { - printf("%s: MII without any PHY!\n", device_get_nameunit(sc->sc_dev)); - if_free(ifp); - UDAV_UNLOCK(sc); - mtx_destroy(&sc->sc_mtx); - return ENXIO; - } - - sc->sc_qdat.ifp = ifp; - sc->sc_qdat.if_rxstart = udav_rxstart; - - /* - * Call MI attach routine. - */ - - ether_ifattach(ifp, eaddr); -#endif - -#if defined(NRND) && NRND > 0 - rnd_attach_source(&sc->rnd_source, devname, RND_TYPE_NET, 0); -#endif - - usb_callout_init(sc->sc_stat_ch); -#if defined(__FreeBSD__) - usb_register_netisr(); -#endif - sc->sc_attached = 1; -#if defined(__NetBSD__) - splx(s); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); -#endif - - usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, sc->sc_dev); - - return 0; - - bad: - sc->sc_dying = 1; - return ENXIO; -} - -/* detach */ -static int -udav_detach(device_t self) -{ - USB_DETACH_START(udav, sc); - struct ifnet *ifp = GET_IFP(sc); -#if defined(__NetBSD__) - int s; -#endif - - DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - /* Detached before attached finished */ - if (!sc->sc_attached) - return (0); - - UDAV_LOCK(sc); - - usb_uncallout(sc->sc_stat_ch, udav_tick, sc); - - /* Remove any pending tasks */ - usb_rem_task(sc->sc_udev, &sc->sc_tick_task); - usb_rem_task(sc->sc_udev, &sc->sc_stop_task); - -#if defined(__NetBSD__) - s = splusb(); -#elif defined(__FreeBSD__) - UDAV_LOCK(sc); -#endif - - if (--sc->sc_refcnt >= 0) { - /* Wait for processes to go away */ - usb_detach_wait(sc->sc_dev); - } -#if defined(__FreeBSD__) - if (ifp->if_drv_flags & IFF_DRV_RUNNING) -#else - if (ifp->if_flags & IFF_RUNNING) -#endif - udav_stop(GET_IFP(sc), 1); - -#if defined(NRND) && NRND > 0 - rnd_detach_source(&sc->rnd_source); -#endif -#if defined(__NetBSD__) - mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY); - ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY); -#endif - ether_ifdetach(ifp); -#if defined(__NetBSD__) - if_detach(ifp); -#endif -#if defined(__FreeBSD__) - if_free(ifp); -#endif - -#ifdef DIAGNOSTIC - if (sc->sc_pipe_tx != NULL) - printf("%s: detach has active tx endpoint.\n", - device_get_nameunit(sc->sc_dev)); - if (sc->sc_pipe_rx != NULL) - printf("%s: detach has active rx endpoint.\n", - device_get_nameunit(sc->sc_dev)); - if (sc->sc_pipe_intr != NULL) - printf("%s: detach has active intr endpoint.\n", - device_get_nameunit(sc->sc_dev)); -#endif - sc->sc_attached = 0; - -#if defined(__NetBSD__) - splx(s); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); -#endif - -#if defined(__FreeBSD__) - mtx_destroy(&sc->sc_mtx); -#endif - - usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (0); -} - -#if 0 -/* read memory */ -static int -udav_mem_read(struct udav_softc *sc, int offset, void *buf, int len) -{ - usb_device_request_t req; - usbd_status err; - - if (sc == NULL) - return (0); - - DPRINTFN(0x200, - ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - if (sc->sc_dying) - return (0); - - offset &= 0xffff; - len &= 0xff; - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = UDAV_REQ_MEM_READ; - USETW(req.wValue, 0x0000); - USETW(req.wIndex, offset); - USETW(req.wLength, len); - - sc->sc_refcnt++; - err = usbd_do_request(sc->sc_udev, &req, buf); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(sc->sc_dev); - if (err) { - DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n", - device_get_nameunit(sc->sc_dev), __func__, offset, err)); - } - - return (err); -} - -/* write memory */ -static int -udav_mem_write(struct udav_softc *sc, int offset, void *buf, int len) -{ - usb_device_request_t req; - usbd_status err; - - if (sc == NULL) - return (0); - - DPRINTFN(0x200, - ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - if (sc->sc_dying) - return (0); - - offset &= 0xffff; - len &= 0xff; - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = UDAV_REQ_MEM_WRITE; - USETW(req.wValue, 0x0000); - USETW(req.wIndex, offset); - USETW(req.wLength, len); - - sc->sc_refcnt++; - err = usbd_do_request(sc->sc_udev, &req, buf); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(sc->sc_dev); - if (err) { - DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", - device_get_nameunit(sc->sc_dev), __func__, offset, err)); - } - - return (err); -} - -/* write memory */ -static int -udav_mem_write1(struct udav_softc *sc, int offset, unsigned char ch) -{ - usb_device_request_t req; - usbd_status err; - - if (sc == NULL) - return (0); - - DPRINTFN(0x200, - ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - if (sc->sc_dying) - return (0); - - offset &= 0xffff; - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = UDAV_REQ_MEM_WRITE1; - USETW(req.wValue, ch); - USETW(req.wIndex, offset); - USETW(req.wLength, 0x0000); - - sc->sc_refcnt++; - err = usbd_do_request(sc->sc_udev, &req, NULL); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(sc->sc_dev); - if (err) { - DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", - device_get_nameunit(sc->sc_dev), __func__, offset, err)); - } - - return (err); -} -#endif - -/* read register(s) */ -static int -udav_csr_read(struct udav_softc *sc, int offset, void *buf, int len) -{ - usb_device_request_t req; - usbd_status err; - - if (sc == NULL) - return (0); - - DPRINTFN(0x200, - ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - if (sc->sc_dying) - return (0); - - offset &= 0xff; - len &= 0xff; - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = UDAV_REQ_REG_READ; - USETW(req.wValue, 0x0000); - USETW(req.wIndex, offset); - USETW(req.wLength, len); - - sc->sc_refcnt++; - err = usbd_do_request(sc->sc_udev, &req, buf); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(sc->sc_dev); - if (err) { - DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n", - device_get_nameunit(sc->sc_dev), __func__, offset, err)); - } - - return (err); -} - -/* write register(s) */ -static int -udav_csr_write(struct udav_softc *sc, int offset, void *buf, int len) -{ - usb_device_request_t req; - usbd_status err; - - if (sc == NULL) - return (0); - - DPRINTFN(0x200, - ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - if (sc->sc_dying) - return (0); - - offset &= 0xff; - len &= 0xff; - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = UDAV_REQ_REG_WRITE; - USETW(req.wValue, 0x0000); - USETW(req.wIndex, offset); - USETW(req.wLength, len); - - sc->sc_refcnt++; - err = usbd_do_request(sc->sc_udev, &req, buf); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(sc->sc_dev); - if (err) { - DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", - device_get_nameunit(sc->sc_dev), __func__, offset, err)); - } - - return (err); -} - -static int -udav_csr_read1(struct udav_softc *sc, int offset) -{ - u_int8_t val = 0; - - if (sc == NULL) - return (0); - - DPRINTFN(0x200, - ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - if (sc->sc_dying) - return (0); - - return (udav_csr_read(sc, offset, &val, 1) ? 0 : val); -} - -/* write a register */ -static int -udav_csr_write1(struct udav_softc *sc, int offset, unsigned char ch) -{ - usb_device_request_t req; - usbd_status err; - - if (sc == NULL) - return (0); - - DPRINTFN(0x200, - ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - if (sc->sc_dying) - return (0); - - offset &= 0xff; - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = UDAV_REQ_REG_WRITE1; - USETW(req.wValue, ch); - USETW(req.wIndex, offset); - USETW(req.wLength, 0x0000); - - sc->sc_refcnt++; - err = usbd_do_request(sc->sc_udev, &req, NULL); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(sc->sc_dev); - if (err) { - DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", - device_get_nameunit(sc->sc_dev), __func__, offset, err)); - } - - return (err); -} - -#if defined(__NetBSD__) -static int -udav_init(struct ifnet *ifp) -#elif defined(__FreeBSD__) -static void -udav_init(void *xsc) -#endif -{ -#if defined(__NetBSD__) - struct udav_softc *sc = ifp->if_softc; -#elif defined(__FreeBSD__) - struct udav_softc *sc = (struct udav_softc *)xsc; - struct ifnet *ifp = GET_IFP(sc); -#endif - struct mii_data *mii = GET_MII(sc); - u_char *eaddr; -#if defined(__NetBSD__) - int s; -#endif - - DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - if (sc->sc_dying) -#if defined(__NetBSD__) - return (EIO); -#elif defined(__FreeBSD__) - return ; -#endif - -#if defined(__NetBSD__) - s = splnet(); -#elif defined(__FreeBSD__) - UDAV_LOCK(sc); -#endif - - /* Cancel pending I/O and free all TX/RX buffers */ - udav_stop(ifp, 1); - -#if defined(__NetBSD__) - eaddr = LLADDR(ifp->if_sadl); -#elif defined(__FreeBSD__) - eaddr = IF_LLADDR(ifp); -#endif - udav_csr_write(sc, UDAV_PAR, eaddr, ETHER_ADDR_LEN); - - /* Initialize network control register */ - /* Disable loopback */ - UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1); - - /* Initialize RX control register */ - UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC); - - /* If we want promiscuous mode, accept all physical frames. */ - if (ifp->if_flags & IFF_PROMISC) - UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC); - else - UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC); - - /* Initialize transmit ring */ - if (usb_ether_tx_list_init(sc, &sc->sc_cdata, - sc->sc_udev) == ENOBUFS) { - printf("%s: tx list init failed\n", device_get_nameunit(sc->sc_dev)); -#if defined(__NetBSD__) - splx(s); - return (EIO); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); - return ; -#endif - - } - - /* Initialize receive ring */ - if (usb_ether_rx_list_init(sc, &sc->sc_cdata, - sc->sc_udev) == ENOBUFS) { - printf("%s: rx list init failed\n", device_get_nameunit(sc->sc_dev)); -#if defined(__NetBSD__) - splx(s); - return (EIO); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); - return ; -#endif - } - - /* Load the multicast filter */ - udav_setmulti(sc); - - /* Enable RX */ - UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_RXEN); - - /* clear POWER_DOWN state of internal PHY */ - UDAV_SETBIT(sc, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0); - UDAV_CLRBIT(sc, UDAV_GPR, UDAV_GPR_GEPIO0); - - mii_mediachg(mii); - - if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) { - if (udav_openpipes(sc)) { -#if defined(__NetBSD__) - splx(s); - return (EIO); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); - return ; -#endif - } - } - -#if defined(__FreeBSD__) - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; -#else - ifp->if_flags |= IFF_RUNNING; - ifp->if_flags &= ~IFF_OACTIVE; -#endif - -#if defined(__NetBSD__) - splx(s); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); -#endif - - usb_callout(sc->sc_stat_ch, hz, udav_tick, sc); - -#if defined(__NetBSD__) - return (0); -#elif defined(__FreeBSD__) - return ; -#endif -} - -static void -udav_reset(struct udav_softc *sc) -{ - int i; - - DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - if (sc->sc_dying) - return; - - /* Select PHY */ -#if 1 - /* - * XXX: force select internal phy. - * external phy routines are not tested. - */ - UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY); -#else - if (sc->sc_flags & UDAV_EXT_PHY) { - UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY); - } else { - UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY); - } -#endif - - UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_RST); - - for (i = 0; i < UDAV_TX_TIMEOUT; i++) { - if (!(udav_csr_read1(sc, UDAV_NCR) & UDAV_NCR_RST)) - break; - delay(10); /* XXX */ - } - delay(10000); /* XXX */ -} - -#if defined(__NetBSD__) || defined(__OpenBSD__) -int -udav_activate(device_t self, enum devact act) -{ - struct udav_softc *sc = (struct udav_softc *)self; - - DPRINTF(("%s: %s: enter, act=%d\n", device_get_nameunit(sc->sc_dev), - __func__, act)); - switch (act) { - case DVACT_ACTIVATE: - return (EOPNOTSUPP); - break; - - case DVACT_DEACTIVATE: - if_deactivate(&sc->sc_ec.ec_if); - sc->sc_dying = 1; - break; - } - return (0); -} -#endif - -#define UDAV_BITS 6 - -#define UDAV_CALCHASH(addr) \ - (ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1)) - -static void -udav_setmulti(struct udav_softc *sc) -{ - struct ifnet *ifp; -#if defined(__NetBSD__) - struct ether_multi *enm; - struct ether_multistep step; -#elif defined(__FreeBSD__) - struct ifmultiaddr *ifma; -#endif - u_int8_t hashes[8]; - int h = 0; - - DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - if (sc->sc_dying) - return; - - ifp = GET_IFP(sc); - - if (ifp->if_flags & IFF_PROMISC) { - UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC); - return; - } else if (ifp->if_flags & IFF_ALLMULTI) { -#if defined(__NetBSD__) - allmulti: -#endif - ifp->if_flags |= IFF_ALLMULTI; - UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL); - UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_PRMSC); - return; - } - - /* first, zot all the existing hash bits */ - memset(hashes, 0x00, sizeof(hashes)); - hashes[7] |= 0x80; /* broadcast address */ - udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes)); - - /* now program new ones */ -#if defined(__NetBSD__) - ETHER_FIRST_MULTI(step, &sc->sc_ec, enm); - while (enm != NULL) { - if (memcmp(enm->enm_addrlo, enm->enm_addrhi, - ETHER_ADDR_LEN) != 0) - goto allmulti; - - h = UDAV_CALCHASH(enm->enm_addrlo); - hashes[h>>3] |= 1 << (h & 0x7); - ETHER_NEXT_MULTI(step, enm); - } -#elif defined(__FreeBSD__) - IF_ADDR_LOCK(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) - { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - h = UDAV_CALCHASH(LLADDR((struct sockaddr_dl *) - ifma->ifma_addr)); - hashes[h>>3] |= 1 << (h & 0x7); - } - IF_ADDR_UNLOCK(ifp); -#endif - - /* disable all multicast */ - ifp->if_flags &= ~IFF_ALLMULTI; - UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL); - - /* write hash value to the register */ - udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes)); -} - -static int -udav_openpipes(struct udav_softc *sc) -{ - struct ue_chain *c; - usbd_status err; - int i; - int error = 0; - - if (sc->sc_dying) - return (EIO); - - sc->sc_refcnt++; - - /* Open RX pipe */ - err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkin_no, - USBD_EXCLUSIVE_USE, &sc->sc_pipe_rx); - if (err) { - printf("%s: open rx pipe failed: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(err)); - error = EIO; - goto done; - } - - /* Open TX pipe */ - err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkout_no, - USBD_EXCLUSIVE_USE, &sc->sc_pipe_tx); - if (err) { - printf("%s: open tx pipe failed: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(err)); - error = EIO; - goto done; - } - -#if 0 - /* XXX: interrupt endpoint is not yet supported */ - /* Open Interrupt pipe */ - err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_intrin_no, - USBD_EXCLUSIVE_USE, &sc->sc_pipe_intr, sc, - &sc->sc_cdata.ue_ibuf, UDAV_INTR_PKGLEN, - udav_intr, UDAV_INTR_INTERVAL); - if (err) { - printf("%s: open intr pipe failed: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(err)); - error = EIO; - goto done; - } -#endif - - - /* Start up the receive pipe. */ - for (i = 0; i < UE_RX_LIST_CNT; i++) { - c = &sc->sc_cdata.ue_rx_chain[i]; - usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_rx, - c, c->ue_buf, UE_BUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, udav_rxeof); - (void)usbd_transfer(c->ue_xfer); - DPRINTF(("%s: %s: start read\n", device_get_nameunit(sc->sc_dev), - __func__)); - } - - done: - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(sc->sc_dev); - - return (error); -} - -static void -udav_start(struct ifnet *ifp) -{ - struct udav_softc *sc = ifp->if_softc; - struct mbuf *m_head = NULL; - - DPRINTF(("%s: %s: enter, link=%d\n", device_get_nameunit(sc->sc_dev), - __func__, sc->sc_link)); - - if (sc->sc_dying) - return; - - if (!sc->sc_link) - return; - -#if defined(__FreeBSD__) - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) -#else - if (ifp->if_flags & IFF_OACTIVE) -#endif - return; -#if defined(__NetBSD__) - IFQ_POLL(&ifp->if_snd, m_head); -#elif defined(__FreeBSD__) - IF_DEQUEUE(&ifp->if_snd, m_head); -#endif - if (m_head == NULL) - return; - - if (udav_send(sc, m_head, 0)) { -#if defined(__FreeBSD__) - IF_PREPEND(&ifp->if_snd, m_head); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; -#else - ifp->if_flags |= IFF_OACTIVE; -#endif - return; - } - -#if defined(__NetBSD__) - IFQ_DEQUEUE(&ifp->if_snd, m_head); -#endif - -#if NBPFILTER > 0 - BPF_MTAP(ifp, m_head); -#endif - -#if defined(__FreeBSD__) - ifp->if_drv_flags |= IFF_DRV_OACTIVE; -#else - ifp->if_flags |= IFF_OACTIVE; -#endif - - /* Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; -} - -static int -udav_send(struct udav_softc *sc, struct mbuf *m, int idx) -{ - int total_len; - struct ue_chain *c; - usbd_status err; - - DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev),__func__)); - - c = &sc->sc_cdata.ue_tx_chain[idx]; - - /* Copy the mbuf data into a contiguous buffer */ - /* first 2 bytes are packet length */ - m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf + 2); - c->ue_mbuf = m; - total_len = m->m_pkthdr.len; - if (total_len < UDAV_MIN_FRAME_LEN) { - memset(c->ue_buf + 2 + total_len, 0, - UDAV_MIN_FRAME_LEN - total_len); - total_len = UDAV_MIN_FRAME_LEN; - } - - /* Frame length is specified in the first 2bytes of the buffer */ - c->ue_buf[0] = (u_int8_t)total_len; - c->ue_buf[1] = (u_int8_t)(total_len >> 8); - total_len += 2; - - usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_tx, c, c->ue_buf, total_len, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - UDAV_TX_TIMEOUT, udav_txeof); - - /* Transmit */ - sc->sc_refcnt++; - err = usbd_transfer(c->ue_xfer); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(sc->sc_dev); - if (err != USBD_IN_PROGRESS) { - printf("%s: udav_send error=%s\n", device_get_nameunit(sc->sc_dev), - usbd_errstr(err)); - /* Stop the interface */ - usb_add_task(sc->sc_udev, &sc->sc_stop_task, USB_TASKQ_DRIVER); - return (EIO); - } - - DPRINTF(("%s: %s: send %d bytes\n", device_get_nameunit(sc->sc_dev), - __func__, total_len)); - - sc->sc_cdata.ue_tx_cnt++; - - return (0); -} - -static void -udav_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct ue_chain *c = priv; - struct udav_softc *sc = c->ue_sc; - struct ifnet *ifp = GET_IFP(sc); -#if defined(__NetBSD__) - int s; -#endif - - if (sc->sc_dying) - return; - -#if defined(__NetBSD__) - s = splnet(); -#elif defined(__FreeBSD__) - UDAV_LOCK(sc); -#endif - - DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - ifp->if_timer = 0; -#if defined(__FreeBSD__) - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; -#else - ifp->if_flags &= ~IFF_OACTIVE; -#endif - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { -#if defined(__NetBSD__) - splx(s); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); -#endif - return; - } - ifp->if_oerrors++; - printf("%s: usb error on tx: %s\n", device_get_nameunit(sc->sc_dev), - usbd_errstr(status)); - if (status == USBD_STALLED) { - sc->sc_refcnt++; - usbd_clear_endpoint_stall(sc->sc_pipe_tx); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(sc->sc_dev); - } -#if defined(__NetBSD__) - splx(s); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); -#endif - return; - } - - ifp->if_opackets++; - - m_freem(c->ue_mbuf); - c->ue_mbuf = NULL; - -#if defined(__NetBSD__) - if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) -#elif defined(__FreeBSD__) - if ( ifp->if_snd.ifq_head != NULL ) -#endif - udav_start(ifp); - -#if defined(__NetBSD__) - splx(s); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); -#endif -} - -static void -udav_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct ue_chain *c = priv; - struct udav_softc *sc = c->ue_sc; - struct ifnet *ifp = GET_IFP(sc); - struct mbuf *m; - u_int32_t total_len; - u_int8_t *pktstat; -#if defined(__NetBSD__) - int s; -#endif - - DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev),__func__)); - - if (sc->sc_dying) - return; - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) - return; - sc->sc_rx_errs++; - if (usbd_ratecheck(&sc->sc_rx_notice)) { - printf("%s: %u usb errors on rx: %s\n", - device_get_nameunit(sc->sc_dev), sc->sc_rx_errs, - usbd_errstr(status)); - sc->sc_rx_errs = 0; - } - if (status == USBD_STALLED) { - sc->sc_refcnt++; - usbd_clear_endpoint_stall(sc->sc_pipe_rx); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(sc->sc_dev); - } - goto done; - } - - usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); - - /* copy data to mbuf */ - m = c->ue_mbuf; - memcpy(mtod(m, char *), c->ue_buf, total_len); - - /* first byte in received data */ - pktstat = mtod(m, u_int8_t *); - m_adj(m, sizeof(u_int8_t)); - DPRINTF(("%s: RX Status: 0x%02x\n", device_get_nameunit(sc->sc_dev), *pktstat)); - - total_len = UGETW(mtod(m, u_int8_t *)); - m_adj(m, sizeof(u_int16_t)); - - if (*pktstat & UDAV_RSR_LCS) { - ifp->if_collisions++; - goto done; - } - - if (total_len < sizeof(struct ether_header) || - *pktstat & UDAV_RSR_ERR) { - ifp->if_ierrors++; - goto done; - } - - ifp->if_ipackets++; - total_len -= ETHER_CRC_LEN; - - m->m_pkthdr.len = m->m_len = total_len; -#if defined(__NetBSD__) - m->m_pkthdr.rcvif = ifp; -#elif defined(__FreeBSD__) - m->m_pkthdr.rcvif = (struct ifnet *)&sc->sc_qdat; -#endif - -#if defined(__NetBSD__) - s = splnet(); -#elif defined(__FreeBSD__) - UDAV_LOCK(sc); -#endif - -#if defined(__NetBSD__) - c->ue_mbuf = usb_ether_newbuf(); - if (c->ue_mbuf == NULL) { - printf("%s: no memory for rx list " - "-- packet dropped!\n", device_get_nameunit(sc->sc_dev)); - ifp->if_ierrors++; - goto done1; - } -#endif - -#if NBPFILTER > 0 - BPF_MTAP(ifp, m); -#endif - - DPRINTF(("%s: %s: deliver %d\n", device_get_nameunit(sc->sc_dev), - __func__, m->m_len)); -#if defined(__NetBSD__) - IF_INPUT(ifp, m); -#endif -#if defined(__FreeBSD__) - usb_ether_input(m); - UDAV_UNLOCK(sc); - return ; -#endif - -#if defined(__NetBSD__) - done1: - splx(s); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); -#endif - done: - /* Setup new transfer */ - usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->ue_buf, UE_BUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, udav_rxeof); - sc->sc_refcnt++; - usbd_transfer(xfer); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(sc->sc_dev); - - DPRINTF(("%s: %s: start rx\n", device_get_nameunit(sc->sc_dev), __func__)); -} - -#if 0 -static void udav_intr() -{ -} -#endif - -static int -udav_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) -{ - struct udav_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; - struct mii_data *mii; -#if defined(__NetBSD__) - int s; -#endif - int error = 0; - - DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - if (sc->sc_dying) - return (EIO); - -#if defined(__NetBSD__) - s = splnet(); -#elif defined(__FreeBSD__) - UDAV_LOCK(sc); -#endif - - switch (cmd) { -#if defined(__FreeBSD__) - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING && - ifp->if_flags & IFF_PROMISC) { - UDAV_SETBIT(sc, UDAV_RCR, - UDAV_RCR_ALL|UDAV_RCR_PRMSC); - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && - !(ifp->if_flags & IFF_PROMISC)) { - if (ifp->if_flags & IFF_ALLMULTI) - UDAV_CLRBIT(sc, UDAV_RCR, - UDAV_RCR_PRMSC); - else - UDAV_CLRBIT(sc, UDAV_RCR, - UDAV_RCR_ALL|UDAV_RCR_PRMSC); - } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - udav_init(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - udav_stop(ifp, 1); - } - error = 0; - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - udav_setmulti(sc); - error = 0; - break; -#endif - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: - mii = GET_MII(sc); - error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd); - break; - - default: - error = ether_ioctl(ifp, cmd, data); -#if defined(__NetBSD__) - if (error == ENETRESET) { - udav_setmulti(sc); - error = 0; - } -#endif - break; - } - -#if defined(__NetBSD__) - splx(s); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); -#endif - - return (error); -} - -static void -udav_watchdog(struct ifnet *ifp) -{ - struct udav_softc *sc = ifp->if_softc; - struct ue_chain *c; - usbd_status stat; -#if defined(__NetBSD__) - int s; -#endif - - DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - ifp->if_oerrors++; - printf("%s: watchdog timeout\n", device_get_nameunit(sc->sc_dev)); - -#if defined(__NetBSD__) - s = splusb(); -#elif defined(__FreeBSD__) - UDAV_LOCK(sc) -#endif - c = &sc->sc_cdata.ue_tx_chain[0]; - usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat); - udav_txeof(c->ue_xfer, c, stat); - -#if defined(__NetBSD__) - if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) -#elif defined(__FreeBSD__) - if ( ifp->if_snd.ifq_head != NULL ) -#endif - udav_start(ifp); -#if defined(__NetBSD__) - splx(s); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); -#endif -} - -static void -udav_stop_task(struct udav_softc *sc) -{ - udav_stop(GET_IFP(sc), 1); -} - -/* Stop the adapter and free any mbufs allocated to the RX and TX lists. */ -static void -udav_stop(struct ifnet *ifp, int disable) -{ - struct udav_softc *sc = ifp->if_softc; - usbd_status err; - - DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - ifp->if_timer = 0; - - udav_reset(sc); - - usb_uncallout(sc->sc_stat_ch, udav_tick, sc); - - /* Stop transfers */ - /* RX endpoint */ - if (sc->sc_pipe_rx != NULL) { - err = usbd_abort_pipe(sc->sc_pipe_rx); - if (err) - printf("%s: abort rx pipe failed: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(err)); - err = usbd_close_pipe(sc->sc_pipe_rx); - if (err) - printf("%s: close rx pipe failed: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(err)); - sc->sc_pipe_rx = NULL; - } - - /* TX endpoint */ - if (sc->sc_pipe_tx != NULL) { - err = usbd_abort_pipe(sc->sc_pipe_tx); - if (err) - printf("%s: abort tx pipe failed: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(err)); - err = usbd_close_pipe(sc->sc_pipe_tx); - if (err) - printf("%s: close tx pipe failed: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(err)); - sc->sc_pipe_tx = NULL; - } - -#if 0 - /* XXX: Interrupt endpoint is not yet supported!! */ - /* Interrupt endpoint */ - if (sc->sc_pipe_intr != NULL) { - err = usbd_abort_pipe(sc->sc_pipe_intr); - if (err) - printf("%s: abort intr pipe failed: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(err)); - err = usbd_close_pipe(sc->sc_pipe_intr); - if (err) - printf("%s: close intr pipe failed: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(err)); - sc->sc_pipe_intr = NULL; - } -#endif - - /* Free RX resources. */ - usb_ether_rx_list_free(&sc->sc_cdata); - /* Free TX resources. */ - usb_ether_tx_list_free(&sc->sc_cdata); - - sc->sc_link = 0; -#if defined(__FreeBSD__) - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); -#else - ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); -#endif -} - -/* Set media options */ -static int -udav_ifmedia_change(struct ifnet *ifp) -{ - struct udav_softc *sc = ifp->if_softc; - struct mii_data *mii = GET_MII(sc); - - DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - if (sc->sc_dying) - return (0); - - sc->sc_link = 0; - if (mii->mii_instance) { - struct mii_softc *miisc; - for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL; - miisc = LIST_NEXT(miisc, mii_list)) - mii_phy_reset(miisc); - } - - return (mii_mediachg(mii)); -} - -/* Report current media status. */ -static void -udav_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr) -{ - struct udav_softc *sc = ifp->if_softc; - struct mii_data *mii = GET_MII(sc); - - DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); - - if (sc->sc_dying) - return; - -#if defined(__FreeBSD__) - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { -#else - if ((ifp->if_flags & IFF_RUNNING) == 0) { -#endif - ifmr->ifm_active = IFM_ETHER | IFM_NONE; - ifmr->ifm_status = 0; - return; - } - - mii_pollstat(mii); - ifmr->ifm_active = mii->mii_media_active; - ifmr->ifm_status = mii->mii_media_status; -} - -static void -udav_tick(void *xsc) -{ - struct udav_softc *sc = xsc; - - if (sc == NULL) - return; - - DPRINTFN(0xff, ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), - __func__)); - - if (sc->sc_dying) - return; - - /* Perform periodic stuff in process context */ - usb_add_task(sc->sc_udev, &sc->sc_tick_task, USB_TASKQ_DRIVER); -} - -static void -udav_tick_task(void *xsc) -{ - struct udav_softc *sc = xsc; - struct ifnet *ifp; - struct mii_data *mii; -#if defined(__NetBSD__) - int s; -#endif - - if (sc == NULL) - return; - - DPRINTFN(0xff, ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), - __func__)); - - if (sc->sc_dying) - return; - - ifp = GET_IFP(sc); - mii = GET_MII(sc); - - if (mii == NULL) - return; - -#if defined(__NetBSD__) - s = splnet(); -#elif defined(__FreeBSD__) - UDAV_LOCK(sc); -#endif - - mii_tick(mii); - if (!sc->sc_link) { - mii_pollstat(mii); - if (mii->mii_media_status & IFM_ACTIVE && - IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { - DPRINTF(("%s: %s: got link\n", - device_get_nameunit(sc->sc_dev), __func__)); - sc->sc_link++; -#if defined(__NetBSD__) - if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) -#elif defined(__FreeBSD__) - if ( ifp->if_snd.ifq_head != NULL ) -#endif - udav_start(ifp); - } - } - - usb_callout(sc->sc_stat_ch, hz, udav_tick, sc); - -#if defined(__NetBSD__) - splx(s); -#elif defined(__FreeBSD__) - UDAV_UNLOCK(sc); -#endif -} - -/* Get exclusive access to the MII registers */ -static void -udav_lock_mii(struct udav_softc *sc) -{ - DPRINTFN(0xff, ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), - __func__)); - - sc->sc_refcnt++; - lockmgr(&sc->sc_mii_lock, LK_EXCLUSIVE, NULL); -} - -static void -udav_unlock_mii(struct udav_softc *sc) -{ - DPRINTFN(0xff, ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), - __func__)); - - lockmgr(&sc->sc_mii_lock, LK_RELEASE, NULL); - if (--sc->sc_refcnt < 0) - usb_detach_wakeup(sc->sc_dev); -} - -static int -udav_miibus_readreg(device_t dev, int phy, int reg) -{ - struct udav_softc *sc; - u_int8_t val[2]; - u_int16_t data16; - - if (dev == NULL) - return (0); - - sc = USBGETSOFTC(dev); - - DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n", - device_get_nameunit(sc->sc_dev), __func__, phy, reg)); - - if (sc->sc_dying) { -#ifdef DIAGNOSTIC - printf("%s: %s: dying\n", device_get_nameunit(sc->sc_dev), - __func__); -#endif - return (0); - } - - /* XXX: one PHY only for the internal PHY */ - if (phy != 0) { - DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", - device_get_nameunit(sc->sc_dev), __func__, phy)); - return (0); - } - - udav_lock_mii(sc); - - /* select internal PHY and set PHY register address */ - udav_csr_write1(sc, UDAV_EPAR, - UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK)); - - /* select PHY operation and start read command */ - udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR); - - /* XXX: should be wait? */ - - /* end read command */ - UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRR); - - /* retrieve the result from data registers */ - udav_csr_read(sc, UDAV_EPDRL, val, 2); - - udav_unlock_mii(sc); - - data16 = val[0] | (val[1] << 8); - - DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n", - device_get_nameunit(sc->sc_dev), __func__, phy, reg, data16)); - - return (data16); -} - -static int -udav_miibus_writereg(device_t dev, int phy, int reg, int data) -{ - struct udav_softc *sc; - u_int8_t val[2]; - - if (dev == NULL) - return (0); /* XXX real error? */ - - sc = USBGETSOFTC(dev); - - DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n", - device_get_nameunit(sc->sc_dev), __func__, phy, reg, data)); - - if (sc->sc_dying) { -#ifdef DIAGNOSTIC - printf("%s: %s: dying\n", device_get_nameunit(sc->sc_dev), - __func__); -#endif - return (0); /* XXX real error? */ - } - - /* XXX: one PHY only for the internal PHY */ - if (phy != 0) { - DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", - device_get_nameunit(sc->sc_dev), __func__, phy)); - return (0); /* XXX real error? */ - } - - udav_lock_mii(sc); - - /* select internal PHY and set PHY register address */ - udav_csr_write1(sc, UDAV_EPAR, - UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK)); - - /* put the value to the data registers */ - val[0] = data & 0xff; - val[1] = (data >> 8) & 0xff; - udav_csr_write(sc, UDAV_EPDRL, val, 2); - - /* select PHY operation and start write command */ - udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW); - - /* XXX: should be wait? */ - - /* end write command */ - UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRW); - - udav_unlock_mii(sc); - - return (0); -} - -static void -udav_miibus_statchg(device_t dev) -{ -#ifdef UDAV_DEBUG - struct udav_softc *sc; - - if (dev == NULL) - return; - - sc = USBGETSOFTC(dev); - DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__)); -#endif - /* Nothing to do */ -} - -#if defined(__FreeBSD__) -/* - * Stop all chip I/O so that the kernel's probe routines don't - * get confused by errant DMAs when rebooting. - */ -static int -udav_shutdown(device_t dev) -{ - struct udav_softc *sc; - - sc = device_get_softc(dev); - - udav_stop_task(sc); - - return (0); -} - -static void -udav_rxstart(struct ifnet *ifp) -{ - struct udav_softc *sc; - struct ue_chain *c; - - sc = ifp->if_softc; - UDAV_LOCK(sc); - c = &sc->sc_cdata.ue_rx_chain[sc->sc_cdata.ue_rx_prod]; - - c->ue_mbuf = usb_ether_newbuf(); - if (c->ue_mbuf == NULL) { - printf("%s: no memory for rx list " - "-- packet dropped!\n", device_get_nameunit(sc->sc_dev)); - ifp->if_ierrors++; - UDAV_UNLOCK(sc); - return; - } - - /* Setup new transfer. */ - usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_rx, - c, c->ue_buf, UE_BUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, udav_rxeof); - usbd_transfer(c->ue_xfer); - - UDAV_UNLOCK(sc); - return; -} -#endif diff --git a/sys/legacy/dev/usb/if_udavreg.h b/sys/legacy/dev/usb/if_udavreg.h deleted file mode 100644 index cb7da28..0000000 --- a/sys/legacy/dev/usb/if_udavreg.h +++ /dev/null @@ -1,210 +0,0 @@ -/* $NetBSD: if_udavreg.h,v 1.2 2003/09/04 15:17:39 tsutsui Exp $ */ -/* $nabe: if_udavreg.h,v 1.2 2003/08/21 16:26:40 nabe Exp $ */ -/* $FreeBSD$ */ -/*- - * Copyright (c) 2003 - * Shingo WATANABE <nabe@nabechan.org>. 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 author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - */ - -#define UDAV_IFACE_INDEX 0 -#define UDAV_CONFIG_NO 1 - -#define UDAV_TX_TIMEOUT 1000 -#define UDAV_TIMEOUT 10000 - -#define ETHER_ALIGN 2 - - -/* Packet length */ -#define UDAV_MIN_FRAME_LEN 60 - -/* Request */ -#define UDAV_REQ_REG_READ 0x00 /* Read from register(s) */ -#define UDAV_REQ_REG_WRITE 0x01 /* Write to register(s) */ -#define UDAV_REQ_REG_WRITE1 0x03 /* Write to a register */ - -#define UDAV_REQ_MEM_READ 0x02 /* Read from memory */ -#define UDAV_REQ_MEM_WRITE 0x05 /* Write to memory */ -#define UDAV_REQ_MEM_WRITE1 0x07 /* Write a byte to memory */ - -/* Registers */ -#define UDAV_NCR 0x00 /* Network Control Register */ -#define UDAV_NCR_EXT_PHY (1<<7) /* Select External PHY */ -#define UDAV_NCR_WAKEEN (1<<6) /* Wakeup Event Enable */ -#define UDAV_NCR_FCOL (1<<4) /* Force Collision Mode */ -#define UDAV_NCR_FDX (1<<3) /* Full-Duplex Mode (RO on Int. PHY) */ -#define UDAV_NCR_LBK1 (1<<2) /* Lookback Mode */ -#define UDAV_NCR_LBK0 (1<<1) /* Lookback Mode */ -#define UDAV_NCR_RST (1<<0) /* Software reset */ - -#define UDAV_RCR 0x05 /* RX Control Register */ -#define UDAV_RCR_WTDIS (1<<6) /* Watchdog Timer Disable */ -#define UDAV_RCR_DIS_LONG (1<<5) /* Discard Long Packet(over 1522Byte) */ -#define UDAV_RCR_DIS_CRC (1<<4) /* Discard CRC Error Packet */ -#define UDAV_RCR_ALL (1<<3) /* Pass All Multicast */ -#define UDAV_RCR_RUNT (1<<2) /* Pass Runt Packet */ -#define UDAV_RCR_PRMSC (1<<1) /* Promiscuous Mode */ -#define UDAV_RCR_RXEN (1<<0) /* RX Enable */ - -#define UDAV_RSR 0x06 /* RX Status Register */ -#define UDAV_RSR_RF (1<<7) /* Runt Frame */ -#define UDAV_RSR_MF (1<<6) /* Multicast Frame */ -#define UDAV_RSR_LCS (1<<5) /* Late Collision Seen */ -#define UDAV_RSR_RWTO (1<<4) /* Receive Watchdog Time-Out */ -#define UDAV_RSR_PLE (1<<3) /* Physical Layer Error */ -#define UDAV_RSR_AE (1<<2) /* Alignment Error */ -#define UDAV_RSR_CE (1<<1) /* CRC Error */ -#define UDAV_RSR_FOE (1<<0) /* FIFO Overflow Error */ -#define UDAV_RSR_ERR (UDAV_RSR_RF | UDAV_RSR_LCS | UDAV_RSR_RWTO |\ - UDAV_RSR_PLE | UDAV_RSR_AE | UDAV_RSR_CE |\ - UDAV_RSR_FOE) - -#define UDAV_EPCR 0x0b /* EEPROM & PHY Control Register */ -#define UDAV_EPCR_REEP (1<<5) /* Reload EEPROM */ -#define UDAV_EPCR_WEP (1<<4) /* Write EEPROM enable */ -#define UDAV_EPCR_EPOS (1<<3) /* EEPROM or PHY Operation Select */ -#define UDAV_EPCR_ERPRR (1<<2) /* EEPROM/PHY Register Read Command */ -#define UDAV_EPCR_ERPRW (1<<1) /* EEPROM/PHY Register Write Command */ -#define UDAV_EPCR_ERRE (1<<0) /* EEPROM/PHY Access Status */ - -#define UDAV_EPAR 0x0c /* EEPROM & PHY Control Register */ -#define UDAV_EPAR_PHY_ADR1 (1<<7) /* PHY Address bit 1 */ -#define UDAV_EPAR_PHY_ADR0 (1<<6) /* PHY Address bit 0 */ -#define UDAV_EPAR_EROA (1<<0) /* EEPROM Word/PHY Register Address */ -#define UDAV_EPAR_EROA_MASK (0x1f) /* [5:0] */ - -#define UDAV_EPDRL 0x0d /* EEPROM & PHY Data Register */ -#define UDAV_EPDRH 0x0e /* EEPROM & PHY Data Register */ - -#define UDAV_PAR0 0x10 /* Ethernet Address, load from EEPROM */ -#define UDAV_PAR1 0x11 /* Ethernet Address, load from EEPROM */ -#define UDAV_PAR2 0x12 /* Ethernet Address, load from EEPROM */ -#define UDAV_PAR3 0x13 /* Ethernet Address, load from EEPROM */ -#define UDAV_PAR4 0x14 /* Ethernet Address, load from EEPROM */ -#define UDAV_PAR5 0x15 /* Ethernet Address, load from EEPROM */ -#define UDAV_PAR UDAV_PAR0 - -#define UDAV_MAR0 0x16 /* Multicast Register */ -#define UDAV_MAR1 0x17 /* Multicast Register */ -#define UDAV_MAR2 0x18 /* Multicast Register */ -#define UDAV_MAR3 0x19 /* Multicast Register */ -#define UDAV_MAR4 0x1a /* Multicast Register */ -#define UDAV_MAR5 0x1b /* Multicast Register */ -#define UDAV_MAR6 0x1c /* Multicast Register */ -#define UDAV_MAR7 0x1d /* Multicast Register */ -#define UDAV_MAR UDAV_MAR0 - -#define UDAV_GPCR 0x1e /* General purpose control register */ -#define UDAV_GPCR_GEP_CNTL6 (1<<6) /* General purpose control 6 */ -#define UDAV_GPCR_GEP_CNTL5 (1<<5) /* General purpose control 5 */ -#define UDAV_GPCR_GEP_CNTL4 (1<<4) /* General purpose control 4 */ -#define UDAV_GPCR_GEP_CNTL3 (1<<3) /* General purpose control 3 */ -#define UDAV_GPCR_GEP_CNTL2 (1<<2) /* General purpose control 2 */ -#define UDAV_GPCR_GEP_CNTL1 (1<<1) /* General purpose control 1 */ -#define UDAV_GPCR_GEP_CNTL0 (1<<0) /* General purpose control 0 */ - -#define UDAV_GPR 0x1f /* General purpose register */ -#define UDAV_GPR_GEPIO6 (1<<6) /* General purpose 6 */ -#define UDAV_GPR_GEPIO5 (1<<5) /* General purpose 5 */ -#define UDAV_GPR_GEPIO4 (1<<4) /* General purpose 4 */ -#define UDAV_GPR_GEPIO3 (1<<3) /* General purpose 3 */ -#define UDAV_GPR_GEPIO2 (1<<2) /* General purpose 2 */ -#define UDAV_GPR_GEPIO1 (1<<1) /* General purpose 1 */ -#define UDAV_GPR_GEPIO0 (1<<0) /* General purpose 0 */ - -#if defined(__FreeBSD__) -#define GET_IFP(sc) ((sc)->sc_ifp) -#elif defined(__OpenBSD__) -#define GET_IFP(sc) (&(sc)->sc_ac.ac_if) -#elif defined(__NetBSD__) -#define GET_IFP(sc) (&(sc)->sc_ec.ec_if) -#endif -#if defined(__FreeBSD__) -#define GET_MII(sc) (device_get_softc((sc)->sc_miibus)) -#else -#define GET_MII(sc) (&(sc)->sc_mii) -#endif - -#if defined(__FreeBSD__) -#if 0 -#define UDAV_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) -#define UDAV_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) -#else -#define UDAV_LOCK(_sc) -#define UDAV_UNLOCK(_sc) -#endif -#endif - -struct udav_softc { -#if defined(__FreeBSD__) - struct ifnet *sc_ifp; -#endif - device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; - - /* USB */ - usbd_interface_handle sc_ctl_iface; - /* int sc_ctl_iface_no; */ - int sc_bulkin_no; /* bulk in endpoint */ - int sc_bulkout_no; /* bulk out endpoint */ - int sc_intrin_no; /* intr in endpoint */ - usbd_pipe_handle sc_pipe_rx; - usbd_pipe_handle sc_pipe_tx; - usbd_pipe_handle sc_pipe_intr; - usb_callout_t sc_stat_ch; - u_int sc_rx_errs; - /* u_int sc_intr_errs; */ - struct timeval sc_rx_notice; - - /* Ethernet */ - -#if defined(__FreeBSD__) - device_t sc_miibus ; - struct mtx sc_mtx ; - struct usb_qdat sc_qdat; -#elif defined(__NetBSD__) - struct ethercom sc_ec; /* ethernet common */ - struct mii_data sc_mii; -#endif - struct lock sc_mii_lock; - int sc_link; -#define sc_media udav_mii.mii_media -#if defined(NRND) && NRND > 0 - rndsource_element_t rnd_source; -#endif - struct ue_cdata sc_cdata; - - int sc_attached; - int sc_dying; - int sc_refcnt; - - struct usb_task sc_tick_task; - struct usb_task sc_stop_task; - - u_int16_t sc_flags; -}; diff --git a/sys/legacy/dev/usb/if_ural.c b/sys/legacy/dev/usb/if_ural.c deleted file mode 100644 index 4595761..0000000 --- a/sys/legacy/dev/usb/if_ural.c +++ /dev/null @@ -1,2505 +0,0 @@ -/* $FreeBSD$ */ - -/*- - * Copyright (c) 2005, 2006 - * Damien Bergamini <damien.bergamini@free.fr> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/*- - * Ralink Technology RT2500USB chipset driver - * http://www.ralinktech.com/ - */ - -#include <sys/param.h> -#include <sys/sysctl.h> -#include <sys/sockio.h> -#include <sys/mbuf.h> -#include <sys/kernel.h> -#include <sys/socket.h> -#include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/endian.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <net/bpf.h> -#include <net/if.h> -#include <net/if_arp.h> -#include <net/ethernet.h> -#include <net/if_dl.h> -#include <net/if_media.h> -#include <net/if_types.h> - -#include <net80211/ieee80211_var.h> -#include <net80211/ieee80211_amrr.h> -#include <net80211/ieee80211_phy.h> -#include <net80211/ieee80211_radiotap.h> -#include <net80211/ieee80211_regdomain.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include "usbdevs.h" - -#include <dev/usb/if_uralreg.h> -#include <dev/usb/if_uralvar.h> - -#ifdef USB_DEBUG -#define DPRINTF(x) do { if (uraldebug > 0) printf x; } while (0) -#define DPRINTFN(n, x) do { if (uraldebug >= (n)) printf x; } while (0) -int uraldebug = 0; -SYSCTL_NODE(_hw_usb, OID_AUTO, ural, CTLFLAG_RW, 0, "USB ural"); -SYSCTL_INT(_hw_usb_ural, OID_AUTO, debug, CTLFLAG_RW, &uraldebug, 0, - "ural debug level"); -#else -#define DPRINTF(x) -#define DPRINTFN(n, x) -#endif - -#define URAL_RSSI(rssi) \ - ((rssi) > (RAL_NOISE_FLOOR + RAL_RSSI_CORR) ? \ - ((rssi) - (RAL_NOISE_FLOOR + RAL_RSSI_CORR)) : 0) - -/* various supported device vendors/products */ -static const struct usb_devno ural_devs[] = { - { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_WL167G }, - { USB_VENDOR_ASUS, USB_PRODUCT_RALINK_RT2570 }, - { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050 }, - { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7051 }, - { USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU }, - { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG122 }, - { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWBKG }, - { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GN54G }, - { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254 }, - { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54G }, - { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GP }, - { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_HU200TS }, - { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54 }, - { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54AI }, - { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54YB }, - { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_NINWIFI }, - { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570 }, - { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_2 }, - { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_3 }, - { USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_NV902 }, - { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570 }, - { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_2 }, - { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_3 }, - { USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WL54G }, - { USB_VENDOR_SMC, USB_PRODUCT_SMC_2862WG }, - { USB_VENDOR_SPHAIRON, USB_PRODUCT_SPHAIRON_UB801R}, - { USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2570 }, - { USB_VENDOR_VTECH, USB_PRODUCT_VTECH_RT2570 }, - { USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT2570 } -}; - -MODULE_DEPEND(ural, wlan, 1, 1, 1); -MODULE_DEPEND(ural, wlan_amrr, 1, 1, 1); -MODULE_DEPEND(ural, usb, 1, 1, 1); - -static struct ieee80211vap *ural_vap_create(struct ieee80211com *, - const char name[IFNAMSIZ], int unit, int opmode, - int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]); -static void ural_vap_delete(struct ieee80211vap *); -static int ural_alloc_tx_list(struct ural_softc *); -static void ural_free_tx_list(struct ural_softc *); -static int ural_alloc_rx_list(struct ural_softc *); -static void ural_free_rx_list(struct ural_softc *); -static void ural_task(void *); -static void ural_scantask(void *); -static int ural_newstate(struct ieee80211vap *, - enum ieee80211_state, int); -static void ural_txeof(usbd_xfer_handle, usbd_private_handle, - usbd_status); -static void ural_rxeof(usbd_xfer_handle, usbd_private_handle, - usbd_status); -static void ural_setup_tx_desc(struct ural_softc *, - struct ural_tx_desc *, uint32_t, int, int); -static int ural_tx_bcn(struct ural_softc *, struct mbuf *, - struct ieee80211_node *); -static int ural_tx_mgt(struct ural_softc *, struct mbuf *, - struct ieee80211_node *); -static int ural_tx_data(struct ural_softc *, struct mbuf *, - struct ieee80211_node *); -static void ural_start(struct ifnet *); -static void ural_watchdog(void *); -static int ural_ioctl(struct ifnet *, u_long, caddr_t); -static void ural_set_testmode(struct ural_softc *); -static void ural_eeprom_read(struct ural_softc *, uint16_t, void *, - int); -static uint16_t ural_read(struct ural_softc *, uint16_t); -static void ural_read_multi(struct ural_softc *, uint16_t, void *, - int); -static void ural_write(struct ural_softc *, uint16_t, uint16_t); -static void ural_write_multi(struct ural_softc *, uint16_t, void *, - int) __unused; -static void ural_bbp_write(struct ural_softc *, uint8_t, uint8_t); -static uint8_t ural_bbp_read(struct ural_softc *, uint8_t); -static void ural_rf_write(struct ural_softc *, uint8_t, uint32_t); -static struct ieee80211_node *ural_node_alloc(struct ieee80211vap *, - const uint8_t mac[IEEE80211_ADDR_LEN]); -static void ural_newassoc(struct ieee80211_node *, int); -static void ural_scan_start(struct ieee80211com *); -static void ural_scan_end(struct ieee80211com *); -static void ural_set_channel(struct ieee80211com *); -static void ural_set_chan(struct ural_softc *, - struct ieee80211_channel *); -static void ural_disable_rf_tune(struct ural_softc *); -static void ural_enable_tsf_sync(struct ural_softc *); -static void ural_update_slot(struct ifnet *); -static void ural_set_txpreamble(struct ural_softc *); -static void ural_set_basicrates(struct ural_softc *, - const struct ieee80211_channel *); -static void ural_set_bssid(struct ural_softc *, const uint8_t *); -static void ural_set_macaddr(struct ural_softc *, uint8_t *); -static void ural_update_promisc(struct ural_softc *); -static const char *ural_get_rf(int); -static void ural_read_eeprom(struct ural_softc *); -static int ural_bbp_init(struct ural_softc *); -static void ural_set_txantenna(struct ural_softc *, int); -static void ural_set_rxantenna(struct ural_softc *, int); -static void ural_init_locked(struct ural_softc *); -static void ural_init(void *); -static void ural_stop(void *); -static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *, - const struct ieee80211_bpf_params *); -static void ural_amrr_start(struct ural_softc *, - struct ieee80211_node *); -static void ural_amrr_timeout(void *); -static void ural_amrr_update(usbd_xfer_handle, usbd_private_handle, - usbd_status status); - -/* - * Default values for MAC registers; values taken from the reference driver. - */ -static const struct { - uint16_t reg; - uint16_t val; -} ural_def_mac[] = { - { RAL_TXRX_CSR5, 0x8c8d }, - { RAL_TXRX_CSR6, 0x8b8a }, - { RAL_TXRX_CSR7, 0x8687 }, - { RAL_TXRX_CSR8, 0x0085 }, - { RAL_MAC_CSR13, 0x1111 }, - { RAL_MAC_CSR14, 0x1e11 }, - { RAL_TXRX_CSR21, 0xe78f }, - { RAL_MAC_CSR9, 0xff1d }, - { RAL_MAC_CSR11, 0x0002 }, - { RAL_MAC_CSR22, 0x0053 }, - { RAL_MAC_CSR15, 0x0000 }, - { RAL_MAC_CSR8, 0x0780 }, - { RAL_TXRX_CSR19, 0x0000 }, - { RAL_TXRX_CSR18, 0x005a }, - { RAL_PHY_CSR2, 0x0000 }, - { RAL_TXRX_CSR0, 0x1ec0 }, - { RAL_PHY_CSR4, 0x000f } -}; - -/* - * Default values for BBP registers; values taken from the reference driver. - */ -static const struct { - uint8_t reg; - uint8_t val; -} ural_def_bbp[] = { - { 3, 0x02 }, - { 4, 0x19 }, - { 14, 0x1c }, - { 15, 0x30 }, - { 16, 0xac }, - { 17, 0x48 }, - { 18, 0x18 }, - { 19, 0xff }, - { 20, 0x1e }, - { 21, 0x08 }, - { 22, 0x08 }, - { 23, 0x08 }, - { 24, 0x80 }, - { 25, 0x50 }, - { 26, 0x08 }, - { 27, 0x23 }, - { 30, 0x10 }, - { 31, 0x2b }, - { 32, 0xb9 }, - { 34, 0x12 }, - { 35, 0x50 }, - { 39, 0xc4 }, - { 40, 0x02 }, - { 41, 0x60 }, - { 53, 0x10 }, - { 54, 0x18 }, - { 56, 0x08 }, - { 57, 0x10 }, - { 58, 0x08 }, - { 61, 0x60 }, - { 62, 0x10 }, - { 75, 0xff } -}; - -/* - * Default values for RF register R2 indexed by channel numbers. - */ -static const uint32_t ural_rf2522_r2[] = { - 0x307f6, 0x307fb, 0x30800, 0x30805, 0x3080a, 0x3080f, 0x30814, - 0x30819, 0x3081e, 0x30823, 0x30828, 0x3082d, 0x30832, 0x3083e -}; - -static const uint32_t ural_rf2523_r2[] = { - 0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d, - 0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346 -}; - -static const uint32_t ural_rf2524_r2[] = { - 0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d, - 0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346 -}; - -static const uint32_t ural_rf2525_r2[] = { - 0x20327, 0x20328, 0x20329, 0x2032a, 0x2032b, 0x2032c, 0x2032d, - 0x2032e, 0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20346 -}; - -static const uint32_t ural_rf2525_hi_r2[] = { - 0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20344, 0x20345, - 0x20346, 0x20347, 0x20348, 0x20349, 0x2034a, 0x2034b, 0x2034e -}; - -static const uint32_t ural_rf2525e_r2[] = { - 0x2044d, 0x2044e, 0x2044f, 0x20460, 0x20461, 0x20462, 0x20463, - 0x20464, 0x20465, 0x20466, 0x20467, 0x20468, 0x20469, 0x2046b -}; - -static const uint32_t ural_rf2526_hi_r2[] = { - 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d, 0x0022d, - 0x0022e, 0x0022e, 0x0022f, 0x0022d, 0x00240, 0x00240, 0x00241 -}; - -static const uint32_t ural_rf2526_r2[] = { - 0x00226, 0x00227, 0x00227, 0x00228, 0x00228, 0x00229, 0x00229, - 0x0022a, 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d -}; - -/* - * For dual-band RF, RF registers R1 and R4 also depend on channel number; - * values taken from the reference driver. - */ -static const struct { - uint8_t chan; - uint32_t r1; - uint32_t r2; - uint32_t r4; -} ural_rf5222[] = { - { 1, 0x08808, 0x0044d, 0x00282 }, - { 2, 0x08808, 0x0044e, 0x00282 }, - { 3, 0x08808, 0x0044f, 0x00282 }, - { 4, 0x08808, 0x00460, 0x00282 }, - { 5, 0x08808, 0x00461, 0x00282 }, - { 6, 0x08808, 0x00462, 0x00282 }, - { 7, 0x08808, 0x00463, 0x00282 }, - { 8, 0x08808, 0x00464, 0x00282 }, - { 9, 0x08808, 0x00465, 0x00282 }, - { 10, 0x08808, 0x00466, 0x00282 }, - { 11, 0x08808, 0x00467, 0x00282 }, - { 12, 0x08808, 0x00468, 0x00282 }, - { 13, 0x08808, 0x00469, 0x00282 }, - { 14, 0x08808, 0x0046b, 0x00286 }, - - { 36, 0x08804, 0x06225, 0x00287 }, - { 40, 0x08804, 0x06226, 0x00287 }, - { 44, 0x08804, 0x06227, 0x00287 }, - { 48, 0x08804, 0x06228, 0x00287 }, - { 52, 0x08804, 0x06229, 0x00287 }, - { 56, 0x08804, 0x0622a, 0x00287 }, - { 60, 0x08804, 0x0622b, 0x00287 }, - { 64, 0x08804, 0x0622c, 0x00287 }, - - { 100, 0x08804, 0x02200, 0x00283 }, - { 104, 0x08804, 0x02201, 0x00283 }, - { 108, 0x08804, 0x02202, 0x00283 }, - { 112, 0x08804, 0x02203, 0x00283 }, - { 116, 0x08804, 0x02204, 0x00283 }, - { 120, 0x08804, 0x02205, 0x00283 }, - { 124, 0x08804, 0x02206, 0x00283 }, - { 128, 0x08804, 0x02207, 0x00283 }, - { 132, 0x08804, 0x02208, 0x00283 }, - { 136, 0x08804, 0x02209, 0x00283 }, - { 140, 0x08804, 0x0220a, 0x00283 }, - - { 149, 0x08808, 0x02429, 0x00281 }, - { 153, 0x08808, 0x0242b, 0x00281 }, - { 157, 0x08808, 0x0242d, 0x00281 }, - { 161, 0x08808, 0x0242f, 0x00281 } -}; - -static device_probe_t ural_match; -static device_attach_t ural_attach; -static device_detach_t ural_detach; - -static device_method_t ural_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, ural_match), - DEVMETHOD(device_attach, ural_attach), - DEVMETHOD(device_detach, ural_detach), - - { 0, 0 } -}; - -static driver_t ural_driver = { - "ural", - ural_methods, - sizeof(struct ural_softc) -}; - -static devclass_t ural_devclass; - -DRIVER_MODULE(ural, uhub, ural_driver, ural_devclass, usbd_driver_load, 0); - -static int -ural_match(device_t self) -{ - struct usb_attach_arg *uaa = device_get_ivars(self); - - if (uaa->iface != NULL) - return UMATCH_NONE; - - return (usb_lookup(ural_devs, uaa->vendor, uaa->product) != NULL) ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE; -} - -static int -ural_attach(device_t self) -{ - struct ural_softc *sc = device_get_softc(self); - struct usb_attach_arg *uaa = device_get_ivars(self); - struct ifnet *ifp; - struct ieee80211com *ic; - usb_interface_descriptor_t *id; - usb_endpoint_descriptor_t *ed; - usbd_status error; - int i; - uint8_t bands; - - sc->sc_udev = uaa->device; - sc->sc_dev = self; - - if (usbd_set_config_no(sc->sc_udev, RAL_CONFIG_NO, 0) != 0) { - device_printf(self, "could not set configuration no\n"); - return ENXIO; - } - - /* get the first interface handle */ - error = usbd_device2interface_handle(sc->sc_udev, RAL_IFACE_INDEX, - &sc->sc_iface); - if (error != 0) { - device_printf(self, "could not get interface handle\n"); - return ENXIO; - } - - /* - * Find endpoints. - */ - id = usbd_get_interface_descriptor(sc->sc_iface); - - sc->sc_rx_no = sc->sc_tx_no = -1; - for (i = 0; i < id->bNumEndpoints; i++) { - ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); - if (ed == NULL) { - device_printf(self, "no endpoint descriptor for %d\n", - i); - return ENXIO; - } - - if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) - sc->sc_rx_no = ed->bEndpointAddress; - else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) - sc->sc_tx_no = ed->bEndpointAddress; - } - if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) { - device_printf(self, "missing endpoint\n"); - return ENXIO; - } - - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - return ENXIO; - } - ic = ifp->if_l2com; - - mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); - - usb_init_task(&sc->sc_task, ural_task, sc); - usb_init_task(&sc->sc_scantask, ural_scantask, sc); - callout_init(&sc->watchdog_ch, 0); - - /* retrieve RT2570 rev. no */ - sc->asic_rev = ural_read(sc, RAL_MAC_CSR0); - - /* retrieve MAC address and various other things from EEPROM */ - ural_read_eeprom(sc); - - device_printf(sc->sc_dev, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n", - sc->asic_rev, ural_get_rf(sc->rf_rev)); - - ifp->if_softc = sc; - if_initname(ifp, "ural", device_get_unit(sc->sc_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSGIANT; /* USB stack is still under Giant lock */ - ifp->if_init = ural_init; - ifp->if_ioctl = ural_ioctl; - ifp->if_start = ural_start; - IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); - ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; - ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ - - /* set device capabilities */ - ic->ic_caps = - IEEE80211_C_STA /* station mode supported */ - | IEEE80211_C_IBSS /* IBSS mode supported */ - | IEEE80211_C_MONITOR /* monitor mode supported */ - | IEEE80211_C_HOSTAP /* HostAp mode supported */ - | IEEE80211_C_TXPMGT /* tx power management */ - | IEEE80211_C_SHPREAMBLE /* short preamble supported */ - | IEEE80211_C_SHSLOT /* short slot time supported */ - | IEEE80211_C_BGSCAN /* bg scanning supported */ - | IEEE80211_C_WPA /* 802.11i */ - ; - - bands = 0; - setbit(&bands, IEEE80211_MODE_11B); - setbit(&bands, IEEE80211_MODE_11G); - if (sc->rf_rev == RAL_RF_5222) - setbit(&bands, IEEE80211_MODE_11A); - ieee80211_init_channels(ic, NULL, &bands); - - ieee80211_ifattach(ic); - ic->ic_newassoc = ural_newassoc; - ic->ic_raw_xmit = ural_raw_xmit; - ic->ic_node_alloc = ural_node_alloc; - ic->ic_scan_start = ural_scan_start; - ic->ic_scan_end = ural_scan_end; - ic->ic_set_channel = ural_set_channel; - - ic->ic_vap_create = ural_vap_create; - ic->ic_vap_delete = ural_vap_delete; - - sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); - - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap)); - - sc->sc_rxtap_len = sizeof sc->sc_rxtap; - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(RAL_RX_RADIOTAP_PRESENT); - - sc->sc_txtap_len = sizeof sc->sc_txtap; - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(RAL_TX_RADIOTAP_PRESENT); - - if (bootverbose) - ieee80211_announce(ic); - - return 0; -} - -static int -ural_detach(device_t self) -{ - struct ural_softc *sc = device_get_softc(self); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - ural_stop(sc); - bpfdetach(ifp); - ieee80211_ifdetach(ic); - - usb_rem_task(sc->sc_udev, &sc->sc_task); - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - callout_stop(&sc->watchdog_ch); - - if (sc->amrr_xfer != NULL) { - usbd_free_xfer(sc->amrr_xfer); - sc->amrr_xfer = NULL; - } - - if (sc->sc_rx_pipeh != NULL) { - usbd_abort_pipe(sc->sc_rx_pipeh); - usbd_close_pipe(sc->sc_rx_pipeh); - } - - if (sc->sc_tx_pipeh != NULL) { - usbd_abort_pipe(sc->sc_tx_pipeh); - usbd_close_pipe(sc->sc_tx_pipeh); - } - - ural_free_rx_list(sc); - ural_free_tx_list(sc); - - if_free(ifp); - mtx_destroy(&sc->sc_mtx); - - return 0; -} - -static struct ieee80211vap * -ural_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]) -{ - struct ural_vap *uvp; - struct ieee80211vap *vap; - - if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ - return NULL; - uvp = (struct ural_vap *) malloc(sizeof(struct ural_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (uvp == NULL) - return NULL; - vap = &uvp->vap; - /* enable s/w bmiss handling for sta mode */ - ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); - - /* override state transition machine */ - uvp->newstate = vap->iv_newstate; - vap->iv_newstate = ural_newstate; - - callout_init(&uvp->amrr_ch, 0); - ieee80211_amrr_init(&uvp->amrr, vap, - IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, - IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, - 1000 /* 1 sec */); - - /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); - ic->ic_opmode = opmode; - return vap; -} - -static void -ural_vap_delete(struct ieee80211vap *vap) -{ - struct ural_vap *uvp = URAL_VAP(vap); - - callout_stop(&uvp->amrr_ch); - ieee80211_amrr_cleanup(&uvp->amrr); - ieee80211_vap_detach(vap); - free(uvp, M_80211_VAP); -} - -static int -ural_alloc_tx_list(struct ural_softc *sc) -{ - struct ural_tx_data *data; - int i, error; - - sc->tx_queued = sc->tx_cur = 0; - - for (i = 0; i < RAL_TX_LIST_COUNT; i++) { - data = &sc->tx_data[i]; - - data->sc = sc; - - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { - device_printf(sc->sc_dev, - "could not allocate tx xfer\n"); - error = ENOMEM; - goto fail; - } - - data->buf = usbd_alloc_buffer(data->xfer, - RAL_TX_DESC_SIZE + MCLBYTES); - if (data->buf == NULL) { - device_printf(sc->sc_dev, - "could not allocate tx buffer\n"); - error = ENOMEM; - goto fail; - } - } - - return 0; - -fail: ural_free_tx_list(sc); - return error; -} - -static void -ural_free_tx_list(struct ural_softc *sc) -{ - struct ural_tx_data *data; - int i; - - for (i = 0; i < RAL_TX_LIST_COUNT; i++) { - data = &sc->tx_data[i]; - - if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); - data->xfer = NULL; - } - - if (data->ni != NULL) { - ieee80211_free_node(data->ni); - data->ni = NULL; - } - } -} - -static int -ural_alloc_rx_list(struct ural_softc *sc) -{ - struct ural_rx_data *data; - int i, error; - - for (i = 0; i < RAL_RX_LIST_COUNT; i++) { - data = &sc->rx_data[i]; - - data->sc = sc; - - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { - device_printf(sc->sc_dev, - "could not allocate rx xfer\n"); - error = ENOMEM; - goto fail; - } - - if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) { - device_printf(sc->sc_dev, - "could not allocate rx buffer\n"); - error = ENOMEM; - goto fail; - } - - data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (data->m == NULL) { - device_printf(sc->sc_dev, - "could not allocate rx mbuf\n"); - error = ENOMEM; - goto fail; - } - - data->buf = mtod(data->m, uint8_t *); - } - - return 0; - -fail: ural_free_rx_list(sc); - return error; -} - -static void -ural_free_rx_list(struct ural_softc *sc) -{ - struct ural_rx_data *data; - int i; - - for (i = 0; i < RAL_RX_LIST_COUNT; i++) { - data = &sc->rx_data[i]; - - if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); - data->xfer = NULL; - } - - if (data->m != NULL) { - m_freem(data->m); - data->m = NULL; - } - } -} - -static void -ural_task(void *xarg) -{ - struct ural_softc *sc = xarg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct ural_vap *uvp = URAL_VAP(vap); - const struct ieee80211_txparam *tp; - enum ieee80211_state ostate; - struct ieee80211_node *ni; - struct mbuf *m; - - ostate = vap->iv_state; - - RAL_LOCK(sc); - switch (sc->sc_state) { - case IEEE80211_S_INIT: - if (ostate == IEEE80211_S_RUN) { - /* abort TSF synchronization */ - ural_write(sc, RAL_TXRX_CSR19, 0); - - /* force tx led to stop blinking */ - ural_write(sc, RAL_MAC_CSR20, 0); - } - break; - - case IEEE80211_S_RUN: - ni = vap->iv_bss; - - if (vap->iv_opmode != IEEE80211_M_MONITOR) { - ural_update_slot(ic->ic_ifp); - ural_set_txpreamble(sc); - ural_set_basicrates(sc, ic->ic_bsschan); - ural_set_bssid(sc, ni->ni_bssid); - } - - if (vap->iv_opmode == IEEE80211_M_HOSTAP || - vap->iv_opmode == IEEE80211_M_IBSS) { - m = ieee80211_beacon_alloc(ni, &uvp->bo); - if (m == NULL) { - device_printf(sc->sc_dev, - "could not allocate beacon\n"); - return; - } - - if (ural_tx_bcn(sc, m, ni) != 0) { - device_printf(sc->sc_dev, - "could not send beacon\n"); - return; - } - } - - /* make tx led blink on tx (controlled by ASIC) */ - ural_write(sc, RAL_MAC_CSR20, 1); - - if (vap->iv_opmode != IEEE80211_M_MONITOR) - ural_enable_tsf_sync(sc); - - /* enable automatic rate adaptation */ - tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; - if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) - ural_amrr_start(sc, ni); - - break; - - default: - break; - } - - RAL_UNLOCK(sc); - - IEEE80211_LOCK(ic); - uvp->newstate(vap, sc->sc_state, sc->sc_arg); - if (vap->iv_newstate_cb != NULL) - vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); - IEEE80211_UNLOCK(ic); -} - -static void -ural_scantask(void *arg) -{ - struct ural_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - - RAL_LOCK(sc); - if (sc->sc_scan_action == URAL_SCAN_START) { - /* abort TSF synchronization */ - ural_write(sc, RAL_TXRX_CSR19, 0); - ural_set_bssid(sc, ifp->if_broadcastaddr); - } else if (sc->sc_scan_action == URAL_SET_CHANNEL) { - mtx_lock(&Giant); - ural_set_chan(sc, ic->ic_curchan); - mtx_unlock(&Giant); - } else { - ural_enable_tsf_sync(sc); - /* XXX keep local copy */ - ural_set_bssid(sc, vap->iv_bss->ni_bssid); - } - RAL_UNLOCK(sc); -} - -static int -ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct ural_vap *uvp = URAL_VAP(vap); - struct ieee80211com *ic = vap->iv_ic; - struct ural_softc *sc = ic->ic_ifp->if_softc; - - callout_stop(&uvp->amrr_ch); - - /* do it in a process context */ - sc->sc_state = nstate; - sc->sc_arg = arg; - - usb_rem_task(sc->sc_udev, &sc->sc_task); - if (nstate == IEEE80211_S_INIT) { - uvp->newstate(vap, nstate, arg); - return 0; - } else { - usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); - return EINPROGRESS; - } -} - -#define RAL_RXTX_TURNAROUND 5 /* us */ - -static void -ural_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct ural_tx_data *data = priv; - struct ural_softc *sc = data->sc; - struct ifnet *ifp = sc->sc_ifp; - - if (data->m->m_flags & M_TXCB) - ieee80211_process_callback(data->ni, data->m, - status == USBD_NORMAL_COMPLETION ? 0 : ETIMEDOUT); - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) - return; - - device_printf(sc->sc_dev, "could not transmit buffer: %s\n", - usbd_errstr(status)); - - if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh); - - ifp->if_oerrors++; - /* XXX mbuf leak? */ - return; - } - - m_freem(data->m); - data->m = NULL; - ieee80211_free_node(data->ni); - data->ni = NULL; - - sc->tx_queued--; - ifp->if_opackets++; - - DPRINTFN(10, ("tx done\n")); - - sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ural_start(ifp); -} - -static void -ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct ural_rx_data *data = priv; - struct ural_softc *sc = data->sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ural_rx_desc *desc; - struct ieee80211_node *ni; - struct mbuf *mnew, *m; - int len, rssi; - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) - return; - - if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh); - goto skip; - } - - usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); - - if (len < RAL_RX_DESC_SIZE + IEEE80211_MIN_LEN) { - DPRINTF(("%s: xfer too short %d\n", device_get_nameunit(sc->sc_dev), - len)); - ifp->if_ierrors++; - goto skip; - } - - /* rx descriptor is located at the end */ - desc = (struct ural_rx_desc *)(data->buf + len - RAL_RX_DESC_SIZE); - - if ((le32toh(desc->flags) & RAL_RX_PHY_ERROR) || - (le32toh(desc->flags) & RAL_RX_CRC_ERROR)) { - /* - * This should not happen since we did not request to receive - * those frames when we filled RAL_TXRX_CSR2. - */ - DPRINTFN(5, ("PHY or CRC error\n")); - ifp->if_ierrors++; - goto skip; - } - - mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (mnew == NULL) { - ifp->if_ierrors++; - goto skip; - } - - m = data->m; - data->m = mnew; - data->buf = mtod(data->m, uint8_t *); - - /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; - m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; - - if (bpf_peers_present(ifp->if_bpf)) { - struct ural_rx_radiotap_header *tap = &sc->sc_rxtap; - - tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; - tap->wr_rate = ieee80211_plcp2rate(desc->rate, - (desc->flags & htole32(RAL_RX_OFDM)) ? - IEEE80211_T_OFDM : IEEE80211_T_CCK); - tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); - tap->wr_antenna = sc->rx_ant; - tap->wr_antsignal = URAL_RSSI(desc->rssi); - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); - } - - /* Strip trailing 802.11 MAC FCS. */ - m_adj(m, -IEEE80211_CRC_LEN); - - rssi = URAL_RSSI(desc->rssi); - ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); - if (ni != NULL) { - (void) ieee80211_input(ni, m, rssi, RAL_NOISE_FLOOR, 0); - ieee80211_free_node(ni); - } else - (void) ieee80211_input_all(ic, m, rssi, RAL_NOISE_FLOOR, 0); - - DPRINTFN(15, ("rx done\n")); - -skip: /* setup a new transfer */ - usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ural_rxeof); - usbd_transfer(xfer); -} - -static uint8_t -ural_plcp_signal(int rate) -{ - switch (rate) { - /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ - case 12: return 0xb; - case 18: return 0xf; - case 24: return 0xa; - case 36: return 0xe; - case 48: return 0x9; - case 72: return 0xd; - case 96: return 0x8; - case 108: return 0xc; - - /* CCK rates (NB: not IEEE std, device-specific) */ - case 2: return 0x0; - case 4: return 0x1; - case 11: return 0x2; - case 22: return 0x3; - } - return 0xff; /* XXX unsupported/unknown rate */ -} - -static void -ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc, - uint32_t flags, int len, int rate) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - uint16_t plcp_length; - int remainder; - - desc->flags = htole32(flags); - desc->flags |= htole32(RAL_TX_NEWSEQ); - desc->flags |= htole32(len << 16); - - desc->wme = htole16(RAL_AIFSN(2) | RAL_LOGCWMIN(3) | RAL_LOGCWMAX(5)); - desc->wme |= htole16(RAL_IVOFFSET(sizeof (struct ieee80211_frame))); - - /* setup PLCP fields */ - desc->plcp_signal = ural_plcp_signal(rate); - desc->plcp_service = 4; - - len += IEEE80211_CRC_LEN; - if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) { - desc->flags |= htole32(RAL_TX_OFDM); - - plcp_length = len & 0xfff; - desc->plcp_length_hi = plcp_length >> 6; - desc->plcp_length_lo = plcp_length & 0x3f; - } else { - plcp_length = (16 * len + rate - 1) / rate; - if (rate == 22) { - remainder = (16 * len) % 22; - if (remainder != 0 && remainder < 7) - desc->plcp_service |= RAL_PLCP_LENGEXT; - } - desc->plcp_length_hi = plcp_length >> 8; - desc->plcp_length_lo = plcp_length & 0xff; - - if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) - desc->plcp_signal |= 0x08; - } - - desc->iv = 0; - desc->eiv = 0; -} - -#define RAL_TX_TIMEOUT 5000 - -static int -ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - const struct ieee80211_txparam *tp; - struct ural_tx_desc *desc; - usbd_xfer_handle xfer; - uint8_t cmd; - usbd_status error; - uint8_t *buf; - int xferlen; - - tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; - - xfer = usbd_alloc_xfer(sc->sc_udev); - if (xfer == NULL) - return ENOMEM; - - /* xfer length needs to be a multiple of two! */ - xferlen = (RAL_TX_DESC_SIZE + m0->m_pkthdr.len + 1) & ~1; - - buf = usbd_alloc_buffer(xfer, xferlen); - if (buf == NULL) { - usbd_free_xfer(xfer); - return ENOMEM; - } - - cmd = 0; - usbd_setup_xfer(xfer, sc->sc_tx_pipeh, NULL, &cmd, sizeof cmd, - USBD_FORCE_SHORT_XFER, RAL_TX_TIMEOUT, NULL); - - error = usbd_sync_transfer(xfer); - if (error != 0) { - usbd_free_xfer(xfer); - return error; - } - - desc = (struct ural_tx_desc *)buf; - - m_copydata(m0, 0, m0->m_pkthdr.len, buf + RAL_TX_DESC_SIZE); - ural_setup_tx_desc(sc, desc, RAL_TX_IFS_NEWBACKOFF | RAL_TX_TIMESTAMP, - m0->m_pkthdr.len, tp->mgmtrate); - - DPRINTFN(10, ("sending beacon frame len=%u rate=%u xfer len=%u\n", - m0->m_pkthdr.len, tp->mgmtrate, xferlen)); - - usbd_setup_xfer(xfer, sc->sc_tx_pipeh, NULL, buf, xferlen, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, NULL); - - error = usbd_sync_transfer(xfer); - usbd_free_xfer(xfer); - - return error; -} - -static int -ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = sc->sc_ifp; - const struct ieee80211_txparam *tp; - struct ural_tx_desc *desc; - struct ural_tx_data *data; - struct ieee80211_frame *wh; - struct ieee80211_key *k; - uint32_t flags; - uint16_t dur; - usbd_status error; - int xferlen; - - data = &sc->tx_data[sc->tx_cur]; - desc = (struct ural_tx_desc *)data->buf; - - tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; - - wh = mtod(m0, struct ieee80211_frame *); - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ni, m0); - if (k == NULL) { - m_freem(m0); - return ENOBUFS; - } - wh = mtod(m0, struct ieee80211_frame *); - } - - data->m = m0; - data->ni = ni; - - flags = 0; - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - flags |= RAL_TX_ACK; - - dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate, - ic->ic_flags & IEEE80211_F_SHPREAMBLE); - *(uint16_t *)wh->i_dur = htole16(dur); - - /* tell hardware to add timestamp for probe responses */ - if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_MGT && - (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == - IEEE80211_FC0_SUBTYPE_PROBE_RESP) - flags |= RAL_TX_TIMESTAMP; - } - - if (bpf_peers_present(ifp->if_bpf)) { - struct ural_tx_radiotap_header *tap = &sc->sc_txtap; - - tap->wt_flags = 0; - tap->wt_rate = tp->mgmtrate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - tap->wt_antenna = sc->tx_ant; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); - } - - m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE); - ural_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, tp->mgmtrate); - - /* align end on a 2-bytes boundary */ - xferlen = (RAL_TX_DESC_SIZE + m0->m_pkthdr.len + 1) & ~1; - - /* - * No space left in the last URB to store the extra 2 bytes, force - * sending of another URB. - */ - if ((xferlen % 64) == 0) - xferlen += 2; - - DPRINTFN(10, ("sending mgt frame len=%u rate=%u xfer len=%u\n", - m0->m_pkthdr.len, tp->mgmtrate, xferlen)); - - usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, - xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, - ural_txeof); - - error = usbd_transfer(data->xfer); - if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { - m_freem(m0); - data->m = NULL; - data->ni = NULL; - return error; - } - - sc->tx_queued++; - sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT; - - return 0; -} - -static int -ural_sendprot(struct ural_softc *sc, - const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) -{ - struct ieee80211com *ic = ni->ni_ic; - const struct ieee80211_frame *wh; - struct ural_tx_desc *desc; - struct ural_tx_data *data; - struct mbuf *mprot; - int protrate, ackrate, pktlen, flags, isshort; - uint16_t dur; - usbd_status error; - - KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, - ("protection %d", prot)); - - wh = mtod(m, const struct ieee80211_frame *); - pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; - - protrate = ieee80211_ctl_rate(sc->sc_rates, rate); - ackrate = ieee80211_ack_rate(sc->sc_rates, rate); - - isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; - dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort); - + ieee80211_ack_duration(sc->sc_rates, rate, isshort); - flags = RAL_TX_RETRY(7); - if (prot == IEEE80211_PROT_RTSCTS) { - /* NB: CTS is the same size as an ACK */ - dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort); - flags |= RAL_TX_ACK; - mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); - } else { - mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); - } - if (mprot == NULL) { - /* XXX stat + msg */ - return ENOBUFS; - } - data = &sc->tx_data[sc->tx_cur]; - desc = (struct ural_tx_desc *)data->buf; - - data->m = mprot; - data->ni = ieee80211_ref_node(ni); - m_copydata(mprot, 0, mprot->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE); - ural_setup_tx_desc(sc, desc, flags, mprot->m_pkthdr.len, protrate); - - usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, - /* NB: no roundup necessary */ - RAL_TX_DESC_SIZE + mprot->m_pkthdr.len, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, ural_txeof); - - error = usbd_transfer(data->xfer); - if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { - data->m = NULL; - data->ni = NULL; - return error; - } - - sc->tx_queued++; - sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT; - - return 0; -} - -static int -ural_tx_raw(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, - const struct ieee80211_bpf_params *params) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ural_tx_desc *desc; - struct ural_tx_data *data; - uint32_t flags; - usbd_status error; - int xferlen, rate; - - KASSERT(params != NULL, ("no raw xmit params")); - - data = &sc->tx_data[sc->tx_cur]; - desc = (struct ural_tx_desc *)data->buf; - - rate = params->ibp_rate0 & IEEE80211_RATE_VAL; - /* XXX validate */ - if (rate == 0) { - m_freem(m0); - return EINVAL; - } - flags = 0; - if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) - flags |= RAL_TX_ACK; - if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) { - error = ural_sendprot(sc, m0, ni, - params->ibp_flags & IEEE80211_BPF_RTS ? - IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY, - rate); - if (error) { - m_freem(m0); - return error; - } - flags |= RAL_TX_IFS_SIFS; - } - - if (bpf_peers_present(ifp->if_bpf)) { - struct ural_tx_radiotap_header *tap = &sc->sc_txtap; - - tap->wt_flags = 0; - tap->wt_rate = rate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - tap->wt_antenna = sc->tx_ant; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); - } - - data->m = m0; - data->ni = ni; - - m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE); - /* XXX need to setup descriptor ourself */ - ural_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate); - - /* align end on a 2-bytes boundary */ - xferlen = (RAL_TX_DESC_SIZE + m0->m_pkthdr.len + 1) & ~1; - - /* - * No space left in the last URB to store the extra 2 bytes, force - * sending of another URB. - */ - if ((xferlen % 64) == 0) - xferlen += 2; - - DPRINTFN(10, ("sending raw frame len=%u rate=%u xfer len=%u\n", - m0->m_pkthdr.len, rate, xferlen)); - - usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, - xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, - ural_txeof); - - error = usbd_transfer(data->xfer); - if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { - m_freem(m0); - data->m = NULL; - data->ni = NULL; - return error; - } - - sc->tx_queued++; - sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT; - - return 0; -} - -static int -ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = sc->sc_ifp; - struct ural_tx_desc *desc; - struct ural_tx_data *data; - struct ieee80211_frame *wh; - const struct ieee80211_txparam *tp; - struct ieee80211_key *k; - uint32_t flags = 0; - uint16_t dur; - usbd_status error; - int xferlen, rate; - - wh = mtod(m0, struct ieee80211_frame *); - - tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) - rate = tp->mcastrate; - else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) - rate = tp->ucastrate; - else - rate = ni->ni_txrate; - - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ni, m0); - if (k == NULL) { - m_freem(m0); - return ENOBUFS; - } - /* packet header may have moved, reset our local pointer */ - wh = mtod(m0, struct ieee80211_frame *); - } - - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - int prot = IEEE80211_PROT_NONE; - if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) - prot = IEEE80211_PROT_RTSCTS; - else if ((ic->ic_flags & IEEE80211_F_USEPROT) && - ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) - prot = ic->ic_protmode; - if (prot != IEEE80211_PROT_NONE) { - error = ural_sendprot(sc, m0, ni, prot, rate); - if (error) { - m_freem(m0); - return error; - } - flags |= RAL_TX_IFS_SIFS; - } - } - - data = &sc->tx_data[sc->tx_cur]; - desc = (struct ural_tx_desc *)data->buf; - - data->m = m0; - data->ni = ni; - - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - flags |= RAL_TX_ACK; - flags |= RAL_TX_RETRY(7); - - dur = ieee80211_ack_duration(sc->sc_rates, rate, - ic->ic_flags & IEEE80211_F_SHPREAMBLE); - *(uint16_t *)wh->i_dur = htole16(dur); - } - - if (bpf_peers_present(ifp->if_bpf)) { - struct ural_tx_radiotap_header *tap = &sc->sc_txtap; - - tap->wt_flags = 0; - tap->wt_rate = rate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - tap->wt_antenna = sc->tx_ant; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); - } - - m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE); - ural_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate); - - /* align end on a 2-bytes boundary */ - xferlen = (RAL_TX_DESC_SIZE + m0->m_pkthdr.len + 1) & ~1; - - /* - * No space left in the last URB to store the extra 2 bytes, force - * sending of another URB. - */ - if ((xferlen % 64) == 0) - xferlen += 2; - - DPRINTFN(10, ("sending data frame len=%u rate=%u xfer len=%u\n", - m0->m_pkthdr.len, rate, xferlen)); - - usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, - xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, - ural_txeof); - - error = usbd_transfer(data->xfer); - if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { - m_freem(m0); - data->m = NULL; - data->ni = NULL; - return error; - } - - sc->tx_queued++; - sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT; - - return 0; -} - -static void -ural_start(struct ifnet *ifp) -{ - struct ural_softc *sc = ifp->if_softc; - struct ieee80211_node *ni; - struct mbuf *m; - - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - if (sc->tx_queued >= RAL_TX_LIST_COUNT-1) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - m = ieee80211_encap(ni, m); - if (m == NULL) { - ieee80211_free_node(ni); - continue; - } - if (ural_tx_data(sc, m, ni) != 0) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - break; - } - sc->sc_tx_timer = 5; - callout_reset(&sc->watchdog_ch, hz, ural_watchdog, sc); - } -} - -static void -ural_watchdog(void *arg) -{ - struct ural_softc *sc = (struct ural_softc *)arg; - - RAL_LOCK(sc); - - if (sc->sc_tx_timer > 0) { - if (--sc->sc_tx_timer == 0) { - device_printf(sc->sc_dev, "device timeout\n"); - /*ural_init(sc); XXX needs a process context! */ - sc->sc_ifp->if_oerrors++; - RAL_UNLOCK(sc); - return; - } - callout_reset(&sc->watchdog_ch, hz, ural_watchdog, sc); - } - - RAL_UNLOCK(sc); -} - -static int -ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) -{ - struct ural_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; - - switch (cmd) { - case SIOCSIFFLAGS: - RAL_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - ural_init_locked(sc); - startall = 1; - } else - ural_update_promisc(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ural_stop(sc); - } - RAL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - default: - error = ether_ioctl(ifp, cmd, data); - break; - } - return error; -} - -static void -ural_set_testmode(struct ural_softc *sc) -{ - usb_device_request_t req; - usbd_status error; - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = RAL_VENDOR_REQUEST; - USETW(req.wValue, 4); - USETW(req.wIndex, 1); - USETW(req.wLength, 0); - - error = usbd_do_request(sc->sc_udev, &req, NULL); - if (error != 0) { - device_printf(sc->sc_dev, "could not set test mode: %s\n", - usbd_errstr(error)); - } -} - -static void -ural_eeprom_read(struct ural_softc *sc, uint16_t addr, void *buf, int len) -{ - usb_device_request_t req; - usbd_status error; - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = RAL_READ_EEPROM; - USETW(req.wValue, 0); - USETW(req.wIndex, addr); - USETW(req.wLength, len); - - error = usbd_do_request(sc->sc_udev, &req, buf); - if (error != 0) { - device_printf(sc->sc_dev, "could not read EEPROM: %s\n", - usbd_errstr(error)); - } -} - -static uint16_t -ural_read(struct ural_softc *sc, uint16_t reg) -{ - usb_device_request_t req; - usbd_status error; - uint16_t val; - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = RAL_READ_MAC; - USETW(req.wValue, 0); - USETW(req.wIndex, reg); - USETW(req.wLength, sizeof (uint16_t)); - - error = usbd_do_request(sc->sc_udev, &req, &val); - if (error != 0) { - device_printf(sc->sc_dev, "could not read MAC register: %s\n", - usbd_errstr(error)); - return 0; - } - - return le16toh(val); -} - -static void -ural_read_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len) -{ - usb_device_request_t req; - usbd_status error; - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = RAL_READ_MULTI_MAC; - USETW(req.wValue, 0); - USETW(req.wIndex, reg); - USETW(req.wLength, len); - - error = usbd_do_request(sc->sc_udev, &req, buf); - if (error != 0) { - device_printf(sc->sc_dev, "could not read MAC register: %s\n", - usbd_errstr(error)); - } -} - -static void -ural_write(struct ural_softc *sc, uint16_t reg, uint16_t val) -{ - usb_device_request_t req; - usbd_status error; - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = RAL_WRITE_MAC; - USETW(req.wValue, val); - USETW(req.wIndex, reg); - USETW(req.wLength, 0); - - error = usbd_do_request(sc->sc_udev, &req, NULL); - if (error != 0) { - device_printf(sc->sc_dev, "could not write MAC register: %s\n", - usbd_errstr(error)); - } -} - -static void -ural_write_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len) -{ - usb_device_request_t req; - usbd_status error; - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = RAL_WRITE_MULTI_MAC; - USETW(req.wValue, 0); - USETW(req.wIndex, reg); - USETW(req.wLength, len); - - error = usbd_do_request(sc->sc_udev, &req, buf); - if (error != 0) { - device_printf(sc->sc_dev, "could not write MAC register: %s\n", - usbd_errstr(error)); - } -} - -static void -ural_bbp_write(struct ural_softc *sc, uint8_t reg, uint8_t val) -{ - uint16_t tmp; - int ntries; - - for (ntries = 0; ntries < 5; ntries++) { - if (!(ural_read(sc, RAL_PHY_CSR8) & RAL_BBP_BUSY)) - break; - } - if (ntries == 5) { - device_printf(sc->sc_dev, "could not write to BBP\n"); - return; - } - - tmp = reg << 8 | val; - ural_write(sc, RAL_PHY_CSR7, tmp); -} - -static uint8_t -ural_bbp_read(struct ural_softc *sc, uint8_t reg) -{ - uint16_t val; - int ntries; - - val = RAL_BBP_WRITE | reg << 8; - ural_write(sc, RAL_PHY_CSR7, val); - - for (ntries = 0; ntries < 5; ntries++) { - if (!(ural_read(sc, RAL_PHY_CSR8) & RAL_BBP_BUSY)) - break; - } - if (ntries == 5) { - device_printf(sc->sc_dev, "could not read BBP\n"); - return 0; - } - - return ural_read(sc, RAL_PHY_CSR7) & 0xff; -} - -static void -ural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val) -{ - uint32_t tmp; - int ntries; - - for (ntries = 0; ntries < 5; ntries++) { - if (!(ural_read(sc, RAL_PHY_CSR10) & RAL_RF_LOBUSY)) - break; - } - if (ntries == 5) { - device_printf(sc->sc_dev, "could not write to RF\n"); - return; - } - - tmp = RAL_RF_BUSY | RAL_RF_20BIT | (val & 0xfffff) << 2 | (reg & 0x3); - ural_write(sc, RAL_PHY_CSR9, tmp & 0xffff); - ural_write(sc, RAL_PHY_CSR10, tmp >> 16); - - /* remember last written value in sc */ - sc->rf_regs[reg] = val; - - DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff)); -} - -/* ARGUSED */ -static struct ieee80211_node * -ural_node_alloc(struct ieee80211vap *vap __unused, - const uint8_t mac[IEEE80211_ADDR_LEN] __unused) -{ - struct ural_node *un; - - un = malloc(sizeof(struct ural_node), M_80211_NODE, M_NOWAIT | M_ZERO); - return un != NULL ? &un->ni : NULL; -} - -static void -ural_newassoc(struct ieee80211_node *ni, int isnew) -{ - struct ieee80211vap *vap = ni->ni_vap; - - ieee80211_amrr_node_init(&URAL_VAP(vap)->amrr, &URAL_NODE(ni)->amn, ni); -} - -static void -ural_scan_start(struct ieee80211com *ic) -{ - struct ural_softc *sc = ic->ic_ifp->if_softc; - - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - - /* do it in a process context */ - sc->sc_scan_action = URAL_SCAN_START; - usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER); - -} - -static void -ural_scan_end(struct ieee80211com *ic) -{ - struct ural_softc *sc = ic->ic_ifp->if_softc; - - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - - /* do it in a process context */ - sc->sc_scan_action = URAL_SCAN_END; - usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER); - -} - -static void -ural_set_channel(struct ieee80211com *ic) -{ - - struct ural_softc *sc = ic->ic_ifp->if_softc; - - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - - /* do it in a process context */ - sc->sc_scan_action = URAL_SET_CHANNEL; - usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER); - - sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); -} - -static void -ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - uint8_t power, tmp; - u_int i, chan; - - chan = ieee80211_chan2ieee(ic, c); - if (chan == 0 || chan == IEEE80211_CHAN_ANY) - return; - - if (IEEE80211_IS_CHAN_2GHZ(c)) - power = min(sc->txpow[chan - 1], 31); - else - power = 31; - - /* adjust txpower using ifconfig settings */ - power -= (100 - ic->ic_txpowlimit) / 8; - - DPRINTFN(2, ("setting channel to %u, txpower to %u\n", chan, power)); - - switch (sc->rf_rev) { - case RAL_RF_2522: - ural_rf_write(sc, RAL_RF1, 0x00814); - ural_rf_write(sc, RAL_RF2, ural_rf2522_r2[chan - 1]); - ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040); - break; - - case RAL_RF_2523: - ural_rf_write(sc, RAL_RF1, 0x08804); - ural_rf_write(sc, RAL_RF2, ural_rf2523_r2[chan - 1]); - ural_rf_write(sc, RAL_RF3, power << 7 | 0x38044); - ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286); - break; - - case RAL_RF_2524: - ural_rf_write(sc, RAL_RF1, 0x0c808); - ural_rf_write(sc, RAL_RF2, ural_rf2524_r2[chan - 1]); - ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040); - ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286); - break; - - case RAL_RF_2525: - ural_rf_write(sc, RAL_RF1, 0x08808); - ural_rf_write(sc, RAL_RF2, ural_rf2525_hi_r2[chan - 1]); - ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044); - ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286); - - ural_rf_write(sc, RAL_RF1, 0x08808); - ural_rf_write(sc, RAL_RF2, ural_rf2525_r2[chan - 1]); - ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044); - ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286); - break; - - case RAL_RF_2525E: - ural_rf_write(sc, RAL_RF1, 0x08808); - ural_rf_write(sc, RAL_RF2, ural_rf2525e_r2[chan - 1]); - ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044); - ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00286 : 0x00282); - break; - - case RAL_RF_2526: - ural_rf_write(sc, RAL_RF2, ural_rf2526_hi_r2[chan - 1]); - ural_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381); - ural_rf_write(sc, RAL_RF1, 0x08804); - - ural_rf_write(sc, RAL_RF2, ural_rf2526_r2[chan - 1]); - ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044); - ural_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381); - break; - - /* dual-band RF */ - case RAL_RF_5222: - for (i = 0; ural_rf5222[i].chan != chan; i++); - - ural_rf_write(sc, RAL_RF1, ural_rf5222[i].r1); - ural_rf_write(sc, RAL_RF2, ural_rf5222[i].r2); - ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040); - ural_rf_write(sc, RAL_RF4, ural_rf5222[i].r4); - break; - } - - if (ic->ic_opmode != IEEE80211_M_MONITOR && - (ic->ic_flags & IEEE80211_F_SCAN) == 0) { - /* set Japan filter bit for channel 14 */ - tmp = ural_bbp_read(sc, 70); - - tmp &= ~RAL_JAPAN_FILTER; - if (chan == 14) - tmp |= RAL_JAPAN_FILTER; - - ural_bbp_write(sc, 70, tmp); - - /* clear CRC errors */ - ural_read(sc, RAL_STA_CSR0); - - DELAY(10000); - ural_disable_rf_tune(sc); - } - - /* XXX doesn't belong here */ - /* update basic rate set */ - ural_set_basicrates(sc, c); -} - -/* - * Disable RF auto-tuning. - */ -static void -ural_disable_rf_tune(struct ural_softc *sc) -{ - uint32_t tmp; - - if (sc->rf_rev != RAL_RF_2523) { - tmp = sc->rf_regs[RAL_RF1] & ~RAL_RF1_AUTOTUNE; - ural_rf_write(sc, RAL_RF1, tmp); - } - - tmp = sc->rf_regs[RAL_RF3] & ~RAL_RF3_AUTOTUNE; - ural_rf_write(sc, RAL_RF3, tmp); - - DPRINTFN(2, ("disabling RF autotune\n")); -} - -/* - * Refer to IEEE Std 802.11-1999 pp. 123 for more information on TSF - * synchronization. - */ -static void -ural_enable_tsf_sync(struct ural_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - uint16_t logcwmin, preload, tmp; - - /* first, disable TSF synchronization */ - ural_write(sc, RAL_TXRX_CSR19, 0); - - tmp = (16 * vap->iv_bss->ni_intval) << 4; - ural_write(sc, RAL_TXRX_CSR18, tmp); - - logcwmin = (ic->ic_opmode == IEEE80211_M_IBSS) ? 2 : 0; - preload = (ic->ic_opmode == IEEE80211_M_IBSS) ? 320 : 6; - tmp = logcwmin << 12 | preload; - ural_write(sc, RAL_TXRX_CSR20, tmp); - - /* finally, enable TSF synchronization */ - tmp = RAL_ENABLE_TSF | RAL_ENABLE_TBCN; - if (ic->ic_opmode == IEEE80211_M_STA) - tmp |= RAL_ENABLE_TSF_SYNC(1); - else - tmp |= RAL_ENABLE_TSF_SYNC(2) | RAL_ENABLE_BEACON_GENERATOR; - ural_write(sc, RAL_TXRX_CSR19, tmp); - - DPRINTF(("enabling TSF synchronization\n")); -} - -static void -ural_update_slot(struct ifnet *ifp) -{ - struct ural_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - uint16_t slottime, sifs, eifs; - - slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; - - /* - * These settings may sound a bit inconsistent but this is what the - * reference driver does. - */ - if (ic->ic_curmode == IEEE80211_MODE_11B) { - sifs = 16 - RAL_RXTX_TURNAROUND; - eifs = 364; - } else { - sifs = 10 - RAL_RXTX_TURNAROUND; - eifs = 64; - } - - ural_write(sc, RAL_MAC_CSR10, slottime); - ural_write(sc, RAL_MAC_CSR11, sifs); - ural_write(sc, RAL_MAC_CSR12, eifs); -} - -static void -ural_set_txpreamble(struct ural_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - uint16_t tmp; - - tmp = ural_read(sc, RAL_TXRX_CSR10); - - tmp &= ~RAL_SHORT_PREAMBLE; - if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) - tmp |= RAL_SHORT_PREAMBLE; - - ural_write(sc, RAL_TXRX_CSR10, tmp); -} - -static void -ural_set_basicrates(struct ural_softc *sc, const struct ieee80211_channel *c) -{ - /* XXX wrong, take from rate set */ - /* update basic rate set */ - if (IEEE80211_IS_CHAN_5GHZ(c)) { - /* 11a basic rates: 6, 12, 24Mbps */ - ural_write(sc, RAL_TXRX_CSR11, 0x150); - } else if (IEEE80211_IS_CHAN_ANYG(c)) { - /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */ - ural_write(sc, RAL_TXRX_CSR11, 0x15f); - } else { - /* 11b basic rates: 1, 2Mbps */ - ural_write(sc, RAL_TXRX_CSR11, 0x3); - } -} - -static void -ural_set_bssid(struct ural_softc *sc, const uint8_t *bssid) -{ - uint16_t tmp; - - tmp = bssid[0] | bssid[1] << 8; - ural_write(sc, RAL_MAC_CSR5, tmp); - - tmp = bssid[2] | bssid[3] << 8; - ural_write(sc, RAL_MAC_CSR6, tmp); - - tmp = bssid[4] | bssid[5] << 8; - ural_write(sc, RAL_MAC_CSR7, tmp); - - DPRINTF(("setting BSSID to %6D\n", bssid, ":")); -} - -static void -ural_set_macaddr(struct ural_softc *sc, uint8_t *addr) -{ - uint16_t tmp; - - tmp = addr[0] | addr[1] << 8; - ural_write(sc, RAL_MAC_CSR2, tmp); - - tmp = addr[2] | addr[3] << 8; - ural_write(sc, RAL_MAC_CSR3, tmp); - - tmp = addr[4] | addr[5] << 8; - ural_write(sc, RAL_MAC_CSR4, tmp); - - DPRINTF(("setting MAC address to %6D\n", addr, ":")); -} - -static void -ural_update_promisc(struct ural_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - uint32_t tmp; - - tmp = ural_read(sc, RAL_TXRX_CSR2); - - tmp &= ~RAL_DROP_NOT_TO_ME; - if (!(ifp->if_flags & IFF_PROMISC)) - tmp |= RAL_DROP_NOT_TO_ME; - - ural_write(sc, RAL_TXRX_CSR2, tmp); - - DPRINTF(("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? - "entering" : "leaving")); -} - -static const char * -ural_get_rf(int rev) -{ - switch (rev) { - case RAL_RF_2522: return "RT2522"; - case RAL_RF_2523: return "RT2523"; - case RAL_RF_2524: return "RT2524"; - case RAL_RF_2525: return "RT2525"; - case RAL_RF_2525E: return "RT2525e"; - case RAL_RF_2526: return "RT2526"; - case RAL_RF_5222: return "RT5222"; - default: return "unknown"; - } -} - -static void -ural_read_eeprom(struct ural_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - uint16_t val; - - ural_eeprom_read(sc, RAL_EEPROM_CONFIG0, &val, 2); - val = le16toh(val); - sc->rf_rev = (val >> 11) & 0x7; - sc->hw_radio = (val >> 10) & 0x1; - sc->led_mode = (val >> 6) & 0x7; - sc->rx_ant = (val >> 4) & 0x3; - sc->tx_ant = (val >> 2) & 0x3; - sc->nb_ant = val & 0x3; - - /* read MAC address */ - ural_eeprom_read(sc, RAL_EEPROM_ADDRESS, ic->ic_myaddr, 6); - - /* read default values for BBP registers */ - ural_eeprom_read(sc, RAL_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16); - - /* read Tx power for all b/g channels */ - ural_eeprom_read(sc, RAL_EEPROM_TXPOWER, sc->txpow, 14); -} - -static int -ural_bbp_init(struct ural_softc *sc) -{ -#define N(a) (sizeof (a) / sizeof ((a)[0])) - int i, ntries; - - /* wait for BBP to be ready */ - for (ntries = 0; ntries < 100; ntries++) { - if (ural_bbp_read(sc, RAL_BBP_VERSION) != 0) - break; - DELAY(1000); - } - if (ntries == 100) { - device_printf(sc->sc_dev, "timeout waiting for BBP\n"); - return EIO; - } - - /* initialize BBP registers to default values */ - for (i = 0; i < N(ural_def_bbp); i++) - ural_bbp_write(sc, ural_def_bbp[i].reg, ural_def_bbp[i].val); - -#if 0 - /* initialize BBP registers to values stored in EEPROM */ - for (i = 0; i < 16; i++) { - if (sc->bbp_prom[i].reg == 0xff) - continue; - ural_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val); - } -#endif - - return 0; -#undef N -} - -static void -ural_set_txantenna(struct ural_softc *sc, int antenna) -{ - uint16_t tmp; - uint8_t tx; - - tx = ural_bbp_read(sc, RAL_BBP_TX) & ~RAL_BBP_ANTMASK; - if (antenna == 1) - tx |= RAL_BBP_ANTA; - else if (antenna == 2) - tx |= RAL_BBP_ANTB; - else - tx |= RAL_BBP_DIVERSITY; - - /* need to force I/Q flip for RF 2525e, 2526 and 5222 */ - if (sc->rf_rev == RAL_RF_2525E || sc->rf_rev == RAL_RF_2526 || - sc->rf_rev == RAL_RF_5222) - tx |= RAL_BBP_FLIPIQ; - - ural_bbp_write(sc, RAL_BBP_TX, tx); - - /* update values in PHY_CSR5 and PHY_CSR6 */ - tmp = ural_read(sc, RAL_PHY_CSR5) & ~0x7; - ural_write(sc, RAL_PHY_CSR5, tmp | (tx & 0x7)); - - tmp = ural_read(sc, RAL_PHY_CSR6) & ~0x7; - ural_write(sc, RAL_PHY_CSR6, tmp | (tx & 0x7)); -} - -static void -ural_set_rxantenna(struct ural_softc *sc, int antenna) -{ - uint8_t rx; - - rx = ural_bbp_read(sc, RAL_BBP_RX) & ~RAL_BBP_ANTMASK; - if (antenna == 1) - rx |= RAL_BBP_ANTA; - else if (antenna == 2) - rx |= RAL_BBP_ANTB; - else - rx |= RAL_BBP_DIVERSITY; - - /* need to force no I/Q flip for RF 2525e and 2526 */ - if (sc->rf_rev == RAL_RF_2525E || sc->rf_rev == RAL_RF_2526) - rx &= ~RAL_BBP_FLIPIQ; - - ural_bbp_write(sc, RAL_BBP_RX, rx); -} - -static void -ural_init_locked(struct ural_softc *sc) -{ -#define N(a) (sizeof (a) / sizeof ((a)[0])) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ural_rx_data *data; - uint16_t tmp; - usbd_status error; - int i, ntries; - - ural_set_testmode(sc); - ural_write(sc, 0x308, 0x00f0); /* XXX magic */ - - ural_stop(sc); - - /* initialize MAC registers to default values */ - for (i = 0; i < N(ural_def_mac); i++) - ural_write(sc, ural_def_mac[i].reg, ural_def_mac[i].val); - - /* wait for BBP and RF to wake up (this can take a long time!) */ - for (ntries = 0; ntries < 100; ntries++) { - tmp = ural_read(sc, RAL_MAC_CSR17); - if ((tmp & (RAL_BBP_AWAKE | RAL_RF_AWAKE)) == - (RAL_BBP_AWAKE | RAL_RF_AWAKE)) - break; - DELAY(1000); - } - if (ntries == 100) { - device_printf(sc->sc_dev, - "timeout waiting for BBP/RF to wakeup\n"); - goto fail; - } - - /* we're ready! */ - ural_write(sc, RAL_MAC_CSR1, RAL_HOST_READY); - - /* set basic rate set (will be updated later) */ - ural_write(sc, RAL_TXRX_CSR11, 0x15f); - - if (ural_bbp_init(sc) != 0) - goto fail; - - ural_set_chan(sc, ic->ic_curchan); - - /* clear statistic registers (STA_CSR0 to STA_CSR10) */ - ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta); - - ural_set_txantenna(sc, sc->tx_ant); - ural_set_rxantenna(sc, sc->rx_ant); - - IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); - ural_set_macaddr(sc, ic->ic_myaddr); - - /* - * Allocate xfer for AMRR statistics requests. - */ - sc->amrr_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->amrr_xfer == NULL) { - device_printf(sc->sc_dev, "could not allocate AMRR xfer\n"); - goto fail; - } - - /* - * Open Tx and Rx USB bulk pipes. - */ - error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE, - &sc->sc_tx_pipeh); - if (error != 0) { - device_printf(sc->sc_dev, "could not open Tx pipe: %s\n", - usbd_errstr(error)); - goto fail; - } - - error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE, - &sc->sc_rx_pipeh); - if (error != 0) { - device_printf(sc->sc_dev, "could not open Rx pipe: %s\n", - usbd_errstr(error)); - goto fail; - } - - /* - * Allocate Tx and Rx xfer queues. - */ - error = ural_alloc_tx_list(sc); - if (error != 0) { - device_printf(sc->sc_dev, "could not allocate Tx list\n"); - goto fail; - } - - error = ural_alloc_rx_list(sc); - if (error != 0) { - device_printf(sc->sc_dev, "could not allocate Rx list\n"); - goto fail; - } - - /* - * Start up the receive pipe. - */ - for (i = 0; i < RAL_RX_LIST_COUNT; i++) { - data = &sc->rx_data[i]; - - usbd_setup_xfer(data->xfer, sc->sc_rx_pipeh, data, data->buf, - MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ural_rxeof); - usbd_transfer(data->xfer); - } - - /* kick Rx */ - tmp = RAL_DROP_PHY | RAL_DROP_CRC; - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - tmp |= RAL_DROP_CTL | RAL_DROP_BAD_VERSION; - if (ic->ic_opmode != IEEE80211_M_HOSTAP) - tmp |= RAL_DROP_TODS; - if (!(ifp->if_flags & IFF_PROMISC)) - tmp |= RAL_DROP_NOT_TO_ME; - } - ural_write(sc, RAL_TXRX_CSR2, tmp); - - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; - return; - -fail: ural_stop(sc); -#undef N -} - -static void -ural_init(void *priv) -{ - struct ural_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - RAL_LOCK(sc); - ural_init_locked(sc); - RAL_UNLOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ieee80211_start_all(ic); /* start all vap's */ -} - -static void -ural_stop(void *priv) -{ - struct ural_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - - sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - - /* disable Rx */ - ural_write(sc, RAL_TXRX_CSR2, RAL_DISABLE_RX); - - /* reset ASIC and BBP (but won't reset MAC registers!) */ - ural_write(sc, RAL_MAC_CSR1, RAL_RESET_ASIC | RAL_RESET_BBP); - ural_write(sc, RAL_MAC_CSR1, 0); - - if (sc->amrr_xfer != NULL) { - usbd_free_xfer(sc->amrr_xfer); - sc->amrr_xfer = NULL; - } - - if (sc->sc_rx_pipeh != NULL) { - usbd_abort_pipe(sc->sc_rx_pipeh); - usbd_close_pipe(sc->sc_rx_pipeh); - sc->sc_rx_pipeh = NULL; - } - - if (sc->sc_tx_pipeh != NULL) { - usbd_abort_pipe(sc->sc_tx_pipeh); - usbd_close_pipe(sc->sc_tx_pipeh); - sc->sc_tx_pipeh = NULL; - } - - ural_free_rx_list(sc); - ural_free_tx_list(sc); -} - -static int -ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, - const struct ieee80211_bpf_params *params) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct ural_softc *sc = ifp->if_softc; - - /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - m_freem(m); - ieee80211_free_node(ni); - return ENETDOWN; - } - if (sc->tx_queued >= RAL_TX_LIST_COUNT) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - m_freem(m); - ieee80211_free_node(ni); - return EIO; - } - - ifp->if_opackets++; - - if (params == NULL) { - /* - * Legacy path; interpret frame contents to decide - * precisely how to send the frame. - */ - if (ural_tx_mgt(sc, m, ni) != 0) - goto bad; - } else { - /* - * Caller supplied explicit parameters to use in - * sending the frame. - */ - if (ural_tx_raw(sc, m, ni, params) != 0) - goto bad; - } - sc->sc_tx_timer = 5; - callout_reset(&sc->watchdog_ch, hz, ural_watchdog, sc); - - return 0; -bad: - ifp->if_oerrors++; - ieee80211_free_node(ni); - return EIO; /* XXX */ -} - -static void -ural_amrr_start(struct ural_softc *sc, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ural_vap *uvp = URAL_VAP(vap); - - /* clear statistic registers (STA_CSR0 to STA_CSR10) */ - ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta); - - ieee80211_amrr_node_init(&uvp->amrr, &URAL_NODE(ni)->amn, ni); - - callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, vap); -} - -static void -ural_amrr_timeout(void *arg) -{ - struct ieee80211vap *vap = arg; - struct ural_softc *sc = vap->iv_ic->ic_ifp->if_softc; - usb_device_request_t req; - - /* - * Asynchronously read statistic registers (cleared by read). - */ - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = RAL_READ_MULTI_MAC; - USETW(req.wValue, 0); - USETW(req.wIndex, RAL_STA_CSR0); - USETW(req.wLength, sizeof sc->sta); - - usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, vap, - USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof sc->sta, 0, - ural_amrr_update); - (void)usbd_transfer(sc->amrr_xfer); -} - -static void -ural_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv, - usbd_status status) -{ - struct ieee80211vap *vap = priv; - struct ural_vap *uvp = URAL_VAP(vap); - struct ifnet *ifp = vap->iv_ic->ic_ifp; - struct ural_softc *sc = ifp->if_softc; - struct ieee80211_node *ni = vap->iv_bss; - int ok, fail; - - if (status != USBD_NORMAL_COMPLETION) { - device_printf(sc->sc_dev, "could not retrieve Tx statistics - " - "cancelling automatic rate control\n"); - return; - } - - ok = sc->sta[7] + /* TX ok w/o retry */ - sc->sta[8]; /* TX ok w/ retry */ - fail = sc->sta[9]; /* TX retry-fail count */ - - ieee80211_amrr_tx_update(&URAL_NODE(ni)->amn, - ok+fail, ok, sc->sta[8] + fail); - (void) ieee80211_amrr_choose(ni, &URAL_NODE(ni)->amn); - - ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */ - - callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, vap); -} diff --git a/sys/legacy/dev/usb/if_uralreg.h b/sys/legacy/dev/usb/if_uralreg.h deleted file mode 100644 index 428089f..0000000 --- a/sys/legacy/dev/usb/if_uralreg.h +++ /dev/null @@ -1,210 +0,0 @@ -/* $FreeBSD$ */ - -/*- - * Copyright (c) 2005, 2006 - * Damien Bergamini <damien.bergamini@free.fr> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define RAL_NOISE_FLOOR -95 -#define RAL_RSSI_CORR 120 - -#define RAL_RX_DESC_SIZE (sizeof (struct ural_rx_desc)) -#define RAL_TX_DESC_SIZE (sizeof (struct ural_tx_desc)) - -#define RAL_CONFIG_NO 1 -#define RAL_IFACE_INDEX 0 - -#define RAL_VENDOR_REQUEST 0x01 -#define RAL_WRITE_MAC 0x02 -#define RAL_READ_MAC 0x03 -#define RAL_WRITE_MULTI_MAC 0x06 -#define RAL_READ_MULTI_MAC 0x07 -#define RAL_READ_EEPROM 0x09 - -/* - * MAC registers. - */ -#define RAL_MAC_CSR0 0x0400 /* ASIC Version */ -#define RAL_MAC_CSR1 0x0402 /* System control */ -#define RAL_MAC_CSR2 0x0404 /* MAC addr0 */ -#define RAL_MAC_CSR3 0x0406 /* MAC addr1 */ -#define RAL_MAC_CSR4 0x0408 /* MAC addr2 */ -#define RAL_MAC_CSR5 0x040a /* BSSID0 */ -#define RAL_MAC_CSR6 0x040c /* BSSID1 */ -#define RAL_MAC_CSR7 0x040e /* BSSID2 */ -#define RAL_MAC_CSR8 0x0410 /* Max frame length */ -#define RAL_MAC_CSR9 0x0412 /* Timer control */ -#define RAL_MAC_CSR10 0x0414 /* Slot time */ -#define RAL_MAC_CSR11 0x0416 /* IFS */ -#define RAL_MAC_CSR12 0x0418 /* EIFS */ -#define RAL_MAC_CSR13 0x041a /* Power mode0 */ -#define RAL_MAC_CSR14 0x041c /* Power mode1 */ -#define RAL_MAC_CSR15 0x041e /* Power saving transition0 */ -#define RAL_MAC_CSR16 0x0420 /* Power saving transition1 */ -#define RAL_MAC_CSR17 0x0422 /* Power state control */ -#define RAL_MAC_CSR18 0x0424 /* Auto wake-up control */ -#define RAL_MAC_CSR19 0x0426 /* GPIO control */ -#define RAL_MAC_CSR20 0x0428 /* LED control0 */ -#define RAL_MAC_CSR22 0x042c /* XXX not documented */ - -/* - * Tx/Rx Registers. - */ -#define RAL_TXRX_CSR0 0x0440 /* Security control */ -#define RAL_TXRX_CSR2 0x0444 /* Rx control */ -#define RAL_TXRX_CSR5 0x044a /* CCK Tx BBP ID0 */ -#define RAL_TXRX_CSR6 0x044c /* CCK Tx BBP ID1 */ -#define RAL_TXRX_CSR7 0x044e /* OFDM Tx BBP ID0 */ -#define RAL_TXRX_CSR8 0x0450 /* OFDM Tx BBP ID1 */ -#define RAL_TXRX_CSR10 0x0454 /* Auto responder control */ -#define RAL_TXRX_CSR11 0x0456 /* Auto responder basic rate */ -#define RAL_TXRX_CSR18 0x0464 /* Beacon interval */ -#define RAL_TXRX_CSR19 0x0466 /* Beacon/sync control */ -#define RAL_TXRX_CSR20 0x0468 /* Beacon alignment */ -#define RAL_TXRX_CSR21 0x046a /* XXX not documented */ - -/* - * Security registers. - */ -#define RAL_SEC_CSR0 0x0480 /* Shared key 0, word 0 */ - -/* - * PHY registers. - */ -#define RAL_PHY_CSR2 0x04c4 /* Tx MAC configuration */ -#define RAL_PHY_CSR4 0x04c8 /* Interface configuration */ -#define RAL_PHY_CSR5 0x04ca /* BBP Pre-Tx CCK */ -#define RAL_PHY_CSR6 0x04cc /* BBP Pre-Tx OFDM */ -#define RAL_PHY_CSR7 0x04ce /* BBP serial control */ -#define RAL_PHY_CSR8 0x04d0 /* BBP serial status */ -#define RAL_PHY_CSR9 0x04d2 /* RF serial control0 */ -#define RAL_PHY_CSR10 0x04d4 /* RF serial control1 */ - -/* - * Statistics registers. - */ -#define RAL_STA_CSR0 0x04e0 /* FCS error */ - - -#define RAL_DISABLE_RX (1 << 0) -#define RAL_DROP_CRC (1 << 1) -#define RAL_DROP_PHY (1 << 2) -#define RAL_DROP_CTL (1 << 3) -#define RAL_DROP_NOT_TO_ME (1 << 4) -#define RAL_DROP_TODS (1 << 5) -#define RAL_DROP_BAD_VERSION (1 << 6) -#define RAL_DROP_MULTICAST (1 << 9) -#define RAL_DROP_BROADCAST (1 << 10) - -#define RAL_SHORT_PREAMBLE (1 << 2) - -#define RAL_RESET_ASIC (1 << 0) -#define RAL_RESET_BBP (1 << 1) -#define RAL_HOST_READY (1 << 2) - -#define RAL_ENABLE_TSF (1 << 0) -#define RAL_ENABLE_TSF_SYNC(x) (((x) & 0x3) << 1) -#define RAL_ENABLE_TBCN (1 << 3) -#define RAL_ENABLE_BEACON_GENERATOR (1 << 4) - -#define RAL_RF_AWAKE (3 << 7) -#define RAL_BBP_AWAKE (3 << 5) - -#define RAL_BBP_WRITE (1 << 15) -#define RAL_BBP_BUSY (1 << 0) - -#define RAL_RF1_AUTOTUNE 0x08000 -#define RAL_RF3_AUTOTUNE 0x00040 - -#define RAL_RF_2522 0x00 -#define RAL_RF_2523 0x01 -#define RAL_RF_2524 0x02 -#define RAL_RF_2525 0x03 -#define RAL_RF_2525E 0x04 -#define RAL_RF_2526 0x05 -/* dual-band RF */ -#define RAL_RF_5222 0x10 - -#define RAL_BBP_VERSION 0 -#define RAL_BBP_TX 2 -#define RAL_BBP_RX 14 - -#define RAL_BBP_ANTA 0x00 -#define RAL_BBP_DIVERSITY 0x01 -#define RAL_BBP_ANTB 0x02 -#define RAL_BBP_ANTMASK 0x03 -#define RAL_BBP_FLIPIQ 0x04 - -#define RAL_JAPAN_FILTER 0x08 - -struct ural_tx_desc { - uint32_t flags; -#define RAL_TX_RETRY(x) ((x) << 4) -#define RAL_TX_MORE_FRAG (1 << 8) -#define RAL_TX_ACK (1 << 9) -#define RAL_TX_TIMESTAMP (1 << 10) -#define RAL_TX_OFDM (1 << 11) -#define RAL_TX_NEWSEQ (1 << 12) - -#define RAL_TX_IFS_MASK 0x00006000 -#define RAL_TX_IFS_BACKOFF (0 << 13) -#define RAL_TX_IFS_SIFS (1 << 13) -#define RAL_TX_IFS_NEWBACKOFF (2 << 13) -#define RAL_TX_IFS_NONE (3 << 13) - - uint16_t wme; -#define RAL_LOGCWMAX(x) (((x) & 0xf) << 12) -#define RAL_LOGCWMIN(x) (((x) & 0xf) << 8) -#define RAL_AIFSN(x) (((x) & 0x3) << 6) -#define RAL_IVOFFSET(x) (((x) & 0x3f)) - - uint16_t reserved1; - uint8_t plcp_signal; - uint8_t plcp_service; -#define RAL_PLCP_LENGEXT 0x80 - - uint8_t plcp_length_lo; - uint8_t plcp_length_hi; - uint32_t iv; - uint32_t eiv; -} __packed; - -struct ural_rx_desc { - uint32_t flags; -#define RAL_RX_CRC_ERROR (1 << 5) -#define RAL_RX_OFDM (1 << 6) -#define RAL_RX_PHY_ERROR (1 << 7) - - uint8_t rssi; - uint8_t rate; - uint16_t reserved; - - uint32_t iv; - uint32_t eiv; -} __packed; - -#define RAL_RF_LOBUSY (1 << 15) -#define RAL_RF_BUSY (1 << 31) -#define RAL_RF_20BIT (20 << 24) - -#define RAL_RF1 0 -#define RAL_RF2 2 -#define RAL_RF3 1 -#define RAL_RF4 3 - -#define RAL_EEPROM_ADDRESS 0x0004 -#define RAL_EEPROM_TXPOWER 0x003c -#define RAL_EEPROM_CONFIG0 0x0016 -#define RAL_EEPROM_BBP_BASE 0x001c diff --git a/sys/legacy/dev/usb/if_uralvar.h b/sys/legacy/dev/usb/if_uralvar.h deleted file mode 100644 index 39aef9e..0000000 --- a/sys/legacy/dev/usb/if_uralvar.h +++ /dev/null @@ -1,157 +0,0 @@ -/* $FreeBSD$ */ - -/*- - * Copyright (c) 2005 - * Damien Bergamini <damien.bergamini@free.fr> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define RAL_RX_LIST_COUNT 1 -#define RAL_TX_LIST_COUNT 8 - -#define URAL_SCAN_START 1 -#define URAL_SCAN_END 2 -#define URAL_SET_CHANNEL 3 - - -struct ural_rx_radiotap_header { - struct ieee80211_radiotap_header wr_ihdr; - uint8_t wr_flags; - uint8_t wr_rate; - uint16_t wr_chan_freq; - uint16_t wr_chan_flags; - uint8_t wr_antenna; - uint8_t wr_antsignal; -}; - -#define RAL_RX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_FLAGS) | \ - (1 << IEEE80211_RADIOTAP_RATE) | \ - (1 << IEEE80211_RADIOTAP_CHANNEL) | \ - (1 << IEEE80211_RADIOTAP_ANTENNA) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)) - -struct ural_tx_radiotap_header { - struct ieee80211_radiotap_header wt_ihdr; - uint8_t wt_flags; - uint8_t wt_rate; - uint16_t wt_chan_freq; - uint16_t wt_chan_flags; - uint8_t wt_antenna; -}; - -#define RAL_TX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_FLAGS) | \ - (1 << IEEE80211_RADIOTAP_RATE) | \ - (1 << IEEE80211_RADIOTAP_CHANNEL) | \ - (1 << IEEE80211_RADIOTAP_ANTENNA)) - -struct ural_softc; - -struct ural_tx_data { - struct ural_softc *sc; - usbd_xfer_handle xfer; - uint8_t *buf; - struct mbuf *m; - struct ieee80211_node *ni; -}; - -struct ural_rx_data { - struct ural_softc *sc; - usbd_xfer_handle xfer; - uint8_t *buf; - struct mbuf *m; -}; - -struct ural_node { - struct ieee80211_node ni; - struct ieee80211_amrr_node amn; -}; -#define URAL_NODE(ni) ((struct ural_node *)(ni)) - -struct ural_vap { - struct ieee80211vap vap; - struct ieee80211_beacon_offsets bo; - struct ieee80211_amrr amrr; - struct callout amrr_ch; - - int (*newstate)(struct ieee80211vap *, - enum ieee80211_state, int); -}; -#define URAL_VAP(vap) ((struct ural_vap *)(vap)) - -struct ural_softc { - struct ifnet *sc_ifp; - device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; - - const struct ieee80211_rate_table *sc_rates; - - int sc_rx_no; - int sc_tx_no; - - uint32_t asic_rev; - uint8_t rf_rev; - - usbd_xfer_handle amrr_xfer; - - usbd_pipe_handle sc_rx_pipeh; - usbd_pipe_handle sc_tx_pipeh; - - enum ieee80211_state sc_state; - int sc_arg; - int sc_scan_action; /* should be an enum */ - struct usb_task sc_task; - struct usb_task sc_scantask; - - struct ural_rx_data rx_data[RAL_RX_LIST_COUNT]; - struct ural_tx_data tx_data[RAL_TX_LIST_COUNT]; - int tx_queued; - int tx_cur; - - struct mtx sc_mtx; - - struct callout watchdog_ch; - int sc_tx_timer; - - uint16_t sta[11]; - uint32_t rf_regs[4]; - uint8_t txpow[14]; - - struct { - uint8_t val; - uint8_t reg; - } __packed bbp_prom[16]; - - int led_mode; - int hw_radio; - int rx_ant; - int tx_ant; - int nb_ant; - - struct ural_rx_radiotap_header sc_rxtap; - int sc_rxtap_len; - - struct ural_tx_radiotap_header sc_txtap; - int sc_txtap_len; -}; - -#if 0 -#define RAL_LOCK(sc) mtx_lock(&(sc)->sc_mtx) -#define RAL_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) -#else -#define RAL_LOCK(sc) do { ((sc) = (sc)); mtx_lock(&Giant); } while (0) -#define RAL_UNLOCK(sc) mtx_unlock(&Giant) -#endif diff --git a/sys/legacy/dev/usb/if_zyd.c b/sys/legacy/dev/usb/if_zyd.c deleted file mode 100644 index 3a4abce..0000000 --- a/sys/legacy/dev/usb/if_zyd.c +++ /dev/null @@ -1,3126 +0,0 @@ -/* $OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $ */ -/* $NetBSD: if_zyd.c,v 1.7 2007/06/21 04:04:29 kiyohara Exp $ */ -/* $FreeBSD$ */ - -/*- - * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr> - * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * ZyDAS ZD1211/ZD1211B USB WLAN driver. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/sockio.h> -#include <sys/mbuf.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/socket.h> -#include <sys/sysctl.h> -#include <sys/endian.h> -#include <sys/linker.h> - -#include <net/if.h> -#include <net/if_arp.h> -#include <net/ethernet.h> -#include <net/if_dl.h> -#include <net/if_media.h> -#include <net/if_types.h> - -#include <sys/bus.h> -#include <machine/bus.h> - -#include <net80211/ieee80211_var.h> -#include <net80211/ieee80211_amrr.h> -#include <net80211/ieee80211_phy.h> -#include <net80211/ieee80211_radiotap.h> -#include <net80211/ieee80211_regdomain.h> - -#include <net/bpf.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdivar.h> -#include "usbdevs.h" -#include <dev/usb/usb_ethersubr.h> - -#include <dev/mii/mii.h> -#include <dev/mii/miivar.h> - -#include <dev/usb/if_zydreg.h> -#include <dev/usb/if_zydfw.h> - -#ifdef ZYD_DEBUG -SYSCTL_NODE(_hw_usb, OID_AUTO, zyd, CTLFLAG_RW, 0, "ZyDAS zd1211/zd1211b"); -int zyd_debug = 0; -SYSCTL_INT(_hw_usb_zyd, OID_AUTO, debug, CTLFLAG_RW, &zyd_debug, 0, - "control debugging printfs"); -TUNABLE_INT("hw.usb.zyd.debug", &zyd_debug); -enum { - ZYD_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ - ZYD_DEBUG_RECV = 0x00000002, /* basic recv operation */ - ZYD_DEBUG_RESET = 0x00000004, /* reset processing */ - ZYD_DEBUG_INIT = 0x00000008, /* device init */ - ZYD_DEBUG_TX_PROC = 0x00000010, /* tx ISR proc */ - ZYD_DEBUG_RX_PROC = 0x00000020, /* rx ISR proc */ - ZYD_DEBUG_STATE = 0x00000040, /* 802.11 state transitions */ - ZYD_DEBUG_STAT = 0x00000080, /* statistic */ - ZYD_DEBUG_FW = 0x00000100, /* firmware */ - ZYD_DEBUG_ANY = 0xffffffff -}; -#define DPRINTF(sc, m, fmt, ...) do { \ - if (sc->sc_debug & (m)) \ - printf(fmt, __VA_ARGS__); \ -} while (0) -#else -#define DPRINTF(sc, m, fmt, ...) do { \ - (void) sc; \ -} while (0) -#endif - -static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY; -static const struct zyd_phy_pair zyd_def_phyB[] = ZYD_DEF_PHYB; - -/* various supported device vendors/products */ -#define ZYD_ZD1211_DEV(v, p) \ - { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, ZYD_ZD1211 } -#define ZYD_ZD1211B_DEV(v, p) \ - { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, ZYD_ZD1211B } -static const struct zyd_type { - struct usb_devno dev; - uint8_t rev; -#define ZYD_ZD1211 0 -#define ZYD_ZD1211B 1 -} zyd_devs[] = { - ZYD_ZD1211_DEV(3COM2, 3CRUSB10075), - ZYD_ZD1211_DEV(ABOCOM, WL54), - ZYD_ZD1211_DEV(ASUS, WL159G), - ZYD_ZD1211_DEV(CYBERTAN, TG54USB), - ZYD_ZD1211_DEV(DRAYTEK, VIGOR550), - ZYD_ZD1211_DEV(PLANEX2, GWUS54GD), - ZYD_ZD1211_DEV(PLANEX2, GWUS54GZL), - ZYD_ZD1211_DEV(PLANEX3, GWUS54GZ), - ZYD_ZD1211_DEV(PLANEX3, GWUS54MINI), - ZYD_ZD1211_DEV(SAGEM, XG760A), - ZYD_ZD1211_DEV(SENAO, NUB8301), - ZYD_ZD1211_DEV(SITECOMEU, WL113), - ZYD_ZD1211_DEV(SWEEX, ZD1211), - ZYD_ZD1211_DEV(TEKRAM, QUICKWLAN), - ZYD_ZD1211_DEV(TEKRAM, ZD1211_1), - ZYD_ZD1211_DEV(TEKRAM, ZD1211_2), - ZYD_ZD1211_DEV(TWINMOS, G240), - ZYD_ZD1211_DEV(UMEDIA, ALL0298V2), - ZYD_ZD1211_DEV(UMEDIA, TEW429UB_A), - ZYD_ZD1211_DEV(UMEDIA, TEW429UB), - ZYD_ZD1211_DEV(WISTRONNEWEB, UR055G), - ZYD_ZD1211_DEV(ZCOM, ZD1211), - ZYD_ZD1211_DEV(ZYDAS, ZD1211), - ZYD_ZD1211_DEV(ZYXEL, AG225H), - ZYD_ZD1211_DEV(ZYXEL, ZYAIRG220), - ZYD_ZD1211_DEV(ZYXEL, G200V2), - ZYD_ZD1211_DEV(ZYXEL, G202), - - ZYD_ZD1211B_DEV(ACCTON, SMCWUSBG), - ZYD_ZD1211B_DEV(ACCTON, ZD1211B), - ZYD_ZD1211B_DEV(ASUS, A9T_WIFI), - ZYD_ZD1211B_DEV(BELKIN, F5D7050_V4000), - ZYD_ZD1211B_DEV(BELKIN, ZD1211B), - ZYD_ZD1211B_DEV(CISCOLINKSYS, WUSBF54G), - ZYD_ZD1211B_DEV(FIBERLINE, WL430U), - ZYD_ZD1211B_DEV(MELCO, KG54L), - ZYD_ZD1211B_DEV(PHILIPS, SNU5600), - ZYD_ZD1211B_DEV(PLANEX2, GW_US54GXS), - ZYD_ZD1211B_DEV(SAGEM, XG76NA), - ZYD_ZD1211B_DEV(SITECOMEU, ZD1211B), - ZYD_ZD1211B_DEV(UMEDIA, TEW429UBC1), -#if 0 /* Shall we needs? */ - ZYD_ZD1211B_DEV(UNKNOWN1, ZD1211B_1), - ZYD_ZD1211B_DEV(UNKNOWN1, ZD1211B_2), - ZYD_ZD1211B_DEV(UNKNOWN2, ZD1211B), - ZYD_ZD1211B_DEV(UNKNOWN3, ZD1211B), -#endif - ZYD_ZD1211B_DEV(USR, USR5423), - ZYD_ZD1211B_DEV(VTECH, ZD1211B), - ZYD_ZD1211B_DEV(ZCOM, ZD1211B), - ZYD_ZD1211B_DEV(ZYDAS, ZD1211B), - ZYD_ZD1211B_DEV(ZYXEL, M202), - ZYD_ZD1211B_DEV(ZYXEL, G220V2), -}; -#define zyd_lookup(v, p) \ - ((const struct zyd_type *)usb_lookup(zyd_devs, v, p)) -#define zyd_read16_m(sc, val, data) do { \ - error = zyd_read16(sc, val, data); \ - if (error != 0) \ - goto fail; \ -} while (0) -#define zyd_write16_m(sc, val, data) do { \ - error = zyd_write16(sc, val, data); \ - if (error != 0) \ - goto fail; \ -} while (0) -#define zyd_read32_m(sc, val, data) do { \ - error = zyd_read32(sc, val, data); \ - if (error != 0) \ - goto fail; \ -} while (0) -#define zyd_write32_m(sc, val, data) do { \ - error = zyd_write32(sc, val, data); \ - if (error != 0) \ - goto fail; \ -} while (0) - -static device_probe_t zyd_match; -static device_attach_t zyd_attach; -static device_detach_t zyd_detach; - -static struct ieee80211vap *zyd_vap_create(struct ieee80211com *, - const char name[IFNAMSIZ], int unit, int opmode, - int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]); -static void zyd_vap_delete(struct ieee80211vap *); -static int zyd_open_pipes(struct zyd_softc *); -static void zyd_close_pipes(struct zyd_softc *); -static int zyd_alloc_tx_list(struct zyd_softc *); -static void zyd_free_tx_list(struct zyd_softc *); -static int zyd_alloc_rx_list(struct zyd_softc *); -static void zyd_free_rx_list(struct zyd_softc *); -static struct ieee80211_node *zyd_node_alloc(struct ieee80211vap *, - const uint8_t mac[IEEE80211_ADDR_LEN]); -static void zyd_task(void *); -static int zyd_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int zyd_cmd(struct zyd_softc *, uint16_t, const void *, int, - void *, int, u_int); -static int zyd_read16(struct zyd_softc *, uint16_t, uint16_t *); -static int zyd_read32(struct zyd_softc *, uint16_t, uint32_t *); -static int zyd_write16(struct zyd_softc *, uint16_t, uint16_t); -static int zyd_write32(struct zyd_softc *, uint16_t, uint32_t); -static int zyd_rfwrite(struct zyd_softc *, uint32_t); -static int zyd_lock_phy(struct zyd_softc *); -static int zyd_unlock_phy(struct zyd_softc *); -static int zyd_rf_attach(struct zyd_softc *, uint8_t); -static const char *zyd_rf_name(uint8_t); -static int zyd_hw_init(struct zyd_softc *); -static int zyd_read_pod(struct zyd_softc *); -static int zyd_read_eeprom(struct zyd_softc *); -static int zyd_get_macaddr(struct zyd_softc *); -static int zyd_set_macaddr(struct zyd_softc *, const uint8_t *); -static int zyd_set_bssid(struct zyd_softc *, const uint8_t *); -static int zyd_switch_radio(struct zyd_softc *, int); -static int zyd_set_led(struct zyd_softc *, int, int); -static void zyd_set_multi(void *); -static void zyd_update_mcast(struct ifnet *); -static int zyd_set_rxfilter(struct zyd_softc *); -static void zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *); -static int zyd_set_beacon_interval(struct zyd_softc *, int); -static void zyd_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void zyd_rx_data(struct zyd_softc *, const uint8_t *, uint16_t); -static void zyd_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void zyd_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static int zyd_tx_mgt(struct zyd_softc *, struct mbuf *, - struct ieee80211_node *); -static int zyd_tx_data(struct zyd_softc *, struct mbuf *, - struct ieee80211_node *); -static void zyd_start(struct ifnet *); -static int zyd_raw_xmit(struct ieee80211_node *, struct mbuf *, - const struct ieee80211_bpf_params *); -static void zyd_watchdog(void *); -static int zyd_ioctl(struct ifnet *, u_long, caddr_t); -static void zyd_init_locked(struct zyd_softc *); -static void zyd_init(void *); -static void zyd_stop(struct zyd_softc *, int); -static int zyd_loadfirmware(struct zyd_softc *); -static void zyd_newassoc(struct ieee80211_node *, int); -static void zyd_scantask(void *); -static void zyd_scan_start(struct ieee80211com *); -static void zyd_scan_end(struct ieee80211com *); -static void zyd_set_channel(struct ieee80211com *); -static void zyd_wakeup(struct zyd_softc *); -static int zyd_rfmd_init(struct zyd_rf *); -static int zyd_rfmd_switch_radio(struct zyd_rf *, int); -static int zyd_rfmd_set_channel(struct zyd_rf *, uint8_t); -static int zyd_al2230_init(struct zyd_rf *); -static int zyd_al2230_switch_radio(struct zyd_rf *, int); -static int zyd_al2230_set_channel(struct zyd_rf *, uint8_t); -static int zyd_al2230_set_channel_b(struct zyd_rf *, uint8_t); -static int zyd_al2230_init_b(struct zyd_rf *); -static int zyd_al7230B_init(struct zyd_rf *); -static int zyd_al7230B_switch_radio(struct zyd_rf *, int); -static int zyd_al7230B_set_channel(struct zyd_rf *, uint8_t); -static int zyd_al2210_init(struct zyd_rf *); -static int zyd_al2210_switch_radio(struct zyd_rf *, int); -static int zyd_al2210_set_channel(struct zyd_rf *, uint8_t); -static int zyd_gct_init(struct zyd_rf *); -static int zyd_gct_switch_radio(struct zyd_rf *, int); -static int zyd_gct_set_channel(struct zyd_rf *, uint8_t); -static int zyd_maxim_init(struct zyd_rf *); -static int zyd_maxim_switch_radio(struct zyd_rf *, int); -static int zyd_maxim_set_channel(struct zyd_rf *, uint8_t); -static int zyd_maxim2_init(struct zyd_rf *); -static int zyd_maxim2_switch_radio(struct zyd_rf *, int); -static int zyd_maxim2_set_channel(struct zyd_rf *, uint8_t); - -static int -zyd_match(device_t dev) -{ - struct usb_attach_arg *uaa = device_get_ivars(dev); - - if (!uaa->iface) - return (UMATCH_NONE); - - return (zyd_lookup(uaa->vendor, uaa->product) != NULL) ? - (UMATCH_VENDOR_PRODUCT) : (UMATCH_NONE); -} - -static int -zyd_attach(device_t dev) -{ - int error = ENXIO; - struct ieee80211com *ic; - struct ifnet *ifp; - struct usb_attach_arg *uaa = device_get_ivars(dev); - struct zyd_softc *sc = device_get_softc(dev); - usb_device_descriptor_t* ddesc; - uint8_t bands; - - sc->sc_dev = dev; - sc->sc_udev = uaa->device; - sc->sc_macrev = zyd_lookup(uaa->vendor, uaa->product)->rev; -#ifdef ZYD_DEBUG - sc->sc_debug = zyd_debug; -#endif - - ddesc = usbd_get_device_descriptor(sc->sc_udev); - if (UGETW(ddesc->bcdDevice) < 0x4330) { - device_printf(dev, "device version mismatch: 0x%x " - "(only >= 43.30 supported)\n", - UGETW(ddesc->bcdDevice)); - return (ENXIO); - } - - if ((error = zyd_get_macaddr(sc)) != 0) { - device_printf(sc->sc_dev, "could not read EEPROM\n"); - return (ENXIO); - } - - mtx_init(&sc->sc_txmtx, device_get_nameunit(sc->sc_dev), - MTX_NETWORK_LOCK, MTX_DEF); - usb_init_task(&sc->sc_mcasttask, zyd_set_multi, sc); - usb_init_task(&sc->sc_scantask, zyd_scantask, sc); - usb_init_task(&sc->sc_task, zyd_task, sc); - callout_init(&sc->sc_watchdog_ch, 0); - STAILQ_INIT(&sc->sc_rqh); - - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); - error = ENXIO; - goto fail0; - } - ifp->if_softc = sc; - if_initname(ifp, "zyd", device_get_unit(sc->sc_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSGIANT; /* USB stack is still under Giant lock */ - ifp->if_init = zyd_init; - ifp->if_ioctl = zyd_ioctl; - ifp->if_start = zyd_start; - IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); - IFQ_SET_READY(&ifp->if_snd); - - ic = ifp->if_l2com; - ic->ic_ifp = ifp; - ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ - ic->ic_opmode = IEEE80211_M_STA; - IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid); - - /* set device capabilities */ - ic->ic_caps = - IEEE80211_C_STA /* station mode */ - | IEEE80211_C_MONITOR /* monitor mode */ - | IEEE80211_C_SHPREAMBLE /* short preamble supported */ - | IEEE80211_C_SHSLOT /* short slot time supported */ - | IEEE80211_C_BGSCAN /* capable of bg scanning */ - | IEEE80211_C_WPA /* 802.11i */ - ; - - bands = 0; - setbit(&bands, IEEE80211_MODE_11B); - setbit(&bands, IEEE80211_MODE_11G); - ieee80211_init_channels(ic, NULL, &bands); - - ieee80211_ifattach(ic); - ic->ic_newassoc = zyd_newassoc; - ic->ic_raw_xmit = zyd_raw_xmit; - ic->ic_node_alloc = zyd_node_alloc; - ic->ic_scan_start = zyd_scan_start; - ic->ic_scan_end = zyd_scan_end; - ic->ic_set_channel = zyd_set_channel; - - ic->ic_vap_create = zyd_vap_create; - ic->ic_vap_delete = zyd_vap_delete; - ic->ic_update_mcast = zyd_update_mcast; - - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap)); - sc->sc_rxtap_len = sizeof(sc->sc_rxtap); - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(ZYD_RX_RADIOTAP_PRESENT); - sc->sc_txtap_len = sizeof(sc->sc_txtap); - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(ZYD_TX_RADIOTAP_PRESENT); - - if (bootverbose) - ieee80211_announce(ic); - - usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); - - return (0); - -fail0: mtx_destroy(&sc->sc_txmtx); - return (error); -} - -static int -zyd_detach(device_t dev) -{ - struct zyd_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - if (!device_is_attached(dev)) - return (0); - - /* set a flag to indicate we're detaching. */ - sc->sc_flags |= ZYD_FLAG_DETACHING; - - zyd_stop(sc, 1); - bpfdetach(ifp); - ieee80211_ifdetach(ic); - - zyd_wakeup(sc); - zyd_close_pipes(sc); - - if_free(ifp); - mtx_destroy(&sc->sc_txmtx); - - usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - - return (0); -} - -static struct ieee80211vap * -zyd_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]) -{ - struct zyd_vap *zvp; - struct ieee80211vap *vap; - - if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ - return (NULL); - zvp = (struct zyd_vap *) malloc(sizeof(struct zyd_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (zvp == NULL) - return (NULL); - vap = &zvp->vap; - /* enable s/w bmiss handling for sta mode */ - ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); - - /* override state transition machine */ - zvp->newstate = vap->iv_newstate; - vap->iv_newstate = zyd_newstate; - - ieee80211_amrr_init(&zvp->amrr, vap, - IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, - IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, - 1000 /* 1 sec */); - - /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status); - ic->ic_opmode = opmode; - return (vap); -} - -static void -zyd_vap_delete(struct ieee80211vap *vap) -{ - struct zyd_vap *zvp = ZYD_VAP(vap); - - ieee80211_amrr_cleanup(&zvp->amrr); - ieee80211_vap_detach(vap); - free(zvp, M_80211_VAP); -} - -static int -zyd_open_pipes(struct zyd_softc *sc) -{ - usb_endpoint_descriptor_t *edesc; - int isize; - usbd_status error; - - /* interrupt in */ - edesc = usbd_get_endpoint_descriptor(sc->sc_iface, 0x83); - if (edesc == NULL) - return (EINVAL); - - isize = UGETW(edesc->wMaxPacketSize); - if (isize == 0) /* should not happen */ - return (EINVAL); - - sc->sc_ibuf = malloc(isize, M_USBDEV, M_NOWAIT); - if (sc->sc_ibuf == NULL) - return (ENOMEM); - - error = usbd_open_pipe_intr(sc->sc_iface, 0x83, USBD_SHORT_XFER_OK, - &sc->sc_ep[ZYD_ENDPT_IIN], sc, sc->sc_ibuf, isize, zyd_intr, - USBD_DEFAULT_INTERVAL); - if (error != 0) { - device_printf(sc->sc_dev, "open rx intr pipe failed: %s\n", - usbd_errstr(error)); - goto fail; - } - - /* interrupt out (not necessarily an interrupt pipe) */ - error = usbd_open_pipe(sc->sc_iface, 0x04, USBD_EXCLUSIVE_USE, - &sc->sc_ep[ZYD_ENDPT_IOUT]); - if (error != 0) { - device_printf(sc->sc_dev, "open tx intr pipe failed: %s\n", - usbd_errstr(error)); - goto fail; - } - - /* bulk in */ - error = usbd_open_pipe(sc->sc_iface, 0x82, USBD_EXCLUSIVE_USE, - &sc->sc_ep[ZYD_ENDPT_BIN]); - if (error != 0) { - device_printf(sc->sc_dev, "open rx pipe failed: %s\n", - usbd_errstr(error)); - goto fail; - } - - /* bulk out */ - error = usbd_open_pipe(sc->sc_iface, 0x01, USBD_EXCLUSIVE_USE, - &sc->sc_ep[ZYD_ENDPT_BOUT]); - if (error != 0) { - device_printf(sc->sc_dev, "open tx pipe failed: %s\n", - usbd_errstr(error)); - goto fail; - } - - return (0); - -fail: zyd_close_pipes(sc); - return (ENXIO); -} - -static void -zyd_close_pipes(struct zyd_softc *sc) -{ - int i; - - for (i = 0; i < ZYD_ENDPT_CNT; i++) { - if (sc->sc_ep[i] != NULL) { - usbd_abort_pipe(sc->sc_ep[i]); - usbd_close_pipe(sc->sc_ep[i]); - sc->sc_ep[i] = NULL; - } - } - if (sc->sc_ibuf != NULL) { - free(sc->sc_ibuf, M_USBDEV); - sc->sc_ibuf = NULL; - } -} - -static int -zyd_alloc_tx_list(struct zyd_softc *sc) -{ - int i, error; - - sc->sc_txqueued = 0; - - for (i = 0; i < ZYD_TX_LIST_CNT; i++) { - struct zyd_tx_data *data = &sc->sc_txdata[i]; - - data->sc = sc; /* backpointer for callbacks */ - - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { - device_printf(sc->sc_dev, - "could not allocate tx xfer\n"); - error = ENOMEM; - goto fail; - } - data->buf = usbd_alloc_buffer(data->xfer, ZYD_MAX_TXBUFSZ); - if (data->buf == NULL) { - device_printf(sc->sc_dev, - "could not allocate tx buffer\n"); - error = ENOMEM; - goto fail; - } - - /* clear Tx descriptor */ - bzero(data->buf, sizeof(struct zyd_tx_desc)); - } - return (0); - -fail: zyd_free_tx_list(sc); - return (error); -} - -static void -zyd_free_tx_list(struct zyd_softc *sc) -{ - int i; - - for (i = 0; i < ZYD_TX_LIST_CNT; i++) { - struct zyd_tx_data *data = &sc->sc_txdata[i]; - - if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); - data->xfer = NULL; - } - if (data->ni != NULL) { - ieee80211_free_node(data->ni); - data->ni = NULL; - } - } -} - -static int -zyd_alloc_rx_list(struct zyd_softc *sc) -{ - int i, error; - - for (i = 0; i < ZYD_RX_LIST_CNT; i++) { - struct zyd_rx_data *data = &sc->sc_rxdata[i]; - - data->sc = sc; /* backpointer for callbacks */ - - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { - device_printf(sc->sc_dev, - "could not allocate rx xfer\n"); - error = ENOMEM; - goto fail; - } - data->buf = usbd_alloc_buffer(data->xfer, ZYX_MAX_RXBUFSZ); - if (data->buf == NULL) { - device_printf(sc->sc_dev, - "could not allocate rx buffer\n"); - error = ENOMEM; - goto fail; - } - } - return (0); - -fail: zyd_free_rx_list(sc); - return (error); -} - -static void -zyd_free_rx_list(struct zyd_softc *sc) -{ - int i; - - for (i = 0; i < ZYD_RX_LIST_CNT; i++) { - struct zyd_rx_data *data = &sc->sc_rxdata[i]; - - if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); - data->xfer = NULL; - } - } -} - -/* ARGUSED */ -static struct ieee80211_node * -zyd_node_alloc(struct ieee80211vap *vap __unused, - const uint8_t mac[IEEE80211_ADDR_LEN] __unused) -{ - struct zyd_node *zn; - - zn = malloc(sizeof(struct zyd_node), M_80211_NODE, M_NOWAIT | M_ZERO); - return (zn != NULL) ? (&zn->ni) : (NULL); -} - -static void -zyd_task(void *arg) -{ - int error; - struct zyd_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct ieee80211_node *ni = vap->iv_bss; - struct zyd_vap *zvp = ZYD_VAP(vap); - - switch (sc->sc_state) { - case IEEE80211_S_AUTH: - zyd_set_chan(sc, ic->ic_curchan); - break; - case IEEE80211_S_RUN: - if (vap->iv_opmode == IEEE80211_M_MONITOR) - break; - - /* turn link LED on */ - error = zyd_set_led(sc, ZYD_LED1, 1); - if (error != 0) - goto fail; - - /* make data LED blink upon Tx */ - zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1); - - IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); - zyd_set_bssid(sc, sc->sc_bssid); - break; - default: - break; - } - -fail: - IEEE80211_LOCK(ic); - zvp->newstate(vap, sc->sc_state, sc->sc_arg); - if (vap->iv_newstate_cb != NULL) - vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); - IEEE80211_UNLOCK(ic); -} - -static int -zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct zyd_vap *zvp = ZYD_VAP(vap); - struct ieee80211com *ic = vap->iv_ic; - struct zyd_softc *sc = ic->ic_ifp->if_softc; - - DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__, - ieee80211_state_name[vap->iv_state], - ieee80211_state_name[nstate]); - - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - usb_rem_task(sc->sc_udev, &sc->sc_task); - callout_stop(&sc->sc_watchdog_ch); - - /* do it in a process context */ - sc->sc_state = nstate; - sc->sc_arg = arg; - - if (nstate == IEEE80211_S_INIT) { - zvp->newstate(vap, nstate, arg); - return (0); - } else { - usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); - return (EINPROGRESS); - } -} - -static int -zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen, - void *odata, int olen, u_int flags) -{ - usbd_xfer_handle xfer; - struct zyd_cmd cmd; - struct zyd_rq rq; - uint16_t xferflags; - usbd_status error; - - if (sc->sc_flags & ZYD_FLAG_DETACHING) - return (ENXIO); - - if ((xfer = usbd_alloc_xfer(sc->sc_udev)) == NULL) - return (ENOMEM); - - cmd.code = htole16(code); - bcopy(idata, cmd.data, ilen); - - xferflags = USBD_FORCE_SHORT_XFER; - if (!(flags & ZYD_CMD_FLAG_READ)) - xferflags |= USBD_SYNCHRONOUS; - else { - rq.idata = idata; - rq.odata = odata; - rq.len = olen / sizeof(struct zyd_pair); - STAILQ_INSERT_TAIL(&sc->sc_rqh, &rq, rq); - } - - usbd_setup_xfer(xfer, sc->sc_ep[ZYD_ENDPT_IOUT], 0, &cmd, - sizeof(uint16_t) + ilen, xferflags, ZYD_INTR_TIMEOUT, NULL); - error = usbd_transfer(xfer); - if (error != USBD_IN_PROGRESS && error != 0) { - device_printf(sc->sc_dev, "could not send command (error=%s)\n", - usbd_errstr(error)); - (void)usbd_free_xfer(xfer); - return (EIO); - } - if (!(flags & ZYD_CMD_FLAG_READ)) { - (void)usbd_free_xfer(xfer); - return (0); /* write: don't wait for reply */ - } - /* wait at most one second for command reply */ - error = tsleep(odata, PCATCH, "zydcmd", hz); - if (error == EWOULDBLOCK) - device_printf(sc->sc_dev, "zyd_read sleep timeout\n"); - STAILQ_REMOVE(&sc->sc_rqh, &rq, zyd_rq, rq); - - (void)usbd_free_xfer(xfer); - return (error); -} - -static int -zyd_read16(struct zyd_softc *sc, uint16_t reg, uint16_t *val) -{ - struct zyd_pair tmp; - int error; - - reg = htole16(reg); - error = zyd_cmd(sc, ZYD_CMD_IORD, ®, sizeof(reg), &tmp, sizeof(tmp), - ZYD_CMD_FLAG_READ); - if (error == 0) - *val = le16toh(tmp.val); - return (error); -} - -static int -zyd_read32(struct zyd_softc *sc, uint16_t reg, uint32_t *val) -{ - struct zyd_pair tmp[2]; - uint16_t regs[2]; - int error; - - regs[0] = htole16(ZYD_REG32_HI(reg)); - regs[1] = htole16(ZYD_REG32_LO(reg)); - error = zyd_cmd(sc, ZYD_CMD_IORD, regs, sizeof(regs), tmp, sizeof(tmp), - ZYD_CMD_FLAG_READ); - if (error == 0) - *val = le16toh(tmp[0].val) << 16 | le16toh(tmp[1].val); - return (error); -} - -static int -zyd_write16(struct zyd_softc *sc, uint16_t reg, uint16_t val) -{ - struct zyd_pair pair; - - pair.reg = htole16(reg); - pair.val = htole16(val); - - return zyd_cmd(sc, ZYD_CMD_IOWR, &pair, sizeof(pair), NULL, 0, 0); -} - -static int -zyd_write32(struct zyd_softc *sc, uint16_t reg, uint32_t val) -{ - struct zyd_pair pair[2]; - - pair[0].reg = htole16(ZYD_REG32_HI(reg)); - pair[0].val = htole16(val >> 16); - pair[1].reg = htole16(ZYD_REG32_LO(reg)); - pair[1].val = htole16(val & 0xffff); - - return zyd_cmd(sc, ZYD_CMD_IOWR, pair, sizeof(pair), NULL, 0, 0); -} - -static int -zyd_rfwrite(struct zyd_softc *sc, uint32_t val) -{ - struct zyd_rf *rf = &sc->sc_rf; - struct zyd_rfwrite_cmd req; - uint16_t cr203; - int error, i; - - zyd_read16_m(sc, ZYD_CR203, &cr203); - cr203 &= ~(ZYD_RF_IF_LE | ZYD_RF_CLK | ZYD_RF_DATA); - - req.code = htole16(2); - req.width = htole16(rf->width); - for (i = 0; i < rf->width; i++) { - req.bit[i] = htole16(cr203); - if (val & (1 << (rf->width - 1 - i))) - req.bit[i] |= htole16(ZYD_RF_DATA); - } - error = zyd_cmd(sc, ZYD_CMD_RFCFG, &req, 4 + 2 * rf->width, NULL, 0, 0); -fail: - return (error); -} - -static int -zyd_rfwrite_cr(struct zyd_softc *sc, uint32_t val) -{ - int error; - - zyd_write16_m(sc, ZYD_CR244, (val >> 16) & 0xff); - zyd_write16_m(sc, ZYD_CR243, (val >> 8) & 0xff); - zyd_write16_m(sc, ZYD_CR242, (val >> 0) & 0xff); -fail: - return (error); -} - -static int -zyd_lock_phy(struct zyd_softc *sc) -{ - int error; - uint32_t tmp; - - zyd_read32_m(sc, ZYD_MAC_MISC, &tmp); - tmp &= ~ZYD_UNLOCK_PHY_REGS; - zyd_write32_m(sc, ZYD_MAC_MISC, tmp); -fail: - return (error); -} - -static int -zyd_unlock_phy(struct zyd_softc *sc) -{ - int error; - uint32_t tmp; - - zyd_read32_m(sc, ZYD_MAC_MISC, &tmp); - tmp |= ZYD_UNLOCK_PHY_REGS; - zyd_write32_m(sc, ZYD_MAC_MISC, tmp); -fail: - return (error); -} - -/* - * RFMD RF methods. - */ -static int -zyd_rfmd_init(struct zyd_rf *rf) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - struct zyd_softc *sc = rf->rf_sc; - static const struct zyd_phy_pair phyini[] = ZYD_RFMD_PHY; - static const uint32_t rfini[] = ZYD_RFMD_RF; - int i, error; - - /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) { - zyd_write16_m(sc, phyini[i].reg, phyini[i].val); - } - - /* init RFMD radio */ - for (i = 0; i < N(rfini); i++) { - if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return (error); - } -fail: - return (error); -#undef N -} - -static int -zyd_rfmd_switch_radio(struct zyd_rf *rf, int on) -{ - int error; - struct zyd_softc *sc = rf->rf_sc; - - zyd_write16_m(sc, ZYD_CR10, on ? 0x89 : 0x15); - zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x81); -fail: - return (error); -} - -static int -zyd_rfmd_set_channel(struct zyd_rf *rf, uint8_t chan) -{ - int error; - struct zyd_softc *sc = rf->rf_sc; - static const struct { - uint32_t r1, r2; - } rfprog[] = ZYD_RFMD_CHANTABLE; - - error = zyd_rfwrite(sc, rfprog[chan - 1].r1); - if (error != 0) - goto fail; - error = zyd_rfwrite(sc, rfprog[chan - 1].r2); - if (error != 0) - goto fail; - -fail: - return (error); -} - -/* - * AL2230 RF methods. - */ -static int -zyd_al2230_init(struct zyd_rf *rf) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - struct zyd_softc *sc = rf->rf_sc; - static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY; - static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT; - static const struct zyd_phy_pair phypll[] = { - { ZYD_CR251, 0x2f }, { ZYD_CR251, 0x3f }, - { ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 } - }; - static const uint32_t rfini1[] = ZYD_AL2230_RF_PART1; - static const uint32_t rfini2[] = ZYD_AL2230_RF_PART2; - static const uint32_t rfini3[] = ZYD_AL2230_RF_PART3; - int i, error; - - /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) - zyd_write16_m(sc, phyini[i].reg, phyini[i].val); - - if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) { - for (i = 0; i < N(phy2230s); i++) - zyd_write16_m(sc, phy2230s[i].reg, phy2230s[i].val); - } - - /* init AL2230 radio */ - for (i = 0; i < N(rfini1); i++) { - error = zyd_rfwrite(sc, rfini1[i]); - if (error != 0) - goto fail; - } - - if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) - error = zyd_rfwrite(sc, 0x000824); - else - error = zyd_rfwrite(sc, 0x0005a4); - if (error != 0) - goto fail; - - for (i = 0; i < N(rfini2); i++) { - error = zyd_rfwrite(sc, rfini2[i]); - if (error != 0) - goto fail; - } - - for (i = 0; i < N(phypll); i++) - zyd_write16_m(sc, phypll[i].reg, phypll[i].val); - - for (i = 0; i < N(rfini3); i++) { - error = zyd_rfwrite(sc, rfini3[i]); - if (error != 0) - goto fail; - } -fail: - return (error); -#undef N -} - -static int -zyd_al2230_fini(struct zyd_rf *rf) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - int error, i; - struct zyd_softc *sc = rf->rf_sc; - static const struct zyd_phy_pair phy[] = ZYD_AL2230_PHY_FINI_PART1; - - for (i = 0; i < N(phy); i++) - zyd_write16_m(sc, phy[i].reg, phy[i].val); - - if (sc->sc_newphy != 0) - zyd_write16_m(sc, ZYD_CR9, 0xe1); - - zyd_write16_m(sc, ZYD_CR203, 0x6); -fail: - return (error); -#undef N -} - -static int -zyd_al2230_init_b(struct zyd_rf *rf) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - struct zyd_softc *sc = rf->rf_sc; - static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1; - static const struct zyd_phy_pair phy2[] = ZYD_AL2230_PHY_PART2; - static const struct zyd_phy_pair phy3[] = ZYD_AL2230_PHY_PART3; - static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT; - static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY_B; - static const uint32_t rfini_part1[] = ZYD_AL2230_RF_B_PART1; - static const uint32_t rfini_part2[] = ZYD_AL2230_RF_B_PART2; - static const uint32_t rfini_part3[] = ZYD_AL2230_RF_B_PART3; - static const uint32_t zyd_al2230_chtable[][3] = ZYD_AL2230_CHANTABLE; - int i, error; - - for (i = 0; i < N(phy1); i++) - zyd_write16_m(sc, phy1[i].reg, phy1[i].val); - - /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) - zyd_write16_m(sc, phyini[i].reg, phyini[i].val); - - if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) { - for (i = 0; i < N(phy2230s); i++) - zyd_write16_m(sc, phy2230s[i].reg, phy2230s[i].val); - } - - for (i = 0; i < 3; i++) { - error = zyd_rfwrite_cr(sc, zyd_al2230_chtable[0][i]); - if (error != 0) - return (error); - } - - for (i = 0; i < N(rfini_part1); i++) { - error = zyd_rfwrite_cr(sc, rfini_part1[i]); - if (error != 0) - return (error); - } - - if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) - error = zyd_rfwrite(sc, 0x241000); - else - error = zyd_rfwrite(sc, 0x25a000); - if (error != 0) - goto fail; - - for (i = 0; i < N(rfini_part2); i++) { - error = zyd_rfwrite_cr(sc, rfini_part2[i]); - if (error != 0) - return (error); - } - - for (i = 0; i < N(phy2); i++) - zyd_write16_m(sc, phy2[i].reg, phy2[i].val); - - for (i = 0; i < N(rfini_part3); i++) { - error = zyd_rfwrite_cr(sc, rfini_part3[i]); - if (error != 0) - return (error); - } - - for (i = 0; i < N(phy3); i++) - zyd_write16_m(sc, phy3[i].reg, phy3[i].val); - - error = zyd_al2230_fini(rf); -fail: - return (error); -#undef N -} - -static int -zyd_al2230_switch_radio(struct zyd_rf *rf, int on) -{ - struct zyd_softc *sc = rf->rf_sc; - int error, on251 = (sc->sc_macrev == ZYD_ZD1211) ? 0x3f : 0x7f; - - zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x04); - zyd_write16_m(sc, ZYD_CR251, on ? on251 : 0x2f); -fail: - return (error); -} - -static int -zyd_al2230_set_channel(struct zyd_rf *rf, uint8_t chan) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - int error, i; - struct zyd_softc *sc = rf->rf_sc; - static const struct zyd_phy_pair phy1[] = { - { ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 }, - }; - static const struct { - uint32_t r1, r2, r3; - } rfprog[] = ZYD_AL2230_CHANTABLE; - - error = zyd_rfwrite(sc, rfprog[chan - 1].r1); - if (error != 0) - goto fail; - error = zyd_rfwrite(sc, rfprog[chan - 1].r2); - if (error != 0) - goto fail; - error = zyd_rfwrite(sc, rfprog[chan - 1].r3); - if (error != 0) - goto fail; - - for (i = 0; i < N(phy1); i++) - zyd_write16_m(sc, phy1[i].reg, phy1[i].val); -fail: - return (error); -#undef N -} - -static int -zyd_al2230_set_channel_b(struct zyd_rf *rf, uint8_t chan) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - int error, i; - struct zyd_softc *sc = rf->rf_sc; - static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1; - static const struct { - uint32_t r1, r2, r3; - } rfprog[] = ZYD_AL2230_CHANTABLE_B; - - for (i = 0; i < N(phy1); i++) - zyd_write16_m(sc, phy1[i].reg, phy1[i].val); - - error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r1); - if (error != 0) - goto fail; - error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r2); - if (error != 0) - goto fail; - error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r3); - if (error != 0) - goto fail; - error = zyd_al2230_fini(rf); -fail: - return (error); -#undef N -} - -#define ZYD_AL2230_PHY_BANDEDGE6 \ -{ \ - { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \ - { ZYD_CR47, 0x1e } \ -} - -static int -zyd_al2230_bandedge6(struct zyd_rf *rf, struct ieee80211_channel *c) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - int error = 0, i; - struct zyd_softc *sc = rf->rf_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct zyd_phy_pair r[] = ZYD_AL2230_PHY_BANDEDGE6; - u_int chan = ieee80211_chan2ieee(ic, c); - - if (chan == 1 || chan == 11) - r[0].val = 0x12; - - for (i = 0; i < N(r); i++) - zyd_write16_m(sc, r[i].reg, r[i].val); -fail: - return (error); -#undef N -} - -/* - * AL7230B RF methods. - */ -static int -zyd_al7230B_init(struct zyd_rf *rf) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - struct zyd_softc *sc = rf->rf_sc; - static const struct zyd_phy_pair phyini_1[] = ZYD_AL7230B_PHY_1; - static const struct zyd_phy_pair phyini_2[] = ZYD_AL7230B_PHY_2; - static const struct zyd_phy_pair phyini_3[] = ZYD_AL7230B_PHY_3; - static const uint32_t rfini_1[] = ZYD_AL7230B_RF_1; - static const uint32_t rfini_2[] = ZYD_AL7230B_RF_2; - int i, error; - - /* for AL7230B, PHY and RF need to be initialized in "phases" */ - - /* init RF-dependent PHY registers, part one */ - for (i = 0; i < N(phyini_1); i++) - zyd_write16_m(sc, phyini_1[i].reg, phyini_1[i].val); - - /* init AL7230B radio, part one */ - for (i = 0; i < N(rfini_1); i++) { - if ((error = zyd_rfwrite(sc, rfini_1[i])) != 0) - return (error); - } - /* init RF-dependent PHY registers, part two */ - for (i = 0; i < N(phyini_2); i++) - zyd_write16_m(sc, phyini_2[i].reg, phyini_2[i].val); - - /* init AL7230B radio, part two */ - for (i = 0; i < N(rfini_2); i++) { - if ((error = zyd_rfwrite(sc, rfini_2[i])) != 0) - return (error); - } - /* init RF-dependent PHY registers, part three */ - for (i = 0; i < N(phyini_3); i++) - zyd_write16_m(sc, phyini_3[i].reg, phyini_3[i].val); -fail: - return (error); -#undef N -} - -static int -zyd_al7230B_switch_radio(struct zyd_rf *rf, int on) -{ - int error; - struct zyd_softc *sc = rf->rf_sc; - - zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x04); - zyd_write16_m(sc, ZYD_CR251, on ? 0x3f : 0x2f); -fail: - return (error); -} - -static int -zyd_al7230B_set_channel(struct zyd_rf *rf, uint8_t chan) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - struct zyd_softc *sc = rf->rf_sc; - static const struct { - uint32_t r1, r2; - } rfprog[] = ZYD_AL7230B_CHANTABLE; - static const uint32_t rfsc[] = ZYD_AL7230B_RF_SETCHANNEL; - int i, error; - - zyd_write16_m(sc, ZYD_CR240, 0x57); - zyd_write16_m(sc, ZYD_CR251, 0x2f); - - for (i = 0; i < N(rfsc); i++) { - if ((error = zyd_rfwrite(sc, rfsc[i])) != 0) - return (error); - } - - zyd_write16_m(sc, ZYD_CR128, 0x14); - zyd_write16_m(sc, ZYD_CR129, 0x12); - zyd_write16_m(sc, ZYD_CR130, 0x10); - zyd_write16_m(sc, ZYD_CR38, 0x38); - zyd_write16_m(sc, ZYD_CR136, 0xdf); - - error = zyd_rfwrite(sc, rfprog[chan - 1].r1); - if (error != 0) - goto fail; - error = zyd_rfwrite(sc, rfprog[chan - 1].r2); - if (error != 0) - goto fail; - error = zyd_rfwrite(sc, 0x3c9000); - if (error != 0) - goto fail; - - zyd_write16_m(sc, ZYD_CR251, 0x3f); - zyd_write16_m(sc, ZYD_CR203, 0x06); - zyd_write16_m(sc, ZYD_CR240, 0x08); -fail: - return (error); -#undef N -} - -/* - * AL2210 RF methods. - */ -static int -zyd_al2210_init(struct zyd_rf *rf) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - struct zyd_softc *sc = rf->rf_sc; - static const struct zyd_phy_pair phyini[] = ZYD_AL2210_PHY; - static const uint32_t rfini[] = ZYD_AL2210_RF; - uint32_t tmp; - int i, error; - - zyd_write32_m(sc, ZYD_CR18, 2); - - /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) - zyd_write16_m(sc, phyini[i].reg, phyini[i].val); - - /* init AL2210 radio */ - for (i = 0; i < N(rfini); i++) { - if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return (error); - } - zyd_write16_m(sc, ZYD_CR47, 0x1e); - zyd_read32_m(sc, ZYD_CR_RADIO_PD, &tmp); - zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp & ~1); - zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp | 1); - zyd_write32_m(sc, ZYD_CR_RFCFG, 0x05); - zyd_write32_m(sc, ZYD_CR_RFCFG, 0x00); - zyd_write16_m(sc, ZYD_CR47, 0x1e); - zyd_write32_m(sc, ZYD_CR18, 3); -fail: - return (error); -#undef N -} - -static int -zyd_al2210_switch_radio(struct zyd_rf *rf, int on) -{ - /* vendor driver does nothing for this RF chip */ - - return (0); -} - -static int -zyd_al2210_set_channel(struct zyd_rf *rf, uint8_t chan) -{ - int error; - struct zyd_softc *sc = rf->rf_sc; - static const uint32_t rfprog[] = ZYD_AL2210_CHANTABLE; - uint32_t tmp; - - zyd_write32_m(sc, ZYD_CR18, 2); - zyd_write16_m(sc, ZYD_CR47, 0x1e); - zyd_read32_m(sc, ZYD_CR_RADIO_PD, &tmp); - zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp & ~1); - zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp | 1); - zyd_write32_m(sc, ZYD_CR_RFCFG, 0x05); - zyd_write32_m(sc, ZYD_CR_RFCFG, 0x00); - zyd_write16_m(sc, ZYD_CR47, 0x1e); - - /* actually set the channel */ - error = zyd_rfwrite(sc, rfprog[chan - 1]); - if (error != 0) - goto fail; - - zyd_write32_m(sc, ZYD_CR18, 3); -fail: - return (error); -} - -/* - * GCT RF methods. - */ -static int -zyd_gct_init(struct zyd_rf *rf) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - struct zyd_softc *sc = rf->rf_sc; - static const struct zyd_phy_pair phyini[] = ZYD_GCT_PHY; - static const uint32_t rfini[] = ZYD_GCT_RF; - int i, error; - - /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) - zyd_write16_m(sc, phyini[i].reg, phyini[i].val); - - /* init cgt radio */ - for (i = 0; i < N(rfini); i++) { - if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return (error); - } -fail: - return (error); -#undef N -} - -static int -zyd_gct_switch_radio(struct zyd_rf *rf, int on) -{ - /* vendor driver does nothing for this RF chip */ - - return (0); -} - -static int -zyd_gct_set_channel(struct zyd_rf *rf, uint8_t chan) -{ - int error; - struct zyd_softc *sc = rf->rf_sc; - static const uint32_t rfprog[] = ZYD_GCT_CHANTABLE; - - error = zyd_rfwrite(sc, 0x1c0000); - if (error != 0) - goto fail; - error = zyd_rfwrite(sc, rfprog[chan - 1]); - if (error != 0) - goto fail; - error = zyd_rfwrite(sc, 0x1c0008); -fail: - return (error); -} - -/* - * Maxim RF methods. - */ -static int -zyd_maxim_init(struct zyd_rf *rf) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - struct zyd_softc *sc = rf->rf_sc; - static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY; - static const uint32_t rfini[] = ZYD_MAXIM_RF; - uint16_t tmp; - int i, error; - - /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) - zyd_write16_m(sc, phyini[i].reg, phyini[i].val); - - zyd_read16_m(sc, ZYD_CR203, &tmp); - zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4)); - - /* init maxim radio */ - for (i = 0; i < N(rfini); i++) { - if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return (error); - } - zyd_read16_m(sc, ZYD_CR203, &tmp); - zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4)); -fail: - return (error); -#undef N -} - -static int -zyd_maxim_switch_radio(struct zyd_rf *rf, int on) -{ - - /* vendor driver does nothing for this RF chip */ - return (0); -} - -static int -zyd_maxim_set_channel(struct zyd_rf *rf, uint8_t chan) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - struct zyd_softc *sc = rf->rf_sc; - static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY; - static const uint32_t rfini[] = ZYD_MAXIM_RF; - static const struct { - uint32_t r1, r2; - } rfprog[] = ZYD_MAXIM_CHANTABLE; - uint16_t tmp; - int i, error; - - /* - * Do the same as we do when initializing it, except for the channel - * values coming from the two channel tables. - */ - - /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) - zyd_write16_m(sc, phyini[i].reg, phyini[i].val); - - zyd_read16_m(sc, ZYD_CR203, &tmp); - zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4)); - - /* first two values taken from the chantables */ - error = zyd_rfwrite(sc, rfprog[chan - 1].r1); - if (error != 0) - goto fail; - error = zyd_rfwrite(sc, rfprog[chan - 1].r2); - if (error != 0) - goto fail; - - /* init maxim radio - skipping the two first values */ - for (i = 2; i < N(rfini); i++) { - if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return (error); - } - zyd_read16_m(sc, ZYD_CR203, &tmp); - zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4)); -fail: - return (error); -#undef N -} - -/* - * Maxim2 RF methods. - */ -static int -zyd_maxim2_init(struct zyd_rf *rf) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - struct zyd_softc *sc = rf->rf_sc; - static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY; - static const uint32_t rfini[] = ZYD_MAXIM2_RF; - uint16_t tmp; - int i, error; - - /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) - zyd_write16_m(sc, phyini[i].reg, phyini[i].val); - - zyd_read16_m(sc, ZYD_CR203, &tmp); - zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4)); - - /* init maxim2 radio */ - for (i = 0; i < N(rfini); i++) { - if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return (error); - } - zyd_read16_m(sc, ZYD_CR203, &tmp); - zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4)); -fail: - return (error); -#undef N -} - -static int -zyd_maxim2_switch_radio(struct zyd_rf *rf, int on) -{ - - /* vendor driver does nothing for this RF chip */ - return (0); -} - -static int -zyd_maxim2_set_channel(struct zyd_rf *rf, uint8_t chan) -{ -#define N(a) (sizeof(a) / sizeof((a)[0])) - struct zyd_softc *sc = rf->rf_sc; - static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY; - static const uint32_t rfini[] = ZYD_MAXIM2_RF; - static const struct { - uint32_t r1, r2; - } rfprog[] = ZYD_MAXIM2_CHANTABLE; - uint16_t tmp; - int i, error; - - /* - * Do the same as we do when initializing it, except for the channel - * values coming from the two channel tables. - */ - - /* init RF-dependent PHY registers */ - for (i = 0; i < N(phyini); i++) - zyd_write16_m(sc, phyini[i].reg, phyini[i].val); - - zyd_read16_m(sc, ZYD_CR203, &tmp); - zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4)); - - /* first two values taken from the chantables */ - error = zyd_rfwrite(sc, rfprog[chan - 1].r1); - if (error != 0) - goto fail; - error = zyd_rfwrite(sc, rfprog[chan - 1].r2); - if (error != 0) - goto fail; - - /* init maxim2 radio - skipping the two first values */ - for (i = 2; i < N(rfini); i++) { - if ((error = zyd_rfwrite(sc, rfini[i])) != 0) - return (error); - } - zyd_read16_m(sc, ZYD_CR203, &tmp); - zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4)); -fail: - return (error); -#undef N -} - -static int -zyd_rf_attach(struct zyd_softc *sc, uint8_t type) -{ - struct zyd_rf *rf = &sc->sc_rf; - - rf->rf_sc = sc; - - switch (type) { - case ZYD_RF_RFMD: - rf->init = zyd_rfmd_init; - rf->switch_radio = zyd_rfmd_switch_radio; - rf->set_channel = zyd_rfmd_set_channel; - rf->width = 24; /* 24-bit RF values */ - break; - case ZYD_RF_AL2230: - case ZYD_RF_AL2230S: - if (sc->sc_macrev == ZYD_ZD1211B) { - rf->init = zyd_al2230_init_b; - rf->set_channel = zyd_al2230_set_channel_b; - } else { - rf->init = zyd_al2230_init; - rf->set_channel = zyd_al2230_set_channel; - } - rf->switch_radio = zyd_al2230_switch_radio; - rf->bandedge6 = zyd_al2230_bandedge6; - rf->width = 24; /* 24-bit RF values */ - break; - case ZYD_RF_AL7230B: - rf->init = zyd_al7230B_init; - rf->switch_radio = zyd_al7230B_switch_radio; - rf->set_channel = zyd_al7230B_set_channel; - rf->width = 24; /* 24-bit RF values */ - break; - case ZYD_RF_AL2210: - rf->init = zyd_al2210_init; - rf->switch_radio = zyd_al2210_switch_radio; - rf->set_channel = zyd_al2210_set_channel; - rf->width = 24; /* 24-bit RF values */ - break; - case ZYD_RF_GCT: - rf->init = zyd_gct_init; - rf->switch_radio = zyd_gct_switch_radio; - rf->set_channel = zyd_gct_set_channel; - rf->width = 21; /* 21-bit RF values */ - break; - case ZYD_RF_MAXIM_NEW: - rf->init = zyd_maxim_init; - rf->switch_radio = zyd_maxim_switch_radio; - rf->set_channel = zyd_maxim_set_channel; - rf->width = 18; /* 18-bit RF values */ - break; - case ZYD_RF_MAXIM_NEW2: - rf->init = zyd_maxim2_init; - rf->switch_radio = zyd_maxim2_switch_radio; - rf->set_channel = zyd_maxim2_set_channel; - rf->width = 18; /* 18-bit RF values */ - break; - default: - device_printf(sc->sc_dev, - "sorry, radio \"%s\" is not supported yet\n", - zyd_rf_name(type)); - return (EINVAL); - } - return (0); -} - -static const char * -zyd_rf_name(uint8_t type) -{ - static const char * const zyd_rfs[] = { - "unknown", "unknown", "UW2451", "UCHIP", "AL2230", - "AL7230B", "THETA", "AL2210", "MAXIM_NEW", "GCT", - "AL2230S", "RALINK", "INTERSIL", "RFMD", "MAXIM_NEW2", - "PHILIPS" - }; - - return zyd_rfs[(type > 15) ? 0 : type]; -} - -static int -zyd_hw_init(struct zyd_softc *sc) -{ - int error; - const struct zyd_phy_pair *phyp; - struct zyd_rf *rf = &sc->sc_rf; - uint16_t val; - - /* specify that the plug and play is finished */ - zyd_write32_m(sc, ZYD_MAC_AFTER_PNP, 1); - zyd_read16_m(sc, ZYD_FIRMWARE_BASE_ADDR, &sc->sc_fwbase); - DPRINTF(sc, ZYD_DEBUG_FW, "firmware base address=0x%04x\n", - sc->sc_fwbase); - - /* retrieve firmware revision number */ - zyd_read16_m(sc, sc->sc_fwbase + ZYD_FW_FIRMWARE_REV, &sc->sc_fwrev); - zyd_write32_m(sc, ZYD_CR_GPI_EN, 0); - zyd_write32_m(sc, ZYD_MAC_CONT_WIN_LIMIT, 0x7f043f); - /* set mandatory rates - XXX assumes 802.11b/g */ - zyd_write32_m(sc, ZYD_MAC_MAN_RATE, 0x150f); - - /* disable interrupts */ - zyd_write32_m(sc, ZYD_CR_INTERRUPT, 0); - - if ((error = zyd_read_pod(sc)) != 0) { - device_printf(sc->sc_dev, "could not read EEPROM\n"); - goto fail; - } - - /* PHY init (resetting) */ - error = zyd_lock_phy(sc); - if (error != 0) - goto fail; - phyp = (sc->sc_macrev == ZYD_ZD1211B) ? zyd_def_phyB : zyd_def_phy; - for (; phyp->reg != 0; phyp++) - zyd_write16_m(sc, phyp->reg, phyp->val); - if (sc->sc_macrev == ZYD_ZD1211 && sc->sc_fix_cr157 != 0) { - zyd_read16_m(sc, ZYD_EEPROM_PHY_REG, &val); - zyd_write32_m(sc, ZYD_CR157, val >> 8); - } - error = zyd_unlock_phy(sc); - if (error != 0) - goto fail; - - /* HMAC init */ - zyd_write32_m(sc, ZYD_MAC_ACK_EXT, 0x00000020); - zyd_write32_m(sc, ZYD_CR_ADDA_MBIAS_WT, 0x30000808); - zyd_write32_m(sc, ZYD_MAC_SNIFFER, 0x00000000); - zyd_write32_m(sc, ZYD_MAC_RXFILTER, 0x00000000); - zyd_write32_m(sc, ZYD_MAC_GHTBL, 0x00000000); - zyd_write32_m(sc, ZYD_MAC_GHTBH, 0x80000000); - zyd_write32_m(sc, ZYD_MAC_MISC, 0x000000a4); - zyd_write32_m(sc, ZYD_CR_ADDA_PWR_DWN, 0x0000007f); - zyd_write32_m(sc, ZYD_MAC_BCNCFG, 0x00f00401); - zyd_write32_m(sc, ZYD_MAC_PHY_DELAY2, 0x00000000); - zyd_write32_m(sc, ZYD_MAC_ACK_EXT, 0x00000080); - zyd_write32_m(sc, ZYD_CR_ADDA_PWR_DWN, 0x00000000); - zyd_write32_m(sc, ZYD_MAC_SIFS_ACK_TIME, 0x00000100); - zyd_write32_m(sc, ZYD_CR_RX_PE_DELAY, 0x00000070); - zyd_write32_m(sc, ZYD_CR_PS_CTRL, 0x10000000); - zyd_write32_m(sc, ZYD_MAC_RTSCTSRATE, 0x02030203); - zyd_write32_m(sc, ZYD_MAC_AFTER_PNP, 1); - zyd_write32_m(sc, ZYD_MAC_BACKOFF_PROTECT, 0x00000114); - zyd_write32_m(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0a47c032); - zyd_write32_m(sc, ZYD_MAC_CAM_MODE, 0x3); - - if (sc->sc_macrev == ZYD_ZD1211) { - zyd_write32_m(sc, ZYD_MAC_RETRY, 0x00000002); - zyd_write32_m(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640); - } else { - zyd_write32_m(sc, ZYD_MACB_MAX_RETRY, 0x02020202); - zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f); - zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f); - zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f); - zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f); - zyd_write32_m(sc, ZYD_MACB_AIFS_CTL1, 0x00280028); - zyd_write32_m(sc, ZYD_MACB_AIFS_CTL2, 0x008C003C); - zyd_write32_m(sc, ZYD_MACB_TXOP, 0x01800824); - zyd_write32_m(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0eff); - } - - /* init beacon interval to 100ms */ - if ((error = zyd_set_beacon_interval(sc, 100)) != 0) - goto fail; - - if ((error = zyd_rf_attach(sc, sc->sc_rfrev)) != 0) { - device_printf(sc->sc_dev, "could not attach RF, rev 0x%x\n", - sc->sc_rfrev); - goto fail; - } - - /* RF chip init */ - error = zyd_lock_phy(sc); - if (error != 0) - goto fail; - error = (*rf->init)(rf); - if (error != 0) { - device_printf(sc->sc_dev, - "radio initialization failed, error %d\n", error); - goto fail; - } - error = zyd_unlock_phy(sc); - if (error != 0) - goto fail; - - if ((error = zyd_read_eeprom(sc)) != 0) { - device_printf(sc->sc_dev, "could not read EEPROM\n"); - goto fail; - } - -fail: return (error); -} - -static int -zyd_read_pod(struct zyd_softc *sc) -{ - int error; - uint32_t tmp; - - zyd_read32_m(sc, ZYD_EEPROM_POD, &tmp); - sc->sc_rfrev = tmp & 0x0f; - sc->sc_ledtype = (tmp >> 4) & 0x01; - sc->sc_al2230s = (tmp >> 7) & 0x01; - sc->sc_cckgain = (tmp >> 8) & 0x01; - sc->sc_fix_cr157 = (tmp >> 13) & 0x01; - sc->sc_parev = (tmp >> 16) & 0x0f; - sc->sc_bandedge6 = (tmp >> 21) & 0x01; - sc->sc_newphy = (tmp >> 31) & 0x01; - sc->sc_txled = ((tmp & (1 << 24)) && (tmp & (1 << 29))) ? 0 : 1; -fail: - return (error); -} - -static int -zyd_read_eeprom(struct zyd_softc *sc) -{ - uint16_t val; - int error, i; - - /* read Tx power calibration tables */ - for (i = 0; i < 7; i++) { - zyd_read16_m(sc, ZYD_EEPROM_PWR_CAL + i, &val); - sc->sc_pwrcal[i * 2] = val >> 8; - sc->sc_pwrcal[i * 2 + 1] = val & 0xff; - zyd_read16_m(sc, ZYD_EEPROM_PWR_INT + i, &val); - sc->sc_pwrint[i * 2] = val >> 8; - sc->sc_pwrint[i * 2 + 1] = val & 0xff; - zyd_read16_m(sc, ZYD_EEPROM_36M_CAL + i, &val); - sc->sc_ofdm36_cal[i * 2] = val >> 8; - sc->sc_ofdm36_cal[i * 2 + 1] = val & 0xff; - zyd_read16_m(sc, ZYD_EEPROM_48M_CAL + i, &val); - sc->sc_ofdm48_cal[i * 2] = val >> 8; - sc->sc_ofdm48_cal[i * 2 + 1] = val & 0xff; - zyd_read16_m(sc, ZYD_EEPROM_54M_CAL + i, &val); - sc->sc_ofdm54_cal[i * 2] = val >> 8; - sc->sc_ofdm54_cal[i * 2 + 1] = val & 0xff; - } -fail: - return (error); -} - -static int -zyd_get_macaddr(struct zyd_softc *sc) -{ - usb_device_request_t req; - usbd_status error; - - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = ZYD_READFWDATAREQ; - USETW(req.wValue, ZYD_EEPROM_MAC_ADDR_P1); - USETW(req.wIndex, 0); - USETW(req.wLength, IEEE80211_ADDR_LEN); - - error = usbd_do_request(sc->sc_udev, &req, sc->sc_bssid); - if (error != 0) { - device_printf(sc->sc_dev, "could not read EEPROM: %s\n", - usbd_errstr(error)); - } - - return (error); -} - -static int -zyd_set_macaddr(struct zyd_softc *sc, const uint8_t *addr) -{ - int error; - uint32_t tmp; - - tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0]; - zyd_write32_m(sc, ZYD_MAC_MACADRL, tmp); - tmp = addr[5] << 8 | addr[4]; - zyd_write32_m(sc, ZYD_MAC_MACADRH, tmp); -fail: - return (error); -} - -static int -zyd_set_bssid(struct zyd_softc *sc, const uint8_t *addr) -{ - int error; - uint32_t tmp; - - tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0]; - zyd_write32_m(sc, ZYD_MAC_BSSADRL, tmp); - tmp = addr[5] << 8 | addr[4]; - zyd_write32_m(sc, ZYD_MAC_BSSADRH, tmp); -fail: - return (error); -} - -static int -zyd_switch_radio(struct zyd_softc *sc, int on) -{ - struct zyd_rf *rf = &sc->sc_rf; - int error; - - error = zyd_lock_phy(sc); - if (error != 0) - goto fail; - error = (*rf->switch_radio)(rf, on); - if (error != 0) - goto fail; - error = zyd_unlock_phy(sc); -fail: - return (error); -} - -static int -zyd_set_led(struct zyd_softc *sc, int which, int on) -{ - int error; - uint32_t tmp; - - zyd_read32_m(sc, ZYD_MAC_TX_PE_CONTROL, &tmp); - tmp &= ~which; - if (on) - tmp |= which; - zyd_write32_m(sc, ZYD_MAC_TX_PE_CONTROL, tmp); -fail: - return (error); -} - -static void -zyd_set_multi(void *arg) -{ - int error; - struct zyd_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ifmultiaddr *ifma; - uint32_t low, high; - uint8_t v; - - if (!(ifp->if_flags & IFF_UP)) - return; - - low = 0x00000000; - high = 0x80000000; - - if (ic->ic_opmode == IEEE80211_M_MONITOR || - (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) { - low = 0xffffffff; - high = 0xffffffff; - } else { - IF_ADDR_LOCK(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - v = ((uint8_t *)LLADDR((struct sockaddr_dl *) - ifma->ifma_addr))[5] >> 2; - if (v < 32) - low |= 1 << v; - else - high |= 1 << (v - 32); - } - IF_ADDR_UNLOCK(ifp); - } - - /* reprogram multicast global hash table */ - zyd_write32_m(sc, ZYD_MAC_GHTBL, low); - zyd_write32_m(sc, ZYD_MAC_GHTBH, high); -fail: - if (error != 0) - device_printf(sc->sc_dev, - "could not set multicast hash table\n"); -} - -static void -zyd_update_mcast(struct ifnet *ifp) -{ - struct zyd_softc *sc = ifp->if_softc; - - if (!(sc->sc_flags & ZYD_FLAG_INITDONE)) - return; - - usb_add_task(sc->sc_udev, &sc->sc_mcasttask, USB_TASKQ_DRIVER); -} - -static int -zyd_set_rxfilter(struct zyd_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - uint32_t rxfilter; - - switch (ic->ic_opmode) { - case IEEE80211_M_STA: - rxfilter = ZYD_FILTER_BSS; - break; - case IEEE80211_M_IBSS: - case IEEE80211_M_HOSTAP: - rxfilter = ZYD_FILTER_HOSTAP; - break; - case IEEE80211_M_MONITOR: - rxfilter = ZYD_FILTER_MONITOR; - break; - default: - /* should not get there */ - return (EINVAL); - } - return zyd_write32(sc, ZYD_MAC_RXFILTER, rxfilter); -} - -static void -zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c) -{ - int error; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct zyd_rf *rf = &sc->sc_rf; - uint32_t tmp; - u_int chan; - - chan = ieee80211_chan2ieee(ic, c); - if (chan == 0 || chan == IEEE80211_CHAN_ANY) { - /* XXX should NEVER happen */ - device_printf(sc->sc_dev, - "%s: invalid channel %x\n", __func__, chan); - return; - } - - error = zyd_lock_phy(sc); - if (error != 0) - goto fail; - - error = (*rf->set_channel)(rf, chan); - if (error != 0) - goto fail; - - /* update Tx power */ - zyd_write16_m(sc, ZYD_CR31, sc->sc_pwrint[chan - 1]); - - if (sc->sc_macrev == ZYD_ZD1211B) { - zyd_write16_m(sc, ZYD_CR67, sc->sc_ofdm36_cal[chan - 1]); - zyd_write16_m(sc, ZYD_CR66, sc->sc_ofdm48_cal[chan - 1]); - zyd_write16_m(sc, ZYD_CR65, sc->sc_ofdm54_cal[chan - 1]); - zyd_write16_m(sc, ZYD_CR68, sc->sc_pwrcal[chan - 1]); - zyd_write16_m(sc, ZYD_CR69, 0x28); - zyd_write16_m(sc, ZYD_CR69, 0x2a); - } - if (sc->sc_cckgain) { - /* set CCK baseband gain from EEPROM */ - if (zyd_read32(sc, ZYD_EEPROM_PHY_REG, &tmp) == 0) - zyd_write16_m(sc, ZYD_CR47, tmp & 0xff); - } - if (sc->sc_bandedge6 && rf->bandedge6 != NULL) { - error = (*rf->bandedge6)(rf, c); - if (error != 0) - goto fail; - } - zyd_write32_m(sc, ZYD_CR_CONFIG_PHILIPS, 0); - - error = zyd_unlock_phy(sc); - if (error != 0) - goto fail; - - sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq = - htole16(c->ic_freq); - sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags = - htole16(c->ic_flags); -fail: - return; -} - -static int -zyd_set_beacon_interval(struct zyd_softc *sc, int bintval) -{ - int error; - uint32_t val; - - zyd_read32_m(sc, ZYD_CR_ATIM_WND_PERIOD, &val); - sc->sc_atim_wnd = val; - zyd_read32_m(sc, ZYD_CR_PRE_TBTT, &val); - sc->sc_pre_tbtt = val; - sc->sc_bcn_int = bintval; - - if (sc->sc_bcn_int <= 5) - sc->sc_bcn_int = 5; - if (sc->sc_pre_tbtt < 4 || sc->sc_pre_tbtt >= sc->sc_bcn_int) - sc->sc_pre_tbtt = sc->sc_bcn_int - 1; - if (sc->sc_atim_wnd >= sc->sc_pre_tbtt) - sc->sc_atim_wnd = sc->sc_pre_tbtt - 1; - - zyd_write32_m(sc, ZYD_CR_ATIM_WND_PERIOD, sc->sc_atim_wnd); - zyd_write32_m(sc, ZYD_CR_PRE_TBTT, sc->sc_pre_tbtt); - zyd_write32_m(sc, ZYD_CR_BCN_INTERVAL, sc->sc_bcn_int); -fail: - return (error); -} - -static void -zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct zyd_softc *sc = (struct zyd_softc *)priv; - struct zyd_cmd *cmd; - uint32_t datalen; - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) - return; - - if (status == USBD_STALLED) { - usbd_clear_endpoint_stall_async( - sc->sc_ep[ZYD_ENDPT_IIN]); - } - return; - } - - cmd = (struct zyd_cmd *)sc->sc_ibuf; - - if (le16toh(cmd->code) == ZYD_NOTIF_RETRYSTATUS) { - struct zyd_notif_retry *retry = - (struct zyd_notif_retry *)cmd->data; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct ieee80211_node *ni; - - DPRINTF(sc, ZYD_DEBUG_TX_PROC, - "retry intr: rate=0x%x addr=%s count=%d (0x%x)\n", - le16toh(retry->rate), ether_sprintf(retry->macaddr), - le16toh(retry->count) & 0xff, le16toh(retry->count)); - - /* - * Find the node to which the packet was sent and update its - * retry statistics. In BSS mode, this node is the AP we're - * associated to so no lookup is actually needed. - */ - ni = ieee80211_find_txnode(vap, retry->macaddr); - if (ni != NULL) { - ieee80211_amrr_tx_complete(&ZYD_NODE(ni)->amn, - IEEE80211_AMRR_FAILURE, 1); - ieee80211_free_node(ni); - } - if (le16toh(retry->count) & 0x100) - ifp->if_oerrors++; /* too many retries */ - } else if (le16toh(cmd->code) == ZYD_NOTIF_IORD) { - struct zyd_rq *rqp; - - if (le16toh(*(uint16_t *)cmd->data) == ZYD_CR_INTERRUPT) - return; /* HMAC interrupt */ - - usbd_get_xfer_status(xfer, NULL, NULL, &datalen, NULL); - datalen -= sizeof(cmd->code); - datalen -= 2; /* XXX: padding? */ - - STAILQ_FOREACH(rqp, &sc->sc_rqh, rq) { - int i; - - if (sizeof(struct zyd_pair) * rqp->len != datalen) - continue; - for (i = 0; i < rqp->len; i++) { - if (*(((const uint16_t *)rqp->idata) + i) != - (((struct zyd_pair *)cmd->data) + i)->reg) - break; - } - if (i != rqp->len) - continue; - - /* copy answer into caller-supplied buffer */ - bcopy(cmd->data, rqp->odata, - sizeof(struct zyd_pair) * rqp->len); - wakeup(rqp->odata); /* wakeup caller */ - - return; - } - return; /* unexpected IORD notification */ - } else { - device_printf(sc->sc_dev, "unknown notification %x\n", - le16toh(cmd->code)); - } -} - -static void -zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211_node *ni; - const struct zyd_plcphdr *plcp; - const struct zyd_rx_stat *stat; - struct mbuf *m; - int rlen, rssi, nf; - - if (len < ZYD_MIN_FRAGSZ) { - DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too short (length=%d)\n", - device_get_nameunit(sc->sc_dev), len); - ifp->if_ierrors++; - return; - } - - plcp = (const struct zyd_plcphdr *)buf; - stat = (const struct zyd_rx_stat *) - (buf + len - sizeof(struct zyd_rx_stat)); - - if (stat->flags & ZYD_RX_ERROR) { - DPRINTF(sc, ZYD_DEBUG_RECV, - "%s: RX status indicated error (%x)\n", - device_get_nameunit(sc->sc_dev), stat->flags); - ifp->if_ierrors++; - return; - } - - /* compute actual frame length */ - rlen = len - sizeof(struct zyd_plcphdr) - - sizeof(struct zyd_rx_stat) - IEEE80211_CRC_LEN; - - /* allocate a mbuf to store the frame */ - if (rlen > MHLEN) - m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - else - m = m_gethdr(M_DONTWAIT, MT_DATA); - if (m == NULL) { - DPRINTF(sc, ZYD_DEBUG_RECV, "%s: could not allocate rx mbuf\n", - device_get_nameunit(sc->sc_dev)); - ifp->if_ierrors++; - return; - } - m->m_pkthdr.rcvif = ifp; - m->m_pkthdr.len = m->m_len = rlen; - bcopy((const uint8_t *)(plcp + 1), mtod(m, uint8_t *), rlen); - - if (bpf_peers_present(ifp->if_bpf)) { - struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap; - - tap->wr_flags = 0; - if (stat->flags & (ZYD_RX_BADCRC16 | ZYD_RX_BADCRC32)) - tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; - /* XXX toss, no way to express errors */ - if (stat->flags & ZYD_RX_DECRYPTERR) - tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; - tap->wr_rate = ieee80211_plcp2rate(plcp->signal, - (stat->flags & ZYD_RX_OFDM) ? - IEEE80211_T_OFDM : IEEE80211_T_CCK); - tap->wr_antsignal = stat->rssi + -95; - tap->wr_antnoise = -95; /* XXX */ - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); - } - - rssi = stat->rssi > 63 ? 127 : 2 * stat->rssi; - nf = -95; /* XXX */ - - ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); - if (ni != NULL) { - (void)ieee80211_input(ni, m, rssi, nf, 0); - ieee80211_free_node(ni); - } else - (void)ieee80211_input_all(ic, m, rssi, nf, 0); -} - -static void -zyd_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct zyd_rx_data *data = priv; - struct zyd_softc *sc = data->sc; - struct ifnet *ifp = sc->sc_ifp; - const struct zyd_rx_desc *desc; - int len; - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) - return; - - if (status == USBD_STALLED) - usbd_clear_endpoint_stall(sc->sc_ep[ZYD_ENDPT_BIN]); - - goto skip; - } - usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); - - if (len < ZYD_MIN_RXBUFSZ) { - DPRINTF(sc, ZYD_DEBUG_RECV, "%s: xfer too short (length=%d)\n", - device_get_nameunit(sc->sc_dev), len); - ifp->if_ierrors++; /* XXX not really errors */ - goto skip; - } - - desc = (const struct zyd_rx_desc *) - (data->buf + len - sizeof(struct zyd_rx_desc)); - - if (UGETW(desc->tag) == ZYD_TAG_MULTIFRAME) { - const uint8_t *p = data->buf, *end = p + len; - int i; - - DPRINTF(sc, ZYD_DEBUG_RECV, - "%s: received multi-frame transfer\n", __func__); - - for (i = 0; i < ZYD_MAX_RXFRAMECNT; i++) { - const uint16_t len16 = UGETW(desc->len[i]); - - if (len16 == 0 || p + len16 > end) - break; - - zyd_rx_data(sc, p, len16); - /* next frame is aligned on a 32-bit boundary */ - p += (len16 + 3) & ~3; - } - } else { - DPRINTF(sc, ZYD_DEBUG_RECV, - "%s: received single-frame transfer\n", __func__); - - zyd_rx_data(sc, data->buf, len); - } - -skip: /* setup a new transfer */ - usbd_setup_xfer(xfer, sc->sc_ep[ZYD_ENDPT_BIN], data, NULL, - ZYX_MAX_RXBUFSZ, USBD_NO_COPY | USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, zyd_rxeof); - (void)usbd_transfer(xfer); -} - -static uint8_t -zyd_plcp_signal(int rate) -{ - switch (rate) { - /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ - case 12: - return (0xb); - case 18: - return (0xf); - case 24: - return (0xa); - case 36: - return (0xe); - case 48: - return (0x9); - case 72: - return (0xd); - case 96: - return (0x8); - case 108: - return (0xc); - /* CCK rates (NB: not IEEE std, device-specific) */ - case 2: - return (0x0); - case 4: - return (0x1); - case 11: - return (0x2); - case 22: - return (0x3); - } - return (0xff); /* XXX unsupported/unknown rate */ -} - -static int -zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = sc->sc_ifp; - struct zyd_tx_desc *desc; - struct zyd_tx_data *data; - struct ieee80211_frame *wh; - struct ieee80211_key *k; - int data_idx, rate, totlen, xferlen; - uint16_t pktlen; - usbd_status error; - - data_idx = sc->sc_txidx; - sc->sc_txidx = (sc->sc_txidx + 1) % ZYD_TX_LIST_CNT; - - data = &sc->sc_txdata[data_idx]; - desc = (struct zyd_tx_desc *)data->buf; - - rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; - - wh = mtod(m0, struct ieee80211_frame *); - - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ni, m0); - if (k == NULL) { - m_freem(m0); - return (ENOBUFS); - } - } - - data->ni = ni; - data->m = m0; - - wh = mtod(m0, struct ieee80211_frame *); - - xferlen = sizeof(struct zyd_tx_desc) + m0->m_pkthdr.len; - totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN; - - /* fill Tx descriptor */ - desc->len = htole16(totlen); - - desc->flags = ZYD_TX_FLAG_BACKOFF; - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - /* multicast frames are not sent at OFDM rates in 802.11b/g */ - if (totlen > vap->iv_rtsthreshold) { - desc->flags |= ZYD_TX_FLAG_RTS; - } else if (ZYD_RATE_IS_OFDM(rate) && - (ic->ic_flags & IEEE80211_F_USEPROT)) { - if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) - desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF; - else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) - desc->flags |= ZYD_TX_FLAG_RTS; - } - } else - desc->flags |= ZYD_TX_FLAG_MULTICAST; - - if ((wh->i_fc[0] & - (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == - (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL)) - desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL); - - desc->phy = zyd_plcp_signal(rate); - if (ZYD_RATE_IS_OFDM(rate)) { - desc->phy |= ZYD_TX_PHY_OFDM; - if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) - desc->phy |= ZYD_TX_PHY_5GHZ; - } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) - desc->phy |= ZYD_TX_PHY_SHPREAMBLE; - - /* actual transmit length (XXX why +10?) */ - pktlen = sizeof(struct zyd_tx_desc) + 10; - if (sc->sc_macrev == ZYD_ZD1211) - pktlen += totlen; - desc->pktlen = htole16(pktlen); - - desc->plcp_length = (16 * totlen + rate - 1) / rate; - desc->plcp_service = 0; - if (rate == 22) { - const int remainder = (16 * totlen) % 22; - if (remainder != 0 && remainder < 7) - desc->plcp_service |= ZYD_PLCP_LENGEXT; - } - - if (bpf_peers_present(ifp->if_bpf)) { - struct zyd_tx_radiotap_header *tap = &sc->sc_txtap; - - tap->wt_flags = 0; - tap->wt_rate = rate; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); - } - - m_copydata(m0, 0, m0->m_pkthdr.len, - data->buf + sizeof(struct zyd_tx_desc)); - - DPRINTF(sc, ZYD_DEBUG_XMIT, - "%s: sending mgt frame len=%zu rate=%u xferlen=%u\n", - device_get_nameunit(sc->sc_dev), (size_t)m0->m_pkthdr.len, - rate, xferlen); - - usbd_setup_xfer(data->xfer, sc->sc_ep[ZYD_ENDPT_BOUT], data, - data->buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - ZYD_TX_TIMEOUT, zyd_txeof); - error = usbd_transfer(data->xfer); - if (error != USBD_IN_PROGRESS && error != 0) { - ifp->if_oerrors++; - return (EIO); - } - sc->sc_txqueued++; - - return (0); -} - -static void -zyd_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct zyd_tx_data *data = priv; - struct zyd_softc *sc = data->sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211_node *ni; - struct mbuf *m; - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) - return; - - device_printf(sc->sc_dev, "could not transmit buffer: %s\n", - usbd_errstr(status)); - - if (status == USBD_STALLED) { - usbd_clear_endpoint_stall_async( - sc->sc_ep[ZYD_ENDPT_BOUT]); - } - ifp->if_oerrors++; - return; - } - - ni = data->ni; - /* update rate control statistics */ - ieee80211_amrr_tx_complete(&ZYD_NODE(ni)->amn, - IEEE80211_AMRR_SUCCESS, 0); - - /* - * Do any tx complete callback. Note this must - * be done before releasing the node reference. - */ - m = data->m; - if (m != NULL && m->m_flags & M_TXCB) { - ieee80211_process_callback(ni, m, 0); /* XXX status? */ - m_freem(m); - data->m = NULL; - } - - ieee80211_free_node(ni); - data->ni = NULL; - - ZYD_TX_LOCK(sc); - sc->sc_txqueued--; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ZYD_TX_UNLOCK(sc); - - ifp->if_opackets++; - sc->sc_txtimer = 0; - zyd_start(ifp); -} - -static int -zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = sc->sc_ifp; - struct zyd_tx_desc *desc; - struct zyd_tx_data *data; - struct ieee80211_frame *wh; - const struct ieee80211_txparam *tp; - struct ieee80211_key *k; - int data_idx, rate, totlen, xferlen; - uint16_t pktlen; - usbd_status error; - - data_idx = sc->sc_txidx; - sc->sc_txidx = (sc->sc_txidx + 1) % ZYD_TX_LIST_CNT; - - wh = mtod(m0, struct ieee80211_frame *); - data = &sc->sc_txdata[data_idx]; - desc = (struct zyd_tx_desc *)data->buf; - - desc->flags = ZYD_TX_FLAG_BACKOFF; - tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { - rate = tp->mcastrate; - desc->flags |= ZYD_TX_FLAG_MULTICAST; - } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { - rate = tp->ucastrate; - } else { - (void) ieee80211_amrr_choose(ni, &ZYD_NODE(ni)->amn); - rate = ni->ni_txrate; - } - - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ni, m0); - if (k == NULL) { - m_freem(m0); - return (ENOBUFS); - } - /* packet header may have moved, reset our local pointer */ - wh = mtod(m0, struct ieee80211_frame *); - } - - data->ni = ni; - data->m = NULL; - - xferlen = sizeof(struct zyd_tx_desc) + m0->m_pkthdr.len; - totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN; - - /* fill Tx descriptor */ - desc->len = htole16(totlen); - - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - /* multicast frames are not sent at OFDM rates in 802.11b/g */ - if (totlen > vap->iv_rtsthreshold) { - desc->flags |= ZYD_TX_FLAG_RTS; - } else if (ZYD_RATE_IS_OFDM(rate) && - (ic->ic_flags & IEEE80211_F_USEPROT)) { - if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) - desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF; - else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) - desc->flags |= ZYD_TX_FLAG_RTS; - } - } - - if ((wh->i_fc[0] & - (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == - (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL)) - desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL); - - desc->phy = zyd_plcp_signal(rate); - if (ZYD_RATE_IS_OFDM(rate)) { - desc->phy |= ZYD_TX_PHY_OFDM; - if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) - desc->phy |= ZYD_TX_PHY_5GHZ; - } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) - desc->phy |= ZYD_TX_PHY_SHPREAMBLE; - - /* actual transmit length (XXX why +10?) */ - pktlen = sizeof(struct zyd_tx_desc) + 10; - if (sc->sc_macrev == ZYD_ZD1211) - pktlen += totlen; - desc->pktlen = htole16(pktlen); - - desc->plcp_length = (16 * totlen + rate - 1) / rate; - desc->plcp_service = 0; - if (rate == 22) { - const int remainder = (16 * totlen) % 22; - if (remainder != 0 && remainder < 7) - desc->plcp_service |= ZYD_PLCP_LENGEXT; - } - - if (bpf_peers_present(ifp->if_bpf)) { - struct zyd_tx_radiotap_header *tap = &sc->sc_txtap; - - tap->wt_flags = 0; - tap->wt_rate = rate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); - } - - m_copydata(m0, 0, m0->m_pkthdr.len, - data->buf + sizeof(struct zyd_tx_desc)); - - DPRINTF(sc, ZYD_DEBUG_XMIT, - "%s: sending data frame len=%zu rate=%u xferlen=%u\n", - device_get_nameunit(sc->sc_dev), (size_t)m0->m_pkthdr.len, - rate, xferlen); - - m_freem(m0); /* mbuf no longer needed */ - - usbd_setup_xfer(data->xfer, sc->sc_ep[ZYD_ENDPT_BOUT], data, - data->buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - ZYD_TX_TIMEOUT, zyd_txeof); - error = usbd_transfer(data->xfer); - if (error != USBD_IN_PROGRESS && error != 0) { - ifp->if_oerrors++; - return (EIO); - } - sc->sc_txqueued++; - - return (0); -} - -static void -zyd_start(struct ifnet *ifp) -{ - struct zyd_softc *sc = ifp->if_softc; - struct ieee80211_node *ni; - struct mbuf *m; - - ZYD_TX_LOCK(sc); - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - if (sc->sc_txqueued >= ZYD_TX_LIST_CNT) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; - m = ieee80211_encap(ni, m); - if (m == NULL) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - continue; - } - if (zyd_tx_data(sc, m, ni) != 0) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - break; - } - - sc->sc_txtimer = 5; - } - ZYD_TX_UNLOCK(sc); -} - -static int -zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, - const struct ieee80211_bpf_params *params) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct zyd_softc *sc = ifp->if_softc; - - /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - m_freem(m); - ieee80211_free_node(ni); - return (ENETDOWN); - } - ZYD_TX_LOCK(sc); - if (sc->sc_txqueued >= ZYD_TX_LIST_CNT) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - m_freem(m); - ieee80211_free_node(ni); - return (ENOBUFS); /* XXX */ - } - - /* - * Legacy path; interpret frame contents to decide - * precisely how to send the frame. - * XXX raw path - */ - if (zyd_tx_mgt(sc, m, ni) != 0) { - ZYD_TX_UNLOCK(sc); - ifp->if_oerrors++; - ieee80211_free_node(ni); - return (EIO); - } - - ZYD_TX_UNLOCK(sc); - ifp->if_opackets++; - sc->sc_txtimer = 5; - return (0); -} - -static void -zyd_watchdog(void *arg) -{ - struct zyd_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - - if (sc->sc_txtimer > 0) { - if (--sc->sc_txtimer == 0) { - device_printf(sc->sc_dev, "device timeout\n"); - /* zyd_init(ifp); XXX needs a process context ? */ - ifp->if_oerrors++; - return; - } - callout_reset(&sc->sc_watchdog_ch, hz, zyd_watchdog, sc); - } -} - -static int -zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) -{ - struct zyd_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; - - switch (cmd) { - case SIOCSIFFLAGS: - ZYD_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if ((ifp->if_flags ^ sc->sc_if_flags) & - (IFF_ALLMULTI | IFF_PROMISC)) - zyd_set_multi(sc); - } else { - zyd_init_locked(sc); - startall = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - zyd_stop(sc, 1); - } - sc->sc_if_flags = ifp->if_flags; - ZYD_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - return (error); -} - -static void -zyd_init_locked(struct zyd_softc *sc) -{ - int error, i; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - uint32_t val; - - if (!(sc->sc_flags & ZYD_FLAG_INITONCE)) { - error = zyd_loadfirmware(sc); - if (error != 0) { - device_printf(sc->sc_dev, - "could not load firmware (error=%d)\n", error); - goto fail; - } - - error = usbd_set_config_no(sc->sc_udev, ZYD_CONFIG_NO, 1); - if (error != 0) { - device_printf(sc->sc_dev, "setting config no failed\n"); - goto fail; - } - error = usbd_device2interface_handle(sc->sc_udev, - ZYD_IFACE_INDEX, &sc->sc_iface); - if (error != 0) { - device_printf(sc->sc_dev, - "getting interface handle failed\n"); - goto fail; - } - - if ((error = zyd_open_pipes(sc)) != 0) { - device_printf(sc->sc_dev, "could not open pipes\n"); - goto fail; - } - if ((error = zyd_hw_init(sc)) != 0) { - device_printf(sc->sc_dev, - "hardware initialization failed\n"); - goto fail; - } - - device_printf(sc->sc_dev, - "HMAC ZD1211%s, FW %02x.%02x, RF %s S%x, PA%x LED %x " - "BE%x NP%x Gain%x F%x\n", - (sc->sc_macrev == ZYD_ZD1211) ? "": "B", - sc->sc_fwrev >> 8, sc->sc_fwrev & 0xff, - zyd_rf_name(sc->sc_rfrev), sc->sc_al2230s, sc->sc_parev, - sc->sc_ledtype, sc->sc_bandedge6, sc->sc_newphy, - sc->sc_cckgain, sc->sc_fix_cr157); - - /* read regulatory domain (currently unused) */ - zyd_read32_m(sc, ZYD_EEPROM_SUBID, &val); - sc->sc_regdomain = val >> 16; - DPRINTF(sc, ZYD_DEBUG_INIT, "regulatory domain %x\n", - sc->sc_regdomain); - - /* we'll do software WEP decryption for now */ - DPRINTF(sc, ZYD_DEBUG_INIT, "%s: setting encryption type\n", - __func__); - zyd_write32_m(sc, ZYD_MAC_ENCRYPTION_TYPE, ZYD_ENC_SNIFFER); - - sc->sc_flags |= ZYD_FLAG_INITONCE; - } - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - zyd_stop(sc, 0); - - /* reset softc variables. */ - sc->sc_txidx = 0; - - IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); - DPRINTF(sc, ZYD_DEBUG_INIT, "setting MAC address to %s\n", - ether_sprintf(ic->ic_myaddr)); - error = zyd_set_macaddr(sc, ic->ic_myaddr); - if (error != 0) - return; - - /* set basic rates */ - if (ic->ic_curmode == IEEE80211_MODE_11B) - zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x0003); - else if (ic->ic_curmode == IEEE80211_MODE_11A) - zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x1500); - else /* assumes 802.11b/g */ - zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0xff0f); - - /* promiscuous mode */ - zyd_write32_m(sc, ZYD_MAC_SNIFFER, 0); - /* multicast setup */ - zyd_set_multi(sc); - /* set RX filter */ - error = zyd_set_rxfilter(sc); - if (error != 0) - goto fail; - - /* switch radio transmitter ON */ - error = zyd_switch_radio(sc, 1); - if (error != 0) - goto fail; - /* set default BSS channel */ - zyd_set_chan(sc, ic->ic_curchan); - - /* - * Allocate Tx and Rx xfer queues. - */ - if ((error = zyd_alloc_tx_list(sc)) != 0) { - device_printf(sc->sc_dev, "could not allocate Tx list\n"); - goto fail; - } - if ((error = zyd_alloc_rx_list(sc)) != 0) { - device_printf(sc->sc_dev, "could not allocate Rx list\n"); - goto fail; - } - - /* - * Start up the receive pipe. - */ - for (i = 0; i < ZYD_RX_LIST_CNT; i++) { - struct zyd_rx_data *data = &sc->sc_rxdata[i]; - - usbd_setup_xfer(data->xfer, sc->sc_ep[ZYD_ENDPT_BIN], data, - NULL, ZYX_MAX_RXBUFSZ, USBD_NO_COPY | USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, zyd_rxeof); - error = usbd_transfer(data->xfer); - if (error != USBD_IN_PROGRESS && error != 0) { - device_printf(sc->sc_dev, - "could not queue Rx transfer\n"); - goto fail; - } - } - - /* enable interrupts */ - zyd_write32_m(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK); - - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; - sc->sc_flags |= ZYD_FLAG_INITDONE; - - callout_reset(&sc->sc_watchdog_ch, hz, zyd_watchdog, sc); - return; - -fail: zyd_stop(sc, 1); - return; -} - -static void -zyd_init(void *priv) -{ - struct zyd_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - ZYD_LOCK(sc); - zyd_init_locked(sc); - ZYD_UNLOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ieee80211_start_all(ic); /* start all vap's */ -} - -static void -zyd_stop(struct zyd_softc *sc, int disable) -{ - int error; - struct ifnet *ifp = sc->sc_ifp; - - sc->sc_txtimer = 0; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - - /* switch radio transmitter OFF */ - error = zyd_switch_radio(sc, 0); - if (error != 0) - goto fail; - /* disable Rx */ - zyd_write32_m(sc, ZYD_MAC_RXFILTER, 0); - /* disable interrupts */ - zyd_write32_m(sc, ZYD_CR_INTERRUPT, 0); - - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - usb_rem_task(sc->sc_udev, &sc->sc_task); - callout_stop(&sc->sc_watchdog_ch); - - usbd_abort_pipe(sc->sc_ep[ZYD_ENDPT_BIN]); - usbd_abort_pipe(sc->sc_ep[ZYD_ENDPT_BOUT]); - - zyd_free_rx_list(sc); - zyd_free_tx_list(sc); -fail: - return; -} - -static int -zyd_loadfirmware(struct zyd_softc *sc) -{ - usb_device_request_t req; - size_t size; - u_char *fw; - uint8_t stat; - uint16_t addr; - - if (sc->sc_flags & ZYD_FLAG_FWLOADED) - return (0); - - if (sc->sc_macrev == ZYD_ZD1211) { - fw = (u_char *)zd1211_firmware; - size = sizeof(zd1211_firmware); - } else { - fw = (u_char *)zd1211b_firmware; - size = sizeof(zd1211b_firmware); - } - - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = ZYD_DOWNLOADREQ; - USETW(req.wIndex, 0); - - addr = ZYD_FIRMWARE_START_ADDR; - while (size > 0) { - /* - * When the transfer size is 4096 bytes, it is not - * likely to be able to transfer it. - * The cause is port or machine or chip? - */ - const int mlen = min(size, 64); - - DPRINTF(sc, ZYD_DEBUG_FW, - "loading firmware block: len=%d, addr=0x%x\n", mlen, addr); - - USETW(req.wValue, addr); - USETW(req.wLength, mlen); - if (usbd_do_request(sc->sc_udev, &req, fw) != 0) - return (EIO); - - addr += mlen / 2; - fw += mlen; - size -= mlen; - } - - /* check whether the upload succeeded */ - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = ZYD_DOWNLOADSTS; - USETW(req.wValue, 0); - USETW(req.wIndex, 0); - USETW(req.wLength, sizeof(stat)); - if (usbd_do_request(sc->sc_udev, &req, &stat) != 0) - return (EIO); - - sc->sc_flags |= ZYD_FLAG_FWLOADED; - - return (stat & 0x80) ? (EIO) : (0); -} - -static void -zyd_newassoc(struct ieee80211_node *ni, int isnew) -{ - struct ieee80211vap *vap = ni->ni_vap; - - ieee80211_amrr_node_init(&ZYD_VAP(vap)->amrr, &ZYD_NODE(ni)->amn, ni); -} - -static void -zyd_scan_start(struct ieee80211com *ic) -{ - struct zyd_softc *sc = ic->ic_ifp->if_softc; - - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - - /* do it in a process context */ - sc->sc_scan_action = ZYD_SCAN_START; - usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER); -} - -static void -zyd_scan_end(struct ieee80211com *ic) -{ - struct zyd_softc *sc = ic->ic_ifp->if_softc; - - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - - /* do it in a process context */ - sc->sc_scan_action = ZYD_SCAN_END; - usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER); -} - -static void -zyd_set_channel(struct ieee80211com *ic) -{ - struct zyd_softc *sc = ic->ic_ifp->if_softc; - - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - /* do it in a process context */ - sc->sc_scan_action = ZYD_SET_CHANNEL; - usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER); -} - -static void -zyd_scantask(void *arg) -{ - struct zyd_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - ZYD_LOCK(sc); - - switch (sc->sc_scan_action) { - case ZYD_SCAN_START: - /* want broadcast address while scanning */ - zyd_set_bssid(sc, ifp->if_broadcastaddr); - break; - case ZYD_SCAN_END: - /* restore previous bssid */ - zyd_set_bssid(sc, sc->sc_bssid); - break; - case ZYD_SET_CHANNEL: - zyd_set_chan(sc, ic->ic_curchan); - break; - default: - device_printf(sc->sc_dev, "unknown scan action %d\n", - sc->sc_scan_action); - break; - } - - ZYD_UNLOCK(sc); -} - -static void -zyd_wakeup(struct zyd_softc *sc) -{ - struct zyd_rq *rqp; - - STAILQ_FOREACH(rqp, &sc->sc_rqh, rq) - wakeup(rqp->odata); /* wakeup sleeping caller */ -} - -static device_method_t zyd_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, zyd_match), - DEVMETHOD(device_attach, zyd_attach), - DEVMETHOD(device_detach, zyd_detach), - - { 0, 0 } -}; - -static driver_t zyd_driver = { - "zyd", - zyd_methods, - sizeof(struct zyd_softc) -}; - -static devclass_t zyd_devclass; - -DRIVER_MODULE(zyd, uhub, zyd_driver, zyd_devclass, usbd_driver_load, 0); -MODULE_DEPEND(zyd, wlan, 1, 1, 1); -MODULE_DEPEND(zyd, wlan_amrr, 1, 1, 1); -MODULE_DEPEND(zyd, usb, 1, 1, 1); diff --git a/sys/legacy/dev/usb/if_zydfw.h b/sys/legacy/dev/usb/if_zydfw.h deleted file mode 100644 index 46f5c2a..0000000 --- a/sys/legacy/dev/usb/if_zydfw.h +++ /dev/null @@ -1,1144 +0,0 @@ -/* - * Copyright (C) 2001, 2002, 2003,2004 ZyDAS Technology Corporation. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted provided - * that the following conditions are met: - * 1. Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistribution 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - */ - -/* $FreeBSD$ */ - -uint8_t zd1211_firmware[] = { - 0x08, 0x91, 0xFF, 0xED, 0x09, 0x93, 0x1E, 0xEE, - 0xD1, 0x94, 0x11, 0xEE, 0x88, 0xD4, 0xD1, 0x96, - 0xD1, 0x98, 0x5C, 0x99, 0x5C, 0x99, 0x4C, 0x99, - 0x04, 0x9D, 0xD1, 0x98, 0xD1, 0x9A, 0x03, 0xEE, - 0xF4, 0x94, 0xD3, 0xD4, 0x41, 0x2A, 0x40, 0x4A, - 0x45, 0xBE, 0x88, 0x92, 0x41, 0x24, 0x40, 0x44, - 0x53, 0xBE, 0x40, 0xF0, 0x93, 0xEE, 0x41, 0xEE, - 0x98, 0x9A, 0xD4, 0xF7, 0x02, 0x00, 0x1F, 0xEC, - 0x00, 0x00, 0xB2, 0xF8, 0x4D, 0x00, 0xA1, 0xEC, - 0x00, 0x00, 0xA6, 0xF7, 0x21, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xD8, - 0xA0, 0x90, 0x98, 0x9A, 0x98, 0x9A, 0xA0, 0xD8, - 0x40, 0xF0, 0xB4, 0xF0, 0xA0, 0x90, 0x98, 0x9A, - 0xA0, 0xD8, 0x40, 0xF0, 0x64, 0xEF, 0xA0, 0x90, - 0x98, 0x9A, 0xA0, 0xD8, 0x40, 0xF0, 0xF6, 0xF0, - 0xA0, 0x90, 0x98, 0x9A, 0xA0, 0xD8, 0x40, 0xF0, - 0xF7, 0xF6, 0xA0, 0x90, 0x98, 0x9A, 0xA0, 0xD8, - 0x40, 0xF0, 0xF8, 0xF5, 0xA0, 0x90, 0x98, 0x9A, - 0xA0, 0xD8, 0x40, 0xF0, 0xF1, 0xF0, 0xA0, 0x90, - 0x98, 0x9A, 0x98, 0x9A, 0xA0, 0xD8, 0x40, 0xF0, - 0x97, 0xF7, 0xA0, 0x90, 0x98, 0x9A, 0x88, 0xDA, - 0x08, 0x0B, 0x01, 0x00, 0x0D, 0x03, 0x03, 0x00, - 0x09, 0x05, 0x01, 0x00, 0xC2, 0x94, 0x42, 0x02, - 0xC1, 0x92, 0x03, 0x96, 0x1B, 0xD7, 0x2A, 0x86, - 0x1A, 0xD5, 0x2B, 0x86, 0x09, 0xA3, 0x00, 0x80, - 0x19, 0xD3, 0x2C, 0x86, 0x00, 0xEE, 0x0A, 0x65, - 0xC0, 0x7A, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, - 0xFE, 0xFF, 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A, - 0x88, 0xDA, 0x42, 0x20, 0x08, 0x0B, 0x01, 0x00, - 0x0D, 0x03, 0x05, 0x00, 0x05, 0x94, 0xC5, 0xD4, - 0x09, 0x05, 0x01, 0x00, 0xC2, 0x94, 0x01, 0xD4, - 0x42, 0x02, 0xC1, 0x96, 0x0A, 0x65, 0xC0, 0x7A, - 0x02, 0x99, 0xC4, 0x92, 0x41, 0xA2, 0xC4, 0xD2, - 0xC5, 0x98, 0x1C, 0xD9, 0x2A, 0x86, 0x01, 0x98, - 0x1C, 0xD9, 0x2B, 0x86, 0x1B, 0xD7, 0x2C, 0x86, - 0x00, 0xEE, 0x09, 0xB3, 0xFE, 0xFF, 0xC2, 0xD2, - 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, - 0x41, 0x20, 0x08, 0x0B, 0x01, 0x00, 0x40, 0xF0, - 0xE5, 0xEE, 0x11, 0x93, 0xD8, 0xF7, 0x41, 0x42, - 0x02, 0x5E, 0x0F, 0x9F, 0xAE, 0xEE, 0x40, 0xF1, - 0x40, 0x92, 0x19, 0xD3, 0xD8, 0xF7, 0xC5, 0x92, - 0x41, 0x92, 0x19, 0xD3, 0x00, 0x83, 0x40, 0x92, - 0x19, 0xD3, 0x00, 0x83, 0x0F, 0x9F, 0x95, 0xF8, - 0x0F, 0x9F, 0x99, 0xEE, 0x42, 0x42, 0x02, 0x5E, - 0x0F, 0x9F, 0x99, 0xEE, 0x40, 0x92, 0x19, 0xD3, - 0xD8, 0xF7, 0x09, 0x93, 0xC7, 0xF7, 0x19, 0xD3, - 0x91, 0xEC, 0x40, 0xF0, 0x5F, 0xF2, 0x09, 0x63, - 0x00, 0x80, 0x19, 0xD3, 0xF2, 0xBD, 0x0F, 0x9F, - 0x99, 0xEE, 0x41, 0x00, 0x88, 0x98, 0x90, 0x9A, - 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x40, 0x92, - 0x19, 0xD3, 0x12, 0x95, 0x19, 0xD3, 0x10, 0x95, - 0x19, 0xD3, 0x02, 0x80, 0x19, 0xD3, 0x03, 0x82, - 0x09, 0x93, 0xC7, 0xF7, 0x19, 0xD3, 0x91, 0xEC, - 0x40, 0xF0, 0x5F, 0xF2, 0x40, 0xF0, 0xDE, 0xF3, - 0x11, 0x93, 0x04, 0xEC, 0x42, 0x42, 0x02, 0x5E, - 0x0F, 0x9F, 0xE3, 0xEE, 0x40, 0x92, 0x19, 0xD3, - 0x04, 0xEC, 0x40, 0xF0, 0x38, 0xF2, 0x88, 0x98, - 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, - 0x11, 0x93, 0x44, 0x96, 0x09, 0xB3, 0xFF, 0xFD, - 0x19, 0xD3, 0x44, 0x96, 0x40, 0xF0, 0x90, 0xF7, - 0x6E, 0x92, 0x19, 0xD3, 0x05, 0x84, 0x40, 0xF0, - 0xC4, 0xEE, 0x4B, 0x62, 0x0A, 0x95, 0x2E, 0xEE, - 0xD1, 0xD4, 0x0B, 0x97, 0x2B, 0xEE, 0xD1, 0xD6, - 0x0A, 0x95, 0x00, 0xEE, 0xD1, 0xD4, 0x0B, 0x97, - 0x2F, 0xEE, 0xD1, 0xD6, 0x0A, 0x95, 0x34, 0xEE, - 0xD1, 0xD4, 0x0B, 0x97, 0x39, 0xEE, 0xD1, 0xD6, - 0x0A, 0x95, 0x3E, 0xEE, 0xD1, 0xD4, 0x0B, 0x97, - 0x43, 0xEE, 0xD1, 0xD6, 0x0A, 0x95, 0x48, 0xEE, - 0xD1, 0xD4, 0x0B, 0x97, 0x4D, 0xEE, 0xD1, 0xD6, - 0x0A, 0x95, 0x4E, 0xEE, 0xC1, 0xD4, 0x0A, 0x65, - 0x00, 0x44, 0x02, 0x97, 0xC3, 0x92, 0x44, 0xA2, - 0xC2, 0xD2, 0x43, 0xF1, 0x09, 0x93, 0x01, 0x3F, - 0x19, 0xD3, 0xC0, 0x85, 0x11, 0x93, 0x44, 0x96, - 0x09, 0xB3, 0xFF, 0xFC, 0x19, 0xD3, 0x44, 0x96, - 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, - 0x01, 0x00, 0x0D, 0x03, 0x03, 0x00, 0x03, 0x96, - 0x41, 0x02, 0x03, 0x99, 0xC4, 0x94, 0x42, 0x04, - 0xC1, 0x04, 0xC2, 0x94, 0xC3, 0xD4, 0x88, 0x98, - 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, - 0x40, 0x92, 0x19, 0xD3, 0x94, 0xEC, 0x13, 0x97, - 0x95, 0xEC, 0x1B, 0xD7, 0x02, 0x80, 0x11, 0x93, - 0x99, 0xEC, 0x19, 0xD3, 0x7C, 0x96, 0x0B, 0x97, - 0xA0, 0x00, 0x1B, 0xD7, 0x6E, 0xEC, 0x0A, 0x65, - 0x0E, 0x42, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, - 0xFF, 0xBF, 0x11, 0xA3, 0x9A, 0xEC, 0xC2, 0xD2, - 0x0A, 0x65, 0xEB, 0x43, 0x02, 0x97, 0xC3, 0x92, - 0x09, 0xA3, 0xC0, 0x00, 0xC2, 0xD2, 0x0A, 0x65, - 0xE9, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, - 0xBF, 0xFF, 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A, - 0x88, 0xDA, 0x47, 0x20, 0x08, 0x0B, 0x01, 0x00, - 0x14, 0x99, 0x03, 0x80, 0x0C, 0xB3, 0x00, 0x10, - 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x97, 0xF0, - 0x11, 0x93, 0x9F, 0xEC, 0x41, 0x02, 0x19, 0xD3, - 0x9F, 0xEC, 0x11, 0x93, 0xD6, 0xF7, 0x40, 0x42, - 0x02, 0x4E, 0x0F, 0x9F, 0x84, 0xEF, 0x0A, 0x65, - 0xFE, 0x7F, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3, - 0x00, 0x04, 0xC2, 0xD2, 0x0F, 0x9F, 0xB1, 0xF0, - 0x11, 0x93, 0x94, 0xEC, 0x02, 0xD2, 0x40, 0x42, - 0x02, 0x5E, 0x0F, 0x9F, 0xD0, 0xEF, 0x41, 0x92, - 0x19, 0xD3, 0x94, 0xEC, 0x19, 0xD3, 0x9F, 0xEC, - 0x12, 0x95, 0x02, 0x80, 0x1A, 0xD5, 0x95, 0xEC, - 0x13, 0x97, 0x7C, 0x96, 0x1B, 0xD7, 0x99, 0xEC, - 0x0A, 0x65, 0x0E, 0x42, 0x02, 0x97, 0xC3, 0x92, - 0x09, 0xB3, 0x00, 0x40, 0x19, 0xD3, 0x9A, 0xEC, - 0x09, 0x63, 0x00, 0x40, 0xC2, 0xD2, 0x02, 0x94, - 0x1A, 0xD5, 0x7C, 0x96, 0x0C, 0xB3, 0x00, 0x08, - 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0xB0, 0xEF, - 0x0C, 0xB3, 0xFF, 0x07, 0x0F, 0x9F, 0xB4, 0xEF, - 0x11, 0x93, 0x06, 0x80, 0x09, 0xB3, 0xFF, 0x07, - 0x09, 0x03, 0x00, 0xA0, 0x19, 0xD3, 0x97, 0xEC, - 0x40, 0x98, 0x0B, 0x97, 0x9C, 0xEC, 0x04, 0x95, - 0x03, 0x05, 0x14, 0x03, 0x97, 0xEC, 0x46, 0x02, - 0xC1, 0x92, 0xC2, 0xD2, 0x41, 0x08, 0x42, 0x48, - 0x02, 0x9E, 0x0F, 0x9F, 0xBB, 0xEF, 0x11, 0x93, - 0x97, 0xEC, 0xC1, 0x92, 0xC5, 0xD2, 0x5F, 0xB2, - 0x19, 0xD3, 0x9B, 0xEC, 0x0F, 0x9F, 0xD3, 0xEF, - 0x13, 0x97, 0x98, 0xEC, 0xC5, 0xD6, 0x11, 0x93, - 0x03, 0x80, 0x09, 0xB3, 0x00, 0x08, 0x40, 0x42, - 0x02, 0x4E, 0x0F, 0x9F, 0xE9, 0xEF, 0x11, 0x93, - 0xDC, 0xF7, 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7, - 0x11, 0x93, 0xDB, 0xF7, 0x09, 0xA3, 0x00, 0x10, - 0x19, 0xD3, 0xDB, 0xF7, 0x40, 0x98, 0x1C, 0xD9, - 0x9B, 0xEC, 0x12, 0x95, 0x9B, 0xEC, 0x40, 0x44, - 0x02, 0x4E, 0x0F, 0x9F, 0x86, 0xF0, 0x0A, 0xB3, - 0x08, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, - 0x07, 0xF0, 0x0A, 0xB3, 0x07, 0x00, 0x09, 0x05, - 0xA9, 0xEC, 0xC2, 0x94, 0x01, 0xD4, 0x09, 0x03, - 0xA1, 0xEC, 0xC1, 0x92, 0x19, 0xD3, 0x9B, 0xEC, - 0xC5, 0x94, 0x0A, 0xB5, 0x00, 0xFF, 0x01, 0xA5, - 0xC5, 0xD4, 0x0F, 0x9F, 0x13, 0xF0, 0x0A, 0x05, - 0xFF, 0xFF, 0x0A, 0x03, 0xB1, 0xEC, 0xC1, 0x92, - 0x01, 0xD2, 0x1A, 0xD5, 0x9B, 0xEC, 0xC5, 0x96, - 0x0B, 0x07, 0xFF, 0xFF, 0xC5, 0xD6, 0x11, 0x93, - 0x97, 0xEC, 0xC5, 0x98, 0xC1, 0xD8, 0x11, 0x93, - 0x97, 0xEC, 0x09, 0x05, 0x0B, 0x00, 0x03, 0xD4, - 0xC2, 0x96, 0x06, 0xD6, 0x7B, 0x95, 0x7A, 0x95, - 0x4C, 0x02, 0xC1, 0x92, 0x59, 0x93, 0x59, 0x93, - 0x01, 0xA5, 0x01, 0x98, 0x0C, 0xF5, 0x7B, 0x93, - 0x09, 0x09, 0x01, 0x00, 0x06, 0x92, 0x09, 0xB3, - 0xFF, 0x00, 0x04, 0xD2, 0x5C, 0x93, 0x59, 0x93, - 0x04, 0x94, 0x01, 0xA5, 0x03, 0x96, 0xC3, 0xD4, - 0x11, 0x93, 0x97, 0xEC, 0x4C, 0x02, 0x05, 0xD2, - 0xC1, 0x92, 0x09, 0xB3, 0x00, 0xFF, 0x7C, 0x95, - 0x7A, 0x95, 0x02, 0xA3, 0x05, 0x98, 0xC4, 0xD2, - 0x12, 0x95, 0x97, 0xEC, 0x45, 0x04, 0x02, 0x97, - 0xC3, 0x92, 0x09, 0xA3, 0x00, 0x01, 0xC2, 0xD2, - 0x12, 0x95, 0x9B, 0xEC, 0x0A, 0xB3, 0x08, 0x00, - 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x5B, 0xF0, - 0x12, 0x95, 0x97, 0xEC, 0x4A, 0x04, 0x02, 0x99, - 0xC4, 0x92, 0x01, 0x98, 0x0C, 0xF3, 0x7B, 0x93, - 0x41, 0x02, 0x0F, 0x9F, 0x7C, 0xF0, 0x43, 0x44, - 0x02, 0x8E, 0x0F, 0x9F, 0x7D, 0xF0, 0x11, 0x93, - 0x97, 0xEC, 0x42, 0x02, 0x0A, 0x05, 0xFF, 0xFF, - 0xC1, 0xD4, 0x11, 0x93, 0x97, 0xEC, 0x4A, 0x02, - 0x12, 0x95, 0x60, 0x96, 0xC1, 0xD4, 0x12, 0x95, - 0x97, 0xEC, 0x4B, 0x04, 0x02, 0x97, 0xC3, 0x92, - 0x09, 0xB3, 0x1F, 0xFF, 0xC2, 0xD2, 0x12, 0x95, - 0x97, 0xEC, 0x4B, 0x04, 0x11, 0x93, 0x62, 0x96, - 0x41, 0x93, 0x59, 0x93, 0x02, 0x99, 0xC4, 0xA2, - 0xC2, 0xD2, 0xC5, 0x92, 0x19, 0xD3, 0x98, 0xEC, - 0x0A, 0x95, 0x0C, 0x02, 0x1A, 0xD5, 0x02, 0x80, - 0x0F, 0x9F, 0xB1, 0xF0, 0x09, 0x63, 0xFE, 0x7F, - 0x01, 0x97, 0xC3, 0x94, 0x0A, 0xA5, 0x00, 0x04, - 0xC1, 0xD4, 0x11, 0x93, 0x9F, 0xEC, 0x09, 0xA3, - 0x00, 0x01, 0x19, 0xD3, 0x9F, 0xEC, 0x40, 0xF0, - 0x39, 0xEF, 0x0F, 0x9F, 0xB1, 0xF0, 0x11, 0x93, - 0x94, 0xEC, 0x41, 0x42, 0x02, 0x5E, 0x0F, 0x9F, - 0xA6, 0xF0, 0x40, 0xF0, 0x39, 0xEF, 0x11, 0x93, - 0x95, 0xEC, 0x44, 0xB2, 0x40, 0x42, 0x02, 0x4E, - 0x0F, 0x9F, 0xB1, 0xF0, 0x48, 0x98, 0x1C, 0xD9, - 0x02, 0x80, 0x11, 0x93, 0x91, 0xEC, 0x41, 0x22, - 0x0A, 0x95, 0xB1, 0xF0, 0x88, 0xD4, 0x88, 0xDC, - 0x91, 0x9A, 0x47, 0x00, 0x88, 0x98, 0x90, 0x9A, - 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x11, 0x93, - 0x04, 0x82, 0x48, 0xB2, 0x40, 0x42, 0x02, 0x4E, - 0x0F, 0x9F, 0xC8, 0xF0, 0x0A, 0x65, 0xFD, 0x7D, - 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, 0xFF, 0xFE, - 0xC2, 0xD2, 0x41, 0x92, 0x19, 0xD3, 0xBF, 0xEC, - 0x11, 0x93, 0x04, 0x82, 0x43, 0xB2, 0x12, 0x95, - 0x03, 0x82, 0x02, 0xB3, 0x40, 0x42, 0x02, 0x4E, - 0x0F, 0x9F, 0xEF, 0xF0, 0x0A, 0xB3, 0x00, 0xFF, - 0x48, 0xA2, 0x19, 0xD3, 0x03, 0x82, 0x40, 0xF0, - 0xEB, 0xF3, 0x11, 0x93, 0xBF, 0xEC, 0x41, 0x42, - 0x02, 0x5E, 0x0F, 0x9F, 0xEF, 0xF0, 0x11, 0x93, - 0x07, 0x82, 0x11, 0x43, 0x03, 0xEC, 0x02, 0x0E, - 0x0F, 0x9F, 0xEF, 0xF0, 0x11, 0x93, 0x03, 0x82, - 0x09, 0xA3, 0x00, 0x01, 0x19, 0xD3, 0x03, 0x82, - 0x40, 0x96, 0x1B, 0xD7, 0xBF, 0xEC, 0x88, 0x98, - 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, - 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, - 0x01, 0x00, 0x11, 0x93, 0x20, 0xBC, 0xC8, 0xD2, - 0x40, 0xF0, 0x48, 0xF1, 0x41, 0x00, 0x88, 0x98, - 0x90, 0x9A, 0x88, 0xDA, 0x42, 0x20, 0x08, 0x0B, - 0x01, 0x00, 0x0D, 0x03, 0x05, 0x00, 0x05, 0x94, - 0x41, 0x02, 0xC1, 0x92, 0x01, 0x97, 0xC3, 0x96, - 0xC2, 0xD6, 0x0A, 0x45, 0x00, 0x95, 0x02, 0x5E, - 0x0F, 0x9F, 0x45, 0xF1, 0xC1, 0x92, 0x41, 0xB2, - 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x45, 0xF1, - 0x11, 0x93, 0xC0, 0xEC, 0x40, 0x42, 0x02, 0x5E, - 0x0F, 0x9F, 0x45, 0xF1, 0x41, 0x98, 0x1C, 0xD9, - 0xC0, 0xEC, 0x12, 0x95, 0x02, 0x80, 0x01, 0xD4, - 0x40, 0xF0, 0x56, 0xF2, 0x0B, 0x67, 0xFD, 0x7D, - 0x03, 0x99, 0xC4, 0x92, 0x0C, 0x99, 0x96, 0x03, - 0x1C, 0xD9, 0x06, 0x82, 0x41, 0x98, 0x1C, 0xD9, - 0x02, 0x82, 0x42, 0x98, 0x1C, 0xD9, 0x05, 0x82, - 0x0C, 0x69, 0x80, 0x7F, 0x1C, 0xD9, 0x00, 0xB0, - 0x09, 0xA3, 0x00, 0x01, 0xC3, 0xD2, 0x01, 0x94, - 0x0A, 0xB3, 0x04, 0x00, 0x40, 0x42, 0x02, 0x4E, - 0x0F, 0x9F, 0x43, 0xF1, 0x42, 0xA4, 0x1A, 0xD5, - 0x02, 0x80, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A, - 0x88, 0xDA, 0x42, 0x20, 0x08, 0x0B, 0x01, 0x00, - 0x05, 0x92, 0xC5, 0xD2, 0x60, 0xB2, 0x40, 0x42, - 0x02, 0x4E, 0x0F, 0x9F, 0x55, 0xF1, 0x40, 0xF0, - 0x35, 0xF7, 0xC5, 0x94, 0x0A, 0xB3, 0x10, 0x00, - 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x5E, 0xF1, - 0x40, 0xF0, 0x23, 0xF6, 0xC5, 0x96, 0x0B, 0xB3, - 0x40, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, - 0x67, 0xF1, 0x40, 0xF0, 0x5D, 0xF5, 0xC5, 0x94, - 0x0A, 0xB3, 0x01, 0x00, 0x40, 0x42, 0x02, 0x4E, - 0x0F, 0x9F, 0xC8, 0xF1, 0x13, 0x97, 0x21, 0xBC, - 0x01, 0xD6, 0x0B, 0xB3, 0x02, 0x00, 0x40, 0x42, - 0x02, 0x4E, 0x0F, 0x9F, 0x79, 0xF1, 0x40, 0xF0, - 0x62, 0xFB, 0x01, 0x94, 0x0A, 0xB3, 0x04, 0x00, - 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x82, 0xF1, - 0x40, 0xF0, 0x6C, 0xFB, 0x01, 0x96, 0x0B, 0xB3, - 0x01, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, - 0xA2, 0xF1, 0x40, 0xF0, 0xB0, 0xFA, 0x41, 0x92, - 0x19, 0xD3, 0xD5, 0xF7, 0x11, 0x93, 0x03, 0xEC, - 0x09, 0x43, 0x40, 0x00, 0x02, 0x5E, 0x0F, 0x9F, - 0x98, 0xF1, 0x40, 0x94, 0x1A, 0xD5, 0xD5, 0xF7, - 0x11, 0x93, 0x00, 0xEC, 0x40, 0x42, 0x02, 0x4E, - 0x0F, 0x9F, 0xAB, 0xF1, 0x40, 0xF0, 0x38, 0xF2, - 0x0F, 0x9F, 0xAB, 0xF1, 0x01, 0x96, 0x0B, 0xB3, - 0x08, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, - 0xAB, 0xF1, 0x40, 0xF0, 0x7C, 0xFB, 0x01, 0x94, - 0x0A, 0xB3, 0x10, 0x00, 0x40, 0x42, 0x02, 0x4E, - 0x0F, 0x9F, 0xB4, 0xF1, 0x40, 0xF0, 0x87, 0xFB, - 0x11, 0x93, 0x10, 0xEC, 0x42, 0x42, 0x02, 0x5E, - 0x0F, 0x9F, 0xBF, 0xF1, 0x44, 0x96, 0x1B, 0xD7, - 0x0B, 0xBC, 0x0F, 0x9F, 0xC5, 0xF1, 0x41, 0x42, - 0x02, 0x5E, 0x0F, 0x9F, 0xC5, 0xF1, 0x19, 0xD3, - 0x0B, 0xBC, 0x40, 0x92, 0x19, 0xD3, 0x10, 0xEC, - 0xC5, 0x94, 0x0A, 0xB3, 0x80, 0x00, 0x40, 0x42, - 0x02, 0x4E, 0x0F, 0x9F, 0x12, 0xF2, 0x13, 0x97, - 0x28, 0xBC, 0x01, 0xD6, 0x0B, 0xB3, 0x40, 0x00, - 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0xDA, 0xF1, - 0x40, 0xF0, 0x18, 0xF7, 0x01, 0x94, 0x0A, 0xB3, - 0x02, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, - 0xED, 0xF1, 0x40, 0xF0, 0xC4, 0xEE, 0x40, 0xF0, - 0x8F, 0xFB, 0x40, 0xF0, 0x1B, 0xF2, 0x40, 0x96, - 0x1B, 0xD7, 0x00, 0xEC, 0x41, 0x92, 0x19, 0xD3, - 0xD8, 0xF7, 0x01, 0x94, 0x0A, 0xB3, 0x04, 0x00, - 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x09, 0xF2, - 0x40, 0xF0, 0x9E, 0xFB, 0x09, 0x63, 0x00, 0x44, - 0x01, 0x97, 0xC3, 0x94, 0x48, 0xA4, 0xC1, 0xD4, - 0x00, 0xEE, 0x40, 0x92, 0x19, 0xD3, 0x12, 0x95, - 0x19, 0xD3, 0x10, 0x95, 0x19, 0xD3, 0x02, 0x80, - 0x19, 0xD3, 0x03, 0x82, 0x41, 0x92, 0x19, 0xD3, - 0xD8, 0xF7, 0x01, 0x94, 0x0A, 0xB3, 0x08, 0x00, - 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x12, 0xF2, - 0x40, 0xF0, 0xAE, 0xFB, 0x0A, 0x65, 0x00, 0x44, - 0x02, 0x97, 0xC3, 0x92, 0x44, 0xA2, 0xC2, 0xD2, - 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, - 0x08, 0x0B, 0x01, 0x00, 0x09, 0x63, 0x00, 0x40, - 0x19, 0xD3, 0xF2, 0xBD, 0x0A, 0x65, 0xEA, 0x43, - 0x02, 0x97, 0xC3, 0x92, 0x44, 0xA2, 0xC2, 0xD2, - 0x0A, 0x65, 0xE9, 0x43, 0x02, 0x97, 0xC3, 0x92, - 0x09, 0xA3, 0x40, 0x00, 0xC2, 0xD2, 0x0A, 0x65, - 0xEB, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3, - 0xC0, 0x00, 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A, - 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x09, 0x63, - 0x00, 0x80, 0x19, 0xD3, 0xF2, 0xBD, 0x0A, 0x65, - 0xE8, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3, - 0xC0, 0x00, 0xC2, 0xD2, 0x0A, 0x65, 0xEB, 0x43, - 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, 0xBF, 0xFF, - 0xC2, 0xD2, 0x0A, 0x65, 0xEA, 0x43, 0x02, 0x97, - 0xC3, 0x92, 0x09, 0xB3, 0xFB, 0xFF, 0xC2, 0xD2, - 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, - 0x01, 0x00, 0x09, 0x93, 0x00, 0x01, 0x19, 0xD3, - 0x02, 0x80, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, - 0x08, 0x0B, 0x01, 0x00, 0x09, 0x93, 0x00, 0x09, - 0x19, 0xD3, 0x02, 0x80, 0x40, 0xF0, 0x56, 0xF2, - 0x40, 0x92, 0x19, 0xD3, 0x94, 0xEC, 0xC8, 0xD2, - 0x09, 0x93, 0x91, 0xEC, 0xC8, 0xD2, 0x40, 0xF0, - 0x2A, 0xEF, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A, - 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x40, 0xF0, - 0x3B, 0xF5, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, - 0x85, 0xF2, 0x0A, 0x65, 0xFE, 0x7F, 0x02, 0x97, - 0xC3, 0x92, 0x44, 0xA2, 0xC2, 0xD2, 0x0F, 0x9F, - 0x92, 0xF2, 0x40, 0xF0, 0x94, 0xF2, 0x40, 0x42, - 0x02, 0x5E, 0x0F, 0x9F, 0x92, 0xF2, 0xC8, 0xD2, - 0x09, 0x93, 0x91, 0xEC, 0xC8, 0xD2, 0x40, 0xF0, - 0x2A, 0xEF, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A, - 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x11, 0x93, - 0xF1, 0xBD, 0x19, 0xD3, 0xB6, 0xEC, 0x11, 0x93, - 0xB4, 0xEC, 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, - 0xAC, 0xF2, 0x09, 0x63, 0x00, 0x80, 0x01, 0x97, - 0xC3, 0x94, 0x0A, 0x07, 0x07, 0x00, 0xC1, 0xD6, - 0x0A, 0x05, 0x00, 0xA0, 0x1A, 0xD5, 0x96, 0xEC, - 0x11, 0x93, 0xB6, 0xEC, 0x19, 0xD3, 0x01, 0x80, - 0x0A, 0x65, 0xFE, 0x7F, 0x02, 0x97, 0xC3, 0x92, - 0x41, 0xA2, 0xC2, 0xD2, 0x40, 0x92, 0x88, 0x98, - 0x90, 0x9A, 0x88, 0xDA, 0x41, 0x20, 0x08, 0x0B, - 0x01, 0x00, 0x13, 0x97, 0xB4, 0xEC, 0x40, 0x46, - 0x02, 0x5E, 0x0F, 0x9F, 0x2C, 0xF3, 0x12, 0x95, - 0x96, 0xEC, 0x0A, 0x03, 0x07, 0x00, 0xC1, 0x92, - 0xC2, 0xD2, 0x11, 0x93, 0x96, 0xEC, 0x09, 0x05, - 0x01, 0x00, 0x48, 0x02, 0xC1, 0x92, 0xC2, 0xD2, - 0x11, 0x93, 0x96, 0xEC, 0x4E, 0x02, 0xC1, 0x94, - 0xC5, 0xD6, 0xC5, 0x92, 0x11, 0x07, 0x96, 0xEC, - 0x0B, 0x03, 0x0F, 0x00, 0xC1, 0x98, 0x46, 0x06, - 0x7A, 0x93, 0x79, 0x93, 0x5C, 0x95, 0x5A, 0x95, - 0x02, 0xA3, 0xC3, 0xD2, 0x04, 0x95, 0xC5, 0x96, - 0x41, 0x06, 0xC5, 0xD6, 0x42, 0x46, 0x02, 0x9E, - 0x0F, 0x9F, 0xD5, 0xF2, 0x11, 0x93, 0x96, 0xEC, - 0x09, 0x05, 0x05, 0x00, 0x41, 0x02, 0xC1, 0x92, - 0xC2, 0xD2, 0x11, 0x93, 0x96, 0xEC, 0xC1, 0x92, - 0x09, 0xB5, 0x1F, 0x00, 0x43, 0x44, 0x02, 0x8E, - 0x0F, 0x9F, 0x02, 0xF3, 0x40, 0x44, 0x02, 0x4E, - 0x0F, 0x9F, 0x03, 0xF3, 0x0A, 0x05, 0xFF, 0xFF, - 0x0F, 0x9F, 0x03, 0xF3, 0x43, 0x94, 0x11, 0x93, - 0x96, 0xEC, 0x42, 0x02, 0xC1, 0xD4, 0x11, 0x93, - 0x96, 0xEC, 0x49, 0x02, 0xC1, 0x92, 0x19, 0xD3, - 0xB4, 0xEC, 0x09, 0x05, 0xF2, 0xFF, 0x1A, 0xD5, - 0x92, 0xEC, 0x09, 0x43, 0xD0, 0x07, 0x02, 0x9E, - 0x0F, 0x9F, 0x2C, 0xF3, 0x11, 0x93, 0xDC, 0xF7, - 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7, 0x11, 0x93, - 0xDB, 0xF7, 0x09, 0xA3, 0x40, 0x00, 0x19, 0xD3, - 0xDB, 0xF7, 0x09, 0x63, 0x00, 0x80, 0x01, 0x95, - 0xC2, 0x94, 0x1A, 0xD5, 0xB5, 0xEC, 0x40, 0x96, - 0x1B, 0xD7, 0xB4, 0xEC, 0x0F, 0x9F, 0x92, 0xF3, - 0x11, 0x93, 0x92, 0xEC, 0x12, 0x95, 0xB6, 0xEC, - 0x02, 0x43, 0x02, 0x8E, 0x0F, 0x9F, 0x7A, 0xF3, - 0x02, 0x0E, 0x0F, 0x9F, 0x4D, 0xF3, 0x11, 0x93, - 0xDC, 0xF7, 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7, - 0x11, 0x93, 0xDB, 0xF7, 0x09, 0xA3, 0x80, 0x00, - 0x19, 0xD3, 0xDB, 0xF7, 0x09, 0x63, 0x00, 0x80, - 0x01, 0x95, 0xC2, 0x94, 0x1A, 0xD5, 0xB5, 0xEC, - 0x40, 0x96, 0x1B, 0xD7, 0xB4, 0xEC, 0x0F, 0x9F, - 0x92, 0xF3, 0x11, 0x93, 0x03, 0x80, 0x09, 0xB3, - 0x00, 0x40, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, - 0x5F, 0xF3, 0x11, 0x93, 0xC0, 0xEC, 0x40, 0x42, - 0x02, 0x5E, 0x0F, 0x9F, 0x5F, 0xF3, 0x40, 0xF0, - 0xA6, 0xF3, 0x0F, 0x9F, 0x94, 0xF3, 0x41, 0x92, - 0xC8, 0xD2, 0x0A, 0x95, 0x91, 0xEC, 0xC8, 0xD4, - 0x40, 0xF0, 0x2A, 0xEF, 0x42, 0x00, 0x11, 0x93, - 0xC0, 0xEC, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, - 0x72, 0xF3, 0x42, 0x96, 0x1B, 0xD7, 0xC0, 0xEC, - 0x0F, 0x9F, 0x94, 0xF3, 0x0A, 0x65, 0xFE, 0x7F, - 0x02, 0x97, 0xC3, 0x92, 0x42, 0xA2, 0xC2, 0xD2, - 0x0F, 0x9F, 0x94, 0xF3, 0x12, 0x45, 0x03, 0xEC, - 0x02, 0x4E, 0x0F, 0x9F, 0x8C, 0xF3, 0x11, 0x93, - 0xDC, 0xF7, 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7, - 0x11, 0x93, 0xDB, 0xF7, 0x09, 0xA3, 0x00, 0x08, - 0x19, 0xD3, 0xDB, 0xF7, 0x1A, 0xD5, 0x92, 0xEC, - 0x11, 0x93, 0x92, 0xEC, 0x19, 0x25, 0x92, 0xEC, - 0x09, 0x63, 0x00, 0x80, 0x19, 0xD3, 0xF2, 0xBD, - 0x41, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, - 0x08, 0x0B, 0x01, 0x00, 0x40, 0xF0, 0xA6, 0xF3, - 0x40, 0x92, 0xC8, 0xD2, 0x09, 0x93, 0x91, 0xEC, - 0xC8, 0xD2, 0x40, 0xF0, 0x2A, 0xEF, 0x42, 0x00, - 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, - 0x01, 0x00, 0x11, 0x93, 0xD7, 0xF7, 0x40, 0x42, - 0x02, 0x4E, 0x0F, 0x9F, 0xB6, 0xF3, 0x0A, 0x65, - 0xBC, 0x69, 0x02, 0x97, 0xC3, 0x92, 0x09, 0x83, - 0x00, 0x02, 0xC2, 0xD2, 0x11, 0x93, 0x03, 0x80, - 0x09, 0xB3, 0x00, 0x40, 0x40, 0x42, 0x02, 0x5E, - 0x0F, 0x9F, 0xC9, 0xF3, 0x11, 0x93, 0xDC, 0xF7, - 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7, 0x11, 0x93, - 0xDB, 0xF7, 0x09, 0xA3, 0x00, 0x20, 0x19, 0xD3, - 0xDB, 0xF7, 0x11, 0x93, 0xB5, 0xEC, 0x19, 0xD3, - 0x04, 0x80, 0x12, 0x95, 0xB4, 0xEC, 0x1A, 0xD5, - 0x05, 0x80, 0x09, 0x63, 0x00, 0x80, 0x01, 0x97, - 0xC3, 0x96, 0x1B, 0xD7, 0xB5, 0xEC, 0x40, 0x94, - 0x1A, 0xD5, 0xB4, 0xEC, 0x19, 0xD3, 0xF2, 0xBD, - 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, - 0x01, 0x00, 0x09, 0x93, 0x96, 0x03, 0x19, 0xD3, - 0x06, 0x82, 0x09, 0x93, 0x00, 0x01, 0x19, 0xD3, - 0x03, 0x82, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, - 0x47, 0x20, 0x08, 0x0B, 0x01, 0x00, 0x11, 0x93, - 0x01, 0x82, 0xC5, 0xD2, 0x40, 0x94, 0x01, 0xD4, - 0x13, 0x97, 0xB8, 0xEC, 0x02, 0xD6, 0x03, 0x95, - 0x0C, 0x99, 0xBB, 0xEC, 0x04, 0x05, 0x13, 0x97, - 0x03, 0xEC, 0x01, 0x27, 0x02, 0x99, 0xC4, 0x92, - 0x03, 0x03, 0xC2, 0xD2, 0x14, 0x99, 0xBA, 0xEC, - 0x03, 0x09, 0x1C, 0xD9, 0xBA, 0xEC, 0x12, 0x95, - 0x04, 0x82, 0x0A, 0xB3, 0x02, 0x00, 0x40, 0x42, - 0x02, 0x4E, 0x0F, 0x9F, 0x29, 0xF5, 0x01, 0x92, - 0x03, 0xD2, 0x0A, 0xA3, 0x02, 0x00, 0x19, 0xD3, - 0x04, 0x82, 0x02, 0x96, 0x0B, 0x05, 0x01, 0x00, - 0x1A, 0xD5, 0xB8, 0xEC, 0xC5, 0x92, 0x43, 0x42, - 0x02, 0x9E, 0x0F, 0x9F, 0x37, 0xF4, 0x42, 0x44, - 0x02, 0x8E, 0x0F, 0x9F, 0x37, 0xF4, 0x11, 0x93, - 0xBF, 0xEC, 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, - 0x37, 0xF4, 0x0C, 0x49, 0xD3, 0x08, 0x02, 0x8E, - 0x0F, 0x9F, 0x37, 0xF4, 0x11, 0x63, 0x07, 0x82, - 0x11, 0xA3, 0x07, 0x82, 0x71, 0x93, 0x79, 0x93, - 0x79, 0x93, 0x79, 0x93, 0x03, 0xD2, 0xC5, 0x94, - 0x0A, 0xB5, 0xFC, 0xFF, 0x04, 0xD4, 0x03, 0x96, - 0x40, 0x46, 0x02, 0x5E, 0x0F, 0x9F, 0x46, 0xF4, - 0x11, 0x93, 0xB8, 0xEC, 0x41, 0x42, 0x02, 0x8E, - 0x0F, 0x9F, 0x4D, 0xF4, 0xC5, 0x98, 0x0C, 0x03, - 0xFF, 0xFF, 0x42, 0x42, 0x02, 0x8E, 0x0F, 0x9F, - 0x74, 0xF4, 0x0A, 0x95, 0xBB, 0xEC, 0x42, 0x92, - 0x19, 0xD3, 0xB9, 0xEC, 0xC5, 0x96, 0x43, 0x46, - 0x02, 0x9E, 0x0F, 0x9F, 0x66, 0xF4, 0x0B, 0x07, - 0xFC, 0xFF, 0xC5, 0xD6, 0xD2, 0x98, 0x1C, 0xD9, - 0xC8, 0xBC, 0xD2, 0x96, 0x1B, 0xD7, 0xCA, 0xBC, - 0x09, 0x03, 0xFF, 0xFF, 0x40, 0x42, 0x02, 0x5E, - 0x0F, 0x9F, 0x52, 0xF4, 0x19, 0xD3, 0xB9, 0xEC, - 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0x72, 0xF4, - 0x0A, 0x05, 0xFE, 0xFF, 0xCA, 0xD2, 0xC2, 0xD2, - 0x0F, 0x9F, 0x74, 0xF4, 0x1A, 0xD5, 0x93, 0xEC, - 0x03, 0x98, 0x40, 0x48, 0x02, 0x5E, 0x0F, 0x9F, - 0xA1, 0xF4, 0x11, 0x93, 0xB8, 0xEC, 0x41, 0x42, - 0x02, 0x9E, 0x0F, 0x9F, 0x84, 0xF4, 0x04, 0x94, - 0x48, 0x44, 0x02, 0x4E, 0x0F, 0x9F, 0x8F, 0xF4, - 0x41, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0xA1, 0xF4, - 0x11, 0x93, 0x04, 0x82, 0x41, 0xB2, 0x40, 0x42, - 0x02, 0x4E, 0x0F, 0x9F, 0xA1, 0xF4, 0x41, 0x96, - 0x01, 0xD6, 0x0A, 0x65, 0xBD, 0x43, 0x02, 0x99, - 0xC4, 0x92, 0x09, 0xA3, 0x80, 0x00, 0xC2, 0xD2, - 0x0A, 0x65, 0xE8, 0x43, 0x02, 0x97, 0xC3, 0x92, - 0x09, 0xB3, 0xBF, 0xFF, 0xC2, 0xD2, 0x0F, 0x9F, - 0xFA, 0xF4, 0xC5, 0x98, 0x43, 0x48, 0x02, 0x9E, - 0x0F, 0x9F, 0xFA, 0xF4, 0x4F, 0x96, 0x0C, 0xB3, - 0x01, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, - 0xAE, 0xF4, 0x47, 0x96, 0x11, 0x93, 0xB7, 0xEC, - 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0xD6, 0xF4, - 0x11, 0x93, 0xB8, 0xEC, 0x41, 0x42, 0x02, 0x5E, - 0x0F, 0x9F, 0xD6, 0xF4, 0x12, 0x95, 0x00, 0x82, - 0x0A, 0x05, 0xFF, 0xAF, 0x05, 0xD4, 0xC8, 0xD6, - 0xC8, 0xD2, 0x40, 0xF0, 0x7B, 0xF7, 0x42, 0x00, - 0x05, 0x96, 0xC3, 0x94, 0x01, 0xB5, 0x40, 0x44, - 0x02, 0x4E, 0x0F, 0x9F, 0xD6, 0xF4, 0x06, 0x98, - 0x50, 0x98, 0x1C, 0xD9, 0xA2, 0xBC, 0x40, 0x98, - 0x1C, 0xD9, 0xA2, 0xBC, 0x40, 0x92, 0x03, 0xD2, - 0x0F, 0x9F, 0xFF, 0xF4, 0x03, 0x94, 0x40, 0x44, - 0x02, 0x5E, 0x0F, 0x9F, 0xE3, 0xF4, 0x0A, 0x65, - 0x5E, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x48, 0xA2, - 0xC2, 0xD2, 0x0F, 0x9F, 0xFF, 0xF4, 0x11, 0x93, - 0xB8, 0xEC, 0x0C, 0x99, 0xBB, 0xEC, 0x04, 0x03, - 0x04, 0x96, 0x13, 0x25, 0x03, 0xEC, 0xC1, 0xD4, - 0x11, 0x93, 0xBA, 0xEC, 0x19, 0x05, 0xBA, 0xEC, - 0x1B, 0xD7, 0x01, 0x82, 0x0A, 0x65, 0xFD, 0x7D, - 0x02, 0x99, 0xC4, 0x92, 0x43, 0xA2, 0xC2, 0xD2, - 0x41, 0x92, 0x01, 0xD2, 0x03, 0x94, 0x40, 0x44, - 0x02, 0x5E, 0x0F, 0x9F, 0x13, 0xF5, 0x11, 0x93, - 0xB9, 0xEC, 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, - 0x0B, 0xF5, 0x19, 0xD3, 0xB8, 0xEC, 0x19, 0xD3, - 0xBA, 0xEC, 0x19, 0xD3, 0xBB, 0xEC, 0x03, 0x96, - 0x40, 0x46, 0x02, 0x5E, 0x0F, 0x9F, 0x13, 0xF5, - 0x41, 0x98, 0x1C, 0xD9, 0xB7, 0xEC, 0x11, 0x93, - 0xBF, 0xEC, 0x41, 0x42, 0x02, 0x5E, 0x0F, 0x9F, - 0x24, 0xF5, 0x11, 0x93, 0x00, 0x82, 0x19, 0xD3, - 0x02, 0x82, 0x0A, 0x65, 0xFD, 0x7D, 0x02, 0x97, - 0xC3, 0x92, 0x09, 0xA3, 0x00, 0x01, 0xC2, 0xD2, - 0x40, 0x98, 0x1C, 0xD9, 0xBF, 0xEC, 0x0F, 0x9F, - 0x2C, 0xF5, 0x01, 0x92, 0x19, 0xD3, 0xB7, 0xEC, - 0x01, 0x94, 0x40, 0x44, 0x02, 0x5E, 0x0F, 0x9F, - 0x38, 0xF5, 0x0A, 0x65, 0xEA, 0x43, 0x02, 0x97, - 0xC3, 0x92, 0x09, 0xB3, 0xFB, 0xFF, 0xC2, 0xD2, - 0x47, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, - 0x08, 0x0B, 0x01, 0x00, 0x12, 0x95, 0x03, 0x80, - 0x0A, 0xB3, 0x00, 0x40, 0x40, 0x42, 0x02, 0x4E, - 0x0F, 0x9F, 0x57, 0xF5, 0x0A, 0xB7, 0x00, 0x08, - 0x40, 0x46, 0x02, 0x5E, 0x0F, 0x9F, 0x5A, 0xF5, - 0x11, 0x93, 0x03, 0xEC, 0x41, 0x02, 0x09, 0xB3, - 0xFE, 0xFF, 0x12, 0x95, 0x07, 0x80, 0x01, 0x45, - 0x02, 0x8E, 0x0F, 0x9F, 0x5A, 0xF5, 0x41, 0x92, - 0x0F, 0x9F, 0x5B, 0xF5, 0x40, 0x92, 0x88, 0x98, - 0x90, 0x9A, 0x88, 0xDA, 0x41, 0x20, 0x08, 0x0B, - 0x01, 0x00, 0x0A, 0x65, 0xE9, 0x43, 0x02, 0x97, - 0xC3, 0x92, 0x09, 0xA3, 0x40, 0x00, 0xC2, 0xD2, - 0x13, 0x97, 0x6E, 0xEC, 0x0B, 0x47, 0xA0, 0x00, - 0x02, 0x5E, 0x0F, 0x9F, 0x86, 0xF5, 0x09, 0x63, - 0x08, 0x43, 0x0A, 0x65, 0xFF, 0x5F, 0x01, 0x99, - 0xC4, 0xD4, 0x0A, 0x95, 0x9B, 0xEC, 0xD2, 0x96, - 0x1B, 0xD7, 0xFA, 0xBC, 0xD2, 0x96, 0xC4, 0xD6, - 0xD2, 0x98, 0x1C, 0xD9, 0xFA, 0xBC, 0xD2, 0x96, - 0xC1, 0xD6, 0xC2, 0x94, 0x1A, 0xD5, 0xFA, 0xBC, - 0x0F, 0x9F, 0xC4, 0xF5, 0x0C, 0x69, 0xFF, 0x6F, - 0x1C, 0xD9, 0xF8, 0xBC, 0x0B, 0x47, 0x10, 0x95, - 0x02, 0x5E, 0x0F, 0x9F, 0x9E, 0xF5, 0x0A, 0x95, - 0x6F, 0xEC, 0x09, 0x63, 0x06, 0x43, 0x01, 0x99, - 0xC4, 0xD6, 0xD2, 0x96, 0x1B, 0xD7, 0xF8, 0xBC, - 0x0C, 0x69, 0xEE, 0x6A, 0xC1, 0xD8, 0xC2, 0x94, - 0x1A, 0xD5, 0xF8, 0xBC, 0x40, 0x92, 0xC5, 0xD2, - 0x11, 0x43, 0xC1, 0xEC, 0x02, 0x0E, 0x0F, 0x9F, - 0xC1, 0xF5, 0xC5, 0x94, 0x0A, 0x03, 0x71, 0xEC, - 0xC1, 0x94, 0x1A, 0xD5, 0xFA, 0xBC, 0x11, 0x93, - 0xC0, 0xEC, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, - 0xB3, 0xF5, 0x0A, 0x95, 0x6F, 0xEC, 0xC8, 0xD4, - 0x40, 0xF0, 0x9C, 0xF7, 0x19, 0xD3, 0xF8, 0xBC, - 0x41, 0x00, 0xC5, 0x96, 0x41, 0x06, 0xC5, 0xD6, - 0x13, 0x47, 0xC1, 0xEC, 0x02, 0x1E, 0x0F, 0x9F, - 0xA5, 0xF5, 0x40, 0x98, 0x1C, 0xD9, 0xFA, 0xBC, - 0x40, 0x92, 0x19, 0xD3, 0x6E, 0xEC, 0x19, 0xD3, - 0xC1, 0xEC, 0x0A, 0x65, 0x52, 0x43, 0x02, 0x97, - 0xC3, 0x92, 0x48, 0xA2, 0xC2, 0xD2, 0x0A, 0x65, - 0xEB, 0x43, 0x02, 0x99, 0xC4, 0x92, 0x09, 0xB3, - 0xBF, 0xFF, 0xC2, 0xD2, 0x41, 0x00, 0x88, 0x98, - 0x90, 0x9A, 0x88, 0xDA, 0x43, 0x20, 0x08, 0x0B, - 0x01, 0x00, 0x06, 0x92, 0x01, 0xD2, 0x0A, 0x65, - 0xF0, 0x6A, 0x0B, 0x97, 0x6F, 0xEC, 0x02, 0x99, - 0xC4, 0x98, 0xD3, 0xD8, 0x02, 0xD6, 0x0A, 0x03, - 0x02, 0x00, 0x01, 0x97, 0xC3, 0x98, 0x02, 0x96, - 0xC3, 0xD8, 0x01, 0x96, 0xC1, 0xD6, 0x1A, 0xD5, - 0x6E, 0xEC, 0xC5, 0x98, 0x14, 0x99, 0x6F, 0xEC, - 0xC2, 0xD8, 0x43, 0x00, 0x88, 0x98, 0x90, 0x9A, - 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x40, 0x92, - 0xC8, 0xD2, 0x40, 0xF0, 0xD9, 0xF5, 0x41, 0x00, - 0x11, 0x93, 0xC0, 0xEC, 0x40, 0x42, 0x02, 0x4E, - 0x0F, 0x9F, 0x13, 0xF6, 0x42, 0x42, 0x02, 0x5E, - 0x0F, 0x9F, 0x10, 0xF6, 0x0A, 0x65, 0xFE, 0x7F, - 0x02, 0x97, 0xC3, 0x92, 0x42, 0xA2, 0xC2, 0xD2, - 0x40, 0x92, 0x19, 0xD3, 0xC0, 0xEC, 0x0A, 0x65, - 0xEB, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3, - 0xC0, 0x00, 0xC2, 0xD2, 0x0A, 0x65, 0xE9, 0x43, - 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, 0xBF, 0xFF, - 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, - 0x63, 0x20, 0x08, 0x0B, 0x01, 0x00, 0x11, 0x93, - 0xAF, 0xBC, 0x47, 0xB2, 0x59, 0x95, 0x5A, 0x95, - 0x12, 0xA5, 0xBF, 0xBC, 0x0A, 0xB3, 0x01, 0x00, - 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x35, 0xF6, - 0x41, 0x04, 0x05, 0x93, 0x40, 0x96, 0x20, 0xD6, - 0x62, 0x97, 0x0F, 0x9F, 0x44, 0xF6, 0x14, 0x99, - 0xFC, 0xBC, 0xD1, 0xD8, 0x14, 0x99, 0xFE, 0xBC, - 0xD1, 0xD8, 0x20, 0x98, 0x42, 0x08, 0x20, 0xD8, - 0x20, 0x98, 0x03, 0x49, 0x02, 0x1E, 0x0F, 0x9F, - 0x3B, 0xF6, 0xC5, 0x92, 0x62, 0x42, 0x02, 0x4E, - 0x0F, 0x9F, 0x5D, 0xF6, 0x02, 0x8E, 0x0F, 0x9F, - 0x57, 0xF6, 0x61, 0x42, 0x02, 0x4E, 0x0F, 0x9F, - 0x81, 0xF6, 0x0F, 0x9F, 0xAE, 0xF6, 0x63, 0x42, - 0x02, 0x4E, 0x0F, 0x9F, 0xA4, 0xF6, 0x0F, 0x9F, - 0xAE, 0xF6, 0x0D, 0x03, 0x01, 0x00, 0x0C, 0x99, - 0x71, 0xEC, 0x0B, 0x05, 0xFF, 0xFF, 0x40, 0x96, - 0x0F, 0x9F, 0x6A, 0xF6, 0xD1, 0x96, 0xD4, 0xD6, - 0x20, 0x96, 0x41, 0x06, 0x20, 0xD6, 0x02, 0x47, - 0x02, 0x1E, 0x0F, 0x9F, 0x66, 0xF6, 0x1A, 0xD5, - 0xC1, 0xEC, 0x0A, 0x65, 0xEB, 0x43, 0x02, 0x99, - 0xC4, 0x92, 0x09, 0xA3, 0xC0, 0x00, 0xC2, 0xD2, - 0x0A, 0x65, 0xE9, 0x43, 0x02, 0x97, 0xC3, 0x92, - 0x09, 0xB3, 0xBF, 0xFF, 0xC2, 0xD2, 0x0F, 0x9F, - 0xAE, 0xF6, 0x0A, 0x03, 0xFE, 0xFF, 0x61, 0x95, - 0x40, 0x98, 0x20, 0xD8, 0x02, 0x49, 0x02, 0x0E, - 0x0F, 0x9F, 0xAE, 0xF6, 0x0D, 0x03, 0x01, 0x00, - 0x21, 0xD2, 0x20, 0x92, 0x05, 0x03, 0x42, 0x02, - 0xC8, 0xD2, 0x21, 0x96, 0xC3, 0x92, 0x42, 0x06, - 0x21, 0xD6, 0xC8, 0xD2, 0x22, 0xD4, 0x40, 0xF0, - 0x01, 0xF1, 0x42, 0x00, 0x20, 0x98, 0x42, 0x08, - 0x20, 0xD8, 0x22, 0x94, 0x02, 0x49, 0x02, 0x1E, - 0x0F, 0x9F, 0x8D, 0xF6, 0x0F, 0x9F, 0xAE, 0xF6, - 0x0D, 0x03, 0x03, 0x00, 0xC8, 0xD2, 0x02, 0x92, - 0xC8, 0xD2, 0x01, 0x96, 0xC8, 0xD6, 0x40, 0xF0, - 0xB1, 0xF6, 0x43, 0x00, 0x63, 0x00, 0x88, 0x98, - 0x90, 0x9A, 0x88, 0xDA, 0x45, 0x20, 0x08, 0x0B, - 0x01, 0x00, 0x0D, 0x03, 0x08, 0x00, 0x08, 0x94, - 0xC5, 0xD4, 0x09, 0x05, 0x01, 0x00, 0xC2, 0x94, - 0x03, 0xD4, 0x42, 0x02, 0xC1, 0x92, 0x01, 0xD2, - 0x02, 0x97, 0xC5, 0x94, 0x0A, 0x83, 0xFF, 0xFF, - 0x11, 0xB3, 0x2C, 0x93, 0x09, 0xB3, 0xFB, 0xFF, - 0x19, 0xD3, 0x2C, 0x93, 0x03, 0x92, 0x40, 0x42, - 0x02, 0x4E, 0x0F, 0x9F, 0xE4, 0xF6, 0x01, 0x94, - 0xD2, 0x92, 0x19, 0xD3, 0x2C, 0x93, 0x01, 0xD4, - 0x02, 0x94, 0x12, 0x95, 0x2C, 0x93, 0x44, 0xA4, - 0x1A, 0xD5, 0x2C, 0x93, 0x0A, 0xB5, 0xFB, 0xFF, - 0x1A, 0xD5, 0x2C, 0x93, 0x0B, 0x07, 0xFF, 0xFF, - 0x40, 0x46, 0x02, 0x5E, 0x0F, 0x9F, 0xCF, 0xF6, - 0x09, 0x63, 0xD4, 0x6C, 0x01, 0x95, 0xC2, 0x96, - 0xC5, 0x94, 0x02, 0xA7, 0xC1, 0xD6, 0x03, 0x92, - 0x54, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0xF4, 0xF6, - 0x0A, 0x83, 0xFF, 0xFF, 0x1B, 0xB3, 0x2C, 0x93, - 0x45, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, - 0x08, 0x0B, 0x01, 0x00, 0x09, 0x63, 0x00, 0x40, - 0x19, 0xD3, 0xF2, 0xBD, 0x40, 0xF0, 0x3B, 0xF5, - 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0x08, 0xF7, - 0x40, 0xF0, 0x94, 0xF2, 0x0F, 0x9F, 0x16, 0xF7, - 0x40, 0x96, 0xC8, 0xD6, 0x09, 0x93, 0x91, 0xEC, - 0xC8, 0xD2, 0x40, 0xF0, 0x2A, 0xEF, 0x0A, 0x65, - 0xFE, 0x7F, 0x02, 0x97, 0xC3, 0x92, 0x44, 0xA2, - 0xC2, 0xD2, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A, - 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x0A, 0x65, - 0xE8, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3, - 0x40, 0x00, 0xC2, 0xD2, 0x0A, 0x65, 0xEA, 0x43, - 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, 0xFB, 0xFF, - 0xC2, 0xD2, 0x40, 0x92, 0x19, 0xD3, 0x2D, 0xBC, - 0x0A, 0x65, 0xD8, 0x43, 0x02, 0x97, 0xC3, 0x92, - 0x09, 0xB3, 0xBF, 0xFF, 0xC2, 0xD2, 0x88, 0x98, - 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, - 0x09, 0x63, 0xEA, 0x43, 0x01, 0x97, 0xC3, 0x94, - 0x44, 0xA4, 0xC1, 0xD4, 0x11, 0x93, 0xB9, 0xEC, - 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x6F, 0xF7, - 0x12, 0x95, 0x93, 0xEC, 0x0B, 0x67, 0x36, 0x43, - 0xD2, 0x98, 0x1C, 0xD9, 0xC8, 0xBC, 0xD2, 0x98, - 0x03, 0x93, 0xC1, 0xD8, 0x11, 0x93, 0xB9, 0xEC, - 0x09, 0x03, 0xFF, 0xFF, 0x19, 0xD3, 0xB9, 0xEC, - 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0x48, 0xF7, - 0x19, 0xD3, 0xB8, 0xEC, 0x19, 0xD3, 0xBA, 0xEC, - 0x0A, 0x05, 0xFE, 0xFF, 0xCA, 0xD2, 0xCA, 0xD2, - 0xC2, 0xD2, 0x0A, 0x65, 0x5E, 0x43, 0x02, 0x97, - 0xC3, 0x92, 0x48, 0xA2, 0xC2, 0xD2, 0x0A, 0x65, - 0xEA, 0x43, 0x02, 0x99, 0xC4, 0x92, 0x09, 0xB3, - 0xFB, 0xFF, 0x0F, 0x9F, 0x78, 0xF7, 0x11, 0x93, - 0x03, 0xEC, 0x19, 0xD3, 0x01, 0x82, 0x0A, 0x65, - 0xFD, 0x7D, 0x02, 0x97, 0xC3, 0x92, 0x43, 0xA2, - 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, - 0x08, 0x0B, 0x01, 0x00, 0x03, 0x92, 0x04, 0x96, - 0x0D, 0x5E, 0x50, 0x46, 0x02, 0x0E, 0x40, 0x92, - 0x09, 0xEE, 0x44, 0x46, 0x04, 0x0E, 0x59, 0x93, - 0x44, 0x26, 0x04, 0x5E, 0x46, 0xEE, 0x41, 0x93, - 0x41, 0x26, 0x43, 0x4E, 0x88, 0x98, 0x90, 0x9A, - 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x40, 0xF0, - 0xB1, 0xFE, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, - 0x08, 0x0B, 0x01, 0x00, 0x88, 0x98, 0x90, 0x9A, - 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x03, 0x94, - 0x1A, 0xD5, 0xA3, 0xF7, 0x11, 0x93, 0x00, 0x90, - 0x88, 0x98, 0x90, 0x9A, 0x1D, 0x00, 0x1A, 0x00, - 0x03, 0x00, 0x03, 0x00, 0x18, 0x00, 0x19, 0x00, - 0x1A, 0x00, 0x1B, 0x00, 0x16, 0x00, 0x21, 0x00, - 0x12, 0x00, 0x09, 0x00, 0x13, 0x00, 0x19, 0x00, - 0x19, 0x00, 0x19, 0x00, 0x21, 0x00, 0x2D, 0x00, - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x69, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5F, 0xF2, 0xCD, 0xF7, 0x00, 0x00, 0x74, 0xF2, - 0xCD, 0xF7, 0x00, 0x00, 0xB9, 0xF2, 0xCA, 0xF7, - 0xD1, 0xF7, 0x00, 0x00, 0x97, 0xF3, 0xCD, 0xF7, - 0x05, 0x46, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* - * current zd1211b firmware version. - */ -#define ZD1211B_FIRMWARE_VER 4705 - -uint8_t zd1211b_firmware[] = { - 0x08, 0x91, 0xff, 0xed, 0x09, 0x93, 0x1e, 0xee, 0xd1, 0x94, 0x11, - 0xee, 0x88, 0xd4, 0xd1, 0x96, 0xd1, 0x98, 0x5c, 0x99, 0x5c, 0x99, - 0x4c, 0x99, 0x04, 0x9d, 0xd1, 0x98, 0xd1, 0x9a, 0x03, 0xee, 0xf4, - 0x94, 0xd3, 0xd4, 0x41, 0x2a, 0x40, 0x4a, 0x45, 0xbe, 0x88, 0x92, - 0x41, 0x24, 0x40, 0x44, 0x53, 0xbe, 0x40, 0xf0, 0x4e, 0xee, 0x41, - 0xee, 0x98, 0x9a, 0x72, 0xf7, 0x02, 0x00, 0x1f, 0xec, 0x00, 0x00, - 0xb2, 0xf8, 0x4d, 0x00, 0xa1, 0xec, 0x00, 0x00, 0x43, 0xf7, 0x22, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xd8, - 0xa0, 0x90, 0x98, 0x9a, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x5a, - 0xf0, 0xa0, 0x90, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x0a, 0xef, - 0xa0, 0x90, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x97, 0xf0, 0xa0, - 0x90, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x94, 0xf6, 0xa0, 0x90, - 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x95, 0xf5, 0xa0, 0x90, 0x98, - 0x9a, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x34, 0xf7, 0xa0, 0x90, - 0x98, 0x9a, 0x88, 0xda, 0x41, 0x20, 0x08, 0x0b, 0x01, 0x00, 0x40, - 0xf0, 0x8e, 0xee, 0x40, 0x96, 0x0a, 0x65, 0x00, 0x7d, 0x11, 0x93, - 0x76, 0xf7, 0x41, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x57, 0xee, 0x40, - 0xf1, 0x1b, 0xd7, 0x76, 0xf7, 0xc5, 0x92, 0x02, 0x99, 0x41, 0x92, - 0xc4, 0xd2, 0x40, 0x92, 0xc4, 0xd2, 0x0f, 0x9f, 0x95, 0xf8, 0x0f, - 0x9f, 0x57, 0xee, 0x41, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, - 0x08, 0x0b, 0x01, 0x00, 0x40, 0x92, 0x19, 0xd3, 0x12, 0x95, 0x19, - 0xd3, 0x10, 0x95, 0x19, 0xd3, 0x02, 0x80, 0x19, 0xd3, 0x03, 0x82, - 0x09, 0x93, 0x65, 0xf7, 0x19, 0xd3, 0x91, 0xec, 0x40, 0xf0, 0x07, - 0xf2, 0x40, 0xf0, 0x75, 0xf3, 0x11, 0x93, 0x04, 0xec, 0x42, 0x42, - 0x02, 0x5e, 0x0f, 0x9f, 0x8c, 0xee, 0x40, 0x92, 0x19, 0xd3, 0x04, - 0xec, 0x40, 0xf0, 0xe0, 0xf1, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, - 0x08, 0x0b, 0x01, 0x00, 0x11, 0x93, 0x44, 0x96, 0x09, 0xb3, 0xff, - 0xfd, 0x19, 0xd3, 0x44, 0x96, 0x40, 0xf0, 0x2d, 0xf7, 0x40, 0xf0, - 0x6d, 0xee, 0x4b, 0x62, 0x0a, 0x95, 0x2e, 0xee, 0xd1, 0xd4, 0x0b, - 0x97, 0x2b, 0xee, 0xd1, 0xd6, 0x0a, 0x95, 0x00, 0xee, 0xd1, 0xd4, - 0x0b, 0x97, 0x2f, 0xee, 0xd1, 0xd6, 0x0a, 0x95, 0x34, 0xee, 0xd1, - 0xd4, 0x0b, 0x97, 0x39, 0xee, 0xd1, 0xd6, 0x0a, 0x95, 0x3e, 0xee, - 0xd1, 0xd4, 0x0b, 0x97, 0x43, 0xee, 0xd1, 0xd6, 0x0a, 0x95, 0x2e, - 0xee, 0xd1, 0xd4, 0x0b, 0x97, 0x48, 0xee, 0xd1, 0xd6, 0x0a, 0x95, - 0x49, 0xee, 0xc1, 0xd4, 0x0a, 0x65, 0x00, 0x44, 0x02, 0x97, 0xc3, - 0x92, 0x44, 0xa2, 0xc2, 0xd2, 0x43, 0xf1, 0x09, 0x93, 0x01, 0x3f, - 0x19, 0xd3, 0xc0, 0x85, 0x11, 0x93, 0x44, 0x96, 0x09, 0xb3, 0xff, - 0xfc, 0x19, 0xd3, 0x44, 0x96, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, - 0x08, 0x0b, 0x01, 0x00, 0x0d, 0x03, 0x03, 0x00, 0x03, 0x96, 0x41, - 0x02, 0x03, 0x99, 0xc4, 0x94, 0x42, 0x04, 0xc1, 0x04, 0xc2, 0x94, - 0xc3, 0xd4, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, - 0x00, 0x40, 0x92, 0x19, 0xd3, 0x94, 0xec, 0x13, 0x97, 0x95, 0xec, - 0x1b, 0xd7, 0x02, 0x80, 0x11, 0x93, 0x99, 0xec, 0x19, 0xd3, 0x7c, - 0x96, 0x0b, 0x97, 0xa0, 0x00, 0x1b, 0xd7, 0x6e, 0xec, 0x0a, 0x65, - 0x0e, 0x42, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xff, 0xbf, 0x11, - 0xa3, 0x9a, 0xec, 0xc2, 0xd2, 0x0a, 0x65, 0xeb, 0x43, 0x02, 0x97, - 0xc3, 0x92, 0x09, 0xa3, 0xc0, 0x00, 0xc2, 0xd2, 0x0a, 0x65, 0xe9, - 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xbf, 0xff, 0xc2, 0xd2, - 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x47, 0x20, 0x08, 0x0b, 0x01, - 0x00, 0x14, 0x99, 0x03, 0x80, 0x0c, 0xb3, 0x00, 0x10, 0x40, 0x42, - 0x02, 0x4e, 0x0f, 0x9f, 0x3d, 0xf0, 0x11, 0x93, 0x9f, 0xec, 0x41, - 0x02, 0x19, 0xd3, 0x9f, 0xec, 0x11, 0x93, 0x74, 0xf7, 0x40, 0x42, - 0x02, 0x4e, 0x0f, 0x9f, 0x2a, 0xef, 0x0a, 0x65, 0xfe, 0x7f, 0x02, - 0x97, 0xc3, 0x92, 0x09, 0xa3, 0x00, 0x04, 0xc2, 0xd2, 0x0f, 0x9f, - 0x57, 0xf0, 0x11, 0x93, 0x94, 0xec, 0x02, 0xd2, 0x40, 0x42, 0x02, - 0x5e, 0x0f, 0x9f, 0x76, 0xef, 0x41, 0x92, 0x19, 0xd3, 0x94, 0xec, - 0x19, 0xd3, 0x9f, 0xec, 0x12, 0x95, 0x02, 0x80, 0x1a, 0xd5, 0x95, - 0xec, 0x13, 0x97, 0x7c, 0x96, 0x1b, 0xd7, 0x99, 0xec, 0x0a, 0x65, - 0x0e, 0x42, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0x00, 0x40, 0x19, - 0xd3, 0x9a, 0xec, 0x09, 0x63, 0x00, 0x40, 0xc2, 0xd2, 0x02, 0x94, - 0x1a, 0xd5, 0x7c, 0x96, 0x0c, 0xb3, 0x00, 0x08, 0x40, 0x42, 0x02, - 0x5e, 0x0f, 0x9f, 0x56, 0xef, 0x0c, 0xb3, 0xff, 0x07, 0x0f, 0x9f, - 0x5a, 0xef, 0x11, 0x93, 0x06, 0x80, 0x09, 0xb3, 0xff, 0x07, 0x09, - 0x03, 0x00, 0xa0, 0x19, 0xd3, 0x97, 0xec, 0x40, 0x98, 0x0b, 0x97, - 0x9c, 0xec, 0x04, 0x95, 0x03, 0x05, 0x14, 0x03, 0x97, 0xec, 0x46, - 0x02, 0xc1, 0x92, 0xc2, 0xd2, 0x41, 0x08, 0x42, 0x48, 0x02, 0x9e, - 0x0f, 0x9f, 0x61, 0xef, 0x11, 0x93, 0x97, 0xec, 0xc1, 0x92, 0xc5, - 0xd2, 0x5f, 0xb2, 0x19, 0xd3, 0x9b, 0xec, 0x0f, 0x9f, 0x79, 0xef, - 0x13, 0x97, 0x98, 0xec, 0xc5, 0xd6, 0x11, 0x93, 0x03, 0x80, 0x09, - 0xb3, 0x00, 0x08, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x8f, 0xef, - 0x11, 0x93, 0x7a, 0xf7, 0x41, 0x02, 0x19, 0xd3, 0x7a, 0xf7, 0x11, - 0x93, 0x79, 0xf7, 0x09, 0xa3, 0x00, 0x10, 0x19, 0xd3, 0x79, 0xf7, - 0x40, 0x98, 0x1c, 0xd9, 0x9b, 0xec, 0x12, 0x95, 0x9b, 0xec, 0x40, - 0x44, 0x02, 0x4e, 0x0f, 0x9f, 0x2c, 0xf0, 0x0a, 0xb3, 0x08, 0x00, - 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xad, 0xef, 0x0a, 0xb3, 0x07, - 0x00, 0x09, 0x05, 0xa9, 0xec, 0xc2, 0x94, 0x01, 0xd4, 0x09, 0x03, - 0xa1, 0xec, 0xc1, 0x92, 0x19, 0xd3, 0x9b, 0xec, 0xc5, 0x94, 0x0a, - 0xb5, 0x00, 0xff, 0x01, 0xa5, 0xc5, 0xd4, 0x0f, 0x9f, 0xb9, 0xef, - 0x0a, 0x05, 0xff, 0xff, 0x0a, 0x03, 0xb1, 0xec, 0xc1, 0x92, 0x01, - 0xd2, 0x1a, 0xd5, 0x9b, 0xec, 0xc5, 0x96, 0x0b, 0x07, 0xff, 0xff, - 0xc5, 0xd6, 0x11, 0x93, 0x97, 0xec, 0xc5, 0x98, 0xc1, 0xd8, 0x11, - 0x93, 0x97, 0xec, 0x09, 0x05, 0x0b, 0x00, 0x03, 0xd4, 0xc2, 0x96, - 0x06, 0xd6, 0x7b, 0x95, 0x7a, 0x95, 0x4c, 0x02, 0xc1, 0x92, 0x59, - 0x93, 0x59, 0x93, 0x01, 0xa5, 0x01, 0x98, 0x0c, 0xf5, 0x7b, 0x93, - 0x09, 0x09, 0x01, 0x00, 0x06, 0x92, 0x09, 0xb3, 0xff, 0x00, 0x04, - 0xd2, 0x5c, 0x93, 0x59, 0x93, 0x04, 0x94, 0x01, 0xa5, 0x03, 0x96, - 0xc3, 0xd4, 0x11, 0x93, 0x97, 0xec, 0x4c, 0x02, 0x05, 0xd2, 0xc1, - 0x92, 0x09, 0xb3, 0x00, 0xff, 0x7c, 0x95, 0x7a, 0x95, 0x02, 0xa3, - 0x05, 0x98, 0xc4, 0xd2, 0x12, 0x95, 0x97, 0xec, 0x45, 0x04, 0x02, - 0x97, 0xc3, 0x92, 0x09, 0xa3, 0x00, 0x01, 0xc2, 0xd2, 0x12, 0x95, - 0x9b, 0xec, 0x0a, 0xb3, 0x08, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, - 0x9f, 0x01, 0xf0, 0x12, 0x95, 0x97, 0xec, 0x4a, 0x04, 0x02, 0x99, - 0xc4, 0x92, 0x01, 0x98, 0x0c, 0xf3, 0x7b, 0x93, 0x41, 0x02, 0x0f, - 0x9f, 0x22, 0xf0, 0x43, 0x44, 0x02, 0x8e, 0x0f, 0x9f, 0x23, 0xf0, - 0x11, 0x93, 0x97, 0xec, 0x42, 0x02, 0x0a, 0x05, 0xff, 0xff, 0xc1, - 0xd4, 0x11, 0x93, 0x97, 0xec, 0x4a, 0x02, 0x12, 0x95, 0x60, 0x96, - 0xc1, 0xd4, 0x12, 0x95, 0x97, 0xec, 0x4b, 0x04, 0x02, 0x97, 0xc3, - 0x92, 0x09, 0xb3, 0x1f, 0xff, 0xc2, 0xd2, 0x12, 0x95, 0x97, 0xec, - 0x4b, 0x04, 0x11, 0x93, 0x62, 0x96, 0x41, 0x93, 0x59, 0x93, 0x02, - 0x99, 0xc4, 0xa2, 0xc2, 0xd2, 0xc5, 0x92, 0x19, 0xd3, 0x98, 0xec, - 0x0a, 0x95, 0x0c, 0x02, 0x1a, 0xd5, 0x02, 0x80, 0x0f, 0x9f, 0x57, - 0xf0, 0x09, 0x63, 0xfe, 0x7f, 0x01, 0x97, 0xc3, 0x94, 0x0a, 0xa5, - 0x00, 0x04, 0xc1, 0xd4, 0x11, 0x93, 0x9f, 0xec, 0x09, 0xa3, 0x00, - 0x01, 0x19, 0xd3, 0x9f, 0xec, 0x40, 0xf0, 0xdf, 0xee, 0x0f, 0x9f, - 0x57, 0xf0, 0x11, 0x93, 0x94, 0xec, 0x41, 0x42, 0x02, 0x5e, 0x0f, - 0x9f, 0x4c, 0xf0, 0x40, 0xf0, 0xdf, 0xee, 0x11, 0x93, 0x95, 0xec, - 0x44, 0xb2, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x57, 0xf0, 0x48, - 0x98, 0x1c, 0xd9, 0x02, 0x80, 0x11, 0x93, 0x91, 0xec, 0x41, 0x22, - 0x0a, 0x95, 0x57, 0xf0, 0x88, 0xd4, 0x88, 0xdc, 0x91, 0x9a, 0x47, - 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, - 0x11, 0x93, 0x04, 0x82, 0x48, 0xb2, 0x40, 0x42, 0x02, 0x4e, 0x0f, - 0x9f, 0x6e, 0xf0, 0x0a, 0x65, 0xfd, 0x7d, 0x02, 0x97, 0xc3, 0x92, - 0x09, 0xb3, 0xff, 0xfe, 0xc2, 0xd2, 0x41, 0x92, 0x19, 0xd3, 0xbf, - 0xec, 0x11, 0x93, 0x04, 0x82, 0x43, 0xb2, 0x12, 0x95, 0x03, 0x82, - 0x02, 0xb3, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x95, 0xf0, 0x0a, - 0xb3, 0x00, 0xff, 0x48, 0xa2, 0x19, 0xd3, 0x03, 0x82, 0x40, 0xf0, - 0x82, 0xf3, 0x11, 0x93, 0xbf, 0xec, 0x41, 0x42, 0x02, 0x5e, 0x0f, - 0x9f, 0x95, 0xf0, 0x11, 0x93, 0x07, 0x82, 0x11, 0x43, 0x03, 0xec, - 0x02, 0x0e, 0x0f, 0x9f, 0x95, 0xf0, 0x11, 0x93, 0x03, 0x82, 0x09, - 0xa3, 0x00, 0x01, 0x19, 0xd3, 0x03, 0x82, 0x40, 0x96, 0x1b, 0xd7, - 0xbf, 0xec, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, - 0x00, 0x11, 0x93, 0x20, 0xbc, 0xc8, 0xd2, 0x40, 0xf0, 0xe9, 0xf0, - 0x41, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x42, 0x20, 0x08, - 0x0b, 0x01, 0x00, 0x0d, 0x03, 0x05, 0x00, 0x05, 0x94, 0x41, 0x02, - 0xc1, 0x92, 0x01, 0x97, 0xc3, 0x96, 0xc2, 0xd6, 0x0a, 0x45, 0x00, - 0x95, 0x02, 0x5e, 0x0f, 0x9f, 0xe6, 0xf0, 0xc1, 0x92, 0x41, 0xb2, - 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xe6, 0xf0, 0x11, 0x93, 0xc0, - 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xe6, 0xf0, 0x41, 0x98, - 0x1c, 0xd9, 0xc0, 0xec, 0x12, 0x95, 0x02, 0x80, 0x01, 0xd4, 0x40, - 0xf0, 0xfe, 0xf1, 0x0b, 0x67, 0xfd, 0x7d, 0x03, 0x99, 0xc4, 0x92, - 0x0c, 0x99, 0x96, 0x03, 0x1c, 0xd9, 0x06, 0x82, 0x41, 0x98, 0x1c, - 0xd9, 0x02, 0x82, 0x42, 0x98, 0x1c, 0xd9, 0x05, 0x82, 0x0c, 0x69, - 0x80, 0x7f, 0x1c, 0xd9, 0x00, 0xb0, 0x09, 0xa3, 0x00, 0x01, 0xc3, - 0xd2, 0x01, 0x94, 0x0a, 0xb3, 0x04, 0x00, 0x40, 0x42, 0x02, 0x4e, - 0x0f, 0x9f, 0xe4, 0xf0, 0x42, 0xa4, 0x1a, 0xd5, 0x02, 0x80, 0x42, - 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x42, 0x20, 0x08, 0x0b, - 0x01, 0x00, 0x05, 0x92, 0xc5, 0xd2, 0x60, 0xb2, 0x40, 0x42, 0x02, - 0x4e, 0x0f, 0x9f, 0xf6, 0xf0, 0x40, 0xf0, 0xd2, 0xf6, 0xc5, 0x94, - 0x0a, 0xb3, 0x10, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xff, - 0xf0, 0x40, 0xf0, 0xc0, 0xf5, 0xc5, 0x96, 0x0b, 0xb3, 0x40, 0x00, - 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x08, 0xf1, 0x40, 0xf0, 0xfa, - 0xf4, 0xc5, 0x94, 0x0a, 0xb3, 0x01, 0x00, 0x40, 0x42, 0x02, 0x4e, - 0x0f, 0x9f, 0x70, 0xf1, 0x13, 0x97, 0x21, 0xbc, 0x01, 0xd6, 0x0b, - 0xb3, 0x02, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x1a, 0xf1, - 0x40, 0xf0, 0x62, 0xfb, 0x01, 0x94, 0x0a, 0xb3, 0x04, 0x00, 0x40, - 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x23, 0xf1, 0x40, 0xf0, 0x6c, 0xfb, - 0x01, 0x96, 0x0b, 0xb3, 0x01, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, - 0x9f, 0x4c, 0xf1, 0x40, 0xf0, 0xb0, 0xfa, 0x41, 0x92, 0x19, 0xd3, - 0x73, 0xf7, 0x11, 0x93, 0x03, 0xec, 0x09, 0x43, 0x40, 0x00, 0x02, - 0x5e, 0x0f, 0x9f, 0x39, 0xf1, 0x40, 0x94, 0x1a, 0xd5, 0x73, 0xf7, - 0x11, 0x93, 0x00, 0xec, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x55, - 0xf1, 0x11, 0x93, 0xc1, 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, - 0x55, 0xf1, 0x40, 0xf0, 0xe0, 0xf1, 0x41, 0x96, 0x1b, 0xd7, 0xc1, - 0xec, 0x0f, 0x9f, 0x55, 0xf1, 0x01, 0x94, 0x0a, 0xb3, 0x08, 0x00, - 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x55, 0xf1, 0x40, 0xf0, 0x7c, - 0xfb, 0x01, 0x96, 0x0b, 0xb3, 0x10, 0x00, 0x40, 0x42, 0x02, 0x4e, - 0x0f, 0x9f, 0x5e, 0xf1, 0x40, 0xf0, 0x87, 0xfb, 0x11, 0x93, 0x10, - 0xec, 0x42, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x67, 0xf1, 0x44, 0x92, - 0x0f, 0x9f, 0x6b, 0xf1, 0x41, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x6d, - 0xf1, 0x19, 0xd3, 0x0b, 0xbc, 0x40, 0x94, 0x1a, 0xd5, 0x10, 0xec, - 0xc5, 0x96, 0x0b, 0xb3, 0x80, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, - 0x9f, 0xba, 0xf1, 0x11, 0x93, 0x28, 0xbc, 0x01, 0xd2, 0x09, 0xb3, - 0x40, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x82, 0xf1, 0x40, - 0xf0, 0xb5, 0xf6, 0x01, 0x94, 0x0a, 0xb3, 0x02, 0x00, 0x40, 0x42, - 0x02, 0x4e, 0x0f, 0x9f, 0x95, 0xf1, 0x40, 0xf0, 0x6d, 0xee, 0x40, - 0xf0, 0x8f, 0xfb, 0x40, 0xf0, 0xc3, 0xf1, 0x40, 0x96, 0x1b, 0xd7, - 0x00, 0xec, 0x41, 0x92, 0x19, 0xd3, 0x76, 0xf7, 0x01, 0x94, 0x0a, - 0xb3, 0x04, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xb1, 0xf1, - 0x40, 0xf0, 0x9e, 0xfb, 0x09, 0x63, 0x00, 0x44, 0x01, 0x97, 0xc3, - 0x94, 0x48, 0xa4, 0xc1, 0xd4, 0x00, 0xee, 0x40, 0x92, 0x19, 0xd3, - 0x12, 0x95, 0x19, 0xd3, 0x10, 0x95, 0x19, 0xd3, 0x02, 0x80, 0x19, - 0xd3, 0x03, 0x82, 0x41, 0x92, 0x19, 0xd3, 0x76, 0xf7, 0x01, 0x94, - 0x0a, 0xb3, 0x08, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xba, - 0xf1, 0x40, 0xf0, 0xae, 0xfb, 0x0a, 0x65, 0x00, 0x44, 0x02, 0x97, - 0xc3, 0x92, 0x44, 0xa2, 0xc2, 0xd2, 0x42, 0x00, 0x88, 0x98, 0x90, - 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x09, 0x63, 0x00, 0x40, - 0x19, 0xd3, 0xf2, 0xbd, 0x0a, 0x65, 0xea, 0x43, 0x02, 0x97, 0xc3, - 0x92, 0x44, 0xa2, 0xc2, 0xd2, 0x0a, 0x65, 0xe9, 0x43, 0x02, 0x97, - 0xc3, 0x92, 0x09, 0xa3, 0x40, 0x00, 0xc2, 0xd2, 0x0a, 0x65, 0xeb, - 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3, 0xc0, 0x00, 0xc2, 0xd2, - 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x09, - 0x63, 0x00, 0x80, 0x19, 0xd3, 0xf2, 0xbd, 0x0a, 0x65, 0xe8, 0x43, - 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3, 0xc0, 0x00, 0xc2, 0xd2, 0x0a, - 0x65, 0xeb, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xbf, 0xff, - 0xc2, 0xd2, 0x0a, 0x65, 0xea, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, - 0xb3, 0xfb, 0xff, 0xc2, 0xd2, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, - 0x08, 0x0b, 0x01, 0x00, 0x09, 0x93, 0x00, 0x01, 0x19, 0xd3, 0x02, - 0x80, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, - 0x09, 0x93, 0x00, 0x09, 0x19, 0xd3, 0x02, 0x80, 0x40, 0xf0, 0xfe, - 0xf1, 0x40, 0x92, 0x19, 0xd3, 0x94, 0xec, 0xc8, 0xd2, 0x09, 0x93, - 0x91, 0xec, 0xc8, 0xd2, 0x40, 0xf0, 0xd0, 0xee, 0x42, 0x00, 0x88, - 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x40, 0xf0, - 0xd8, 0xf4, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x2d, 0xf2, 0x0a, - 0x65, 0xfe, 0x7f, 0x02, 0x97, 0xc3, 0x92, 0x44, 0xa2, 0xc2, 0xd2, - 0x0f, 0x9f, 0x3a, 0xf2, 0x40, 0xf0, 0x3c, 0xf2, 0x40, 0x42, 0x02, - 0x5e, 0x0f, 0x9f, 0x3a, 0xf2, 0xc8, 0xd2, 0x09, 0x93, 0x91, 0xec, - 0xc8, 0xd2, 0x40, 0xf0, 0xd0, 0xee, 0x42, 0x00, 0x88, 0x98, 0x90, - 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x11, 0x93, 0xf1, 0xbd, - 0x19, 0xd3, 0xb6, 0xec, 0x11, 0x93, 0xb4, 0xec, 0x40, 0x42, 0x02, - 0x5e, 0x0f, 0x9f, 0x54, 0xf2, 0x09, 0x63, 0x00, 0x80, 0x01, 0x97, - 0xc3, 0x94, 0x0a, 0x07, 0x07, 0x00, 0xc1, 0xd6, 0x0a, 0x05, 0x00, - 0xa0, 0x1a, 0xd5, 0x96, 0xec, 0x11, 0x93, 0xb6, 0xec, 0x19, 0xd3, - 0x01, 0x80, 0x0a, 0x65, 0xfe, 0x7f, 0x02, 0x97, 0xc3, 0x92, 0x41, - 0xa2, 0xc2, 0xd2, 0x40, 0x92, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, - 0x41, 0x20, 0x08, 0x0b, 0x01, 0x00, 0x13, 0x97, 0xb4, 0xec, 0x40, - 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0xc3, 0xf2, 0x12, 0x95, 0x96, 0xec, - 0x0a, 0x03, 0x07, 0x00, 0xc1, 0x92, 0xc2, 0xd2, 0x11, 0x93, 0x96, - 0xec, 0x09, 0x05, 0x01, 0x00, 0x48, 0x02, 0xc1, 0x92, 0xc2, 0xd2, - 0x11, 0x93, 0x96, 0xec, 0x4e, 0x02, 0xc1, 0x94, 0xc5, 0xd6, 0xc5, - 0x92, 0x11, 0x07, 0x96, 0xec, 0x0b, 0x03, 0x0f, 0x00, 0xc1, 0x98, - 0x46, 0x06, 0x7a, 0x93, 0x79, 0x93, 0x5c, 0x95, 0x5a, 0x95, 0x02, - 0xa3, 0xc3, 0xd2, 0x04, 0x95, 0xc5, 0x96, 0x41, 0x06, 0xc5, 0xd6, - 0x42, 0x46, 0x02, 0x9e, 0x0f, 0x9f, 0x7d, 0xf2, 0x11, 0x93, 0x96, - 0xec, 0x09, 0x05, 0x05, 0x00, 0x41, 0x02, 0xc1, 0x92, 0xc2, 0xd2, - 0x11, 0x93, 0x96, 0xec, 0xc1, 0x92, 0x09, 0xb5, 0x1f, 0x00, 0x43, - 0x44, 0x02, 0x8e, 0x0f, 0x9f, 0xaa, 0xf2, 0x40, 0x44, 0x02, 0x4e, - 0x0f, 0x9f, 0xab, 0xf2, 0x0a, 0x05, 0xff, 0xff, 0x0f, 0x9f, 0xab, - 0xf2, 0x43, 0x94, 0x11, 0x93, 0x96, 0xec, 0x42, 0x02, 0xc1, 0xd4, - 0x13, 0x97, 0x96, 0xec, 0x03, 0x93, 0xd1, 0x94, 0x7a, 0x95, 0x7a, - 0x95, 0xc1, 0x92, 0x59, 0x93, 0x59, 0x93, 0x01, 0x05, 0x49, 0x06, - 0xc3, 0x92, 0x7f, 0xb2, 0x01, 0x05, 0x1a, 0xd5, 0xb4, 0xec, 0x0a, - 0x05, 0xf2, 0xff, 0x1a, 0xd5, 0x92, 0xec, 0x11, 0x93, 0x92, 0xec, - 0x12, 0x95, 0xb6, 0xec, 0x02, 0x43, 0x02, 0x8e, 0x0f, 0x9f, 0x11, - 0xf3, 0x02, 0x0e, 0x0f, 0x9f, 0xe4, 0xf2, 0x11, 0x93, 0x7a, 0xf7, - 0x41, 0x02, 0x19, 0xd3, 0x7a, 0xf7, 0x11, 0x93, 0x79, 0xf7, 0x09, - 0xa3, 0x80, 0x00, 0x19, 0xd3, 0x79, 0xf7, 0x09, 0x63, 0x00, 0x80, - 0x01, 0x95, 0xc2, 0x94, 0x1a, 0xd5, 0xb5, 0xec, 0x40, 0x96, 0x1b, - 0xd7, 0xb4, 0xec, 0x0f, 0x9f, 0x29, 0xf3, 0x11, 0x93, 0x03, 0x80, - 0x09, 0xb3, 0x00, 0x40, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xf6, - 0xf2, 0x11, 0x93, 0xc0, 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, - 0xf6, 0xf2, 0x40, 0xf0, 0x3d, 0xf3, 0x0f, 0x9f, 0x2b, 0xf3, 0x41, - 0x92, 0xc8, 0xd2, 0x0a, 0x95, 0x91, 0xec, 0xc8, 0xd4, 0x40, 0xf0, - 0xd0, 0xee, 0x42, 0x00, 0x11, 0x93, 0xc0, 0xec, 0x40, 0x42, 0x02, - 0x4e, 0x0f, 0x9f, 0x09, 0xf3, 0x42, 0x96, 0x1b, 0xd7, 0xc0, 0xec, - 0x0f, 0x9f, 0x2b, 0xf3, 0x0a, 0x65, 0xfe, 0x7f, 0x02, 0x97, 0xc3, - 0x92, 0x42, 0xa2, 0xc2, 0xd2, 0x0f, 0x9f, 0x2b, 0xf3, 0x12, 0x45, - 0x03, 0xec, 0x02, 0x4e, 0x0f, 0x9f, 0x23, 0xf3, 0x11, 0x93, 0x7a, - 0xf7, 0x41, 0x02, 0x19, 0xd3, 0x7a, 0xf7, 0x11, 0x93, 0x79, 0xf7, - 0x09, 0xa3, 0x00, 0x08, 0x19, 0xd3, 0x79, 0xf7, 0x1a, 0xd5, 0x92, - 0xec, 0x11, 0x93, 0x92, 0xec, 0x19, 0x25, 0x92, 0xec, 0x09, 0x63, - 0x00, 0x80, 0x19, 0xd3, 0xf2, 0xbd, 0x41, 0x00, 0x88, 0x98, 0x90, - 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x40, 0xf0, 0x3d, 0xf3, - 0x40, 0x92, 0xc8, 0xd2, 0x09, 0x93, 0x91, 0xec, 0xc8, 0xd2, 0x40, - 0xf0, 0xd0, 0xee, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, - 0x08, 0x0b, 0x01, 0x00, 0x11, 0x93, 0x75, 0xf7, 0x40, 0x42, 0x02, - 0x4e, 0x0f, 0x9f, 0x4d, 0xf3, 0x0a, 0x65, 0xbc, 0x69, 0x02, 0x97, - 0xc3, 0x92, 0x09, 0x83, 0x00, 0x02, 0xc2, 0xd2, 0x11, 0x93, 0x03, - 0x80, 0x09, 0xb3, 0x00, 0x40, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, - 0x60, 0xf3, 0x11, 0x93, 0x7a, 0xf7, 0x41, 0x02, 0x19, 0xd3, 0x7a, - 0xf7, 0x11, 0x93, 0x79, 0xf7, 0x09, 0xa3, 0x00, 0x20, 0x19, 0xd3, - 0x79, 0xf7, 0x11, 0x93, 0xb5, 0xec, 0x19, 0xd3, 0x04, 0x80, 0x12, - 0x95, 0xb4, 0xec, 0x1a, 0xd5, 0x05, 0x80, 0x09, 0x63, 0x00, 0x80, - 0x01, 0x97, 0xc3, 0x96, 0x1b, 0xd7, 0xb5, 0xec, 0x40, 0x94, 0x1a, - 0xd5, 0xb4, 0xec, 0x19, 0xd3, 0xf2, 0xbd, 0x88, 0x98, 0x90, 0x9a, - 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x09, 0x93, 0x96, 0x03, 0x19, - 0xd3, 0x06, 0x82, 0x09, 0x93, 0x00, 0x01, 0x19, 0xd3, 0x03, 0x82, - 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x47, 0x20, 0x08, 0x0b, 0x01, - 0x00, 0x11, 0x93, 0x01, 0x82, 0xc5, 0xd2, 0x40, 0x94, 0x01, 0xd4, - 0x13, 0x97, 0xb8, 0xec, 0x02, 0xd6, 0x03, 0x95, 0x0c, 0x99, 0xbb, - 0xec, 0x04, 0x05, 0x13, 0x97, 0x03, 0xec, 0x01, 0x27, 0x02, 0x99, - 0xc4, 0x92, 0x03, 0x03, 0xc2, 0xd2, 0x14, 0x99, 0xba, 0xec, 0x03, - 0x09, 0x1c, 0xd9, 0xba, 0xec, 0x12, 0x95, 0x04, 0x82, 0x0a, 0xb3, - 0x02, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xc6, 0xf4, 0x01, - 0x92, 0x03, 0xd2, 0x0a, 0xa3, 0x02, 0x00, 0x19, 0xd3, 0x04, 0x82, - 0x02, 0x96, 0x0b, 0x05, 0x01, 0x00, 0x1a, 0xd5, 0xb8, 0xec, 0xc5, - 0x92, 0x43, 0x42, 0x02, 0x9e, 0x0f, 0x9f, 0xce, 0xf3, 0x42, 0x44, - 0x02, 0x8e, 0x0f, 0x9f, 0xce, 0xf3, 0x11, 0x93, 0xbf, 0xec, 0x40, - 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xce, 0xf3, 0x0c, 0x49, 0xd3, 0x08, - 0x02, 0x8e, 0x0f, 0x9f, 0xce, 0xf3, 0x11, 0x63, 0x07, 0x82, 0x11, - 0xa3, 0x07, 0x82, 0x71, 0x93, 0x79, 0x93, 0x79, 0x93, 0x79, 0x93, - 0x03, 0xd2, 0xc5, 0x94, 0x0a, 0xb5, 0xfc, 0xff, 0x04, 0xd4, 0x03, - 0x96, 0x40, 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0xdd, 0xf3, 0x11, 0x93, - 0xb8, 0xec, 0x41, 0x42, 0x02, 0x8e, 0x0f, 0x9f, 0xe4, 0xf3, 0xc5, - 0x98, 0x0c, 0x03, 0xff, 0xff, 0x42, 0x42, 0x02, 0x8e, 0x0f, 0x9f, - 0x0b, 0xf4, 0x0a, 0x95, 0xbb, 0xec, 0x42, 0x92, 0x19, 0xd3, 0xb9, - 0xec, 0xc5, 0x96, 0x43, 0x46, 0x02, 0x9e, 0x0f, 0x9f, 0xfd, 0xf3, - 0x0b, 0x07, 0xfc, 0xff, 0xc5, 0xd6, 0xd2, 0x98, 0x1c, 0xd9, 0xc8, - 0xbc, 0xd2, 0x96, 0x1b, 0xd7, 0xca, 0xbc, 0x09, 0x03, 0xff, 0xff, - 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xe9, 0xf3, 0x19, 0xd3, 0xb9, - 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x09, 0xf4, 0x0a, 0x05, - 0xfe, 0xff, 0xca, 0xd2, 0xc2, 0xd2, 0x0f, 0x9f, 0x0b, 0xf4, 0x1a, - 0xd5, 0x93, 0xec, 0x03, 0x98, 0x40, 0x48, 0x02, 0x5e, 0x0f, 0x9f, - 0x38, 0xf4, 0x11, 0x93, 0xb8, 0xec, 0x41, 0x42, 0x02, 0x9e, 0x0f, - 0x9f, 0x1b, 0xf4, 0x04, 0x94, 0x48, 0x44, 0x02, 0x4e, 0x0f, 0x9f, - 0x26, 0xf4, 0x41, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x38, 0xf4, 0x11, - 0x93, 0x04, 0x82, 0x41, 0xb2, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, - 0x38, 0xf4, 0x41, 0x96, 0x01, 0xd6, 0x0a, 0x65, 0xbd, 0x43, 0x02, - 0x99, 0xc4, 0x92, 0x09, 0xa3, 0x80, 0x00, 0xc2, 0xd2, 0x0a, 0x65, - 0xe8, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xbf, 0xff, 0xc2, - 0xd2, 0x0f, 0x9f, 0x97, 0xf4, 0xc5, 0x98, 0x43, 0x48, 0x02, 0x9e, - 0x0f, 0x9f, 0x97, 0xf4, 0x4f, 0x96, 0x0c, 0xb3, 0x01, 0x00, 0x40, - 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x45, 0xf4, 0x47, 0x96, 0x11, 0x93, - 0xb7, 0xec, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x73, 0xf4, 0x11, - 0x93, 0xb8, 0xec, 0x41, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x73, 0xf4, - 0x12, 0x95, 0x00, 0x82, 0x0a, 0x05, 0xff, 0xaf, 0x05, 0xd4, 0xc8, - 0xd6, 0xc8, 0xd2, 0x40, 0xf0, 0x18, 0xf7, 0x42, 0x00, 0x05, 0x96, - 0xc3, 0x94, 0x01, 0xb5, 0x40, 0x44, 0x02, 0x5e, 0x0f, 0x9f, 0x68, - 0xf4, 0x11, 0x93, 0xba, 0xec, 0x4d, 0x42, 0x02, 0x8e, 0x0f, 0x9f, - 0x73, 0xf4, 0x06, 0x98, 0x50, 0x98, 0x1c, 0xd9, 0xa2, 0xbc, 0x40, - 0x98, 0x1c, 0xd9, 0xa2, 0xbc, 0x40, 0x92, 0x03, 0xd2, 0x0f, 0x9f, - 0x9c, 0xf4, 0x03, 0x94, 0x40, 0x44, 0x02, 0x5e, 0x0f, 0x9f, 0x80, - 0xf4, 0x0a, 0x65, 0x5e, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x48, 0xa2, - 0xc2, 0xd2, 0x0f, 0x9f, 0x9c, 0xf4, 0x11, 0x93, 0xb8, 0xec, 0x0c, - 0x99, 0xbb, 0xec, 0x04, 0x03, 0x04, 0x96, 0x13, 0x25, 0x03, 0xec, - 0xc1, 0xd4, 0x11, 0x93, 0xba, 0xec, 0x19, 0x05, 0xba, 0xec, 0x1b, - 0xd7, 0x01, 0x82, 0x0a, 0x65, 0xfd, 0x7d, 0x02, 0x99, 0xc4, 0x92, - 0x43, 0xa2, 0xc2, 0xd2, 0x41, 0x92, 0x01, 0xd2, 0x03, 0x94, 0x40, - 0x44, 0x02, 0x5e, 0x0f, 0x9f, 0xb0, 0xf4, 0x11, 0x93, 0xb9, 0xec, - 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xa8, 0xf4, 0x19, 0xd3, 0xb8, - 0xec, 0x19, 0xd3, 0xba, 0xec, 0x19, 0xd3, 0xbb, 0xec, 0x03, 0x96, - 0x40, 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0xb0, 0xf4, 0x41, 0x98, 0x1c, - 0xd9, 0xb7, 0xec, 0x11, 0x93, 0xbf, 0xec, 0x41, 0x42, 0x02, 0x5e, - 0x0f, 0x9f, 0xc1, 0xf4, 0x11, 0x93, 0x00, 0x82, 0x19, 0xd3, 0x02, - 0x82, 0x0a, 0x65, 0xfd, 0x7d, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3, - 0x00, 0x01, 0xc2, 0xd2, 0x40, 0x98, 0x1c, 0xd9, 0xbf, 0xec, 0x0f, - 0x9f, 0xc9, 0xf4, 0x01, 0x92, 0x19, 0xd3, 0xb7, 0xec, 0x01, 0x94, - 0x40, 0x44, 0x02, 0x5e, 0x0f, 0x9f, 0xd5, 0xf4, 0x0a, 0x65, 0xea, - 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xfb, 0xff, 0xc2, 0xd2, - 0x47, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, - 0x00, 0x12, 0x95, 0x03, 0x80, 0x0a, 0xb3, 0x00, 0x40, 0x40, 0x42, - 0x02, 0x4e, 0x0f, 0x9f, 0xf4, 0xf4, 0x0a, 0xb7, 0x00, 0x08, 0x40, - 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0xf7, 0xf4, 0x11, 0x93, 0x03, 0xec, - 0x41, 0x02, 0x09, 0xb3, 0xfe, 0xff, 0x12, 0x95, 0x07, 0x80, 0x01, - 0x45, 0x02, 0x8e, 0x0f, 0x9f, 0xf7, 0xf4, 0x41, 0x92, 0x0f, 0x9f, - 0xf8, 0xf4, 0x40, 0x92, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x41, - 0x20, 0x08, 0x0b, 0x01, 0x00, 0x0a, 0x65, 0xe9, 0x43, 0x02, 0x97, - 0xc3, 0x92, 0x09, 0xa3, 0x40, 0x00, 0xc2, 0xd2, 0x13, 0x97, 0x6e, - 0xec, 0x0b, 0x47, 0xa0, 0x00, 0x02, 0x5e, 0x0f, 0x9f, 0x23, 0xf5, - 0x09, 0x63, 0x08, 0x43, 0x0a, 0x65, 0xff, 0x5f, 0x01, 0x99, 0xc4, - 0xd4, 0x0a, 0x95, 0x9b, 0xec, 0xd2, 0x96, 0x1b, 0xd7, 0xfa, 0xbc, - 0xd2, 0x96, 0xc4, 0xd6, 0xd2, 0x98, 0x1c, 0xd9, 0xfa, 0xbc, 0xd2, - 0x96, 0xc1, 0xd6, 0xc2, 0x94, 0x1a, 0xd5, 0xfa, 0xbc, 0x0f, 0x9f, - 0x61, 0xf5, 0x0c, 0x69, 0xff, 0x6f, 0x1c, 0xd9, 0xf8, 0xbc, 0x0b, - 0x47, 0x10, 0x95, 0x02, 0x5e, 0x0f, 0x9f, 0x3b, 0xf5, 0x0a, 0x95, - 0x6f, 0xec, 0x09, 0x63, 0x06, 0x43, 0x01, 0x99, 0xc4, 0xd6, 0xd2, - 0x96, 0x1b, 0xd7, 0xf8, 0xbc, 0x0c, 0x69, 0xee, 0x6a, 0xc1, 0xd8, - 0xc2, 0x94, 0x1a, 0xd5, 0xf8, 0xbc, 0x40, 0x92, 0xc5, 0xd2, 0x11, - 0x43, 0xc2, 0xec, 0x02, 0x0e, 0x0f, 0x9f, 0x5e, 0xf5, 0xc5, 0x94, - 0x0a, 0x03, 0x71, 0xec, 0xc1, 0x94, 0x1a, 0xd5, 0xfa, 0xbc, 0x11, - 0x93, 0xc0, 0xec, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x50, 0xf5, - 0x0a, 0x95, 0x6f, 0xec, 0xc8, 0xd4, 0x40, 0xf0, 0x39, 0xf7, 0x19, - 0xd3, 0xf8, 0xbc, 0x41, 0x00, 0xc5, 0x96, 0x41, 0x06, 0xc5, 0xd6, - 0x13, 0x47, 0xc2, 0xec, 0x02, 0x1e, 0x0f, 0x9f, 0x42, 0xf5, 0x40, - 0x98, 0x1c, 0xd9, 0xfa, 0xbc, 0x40, 0x92, 0x19, 0xd3, 0x6e, 0xec, - 0x19, 0xd3, 0xc2, 0xec, 0x0a, 0x65, 0x52, 0x43, 0x02, 0x97, 0xc3, - 0x92, 0x48, 0xa2, 0xc2, 0xd2, 0x0a, 0x65, 0xeb, 0x43, 0x02, 0x99, - 0xc4, 0x92, 0x09, 0xb3, 0xbf, 0xff, 0xc2, 0xd2, 0x41, 0x00, 0x88, - 0x98, 0x90, 0x9a, 0x88, 0xda, 0x43, 0x20, 0x08, 0x0b, 0x01, 0x00, - 0x06, 0x92, 0x01, 0xd2, 0x0a, 0x65, 0xf0, 0x6a, 0x0b, 0x97, 0x6f, - 0xec, 0x02, 0x99, 0xc4, 0x98, 0xd3, 0xd8, 0x02, 0xd6, 0x0a, 0x03, - 0x02, 0x00, 0x01, 0x97, 0xc3, 0x98, 0x02, 0x96, 0xc3, 0xd8, 0x01, - 0x96, 0xc1, 0xd6, 0x1a, 0xd5, 0x6e, 0xec, 0xc5, 0x98, 0x14, 0x99, - 0x6f, 0xec, 0xc2, 0xd8, 0x43, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, - 0xda, 0x08, 0x0b, 0x01, 0x00, 0x40, 0x92, 0xc8, 0xd2, 0x40, 0xf0, - 0x76, 0xf5, 0x41, 0x00, 0x11, 0x93, 0xc0, 0xec, 0x40, 0x42, 0x02, - 0x4e, 0x0f, 0x9f, 0xb0, 0xf5, 0x42, 0x42, 0x02, 0x5e, 0x0f, 0x9f, - 0xad, 0xf5, 0x0a, 0x65, 0xfe, 0x7f, 0x02, 0x97, 0xc3, 0x92, 0x42, - 0xa2, 0xc2, 0xd2, 0x40, 0x92, 0x19, 0xd3, 0xc0, 0xec, 0x0a, 0x65, - 0xeb, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3, 0xc0, 0x00, 0xc2, - 0xd2, 0x0a, 0x65, 0xe9, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, - 0xbf, 0xff, 0xc2, 0xd2, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x63, - 0x20, 0x08, 0x0b, 0x01, 0x00, 0x11, 0x93, 0xaf, 0xbc, 0x47, 0xb2, - 0x59, 0x95, 0x5a, 0x95, 0x12, 0xa5, 0xbf, 0xbc, 0x0a, 0xb3, 0x01, - 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xd2, 0xf5, 0x41, 0x04, - 0x05, 0x93, 0x40, 0x96, 0x20, 0xd6, 0x62, 0x97, 0x0f, 0x9f, 0xe1, - 0xf5, 0x14, 0x99, 0xfc, 0xbc, 0xd1, 0xd8, 0x14, 0x99, 0xfe, 0xbc, - 0xd1, 0xd8, 0x20, 0x98, 0x42, 0x08, 0x20, 0xd8, 0x20, 0x98, 0x03, - 0x49, 0x02, 0x1e, 0x0f, 0x9f, 0xd8, 0xf5, 0xc5, 0x92, 0x62, 0x42, - 0x02, 0x4e, 0x0f, 0x9f, 0xfa, 0xf5, 0x02, 0x8e, 0x0f, 0x9f, 0xf4, - 0xf5, 0x61, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x1e, 0xf6, 0x0f, 0x9f, - 0x4b, 0xf6, 0x63, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x41, 0xf6, 0x0f, - 0x9f, 0x4b, 0xf6, 0x0d, 0x03, 0x01, 0x00, 0x0c, 0x99, 0x71, 0xec, - 0x0b, 0x05, 0xff, 0xff, 0x40, 0x96, 0x0f, 0x9f, 0x07, 0xf6, 0xd1, - 0x96, 0xd4, 0xd6, 0x20, 0x96, 0x41, 0x06, 0x20, 0xd6, 0x02, 0x47, - 0x02, 0x1e, 0x0f, 0x9f, 0x03, 0xf6, 0x1a, 0xd5, 0xc2, 0xec, 0x0a, - 0x65, 0xeb, 0x43, 0x02, 0x99, 0xc4, 0x92, 0x09, 0xa3, 0xc0, 0x00, - 0xc2, 0xd2, 0x0a, 0x65, 0xe9, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, - 0xb3, 0xbf, 0xff, 0xc2, 0xd2, 0x0f, 0x9f, 0x4b, 0xf6, 0x0a, 0x03, - 0xfe, 0xff, 0x61, 0x95, 0x40, 0x98, 0x20, 0xd8, 0x02, 0x49, 0x02, - 0x0e, 0x0f, 0x9f, 0x4b, 0xf6, 0x0d, 0x03, 0x01, 0x00, 0x21, 0xd2, - 0x20, 0x92, 0x05, 0x03, 0x42, 0x02, 0xc8, 0xd2, 0x21, 0x96, 0xc3, - 0x92, 0x42, 0x06, 0x21, 0xd6, 0xc8, 0xd2, 0x22, 0xd4, 0x40, 0xf0, - 0xa2, 0xf0, 0x42, 0x00, 0x20, 0x98, 0x42, 0x08, 0x20, 0xd8, 0x22, - 0x94, 0x02, 0x49, 0x02, 0x1e, 0x0f, 0x9f, 0x2a, 0xf6, 0x0f, 0x9f, - 0x4b, 0xf6, 0x0d, 0x03, 0x03, 0x00, 0xc8, 0xd2, 0x02, 0x92, 0xc8, - 0xd2, 0x01, 0x96, 0xc8, 0xd6, 0x40, 0xf0, 0x4e, 0xf6, 0x43, 0x00, - 0x63, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x45, 0x20, 0x08, - 0x0b, 0x01, 0x00, 0x0d, 0x03, 0x08, 0x00, 0x08, 0x94, 0xc5, 0xd4, - 0x09, 0x05, 0x01, 0x00, 0xc2, 0x94, 0x03, 0xd4, 0x42, 0x02, 0xc1, - 0x92, 0x01, 0xd2, 0x02, 0x97, 0xc5, 0x94, 0x0a, 0x83, 0xff, 0xff, - 0x11, 0xb3, 0x2c, 0x93, 0x09, 0xb3, 0xfb, 0xff, 0x19, 0xd3, 0x2c, - 0x93, 0x03, 0x92, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x81, 0xf6, - 0x01, 0x94, 0xd2, 0x92, 0x19, 0xd3, 0x2c, 0x93, 0x01, 0xd4, 0x02, - 0x94, 0x12, 0x95, 0x2c, 0x93, 0x44, 0xa4, 0x1a, 0xd5, 0x2c, 0x93, - 0x0a, 0xb5, 0xfb, 0xff, 0x1a, 0xd5, 0x2c, 0x93, 0x0b, 0x07, 0xff, - 0xff, 0x40, 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0x6c, 0xf6, 0x09, 0x63, - 0xd4, 0x6c, 0x01, 0x95, 0xc2, 0x96, 0xc5, 0x94, 0x02, 0xa7, 0xc1, - 0xd6, 0x03, 0x92, 0x54, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x91, 0xf6, - 0x0a, 0x83, 0xff, 0xff, 0x1b, 0xb3, 0x2c, 0x93, 0x45, 0x00, 0x88, - 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x09, 0x63, - 0x00, 0x40, 0x19, 0xd3, 0xf2, 0xbd, 0x40, 0xf0, 0xd8, 0xf4, 0x40, - 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xa5, 0xf6, 0x40, 0xf0, 0x3c, 0xf2, - 0x0f, 0x9f, 0xb3, 0xf6, 0x40, 0x96, 0xc8, 0xd6, 0x09, 0x93, 0x91, - 0xec, 0xc8, 0xd2, 0x40, 0xf0, 0xd0, 0xee, 0x0a, 0x65, 0xfe, 0x7f, - 0x02, 0x97, 0xc3, 0x92, 0x44, 0xa2, 0xc2, 0xd2, 0x42, 0x00, 0x88, - 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x0a, 0x65, - 0xe8, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3, 0x40, 0x00, 0xc2, - 0xd2, 0x0a, 0x65, 0xea, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, - 0xfb, 0xff, 0xc2, 0xd2, 0x40, 0x92, 0x19, 0xd3, 0x2d, 0xbc, 0x0a, - 0x65, 0xd8, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xbf, 0xff, - 0xc2, 0xd2, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, - 0x00, 0x09, 0x63, 0xea, 0x43, 0x01, 0x97, 0xc3, 0x94, 0x44, 0xa4, - 0xc1, 0xd4, 0x11, 0x93, 0xb9, 0xec, 0x40, 0x42, 0x02, 0x4e, 0x0f, - 0x9f, 0x0c, 0xf7, 0x12, 0x95, 0x93, 0xec, 0x0b, 0x67, 0x36, 0x43, - 0xd2, 0x98, 0x1c, 0xd9, 0xc8, 0xbc, 0xd2, 0x98, 0x03, 0x93, 0xc1, - 0xd8, 0x11, 0x93, 0xb9, 0xec, 0x09, 0x03, 0xff, 0xff, 0x19, 0xd3, - 0xb9, 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xe5, 0xf6, 0x19, - 0xd3, 0xb8, 0xec, 0x19, 0xd3, 0xba, 0xec, 0x0a, 0x05, 0xfe, 0xff, - 0xca, 0xd2, 0xca, 0xd2, 0xc2, 0xd2, 0x0a, 0x65, 0x5e, 0x43, 0x02, - 0x97, 0xc3, 0x92, 0x48, 0xa2, 0xc2, 0xd2, 0x0a, 0x65, 0xea, 0x43, - 0x02, 0x99, 0xc4, 0x92, 0x09, 0xb3, 0xfb, 0xff, 0x0f, 0x9f, 0x15, - 0xf7, 0x11, 0x93, 0x03, 0xec, 0x19, 0xd3, 0x01, 0x82, 0x0a, 0x65, - 0xfd, 0x7d, 0x02, 0x97, 0xc3, 0x92, 0x43, 0xa2, 0xc2, 0xd2, 0x88, - 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x03, 0x92, - 0x04, 0x96, 0x0d, 0x5e, 0x50, 0x46, 0x02, 0x0e, 0x40, 0x92, 0x09, - 0xee, 0x44, 0x46, 0x04, 0x0e, 0x59, 0x93, 0x44, 0x26, 0x04, 0x5e, - 0x46, 0xee, 0x41, 0x93, 0x41, 0x26, 0x43, 0x4e, 0x88, 0x98, 0x90, - 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x40, 0xf0, 0xb1, 0xfe, - 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x88, - 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x03, 0x94, - 0x1a, 0xd5, 0x40, 0xf7, 0x11, 0x93, 0x00, 0x90, 0x88, 0x98, 0x90, - 0x9a, 0x1d, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x03, 0x00, 0x18, 0x00, - 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x16, 0x00, 0x21, 0x00, 0x12, - 0x00, 0x09, 0x00, 0x13, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, - 0x21, 0x00, 0x2d, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf2, 0x6b, 0xf7, 0x00, 0x00, - 0x1c, 0xf2, 0x6b, 0xf7, 0x00, 0x00, 0x61, 0xf2, 0x68, 0xf7, 0x6f, - 0xf7, 0x00, 0x00, 0x2e, 0xf3, 0x6b, 0xf7, 0x25, 0x47, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 -}; diff --git a/sys/legacy/dev/usb/if_zydreg.h b/sys/legacy/dev/usb/if_zydreg.h deleted file mode 100644 index feae22f..0000000 --- a/sys/legacy/dev/usb/if_zydreg.h +++ /dev/null @@ -1,1322 +0,0 @@ -/* $OpenBSD: if_zydreg.h,v 1.19 2006/11/30 19:28:07 damien Exp $ */ -/* $NetBSD: if_zydreg.h,v 1.2 2007/06/16 11:18:45 kiyohara Exp $ */ -/* $FreeBSD$ */ - -/*- - * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr> - * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * ZyDAS ZD1211/ZD1211B USB WLAN driver. - */ - -#define ZYD_CR_GPI_EN 0x9418 -#define ZYD_CR_RADIO_PD 0x942c -#define ZYD_CR_RF2948_PD 0x942c -#define ZYD_CR_EN_PS_MANUAL_AGC 0x943c -#define ZYD_CR_CONFIG_PHILIPS 0x9440 -#define ZYD_CR_I2C_WRITE 0x9444 -#define ZYD_CR_SA2400_SER_RP 0x9448 -#define ZYD_CR_RADIO_PE 0x9458 -#define ZYD_CR_RST_BUS_MASTER 0x945c -#define ZYD_CR_RFCFG 0x9464 -#define ZYD_CR_HSTSCHG 0x946c -#define ZYD_CR_PHY_ON 0x9474 -#define ZYD_CR_RX_DELAY 0x9478 -#define ZYD_CR_RX_PE_DELAY 0x947c -#define ZYD_CR_GPIO_1 0x9490 -#define ZYD_CR_GPIO_2 0x9494 -#define ZYD_CR_EnZYD_CRyBufMux 0x94a8 -#define ZYD_CR_PS_CTRL 0x9500 -#define ZYD_CR_ADDA_PWR_DWN 0x9504 -#define ZYD_CR_ADDA_MBIAS_WT 0x9508 -#define ZYD_CR_INTERRUPT 0x9510 -#define ZYD_CR_MAC_PS_STATE 0x950c -#define ZYD_CR_ATIM_WND_PERIOD 0x951c -#define ZYD_CR_BCN_INTERVAL 0x9520 -#define ZYD_CR_PRE_TBTT 0x9524 - -/* - * MAC registers. - */ -#define ZYD_MAC_MACADRL 0x9610 /* MAC address (low) */ -#define ZYD_MAC_MACADRH 0x9614 /* MAC address (high) */ -#define ZYD_MAC_BSSADRL 0x9618 /* BSS address (low) */ -#define ZYD_MAC_BSSADRH 0x961c /* BSS address (high) */ -#define ZYD_MAC_BCNCFG 0x9620 /* BCN configuration */ -#define ZYD_MAC_GHTBL 0x9624 /* Group hash table (low) */ -#define ZYD_MAC_GHTBH 0x9628 /* Group hash table (high) */ -#define ZYD_MAC_RX_TIMEOUT 0x962c /* Rx timeout value */ -#define ZYD_MAC_BAS_RATE 0x9630 /* Basic rate setting */ -#define ZYD_MAC_MAN_RATE 0x9634 /* Mandatory rate setting */ -#define ZYD_MAC_RTSCTSRATE 0x9638 /* RTS CTS rate */ -#define ZYD_MAC_BACKOFF_PROTECT 0x963c /* Backoff protection */ -#define ZYD_MAC_RX_THRESHOLD 0x9640 /* Rx threshold */ -#define ZYD_MAC_TX_PE_CONTROL 0x9644 /* Tx_PE control */ -#define ZYD_MAC_AFTER_PNP 0x9648 /* After PnP */ -#define ZYD_MAC_RX_PE_DELAY 0x964c /* Rx_pe delay */ -#define ZYD_MAC_RX_ADDR2_L 0x9650 /* RX address2 (low) */ -#define ZYD_MAC_RX_ADDR2_H 0x9654 /* RX address2 (high) */ -#define ZYD_MAC_SIFS_ACK_TIME 0x9658 /* Dynamic SIFS ack time */ -#define ZYD_MAC_PHY_DELAY 0x9660 /* PHY delay */ -#define ZYD_MAC_PHY_DELAY2 0x966c /* PHY delay */ -#define ZYD_MAC_BCNFIFO 0x9670 /* Beacon FIFO I/O port */ -#define ZYD_MAC_SNIFFER 0x9674 /* Sniffer on/off */ -#define ZYD_MAC_ENCRYPTION_TYPE 0x9678 /* Encryption type */ -#define ZYD_MAC_RETRY 0x967c /* Retry time */ -#define ZYD_MAC_MISC 0x9680 /* Misc */ -#define ZYD_MAC_STMACHINESTAT 0x9684 /* State machine status */ -#define ZYD_MAC_TX_UNDERRUN_CNT 0x9688 /* TX underrun counter */ -#define ZYD_MAC_RXFILTER 0x968c /* Send to host settings */ -#define ZYD_MAC_ACK_EXT 0x9690 /* Acknowledge extension */ -#define ZYD_MAC_BCNFIFOST 0x9694 /* BCN FIFO set and status */ -#define ZYD_MAC_DIFS_EIFS_SIFS 0x9698 /* DIFS, EIFS & SIFS settings */ -#define ZYD_MAC_RX_TIMEOUT_CNT 0x969c /* RX timeout count */ -#define ZYD_MAC_RX_TOTAL_FRAME 0x96a0 /* RX total frame count */ -#define ZYD_MAC_RX_CRC32_CNT 0x96a4 /* RX CRC32 frame count */ -#define ZYD_MAC_RX_CRC16_CNT 0x96a8 /* RX CRC16 frame count */ -#define ZYD_MAC_RX_UDEC 0x96ac /* RX unicast decr. error count */ -#define ZYD_MAC_RX_OVERRUN_CNT 0x96b0 /* RX FIFO overrun count */ -#define ZYD_MAC_RX_MDEC 0x96bc /* RX multicast decr. err. cnt. */ -#define ZYD_MAC_NAV_TCR 0x96c4 /* NAV timer count read */ -#define ZYD_MAC_BACKOFF_ST_RD 0x96c8 /* Backoff status read */ -#define ZYD_MAC_DM_RETRY_CNT_RD 0x96cc /* DM retry count read */ -#define ZYD_MAC_RX_ACR 0x96d0 /* RX arbitration count read */ -#define ZYD_MAC_TX_CCR 0x96d4 /* Tx complete count read */ -#define ZYD_MAC_TCB_ADDR 0x96e8 /* Current PCI process TCP addr */ -#define ZYD_MAC_RCB_ADDR 0x96ec /* Next RCB address */ -#define ZYD_MAC_CONT_WIN_LIMIT 0x96f0 /* Contention window limit */ -#define ZYD_MAC_TX_PKT 0x96f4 /* Tx total packet count read */ -#define ZYD_MAC_DL_CTRL 0x96f8 /* Download control */ -#define ZYD_MAC_CAM_MODE 0x9700 /* CAM: Continuous Access Mode */ -#define ZYD_MACB_TXPWR_CTL1 0x9b00 -#define ZYD_MACB_TXPWR_CTL2 0x9b04 -#define ZYD_MACB_TXPWR_CTL3 0x9b08 -#define ZYD_MACB_TXPWR_CTL4 0x9b0c -#define ZYD_MACB_AIFS_CTL1 0x9b10 -#define ZYD_MACB_AIFS_CTL2 0x9b14 -#define ZYD_MACB_TXOP 0x9b20 -#define ZYD_MACB_MAX_RETRY 0x9b28 - -/* - * Miscellanous registers. - */ -#define ZYD_FIRMWARE_START_ADDR 0xee00 -#define ZYD_FIRMWARE_BASE_ADDR 0xee1d /* Firmware base address */ - -/* - * EEPROM registers. - */ -#define ZYD_EEPROM_START_HEAD 0xf800 /* EEPROM start */ -#define ZYD_EEPROM_SUBID 0xf817 -#define ZYD_EEPROM_POD 0xf819 -#define ZYD_EEPROM_MAC_ADDR_P1 0xf81b /* Part 1 of the MAC address */ -#define ZYD_EEPROM_MAC_ADDR_P2 0xf81d /* Part 2 of the MAC address */ -#define ZYD_EEPROM_PWR_CAL 0xf81f /* Calibration */ -#define ZYD_EEPROM_PWR_INT 0xf827 /* Calibration */ -#define ZYD_EEPROM_ALLOWEDCHAN 0xf82f /* Allowed CH mask, 1 bit each */ -#define ZYD_EEPROM_DEVICE_VER 0xf837 /* Device version */ -#define ZYD_EEPROM_PHY_REG 0xf83c /* PHY registers */ -#define ZYD_EEPROM_36M_CAL 0xf83f /* Calibration */ -#define ZYD_EEPROM_11A_INT 0xf847 /* Interpolation */ -#define ZYD_EEPROM_48M_CAL 0xf84f /* Calibration */ -#define ZYD_EEPROM_48M_INT 0xf857 /* Interpolation */ -#define ZYD_EEPROM_54M_CAL 0xf85f /* Calibration */ -#define ZYD_EEPROM_54M_INT 0xf867 /* Interpolation */ - -/* - * Firmware registers offsets (relative to fwbase). - */ -#define ZYD_FW_FIRMWARE_REV 0x0000 /* Firmware version */ -#define ZYD_FW_USB_SPEED 0x0001 /* USB speed (!=0 if highspeed) */ -#define ZYD_FW_FIX_TX_RATE 0x0002 /* Fixed TX rate */ -#define ZYD_FW_LINK_STATUS 0x0003 -#define ZYD_FW_SOFT_RESET 0x0004 -#define ZYD_FW_FLASH_CHK 0x0005 - -/* possible flags for register ZYD_FW_LINK_STATUS */ -#define ZYD_LED1 (1 << 8) -#define ZYD_LED2 (1 << 9) - -/* - * RF IDs. - */ -#define ZYD_RF_UW2451 0x2 /* not supported yet */ -#define ZYD_RF_UCHIP 0x3 /* not supported yet */ -#define ZYD_RF_AL2230 0x4 -#define ZYD_RF_AL7230B 0x5 -#define ZYD_RF_THETA 0x6 /* not supported yet */ -#define ZYD_RF_AL2210 0x7 -#define ZYD_RF_MAXIM_NEW 0x8 -#define ZYD_RF_GCT 0x9 -#define ZYD_RF_AL2230S 0xa /* not supported yet */ -#define ZYD_RF_RALINK 0xb /* not supported yet */ -#define ZYD_RF_INTERSIL 0xc /* not supported yet */ -#define ZYD_RF_RFMD 0xd -#define ZYD_RF_MAXIM_NEW2 0xe -#define ZYD_RF_PHILIPS 0xf /* not supported yet */ - -/* - * PHY registers (8 bits, not documented). - */ -#define ZYD_CR0 0x9000 -#define ZYD_CR1 0x9004 -#define ZYD_CR2 0x9008 -#define ZYD_CR3 0x900c -#define ZYD_CR5 0x9010 -#define ZYD_CR6 0x9014 -#define ZYD_CR7 0x9018 -#define ZYD_CR8 0x901c -#define ZYD_CR4 0x9020 -#define ZYD_CR9 0x9024 -#define ZYD_CR10 0x9028 -#define ZYD_CR11 0x902c -#define ZYD_CR12 0x9030 -#define ZYD_CR13 0x9034 -#define ZYD_CR14 0x9038 -#define ZYD_CR15 0x903c -#define ZYD_CR16 0x9040 -#define ZYD_CR17 0x9044 -#define ZYD_CR18 0x9048 -#define ZYD_CR19 0x904c -#define ZYD_CR20 0x9050 -#define ZYD_CR21 0x9054 -#define ZYD_CR22 0x9058 -#define ZYD_CR23 0x905c -#define ZYD_CR24 0x9060 -#define ZYD_CR25 0x9064 -#define ZYD_CR26 0x9068 -#define ZYD_CR27 0x906c -#define ZYD_CR28 0x9070 -#define ZYD_CR29 0x9074 -#define ZYD_CR30 0x9078 -#define ZYD_CR31 0x907c -#define ZYD_CR32 0x9080 -#define ZYD_CR33 0x9084 -#define ZYD_CR34 0x9088 -#define ZYD_CR35 0x908c -#define ZYD_CR36 0x9090 -#define ZYD_CR37 0x9094 -#define ZYD_CR38 0x9098 -#define ZYD_CR39 0x909c -#define ZYD_CR40 0x90a0 -#define ZYD_CR41 0x90a4 -#define ZYD_CR42 0x90a8 -#define ZYD_CR43 0x90ac -#define ZYD_CR44 0x90b0 -#define ZYD_CR45 0x90b4 -#define ZYD_CR46 0x90b8 -#define ZYD_CR47 0x90bc -#define ZYD_CR48 0x90c0 -#define ZYD_CR49 0x90c4 -#define ZYD_CR50 0x90c8 -#define ZYD_CR51 0x90cc -#define ZYD_CR52 0x90d0 -#define ZYD_CR53 0x90d4 -#define ZYD_CR54 0x90d8 -#define ZYD_CR55 0x90dc -#define ZYD_CR56 0x90e0 -#define ZYD_CR57 0x90e4 -#define ZYD_CR58 0x90e8 -#define ZYD_CR59 0x90ec -#define ZYD_CR60 0x90f0 -#define ZYD_CR61 0x90f4 -#define ZYD_CR62 0x90f8 -#define ZYD_CR63 0x90fc -#define ZYD_CR64 0x9100 -#define ZYD_CR65 0x9104 -#define ZYD_CR66 0x9108 -#define ZYD_CR67 0x910c -#define ZYD_CR68 0x9110 -#define ZYD_CR69 0x9114 -#define ZYD_CR70 0x9118 -#define ZYD_CR71 0x911c -#define ZYD_CR72 0x9120 -#define ZYD_CR73 0x9124 -#define ZYD_CR74 0x9128 -#define ZYD_CR75 0x912c -#define ZYD_CR76 0x9130 -#define ZYD_CR77 0x9134 -#define ZYD_CR78 0x9138 -#define ZYD_CR79 0x913c -#define ZYD_CR80 0x9140 -#define ZYD_CR81 0x9144 -#define ZYD_CR82 0x9148 -#define ZYD_CR83 0x914c -#define ZYD_CR84 0x9150 -#define ZYD_CR85 0x9154 -#define ZYD_CR86 0x9158 -#define ZYD_CR87 0x915c -#define ZYD_CR88 0x9160 -#define ZYD_CR89 0x9164 -#define ZYD_CR90 0x9168 -#define ZYD_CR91 0x916c -#define ZYD_CR92 0x9170 -#define ZYD_CR93 0x9174 -#define ZYD_CR94 0x9178 -#define ZYD_CR95 0x917c -#define ZYD_CR96 0x9180 -#define ZYD_CR97 0x9184 -#define ZYD_CR98 0x9188 -#define ZYD_CR99 0x918c -#define ZYD_CR100 0x9190 -#define ZYD_CR101 0x9194 -#define ZYD_CR102 0x9198 -#define ZYD_CR103 0x919c -#define ZYD_CR104 0x91a0 -#define ZYD_CR105 0x91a4 -#define ZYD_CR106 0x91a8 -#define ZYD_CR107 0x91ac -#define ZYD_CR108 0x91b0 -#define ZYD_CR109 0x91b4 -#define ZYD_CR110 0x91b8 -#define ZYD_CR111 0x91bc -#define ZYD_CR112 0x91c0 -#define ZYD_CR113 0x91c4 -#define ZYD_CR114 0x91c8 -#define ZYD_CR115 0x91cc -#define ZYD_CR116 0x91d0 -#define ZYD_CR117 0x91d4 -#define ZYD_CR118 0x91d8 -#define ZYD_CR119 0x91dc -#define ZYD_CR120 0x91e0 -#define ZYD_CR121 0x91e4 -#define ZYD_CR122 0x91e8 -#define ZYD_CR123 0x91ec -#define ZYD_CR124 0x91f0 -#define ZYD_CR125 0x91f4 -#define ZYD_CR126 0x91f8 -#define ZYD_CR127 0x91fc -#define ZYD_CR128 0x9200 -#define ZYD_CR129 0x9204 -#define ZYD_CR130 0x9208 -#define ZYD_CR131 0x920c -#define ZYD_CR132 0x9210 -#define ZYD_CR133 0x9214 -#define ZYD_CR134 0x9218 -#define ZYD_CR135 0x921c -#define ZYD_CR136 0x9220 -#define ZYD_CR137 0x9224 -#define ZYD_CR138 0x9228 -#define ZYD_CR139 0x922c -#define ZYD_CR140 0x9230 -#define ZYD_CR141 0x9234 -#define ZYD_CR142 0x9238 -#define ZYD_CR143 0x923c -#define ZYD_CR144 0x9240 -#define ZYD_CR145 0x9244 -#define ZYD_CR146 0x9248 -#define ZYD_CR147 0x924c -#define ZYD_CR148 0x9250 -#define ZYD_CR149 0x9254 -#define ZYD_CR150 0x9258 -#define ZYD_CR151 0x925c -#define ZYD_CR152 0x9260 -#define ZYD_CR153 0x9264 -#define ZYD_CR154 0x9268 -#define ZYD_CR155 0x926c -#define ZYD_CR156 0x9270 -#define ZYD_CR157 0x9274 -#define ZYD_CR158 0x9278 -#define ZYD_CR159 0x927c -#define ZYD_CR160 0x9280 -#define ZYD_CR161 0x9284 -#define ZYD_CR162 0x9288 -#define ZYD_CR163 0x928c -#define ZYD_CR164 0x9290 -#define ZYD_CR165 0x9294 -#define ZYD_CR166 0x9298 -#define ZYD_CR167 0x929c -#define ZYD_CR168 0x92a0 -#define ZYD_CR169 0x92a4 -#define ZYD_CR170 0x92a8 -#define ZYD_CR171 0x92ac -#define ZYD_CR172 0x92b0 -#define ZYD_CR173 0x92b4 -#define ZYD_CR174 0x92b8 -#define ZYD_CR175 0x92bc -#define ZYD_CR176 0x92c0 -#define ZYD_CR177 0x92c4 -#define ZYD_CR178 0x92c8 -#define ZYD_CR179 0x92cc -#define ZYD_CR180 0x92d0 -#define ZYD_CR181 0x92d4 -#define ZYD_CR182 0x92d8 -#define ZYD_CR183 0x92dc -#define ZYD_CR184 0x92e0 -#define ZYD_CR185 0x92e4 -#define ZYD_CR186 0x92e8 -#define ZYD_CR187 0x92ec -#define ZYD_CR188 0x92f0 -#define ZYD_CR189 0x92f4 -#define ZYD_CR190 0x92f8 -#define ZYD_CR191 0x92fc -#define ZYD_CR192 0x9300 -#define ZYD_CR193 0x9304 -#define ZYD_CR194 0x9308 -#define ZYD_CR195 0x930c -#define ZYD_CR196 0x9310 -#define ZYD_CR197 0x9314 -#define ZYD_CR198 0x9318 -#define ZYD_CR199 0x931c -#define ZYD_CR200 0x9320 -#define ZYD_CR201 0x9324 -#define ZYD_CR202 0x9328 -#define ZYD_CR203 0x932c -#define ZYD_CR204 0x9330 -#define ZYD_CR205 0x9334 -#define ZYD_CR206 0x9338 -#define ZYD_CR207 0x933c -#define ZYD_CR208 0x9340 -#define ZYD_CR209 0x9344 -#define ZYD_CR210 0x9348 -#define ZYD_CR211 0x934c -#define ZYD_CR212 0x9350 -#define ZYD_CR213 0x9354 -#define ZYD_CR214 0x9358 -#define ZYD_CR215 0x935c -#define ZYD_CR216 0x9360 -#define ZYD_CR217 0x9364 -#define ZYD_CR218 0x9368 -#define ZYD_CR219 0x936c -#define ZYD_CR220 0x9370 -#define ZYD_CR221 0x9374 -#define ZYD_CR222 0x9378 -#define ZYD_CR223 0x937c -#define ZYD_CR224 0x9380 -#define ZYD_CR225 0x9384 -#define ZYD_CR226 0x9388 -#define ZYD_CR227 0x938c -#define ZYD_CR228 0x9390 -#define ZYD_CR229 0x9394 -#define ZYD_CR230 0x9398 -#define ZYD_CR231 0x939c -#define ZYD_CR232 0x93a0 -#define ZYD_CR233 0x93a4 -#define ZYD_CR234 0x93a8 -#define ZYD_CR235 0x93ac -#define ZYD_CR236 0x93b0 -#define ZYD_CR240 0x93c0 -#define ZYD_CR241 0x93c4 -#define ZYD_CR242 0x93c8 -#define ZYD_CR243 0x93cc -#define ZYD_CR244 0x93d0 -#define ZYD_CR245 0x93d4 -#define ZYD_CR251 0x93ec -#define ZYD_CR252 0x93f0 -#define ZYD_CR253 0x93f4 -#define ZYD_CR254 0x93f8 -#define ZYD_CR255 0x93fc - -/* copied nearly verbatim from the Linux driver rewrite */ -#define ZYD_DEF_PHY \ -{ \ - { ZYD_CR0, 0x0a }, { ZYD_CR1, 0x06 }, { ZYD_CR2, 0x26 }, \ - { ZYD_CR3, 0x38 }, { ZYD_CR4, 0x80 }, { ZYD_CR9, 0xa0 }, \ - { ZYD_CR10, 0x81 }, { ZYD_CR11, 0x00 }, { ZYD_CR12, 0x7f }, \ - { ZYD_CR13, 0x8c }, { ZYD_CR14, 0x80 }, { ZYD_CR15, 0x3d }, \ - { ZYD_CR16, 0x20 }, { ZYD_CR17, 0x1e }, { ZYD_CR18, 0x0a }, \ - { ZYD_CR19, 0x48 }, { ZYD_CR20, 0x0c }, { ZYD_CR21, 0x0c }, \ - { ZYD_CR22, 0x23 }, { ZYD_CR23, 0x90 }, { ZYD_CR24, 0x14 }, \ - { ZYD_CR25, 0x40 }, { ZYD_CR26, 0x10 }, { ZYD_CR27, 0x19 }, \ - { ZYD_CR28, 0x7f }, { ZYD_CR29, 0x80 }, { ZYD_CR30, 0x4b }, \ - { ZYD_CR31, 0x60 }, { ZYD_CR32, 0x43 }, { ZYD_CR33, 0x08 }, \ - { ZYD_CR34, 0x06 }, { ZYD_CR35, 0x0a }, { ZYD_CR36, 0x00 }, \ - { ZYD_CR37, 0x00 }, { ZYD_CR38, 0x38 }, { ZYD_CR39, 0x0c }, \ - { ZYD_CR40, 0x84 }, { ZYD_CR41, 0x2a }, { ZYD_CR42, 0x80 }, \ - { ZYD_CR43, 0x10 }, { ZYD_CR44, 0x12 }, { ZYD_CR46, 0xff }, \ - { ZYD_CR47, 0x1e }, { ZYD_CR48, 0x26 }, { ZYD_CR49, 0x5b }, \ - { ZYD_CR64, 0xd0 }, { ZYD_CR65, 0x04 }, { ZYD_CR66, 0x58 }, \ - { ZYD_CR67, 0xc9 }, { ZYD_CR68, 0x88 }, { ZYD_CR69, 0x41 }, \ - { ZYD_CR70, 0x23 }, { ZYD_CR71, 0x10 }, { ZYD_CR72, 0xff }, \ - { ZYD_CR73, 0x32 }, { ZYD_CR74, 0x30 }, { ZYD_CR75, 0x65 }, \ - { ZYD_CR76, 0x41 }, { ZYD_CR77, 0x1b }, { ZYD_CR78, 0x30 }, \ - { ZYD_CR79, 0x68 }, { ZYD_CR80, 0x64 }, { ZYD_CR81, 0x64 }, \ - { ZYD_CR82, 0x00 }, { ZYD_CR83, 0x00 }, { ZYD_CR84, 0x00 }, \ - { ZYD_CR85, 0x02 }, { ZYD_CR86, 0x00 }, { ZYD_CR87, 0x00 }, \ - { ZYD_CR88, 0xff }, { ZYD_CR89, 0xfc }, { ZYD_CR90, 0x00 }, \ - { ZYD_CR91, 0x00 }, { ZYD_CR92, 0x00 }, { ZYD_CR93, 0x08 }, \ - { ZYD_CR94, 0x00 }, { ZYD_CR95, 0x00 }, { ZYD_CR96, 0xff }, \ - { ZYD_CR97, 0xe7 }, { ZYD_CR98, 0x00 }, { ZYD_CR99, 0x00 }, \ - { ZYD_CR100, 0x00 }, { ZYD_CR101, 0xae }, { ZYD_CR102, 0x02 }, \ - { ZYD_CR103, 0x00 }, { ZYD_CR104, 0x03 }, { ZYD_CR105, 0x65 }, \ - { ZYD_CR106, 0x04 }, { ZYD_CR107, 0x00 }, { ZYD_CR108, 0x0a }, \ - { ZYD_CR109, 0xaa }, { ZYD_CR110, 0xaa }, { ZYD_CR111, 0x25 }, \ - { ZYD_CR112, 0x25 }, { ZYD_CR113, 0x00 }, { ZYD_CR119, 0x1e }, \ - { ZYD_CR125, 0x90 }, { ZYD_CR126, 0x00 }, { ZYD_CR127, 0x00 }, \ - { ZYD_CR5, 0x00 }, { ZYD_CR6, 0x00 }, { ZYD_CR7, 0x00 }, \ - { ZYD_CR8, 0x00 }, { ZYD_CR9, 0x20 }, { ZYD_CR12, 0xf0 }, \ - { ZYD_CR20, 0x0e }, { ZYD_CR21, 0x0e }, { ZYD_CR27, 0x10 }, \ - { ZYD_CR44, 0x33 }, { ZYD_CR47, 0x1E }, { ZYD_CR83, 0x24 }, \ - { ZYD_CR84, 0x04 }, { ZYD_CR85, 0x00 }, { ZYD_CR86, 0x0C }, \ - { ZYD_CR87, 0x12 }, { ZYD_CR88, 0x0C }, { ZYD_CR89, 0x00 }, \ - { ZYD_CR90, 0x10 }, { ZYD_CR91, 0x08 }, { ZYD_CR93, 0x00 }, \ - { ZYD_CR94, 0x01 }, { ZYD_CR95, 0x00 }, { ZYD_CR96, 0x50 }, \ - { ZYD_CR97, 0x37 }, { ZYD_CR98, 0x35 }, { ZYD_CR101, 0x13 }, \ - { ZYD_CR102, 0x27 }, { ZYD_CR103, 0x27 }, { ZYD_CR104, 0x18 }, \ - { ZYD_CR105, 0x12 }, { ZYD_CR109, 0x27 }, { ZYD_CR110, 0x27 }, \ - { ZYD_CR111, 0x27 }, { ZYD_CR112, 0x27 }, { ZYD_CR113, 0x27 }, \ - { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x26 }, { ZYD_CR116, 0x24 }, \ - { ZYD_CR117, 0xfc }, { ZYD_CR118, 0xfa }, { ZYD_CR120, 0x4f }, \ - { ZYD_CR125, 0xaa }, { ZYD_CR127, 0x03 }, { ZYD_CR128, 0x14 }, \ - { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, { ZYD_CR131, 0x0C }, \ - { ZYD_CR136, 0xdf }, { ZYD_CR137, 0x40 }, { ZYD_CR138, 0xa0 }, \ - { ZYD_CR139, 0xb0 }, { ZYD_CR140, 0x99 }, { ZYD_CR141, 0x82 }, \ - { ZYD_CR142, 0x54 }, { ZYD_CR143, 0x1c }, { ZYD_CR144, 0x6c }, \ - { ZYD_CR147, 0x07 }, { ZYD_CR148, 0x4c }, { ZYD_CR149, 0x50 }, \ - { ZYD_CR150, 0x0e }, { ZYD_CR151, 0x18 }, { ZYD_CR160, 0xfe }, \ - { ZYD_CR161, 0xee }, { ZYD_CR162, 0xaa }, { ZYD_CR163, 0xfa }, \ - { ZYD_CR164, 0xfa }, { ZYD_CR165, 0xea }, { ZYD_CR166, 0xbe }, \ - { ZYD_CR167, 0xbe }, { ZYD_CR168, 0x6a }, { ZYD_CR169, 0xba }, \ - { ZYD_CR170, 0xba }, { ZYD_CR171, 0xba }, { ZYD_CR204, 0x7d }, \ - { ZYD_CR203, 0x30 }, { 0, 0} \ -} - -#define ZYD_DEF_PHYB \ -{ \ - { ZYD_CR0, 0x14 }, { ZYD_CR1, 0x06 }, { ZYD_CR2, 0x26 }, \ - { ZYD_CR3, 0x38 }, { ZYD_CR4, 0x80 }, { ZYD_CR9, 0xe0 }, \ - { ZYD_CR10, 0x81 }, { ZYD_CR11, 0x00 }, { ZYD_CR12, 0xf0 }, \ - { ZYD_CR13, 0x8c }, { ZYD_CR14, 0x80 }, { ZYD_CR15, 0x3d }, \ - { ZYD_CR16, 0x20 }, { ZYD_CR17, 0x1e }, { ZYD_CR18, 0x0a }, \ - { ZYD_CR19, 0x48 }, { ZYD_CR20, 0x10 }, { ZYD_CR21, 0x0e }, \ - { ZYD_CR22, 0x23 }, { ZYD_CR23, 0x90 }, { ZYD_CR24, 0x14 }, \ - { ZYD_CR25, 0x40 }, { ZYD_CR26, 0x10 }, { ZYD_CR27, 0x10 }, \ - { ZYD_CR28, 0x7f }, { ZYD_CR29, 0x80 }, { ZYD_CR30, 0x4b }, \ - { ZYD_CR31, 0x60 }, { ZYD_CR32, 0x43 }, { ZYD_CR33, 0x08 }, \ - { ZYD_CR34, 0x06 }, { ZYD_CR35, 0x0a }, { ZYD_CR36, 0x00 }, \ - { ZYD_CR37, 0x00 }, { ZYD_CR38, 0x38 }, { ZYD_CR39, 0x0c }, \ - { ZYD_CR40, 0x84 }, { ZYD_CR41, 0x2a }, { ZYD_CR42, 0x80 }, \ - { ZYD_CR43, 0x10 }, { ZYD_CR44, 0x33 }, { ZYD_CR46, 0xff }, \ - { ZYD_CR47, 0x1E }, { ZYD_CR48, 0x26 }, { ZYD_CR49, 0x5b }, \ - { ZYD_CR64, 0xd0 }, { ZYD_CR65, 0x04 }, { ZYD_CR66, 0x58 }, \ - { ZYD_CR67, 0xc9 }, { ZYD_CR68, 0x88 }, { ZYD_CR69, 0x41 }, \ - { ZYD_CR70, 0x23 }, { ZYD_CR71, 0x10 }, { ZYD_CR72, 0xff }, \ - { ZYD_CR73, 0x32 }, { ZYD_CR74, 0x30 }, { ZYD_CR75, 0x65 }, \ - { ZYD_CR76, 0x41 }, { ZYD_CR77, 0x1b }, { ZYD_CR78, 0x30 }, \ - { ZYD_CR79, 0xf0 }, { ZYD_CR80, 0x64 }, { ZYD_CR81, 0x64 }, \ - { ZYD_CR82, 0x00 }, { ZYD_CR83, 0x24 }, { ZYD_CR84, 0x04 }, \ - { ZYD_CR85, 0x00 }, { ZYD_CR86, 0x0c }, { ZYD_CR87, 0x12 }, \ - { ZYD_CR88, 0x0c }, { ZYD_CR89, 0x00 }, { ZYD_CR90, 0x58 }, \ - { ZYD_CR91, 0x04 }, { ZYD_CR92, 0x00 }, { ZYD_CR93, 0x00 }, \ - { ZYD_CR94, 0x01 }, { ZYD_CR95, 0x20 }, { ZYD_CR96, 0x50 }, \ - { ZYD_CR97, 0x37 }, { ZYD_CR98, 0x35 }, { ZYD_CR99, 0x00 }, \ - { ZYD_CR100, 0x01 }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \ - { ZYD_CR103, 0x27 }, { ZYD_CR104, 0x18 }, { ZYD_CR105, 0x12 }, \ - { ZYD_CR106, 0x04 }, { ZYD_CR107, 0x00 }, { ZYD_CR108, 0x0a }, \ - { ZYD_CR109, 0x27 }, { ZYD_CR110, 0x27 }, { ZYD_CR111, 0x27 }, \ - { ZYD_CR112, 0x27 }, { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, \ - { ZYD_CR115, 0x26 }, { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xfc }, \ - { ZYD_CR118, 0xfa }, { ZYD_CR119, 0x1e }, { ZYD_CR125, 0x90 }, \ - { ZYD_CR126, 0x00 }, { ZYD_CR127, 0x00 }, { ZYD_CR128, 0x14 }, \ - { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, { ZYD_CR131, 0x0c }, \ - { ZYD_CR136, 0xdf }, { ZYD_CR137, 0xa0 }, { ZYD_CR138, 0xa8 }, \ - { ZYD_CR139, 0xb4 }, { ZYD_CR140, 0x98 }, { ZYD_CR141, 0x82 }, \ - { ZYD_CR142, 0x53 }, { ZYD_CR143, 0x1c }, { ZYD_CR144, 0x6c }, \ - { ZYD_CR147, 0x07 }, { ZYD_CR148, 0x40 }, { ZYD_CR149, 0x40 }, \ - { ZYD_CR150, 0x14 }, { ZYD_CR151, 0x18 }, { ZYD_CR159, 0x70 }, \ - { ZYD_CR160, 0xfe }, { ZYD_CR161, 0xee }, { ZYD_CR162, 0xaa }, \ - { ZYD_CR163, 0xfa }, { ZYD_CR164, 0xfa }, { ZYD_CR165, 0xea }, \ - { ZYD_CR166, 0xbe }, { ZYD_CR167, 0xbe }, { ZYD_CR168, 0x6a }, \ - { ZYD_CR169, 0xba }, { ZYD_CR170, 0xba }, { ZYD_CR171, 0xba }, \ - { ZYD_CR204, 0x7d }, { ZYD_CR203, 0x30 }, \ - { 0, 0 } \ -} - -#define ZYD_RFMD_PHY \ -{ \ - { ZYD_CR2, 0x1e }, { ZYD_CR9, 0x20 }, { ZYD_CR10, 0x89 }, \ - { ZYD_CR11, 0x00 }, { ZYD_CR15, 0xd0 }, { ZYD_CR17, 0x68 }, \ - { ZYD_CR19, 0x4a }, { ZYD_CR20, 0x0c }, { ZYD_CR21, 0x0e }, \ - { ZYD_CR23, 0x48 }, { ZYD_CR24, 0x14 }, { ZYD_CR26, 0x90 }, \ - { ZYD_CR27, 0x30 }, { ZYD_CR29, 0x20 }, { ZYD_CR31, 0xb2 }, \ - { ZYD_CR32, 0x43 }, { ZYD_CR33, 0x28 }, { ZYD_CR38, 0x30 }, \ - { ZYD_CR34, 0x0f }, { ZYD_CR35, 0xf0 }, { ZYD_CR41, 0x2a }, \ - { ZYD_CR46, 0x7f }, { ZYD_CR47, 0x1e }, { ZYD_CR51, 0xc5 }, \ - { ZYD_CR52, 0xc5 }, { ZYD_CR53, 0xc5 }, { ZYD_CR79, 0x58 }, \ - { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR82, 0x00 }, \ - { ZYD_CR83, 0x24 }, { ZYD_CR84, 0x04 }, { ZYD_CR85, 0x00 }, \ - { ZYD_CR86, 0x10 }, { ZYD_CR87, 0x2a }, { ZYD_CR88, 0x10 }, \ - { ZYD_CR89, 0x24 }, { ZYD_CR90, 0x18 }, { ZYD_CR91, 0x00 }, \ - { ZYD_CR92, 0x0a }, { ZYD_CR93, 0x00 }, { ZYD_CR94, 0x01 }, \ - { ZYD_CR95, 0x00 }, { ZYD_CR96, 0x40 }, { ZYD_CR97, 0x37 }, \ - { ZYD_CR98, 0x05 }, { ZYD_CR99, 0x28 }, { ZYD_CR100, 0x00 }, \ - { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, { ZYD_CR103, 0x27 }, \ - { ZYD_CR104, 0x18 }, { ZYD_CR105, 0x12 }, { ZYD_CR106, 0x1a }, \ - { ZYD_CR107, 0x24 }, { ZYD_CR108, 0x0a }, { ZYD_CR109, 0x13 }, \ - { ZYD_CR110, 0x2f }, { ZYD_CR111, 0x27 }, { ZYD_CR112, 0x27 }, \ - { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x40 }, \ - { ZYD_CR116, 0x40 }, { ZYD_CR117, 0xf0 }, { ZYD_CR118, 0xf0 }, \ - { ZYD_CR119, 0x16 }, { ZYD_CR122, 0x00 }, { ZYD_CR127, 0x03 }, \ - { ZYD_CR131, 0x08 }, { ZYD_CR138, 0x28 }, { ZYD_CR148, 0x44 }, \ - { ZYD_CR150, 0x10 }, { ZYD_CR169, 0xbb }, { ZYD_CR170, 0xbb } \ -} - -#define ZYD_RFMD_RF \ -{ \ - 0x000007, 0x07dd43, 0x080959, 0x0e6666, 0x116a57, 0x17dd43, \ - 0x1819f9, 0x1e6666, 0x214554, 0x25e7fa, 0x27fffa, 0x294128, \ - 0x2c0000, 0x300000, 0x340000, 0x381e0f, 0x6c180f \ -} - -#define ZYD_RFMD_CHANTABLE \ -{ \ - { 0x181979, 0x1e6666 }, \ - { 0x181989, 0x1e6666 }, \ - { 0x181999, 0x1e6666 }, \ - { 0x1819a9, 0x1e6666 }, \ - { 0x1819b9, 0x1e6666 }, \ - { 0x1819c9, 0x1e6666 }, \ - { 0x1819d9, 0x1e6666 }, \ - { 0x1819e9, 0x1e6666 }, \ - { 0x1819f9, 0x1e6666 }, \ - { 0x181a09, 0x1e6666 }, \ - { 0x181a19, 0x1e6666 }, \ - { 0x181a29, 0x1e6666 }, \ - { 0x181a39, 0x1e6666 }, \ - { 0x181a60, 0x1c0000 } \ -} - -#define ZYD_AL2230_PHY \ -{ \ - { ZYD_CR15, 0x20 }, { ZYD_CR23, 0x40 }, { ZYD_CR24, 0x20 }, \ - { ZYD_CR26, 0x11 }, { ZYD_CR28, 0x3e }, { ZYD_CR29, 0x00 }, \ - { ZYD_CR44, 0x33 }, { ZYD_CR106, 0x2a }, { ZYD_CR107, 0x1a }, \ - { ZYD_CR109, 0x09 }, { ZYD_CR110, 0x27 }, { ZYD_CR111, 0x2b }, \ - { ZYD_CR112, 0x2b }, { ZYD_CR119, 0x0a }, { ZYD_CR10, 0x89 }, \ - { ZYD_CR17, 0x28 }, { ZYD_CR26, 0x93 }, { ZYD_CR34, 0x30 }, \ - { ZYD_CR35, 0x3e }, { ZYD_CR41, 0x24 }, { ZYD_CR44, 0x32 }, \ - { ZYD_CR46, 0x96 }, { ZYD_CR47, 0x1e }, { ZYD_CR79, 0x58 }, \ - { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR87, 0x0a }, \ - { ZYD_CR89, 0x04 }, { ZYD_CR92, 0x0a }, { ZYD_CR99, 0x28 }, \ - { ZYD_CR100, 0x00 }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \ - { ZYD_CR106, 0x24 }, { ZYD_CR107, 0x2a }, { ZYD_CR109, 0x09 }, \ - { ZYD_CR110, 0x13 }, { ZYD_CR111, 0x1f }, { ZYD_CR112, 0x1f }, \ - { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \ - { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0xfc }, \ - { ZYD_CR119, 0x10 }, { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x77 }, \ - { ZYD_CR122, 0xe0 }, { ZYD_CR137, 0x88 }, { ZYD_CR252, 0xff }, \ - { ZYD_CR253, 0xff }, { ZYD_CR251, 0x2f }, { ZYD_CR251, 0x3f }, \ - { ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 } \ -} - -#define ZYD_AL2230_PHY_B \ -{ \ - { ZYD_CR10, 0x89 }, { ZYD_CR15, 0x20 }, { ZYD_CR17, 0x2B }, \ - { ZYD_CR23, 0x40 }, { ZYD_CR24, 0x20 }, { ZYD_CR26, 0x93 }, \ - { ZYD_CR28, 0x3e }, { ZYD_CR29, 0x00 }, { ZYD_CR33, 0x28 }, \ - { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x3e }, { ZYD_CR41, 0x24 }, \ - { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x99 }, { ZYD_CR47, 0x1e }, \ - { ZYD_CR48, 0x06 }, { ZYD_CR49, 0xf9 }, { ZYD_CR51, 0x01 }, \ - { ZYD_CR52, 0x80 }, { ZYD_CR53, 0x7e }, { ZYD_CR65, 0x00 }, \ - { ZYD_CR66, 0x00 }, { ZYD_CR67, 0x00 }, { ZYD_CR68, 0x00 }, \ - { ZYD_CR69, 0x28 }, { ZYD_CR79, 0x58 }, { ZYD_CR80, 0x30 }, \ - { ZYD_CR81, 0x30 }, { ZYD_CR87, 0x0a }, { ZYD_CR89, 0x04 }, \ - { ZYD_CR91, 0x00 }, { ZYD_CR92, 0x0a }, { ZYD_CR98, 0x8d }, \ - { ZYD_CR99, 0x00 }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \ - { ZYD_CR106, 0x24 }, { ZYD_CR107, 0x2a }, { ZYD_CR109, 0x13 }, \ - { ZYD_CR110, 0x1f }, { ZYD_CR111, 0x1f }, { ZYD_CR112, 0x1f }, \ - { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x26 }, \ - { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xfa }, { ZYD_CR118, 0xfa }, \ - { ZYD_CR119, 0x10 }, { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x6c }, \ - { ZYD_CR122, 0xfc }, { ZYD_CR123, 0x57 }, { ZYD_CR125, 0xad }, \ - { ZYD_CR126, 0x6c }, { ZYD_CR127, 0x03 }, { ZYD_CR137, 0x50 }, \ - { ZYD_CR138, 0xa8 }, { ZYD_CR144, 0xac }, { ZYD_CR150, 0x0d }, \ - { ZYD_CR252, 0x34 }, { ZYD_CR253, 0x34 } \ -} - -#define ZYD_AL2230_PHY_PART1 \ -{ \ - { ZYD_CR240, 0x57 }, { ZYD_CR9, 0xe0 } \ -} - -#define ZYD_AL2230_PHY_PART2 \ -{ \ - { ZYD_CR251, 0x2f }, { ZYD_CR251, 0x7f }, \ -} - -#define ZYD_AL2230_PHY_PART3 \ -{ \ - { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \ -} - -#define ZYD_AL2230S_PHY_INIT \ -{ \ - { ZYD_CR47, 0x1e }, { ZYD_CR106, 0x22 }, { ZYD_CR107, 0x2a }, \ - { ZYD_CR109, 0x13 }, { ZYD_CR118, 0xf8 }, { ZYD_CR119, 0x12 }, \ - { ZYD_CR122, 0xe0 }, { ZYD_CR128, 0x10 }, { ZYD_CR129, 0x0e }, \ - { ZYD_CR130, 0x10 } \ -} - -#define ZYD_AL2230_PHY_FINI_PART1 \ -{ \ - { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR79, 0x58 }, \ - { ZYD_CR12, 0xf0 }, { ZYD_CR77, 0x1b }, { ZYD_CR78, 0x58 }, \ - { ZYD_CR203, 0x06 }, { ZYD_CR240, 0x80 }, \ -} - -#define ZYD_AL2230_RF_PART1 \ -{ \ - 0x03f790, 0x033331, 0x00000d, 0x0b3331, 0x03b812, 0x00fff3 \ -} - -#define ZYD_AL2230_RF_PART2 \ -{ \ - 0x000da4, 0x0f4dc5, 0x0805b6, 0x011687, 0x000688, 0x0403b9, \ - 0x00dbba, 0x00099b, 0x0bdffc, 0x00000d, 0x00500f \ -} - -#define ZYD_AL2230_RF_PART3 \ -{ \ - 0x00d00f, 0x004c0f, 0x00540f, 0x00700f, 0x00500f \ -} - -#define ZYD_AL2230_RF_B \ -{ \ - 0x03f790, 0x033331, 0x00000d, 0x0b3331, 0x03b812, 0x00fff3, \ - 0x0005a4, 0x0f4dc5, 0x0805b6, 0x0146c7, 0x000688, 0x0403b9, \ - 0x00dbba, 0x00099b, 0x0bdffc, 0x00000d, 0x00580f \ -} - -#define ZYD_AL2230_RF_B_PART1 \ -{ \ - 0x8cccd0, 0x481dc0, 0xcfff00, 0x25a000 \ -} - -#define ZYD_AL2230_RF_B_PART2 \ -{ \ - 0x25a000, 0xa3b2f0, 0x6da010, 0xe36280, 0x116000, 0x9dc020, \ - 0x5ddb00, 0xd99000, 0x3ffbd0, 0xb00000, 0xf01a00 \ -} - -#define ZYD_AL2230_RF_B_PART3 \ -{ \ - 0xf01b00, 0xf01e00, 0xf01a00 \ -} - -#define ZYD_AL2230_CHANTABLE \ -{ \ - { 0x03f790, 0x033331, 0x00000d }, \ - { 0x03f790, 0x0b3331, 0x00000d }, \ - { 0x03e790, 0x033331, 0x00000d }, \ - { 0x03e790, 0x0b3331, 0x00000d }, \ - { 0x03f7a0, 0x033331, 0x00000d }, \ - { 0x03f7a0, 0x0b3331, 0x00000d }, \ - { 0x03e7a0, 0x033331, 0x00000d }, \ - { 0x03e7a0, 0x0b3331, 0x00000d }, \ - { 0x03f7b0, 0x033331, 0x00000d }, \ - { 0x03f7b0, 0x0b3331, 0x00000d }, \ - { 0x03e7b0, 0x033331, 0x00000d }, \ - { 0x03e7b0, 0x0b3331, 0x00000d }, \ - { 0x03f7c0, 0x033331, 0x00000d }, \ - { 0x03e7c0, 0x066661, 0x00000d } \ -} - -#define ZYD_AL2230_CHANTABLE_B \ -{ \ - { 0x09efc0, 0x8cccc0, 0xb00000 }, \ - { 0x09efc0, 0x8cccd0, 0xb00000 }, \ - { 0x09e7c0, 0x8cccc0, 0xb00000 }, \ - { 0x09e7c0, 0x8cccd0, 0xb00000 }, \ - { 0x05efc0, 0x8cccc0, 0xb00000 }, \ - { 0x05efc0, 0x8cccd0, 0xb00000 }, \ - { 0x05e7c0, 0x8cccc0, 0xb00000 }, \ - { 0x05e7c0, 0x8cccd0, 0xb00000 }, \ - { 0x0defc0, 0x8cccc0, 0xb00000 }, \ - { 0x0defc0, 0x8cccd0, 0xb00000 }, \ - { 0x0de7c0, 0x8cccc0, 0xb00000 }, \ - { 0x0de7c0, 0x8cccd0, 0xb00000 }, \ - { 0x03efc0, 0x8cccc0, 0xb00000 }, \ - { 0x03e7c0, 0x866660, 0xb00000 } \ -} - -#define ZYD_AL7230B_PHY_1 \ -{ \ - { ZYD_CR240, 0x57 }, { ZYD_CR15, 0x20 }, { ZYD_CR23, 0x40 }, \ - { ZYD_CR24, 0x20 }, { ZYD_CR26, 0x11 }, { ZYD_CR28, 0x3e }, \ - { ZYD_CR29, 0x00 }, { ZYD_CR44, 0x33 }, { ZYD_CR106, 0x22 }, \ - { ZYD_CR107, 0x1a }, { ZYD_CR109, 0x09 }, { ZYD_CR110, 0x27 }, \ - { ZYD_CR111, 0x2b }, { ZYD_CR112, 0x2b }, { ZYD_CR119, 0x0a }, \ - { ZYD_CR122, 0xfc }, { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x28 }, \ - { ZYD_CR26, 0x93 }, { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x3e }, \ - { ZYD_CR41, 0x24 }, { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x96 }, \ - { ZYD_CR47, 0x1e }, { ZYD_CR79, 0x58 }, { ZYD_CR80, 0x30 }, \ - { ZYD_CR81, 0x30 }, { ZYD_CR87, 0x0a }, { ZYD_CR89, 0x04 }, \ - { ZYD_CR92, 0x0a }, { ZYD_CR99, 0x28 }, { ZYD_CR100, 0x02 }, \ - { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, { ZYD_CR106, 0x22 }, \ - { ZYD_CR107, 0x3f }, { ZYD_CR109, 0x09 }, { ZYD_CR110, 0x1f }, \ - { ZYD_CR111, 0x1f }, { ZYD_CR112, 0x1f }, { ZYD_CR113, 0x27 }, \ - { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, { ZYD_CR116, 0x3f }, \ - { ZYD_CR117, 0xfa }, { ZYD_CR118, 0xfc }, { ZYD_CR119, 0x10 }, \ - { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x77 }, { ZYD_CR137, 0x88 }, \ - { ZYD_CR138, 0xa8 }, { ZYD_CR252, 0x34 }, { ZYD_CR253, 0x34 }, \ - { ZYD_CR251, 0x2f } \ -} - -#define ZYD_AL7230B_PHY_2 \ -{ \ - { ZYD_CR251, 0x3f }, { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, \ - { ZYD_CR130, 0x10 }, { ZYD_CR38, 0x38 }, { ZYD_CR136, 0xdf } \ -} - -#define ZYD_AL7230B_PHY_3 \ -{ \ - { ZYD_CR203, 0x06 }, { ZYD_CR240, 0x80 } \ -} - -#define ZYD_AL7230B_RF_1 \ -{ \ - 0x09ec04, 0x8cccc8, 0x4ff821, 0xc5fbfc, 0x21ebfe, 0xafd401, \ - 0x6cf56a, 0xe04073, 0x193d76, 0x9dd844, 0x500007, 0xd8c010, \ - 0x3c9000, 0xbfffff, 0x700000, 0xf15d58 \ -} - -#define ZYD_AL7230B_RF_2 \ -{ \ - 0xf15d59, 0xf15d5c, 0xf15d58 \ -} - -#define ZYD_AL7230B_RF_SETCHANNEL \ -{ \ - 0x4ff821, 0xc5fbfc, 0x21ebfe, 0xafd401, 0x6cf56a, 0xe04073, \ - 0x193d76, 0x9dd844, 0x500007, 0xd8c010, 0x3c9000, 0xf15d58 \ -} - -#define ZYD_AL7230B_CHANTABLE \ -{ \ - { 0x09ec00, 0x8cccc8 }, \ - { 0x09ec00, 0x8cccd8 }, \ - { 0x09ec00, 0x8cccc0 }, \ - { 0x09ec00, 0x8cccd0 }, \ - { 0x05ec00, 0x8cccc8 }, \ - { 0x05ec00, 0x8cccd8 }, \ - { 0x05ec00, 0x8cccc0 }, \ - { 0x05ec00, 0x8cccd0 }, \ - { 0x0dec00, 0x8cccc8 }, \ - { 0x0dec00, 0x8cccd8 }, \ - { 0x0dec00, 0x8cccc0 }, \ - { 0x0dec00, 0x8cccd0 }, \ - { 0x03ec00, 0x8cccc8 }, \ - { 0x03ec00, 0x866660 } \ -} - -#define ZYD_AL2210_PHY \ -{ \ - { ZYD_CR9, 0xe0 }, { ZYD_CR10, 0x91 }, { ZYD_CR12, 0x90 }, \ - { ZYD_CR15, 0xd0 }, { ZYD_CR16, 0x40 }, { ZYD_CR17, 0x58 }, \ - { ZYD_CR18, 0x04 }, { ZYD_CR23, 0x66 }, { ZYD_CR24, 0x14 }, \ - { ZYD_CR26, 0x90 }, { ZYD_CR31, 0x80 }, { ZYD_CR34, 0x06 }, \ - { ZYD_CR35, 0x3e }, { ZYD_CR38, 0x38 }, { ZYD_CR46, 0x90 }, \ - { ZYD_CR47, 0x1e }, { ZYD_CR64, 0x64 }, { ZYD_CR79, 0xb5 }, \ - { ZYD_CR80, 0x38 }, { ZYD_CR81, 0x30 }, { ZYD_CR113, 0xc0 }, \ - { ZYD_CR127, 0x03 } \ -} - -#define ZYD_AL2210_RF \ -{ \ - 0x2396c0, 0x00fcb1, 0x358132, 0x0108b3, 0xc77804, 0x456415, \ - 0xff2226, 0x806667, 0x7860f8, 0xbb01c9, 0x00000a, 0x00000b \ -} - -#define ZYD_AL2210_CHANTABLE \ -{ \ - 0x0196c0, 0x019710, 0x019760, 0x0197b0, 0x019800, 0x019850, \ - 0x0198a0, 0x0198f0, 0x019940, 0x019990, 0x0199e0, 0x019a30, \ - 0x019a80, 0x019b40 \ -} - -#define ZYD_GCT_PHY \ -{ \ - { ZYD_CR47, 0x1e }, { ZYD_CR15, 0xdc }, { ZYD_CR113, 0xc0 }, \ - { ZYD_CR20, 0x0c }, { ZYD_CR17, 0x65 }, { ZYD_CR34, 0x04 }, \ - { ZYD_CR35, 0x35 }, { ZYD_CR24, 0x20 }, { ZYD_CR9, 0xe0 }, \ - { ZYD_CR127, 0x02 }, { ZYD_CR10, 0x91 }, { ZYD_CR23, 0x7f }, \ - { ZYD_CR27, 0x10 }, { ZYD_CR28, 0x7a }, { ZYD_CR79, 0xb5 }, \ - { ZYD_CR64, 0x80 }, { ZYD_CR33, 0x28 }, { ZYD_CR38, 0x30 } \ -} - -#define ZYD_GCT_RF \ -{ \ - 0x1f0000, 0x1f0000, 0x1f0200, 0x1f0600, 0x1f8600, 0x1f8600, \ - 0x002050, 0x1f8000, 0x1f8200, 0x1f8600, 0x1c0000, 0x10c458, \ - 0x088e92, 0x187b82, 0x0401b4, 0x140816, 0x0c7000, 0x1c0000, \ - 0x02ccae, 0x128023, 0x0a0000, 0x1a0000, 0x06e380, 0x16cb94, \ - 0x0e1740, 0x014980, 0x116240, 0x090000, 0x192304, 0x05112f, \ - 0x0d54a8, 0x0f8000, 0x1c0008, 0x1c0000, 0x1a0000, 0x1c0008, \ - 0x150000, 0x0c7000, 0x150800, 0x150000 \ -} - -#define ZYD_GCT_CHANTABLE \ -{ \ - 0x1a0000, 0x1a8000, 0x1a4000, 0x1ac000, 0x1a2000, 0x1aa000, \ - 0x1a6000, 0x1ae000, 0x1a1000, 0x1a9000, 0x1a5000, 0x1ad000, \ - 0x1a3000, 0x1ab000 \ -} - -#define ZYD_MAXIM_PHY \ -{ \ - { ZYD_CR23, 0x40 }, { ZYD_CR15, 0x20 }, { ZYD_CR28, 0x3e }, \ - { ZYD_CR29, 0x00 }, { ZYD_CR26, 0x11 }, { ZYD_CR44, 0x33 }, \ - { ZYD_CR106, 0x2a }, { ZYD_CR107, 0x1a }, { ZYD_CR109, 0x2b }, \ - { ZYD_CR110, 0x2b }, { ZYD_CR111, 0x2b }, { ZYD_CR112, 0x2b }, \ - { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x20 }, { ZYD_CR26, 0x93 }, \ - { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x40 }, { ZYD_CR41, 0x24 }, \ - { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x90 }, { ZYD_CR89, 0x18 }, \ - { ZYD_CR92, 0x0a }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \ - { ZYD_CR106, 0x20 }, { ZYD_CR107, 0x24 }, { ZYD_CR109, 0x09 }, \ - { ZYD_CR110, 0x13 }, { ZYD_CR111, 0x13 }, { ZYD_CR112, 0x13 }, \ - { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \ - { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0xfa }, \ - { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x77 }, { ZYD_CR122, 0xfe }, \ - { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x20 }, { ZYD_CR26, 0x93 }, \ - { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x40 }, { ZYD_CR41, 0x24 }, \ - { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x90 }, { ZYD_CR89, 0x18 }, \ - { ZYD_CR92, 0x0a }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \ - { ZYD_CR106, 0x20 }, { ZYD_CR107, 0x24 }, { ZYD_CR109, 0x13 }, \ - { ZYD_CR110, 0x27 }, { ZYD_CR111, 0x27 }, { ZYD_CR112, 0x13 }, \ - { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \ - { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0x00 }, \ - { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x06 }, { ZYD_CR122, 0xfe }, \ - { ZYD_CR150, 0x0d } \ -} - -#define ZYD_MAXIM_RF \ -{ \ - 0x00ccd4, 0x030a03, 0x000400, 0x000ca1, 0x010072, 0x018645, \ - 0x004006, 0x0000a7, 0x008258, 0x003fc9, 0x00040a, 0x00000b, \ - 0x00026c \ -} - -#define ZYD_MAXIM_CHANTABLE \ -{ \ - { 0x0ccd4, 0x30a03 }, \ - { 0x22224, 0x00a13 }, \ - { 0x37774, 0x10a13 }, \ - { 0x0ccd4, 0x30a13 }, \ - { 0x22224, 0x00a23 }, \ - { 0x37774, 0x10a23 }, \ - { 0x0ccd4, 0x30a23 }, \ - { 0x22224, 0x00a33 }, \ - { 0x37774, 0x10a33 }, \ - { 0x0ccd4, 0x30a33 }, \ - { 0x22224, 0x00a43 }, \ - { 0x37774, 0x10a43 }, \ - { 0x0ccd4, 0x30a43 }, \ - { 0x199a4, 0x20a53 } \ -} - -#define ZYD_MAXIM2_PHY \ -{ \ - { ZYD_CR23, 0x40 }, { ZYD_CR15, 0x20 }, { ZYD_CR28, 0x3e }, \ - { ZYD_CR29, 0x00 }, { ZYD_CR26, 0x11 }, { ZYD_CR44, 0x33 }, \ - { ZYD_CR106, 0x2a }, { ZYD_CR107, 0x1a }, { ZYD_CR109, 0x2b }, \ - { ZYD_CR110, 0x2b }, { ZYD_CR111, 0x2b }, { ZYD_CR112, 0x2b }, \ - { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x20 }, { ZYD_CR26, 0x93 }, \ - { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x40 }, { ZYD_CR41, 0x24 }, \ - { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x90 }, { ZYD_CR89, 0x18 }, \ - { ZYD_CR92, 0x0a }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \ - { ZYD_CR106, 0x20 }, { ZYD_CR107, 0x24 }, { ZYD_CR109, 0x09 }, \ - { ZYD_CR110, 0x13 }, { ZYD_CR111, 0x13 }, { ZYD_CR112, 0x13 }, \ - { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \ - { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0xfa }, \ - { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x77 }, { ZYD_CR122, 0xfe }, \ - { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x20 }, { ZYD_CR26, 0x93 }, \ - { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x40 }, { ZYD_CR41, 0x24 }, \ - { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x90 }, { ZYD_CR79, 0x58 }, \ - { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR89, 0x18 }, \ - { ZYD_CR92, 0x0a }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \ - { ZYD_CR106, 0x20 }, { ZYD_CR107, 0x24 }, { ZYD_CR109, 0x09 }, \ - { ZYD_CR110, 0x13 }, { ZYD_CR111, 0x13 }, { ZYD_CR112, 0x13 }, \ - { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \ - { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0x00 }, \ - { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x06 }, { ZYD_CR122, 0xfe } \ -} - -#define ZYD_MAXIM2_RF \ -{ \ - 0x33334, 0x10a03, 0x00400, 0x00ca1, 0x10072, 0x18645, 0x04006, \ - 0x000a7, 0x08258, 0x03fc9, 0x0040a, 0x0000b, 0x0026c \ -} - -#define ZYD_MAXIM2_CHANTABLE_F \ -{ \ - 0x33334, 0x08884, 0x1ddd4, 0x33334, 0x08884, 0x1ddd4, 0x33334, \ - 0x08884, 0x1ddd4, 0x33334, 0x08884, 0x1ddd4, 0x33334, 0x26664 \ -} - -#define ZYD_MAXIM2_CHANTABLE \ -{ \ - { 0x33334, 0x10a03 }, \ - { 0x08884, 0x20a13 }, \ - { 0x1ddd4, 0x30a13 }, \ - { 0x33334, 0x10a13 }, \ - { 0x08884, 0x20a23 }, \ - { 0x1ddd4, 0x30a23 }, \ - { 0x33334, 0x10a23 }, \ - { 0x08884, 0x20a33 }, \ - { 0x1ddd4, 0x30a33 }, \ - { 0x33334, 0x10a33 }, \ - { 0x08884, 0x20a43 }, \ - { 0x1ddd4, 0x30a43 }, \ - { 0x33334, 0x10a43 }, \ - { 0x26664, 0x20a53 } \ -} - -/* - * Control pipe requests. - */ -#define ZYD_DOWNLOADREQ 0x30 -#define ZYD_DOWNLOADSTS 0x31 -#define ZYD_READFWDATAREQ 0x32 - -/* possible values for register ZYD_CR_INTERRUPT */ -#define ZYD_HWINT_MASK 0x004f0000 - -/* possible values for register ZYD_MAC_MISC */ -#define ZYD_UNLOCK_PHY_REGS 0x80 - -/* possible values for register ZYD_MAC_ENCRYPTION_TYPE */ -#define ZYD_ENC_SNIFFER 8 - -/* flags for register ZYD_MAC_RXFILTER */ -#define ZYD_FILTER_ASS_REQ (1 << 0) -#define ZYD_FILTER_ASS_RSP (1 << 1) -#define ZYD_FILTER_REASS_REQ (1 << 2) -#define ZYD_FILTER_REASS_RSP (1 << 3) -#define ZYD_FILTER_PRB_REQ (1 << 4) -#define ZYD_FILTER_PRB_RSP (1 << 5) -#define ZYD_FILTER_BCN (1 << 8) -#define ZYD_FILTER_ATIM (1 << 9) -#define ZYD_FILTER_DEASS (1 << 10) -#define ZYD_FILTER_AUTH (1 << 11) -#define ZYD_FILTER_DEAUTH (1 << 12) -#define ZYD_FILTER_PS_POLL (1 << 26) -#define ZYD_FILTER_RTS (1 << 27) -#define ZYD_FILTER_CTS (1 << 28) -#define ZYD_FILTER_ACK (1 << 29) -#define ZYD_FILTER_CFE (1 << 30) -#define ZYD_FILTER_CFE_A (1 << 31) - -/* helpers for register ZYD_MAC_RXFILTER */ -#define ZYD_FILTER_MONITOR 0xffffffff -#define ZYD_FILTER_BSS \ - (ZYD_FILTER_ASS_REQ | ZYD_FILTER_ASS_RSP | \ - ZYD_FILTER_REASS_REQ | ZYD_FILTER_REASS_RSP | \ - ZYD_FILTER_PRB_REQ | ZYD_FILTER_PRB_RSP | \ - (0x3 << 6) | \ - ZYD_FILTER_BCN | ZYD_FILTER_ATIM | ZYD_FILTER_DEASS | \ - ZYD_FILTER_AUTH | ZYD_FILTER_DEAUTH | \ - (0x7 << 13) | \ - ZYD_FILTER_PS_POLL | ZYD_FILTER_ACK) -#define ZYD_FILTER_HOSTAP \ - (ZYD_FILTER_ASS_REQ | ZYD_FILTER_REASS_REQ | \ - ZYD_FILTER_PRB_REQ | ZYD_FILTER_DEASS | ZYD_FILTER_AUTH | \ - ZYD_FILTER_DEAUTH | ZYD_FILTER_PS_POLL) - -struct zyd_tx_desc { - uint8_t phy; -#define ZYD_TX_PHY_SIGNAL(x) ((x) & 0xf) -#define ZYD_TX_PHY_OFDM (1 << 4) -#define ZYD_TX_PHY_SHPREAMBLE (1 << 5) /* CCK */ -#define ZYD_TX_PHY_5GHZ (1 << 5) /* OFDM */ - uint16_t len; - uint8_t flags; -#define ZYD_TX_FLAG_BACKOFF (1 << 0) -#define ZYD_TX_FLAG_MULTICAST (1 << 1) -#define ZYD_TX_FLAG_TYPE(x) (((x) & 0x3) << 2) -#define ZYD_TX_TYPE_DATA 0 -#define ZYD_TX_TYPE_PS_POLL 1 -#define ZYD_TX_TYPE_MGMT 2 -#define ZYD_TX_TYPE_CTL 3 -#define ZYD_TX_FLAG_WAKEUP (1 << 4) -#define ZYD_TX_FLAG_RTS (1 << 5) -#define ZYD_TX_FLAG_ENCRYPT (1 << 6) -#define ZYD_TX_FLAG_CTS_TO_SELF (1 << 7) - uint16_t pktlen; - uint16_t plcp_length; - uint8_t plcp_service; -#define ZYD_PLCP_LENGEXT 0x80 - uint16_t nextlen; -} __packed; - -struct zyd_plcphdr { - uint8_t signal; - uint8_t reserved[2]; - uint16_t service; /* unaligned! */ -} __packed; - -struct zyd_rx_stat { - uint8_t signal_cck; - uint8_t rssi; - uint8_t signal_ofdm; - uint8_t cipher; -#define ZYD_RX_CIPHER_WEP64 1 -#define ZYD_RX_CIPHER_TKIP 2 -#define ZYD_RX_CIPHER_AES 4 -#define ZYD_RX_CIPHER_WEP128 5 -#define ZYD_RX_CIPHER_WEP256 6 -#define ZYD_RX_CIPHER_WEP \ - (ZYD_RX_CIPHER_WEP64 | ZYD_RX_CIPHER_WEP128 | ZYD_RX_CIPHER_WEP256) - uint8_t flags; -#define ZYD_RX_OFDM (1 << 0) -#define ZYD_RX_TIMEOUT (1 << 1) -#define ZYD_RX_OVERRUN (1 << 2) -#define ZYD_RX_DECRYPTERR (1 << 3) -#define ZYD_RX_BADCRC32 (1 << 4) -#define ZYD_RX_NOT2ME (1 << 5) -#define ZYD_RX_BADCRC16 (1 << 6) -#define ZYD_RX_ERROR (1 << 7) -} __packed; - -/* this structure may be unaligned */ -struct zyd_rx_desc { -#define ZYD_MAX_RXFRAMECNT 3 - uWord len[ZYD_MAX_RXFRAMECNT]; - uWord tag; -#define ZYD_TAG_MULTIFRAME 0x697e -} __packed; - -/* I2C bus alike */ -struct zyd_rfwrite_cmd { - uint16_t code; - uint16_t width; - uint16_t bit[32]; -#define ZYD_RF_IF_LE (1 << 1) -#define ZYD_RF_CLK (1 << 2) -#define ZYD_RF_DATA (1 << 3) -} __packed; - -struct zyd_cmd { - uint16_t code; -#define ZYD_CMD_IOWR 0x0021 /* write HMAC or PHY register */ -#define ZYD_CMD_IORD 0x0022 /* read HMAC or PHY register */ -#define ZYD_CMD_RFCFG 0x0023 /* write RF register */ -#define ZYD_NOTIF_IORD 0x9001 /* response for ZYD_CMD_IORD */ -#define ZYD_NOTIF_MACINTR 0x9001 /* interrupt notification */ -#define ZYD_NOTIF_RETRYSTATUS 0xa001 /* Tx retry notification */ - uint8_t data[64]; -} __packed; - -/* structure for command ZYD_CMD_IOWR */ -struct zyd_pair { - uint16_t reg; -/* helpers macros to read/write 32-bit registers */ -#define ZYD_REG32_LO(reg) (reg) -#define ZYD_REG32_HI(reg) \ - ((reg) + ((((reg) & 0xf000) == 0x9000) ? 2 : 1)) - uint16_t val; -} __packed; - -/* structure for notification ZYD_NOTIF_RETRYSTATUS */ -struct zyd_notif_retry { - uint16_t rate; - uint8_t macaddr[IEEE80211_ADDR_LEN]; - uint16_t count; -} __packed; - -#define ZYD_CONFIG_NO 1 -#define ZYD_IFACE_INDEX 0 - -#define ZYD_INTR_TIMEOUT 1000 -#define ZYD_TX_TIMEOUT 10000 - -#define ZYD_MAX_TXBUFSZ \ - (sizeof(struct zyd_tx_desc) + MCLBYTES) -#define ZYD_MIN_FRAGSZ \ - (sizeof(struct zyd_plcphdr) + IEEE80211_MIN_LEN + \ - sizeof(struct zyd_rx_stat)) -#define ZYD_MIN_RXBUFSZ ZYD_MIN_FRAGSZ -#define ZYX_MAX_RXBUFSZ \ - ((sizeof (struct zyd_plcphdr) + IEEE80211_MAX_LEN + \ - sizeof (struct zyd_rx_stat)) * ZYD_MAX_RXFRAMECNT + \ - sizeof (struct zyd_rx_desc)) - -#define ZYD_RX_LIST_CNT 1 -#define ZYD_TX_LIST_CNT 5 -#define ZYD_CMD_FLAG_READ (1 << 0) - -/* quickly determine if a given rate is CCK or OFDM */ -#define ZYD_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22) - -struct zyd_phy_pair { - uint16_t reg; - uint8_t val; -}; - -struct zyd_mac_pair { - uint16_t reg; - uint32_t val; -}; - -struct zyd_tx_data { - struct zyd_softc *sc; - usbd_xfer_handle xfer; - uint8_t *buf; - struct ieee80211_node *ni; - struct mbuf *m; -}; - -struct zyd_rx_data { - struct zyd_softc *sc; - usbd_xfer_handle xfer; - const uint8_t *buf; -}; - -struct zyd_node { - struct ieee80211_node ni; /* must be the first */ - struct ieee80211_amrr_node amn; -}; -#define ZYD_NODE(ni) ((struct zyd_node *)(ni)) - -struct zyd_rx_radiotap_header { - struct ieee80211_radiotap_header wr_ihdr; - uint8_t wr_flags; - uint8_t wr_rate; - uint16_t wr_chan_freq; - uint16_t wr_chan_flags; - int8_t wr_antsignal; - int8_t wr_antnoise; -} __packed; - -#define ZYD_RX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_FLAGS) | \ - (1 << IEEE80211_RADIOTAP_RATE) | \ - (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ - (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ - (1 << IEEE80211_RADIOTAP_CHANNEL)) - -struct zyd_tx_radiotap_header { - struct ieee80211_radiotap_header wt_ihdr; - uint8_t wt_flags; - uint8_t wt_rate; - uint16_t wt_chan_freq; - uint16_t wt_chan_flags; -} __packed; - -#define ZYD_TX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_FLAGS) | \ - (1 << IEEE80211_RADIOTAP_RATE) | \ - (1 << IEEE80211_RADIOTAP_CHANNEL)) - -struct zyd_softc; /* forward declaration */ - -struct zyd_rf { - /* RF methods */ - int (*init)(struct zyd_rf *); - int (*switch_radio)(struct zyd_rf *, int); - int (*set_channel)(struct zyd_rf *, uint8_t); - int (*bandedge6)(struct zyd_rf *, - struct ieee80211_channel *); - /* RF attributes */ - struct zyd_softc *rf_sc; /* back-pointer */ - int width; -}; - -struct zyd_rq { - const uint16_t *idata; - struct zyd_pair *odata; - int len; - STAILQ_ENTRY(zyd_rq) rq; -}; - -struct zyd_vap { - struct ieee80211vap vap; - int (*newstate)(struct ieee80211vap *, - enum ieee80211_state, int); - struct callout amrr_ch; - struct ieee80211_amrr amrr; -}; -#define ZYD_VAP(vap) ((struct zyd_vap *)(vap)) - -struct zyd_softc { - device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; - struct ifnet *sc_ifp; - - enum ieee80211_state sc_state; - int sc_arg; - int sc_flags; -#define ZYD_FLAG_FWLOADED (1 << 0) -#define ZYD_FLAG_DETACHING (1 << 1) -#define ZYD_FLAG_INITONCE (1 << 2) -#define ZYD_FLAG_INITDONE (1 << 3) - int sc_if_flags; - uint32_t sc_debug; - - struct usb_task sc_mcasttask; - struct usb_task sc_scantask; - int sc_scan_action; -#define ZYD_SCAN_START 0 -#define ZYD_SCAN_END 1 -#define ZYD_SET_CHANNEL 2 - struct usb_task sc_task; - struct callout sc_watchdog_ch; - - struct zyd_rf sc_rf; - - STAILQ_HEAD(, zyd_rq) sc_rqh; - - uint8_t sc_bssid[IEEE80211_ADDR_LEN]; - uint16_t sc_fwbase; - uint8_t sc_regdomain; - uint8_t sc_macrev; - uint16_t sc_fwrev; - uint8_t sc_rfrev; - uint8_t sc_parev; - uint8_t sc_al2230s; - uint8_t sc_bandedge6; - uint8_t sc_newphy; - uint8_t sc_cckgain; - uint8_t sc_fix_cr157; - uint8_t sc_ledtype; - uint8_t sc_txled; - - uint32_t sc_atim_wnd; - uint32_t sc_pre_tbtt; - uint32_t sc_bcn_int; - - uint8_t sc_pwrcal[14]; - uint8_t sc_pwrint[14]; - uint8_t sc_ofdm36_cal[14]; - uint8_t sc_ofdm48_cal[14]; - uint8_t sc_ofdm54_cal[14]; -#define ZYD_ENDPT_BOUT 0 -#define ZYD_ENDPT_BIN 1 -#define ZYD_ENDPT_IIN 2 -#define ZYD_ENDPT_IOUT 3 -#define ZYD_ENDPT_CNT 4 - usbd_pipe_handle sc_ep[ZYD_ENDPT_CNT]; - uint8_t *sc_ibuf; - - struct mtx sc_txmtx; - struct zyd_rx_data sc_rxdata[ZYD_RX_LIST_CNT]; - struct zyd_tx_data sc_txdata[ZYD_TX_LIST_CNT]; - int sc_txidx; - int sc_txqueued; - int sc_txtimer; - - struct zyd_rx_radiotap_header sc_rxtap; - int sc_rxtap_len; - struct zyd_tx_radiotap_header sc_txtap; - int sc_txtap_len; -}; - -#define ZYD_LOCK(sc) do { ((sc) = (sc)); mtx_lock(&Giant); } while (0) -#define ZYD_UNLOCK(sc) mtx_unlock(&Giant) -#define ZYD_TX_LOCK(sc) mtx_lock(&(sc)->sc_txmtx) -#define ZYD_TX_UNLOCK(sc) mtx_unlock(&(sc)->sc_txmtx) - |