diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2008-05-23 14:04:20 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2008-05-23 14:04:20 +0000 |
commit | 3ac223e8c3b095ae1615415aca3b2d744e23dd64 (patch) | |
tree | 117cf2ea1e574448019449512e2fd4b6fc517d9b /sys/dev/ic | |
parent | a3130ae961049bddc673b23d3612b3898032e6d1 (diff) |
Bye bye awi(4). No net80211 love, uses its own WEP code and has not worked
properly in 8.5 years so just garbage collect the driver.
ok damien@ deraadt@
Diffstat (limited to 'sys/dev/ic')
-rw-r--r-- | sys/dev/ic/am79c930.c | 450 | ||||
-rw-r--r-- | sys/dev/ic/am79c930reg.h | 125 | ||||
-rw-r--r-- | sys/dev/ic/am79c930var.h | 78 | ||||
-rw-r--r-- | sys/dev/ic/awi.c | 2839 | ||||
-rw-r--r-- | sys/dev/ic/awi_wep.c | 551 | ||||
-rw-r--r-- | sys/dev/ic/awireg.h | 460 | ||||
-rw-r--r-- | sys/dev/ic/awivar.h | 242 |
7 files changed, 0 insertions, 4745 deletions
diff --git a/sys/dev/ic/am79c930.c b/sys/dev/ic/am79c930.c deleted file mode 100644 index 3e4363b7b26..00000000000 --- a/sys/dev/ic/am79c930.c +++ /dev/null @@ -1,450 +0,0 @@ -/* $OpenBSD: am79c930.c,v 1.4 2002/03/14 01:26:54 millert Exp $ */ -/* $NetBSD: am79c930.c,v 1.5 2000/03/23 13:57:58 onoe Exp $ */ - -/*- - * Copyright (c) 1999 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Bill Sommerfeld - * - * 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 the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -/* - * Am79c930 chip driver. - * - * This is used by the awi driver to use the shared - * memory attached to the 79c930 to communicate with the firmware running - * in the 930's on-board 80188 core. - * - * The 79c930 can be mapped into just I/O space, or also have a - * memory mapping; the mapping must be set up by the bus front-end - * before am79c930_init is called. - */ - -/* - * operations: - * - * read_8, read_16, read_32, read_64, read_bytes - * write_8, write_16, write_32, write_64, write_bytes - * (two versions, depending on whether memory-space or i/o space is in use). - * - * interrupt E.C. - * start isr - * end isr - */ - -#include <sys/param.h> -#include <sys/systm.h> -#ifndef __FreeBSD__ -#include <sys/device.h> -#endif - -#include <machine/cpu.h> -#ifdef __FreeBSD__ -#include <machine/bus_pio.h> -#include <machine/bus_memio.h> -#endif -#include <machine/bus.h> -#ifdef __NetBSD__ -#include <machine/intr.h> -#endif - -#if defined(__NetBSD__) || defined(__OpenBSD__) -#include <dev/ic/am79c930reg.h> -#include <dev/ic/am79c930var.h> -#endif -#ifdef __FreeBSD__ -#include <dev/awi/am79c930reg.h> -#include <dev/awi/am79c930var.h> -#endif - -#define AM930_DELAY(x) /*nothing*/ - -void am79c930_regdump(struct am79c930_softc *sc); - -static void io_write_1(struct am79c930_softc *, u_int32_t, u_int8_t); -static void io_write_2(struct am79c930_softc *, u_int32_t, u_int16_t); -static void io_write_4(struct am79c930_softc *, u_int32_t, u_int32_t); -static void io_write_bytes(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t); - -static u_int8_t io_read_1(struct am79c930_softc *, u_int32_t); -static u_int16_t io_read_2(struct am79c930_softc *, u_int32_t); -static u_int32_t io_read_4(struct am79c930_softc *, u_int32_t); -static void io_read_bytes(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t); - -static void mem_write_1(struct am79c930_softc *, u_int32_t, u_int8_t); -static void mem_write_2(struct am79c930_softc *, u_int32_t, u_int16_t); -static void mem_write_4(struct am79c930_softc *, u_int32_t, u_int32_t); -static void mem_write_bytes(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t); - -static u_int8_t mem_read_1(struct am79c930_softc *, u_int32_t); -static u_int16_t mem_read_2(struct am79c930_softc *, u_int32_t); -static u_int32_t mem_read_4(struct am79c930_softc *, u_int32_t); -static void mem_read_bytes(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t); - -static struct am79c930_ops iospace_ops = { - io_write_1, - io_write_2, - io_write_4, - io_write_bytes, - io_read_1, - io_read_2, - io_read_4, - io_read_bytes -}; - -struct am79c930_ops memspace_ops = { - mem_write_1, - mem_write_2, - mem_write_4, - mem_write_bytes, - mem_read_1, - mem_read_2, - mem_read_4, - mem_read_bytes -}; - -static void io_write_1 (sc, off, val) - struct am79c930_softc *sc; - u_int32_t off; - u_int8_t val; -{ - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI, - ((off>>8)& 0x7f)); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff)); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA, val); - AM930_DELAY(1); -} - -static void io_write_2 (sc, off, val) - struct am79c930_softc *sc; - u_int32_t off; - u_int16_t val; -{ - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI, - ((off>>8)& 0x7f)); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_LMA_LO, (off&0xff)); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA, val & 0xff); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA, (val>>8)&0xff); - AM930_DELAY(1); -} - -static void io_write_4 (sc, off, val) - struct am79c930_softc *sc; - u_int32_t off; - u_int32_t val; -{ - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI, - ((off>>8)& 0x7f)); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_LMA_LO, (off&0xff)); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,val & 0xff); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,(val>>8)&0xff); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,(val>>16)&0xff); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,(val>>24)&0xff); - AM930_DELAY(1); -} - -static void io_write_bytes (sc, off, ptr, len) - struct am79c930_softc *sc; - u_int32_t off; - u_int8_t *ptr; - size_t len; -{ - int i; - - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI, - ((off>>8)& 0x7f)); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_LMA_LO, (off&0xff)); - AM930_DELAY(1); - for (i=0; i<len; i++) - bus_space_write_1(sc->sc_iot,sc->sc_ioh,AM79C930_IODPA,ptr[i]); -} - -static u_int8_t io_read_1 (sc, off) - struct am79c930_softc *sc; - u_int32_t off; -{ - u_int8_t val; - - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI, - ((off>>8)& 0x7f)); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff)); - AM930_DELAY(1); - val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA); - AM930_DELAY(1); - return val; -} - -static u_int16_t io_read_2 (sc, off) - struct am79c930_softc *sc; - u_int32_t off; -{ - u_int16_t val; - - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI, - ((off>>8)& 0x7f)); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff)); - AM930_DELAY(1); - val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA); - AM930_DELAY(1); - val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 8; - AM930_DELAY(1); - return val; -} - -static u_int32_t io_read_4 (sc, off) - struct am79c930_softc *sc; - u_int32_t off; -{ - u_int32_t val; - - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI, - ((off>>8)& 0x7f)); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff)); - AM930_DELAY(1); - val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA); - AM930_DELAY(1); - val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 8; - AM930_DELAY(1); - val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 16; - AM930_DELAY(1); - val |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, AM79C930_IODPA) << 24; - AM930_DELAY(1); - return val; -} - -static void io_read_bytes (sc, off, ptr, len) - struct am79c930_softc *sc; - u_int32_t off; - u_int8_t *ptr; - size_t len; -{ - int i; - - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_HI, - ((off>>8)& 0x7f)); - AM930_DELAY(1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_LMA_LO, (off&0xff)); - AM930_DELAY(1); - for (i=0; i<len; i++) - ptr[i] = bus_space_read_1(sc->sc_iot, sc->sc_ioh, - AM79C930_IODPA); -} - -static void mem_write_1 (sc, off, val) - struct am79c930_softc *sc; - u_int32_t off; - u_int8_t val; -{ - bus_space_write_1(sc->sc_memt, sc->sc_memh, off, val); -} - -static void mem_write_2 (sc, off, val) - struct am79c930_softc *sc; - u_int32_t off; - u_int16_t val; -{ - bus_space_tag_t t = sc->sc_memt; - bus_space_handle_t h = sc->sc_memh; - - /* could be unaligned */ - if ((off & 0x1) == 0) - bus_space_write_2(t, h, off, val); - else { - bus_space_write_1(t, h, off, val & 0xff); - bus_space_write_1(t, h, off+1, (val >> 8) & 0xff); - } -} - -static void mem_write_4 (sc, off, val) - struct am79c930_softc *sc; - u_int32_t off; - u_int32_t val; -{ - bus_space_tag_t t = sc->sc_memt; - bus_space_handle_t h = sc->sc_memh; - - /* could be unaligned */ - if ((off & 0x3) == 0) - bus_space_write_4(t, h, off, val); - else { - bus_space_write_1(t, h, off, val & 0xff); - bus_space_write_1(t, h, off+1, (val >> 8) & 0xff); - bus_space_write_1(t, h, off+2, (val >> 16) & 0xff); - bus_space_write_1(t, h, off+3, (val >> 24) & 0xff); - } -} - -static void mem_write_bytes (sc, off, ptr, len) - struct am79c930_softc *sc; - u_int32_t off; - u_int8_t *ptr; - size_t len; -{ - bus_space_write_region_1 (sc->sc_memt, sc->sc_memh, off, ptr, len); -} - - -static u_int8_t mem_read_1 (sc, off) - struct am79c930_softc *sc; - u_int32_t off; -{ - return bus_space_read_1(sc->sc_memt, sc->sc_memh, off); -} - -static u_int16_t mem_read_2 (sc, off) - struct am79c930_softc *sc; - u_int32_t off; -{ - /* could be unaligned */ - if ((off & 0x1) == 0) - return bus_space_read_2(sc->sc_memt, sc->sc_memh, off); - else - return - bus_space_read_1(sc->sc_memt, sc->sc_memh, off ) | - (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+1) << 8); -} - -static u_int32_t mem_read_4 (sc, off) - struct am79c930_softc *sc; - u_int32_t off; -{ - /* could be unaligned */ - if ((off & 0x3) == 0) - return bus_space_read_4(sc->sc_memt, sc->sc_memh, off); - else - return - bus_space_read_1(sc->sc_memt, sc->sc_memh, off ) | - (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+1) << 8) | - (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+2) <<16) | - (bus_space_read_1(sc->sc_memt, sc->sc_memh, off+3) <<24); -} - - - -static void mem_read_bytes (sc, off, ptr, len) - struct am79c930_softc *sc; - u_int32_t off; - u_int8_t *ptr; - size_t len; -{ - bus_space_read_region_1 (sc->sc_memt, sc->sc_memh, off, ptr, len); -} - - - - -/* - * Set bits in GCR. - */ - -void am79c930_gcr_setbits (sc, bits) - struct am79c930_softc *sc; - u_int8_t bits; -{ - u_int8_t gcr = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR); - - gcr |= bits; - - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_GCR, gcr); -} - -/* - * Clear bits in GCR. - */ - -void am79c930_gcr_clearbits (sc, bits) - struct am79c930_softc *sc; - u_int8_t bits; -{ - u_int8_t gcr = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR); - - gcr &= ~bits; - - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_GCR, gcr); -} - -u_int8_t am79c930_gcr_read (sc) - struct am79c930_softc *sc; -{ - return bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR); -} - -#if 0 -void am79c930_regdump (sc) - struct am79c930_softc *sc; -{ - u_int8_t buf[8]; - int i; - - AM930_DELAY(5); - for (i=0; i<8; i++) { - buf[i] = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, i); - AM930_DELAY(5); - } - printf("am79c930: regdump:"); - for (i=0; i<8; i++) { - printf(" %02x", buf[i]); - } - printf("\n"); -} -#endif - -void am79c930_chip_init (sc, how) - struct am79c930_softc *sc; -{ - /* zero the bank select register, and leave it that way.. */ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_BSS, 0); - if (how) - sc->sc_ops = &memspace_ops; - else - sc->sc_ops = &iospace_ops; -} - - diff --git a/sys/dev/ic/am79c930reg.h b/sys/dev/ic/am79c930reg.h deleted file mode 100644 index 421e8b1a13b..00000000000 --- a/sys/dev/ic/am79c930reg.h +++ /dev/null @@ -1,125 +0,0 @@ -/* $OpenBSD: am79c930reg.h,v 1.5 2003/10/21 18:58:48 jmc Exp $ */ - -/*- - * Copyright (c) 1999 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Bill Sommerfeld - * - * 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 the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -/* - * Device register definitions gleaned from from the AMD "Am79C930 - * PCnet(tm)-Mobile Single Chip Wireless LAN Media Access Controller" - * data sheet, AMD Pub #20183, Rev B, amendment/0, issue date August 1997. - * - * As of 1999/10/23, this was available from AMD's web site in PDF - * form. - */ - - -/* - * The 79c930 contains a bus interface unit, a media access - * controller, and a transceiver attachment interface. - * The MAC contains an 80188 CPU core. - * typical devices built around this chip typically add 32k or 64k of - * memory for buffers. - * - * The 80188 runs firmware which handles most of the 802.11 gorp, and - * communicates with the host using shared data structures in this - * memory; the specifics of the shared memory layout are not covered - * in this source file; see <dev/ic/am80211fw.h> for details of that layer. - */ - -/* - * Device Registers - */ - -#define AM79C930_IO_BASE 0 -#define AM79C930_IO_SIZE 16 -#define AM79C930_IO_SIZE_BIG 40 -#define AM79C930_IO_ALIGN 0x40 /* am79c930 decodes lower 6bits */ - - -#define AM79C930_GCR 0 /* General Config Register */ - -#define AM79C930_GCR_SWRESET 0x80 /* software reset */ -#define AM79C930_GCR_CORESET 0x40 /* core reset */ -#define AM79C930_GCR_DISPWDN 0x20 /* disable powerdown */ -#define AM79C930_GCR_ECWAIT 0x10 /* embedded controller wait */ -#define AM79C930_GCR_ECINT 0x08 /* interrupt from embedded ctrlr */ -#define AM79C930_GCR_INT2EC 0x04 /* interrupt to embedded ctrlr */ -#define AM79C930_GCR_ENECINT 0x02 /* enable interrupts from e.c. */ -#define AM79C930_GCR_DAM 0x01 /* direct access mode (read only) */ - -#define AM79C930_GCR_BITS "\020\1DAM\2ENECINT\3INT2EC\4ECINT\5ECWAIT\6DISPWDN\7CORESET\010SWRESET" - -#define AM79C930_BSS 1 /* Bank Switching Select register */ - -#define AM79C930_BSS_ECATR 0x80 /* E.C. ALE test read */ -#define AM79C930_BSS_FS 0x20 /* Flash Select */ -#define AM79C930_BSS_MBS 0x18 /* Memory Bank Select */ -#define AM79C930_BSS_EIOW 0x04 /* Expand I/O Window */ -#define AM79C930_BSS_TBS 0x03 /* TAI Bank Select */ - -#define AM79C930_LMA_LO 2 /* Local Memory Address register (low byte) */ - -#define AM79C930_LMA_HI 3 /* Local Memory Address register (high byte) */ - - /* set this bit to turn off ISAPnP version */ -#define AM79C930_LMA_HI_ISAPWRDWN 0x80 - -/* - * mmm, inconsistency in chip documentation: - * According to page 79--80, all four of the following are equivalent - * and address the single byte pointed at by BSS_{FS,MBS} | LMA_{HI,LO} - * According to tables on p63 and p67, they're the LSB through MSB - * of a 32-bit word. - */ - -#define AM79C930_IODPA 4 /* I/O Data port A */ -#define AM79C930_IODPB 5 /* I/O Data port B */ -#define AM79C930_IODPC 6 /* I/O Data port C */ -#define AM79C930_IODPD 7 /* I/O Data port D */ - - -/* - * Transceiver Attachment Interface Registers (TIR space) - * (omitted for now, since host access to them is for diagnostic - * purposes only). - */ - -/* - * memory space goo. - */ - -#define AM79C930_MEM_SIZE 0x8000 /* 32k */ -#define AM79C930_MEM_BASE 0x0 /* starting at 0 */ diff --git a/sys/dev/ic/am79c930var.h b/sys/dev/ic/am79c930var.h deleted file mode 100644 index d85a071533e..00000000000 --- a/sys/dev/ic/am79c930var.h +++ /dev/null @@ -1,78 +0,0 @@ -/* $OpenBSD: am79c930var.h,v 1.4 2002/03/14 01:26:54 millert Exp $ */ - -/*- - * Copyright (c) 1999 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Bill Sommerfeld - * - * 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 the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 AM79C930_BUS_PCMCIA 1 -#define AM79C930_BUS_ISAPNP 2 /* not implemented */ - -struct am79c930_softc -{ - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; - - bus_space_tag_t sc_memt; - bus_space_handle_t sc_memh; - - struct am79c930_ops *sc_ops; - - int sc_bustype; -}; - -struct am79c930_ops -{ - void (*write_1)(struct am79c930_softc *, u_int32_t, u_int8_t); - void (*write_2)(struct am79c930_softc *, u_int32_t, u_int16_t); - void (*write_4)(struct am79c930_softc *, u_int32_t, u_int32_t); - void (*write_bytes)(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t); - - u_int8_t (*read_1)(struct am79c930_softc *, u_int32_t); - u_int16_t (*read_2)(struct am79c930_softc *, u_int32_t); - u_int32_t (*read_4)(struct am79c930_softc *, u_int32_t); - void (*read_bytes)(struct am79c930_softc *, u_int32_t, u_int8_t *, size_t); -}; - -void am79c930_chip_init(struct am79c930_softc *sc, int); - -void am79c930_gcr_setbits(struct am79c930_softc *sc, u_int8_t bits); -void am79c930_gcr_clearbits(struct am79c930_softc *sc, u_int8_t bits); - -u_int8_t am79c930_gcr_read(struct am79c930_softc *sc); - -#define am79c930_hard_reset(sc) am79c930_gcr_setbits(sc, AM79C930_GCR_CORESET) -#define am79c930_hard_reset_off(sc) am79c930_gcr_clearbits(sc, AM79C930_GCR_CORESET) - - diff --git a/sys/dev/ic/awi.c b/sys/dev/ic/awi.c deleted file mode 100644 index c7c79274253..00000000000 --- a/sys/dev/ic/awi.c +++ /dev/null @@ -1,2839 +0,0 @@ -/* $OpenBSD: awi.c,v 1.24 2007/11/25 16:40:04 jmc Exp $ */ -/* $NetBSD: awi.c,v 1.26 2000/07/21 04:48:55 onoe Exp $ */ - -/*- - * Copyright (c) 1999 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Bill Sommerfeld - * - * 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 the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ -/* - * Driver for AMD 802.11 firmware. - * Uses am79c930 chip driver to talk to firmware running on the am79c930. - * - * More-or-less a generic ethernet-like if driver, with 802.11 gorp added. - */ - -/* - * todo: - * - flush tx queue on resynch. - * - clear oactive on "down". - * - rewrite copy-into-mbuf code - * - mgmt state machine gets stuck retransmitting assoc requests. - * - multicast filter. - * - fix device reset so it's more likely to work - * - show status goo through ifmedia. - * - * more todo: - * - deal with more 802.11 frames. - * - send reassoc request - * - deal with reassoc response - * - send/deal with disassociation - * - deal with "full" access points (no room for me). - * - power save mode - * - * later: - * - SSID preferences - * - need ioctls for poking at the MIBs - * - implement ad-hoc mode (including bss creation). - * - decide when to do "ad hoc" vs. infrastructure mode (IFF_LINK flags?) - * (focus on inf. mode since that will be needed for ietf) - * - deal with DH vs. FH versions of the card - * - deal with faster cards (2mb/s) - * - ?WEP goo (mmm, rc4) (it looks not particularly useful). - * - ifmedia revision. - * - common 802.11 mibish things. - * - common 802.11 media layer. - */ - -/* - * Driver for AMD 802.11 PCnetMobile firmware. - * Uses am79c930 chip driver to talk to firmware running on the am79c930. - * - * The initial version of the driver was written by - * Bill Sommerfeld <sommerfeld@netbsd.org>. - * Then the driver module completely rewritten to support cards with DS phy - * and to support adhoc mode by Atsushi Onoe <onoe@netbsd.org> - */ - -#if defined(__FreeBSD__) && __FreeBSD__ >= 4 -#define NBPFILTER 1 -#elif defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include "bpf.h" -#define NBPFILTER NBPF -#else -#include "bpfilter.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/mbuf.h> -#include <sys/malloc.h> -#include <sys/proc.h> -#include <sys/socket.h> -#include <sys/sockio.h> -#include <sys/errno.h> -#include <sys/syslog.h> -#if defined(__FreeBSD__) && __FreeBSD__ >= 4 -#include <sys/bus.h> -#else -#include <sys/device.h> -#endif - -#include <net/if.h> -#include <net/if_dl.h> -#ifndef __OpenBSD__ -#ifdef __FreeBSD__ -#include <net/ethernet.h> -#else -#include <net/if_ether.h> -#endif -#endif -#include <net/if_media.h> -#include <net/if_llc.h> - -#ifdef INET -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/in_var.h> -#include <netinet/ip.h> -#ifdef __NetBSD__ -#include <netinet/if_inarp.h> -#else -#include <netinet/if_ether.h> -#endif -#endif - -#include <net80211/ieee80211.h> -#include <net80211/ieee80211_ioctl.h> - -#if NBPFILTER > 0 -#include <net/bpf.h> -#endif - -#include <machine/cpu.h> -#include <machine/bus.h> -#ifdef __NetBSD__ -#include <machine/intr.h> -#endif -#ifdef __FreeBSD__ -#include <machine/clock.h> -#endif - -#if defined(__NetBSD__) || defined(__OpenBSD__) -#include <dev/ic/am79c930reg.h> -#include <dev/ic/am79c930var.h> -#include <dev/ic/awireg.h> -#include <dev/ic/awivar.h> -#endif -#ifdef __FreeBSD__ -#include <dev/awi/am79c930reg.h> -#include <dev/awi/am79c930var.h> -#include <dev/awi/awireg.h> -#include <dev/awi/awivar.h> -#endif - -static int awi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data); -#ifdef IFM_IEEE80211 -static int awi_media_rate2opt(struct awi_softc *sc, int rate); -static int awi_media_opt2rate(struct awi_softc *sc, int opt); -static int awi_media_change(struct ifnet *ifp); -static void awi_media_status(struct ifnet *ifp, struct ifmediareq *imr); -#endif -static void awi_watchdog(struct ifnet *ifp); -static void awi_start(struct ifnet *ifp); -static void awi_txint(struct awi_softc *sc); -static struct mbuf * awi_fix_txhdr(struct awi_softc *sc, struct mbuf *m0); -static struct mbuf * awi_fix_rxhdr(struct awi_softc *sc, struct mbuf *m0); -static void awi_input(struct awi_softc *sc, struct mbuf *m, u_int32_t rxts, u_int8_t rssi); -static void awi_rxint(struct awi_softc *sc); -static struct mbuf * awi_devget(struct awi_softc *sc, u_int32_t off, u_int16_t len); -static int awi_init_hw(struct awi_softc *sc); -static int awi_init_mibs(struct awi_softc *sc); -static int awi_init_txrx(struct awi_softc *sc); -static void awi_stop_txrx(struct awi_softc *sc); -static int awi_start_scan(struct awi_softc *sc); -static int awi_next_scan(struct awi_softc *sc); -static void awi_stop_scan(struct awi_softc *sc); -static void awi_recv_beacon(struct awi_softc *sc, struct mbuf *m0, u_int32_t rxts, u_int8_t rssi); -static int awi_set_ss(struct awi_softc *sc); -static void awi_try_sync(struct awi_softc *sc); -static void awi_sync_done(struct awi_softc *sc); -static void awi_send_deauth(struct awi_softc *sc); -static void awi_send_auth(struct awi_softc *sc, int seq); -static void awi_recv_auth(struct awi_softc *sc, struct mbuf *m0); -static void awi_send_asreq(struct awi_softc *sc, int reassoc); -static void awi_recv_asresp(struct awi_softc *sc, struct mbuf *m0); -static int awi_mib(struct awi_softc *sc, u_int8_t cmd, u_int8_t mib); -static int awi_cmd_scan(struct awi_softc *sc); -static int awi_cmd(struct awi_softc *sc, u_int8_t cmd); -static void awi_cmd_done(struct awi_softc *sc); -static int awi_next_txd(struct awi_softc *sc, int len, u_int32_t *framep, u_int32_t*ntxdp); -static int awi_lock(struct awi_softc *sc); -static void awi_unlock(struct awi_softc *sc); -static int awi_intr_lock(struct awi_softc *sc); -static void awi_intr_unlock(struct awi_softc *sc); -static int awi_cmd_wait(struct awi_softc *sc); -static void awi_print_essid(u_int8_t *essid); - -#ifdef AWI_DEBUG -static void awi_dump_pkt(struct awi_softc *sc, struct mbuf *m, int rssi); -int awi_verbose = 0; -int awi_dump = 0; -#define AWI_DUMP_MASK(fc0) (1 << (((fc0) & IEEE80211_FC0_SUBTYPE_MASK) >> 4)) -int awi_dump_mask = AWI_DUMP_MASK(IEEE80211_FC0_SUBTYPE_BEACON); -int awi_dump_hdr = 0; -int awi_dump_len = 28; -#endif - -#if NBPFILTER > 0 -#define AWI_BPF_NORM 0 -#define AWI_BPF_RAW 1 -#ifdef __FreeBSD__ -#define AWI_BPF_MTAP(sc, m, raw, dir) do { \ - if ((sc)->sc_ifp->if_bpf && (sc)->sc_rawbpf == (raw)) \ - bpf_mtap((sc)->sc_ifp, (m)); \ -} while (0); -#else -#define AWI_BPF_MTAP(sc, m, raw, dir) do { \ - if ((sc)->sc_ifp->if_bpf && (sc)->sc_rawbpf == (raw)) \ - bpf_mtap((sc)->sc_ifp->if_bpf, (m), dir); \ -} while (0); -#endif -#else -#define AWI_BPF_MTAP(sc, m, raw, dir) -#endif - -#ifndef llc_snap -#define llc_snap llc_un.type_snap -#endif - -#ifdef __OpenBSD__ -struct cfdriver awi_cd = { - NULL, "awi", DV_IFNET -}; -#endif - -#ifdef __FreeBSD__ -#if __FreeBSD__ >= 4 -devclass_t awi_devclass; -#endif - -/* NetBSD compatible functions */ -static char * ether_sprintf(u_int8_t *); - -static char * -ether_sprintf(enaddr) - u_int8_t *enaddr; -{ - static char strbuf[18]; - - snprintf(strbuf, sizeof strbuf, "%6D", enaddr, ":"); - return strbuf; -} -#endif - -int -awi_attach(sc) - struct awi_softc *sc; -{ - struct ifnet *ifp = sc->sc_ifp; - int s; - int error; -#ifdef IFM_IEEE80211 - int i; - u_int8_t *phy_rates; - int mword; - struct ifmediareq imr; -#endif - - s = splnet(); - /* - * Even if we can sleep in initialization state, - * all other processes (e.g. ifconfig) have to wait for - * completion of attaching interface. - */ - sc->sc_busy = 1; - sc->sc_status = AWI_ST_INIT; - TAILQ_INIT(&sc->sc_scan); - error = awi_init_hw(sc); - if (error) { - sc->sc_invalid = 1; - splx(s); - return error; - } - error = awi_init_mibs(sc); - splx(s); - if (error) { - sc->sc_invalid = 1; - return error; - } - - ifp->if_softc = sc; - ifp->if_start = awi_start; - ifp->if_ioctl = awi_ioctl; - ifp->if_watchdog = awi_watchdog; - ifp->if_hdrlen = sizeof(struct ieee80211_frame) + - sizeof(struct ether_header); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; -#ifdef IFF_NOTRAILERS - ifp->if_flags |= IFF_NOTRAILERS; -#endif -#if defined(__NetBSD__) || defined(__OpenBSD__) - memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); -#endif -#ifdef __FreeBSD__ - ifp->if_output = ether_output; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - memcpy(sc->sc_ec.ac_enaddr, sc->sc_mib_addr.aMAC_Address, - ETHER_ADDR_LEN); -#endif - IFQ_SET_READY(&ifp->if_snd); - - printf("%s: IEEE802.11 %s %dMbps (firmware %s)\n", - sc->sc_dev.dv_xname, - sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH ? "FH" : "DS", - sc->sc_tx_rate / 10, sc->sc_banner); - printf("%s: address %s\n", - sc->sc_dev.dv_xname, ether_sprintf(sc->sc_mib_addr.aMAC_Address)); - if_attach(ifp); -#ifdef __OpenBSD__ - ether_ifattach(ifp); -#elif defined(__FreeBSD__) - ether_ifattach(ifp); -#if NBPFILTER > 0 - bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); -#endif -#elif defined(__NetBSD__) - ether_ifattach(ifp, sc->sc_mib_addr.aMAC_Address); -#endif - -#ifdef IFM_IEEE80211 - ifmedia_init(&sc->sc_media, 0, awi_media_change, awi_media_status); - phy_rates = sc->sc_mib_phy.aSuprt_Data_Rates; - for (i = 0; i < phy_rates[1]; i++) { - mword = awi_media_rate2opt(sc, AWI_80211_RATE(phy_rates[2 + i])); - if (mword == 0) - continue; - mword |= IFM_IEEE80211; - ifmedia_add(&sc->sc_media, mword, 0, NULL); - ifmedia_add(&sc->sc_media, - mword | IFM_IEEE80211_ADHOC, 0, NULL); - if (sc->sc_mib_phy.IEEE_PHY_Type != AWI_PHY_TYPE_FH) - ifmedia_add(&sc->sc_media, - mword | IFM_IEEE80211_ADHOC | IFM_FLAG0, 0, NULL); - } - awi_media_status(ifp, &imr); - ifmedia_set(&sc->sc_media, imr.ifm_active); -#endif - - /* ready to accept ioctl */ - awi_unlock(sc); - - /* Attach is successful. */ - sc->sc_attached = 1; - return 0; -} - -#ifndef __FreeBSD__ -int -awi_detach(sc) - struct awi_softc *sc; -{ - struct ifnet *ifp = sc->sc_ifp; - int s; - - /* Succeed if there is no work to do. */ - if (!sc->sc_attached) - return (0); - - s = splnet(); - sc->sc_invalid = 1; - awi_stop(sc); - while (sc->sc_sleep_cnt > 0) { - wakeup(sc); - (void)tsleep(sc, PWAIT, "awidet", 1); - } - if (sc->sc_wep_ctx != NULL) - free(sc->sc_wep_ctx, M_DEVBUF); -#ifdef IFM_IEEE80211 - ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY); -#endif - ether_ifdetach(ifp); - if_detach(ifp); - if (sc->sc_enabled) { - if (sc->sc_disable) - (*sc->sc_disable)(sc); - sc->sc_enabled = 0; - } - splx(s); - return 0; -} - -int -awi_activate(self, act) - struct device *self; - enum devact act; -{ - struct awi_softc *sc = (struct awi_softc *)self; - int s, error = 0; - - s = splnet(); - switch (act) { - case DVACT_ACTIVATE: - break; - - case DVACT_DEACTIVATE: - sc->sc_invalid = 1; -#ifdef __NetBSD__ - if (sc->sc_ifp) - if_deactivate(sc->sc_ifp); -#endif - break; - } - splx(s); - - return error; -} - -void -awi_power(sc, why) - struct awi_softc *sc; - int why; -{ - int s; - int ocansleep; - - if (!sc->sc_enabled) - return; - - s = splnet(); - ocansleep = sc->sc_cansleep; - sc->sc_cansleep = 0; -#ifdef needtobefixed /*ONOE*/ - if (why == PWR_RESUME) { - sc->sc_enabled = 0; - awi_init(sc); - (void)awi_intr(sc); - } else { - awi_stop(sc); - if (sc->sc_disable) - (*sc->sc_disable)(sc); - } -#endif - sc->sc_cansleep = ocansleep; - splx(s); -} -#endif /* __NetBSD__ */ - -static int -awi_ioctl(ifp, cmd, data) - struct ifnet *ifp; - u_long cmd; - caddr_t data; -{ - struct awi_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; - struct ifaddr *ifa = (struct ifaddr *)data; - int s, error; - struct ieee80211_nwid nwid; - u_int8_t *p; - - s = splnet(); - -#ifdef __OpenBSD__ - if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) { - splx(s); - return (error); - } -#endif - - /* serialize ioctl */ - error = awi_lock(sc); - if (error) - goto cantlock; - switch (cmd) { - case SIOCSIFADDR: - ifp->if_flags |= IFF_UP; - switch (ifa->ifa_addr->sa_family) { -#ifdef INET - case AF_INET: - arp_ifinit((void *)ifp, ifa); - break; -#endif - } - /* FALLTHROUGH */ - case SIOCSIFFLAGS: - sc->sc_format_llc = !(ifp->if_flags & IFF_LINK0); - if (!(ifp->if_flags & IFF_UP)) { - if (sc->sc_enabled) { - awi_stop(sc); - if (sc->sc_disable) - (*sc->sc_disable)(sc); - sc->sc_enabled = 0; - } - break; - } - error = awi_init(sc); - break; - - case SIOCADDMULTI: - case SIOCDELMULTI: -#ifdef __FreeBSD__ - error = ENETRESET; /*XXX*/ -#else - error = (cmd == SIOCADDMULTI) ? - ether_addmulti(ifr, &sc->sc_arpcom) : - ether_delmulti(ifr, &sc->sc_arpcom); -#endif - /* - * Do not rescan BSS. Rather, just reset multicast filter. - */ - if (error == ENETRESET) { - if (ifp->if_flags & IFF_RUNNING) - error = awi_init(sc); - else - error = 0; - } - break; - case SIOCSIFMTU: - if (ifr->ifr_mtu > ETHERMTU) - error = EINVAL; - else - ifp->if_mtu = ifr->ifr_mtu; - break; - case SIOCS80211NWID: - if ((error = suser(curproc, 0)) != 0) - break; - error = copyin(ifr->ifr_data, &nwid, sizeof(nwid)); - if (error) - break; - if (nwid.i_len > IEEE80211_NWID_LEN) { - error = EINVAL; - break; - } - if (sc->sc_mib_mac.aDesired_ESS_ID[1] == nwid.i_len && - memcmp(&sc->sc_mib_mac.aDesired_ESS_ID[2], nwid.i_nwid, - nwid.i_len) == 0) - break; - memset(sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE); - sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID; - sc->sc_mib_mac.aDesired_ESS_ID[1] = nwid.i_len; - memcpy(&sc->sc_mib_mac.aDesired_ESS_ID[2], nwid.i_nwid, - nwid.i_len); - if (sc->sc_enabled) { - awi_stop(sc); - error = awi_init(sc); - } - break; - case SIOCG80211NWID: - if (ifp->if_flags & IFF_RUNNING) - p = sc->sc_bss.essid; - else - p = sc->sc_mib_mac.aDesired_ESS_ID; - error = copyout(p + 1, ifr->ifr_data, 1 + IEEE80211_NWID_LEN); - break; - case SIOCS80211NWKEY: - if ((error = suser(curproc, 0)) != 0) - break; - error = awi_wep_setnwkey(sc, (struct ieee80211_nwkey *)data); - break; - case SIOCG80211NWKEY: - error = awi_wep_getnwkey(sc, (struct ieee80211_nwkey *)data); - break; -#ifdef IFM_IEEE80211 - case SIOCSIFMEDIA: - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); - break; -#endif - default: -#ifdef notyet - error = awi_wicfg(ifp, cmd, data); -#else - error = EINVAL; -#endif - break; - } - awi_unlock(sc); - cantlock: - splx(s); - return error; -} - -#ifdef IFM_IEEE80211 -static int -awi_media_rate2opt(sc, rate) - struct awi_softc *sc; - int rate; -{ - int mword; - - mword = 0; - switch (rate) { - case 10: - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) - mword = IFM_IEEE80211_FH1; - else - mword = IFM_IEEE80211_DS1; - break; - case 20: - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) - mword = IFM_IEEE80211_FH2; - else - mword = IFM_IEEE80211_DS2; - break; - case 55: - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_DS) - mword = IFM_IEEE80211_DS5; - break; - case 110: - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_DS) - mword = IFM_IEEE80211_DS11; - break; - } - return mword; -} - -static int -awi_media_opt2rate(sc, opt) - struct awi_softc *sc; - int opt; -{ - int rate; - - rate = 0; - switch (IFM_SUBTYPE(opt)) { - case IFM_IEEE80211_FH1: - case IFM_IEEE80211_FH2: - if (sc->sc_mib_phy.IEEE_PHY_Type != AWI_PHY_TYPE_FH) - return 0; - break; - case IFM_IEEE80211_DS1: - case IFM_IEEE80211_DS2: - case IFM_IEEE80211_DS5: - case IFM_IEEE80211_DS11: - if (sc->sc_mib_phy.IEEE_PHY_Type != AWI_PHY_TYPE_DS) - return 0; - break; - } - - switch (IFM_SUBTYPE(opt)) { - case IFM_IEEE80211_FH1: - case IFM_IEEE80211_DS1: - rate = 10; - break; - case IFM_IEEE80211_FH2: - case IFM_IEEE80211_DS2: - rate = 20; - break; - case IFM_IEEE80211_DS5: - rate = 55; - break; - case IFM_IEEE80211_DS11: - rate = 110; - break; - } - return rate; -} - -/* - * Called from ifmedia_ioctl via awi_ioctl with lock obtained. - */ -static int -awi_media_change(ifp) - struct ifnet *ifp; -{ - struct awi_softc *sc = ifp->if_softc; - struct ifmedia_entry *ime; - u_int8_t *phy_rates; - int i, rate, error; - - error = 0; - ime = sc->sc_media.ifm_cur; - rate = awi_media_opt2rate(sc, ime->ifm_media); - if (rate == 0) - return EINVAL; - if (rate != sc->sc_tx_rate) { - phy_rates = sc->sc_mib_phy.aSuprt_Data_Rates; - for (i = 0; i < phy_rates[1]; i++) { - if (rate == AWI_80211_RATE(phy_rates[2 + i])) - break; - } - if (i == phy_rates[1]) - return EINVAL; - } - if (ime->ifm_media & IFM_IEEE80211_ADHOC) { - sc->sc_mib_local.Network_Mode = 0; - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) - sc->sc_no_bssid = 0; - else - sc->sc_no_bssid = (ime->ifm_media & IFM_FLAG0) ? 1 : 0; - } else { - sc->sc_mib_local.Network_Mode = 1; - } - if (sc->sc_enabled) { - awi_stop(sc); - error = awi_init(sc); - } - return error; -} - -static void -awi_media_status(ifp, imr) - struct ifnet *ifp; - struct ifmediareq *imr; -{ - struct awi_softc *sc = ifp->if_softc; - - imr->ifm_status = IFM_AVALID; - if (ifp->if_flags & IFF_RUNNING) - imr->ifm_status |= IFM_ACTIVE; - imr->ifm_active = IFM_IEEE80211; - imr->ifm_active |= awi_media_rate2opt(sc, sc->sc_tx_rate); - if (sc->sc_mib_local.Network_Mode == 0) { - imr->ifm_active |= IFM_IEEE80211_ADHOC; - if (sc->sc_no_bssid) - imr->ifm_active |= IFM_FLAG0; - } -} -#endif /* IFM_IEEE80211 */ - -int -awi_intr(arg) - void *arg; -{ - struct awi_softc *sc = arg; - u_int16_t status; - int error, handled = 0, ocansleep; - - if (!sc->sc_enabled || !sc->sc_enab_intr || sc->sc_invalid) - return 0; - - am79c930_gcr_setbits(&sc->sc_chip, - AM79C930_GCR_DISPWDN | AM79C930_GCR_ECINT); - awi_write_1(sc, AWI_DIS_PWRDN, 1); - ocansleep = sc->sc_cansleep; - sc->sc_cansleep = 0; - - for (;;) { - error = awi_intr_lock(sc); - if (error) - break; - status = awi_read_1(sc, AWI_INTSTAT); - awi_write_1(sc, AWI_INTSTAT, 0); - awi_write_1(sc, AWI_INTSTAT, 0); - status |= awi_read_1(sc, AWI_INTSTAT2) << 8; - awi_write_1(sc, AWI_INTSTAT2, 0); - DELAY(10); - awi_intr_unlock(sc); - if (!sc->sc_cmd_inprog) - status &= ~AWI_INT_CMD; /* make sure */ - if (status == 0) - break; - handled = 1; - if (status & AWI_INT_RX) - awi_rxint(sc); - if (status & AWI_INT_TX) - awi_txint(sc); - if (status & AWI_INT_CMD) - awi_cmd_done(sc); - if (status & AWI_INT_SCAN_CMPLT) { - if (sc->sc_status == AWI_ST_SCAN && - sc->sc_mgt_timer > 0) - (void)awi_next_scan(sc); - } - } - sc->sc_cansleep = ocansleep; - am79c930_gcr_clearbits(&sc->sc_chip, AM79C930_GCR_DISPWDN); - awi_write_1(sc, AWI_DIS_PWRDN, 0); - return handled; -} - -int -awi_init(sc) - struct awi_softc *sc; -{ - int error, ostatus; - int n; - struct ifnet *ifp = sc->sc_ifp; -#ifdef __FreeBSD__ - struct ifmultiaddr *ifma; -#else - struct ether_multi *enm; - struct ether_multistep step; -#endif - - /* reinitialize muticast filter */ - n = 0; - ifp->if_flags |= IFF_ALLMULTI; - sc->sc_mib_local.Accept_All_Multicast_Dis = 0; - if (ifp->if_flags & IFF_PROMISC) { - sc->sc_mib_mac.aPromiscuous_Enable = 1; - goto set_mib; - } - sc->sc_mib_mac.aPromiscuous_Enable = 0; -#ifdef __FreeBSD__ - if (ifp->if_amcount != 0) - goto set_mib; - for (ifma = LIST_FIRST(&ifp->if_multiaddrs); ifma != NULL; - ifma = LIST_NEXT(ifma, ifma_link)) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - if (n == AWI_GROUP_ADDR_SIZE) - goto set_mib; - memcpy(sc->sc_mib_addr.aGroup_Addresses[n], - LLADDR((struct sockaddr_dl *)ifma->ifma_addr), - ETHER_ADDR_LEN); - n++; - } -#else - ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm); - while (enm != NULL) { - if (n == AWI_GROUP_ADDR_SIZE || - memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN) - != 0) - goto set_mib; - memcpy(sc->sc_mib_addr.aGroup_Addresses[n], enm->enm_addrlo, - ETHER_ADDR_LEN); - n++; - ETHER_NEXT_MULTI(step, enm); - } -#endif - for (; n < AWI_GROUP_ADDR_SIZE; n++) - memset(sc->sc_mib_addr.aGroup_Addresses[n], 0, ETHER_ADDR_LEN); - ifp->if_flags &= ~IFF_ALLMULTI; - sc->sc_mib_local.Accept_All_Multicast_Dis = 1; - - set_mib: -#ifdef notdef /* allow non-encrypted frame for receiving. */ - sc->sc_mib_mgt.Wep_Required = sc->sc_wep_algo != NULL ? 1 : 0; -#endif - if (!sc->sc_enabled) { - sc->sc_enabled = 1; - if (sc->sc_enable) - (*sc->sc_enable)(sc); - sc->sc_status = AWI_ST_INIT; - error = awi_init_hw(sc); - if (error) - return error; - } - ostatus = sc->sc_status; - sc->sc_status = AWI_ST_INIT; - if ((error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_LOCAL)) != 0 || - (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_ADDR)) != 0 || - (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MAC)) != 0 || - (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MGT)) != 0 || - (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_PHY)) != 0) { - awi_stop(sc); - return error; - } - if (ifp->if_flags & IFF_RUNNING) - sc->sc_status = AWI_ST_RUNNING; - else { - if (ostatus == AWI_ST_INIT) { - error = awi_init_txrx(sc); - if (error) - return error; - } - error = awi_start_scan(sc); - } - return error; -} - -void -awi_stop(sc) - struct awi_softc *sc; -{ - struct ifnet *ifp = sc->sc_ifp; - struct awi_bss *bp; - struct mbuf *m; - - sc->sc_status = AWI_ST_INIT; - if (!sc->sc_invalid) { - (void)awi_cmd_wait(sc); - if (sc->sc_mib_local.Network_Mode && - sc->sc_status > AWI_ST_AUTH) - awi_send_deauth(sc); - awi_stop_txrx(sc); - } - ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); - ifp->if_timer = 0; - sc->sc_tx_timer = sc->sc_rx_timer = sc->sc_mgt_timer = 0; - for (;;) { - IF_DEQUEUE(&sc->sc_mgtq, m); - if (m == NULL) - break; - m_freem(m); - } - IFQ_PURGE(&ifp->if_snd); - while ((bp = TAILQ_FIRST(&sc->sc_scan)) != NULL) { - TAILQ_REMOVE(&sc->sc_scan, bp, list); - free(bp, M_DEVBUF); - } -} - -static void -awi_watchdog(ifp) - struct ifnet *ifp; -{ - struct awi_softc *sc = ifp->if_softc; - int ocansleep; - - if (sc->sc_invalid) { - ifp->if_timer = 0; - return; - } - - ocansleep = sc->sc_cansleep; - sc->sc_cansleep = 0; - if (sc->sc_tx_timer && --sc->sc_tx_timer == 0) { - printf("%s: transmit timeout\n", sc->sc_dev.dv_xname); - awi_txint(sc); - } - if (sc->sc_rx_timer && --sc->sc_rx_timer == 0) { - if (ifp->if_flags & IFF_DEBUG) { - printf("%s: no recent beacons from %s; rescanning\n", - sc->sc_dev.dv_xname, - ether_sprintf(sc->sc_bss.bssid)); - } - ifp->if_flags &= ~IFF_RUNNING; - awi_start_scan(sc); - } - if (sc->sc_mgt_timer && --sc->sc_mgt_timer == 0) { - switch (sc->sc_status) { - case AWI_ST_SCAN: - awi_stop_scan(sc); - break; - case AWI_ST_AUTH: - case AWI_ST_ASSOC: - /* restart scan */ - awi_start_scan(sc); - break; - default: - break; - } - } - - if (sc->sc_tx_timer == 0 && sc->sc_rx_timer == 0 && - sc->sc_mgt_timer == 0) - ifp->if_timer = 0; - else - ifp->if_timer = 1; - sc->sc_cansleep = ocansleep; -} - -static void -awi_start(ifp) - struct ifnet *ifp; -{ - struct awi_softc *sc = ifp->if_softc; - struct mbuf *m0, *m; - u_int32_t txd, frame, ntxd; - u_int8_t rate; - int len, sent = 0; - - for (;;) { - txd = sc->sc_txnext; - IF_DEQUEUE(&sc->sc_mgtq, m0); - if (m0 != NULL) { - if (awi_next_txd(sc, m0->m_pkthdr.len, &frame, &ntxd)) { - IF_PREPEND(&sc->sc_mgtq, m0); - ifp->if_flags |= IFF_OACTIVE; - break; - } - } else { - if (!(ifp->if_flags & IFF_RUNNING)) - break; - IFQ_POLL(&ifp->if_snd, m0); - if (m0 == NULL) - break; - len = m0->m_pkthdr.len + sizeof(struct ieee80211_frame); - if (sc->sc_format_llc) - len += sizeof(struct llc) - - sizeof(struct ether_header); - if (sc->sc_wep_algo != NULL) - len += IEEE80211_WEP_IVLEN + - IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN; - if (awi_next_txd(sc, len, &frame, &ntxd)) { - ifp->if_flags |= IFF_OACTIVE; - break; - } - IFQ_DEQUEUE(&ifp->if_snd, m0); - AWI_BPF_MTAP(sc, m0, AWI_BPF_NORM, BPF_DIRECTION_OUT); - m0 = awi_fix_txhdr(sc, m0); - if (sc->sc_wep_algo != NULL && m0 != NULL) - m0 = awi_wep_encrypt(sc, m0, 1); - if (m0 == NULL) { - ifp->if_oerrors++; - continue; - } - ifp->if_opackets++; - } -#ifdef AWI_DEBUG - if (awi_dump) - awi_dump_pkt(sc, m0, -1); -#endif - AWI_BPF_MTAP(sc, m0, AWI_BPF_RAW, BPF_DIRECTION_OUT); - len = 0; - for (m = m0; m != NULL; m = m->m_next) { - awi_write_bytes(sc, frame + len, mtod(m, u_int8_t *), - m->m_len); - len += m->m_len; - } - m_freem(m0); - rate = sc->sc_tx_rate; /*XXX*/ - awi_write_1(sc, ntxd + AWI_TXD_STATE, 0); - awi_write_4(sc, txd + AWI_TXD_START, frame); - awi_write_4(sc, txd + AWI_TXD_NEXT, ntxd); - awi_write_4(sc, txd + AWI_TXD_LENGTH, len); - awi_write_1(sc, txd + AWI_TXD_RATE, rate); - awi_write_4(sc, txd + AWI_TXD_NDA, 0); - awi_write_4(sc, txd + AWI_TXD_NRA, 0); - awi_write_1(sc, txd + AWI_TXD_STATE, AWI_TXD_ST_OWN); - sc->sc_txnext = ntxd; - sent++; - } - if (sent) { - if (sc->sc_tx_timer == 0) - sc->sc_tx_timer = 5; - ifp->if_timer = 1; -#ifdef AWI_DEBUG - if (awi_verbose) - printf("awi_start: sent %d txdone %d txnext %d txbase %d txend %d\n", sent, sc->sc_txdone, sc->sc_txnext, sc->sc_txbase, sc->sc_txend); -#endif - } -} - -static void -awi_txint(sc) - struct awi_softc *sc; -{ - struct ifnet *ifp = sc->sc_ifp; - u_int8_t flags; - - while (sc->sc_txdone != sc->sc_txnext) { - flags = awi_read_1(sc, sc->sc_txdone + AWI_TXD_STATE); - if ((flags & AWI_TXD_ST_OWN) || !(flags & AWI_TXD_ST_DONE)) - break; - if (flags & AWI_TXD_ST_ERROR) - ifp->if_oerrors++; - sc->sc_txdone = awi_read_4(sc, sc->sc_txdone + AWI_TXD_NEXT) & - 0x7fff; - } - sc->sc_tx_timer = 0; - ifp->if_flags &= ~IFF_OACTIVE; -#ifdef AWI_DEBUG - if (awi_verbose) - printf("awi_txint: txdone %d txnext %d txbase %d txend %d\n", - sc->sc_txdone, sc->sc_txnext, sc->sc_txbase, sc->sc_txend); -#endif - awi_start(ifp); -} - -static struct mbuf * -awi_fix_txhdr(sc, m0) - struct awi_softc *sc; - struct mbuf *m0; -{ - struct ether_header eh; - struct ieee80211_frame *wh; - struct llc *llc; - - if (m0->m_len < sizeof(eh)) { - m0 = m_pullup(m0, sizeof(eh)); - if (m0 == NULL) - return NULL; - } - memcpy(&eh, mtod(m0, caddr_t), sizeof(eh)); - if (sc->sc_format_llc) { - m_adj(m0, sizeof(struct ether_header) - sizeof(struct llc)); - llc = mtod(m0, struct llc *); - llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; - llc->llc_control = LLC_UI; - llc->llc_snap.org_code[0] = llc->llc_snap.org_code[1] = - llc->llc_snap.org_code[2] = 0; - llc->llc_snap.ether_type = eh.ether_type; - } - M_PREPEND(m0, sizeof(struct ieee80211_frame), M_DONTWAIT); - if (m0 == NULL) - return NULL; - wh = mtod(m0, struct ieee80211_frame *); - - wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA; - LE_WRITE_2(wh->i_dur, 0); - LE_WRITE_2(wh->i_seq, 0); - if (sc->sc_mib_local.Network_Mode) { - wh->i_fc[1] = IEEE80211_FC1_DIR_TODS; - memcpy(wh->i_addr1, sc->sc_bss.bssid, ETHER_ADDR_LEN); - memcpy(wh->i_addr2, eh.ether_shost, ETHER_ADDR_LEN); - memcpy(wh->i_addr3, eh.ether_dhost, ETHER_ADDR_LEN); - } else { - wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; - memcpy(wh->i_addr1, eh.ether_dhost, ETHER_ADDR_LEN); - memcpy(wh->i_addr2, eh.ether_shost, ETHER_ADDR_LEN); - memcpy(wh->i_addr3, sc->sc_bss.bssid, ETHER_ADDR_LEN); - } - return m0; -} - -static struct mbuf * -awi_fix_rxhdr(sc, m0) - struct awi_softc *sc; - struct mbuf *m0; -{ - struct ieee80211_frame wh; - struct ether_header *eh; - struct llc *llc; - - if (m0->m_len < sizeof(wh)) { - m_freem(m0); - return NULL; - } - llc = (struct llc *)(mtod(m0, caddr_t) + sizeof(wh)); - if (llc->llc_dsap == LLC_SNAP_LSAP && - llc->llc_ssap == LLC_SNAP_LSAP && - llc->llc_control == LLC_UI && - llc->llc_snap.org_code[0] == 0 && - llc->llc_snap.org_code[1] == 0 && - llc->llc_snap.org_code[2] == 0) { - memcpy(&wh, mtod(m0, caddr_t), sizeof(wh)); - m_adj(m0, sizeof(wh) + sizeof(*llc) - sizeof(*eh)); - eh = mtod(m0, struct ether_header *); - switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { - case IEEE80211_FC1_DIR_NODS: - memcpy(eh->ether_dhost, wh.i_addr1, ETHER_ADDR_LEN); - memcpy(eh->ether_shost, wh.i_addr2, ETHER_ADDR_LEN); - break; - case IEEE80211_FC1_DIR_TODS: - memcpy(eh->ether_dhost, wh.i_addr3, ETHER_ADDR_LEN); - memcpy(eh->ether_shost, wh.i_addr2, ETHER_ADDR_LEN); - break; - case IEEE80211_FC1_DIR_FROMDS: - memcpy(eh->ether_dhost, wh.i_addr1, ETHER_ADDR_LEN); - memcpy(eh->ether_shost, wh.i_addr3, ETHER_ADDR_LEN); - break; - case IEEE80211_FC1_DIR_DSTODS: - m_freem(m0); - return NULL; - } - } else { - /* assuming ethernet encapsulation, just strip 802.11 header */ - m_adj(m0, sizeof(wh)); - } - if (ALIGN(mtod(m0, caddr_t) + sizeof(struct ether_header)) != - (u_int)(mtod(m0, caddr_t) + sizeof(struct ether_header))) { - /* XXX: we lose to estimate the type of encapsulation */ - struct mbuf *n, *n0, **np; - caddr_t newdata; - int off, oldmlen; - - n0 = NULL; - np = &n0; - off = 0; - oldmlen = m0->m_pkthdr.len; - while (oldmlen > off) { - if (n0 == NULL) { - MGETHDR(n, M_DONTWAIT, MT_DATA); - if (n == NULL) { - m_freem(m0); - return NULL; - } - M_MOVE_PKTHDR(n, m0); - n->m_len = MHLEN; - } else { - MGET(n, M_DONTWAIT, MT_DATA); - if (n == NULL) { - m_freem(m0); - m_freem(n0); - return NULL; - } - n->m_len = MLEN; - } - if (oldmlen - off >= MINCLSIZE) { - MCLGET(n, M_DONTWAIT); - if (n->m_flags & M_EXT) - n->m_len = n->m_ext.ext_size; - } - if (n0 == NULL) { - newdata = (caddr_t) - ALIGN(n->m_data - + sizeof(struct ether_header)) - - sizeof(struct ether_header); - n->m_len -= newdata - n->m_data; - n->m_data = newdata; - } - if (n->m_len > oldmlen - off) - n->m_len = oldmlen - off; - m_copydata(m0, off, n->m_len, mtod(n, caddr_t)); - off += n->m_len; - *np = n; - np = &n->m_next; - } - m_freem(m0); - m0 = n0; - } - return m0; -} - -static void -awi_input(sc, m, rxts, rssi) - struct awi_softc *sc; - struct mbuf *m; - u_int32_t rxts; - u_int8_t rssi; -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211_frame *wh; - - /* trim CRC here for WEP can find its own CRC at the end of packet. */ - m_adj(m, -ETHER_CRC_LEN); - AWI_BPF_MTAP(sc, m, AWI_BPF_RAW, BPF_DIRECTION_IN); - wh = mtod(m, struct ieee80211_frame *); - if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != - IEEE80211_FC0_VERSION_0) { - printf("%s; receive packet with wrong version: %x\n", - sc->sc_dev.dv_xname, wh->i_fc[0]); - m_freem(m); - ifp->if_ierrors++; - return; - } - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - m = awi_wep_encrypt(sc, m, 0); - if (m == NULL) { - ifp->if_ierrors++; - return; - } - wh = mtod(m, struct ieee80211_frame *); - } -#ifdef AWI_DEBUG - if (awi_dump) - awi_dump_pkt(sc, m, rssi); -#endif - - if ((sc->sc_mib_local.Network_Mode || !sc->sc_no_bssid) && - sc->sc_status == AWI_ST_RUNNING) { - if (memcmp(wh->i_addr2, sc->sc_bss.bssid, ETHER_ADDR_LEN) == 0) { - sc->sc_rx_timer = 10; - sc->sc_bss.rssi = rssi; - } - } - switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) { - case IEEE80211_FC0_TYPE_DATA: - if (sc->sc_mib_local.Network_Mode) { - if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != - IEEE80211_FC1_DIR_FROMDS) { - m_freem(m); - return; - } - } else { - if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != - IEEE80211_FC1_DIR_NODS) { - m_freem(m); - return; - } - } - m = awi_fix_rxhdr(sc, m); - if (m == NULL) { - ifp->if_ierrors++; - break; - } - ifp->if_ipackets++; -#if !(defined(__FreeBSD__) && __FreeBSD__ >= 4) - AWI_BPF_MTAP(sc, m, AWI_BPF_NORM, BPF_DIRECTION_IN); -#endif -#ifdef __NetBSD__ - (*ifp->if_input)(ifp, m); -#else - ether_input_mbuf(ifp, m); -#endif - break; - case IEEE80211_FC0_TYPE_MGT: - if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != - IEEE80211_FC1_DIR_NODS) { - m_freem(m); - return; - } - switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) { - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - case IEEE80211_FC0_SUBTYPE_BEACON: - awi_recv_beacon(sc, m, rxts, rssi); - break; - case IEEE80211_FC0_SUBTYPE_AUTH: - awi_recv_auth(sc, m); - break; - case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: - awi_recv_asresp(sc, m); - break; - case IEEE80211_FC0_SUBTYPE_DEAUTH: - if (sc->sc_mib_local.Network_Mode) - awi_send_auth(sc, 1); - break; - case IEEE80211_FC0_SUBTYPE_DISASSOC: - if (sc->sc_mib_local.Network_Mode) - awi_send_asreq(sc, 1); - break; - } - m_freem(m); - break; - case IEEE80211_FC0_TYPE_CTL: - default: - /* should not come here */ - m_freem(m); - break; - } -} - -static void -awi_rxint(sc) - struct awi_softc *sc; -{ - u_int8_t state, rate, rssi; - u_int16_t len; - u_int32_t frame, next, rxts, rxoff; - struct mbuf *m; - - rxoff = sc->sc_rxdoff; - for (;;) { - state = awi_read_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE); - if (state & AWI_RXD_ST_OWN) - break; - if (!(state & AWI_RXD_ST_CONSUMED)) { - if (state & AWI_RXD_ST_RXERROR) - sc->sc_ifp->if_ierrors++; - else { - len = awi_read_2(sc, rxoff + AWI_RXD_LEN); - rate = awi_read_1(sc, rxoff + AWI_RXD_RATE); - rssi = awi_read_1(sc, rxoff + AWI_RXD_RSSI); - frame = awi_read_4(sc, rxoff + AWI_RXD_START_FRAME) & 0x7fff; - rxts = awi_read_4(sc, rxoff + AWI_RXD_LOCALTIME); - m = awi_devget(sc, frame, len); - if (state & AWI_RXD_ST_LF) - awi_input(sc, m, rxts, rssi); - else - sc->sc_rxpend = m; - } - state |= AWI_RXD_ST_CONSUMED; - awi_write_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE, state); - } - next = awi_read_4(sc, rxoff + AWI_RXD_NEXT); - if (next & AWI_RXD_NEXT_LAST) - break; - /* make sure the next pointer is correct */ - if (next != awi_read_4(sc, rxoff + AWI_RXD_NEXT)) - break; - state |= AWI_RXD_ST_OWN; - awi_write_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE, state); - rxoff = next & 0x7fff; - } - sc->sc_rxdoff = rxoff; -} - -static struct mbuf * -awi_devget(sc, off, len) - struct awi_softc *sc; - u_int32_t off; - u_int16_t len; -{ - struct mbuf *m; - struct mbuf *top, **mp; - u_int tlen; - - top = sc->sc_rxpend; - mp = ⊤ - if (top != NULL) { - sc->sc_rxpend = NULL; - top->m_pkthdr.len += len; - m = top; - while (*mp != NULL) { - m = *mp; - mp = &m->m_next; - } - if (m->m_flags & M_EXT) - tlen = m->m_ext.ext_size; - else if (m->m_flags & M_PKTHDR) - tlen = MHLEN; - else - tlen = MLEN; - tlen -= m->m_len; - if (tlen > len) - tlen = len; - awi_read_bytes(sc, off, mtod(m, u_int8_t *) + m->m_len, tlen); - off += tlen; - len -= tlen; - } - - while (len > 0) { - if (top == NULL) { - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) - return NULL; - m->m_pkthdr.rcvif = sc->sc_ifp; - m->m_pkthdr.len = len; - m->m_len = MHLEN; - } else { - MGET(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - m_freem(top); - return NULL; - } - m->m_len = MLEN; - } - if (len >= MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if (m->m_flags & M_EXT) - m->m_len = m->m_ext.ext_size; - } - if (top == NULL) { - int hdrlen = sizeof(struct ieee80211_frame) + - (sc->sc_format_llc ? sizeof(struct llc) : - sizeof(struct ether_header)); - caddr_t newdata = (caddr_t) - ALIGN(m->m_data + hdrlen) - hdrlen; - m->m_len -= newdata - m->m_data; - m->m_data = newdata; - } - if (m->m_len > len) - m->m_len = len; - awi_read_bytes(sc, off, mtod(m, u_int8_t *), m->m_len); - off += m->m_len; - len -= m->m_len; - *mp = m; - mp = &m->m_next; - } - return top; -} - -/* - * Initialize hardware and start firmware to accept commands. - * Called everytime after power on firmware. - */ - -static int -awi_init_hw(sc) - struct awi_softc *sc; -{ - u_int8_t status; - u_int16_t intmask; - int i, error; - - sc->sc_enab_intr = 0; - sc->sc_invalid = 0; /* XXX: really? */ - awi_drvstate(sc, AWI_DRV_RESET); - - /* reset firmware */ - am79c930_gcr_setbits(&sc->sc_chip, AM79C930_GCR_CORESET); - DELAY(100); - awi_write_1(sc, AWI_SELFTEST, 0); - awi_write_1(sc, AWI_CMD, 0); - awi_write_1(sc, AWI_BANNER, 0); - am79c930_gcr_clearbits(&sc->sc_chip, AM79C930_GCR_CORESET); - DELAY(100); - - /* wait for selftest completion */ - for (i = 0; ; i++) { - if (i >= AWI_SELFTEST_TIMEOUT*hz/1000) { - printf("%s: failed to complete selftest (timeout)\n", - sc->sc_dev.dv_xname); - return ENXIO; - } - status = awi_read_1(sc, AWI_SELFTEST); - if ((status & 0xf0) == 0xf0) - break; - if (sc->sc_cansleep) { - sc->sc_sleep_cnt++; - (void)tsleep(sc, PWAIT, "awitst", 1); - sc->sc_sleep_cnt--; - } else { - DELAY(1000*1000/hz); - } - } - if (status != AWI_SELFTEST_PASSED) { - printf("%s: failed to complete selftest (code %x)\n", - sc->sc_dev.dv_xname, status); - return ENXIO; - } - - /* check banner to confirm firmware write it */ - awi_read_bytes(sc, AWI_BANNER, sc->sc_banner, AWI_BANNER_LEN); - if (memcmp(sc->sc_banner, "PCnetMobile:", 12) != 0) { - printf("%s: failed to complete selftest (bad banner)\n", - sc->sc_dev.dv_xname); - for (i = 0; i < AWI_BANNER_LEN; i++) - printf("%s%02x", i ? ":" : "\t", sc->sc_banner[i]); - printf("\n"); - return ENXIO; - } - - /* initializing interrupt */ - sc->sc_enab_intr = 1; - error = awi_intr_lock(sc); - if (error) - return error; - intmask = AWI_INT_GROGGY | AWI_INT_SCAN_CMPLT | - AWI_INT_TX | AWI_INT_RX | AWI_INT_CMD; - awi_write_1(sc, AWI_INTMASK, ~intmask & 0xff); - awi_write_1(sc, AWI_INTMASK2, 0); - awi_write_1(sc, AWI_INTSTAT, 0); - awi_write_1(sc, AWI_INTSTAT2, 0); - awi_intr_unlock(sc); - am79c930_gcr_setbits(&sc->sc_chip, AM79C930_GCR_ENECINT); - - /* issuing interface test command */ - error = awi_cmd(sc, AWI_CMD_NOP); - if (error) { - printf("%s: failed to complete selftest", sc->sc_dev.dv_xname); - if (error == ENXIO) - printf(" (no hardware)\n"); - else if (error != EWOULDBLOCK) - printf(" (error %d)\n", error); - else if (sc->sc_cansleep) - printf(" (lost interrupt)\n"); - else - printf(" (command timeout)\n"); - } - return error; -} - -/* - * Extract the factory default MIB value from firmware and assign the driver - * default value. - * Called once at attaching the interface. - */ - -static int -awi_init_mibs(sc) - struct awi_softc *sc; -{ - int i, error; - u_int8_t *rate; - - if ((error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_LOCAL)) != 0 || - (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_ADDR)) != 0 || - (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_MAC)) != 0 || - (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_MGT)) != 0 || - (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_PHY)) != 0) { - printf("%s: failed to get default mib value (error %d)\n", - sc->sc_dev.dv_xname, error); - return error; - } - - rate = sc->sc_mib_phy.aSuprt_Data_Rates; - sc->sc_tx_rate = AWI_RATE_1MBIT; - for (i = 0; i < rate[1]; i++) { - if (AWI_80211_RATE(rate[2 + i]) > sc->sc_tx_rate) - sc->sc_tx_rate = AWI_80211_RATE(rate[2 + i]); - } - awi_init_region(sc); - memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE); - sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID; - sc->sc_mib_local.Fragmentation_Dis = 1; - sc->sc_mib_local.Accept_All_Multicast_Dis = 1; - sc->sc_mib_local.Power_Saving_Mode_Dis = 1; - - /* allocate buffers */ - sc->sc_txbase = AWI_BUFFERS; - sc->sc_txend = sc->sc_txbase + - (AWI_TXD_SIZE + sizeof(struct ieee80211_frame) + - sizeof(struct ether_header) + ETHERMTU) * AWI_NTXBUFS; - LE_WRITE_4(&sc->sc_mib_local.Tx_Buffer_Offset, sc->sc_txbase); - LE_WRITE_4(&sc->sc_mib_local.Tx_Buffer_Size, - sc->sc_txend - sc->sc_txbase); - LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Offset, sc->sc_txend); - LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Size, - AWI_BUFFERS_END - sc->sc_txend); - sc->sc_mib_local.Network_Mode = 1; - sc->sc_mib_local.Acting_as_AP = 0; - return 0; -} - -/* - * Start transmitter and receiver of firmware - * Called after awi_init_hw() to start operation. - */ - -static int -awi_init_txrx(sc) - struct awi_softc *sc; -{ - int error; - - /* start transmitter */ - sc->sc_txdone = sc->sc_txnext = sc->sc_txbase; - awi_write_4(sc, sc->sc_txbase + AWI_TXD_START, 0); - awi_write_4(sc, sc->sc_txbase + AWI_TXD_NEXT, 0); - awi_write_4(sc, sc->sc_txbase + AWI_TXD_LENGTH, 0); - awi_write_1(sc, sc->sc_txbase + AWI_TXD_RATE, 0); - awi_write_4(sc, sc->sc_txbase + AWI_TXD_NDA, 0); - awi_write_4(sc, sc->sc_txbase + AWI_TXD_NRA, 0); - awi_write_1(sc, sc->sc_txbase + AWI_TXD_STATE, 0); - awi_write_4(sc, AWI_CMD_PARAMS+AWI_CA_TX_DATA, sc->sc_txbase); - awi_write_4(sc, AWI_CMD_PARAMS+AWI_CA_TX_MGT, 0); - awi_write_4(sc, AWI_CMD_PARAMS+AWI_CA_TX_BCAST, 0); - awi_write_4(sc, AWI_CMD_PARAMS+AWI_CA_TX_PS, 0); - awi_write_4(sc, AWI_CMD_PARAMS+AWI_CA_TX_CF, 0); - error = awi_cmd(sc, AWI_CMD_INIT_TX); - if (error) - return error; - - /* start receiver */ - if (sc->sc_rxpend) { - m_freem(sc->sc_rxpend); - sc->sc_rxpend = NULL; - } - error = awi_cmd(sc, AWI_CMD_INIT_RX); - if (error) - return error; - sc->sc_rxdoff = awi_read_4(sc, AWI_CMD_PARAMS+AWI_CA_IRX_DATA_DESC); - sc->sc_rxmoff = awi_read_4(sc, AWI_CMD_PARAMS+AWI_CA_IRX_PS_DESC); - return 0; -} - -static void -awi_stop_txrx(sc) - struct awi_softc *sc; -{ - - if (sc->sc_cmd_inprog) - (void)awi_cmd_wait(sc); - (void)awi_cmd(sc, AWI_CMD_KILL_RX); - (void)awi_cmd_wait(sc); - sc->sc_cmd_inprog = AWI_CMD_FLUSH_TX; - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_FTX_DATA, 1); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_FTX_MGT, 0); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_FTX_BCAST, 0); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_FTX_PS, 0); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_FTX_CF, 0); - (void)awi_cmd(sc, AWI_CMD_FLUSH_TX); - (void)awi_cmd_wait(sc); -} - -int -awi_init_region(sc) - struct awi_softc *sc; -{ - - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) { - switch (sc->sc_mib_phy.aCurrent_Reg_Domain) { - case AWI_REG_DOMAIN_US: - case AWI_REG_DOMAIN_CA: - case AWI_REG_DOMAIN_EU: - sc->sc_scan_min = 0; - sc->sc_scan_max = 77; - break; - case AWI_REG_DOMAIN_ES: - sc->sc_scan_min = 0; - sc->sc_scan_max = 26; - break; - case AWI_REG_DOMAIN_FR: - sc->sc_scan_min = 0; - sc->sc_scan_max = 32; - break; - case AWI_REG_DOMAIN_JP: - sc->sc_scan_min = 6; - sc->sc_scan_max = 17; - break; - default: - return EINVAL; - } - sc->sc_scan_set = sc->sc_scan_cur % 3 + 1; - } else { - switch (sc->sc_mib_phy.aCurrent_Reg_Domain) { - case AWI_REG_DOMAIN_US: - case AWI_REG_DOMAIN_CA: - sc->sc_scan_min = 1; - sc->sc_scan_max = 11; - sc->sc_scan_cur = 3; - break; - case AWI_REG_DOMAIN_EU: - sc->sc_scan_min = 1; - sc->sc_scan_max = 13; - sc->sc_scan_cur = 3; - break; - case AWI_REG_DOMAIN_ES: - sc->sc_scan_min = 10; - sc->sc_scan_max = 11; - sc->sc_scan_cur = 10; - break; - case AWI_REG_DOMAIN_FR: - sc->sc_scan_min = 10; - sc->sc_scan_max = 13; - sc->sc_scan_cur = 10; - break; - case AWI_REG_DOMAIN_JP: - sc->sc_scan_min = 14; - sc->sc_scan_max = 14; - sc->sc_scan_cur = 14; - break; - default: - return EINVAL; - } - } - sc->sc_ownch = sc->sc_scan_cur; - return 0; -} - -static int -awi_start_scan(sc) - struct awi_softc *sc; -{ - int error = 0; - struct awi_bss *bp; - - while ((bp = TAILQ_FIRST(&sc->sc_scan)) != NULL) { - TAILQ_REMOVE(&sc->sc_scan, bp, list); - free(bp, M_DEVBUF); - } - if (!sc->sc_mib_local.Network_Mode && sc->sc_no_bssid) { - memset(&sc->sc_bss, 0, sizeof(sc->sc_bss)); - sc->sc_bss.essid[0] = IEEE80211_ELEMID_SSID; - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) { - sc->sc_bss.chanset = sc->sc_ownch % 3 + 1; - sc->sc_bss.pattern = sc->sc_ownch; - sc->sc_bss.index = 1; - sc->sc_bss.dwell_time = 200; /*XXX*/ - } else - sc->sc_bss.chanset = sc->sc_ownch; - sc->sc_status = AWI_ST_SETSS; - error = awi_set_ss(sc); - } else { - if (sc->sc_mib_local.Network_Mode) - awi_drvstate(sc, AWI_DRV_INFSC); - else - awi_drvstate(sc, AWI_DRV_ADHSC); - sc->sc_start_bss = 0; - sc->sc_active_scan = 1; - sc->sc_mgt_timer = AWI_ASCAN_WAIT / 1000; - sc->sc_ifp->if_timer = 1; - sc->sc_status = AWI_ST_SCAN; - error = awi_cmd_scan(sc); - } - return error; -} - -static int -awi_next_scan(sc) - struct awi_softc *sc; -{ - int error; - - for (;;) { - /* - * The pattern parameter for FH phy should be incremented - * by 3. But BayStack 650 Access Points apparently always - * assign hop pattern set parameter to 1 for any pattern. - * So we try all combinations of pattern/set parameters. - * Since this causes no error, it may be a bug of - * PCnetMobile firmware. - */ - sc->sc_scan_cur++; - if (sc->sc_scan_cur > sc->sc_scan_max) { - sc->sc_scan_cur = sc->sc_scan_min; - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) - sc->sc_scan_set = sc->sc_scan_set % 3 + 1; - } - error = awi_cmd_scan(sc); - if (error != EINVAL) - break; - } - return error; -} - -static void -awi_stop_scan(sc) - struct awi_softc *sc; -{ - struct ifnet *ifp = sc->sc_ifp; - struct awi_bss *bp, *sbp; - int fail; - - bp = TAILQ_FIRST(&sc->sc_scan); - if (bp == NULL) { - notfound: - if (sc->sc_active_scan) { - if (ifp->if_flags & IFF_DEBUG) - printf("%s: entering passive scan mode\n", - sc->sc_dev.dv_xname); - sc->sc_active_scan = 0; - } - sc->sc_mgt_timer = AWI_PSCAN_WAIT / 1000; - ifp->if_timer = 1; - (void)awi_next_scan(sc); - return; - } - sbp = NULL; - if (ifp->if_flags & IFF_DEBUG) - printf("%s:\tmacaddr ch/pat sig flag wep essid\n", - sc->sc_dev.dv_xname); - for (; bp != NULL; bp = TAILQ_NEXT(bp, list)) { - if (bp->fails) { - /* - * The configuration of the access points may change - * during my scan. So we retries to associate with - * it unless there are any suitable AP. - */ - if (bp->fails++ < 3) - continue; - bp->fails = 0; - } - fail = 0; - /* - * Since the firmware apparently scans not only the specified - * channel of SCAN command but all available channel within - * the region, we should filter out unnecessary responses here. - */ - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) { - if (bp->pattern < sc->sc_scan_min || - bp->pattern > sc->sc_scan_max) - fail |= 0x01; - } else { - if (bp->chanset < sc->sc_scan_min || - bp->chanset > sc->sc_scan_max) - fail |= 0x01; - } - if (sc->sc_mib_local.Network_Mode) { - if (!(bp->capinfo & IEEE80211_CAPINFO_ESS) || - (bp->capinfo & IEEE80211_CAPINFO_IBSS)) - fail |= 0x02; - } else { - if ((bp->capinfo & IEEE80211_CAPINFO_ESS) || - !(bp->capinfo & IEEE80211_CAPINFO_IBSS)) - fail |= 0x02; - } - if (sc->sc_wep_algo == NULL) { - if (bp->capinfo & IEEE80211_CAPINFO_PRIVACY) - fail |= 0x04; - } else { - if (!(bp->capinfo & IEEE80211_CAPINFO_PRIVACY)) - fail |= 0x04; - } - if (sc->sc_mib_mac.aDesired_ESS_ID[1] != 0 && - memcmp(&sc->sc_mib_mac.aDesired_ESS_ID, bp->essid, - sizeof(bp->essid)) != 0) - fail |= 0x08; - if (ifp->if_flags & IFF_DEBUG) { - printf(" %c %s", fail ? '-' : '+', - ether_sprintf(bp->esrc)); - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) - printf(" %2d/%d%c", bp->pattern, bp->chanset, - fail & 0x01 ? '!' : ' '); - else - printf(" %4d%c", bp->chanset, - fail & 0x01 ? '!' : ' '); - printf(" %+4d", bp->rssi); - printf(" %4s%c", - (bp->capinfo & IEEE80211_CAPINFO_ESS) ? "ess" : - (bp->capinfo & IEEE80211_CAPINFO_IBSS) ? "ibss" : - "????", - fail & 0x02 ? '!' : ' '); - printf(" %3s%c ", - (bp->capinfo & IEEE80211_CAPINFO_PRIVACY) ? "wep" : - "no", - fail & 0x04 ? '!' : ' '); - awi_print_essid(bp->essid); - printf("%s\n", fail & 0x08 ? "!" : ""); - } - if (!fail) { - if (sbp == NULL || bp->rssi > sbp->rssi) - sbp = bp; - } - } - if (sbp == NULL) - goto notfound; - sc->sc_bss = *sbp; - (void)awi_set_ss(sc); -} - -static void -awi_recv_beacon(sc, m0, rxts, rssi) - struct awi_softc *sc; - struct mbuf *m0; - u_int32_t rxts; - u_int8_t rssi; -{ - struct ieee80211_frame *wh; - struct awi_bss *bp; - u_int8_t *frame, *eframe; - u_int8_t *tstamp, *bintval, *capinfo, *ssid, *rates, *parms; - - if (sc->sc_status != AWI_ST_SCAN) - return; - wh = mtod(m0, struct ieee80211_frame *); - - frame = (u_int8_t *)&wh[1]; - eframe = mtod(m0, u_int8_t *) + m0->m_len; - /* - * XXX: - * timestamp [8] - * beacon interval [2] - * capability information [2] - * ssid [tlv] - * supported rates [tlv] - * parameter set [tlv] - * ... - */ - if (frame + 12 > eframe) { -#ifdef AWI_DEBUG - if (awi_verbose) - printf("awi_recv_beacon: frame too short \n"); -#endif - return; - } - tstamp = frame; - frame += 8; - bintval = frame; - frame += 2; - capinfo = frame; - frame += 2; - - ssid = rates = parms = NULL; - while (frame < eframe) { - switch (*frame) { - case IEEE80211_ELEMID_SSID: - ssid = frame; - break; - case IEEE80211_ELEMID_RATES: - rates = frame; - break; - case IEEE80211_ELEMID_FHPARMS: - case IEEE80211_ELEMID_DSPARMS: - parms = frame; - break; - } - frame += frame[1] + 2; - } - if (ssid == NULL || rates == NULL || parms == NULL) { -#ifdef AWI_DEBUG - if (awi_verbose) - printf("awi_recv_beacon: ssid=%p, rates=%p, parms=%p\n", - ssid, rates, parms); -#endif - return; - } - if (ssid[1] > IEEE80211_NWID_LEN) { -#ifdef AWI_DEBUG - if (awi_verbose) - printf("awi_recv_beacon: bad ssid len: %d from %s\n", - ssid[1], ether_sprintf(wh->i_addr2)); -#endif - return; - } - - for (bp = TAILQ_FIRST(&sc->sc_scan); bp != NULL; - bp = TAILQ_NEXT(bp, list)) { - if (memcmp(bp->esrc, wh->i_addr2, ETHER_ADDR_LEN) == 0 && - memcmp(bp->bssid, wh->i_addr3, ETHER_ADDR_LEN) == 0) - break; - } - if (bp == NULL) { - bp = malloc(sizeof(struct awi_bss), M_DEVBUF, M_NOWAIT); - if (bp == NULL) - return; - TAILQ_INSERT_TAIL(&sc->sc_scan, bp, list); - memcpy(bp->esrc, wh->i_addr2, ETHER_ADDR_LEN); - memcpy(bp->bssid, wh->i_addr3, ETHER_ADDR_LEN); - memset(bp->essid, 0, sizeof(bp->essid)); - memcpy(bp->essid, ssid, 2 + ssid[1]); - } - bp->rssi = rssi; - bp->rxtime = rxts; - memcpy(bp->timestamp, tstamp, sizeof(bp->timestamp)); - bp->interval = LE_READ_2(bintval); - bp->capinfo = LE_READ_2(capinfo); - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) { - bp->chanset = parms[4]; - bp->pattern = parms[5]; - bp->index = parms[6]; - bp->dwell_time = LE_READ_2(parms + 2); - } else { - bp->chanset = parms[2]; - bp->pattern = 0; - bp->index = 0; - bp->dwell_time = 0; - } - if (sc->sc_mgt_timer == 0) - awi_stop_scan(sc); -} - -static int -awi_set_ss(sc) - struct awi_softc *sc; -{ - struct ifnet *ifp = sc->sc_ifp; - struct awi_bss *bp; - int error; - - sc->sc_status = AWI_ST_SETSS; - bp = &sc->sc_bss; - if (ifp->if_flags & IFF_DEBUG) { - printf("%s: ch %d pat %d id %d dw %d iv %d bss %s ssid ", - sc->sc_dev.dv_xname, bp->chanset, - bp->pattern, bp->index, bp->dwell_time, bp->interval, - ether_sprintf(bp->bssid)); - awi_print_essid(bp->essid); - printf("\n"); - } - memcpy(&sc->sc_mib_mgt.aCurrent_BSS_ID, bp->bssid, ETHER_ADDR_LEN); - memcpy(&sc->sc_mib_mgt.aCurrent_ESS_ID, bp->essid, - AWI_ESS_ID_SIZE); - LE_WRITE_2(&sc->sc_mib_mgt.aBeacon_Period, bp->interval); - error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MGT); - return error; -} - -static void -awi_try_sync(sc) - struct awi_softc *sc; -{ - struct awi_bss *bp; - - sc->sc_status = AWI_ST_SYNC; - bp = &sc->sc_bss; - - if (sc->sc_cmd_inprog) { - if (awi_cmd_wait(sc)) - return; - } - sc->sc_cmd_inprog = AWI_CMD_SYNC; - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_SYNC_SET, bp->chanset); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_SYNC_PATTERN, bp->pattern); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_SYNC_IDX, bp->index); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_SYNC_STARTBSS, - sc->sc_start_bss ? 1 : 0); - awi_write_2(sc, AWI_CMD_PARAMS+AWI_CA_SYNC_DWELL, bp->dwell_time); - awi_write_2(sc, AWI_CMD_PARAMS+AWI_CA_SYNC_MBZ, 0); - awi_write_bytes(sc, AWI_CMD_PARAMS+AWI_CA_SYNC_TIMESTAMP, - bp->timestamp, 8); - awi_write_4(sc, AWI_CMD_PARAMS+AWI_CA_SYNC_REFTIME, bp->rxtime); - (void)awi_cmd(sc, AWI_CMD_SYNC); -} - -static void -awi_sync_done(sc) - struct awi_softc *sc; -{ - struct ifnet *ifp = sc->sc_ifp; - - if (sc->sc_mib_local.Network_Mode) { - awi_drvstate(sc, AWI_DRV_INFSY); - awi_send_auth(sc, 1); - } else { - if (ifp->if_flags & IFF_DEBUG) { - printf("%s: synced with", sc->sc_dev.dv_xname); - if (sc->sc_no_bssid) - printf(" no-bssid"); - else { - printf(" %s ssid ", - ether_sprintf(sc->sc_bss.bssid)); - awi_print_essid(sc->sc_bss.essid); - } - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) - printf(" at chanset %d pattern %d\n", - sc->sc_bss.chanset, sc->sc_bss.pattern); - else - printf(" at channel %d\n", sc->sc_bss.chanset); - } - awi_drvstate(sc, AWI_DRV_ADHSY); - sc->sc_status = AWI_ST_RUNNING; - ifp->if_flags |= IFF_RUNNING; - awi_start(ifp); - } -} - -static void -awi_send_deauth(sc) - struct awi_softc *sc; -{ - struct ifnet *ifp = sc->sc_ifp; - struct mbuf *m; - struct ieee80211_frame *wh; - u_int8_t *deauth; - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) - return; - if (ifp->if_flags & IFF_DEBUG) - printf("%s: sending deauth to %s\n", sc->sc_dev.dv_xname, - ether_sprintf(sc->sc_bss.bssid)); - - wh = mtod(m, struct ieee80211_frame *); - wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | - IEEE80211_FC0_SUBTYPE_AUTH; - wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; - LE_WRITE_2(wh->i_dur, 0); - LE_WRITE_2(wh->i_seq, 0); - memcpy(wh->i_addr1, sc->sc_bss.bssid, ETHER_ADDR_LEN); - memcpy(wh->i_addr2, sc->sc_mib_addr.aMAC_Address, ETHER_ADDR_LEN); - memcpy(wh->i_addr3, sc->sc_bss.bssid, ETHER_ADDR_LEN); - - deauth = (u_int8_t *)&wh[1]; - LE_WRITE_2(deauth, IEEE80211_REASON_AUTH_LEAVE); - deauth += 2; - - m->m_pkthdr.len = m->m_len = deauth - mtod(m, u_int8_t *); - IF_ENQUEUE(&sc->sc_mgtq, m); - awi_start(ifp); - awi_drvstate(sc, AWI_DRV_INFTOSS); -} - -static void -awi_send_auth(sc, seq) - struct awi_softc *sc; - int seq; -{ - struct ifnet *ifp = sc->sc_ifp; - struct mbuf *m; - struct ieee80211_frame *wh; - u_int8_t *auth; - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) - return; - sc->sc_status = AWI_ST_AUTH; - if (ifp->if_flags & IFF_DEBUG) - printf("%s: sending auth to %s\n", sc->sc_dev.dv_xname, - ether_sprintf(sc->sc_bss.bssid)); - - wh = mtod(m, struct ieee80211_frame *); - wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | - IEEE80211_FC0_SUBTYPE_AUTH; - wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; - LE_WRITE_2(wh->i_dur, 0); - LE_WRITE_2(wh->i_seq, 0); - memcpy(wh->i_addr1, sc->sc_bss.esrc, ETHER_ADDR_LEN); - memcpy(wh->i_addr2, sc->sc_mib_addr.aMAC_Address, ETHER_ADDR_LEN); - memcpy(wh->i_addr3, sc->sc_bss.bssid, ETHER_ADDR_LEN); - - auth = (u_int8_t *)&wh[1]; - /* algorithm number */ - LE_WRITE_2(auth, IEEE80211_AUTH_ALG_OPEN); - auth += 2; - /* sequence number */ - LE_WRITE_2(auth, seq); - auth += 2; - /* status */ - LE_WRITE_2(auth, 0); - auth += 2; - - m->m_pkthdr.len = m->m_len = auth - mtod(m, u_int8_t *); - IF_ENQUEUE(&sc->sc_mgtq, m); - awi_start(ifp); - - sc->sc_mgt_timer = AWI_TRANS_TIMEOUT / 1000; - ifp->if_timer = 1; -} - -static void -awi_recv_auth(sc, m0) - struct awi_softc *sc; - struct mbuf *m0; -{ - struct ieee80211_frame *wh; - u_int8_t *auth, *eframe; - struct awi_bss *bp; - u_int16_t status; - - wh = mtod(m0, struct ieee80211_frame *); - auth = (u_int8_t *)&wh[1]; - eframe = mtod(m0, u_int8_t *) + m0->m_len; - if (sc->sc_ifp->if_flags & IFF_DEBUG) - printf("%s: receive auth from %s\n", sc->sc_dev.dv_xname, - ether_sprintf(wh->i_addr2)); - - /* algorithm number */ - if (LE_READ_2(auth) != IEEE80211_AUTH_ALG_OPEN) - return; - auth += 2; - if (!sc->sc_mib_local.Network_Mode) { - if (sc->sc_status != AWI_ST_RUNNING) - return; - if (LE_READ_2(auth) == 1) - awi_send_auth(sc, 2); - return; - } - if (sc->sc_status != AWI_ST_AUTH) - return; - /* sequence number */ - if (LE_READ_2(auth) != 2) - return; - auth += 2; - /* status */ - status = LE_READ_2(auth); - if (status != 0) { - printf("%s: authentication failed (reason %d)\n", - sc->sc_dev.dv_xname, status); - for (bp = TAILQ_FIRST(&sc->sc_scan); bp != NULL; - bp = TAILQ_NEXT(bp, list)) { - if (memcmp(bp->esrc, sc->sc_bss.esrc, ETHER_ADDR_LEN) - == 0) { - bp->fails++; - break; - } - } - return; - } - sc->sc_mgt_timer = 0; - awi_drvstate(sc, AWI_DRV_INFAUTH); - awi_send_asreq(sc, 0); -} - -static void -awi_send_asreq(sc, reassoc) - struct awi_softc *sc; - int reassoc; -{ - struct ifnet *ifp = sc->sc_ifp; - struct mbuf *m; - struct ieee80211_frame *wh; - u_int16_t lintval; - u_int8_t *asreq; - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) - return; - sc->sc_status = AWI_ST_ASSOC; - if (ifp->if_flags & IFF_DEBUG) - printf("%s: sending %sassoc req to %s\n", sc->sc_dev.dv_xname, - reassoc ? "re" : "", - ether_sprintf(sc->sc_bss.bssid)); - - wh = mtod(m, struct ieee80211_frame *); - wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT; - if (reassoc) - wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_REASSOC_REQ; - else - wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_ASSOC_REQ; - wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; - LE_WRITE_2(wh->i_dur, 0); - LE_WRITE_2(wh->i_seq, 0); - memcpy(wh->i_addr1, sc->sc_bss.esrc, ETHER_ADDR_LEN); - memcpy(wh->i_addr2, sc->sc_mib_addr.aMAC_Address, ETHER_ADDR_LEN); - memcpy(wh->i_addr3, sc->sc_bss.bssid, ETHER_ADDR_LEN); - - asreq = (u_int8_t *)&wh[1]; - - /* capability info */ - if (sc->sc_wep_algo == NULL) - LE_WRITE_2(asreq, IEEE80211_CAPINFO_CF_POLLABLE); - else - LE_WRITE_2(asreq, - IEEE80211_CAPINFO_CF_POLLABLE | IEEE80211_CAPINFO_PRIVACY); - asreq += 2; - /* listen interval */ - lintval = LE_READ_2(&sc->sc_mib_mgt.aListen_Interval); - LE_WRITE_2(asreq, lintval); - asreq += 2; - if (reassoc) { - /* current AP address */ - memcpy(asreq, sc->sc_bss.bssid, ETHER_ADDR_LEN); - asreq += ETHER_ADDR_LEN; - } - /* ssid */ - memcpy(asreq, sc->sc_bss.essid, 2 + sc->sc_bss.essid[1]); - asreq += 2 + asreq[1]; - /* supported rates */ - memcpy(asreq, &sc->sc_mib_phy.aSuprt_Data_Rates, 4); - asreq += 2 + asreq[1]; - - m->m_pkthdr.len = m->m_len = asreq - mtod(m, u_int8_t *); - IF_ENQUEUE(&sc->sc_mgtq, m); - awi_start(ifp); - - sc->sc_mgt_timer = AWI_TRANS_TIMEOUT / 1000; - ifp->if_timer = 1; -} - -static void -awi_recv_asresp(sc, m0) - struct awi_softc *sc; - struct mbuf *m0; -{ - struct ieee80211_frame *wh; - u_int8_t *asresp, *eframe; - u_int16_t status; - u_int8_t rate, *phy_rates; - struct awi_bss *bp; - int i, j; - - wh = mtod(m0, struct ieee80211_frame *); - asresp = (u_int8_t *)&wh[1]; - eframe = mtod(m0, u_int8_t *) + m0->m_len; - if (sc->sc_ifp->if_flags & IFF_DEBUG) - printf("%s: receive assoc resp from %s\n", sc->sc_dev.dv_xname, - ether_sprintf(wh->i_addr2)); - - if (!sc->sc_mib_local.Network_Mode) - return; - - if (sc->sc_status != AWI_ST_ASSOC) - return; - /* capability info */ - asresp += 2; - /* status */ - status = LE_READ_2(asresp); - if (status != 0) { - printf("%s: association failed (reason %d)\n", - sc->sc_dev.dv_xname, status); - for (bp = TAILQ_FIRST(&sc->sc_scan); bp != NULL; - bp = TAILQ_NEXT(bp, list)) { - if (memcmp(bp->esrc, sc->sc_bss.esrc, ETHER_ADDR_LEN) - == 0) { - bp->fails++; - break; - } - } - return; - } - asresp += 2; - /* association id */ - asresp += 2; - /* supported rates */ - rate = AWI_RATE_1MBIT; - for (i = 0; i < asresp[1]; i++) { - if (AWI_80211_RATE(asresp[2 + i]) <= rate) - continue; - phy_rates = sc->sc_mib_phy.aSuprt_Data_Rates; - for (j = 0; j < phy_rates[1]; j++) { - if (AWI_80211_RATE(asresp[2 + i]) == - AWI_80211_RATE(phy_rates[2 + j])) - rate = AWI_80211_RATE(asresp[2 + i]); - } - } - if (sc->sc_ifp->if_flags & IFF_DEBUG) { - printf("%s: associated with %s ssid ", - sc->sc_dev.dv_xname, ether_sprintf(sc->sc_bss.bssid)); - awi_print_essid(sc->sc_bss.essid); - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) - printf(" chanset %d pattern %d\n", - sc->sc_bss.chanset, sc->sc_bss.pattern); - else - printf(" channel %d\n", sc->sc_bss.chanset); - } - sc->sc_tx_rate = rate; - sc->sc_mgt_timer = 0; - sc->sc_rx_timer = 10; - sc->sc_ifp->if_timer = 1; - sc->sc_status = AWI_ST_RUNNING; - sc->sc_ifp->if_flags |= IFF_RUNNING; - awi_drvstate(sc, AWI_DRV_INFASSOC); - awi_start(sc->sc_ifp); -} - -static int -awi_mib(sc, cmd, mib) - struct awi_softc *sc; - u_int8_t cmd; - u_int8_t mib; -{ - int error; - u_int8_t size, *ptr; - - switch (mib) { - case AWI_MIB_LOCAL: - ptr = (u_int8_t *)&sc->sc_mib_local; - size = sizeof(sc->sc_mib_local); - break; - case AWI_MIB_ADDR: - ptr = (u_int8_t *)&sc->sc_mib_addr; - size = sizeof(sc->sc_mib_addr); - break; - case AWI_MIB_MAC: - ptr = (u_int8_t *)&sc->sc_mib_mac; - size = sizeof(sc->sc_mib_mac); - break; - case AWI_MIB_STAT: - ptr = (u_int8_t *)&sc->sc_mib_stat; - size = sizeof(sc->sc_mib_stat); - break; - case AWI_MIB_MGT: - ptr = (u_int8_t *)&sc->sc_mib_mgt; - size = sizeof(sc->sc_mib_mgt); - break; - case AWI_MIB_PHY: - ptr = (u_int8_t *)&sc->sc_mib_phy; - size = sizeof(sc->sc_mib_phy); - break; - default: - return EINVAL; - } - if (sc->sc_cmd_inprog) { - error = awi_cmd_wait(sc); - if (error) { - if (error == EWOULDBLOCK) - printf("awi_mib: cmd %d inprog", - sc->sc_cmd_inprog); - return error; - } - } - sc->sc_cmd_inprog = cmd; - if (cmd == AWI_CMD_SET_MIB) - awi_write_bytes(sc, AWI_CMD_PARAMS+AWI_CA_MIB_DATA, ptr, size); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_TYPE, mib); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_SIZE, size); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_INDEX, 0); - error = awi_cmd(sc, cmd); - if (error) - return error; - if (cmd == AWI_CMD_GET_MIB) { - awi_read_bytes(sc, AWI_CMD_PARAMS+AWI_CA_MIB_DATA, ptr, size); -#ifdef AWI_DEBUG - if (awi_verbose) { - int i; - - printf("awi_mib: #%d:", mib); - for (i = 0; i < size; i++) - printf(" %02x", ptr[i]); - printf("\n"); - } -#endif - } - return 0; -} - -static int -awi_cmd_scan(sc) - struct awi_softc *sc; -{ - int error; - u_int8_t scan_mode; - - if (sc->sc_active_scan) - scan_mode = AWI_SCAN_ACTIVE; - else - scan_mode = AWI_SCAN_PASSIVE; - if (sc->sc_mib_mgt.aScan_Mode != scan_mode) { - sc->sc_mib_mgt.aScan_Mode = scan_mode; - error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MGT); - return error; - } - - if (sc->sc_cmd_inprog) { - error = awi_cmd_wait(sc); - if (error) - return error; - } - sc->sc_cmd_inprog = AWI_CMD_SCAN; - awi_write_2(sc, AWI_CMD_PARAMS+AWI_CA_SCAN_DURATION, - sc->sc_active_scan ? AWI_ASCAN_DURATION : AWI_PSCAN_DURATION); - if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) { - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_SCAN_SET, - sc->sc_scan_set); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_SCAN_PATTERN, - sc->sc_scan_cur); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_SCAN_IDX, 1); - } else { - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_SCAN_SET, - sc->sc_scan_cur); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_SCAN_PATTERN, 0); - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_SCAN_IDX, 0); - } - awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_SCAN_SUSP, 0); - return awi_cmd(sc, AWI_CMD_SCAN); -} - -static int -awi_cmd(sc, cmd) - struct awi_softc *sc; - u_int8_t cmd; -{ - u_int8_t status; - int error = 0; - - sc->sc_cmd_inprog = cmd; - awi_write_1(sc, AWI_CMD_STATUS, AWI_STAT_IDLE); - awi_write_1(sc, AWI_CMD, cmd); - if (sc->sc_status != AWI_ST_INIT) - return 0; - error = awi_cmd_wait(sc); - if (error) - return error; - status = awi_read_1(sc, AWI_CMD_STATUS); - awi_write_1(sc, AWI_CMD, 0); - switch (status) { - case AWI_STAT_OK: - break; - case AWI_STAT_BADPARM: - return EINVAL; - default: - printf("%s: command %d failed %x\n", - sc->sc_dev.dv_xname, cmd, status); - return ENXIO; - } - return 0; -} - -static void -awi_cmd_done(sc) - struct awi_softc *sc; -{ - u_int8_t cmd, status; - - status = awi_read_1(sc, AWI_CMD_STATUS); - if (status == AWI_STAT_IDLE) - return; /* stray interrupt */ - - cmd = sc->sc_cmd_inprog; - sc->sc_cmd_inprog = 0; - if (sc->sc_status == AWI_ST_INIT) { - wakeup(sc); - return; - } - awi_write_1(sc, AWI_CMD, 0); - - if (status != AWI_STAT_OK) { - printf("%s: command %d failed %x\n", - sc->sc_dev.dv_xname, cmd, status); - return; - } - switch (sc->sc_status) { - case AWI_ST_SCAN: - if (cmd == AWI_CMD_SET_MIB) - awi_cmd_scan(sc); /* retry */ - break; - case AWI_ST_SETSS: - awi_try_sync(sc); - break; - case AWI_ST_SYNC: - awi_sync_done(sc); - break; - default: - break; - } -} - -static int -awi_next_txd(sc, len, framep, ntxdp) - struct awi_softc *sc; - int len; - u_int32_t *framep, *ntxdp; -{ - u_int32_t txd, ntxd, frame; - - txd = sc->sc_txnext; - frame = txd + AWI_TXD_SIZE; - if (frame + len > sc->sc_txend) - frame = sc->sc_txbase; - ntxd = frame + len; - if (ntxd + AWI_TXD_SIZE > sc->sc_txend) - ntxd = sc->sc_txbase; - *framep = frame; - *ntxdp = ntxd; - /* - * Determine if there are any room in ring buffer. - * --- send wait, === new data, +++ conflict (ENOBUFS) - * base........................end - * done----txd=====ntxd OK - * --txd=====done++++ntxd-- full - * --txd=====ntxd done-- OK - * ==ntxd done----txd=== OK - * ==done++++ntxd----txd=== full - * ++ntxd txd=====done++ full - */ - if (txd < ntxd) { - if (txd < sc->sc_txdone && ntxd + AWI_TXD_SIZE > sc->sc_txdone) - return ENOBUFS; - } else { - if (txd < sc->sc_txdone || ntxd + AWI_TXD_SIZE > sc->sc_txdone) - return ENOBUFS; - } - return 0; -} - -static int -awi_lock(sc) - struct awi_softc *sc; -{ - int error = 0; - - if (curproc == NULL) { - /* - * XXX - * Though driver ioctl should be called with context, - * KAME ipv6 stack calls ioctl in interrupt for now. - * We simply abort the request if there are other - * ioctl requests in progress. - */ - if (sc->sc_busy) { - return EWOULDBLOCK; - if (sc->sc_invalid) - return ENXIO; - } - sc->sc_busy = 1; - sc->sc_cansleep = 0; - return 0; - } - while (sc->sc_busy) { - if (sc->sc_invalid) - return ENXIO; - sc->sc_sleep_cnt++; - error = tsleep(sc, PWAIT | PCATCH, "awilck", 0); - sc->sc_sleep_cnt--; - if (error) - return error; - } - sc->sc_busy = 1; - sc->sc_cansleep = 1; - return 0; -} - -static void -awi_unlock(sc) - struct awi_softc *sc; -{ - sc->sc_busy = 0; - sc->sc_cansleep = 0; - if (sc->sc_sleep_cnt) - wakeup(sc); -} - -static int -awi_intr_lock(sc) - struct awi_softc *sc; -{ - u_int8_t status; - int i, retry; - - status = 1; - for (retry = 0; retry < 10; retry++) { - for (i = 0; i < AWI_LOCKOUT_TIMEOUT*1000/5; i++) { - status = awi_read_1(sc, AWI_LOCKOUT_HOST); - if (status == 0) - break; - DELAY(5); - } - if (status != 0) - break; - awi_write_1(sc, AWI_LOCKOUT_MAC, 1); - status = awi_read_1(sc, AWI_LOCKOUT_HOST); - if (status == 0) - break; - awi_write_1(sc, AWI_LOCKOUT_MAC, 0); - } - if (status != 0) { - printf("%s: failed to lock interrupt\n", - sc->sc_dev.dv_xname); - return ENXIO; - } - return 0; -} - -static void -awi_intr_unlock(sc) - struct awi_softc *sc; -{ - - awi_write_1(sc, AWI_LOCKOUT_MAC, 0); -} - -static int -awi_cmd_wait(sc) - struct awi_softc *sc; -{ - int i, error = 0; - - i = 0; - while (sc->sc_cmd_inprog) { - if (sc->sc_invalid) - return ENXIO; - if (awi_read_1(sc, AWI_CMD) != sc->sc_cmd_inprog) { - printf("%s: failed to access hardware\n", - sc->sc_dev.dv_xname); - sc->sc_invalid = 1; - return ENXIO; - } - if (sc->sc_cansleep) { - sc->sc_sleep_cnt++; - error = tsleep(sc, PWAIT, "awicmd", - AWI_CMD_TIMEOUT*hz/1000); - sc->sc_sleep_cnt--; - } else { - if (awi_read_1(sc, AWI_CMD_STATUS) != AWI_STAT_IDLE) { - awi_cmd_done(sc); - break; - } - if (i++ >= AWI_CMD_TIMEOUT*1000/10) - error = EWOULDBLOCK; - else - DELAY(10); - } - if (error) - break; - } - return error; -} - -static void -awi_print_essid(essid) - u_int8_t *essid; -{ - int i, len; - u_int8_t *p; - - len = essid[1]; - if (len > IEEE80211_NWID_LEN) - len = IEEE80211_NWID_LEN; /*XXX*/ - /* determine printable or not */ - for (i = 0, p = essid + 2; i < len; i++, p++) { - if (*p < ' ' || *p > 0x7e) - break; - } - if (i == len) { - printf("\""); - for (i = 0, p = essid + 2; i < len; i++, p++) - printf("%c", *p); - printf("\""); - } else { - printf("0x"); - for (i = 0, p = essid + 2; i < len; i++, p++) - printf("%02x", *p); - } -} - -#ifdef AWI_DEBUG -static void -awi_dump_pkt(sc, m, rssi) - struct awi_softc *sc; - struct mbuf *m; - int rssi; -{ - struct ieee80211_frame *wh; - int i, l; - - wh = mtod(m, struct ieee80211_frame *); - - if (awi_dump_mask != 0 && - ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK)==IEEE80211_FC1_DIR_NODS) && - ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK)==IEEE80211_FC0_TYPE_MGT)) { - if ((AWI_DUMP_MASK(wh->i_fc[0]) & awi_dump_mask) != 0) - return; - } - if (awi_dump_mask < 0 && - (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK)==IEEE80211_FC0_TYPE_DATA) - return; - - if (rssi < 0) - printf("tx: "); - else - printf("rx: "); - switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) { - case IEEE80211_FC1_DIR_NODS: - printf("NODS %s", ether_sprintf(wh->i_addr2)); - printf("->%s", ether_sprintf(wh->i_addr1)); - printf("(%s)", ether_sprintf(wh->i_addr3)); - break; - case IEEE80211_FC1_DIR_TODS: - printf("TODS %s", ether_sprintf(wh->i_addr2)); - printf("->%s", ether_sprintf(wh->i_addr3)); - printf("(%s)", ether_sprintf(wh->i_addr1)); - break; - case IEEE80211_FC1_DIR_FROMDS: - printf("FRDS %s", ether_sprintf(wh->i_addr3)); - printf("->%s", ether_sprintf(wh->i_addr1)); - printf("(%s)", ether_sprintf(wh->i_addr2)); - break; - case IEEE80211_FC1_DIR_DSTODS: - printf("DSDS %s", ether_sprintf((u_int8_t *)&wh[1])); - printf("->%s", ether_sprintf(wh->i_addr3)); - printf("(%s", ether_sprintf(wh->i_addr2)); - printf("->%s)", ether_sprintf(wh->i_addr1)); - break; - } - switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) { - case IEEE80211_FC0_TYPE_DATA: - printf(" data"); - break; - case IEEE80211_FC0_TYPE_MGT: - switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) { - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - printf(" probe_req"); - break; - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - printf(" probe_resp"); - break; - case IEEE80211_FC0_SUBTYPE_BEACON: - printf(" beacon"); - break; - case IEEE80211_FC0_SUBTYPE_AUTH: - printf(" auth"); - break; - case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - printf(" assoc_req"); - break; - case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: - printf(" assoc_resp"); - break; - case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: - printf(" reassoc_req"); - break; - case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: - printf(" reassoc_resp"); - break; - case IEEE80211_FC0_SUBTYPE_DEAUTH: - printf(" deauth"); - break; - case IEEE80211_FC0_SUBTYPE_DISASSOC: - printf(" disassoc"); - break; - default: - printf(" mgt#%d", - wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); - break; - } - break; - default: - printf(" type#%d", - wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK); - break; - } - if (wh->i_fc[1] & IEEE80211_FC1_WEP) - printf(" WEP"); - if (rssi >= 0) - printf(" +%d", rssi); - printf("\n"); - if (awi_dump_len > 0) { - l = m->m_len; - if (l > awi_dump_len + sizeof(*wh)) - l = awi_dump_len + sizeof(*wh); - i = sizeof(*wh); - if (awi_dump_hdr) - i = 0; - for (; i < l; i++) { - if ((i & 1) == 0) - printf(" "); - printf("%02x", mtod(m, u_int8_t *)[i]); - } - printf("\n"); - } -} -#endif diff --git a/sys/dev/ic/awi_wep.c b/sys/dev/ic/awi_wep.c deleted file mode 100644 index 39d68b31bb1..00000000000 --- a/sys/dev/ic/awi_wep.c +++ /dev/null @@ -1,551 +0,0 @@ -/* $OpenBSD: awi_wep.c,v 1.13 2005/02/21 11:16:00 dlg Exp $ */ -/* $NetBSD: awi_wep.c,v 1.2 2000/07/04 14:47:58 onoe Exp $ */ - -/* - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Atsushi Onoe. - * - * 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 the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -/* - * WEP support framework for the awi driver. - * - * No actual encryption capability is provided here, but any can be added - * to awi_wep_algo table below. - * - * Note that IEEE802.11 specification states WEP uses RC4 with 40bit key, - * which is a proprietary encryption algorithm available under license - * from RSA Data Security Inc. Using another algorithm, includes null - * encryption provided here, the awi driver cannot be able to communicate - * with other stations. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/mbuf.h> -#include <sys/malloc.h> -#include <sys/proc.h> -#include <sys/socket.h> -#include <sys/errno.h> -#include <sys/sockio.h> -#if defined(__FreeBSD__) && __FreeBSD__ >= 4 -#include <sys/bus.h> -#else -#include <sys/device.h> -#endif - -#include <net/if.h> -#include <net/if_dl.h> -#ifdef __FreeBSD__ -#include <net/ethernet.h> -#include <net/if_arp.h> -#elif defined(__OpenBSD__) -#include <netinet/in.h> -#include <netinet/if_ether.h> -#else -#include <net/if_ether.h> -#endif -#include <net/if_media.h> -#include <net80211/ieee80211.h> -#include <net80211/ieee80211_ioctl.h> - -#include <machine/cpu.h> -#include <machine/bus.h> -#ifdef __FreeBSD__ -#include <machine/clock.h> -#endif - -#if defined(__NetBSD__) || defined(__OpenBSD__) -#include <dev/ic/am79c930reg.h> -#include <dev/ic/am79c930var.h> -#include <dev/ic/awireg.h> -#include <dev/ic/awivar.h> -#include <dev/rndvar.h> -#endif - -#ifdef __OpenBSD__ -#include <dev/rndvar.h> -#endif - -#ifdef __OpenBSD__ -#include <dev/rndvar.h> -#endif - -#ifdef __NetBSD__ -#include <crypto/arc4/arc4.h> -#endif - -#ifdef __FreeBSD__ -#include <dev/awi/am79c930reg.h> -#include <dev/awi/am79c930var.h> -#include <dev/awi/awireg.h> -#include <dev/awi/awivar.h> - -#include <crypto/rc4/rc4.h> -static __inline int -arc4_ctxlen(void) -{ - return sizeof(struct rc4_state); -} - -static __inline void -arc4_setkey(void *ctx, u_int8_t *key, int keylen) -{ - rc4_init(ctx, key, keylen); -} - -static __inline void -arc4_encrypt(void *ctx, u_int8_t *dst, u_int8_t *src, int len) -{ - rc4_crypt(ctx, dst, src, len); -} -#endif - -static void awi_crc_init(void); -static u_int32_t awi_crc_update(u_int32_t crc, u_int8_t *buf, int len); - -static int awi_null_ctxlen(void); -static void awi_null_setkey(void *ctx, u_int8_t *key, int keylen); -static void awi_null_copy(void *ctx, u_int8_t *dst, u_int8_t *src, int len); - -/* XXX: the order should be known to wiconfig/user */ - -static struct awi_wep_algo awi_wep_algo[] = { -/* 0: no wep */ - { "no" }, /* dummy for no wep */ - -#if 0 -/* 1: normal wep (arc4) */ - { "arc4", arc4_ctxlen, arc4_setkey, - arc4_encrypt, arc4_encrypt }, -#endif -/* 2: debug wep (null) */ - { "null", awi_null_ctxlen, awi_null_setkey, - awi_null_copy, awi_null_copy }, - /* dummy for wep without encryption */ -}; - -int -awi_wep_setnwkey(sc, nwkey) - struct awi_softc *sc; - struct ieee80211_nwkey *nwkey; -{ - int i, len, error; - u_int8_t keybuf[AWI_MAX_KEYLEN]; - - if (nwkey->i_defkid <= 0 || - nwkey->i_defkid > IEEE80211_WEP_NKID) - return EINVAL; - error = 0; - for (i = 0; i < IEEE80211_WEP_NKID; i++) { - if (nwkey->i_key[i].i_keydat == NULL) - continue; - len = nwkey->i_key[i].i_keylen; - if (len > sizeof(keybuf)) { - error = EINVAL; - break; - } - error = copyin(nwkey->i_key[i].i_keydat, keybuf, len); - if (error) - break; - error = awi_wep_setkey(sc, i, keybuf, len); - if (error) - break; - } - if (error == 0) { - sc->sc_wep_defkid = nwkey->i_defkid - 1; - error = awi_wep_setalgo(sc, nwkey->i_wepon); - if (error == 0 && sc->sc_enabled) { - awi_stop(sc); - error = awi_init(sc); - } - } - return error; -} - -int -awi_wep_getnwkey(sc, nwkey) - struct awi_softc *sc; - struct ieee80211_nwkey *nwkey; -{ - int i, len, error, suerr; - u_int8_t keybuf[AWI_MAX_KEYLEN]; - - nwkey->i_wepon = awi_wep_getalgo(sc); - nwkey->i_defkid = sc->sc_wep_defkid + 1; - /* do not show any keys to non-root user */ -#ifdef __FreeBSD__ - suerr = suser(curproc); -#else -#ifdef __OpenBSD__ - suerr = suser(curproc, 0); -#else - suerr = suser(curproc->p_ucred, &curproc->p_acflag); -#endif -#endif - error = 0; - for (i = 0; i < IEEE80211_WEP_NKID; i++) { - if (nwkey->i_key[i].i_keydat == NULL) - continue; - if (suerr) { - error = suerr; - break; - } - len = sizeof(keybuf); - error = awi_wep_getkey(sc, i, keybuf, &len); - if (error) - break; - if (nwkey->i_key[i].i_keylen < len) { - error = ENOSPC; - break; - } - nwkey->i_key[i].i_keylen = len; - error = copyout(keybuf, nwkey->i_key[i].i_keydat, len); - if (error) - break; - } - return error; -} - -int -awi_wep_getalgo(sc) - struct awi_softc *sc; -{ - - if (sc->sc_wep_algo == NULL) - return 0; - return sc->sc_wep_algo - awi_wep_algo; -} - -int -awi_wep_setalgo(sc, algo) - struct awi_softc *sc; - int algo; -{ - struct awi_wep_algo *awa; - int ctxlen; - - awi_crc_init(); /* XXX: not belongs here */ - if (algo < 0 || algo >= sizeof(awi_wep_algo)/sizeof(awi_wep_algo[0])) - return EINVAL; - awa = &awi_wep_algo[algo]; - if (awa->awa_name == NULL) - return EINVAL; - if (awa->awa_ctxlen == NULL) { - awa = NULL; - ctxlen = 0; - } else - ctxlen = awa->awa_ctxlen(); - if (sc->sc_wep_ctx != NULL) { - free(sc->sc_wep_ctx, M_DEVBUF); - sc->sc_wep_ctx = NULL; - } - if (ctxlen) { - sc->sc_wep_ctx = malloc(ctxlen, M_DEVBUF, M_NOWAIT); - if (sc->sc_wep_ctx == NULL) - return ENOMEM; - } - sc->sc_wep_algo = awa; - return 0; -} - -int -awi_wep_setkey(sc, kid, key, keylen) - struct awi_softc *sc; - int kid; - unsigned char *key; - int keylen; -{ - - if (kid < 0 || kid >= IEEE80211_WEP_NKID) - return EINVAL; - if (keylen < 0 || keylen + IEEE80211_WEP_IVLEN > AWI_MAX_KEYLEN) - return EINVAL; - sc->sc_wep_keylen[kid] = keylen; - if (keylen > 0) - memcpy(sc->sc_wep_key[kid] + IEEE80211_WEP_IVLEN, key, keylen); - return 0; -} - -int -awi_wep_getkey(sc, kid, key, keylen) - struct awi_softc *sc; - int kid; - unsigned char *key; - int *keylen; -{ - - if (kid < 0 || kid >= IEEE80211_WEP_NKID) - return EINVAL; - if (*keylen < sc->sc_wep_keylen[kid]) - return ENOSPC; - *keylen = sc->sc_wep_keylen[kid]; - if (*keylen > 0) - memcpy(key, sc->sc_wep_key[kid] + IEEE80211_WEP_IVLEN, *keylen); - return 0; -} - -struct mbuf * -awi_wep_encrypt(sc, m0, txflag) - struct awi_softc *sc; - struct mbuf *m0; - int txflag; -{ - struct mbuf *m, *n, *n0; - struct ieee80211_frame *wh; - struct awi_wep_algo *awa; - int left, len, moff, noff, keylen, kid; - u_int32_t iv, crc; - u_int8_t *key, *ivp; - void *ctx; - u_int8_t crcbuf[IEEE80211_WEP_CRCLEN]; - - n0 = NULL; - awa = sc->sc_wep_algo; - if (awa == NULL) - goto fail; - ctx = sc->sc_wep_ctx; - m = m0; - left = m->m_pkthdr.len; - MGET(n, M_DONTWAIT, m->m_type); - n0 = n; - if (n == NULL) - goto fail; - M_DUP_PKTHDR(n, m); - len = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + - IEEE80211_WEP_CRCLEN; - if (txflag) { - n->m_pkthdr.len += len; - } else { - wh = mtod(n, struct ieee80211_frame *); - n->m_pkthdr.len -= len; - left -= len; - } - n->m_len = MHLEN; - if (n->m_pkthdr.len >= MINCLSIZE) { - MCLGET(n, M_DONTWAIT); - if (n->m_flags & M_EXT) - n->m_len = n->m_ext.ext_size; - } - len = sizeof(struct ieee80211_frame); - memcpy(mtod(n, caddr_t), mtod(m, caddr_t), len); - left -= len; - moff = len; - noff = len; - if (txflag) { - kid = sc->sc_wep_defkid; - wh = mtod(n, struct ieee80211_frame *); - wh->i_fc[1] |= IEEE80211_FC1_WEP; - iv = arc4random(); - /* - * store IV, byte order is not the matter since it's random. - * assuming IEEE80211_WEP_IVLEN is 3 - */ - ivp = mtod(n, u_int8_t *) + noff; - ivp[0] = (iv >> 16) & 0xff; - ivp[1] = (iv >> 8) & 0xff; - ivp[2] = iv & 0xff; - ivp[3] = kid & 0x03; /* clear pad and keyid */ - noff += IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN; - } else { - ivp = mtod(m, u_int8_t *) + moff; - moff += IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN; - kid = ivp[IEEE80211_WEP_IVLEN] & 0x03; - } - key = sc->sc_wep_key[kid]; - keylen = sc->sc_wep_keylen[kid]; - /* assuming IEEE80211_WEP_IVLEN is 3 */ - key[0] = ivp[0]; - key[1] = ivp[1]; - key[2] = ivp[2]; - awa->awa_setkey(ctx, key, IEEE80211_WEP_IVLEN + keylen); - - /* encrypt with calculating CRC */ - crc = ~0; - while (left > 0) { - len = m->m_len - moff; - if (len == 0) { - m = m->m_next; - moff = 0; - continue; - } - if (len > n->m_len - noff) { - len = n->m_len - noff; - if (len == 0) { - MGET(n->m_next, M_DONTWAIT, n->m_type); - if (n->m_next == NULL) - goto fail; - n = n->m_next; - n->m_len = MLEN; - if (left >= MINCLSIZE) { - MCLGET(n, M_DONTWAIT); - if (n->m_flags & M_EXT) - n->m_len = n->m_ext.ext_size; - } - noff = 0; - continue; - } - } - if (len > left) - len = left; - if (txflag) { - awa->awa_encrypt(ctx, mtod(n, caddr_t) + noff, - mtod(m, caddr_t) + moff, len); - crc = awi_crc_update(crc, mtod(m, caddr_t) + moff, len); - } else { - awa->awa_decrypt(ctx, mtod(n, caddr_t) + noff, - mtod(m, caddr_t) + moff, len); - crc = awi_crc_update(crc, mtod(n, caddr_t) + noff, len); - } - left -= len; - moff += len; - noff += len; - } - crc = ~crc; - if (txflag) { - LE_WRITE_4(crcbuf, crc); - if (n->m_len >= noff + sizeof(crcbuf)) - n->m_len = noff + sizeof(crcbuf); - else { - n->m_len = noff; - MGET(n->m_next, M_DONTWAIT, n->m_type); - if (n->m_next == NULL) - goto fail; - n = n->m_next; - n->m_len = sizeof(crcbuf); - noff = 0; - } - awa->awa_encrypt(ctx, mtod(n, caddr_t) + noff, crcbuf, - sizeof(crcbuf)); - } else { - n->m_len = noff; - noff = 0; - for (; noff < sizeof(crcbuf); noff += len, m = m->m_next) { - if (m->m_len < moff + len) - len = m->m_len - moff; - if (len == 0) - continue; - awa->awa_decrypt(ctx, crcbuf + noff, - mtod(m, caddr_t) + moff, len); - } - if (crc != LE_READ_4(crcbuf)) - goto fail; - } - m_freem(m0); - return n0; - - fail: - m_freem(m0); - m_freem(n0); - return NULL; -} - -/* - * CRC 32 -- routine from RFC 2083 - */ - -/* Table of CRCs of all 8-bit messages */ -static u_int32_t awi_crc_table[256]; -static int awi_crc_table_computed = 0; - -/* Make the table for a fast CRC. */ -static void -awi_crc_init() -{ - u_int32_t c; - int n, k; - - if (awi_crc_table_computed) - return; - for (n = 0; n < 256; n++) { - c = (u_int32_t)n; - for (k = 0; k < 8; k++) { - if (c & 1) - c = 0xedb88320UL ^ (c >> 1); - else - c = c >> 1; - } - awi_crc_table[n] = c; - } - awi_crc_table_computed = 1; -} - -/* - * Update a running CRC with the bytes buf[0..len-1]--the CRC - * should be initialized to all 1's, and the transmitted value - * is the 1's complement of the final running CRC - */ - -static u_int32_t -awi_crc_update(crc, buf, len) - u_int32_t crc; - u_int8_t *buf; - int len; -{ - u_int8_t *endbuf; - - for (endbuf = buf + len; buf < endbuf; buf++) - crc = awi_crc_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); - return crc; -} - -/* - * Null -- do nothing but copy. - */ - -static int -awi_null_ctxlen() -{ - - return 0; -} - -static void -awi_null_setkey(ctx, key, keylen) - void *ctx; - u_char *key; - int keylen; -{ -} - -static void -awi_null_copy(ctx, dst, src, len) - void *ctx; - u_char *dst; - u_char *src; - int len; -{ - - memcpy(dst, src, len); -} diff --git a/sys/dev/ic/awireg.h b/sys/dev/ic/awireg.h deleted file mode 100644 index 933770f9b4b..00000000000 --- a/sys/dev/ic/awireg.h +++ /dev/null @@ -1,460 +0,0 @@ -/* $OpenBSD: awireg.h,v 1.4 2001/07/04 09:02:59 niklas Exp $ */ -/* $NetBSD: awireg.h,v 1.3 2000/03/22 11:22:22 onoe Exp $ */ - -/*- - * Copyright (c) 1999 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Bill Sommerfeld - * - * 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 the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -/* - * The firmware typically loaded onto Am79C930-based 802.11 interfaces - * uses a 32k or larger shared memory buffer to communicate with the - * host. - * - * Depending on the exact configuration of the device, this buffer may - * either be mapped into PCMCIA memory space, or accessible a byte at - * a type through PCMCIA I/O space. - * - * This header defines offsets into this shared memory. - */ - - -/* - * LAST_TXD block. 5 32-bit words. - * - * There are five different output queues; this defines pointers to - * the last completed descriptor for each one. - */ -#define AWI_LAST_TXD 0x3ec /* last completed Tx Descr */ - -#define AWI_LAST_BCAST_TXD AWI_LAST_TXD+0 -#define AWI_LAST_MGT_TXD AWI_LAST_TXD+4 -#define AWI_LAST_DATA_TXD AWI_LAST_TXD+8 -#define AWI_LAST_PS_POLL_TXD AWI_LAST_TXD+12 -#define AWI_LAST_CF_POLL_TXD AWI_LAST_TXD+16 - -/* - * Banner block; null-terminated string. - * - * The doc says it contains - * "PCnetMobile:v2.00 mmddyy APIx.x\0" - */ - -#define AWI_BANNER 0x480 /* Version string */ -#define AWI_BANNER_LEN 0x20 - -/* - * Command block protocol: - * write command byte to a zero value. - * write command status to a zero value. - * write arguments to AWI_COMMAND_PARAMS - * write command byte to a non-zero value. - * wait for command status to be non-zero. - * write command byte to a zero value. - * write command status to a zero value. - */ - -#define AWI_CMD 0x4a0 /* Command opcode byte */ - -#define AWI_CMD_IDLE 0x0 -#define AWI_CMD_NOP 0x1 - -#define AWI_CMD_SET_MIB 0x2 -#define AWI_CMD_GET_MIB 0x9 - -#define AWI_CA_MIB_TYPE 0x0 -#define AWI_CA_MIB_SIZE 0x1 -#define AWI_CA_MIB_INDEX 0x2 -#define AWI_CA_MIB_DATA 0x4 - -#define AWI_MIB_LOCAL 0x0 -#define AWI_MIB_ADDR 0x2 -#define AWI_MIB_MAC 0x3 -#define AWI_MIB_STAT 0x4 -#define AWI_MIB_MGT 0x5 -#define AWI_MIB_DRVR 0x6 -#define AWI_MIB_PHY 0x7 - - -#define AWI_CMD_INIT_TX 0x3 - -#define AWI_CA_TX_LEN 0x14 -#define AWI_CA_TX_DATA 0x0 -#define AWI_CA_TX_MGT 0x4 -#define AWI_CA_TX_BCAST 0x8 -#define AWI_CA_TX_PS 0xc -#define AWI_CA_TX_CF 0x10 - -#define AWI_CMD_FLUSH_TX 0x4 - -#define AWI_CA_FTX_LEN 0x5 -#define AWI_CA_FTX_DATA 0x0 -#define AWI_CA_FTX_MGT 0x1 -#define AWI_CA_FTX_BCAST 0x2 -#define AWI_CA_FTX_PS 0x3 -#define AWI_CA_FTX_CF 0x4 - -#define AWI_CMD_INIT_RX 0x5 -#define AWI_CA_IRX_LEN 0x8 -#define AWI_CA_IRX_DATA_DESC 0x0 /* return */ -#define AWI_CA_IRX_PS_DESC 0x4 /* return */ - -#define AWI_CMD_KILL_RX 0x6 - -#define AWI_CMD_SLEEP 0x7 -#define AWI_CA_SLEEP_LEN 0x8 -#define AWI_CA_WAKEUP 0x0 /* uint64 */ - -#define AWI_CMD_WAKE 0x8 - -#define AWI_CMD_SCAN 0xa -#define AWI_CA_SCAN_LEN 0x6 -#define AWI_CA_SCAN_DURATION 0x0 -#define AWI_CA_SCAN_SET 0x2 -#define AWI_CA_SCAN_PATTERN 0x3 -#define AWI_CA_SCAN_IDX 0x4 -#define AWI_CA_SCAN_SUSP 0x5 - -#define AWI_CMD_SYNC 0xb -#define AWI_CA_SYNC_LEN 0x14 -#define AWI_CA_SYNC_SET 0x0 -#define AWI_CA_SYNC_PATTERN 0x1 -#define AWI_CA_SYNC_IDX 0x2 -#define AWI_CA_SYNC_STARTBSS 0x3 -#define AWI_CA_SYNC_DWELL 0x4 -#define AWI_CA_SYNC_MBZ 0x6 -#define AWI_CA_SYNC_TIMESTAMP 0x8 -#define AWI_CA_SYNC_REFTIME 0x10 - -#define AWI_CMD_RESUME 0xc - -#define AWI_CMD_STATUS 0x4a1 /* Command status */ - -#define AWI_STAT_IDLE 0x0 -#define AWI_STAT_OK 0x1 -#define AWI_STAT_BADCMD 0x2 -#define AWI_STAT_BADPARM 0x3 -#define AWI_STAT_NOTIMP 0x4 -#define AWI_STAT_BADRES 0x5 -#define AWI_STAT_BADMODE 0x6 - -#define AWI_ERROR_OFFSET 0x4a2 /* Offset to erroneous parameter */ -#define AWI_CMD_PARAMS 0x4a4 /* Command parameters */ - -#define AWI_CSB 0x4f0 /* Control/Status block */ - -#define AWI_SELFTEST 0x4f0 - -#define AWI_SELFTEST_INIT 0x00 /* initial */ -#define AWI_SELFTEST_FIRMCKSUM 0x01 /* firmware cksum running */ -#define AWI_SELFTEST_HARDWARE 0x02 /* hardware tests running */ -#define AWI_SELFTEST_MIB 0x03 /* mib initializing */ - -#define AWI_SELFTEST_MIB_FAIL 0xfa -#define AWI_SELFTEST_RADIO_FAIL 0xfb -#define AWI_SELFTEST_MAC_FAIL 0xfc -#define AWI_SELFTEST_FLASH_FAIL 0xfd -#define AWI_SELFTEST_RAM_FAIL 0xfe -#define AWI_SELFTEST_PASSED 0xff - -#define AWI_STA_STATE 0x4f1 - -#define AWI_STA_AP 0x20 /* acting as AP */ -#define AWI_STA_NOPSP 0x10 /* Power Saving disabled */ -#define AWI_STA_DOZE 0x08 /* about to go to sleep */ -#define AWI_STA_PSP 0x04 /* enable PSP */ -#define AWI_STA_RXEN 0x02 /* enable RX */ -#define AWI_STA_TXEN 0x01 /* enable TX */ - -#define AWI_INTSTAT 0x4f3 -#define AWI_INTMASK 0x4f4 - -/* Bits in AWI_INTSTAT/AWI_INTMASK */ - -#define AWI_INT_GROGGY 0x80 /* about to wake up */ -#define AWI_INT_CFP_ENDING 0x40 /* cont. free period ending */ -#define AWI_INT_DTIM 0x20 /* beacon outgoing */ -#define AWI_INT_CFP_START 0x10 /* cont. free period starting */ -#define AWI_INT_SCAN_CMPLT 0x08 /* scan complete */ -#define AWI_INT_TX 0x04 /* tx done */ -#define AWI_INT_RX 0x02 /* rx done */ -#define AWI_INT_CMD 0x01 /* cmd done */ - -/* - * The following are used to implement a locking protocol between host - * and MAC to protect the interrupt status and mask fields. - * - * driver: read lockout_host byte; if zero, set lockout_mac to non-zero, - * then reread lockout_host byte; if still zero, host has lock. - * if non-zero, clear lockout_mac, loop. - */ - -#define AWI_LOCKOUT_MAC 0x4f5 -#define AWI_LOCKOUT_HOST 0x4f6 - - -#define AWI_INTSTAT2 0x4f7 -#define AWI_INTMASK2 0x4fd - -/* Bits in AWI_INTSTAT2/INTMASK2 */ -#define AWI_INT2_RXMGT 0x80 /* mgt/ps received */ -#define AWI_INT2_RXDATA 0x40 /* data received */ -#define AWI_INT2_TXMGT 0x10 /* mgt tx done */ -#define AWI_INT2_TXCF 0x08 /* CF tx done */ -#define AWI_INT2_TXPS 0x04 /* PS tx done */ -#define AWI_INT2_TXBCAST 0x02 /* Broadcast tx done */ -#define AWI_INT2_TXDATA 0x01 /* data tx done */ - -#define AWI_DIS_PWRDN 0x4fc /* disable powerdown if set */ - -#define AWI_DRIVERSTATE 0x4fe /* driver state */ - -#define AWI_DRV_STATEMASK 0x0f - -#define AWI_DRV_RESET 0x0 -#define AWI_DRV_INFSY 0x1 /* inf synced */ -#define AWI_DRV_ADHSC 0x2 /* adhoc scan */ -#define AWI_DRV_ADHSY 0x3 /* adhoc synced */ -#define AWI_DRV_INFSC 0x4 /* inf scanning */ -#define AWI_DRV_INFAUTH 0x5 /* inf authed */ -#define AWI_DRV_INFASSOC 0x6 /* inf associated */ -#define AWI_DRV_INFTOSS 0x7 /* inf handoff */ -#define AWI_DRV_APNONE 0x8 /* AP activity: no assoc */ -#define AWI_DRV_APQUIET 0xc /* AP: >=one assoc, no traffic */ -#define AWI_DRV_APLO 0xd /* AP: >=one assoc, light tfc */ -#define AWI_DRV_APMED 0xe /* AP: >=one assoc, mod tfc */ -#define AWI_DRV_APHIGH 0xf /* AP: >=one assoc, heavy tfc */ - -#define AWI_DRV_AUTORXLED 0x10 -#define AWI_DRV_AUTOTXLED 0x20 -#define AWI_DRV_RXLED 0x40 -#define AWI_DRV_TXLED 0x80 - -#define AWI_VBM 0x500 /* Virtual Bit Map */ - -#define AWI_BUFFERS 0x600 /* Buffers */ -#define AWI_BUFFERS_END 0x6000 - -/* - * Receive descriptors; there are a linked list of these chained - * through the "NEXT" fields, starting from XXX - */ - -#define AWI_RXD_SIZE 0x18 - -#define AWI_RXD_NEXT 0x4 -#define AWI_RXD_NEXT_LAST 0x80000000 - - -#define AWI_RXD_HOST_DESC_STATE 0x9 - -#define AWI_RXD_ST_OWN 0x80 /* host owns this */ -#define AWI_RXD_ST_CONSUMED 0x40 /* host is done */ -#define AWI_RXD_ST_LF 0x20 /* last frag */ -#define AWI_RXD_ST_CRC 0x08 /* CRC error */ -#define AWI_RXD_ST_OFLO 0x02 /* possible buffer overrun */ -#define AWI_RXD_ST_RXERROR 0x01 /* this frame is borked; discard me */ - -#define AWI_RXD_RSSI 0xa /* 1 byte: radio strength indicator */ -#define AWI_RXD_INDEX 0xb /* 1 byte: FH hop index or DS channel */ -#define AWI_RXD_LOCALTIME 0xc /* 4 bytes: local time of RX */ -#define AWI_RXD_START_FRAME 0x10 /* 4 bytes: ptr to first received byte */ -#define AWI_RXD_LEN 0x14 /* 2 bytes: rx len in bytes */ -#define AWI_RXD_RATE 0x16 /* 1 byte: rx rate in 1e5 bps */ - -/* - * Transmit descriptors. - */ - -#define AWI_TXD_SIZE 0x18 - -#define AWI_TXD_START 0x00 /* pointer to start of frame */ -#define AWI_TXD_NEXT 0x04 /* pointer to next TXD */ -#define AWI_TXD_LENGTH 0x08 /* length of frame */ -#define AWI_TXD_STATE 0x0a /* state */ - -#define AWI_TXD_ST_OWN 0x80 /* MAC owns this */ -#define AWI_TXD_ST_DONE 0x40 /* MAC is done */ -#define AWI_TXD_ST_REJ 0x20 /* MAC doesn't like */ -#define AWI_TXD_ST_MSDU 0x10 /* MSDU timeout */ -#define AWI_TXD_ST_ABRT 0x08 /* TX aborted */ -#define AWI_TXD_ST_RETURNED 0x04 /* TX returned */ -#define AWI_TXD_ST_RETRY 0x02 /* TX retries exceeded */ -#define AWI_TXD_ST_ERROR 0x01 /* TX error */ - -#define AWI_TXD_RATE 0x0b /* rate */ - -#define AWI_RATE_1MBIT 10 -#define AWI_RATE_2MBIT 20 - -#define AWI_TXD_NDA 0x0c /* num DIFS attempts */ -#define AWI_TXD_NDF 0x0d /* num DIFS failures */ -#define AWI_TXD_NSA 0x0e /* num SIFS attempts */ -#define AWI_TXD_NSF 0x0f /* num SIFS failures */ - -#define AWI_TXD_NRA 0x14 /* num RTS attempts */ -#define AWI_TXD_NDTA 0x15 /* num data attempts */ -#define AWI_TXD_CTL 0x16 /* control */ - -#define AWI_TXD_CTL_PSN 0x80 /* preserve sequence in MAC frame */ -#define AWI_TXD_CTL_BURST 0x02 /* host is doing 802.11 fragmt. */ -#define AWI_TXD_CTL_FRAGS 0x01 /* override normal fragmentation */ - -/* - * MIB structures. - */ - -#define AWI_ESS_ID_SIZE (IEEE80211_NWID_LEN+2) -struct awi_mib_local { - u_int8_t Fragmentation_Dis; - u_int8_t Add_PLCP_Dis; - u_int8_t MAC_Hdr_Prsv; - u_int8_t Rx_Mgmt_Que_En; - u_int8_t Re_Assembly_Dis; - u_int8_t Strip_PLCP_Dis; - u_int8_t Rx_Error_Dis; - u_int8_t Power_Saving_Mode_Dis; - u_int8_t Accept_All_Multicast_Dis; - u_int8_t Check_Seq_Cntl_Dis; - u_int8_t Flush_CFP_Queue_On_CF_End; - u_int8_t Network_Mode; - u_int8_t PWD_Lvl; - u_int8_t CFP_Mode; - u_int8_t Tx_Buffer_Offset[4]; - u_int8_t Tx_Buffer_Size[4]; - u_int8_t Rx_Buffer_Offset[4]; - u_int8_t Rx_Buffer_Size[4]; - u_int8_t Acting_as_AP; - u_int8_t Fill_CFP; -}; - -struct awi_mib_mac { - u_int8_t _Reserved1[2]; - u_int8_t _Reserved2[2]; - u_int8_t aRTS_Threshold[2]; - u_int8_t aCW_max[2]; - u_int8_t aCW_min[2]; - u_int8_t aPromiscuous_Enable; - u_int8_t _Reserved3; - u_int8_t _Reserved4[4]; - u_int8_t aShort_Retry_Limit; - u_int8_t aLong_Retry_Limit; - u_int8_t aMax_Frame_Length[2]; - u_int8_t aFragmentation_Threshold[2]; - u_int8_t aProbe_Delay[2]; - u_int8_t aMin_Probe_Response_Time[2]; - u_int8_t aMax_Probe_Response_Time[2]; - u_int8_t aMax_Transmit_MSDU_Lifetime[4]; - u_int8_t aMax_Receive_MSDU_Lifetime[4]; - u_int8_t aStation_Basic_Rate[2]; - u_int8_t aDesired_ESS_ID[AWI_ESS_ID_SIZE]; -}; - -struct awi_mib_stat { - u_int8_t aTransmitted_MPDU_Count[4]; - u_int8_t aTransmitted_MSDU_Count[4]; - u_int8_t aOctets_Transmitted_Cnt[4]; - u_int8_t aMulticast_Transmitted_Frame_Count[2]; - u_int8_t aBroadcast_Transmitted_Frame_Count[2]; - u_int8_t aFailed_Count[4]; - u_int8_t aRetry_Count[4]; - u_int8_t aMultiple_Retry_Count[4]; - u_int8_t aFrame_Duplicate_Count[4]; - u_int8_t aRTS_Success_Count[4]; - u_int8_t aRTS_Failure_Count[4]; - u_int8_t aACK_Failure_Count[4]; - u_int8_t aReceived_Frame_Count [4]; - u_int8_t aOctets_Received_Count[4]; - u_int8_t aMulticast_Received_Count[2]; - u_int8_t aBroadcast_Received_Count[2]; - u_int8_t aFCS_Error_Count[4]; - u_int8_t aError_Count[4]; - u_int8_t aWEP_Undecryptable_Count[4]; -}; - -struct awi_mib_mgt { - u_int8_t aPower_Mgt_Mode; - u_int8_t aScan_Mode; -#define AWI_SCAN_PASSIVE 0x00 -#define AWI_SCAN_ACTIVE 0x01 -#define AWI_SCAN_BACKGROUND 0x02 - u_int8_t aScan_State; - u_int8_t aDTIM_Period; - u_int8_t aATIM_Window[2]; - u_int8_t Wep_Required; - u_int8_t _Reserved1; - u_int8_t aBeacon_Period[2]; - u_int8_t aPassive_Scan_Duration[2]; - u_int8_t aListen_Interval[2]; - u_int8_t aMedium_Occupancy_Limit[2]; - u_int8_t aMax_MPDU_Time[2]; - u_int8_t aCFP_Max_Duration[2]; - u_int8_t aCFP_Rate; - u_int8_t Do_Not_Receive_DTIMs; - u_int8_t aStation_ID[2]; - u_int8_t aCurrent_BSS_ID[ETHER_ADDR_LEN]; - u_int8_t aCurrent_ESS_ID[AWI_ESS_ID_SIZE]; -}; - -#define AWI_GROUP_ADDR_SIZE 4 -struct awi_mib_addr { - u_int8_t aMAC_Address[ETHER_ADDR_LEN]; - u_int8_t aGroup_Addresses[AWI_GROUP_ADDR_SIZE][ETHER_ADDR_LEN]; - u_int8_t aTransmit_Enable_Status; - u_int8_t _Reserved1; -}; - -#define AWI_PWR_LEVEL_SIZE 4 -struct awi_mib_phy { - u_int8_t aSlot_Time[2]; - u_int8_t aSIFS[2]; - u_int8_t aMPDU_Maximum[2]; - u_int8_t aHop_Time[2]; - u_int8_t aSuprt_Data_Rates[4]; - u_int8_t aCurrent_Reg_Domain; -#define AWI_REG_DOMAIN_US 0x10 -#define AWI_REG_DOMAIN_CA 0x20 -#define AWI_REG_DOMAIN_EU 0x30 -#define AWI_REG_DOMAIN_ES 0x31 -#define AWI_REG_DOMAIN_FR 0x32 -#define AWI_REG_DOMAIN_JP 0x40 - u_int8_t aPreamble_Lngth; - u_int8_t aPLCP_Hdr_Lngth; - u_int8_t Pwr_Up_Time[AWI_PWR_LEVEL_SIZE][2]; - u_int8_t IEEE_PHY_Type; -#define AWI_PHY_TYPE_FH 1 -#define AWI_PHY_TYPE_DS 2 -#define AWI_PHY_TYPE_IR 3 - u_int8_t RCR_33A_Bits[8]; -}; diff --git a/sys/dev/ic/awivar.h b/sys/dev/ic/awivar.h deleted file mode 100644 index 754938e8697..00000000000 --- a/sys/dev/ic/awivar.h +++ /dev/null @@ -1,242 +0,0 @@ -/* $OpenBSD: awivar.h,v 1.6 2003/10/21 18:58:49 jmc Exp $ */ -/* $NetBSD: awivar.h,v 1.12 2000/07/21 04:48:56 onoe Exp $ */ - -/*- - * Copyright (c) 1999 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Bill Sommerfeld - * - * 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 the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -/* timer values in msec */ -#define AWI_SELFTEST_TIMEOUT 5000 -#define AWI_CMD_TIMEOUT 2000 -#define AWI_LOCKOUT_TIMEOUT 50 -#define AWI_ASCAN_DURATION 100 -#define AWI_ASCAN_WAIT 3000 -#define AWI_PSCAN_DURATION 200 -#define AWI_PSCAN_WAIT 5000 -#define AWI_TRANS_TIMEOUT 2000 - -#define AWI_NTXBUFS 4 -#define AWI_MAX_KEYLEN 16 - -enum awi_status { - AWI_ST_INIT, - AWI_ST_SCAN, - AWI_ST_SETSS, - AWI_ST_SYNC, - AWI_ST_AUTH, - AWI_ST_ASSOC, - AWI_ST_RUNNING -}; - -struct awi_bss -{ - TAILQ_ENTRY(awi_bss) list; - u_int8_t esrc[ETHER_ADDR_LEN]; - u_int8_t chanset; /* channel set to use */ - u_int8_t pattern; /* hop pattern to use */ - u_int8_t index; /* index to use */ - u_int8_t rssi; /* strength of this beacon */ - u_int16_t dwell_time; /* dwell time */ - u_int8_t timestamp[8]; /* timestamp of this bss */ - u_int8_t bssid[ETHER_ADDR_LEN]; - u_int16_t capinfo; - u_int32_t rxtime; /* unit's local time */ - u_int16_t interval; /* beacon interval */ - u_int8_t txrate; - u_int8_t fails; - u_int8_t essid[IEEE80211_NWID_LEN + 2]; -}; - -struct awi_wep_algo { - char *awa_name; - int (*awa_ctxlen)(void); - void (*awa_setkey)(void *, u_char *, int); - void (*awa_encrypt)(void *, u_char *, u_char *, int); - void (*awa_decrypt)(void *, u_char *, u_char *, int); -}; - -struct awi_softc -{ -#ifdef __NetBSD__ - struct device sc_dev; - struct ethercom sc_ec; - void *sc_ih; /* interrupt handler */ -#endif -#ifdef __FreeBSD__ -#if __FreeBSD__ >= 4 - struct { - char dv_xname[64]; /*XXX*/ - } sc_dev; -#else - struct device sc_dev; -#endif -#endif -#ifdef __OpenBSD__ - struct device sc_dev; - struct arpcom sc_arpcom; - void *sc_ih; /* interrupt handler */ -#endif - struct am79c930_softc sc_chip; - struct ifnet *sc_ifp; - int (*sc_enable)(struct awi_softc *); - void (*sc_disable)(struct awi_softc *); - - struct ifmedia sc_media; - enum awi_status sc_status; - unsigned int sc_enabled:1, - sc_busy:1, - sc_cansleep:1, - sc_invalid:1, - sc_enab_intr:1, - sc_format_llc:1, - sc_start_bss:1, - sc_rawbpf:1, - sc_no_bssid:1, - sc_active_scan:1, - sc_attached:1; /* attach has succeeded */ - u_int8_t sc_cmd_inprog; - int sc_sleep_cnt; - - int sc_mgt_timer; - - TAILQ_HEAD(, awi_bss) sc_scan; - u_int8_t sc_scan_cur; - u_int8_t sc_scan_min; - u_int8_t sc_scan_max; - u_int8_t sc_scan_set; - struct awi_bss sc_bss; - u_int8_t sc_ownssid[IEEE80211_NWID_LEN + 2]; - u_int8_t sc_ownch; - - int sc_rx_timer; - u_int32_t sc_rxdoff; - u_int32_t sc_rxmoff; - struct mbuf *sc_rxpend; - - int sc_tx_timer; - u_int8_t sc_tx_rate; - struct ifqueue sc_mgtq; - u_int32_t sc_txbase; - u_int32_t sc_txend; - u_int32_t sc_txnext; - u_int32_t sc_txdone; - - int sc_wep_keylen[IEEE80211_WEP_NKID]; /* keylen */ - u_int8_t sc_wep_key[IEEE80211_WEP_NKID][AWI_MAX_KEYLEN]; - int sc_wep_defkid; - void *sc_wep_ctx; /* work area */ - struct awi_wep_algo *sc_wep_algo; - - u_char sc_banner[AWI_BANNER_LEN]; - struct awi_mib_local sc_mib_local; - struct awi_mib_addr sc_mib_addr; - struct awi_mib_mac sc_mib_mac; - struct awi_mib_stat sc_mib_stat; - struct awi_mib_mgt sc_mib_mgt; - struct awi_mib_phy sc_mib_phy; -}; - -#define awi_read_1(sc, off) ((sc)->sc_chip.sc_ops->read_1)(&sc->sc_chip, off) -#define awi_read_2(sc, off) ((sc)->sc_chip.sc_ops->read_2)(&sc->sc_chip, off) -#define awi_read_4(sc, off) ((sc)->sc_chip.sc_ops->read_4)(&sc->sc_chip, off) -#define awi_read_bytes(sc, off, ptr, len) ((sc)->sc_chip.sc_ops->read_bytes)(&sc->sc_chip, off, ptr, len) - -#define awi_write_1(sc, off, val) \ - ((sc)->sc_chip.sc_ops->write_1)(&sc->sc_chip, off, val) -#define awi_write_2(sc, off, val) \ - ((sc)->sc_chip.sc_ops->write_2)(&sc->sc_chip, off, val) -#define awi_write_4(sc, off, val) \ - ((sc)->sc_chip.sc_ops->write_4)(&sc->sc_chip, off, val) -#define awi_write_bytes(sc, off, ptr, len) \ - ((sc)->sc_chip.sc_ops->write_bytes)(&sc->sc_chip, off, ptr, len) - -#define awi_drvstate(sc, state) \ - awi_write_1(sc, AWI_DRIVERSTATE, \ - ((state) | AWI_DRV_AUTORXLED|AWI_DRV_AUTOTXLED)) - -/* unaligned little endian access */ -#define LE_READ_2(p) \ - (((u_int8_t *)(p))[0] | (((u_int8_t *)(p))[1] << 8)) -#define LE_READ_4(p) \ - (((u_int8_t *)(p))[0] | (((u_int8_t *)(p))[1] << 8) | \ - (((u_int8_t *)(p))[2] << 16) | (((u_int8_t *)(p))[3] << 24)) -#define LE_WRITE_2(p, v) \ - ((((u_int8_t *)(p))[0] = ((u_int32_t)(v) & 0xff)), \ - (((u_int8_t *)(p))[1] = (((u_int32_t)(v) >> 8) & 0xff))) -#define LE_WRITE_4(p, v) \ - ((((u_int8_t *)(p))[0] = ((u_int32_t)(v) & 0xff)), \ - (((u_int8_t *)(p))[1] = (((u_int32_t)(v) >> 8) & 0xff)), \ - (((u_int8_t *)(p))[2] = (((u_int32_t)(v) >> 16) & 0xff)), \ - (((u_int8_t *)(p))[3] = (((u_int32_t)(v) >> 24) & 0xff))) - -#define AWI_80211_RATE(rate) (((rate) & 0x7f) * 5) - -int awi_attach(struct awi_softc *); -int awi_intr(void *); -void awi_reset(struct awi_softc *); -#ifndef __FreeBSD__ -int awi_activate(struct device *, enum devact); -int awi_detach(struct awi_softc *); -void awi_power(struct awi_softc *, int); -#endif - -void awi_stop(struct awi_softc *sc); -int awi_init(struct awi_softc *sc); -int awi_init_region(struct awi_softc *); -int awi_wicfg(struct ifnet *, u_long, caddr_t); - -int awi_wep_setnwkey(struct awi_softc *, struct ieee80211_nwkey *); -int awi_wep_getnwkey(struct awi_softc *, struct ieee80211_nwkey *); -int awi_wep_getalgo(struct awi_softc *); -int awi_wep_setalgo(struct awi_softc *, int); -int awi_wep_setkey(struct awi_softc *, int, unsigned char *, int); -int awi_wep_getkey(struct awi_softc *, int, unsigned char *, int *); -struct mbuf *awi_wep_encrypt(struct awi_softc *, struct mbuf *, int); - -#ifdef __FreeBSD__ -/* Provide mem* for compat with NetBSD to fix LINT */ -static __inline int -memcmp(const void *b1, const void *b2, size_t len) -{ - return (bcmp(b1, b2, len)); -} - -static __inline void * -memset(void *b, int c, size_t len) -{ - bzero(b, len); - return (b); -} -#endif |