mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-16 10:20:30 +00:00
Use generic net80211 framework for awi driver.
Restore awi to be workable again; it was broken.. XXX: The initialization is still unreliable yet, it sometimes fails on some card.
This commit is contained in:
parent
92b3ea67b9
commit
d148e81e76
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=124546
@ -324,8 +324,6 @@ dev/ath/if_ath_pci.c optional ath pci
|
||||
dev/ath/if_ath_pci.c optional ath card
|
||||
dev/awi/am79c930.c optional awi
|
||||
dev/awi/awi.c optional awi
|
||||
dev/awi/awi_wep.c optional awi
|
||||
dev/awi/awi_wicfg.c optional awi
|
||||
dev/awi/if_awi_pccard.c optional awi card
|
||||
dev/awi/if_awi_pccard.c optional awi pccard
|
||||
dev/bfe/if_bfe.c optional bfe
|
||||
@ -1404,7 +1402,6 @@ netgraph/ng_lmi.c optional netgraph_lmi
|
||||
netgraph/ng_l2tp.c optional netgraph_l2tp
|
||||
netgraph/ng_mppc.c optional netgraph_mppc_compression
|
||||
netgraph/ng_mppc.c optional netgraph_mppc_encryption
|
||||
crypto/rc4/rc4.c optional awi
|
||||
crypto/rc4/rc4.c optional wlan
|
||||
crypto/rc4/rc4.c optional netgraph_mppc_encryption
|
||||
crypto/sha1.c optional netgraph_mppc_encryption
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* $NetBSD: am79c930.c,v 1.5 2000/03/23 13:57:58 onoe Exp $ */
|
||||
/* $NetBSD: am79c930.c,v 1.9 2004/01/15 09:33:48 onoe Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
@ -35,9 +36,6 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Am79c930 chip driver.
|
||||
*
|
||||
@ -62,8 +60,17 @@ __FBSDID("$FreeBSD$");
|
||||
* end isr
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __NetBSD__
|
||||
__KERNEL_RCSID(0, "$NetBSD: am79c930.c,v 1.9 2004/01/15 09:33:48 onoe Exp $");
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
__FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/endian.h>
|
||||
#ifndef __FreeBSD__
|
||||
#include <sys/device.h>
|
||||
#endif
|
||||
@ -133,10 +140,8 @@ struct am79c930_ops memspace_ops = {
|
||||
mem_read_bytes
|
||||
};
|
||||
|
||||
static void io_write_1 (sc, off, val)
|
||||
struct am79c930_softc *sc;
|
||||
u_int32_t off;
|
||||
u_int8_t val;
|
||||
static void
|
||||
io_write_1( 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,
|
||||
@ -148,10 +153,8 @@ static void io_write_1 (sc, off, val)
|
||||
AM930_DELAY(1);
|
||||
}
|
||||
|
||||
static void io_write_2 (sc, off, val)
|
||||
struct am79c930_softc *sc;
|
||||
u_int32_t off;
|
||||
u_int16_t val;
|
||||
static void
|
||||
io_write_2(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,
|
||||
@ -165,10 +168,8 @@ static void io_write_2 (sc, off, val)
|
||||
AM930_DELAY(1);
|
||||
}
|
||||
|
||||
static void io_write_4 (sc, off, val)
|
||||
struct am79c930_softc *sc;
|
||||
u_int32_t off;
|
||||
u_int32_t val;
|
||||
static void
|
||||
io_write_4(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,
|
||||
@ -186,11 +187,9 @@ static void io_write_4 (sc, off, val)
|
||||
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;
|
||||
static void
|
||||
io_write_bytes(struct am79c930_softc *sc, u_int32_t off, u_int8_t *ptr,
|
||||
size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -204,12 +203,11 @@ static void io_write_bytes (sc, off, ptr, len)
|
||||
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;
|
||||
static u_int8_t
|
||||
io_read_1(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);
|
||||
@ -220,9 +218,8 @@ static u_int8_t io_read_1 (sc, off)
|
||||
return val;
|
||||
}
|
||||
|
||||
static u_int16_t io_read_2 (sc, off)
|
||||
struct am79c930_softc *sc;
|
||||
u_int32_t off;
|
||||
static u_int16_t
|
||||
io_read_2(struct am79c930_softc *sc, u_int32_t off)
|
||||
{
|
||||
u_int16_t val;
|
||||
|
||||
@ -238,9 +235,8 @@ static u_int16_t io_read_2 (sc, off)
|
||||
return val;
|
||||
}
|
||||
|
||||
static u_int32_t io_read_4 (sc, off)
|
||||
struct am79c930_softc *sc;
|
||||
u_int32_t off;
|
||||
static u_int32_t
|
||||
io_read_4(struct am79c930_softc *sc, u_int32_t off)
|
||||
{
|
||||
u_int32_t val;
|
||||
|
||||
@ -260,11 +256,9 @@ static u_int32_t io_read_4 (sc, off)
|
||||
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;
|
||||
static void
|
||||
io_read_bytes(struct am79c930_softc *sc, u_int32_t off, u_int8_t *ptr,
|
||||
size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -278,42 +272,36 @@ static void io_read_bytes (sc, off, ptr, len)
|
||||
AM79C930_IODPA);
|
||||
}
|
||||
|
||||
static void mem_write_1 (sc, off, val)
|
||||
struct am79c930_softc *sc;
|
||||
u_int32_t off;
|
||||
u_int8_t val;
|
||||
static void
|
||||
mem_write_1(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;
|
||||
static
|
||||
void mem_write_2(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);
|
||||
bus_space_write_2(t, h, off, htole16(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;
|
||||
static void
|
||||
mem_write_4(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);
|
||||
bus_space_write_4(t, h, off, htole32(val));
|
||||
else {
|
||||
bus_space_write_1(t, h, off, val & 0xff);
|
||||
bus_space_write_1(t, h, off+1, (val >> 8) & 0xff);
|
||||
@ -322,43 +310,37 @@ static void mem_write_4 (sc, off, val)
|
||||
}
|
||||
}
|
||||
|
||||
static void mem_write_bytes (sc, off, ptr, len)
|
||||
struct am79c930_softc *sc;
|
||||
u_int32_t off;
|
||||
u_int8_t *ptr;
|
||||
size_t len;
|
||||
static void
|
||||
mem_write_bytes(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;
|
||||
static u_int8_t
|
||||
mem_read_1(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;
|
||||
static u_int16_t
|
||||
mem_read_2(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);
|
||||
return le16toh(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;
|
||||
static u_int32_t
|
||||
mem_read_4(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);
|
||||
return le32toh(bus_space_read_4(sc->sc_memt, sc->sc_memh, off));
|
||||
else
|
||||
return
|
||||
bus_space_read_1(sc->sc_memt, sc->sc_memh, off ) |
|
||||
@ -367,27 +349,20 @@ static u_int32_t mem_read_4 (sc, off)
|
||||
(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;
|
||||
static void
|
||||
mem_read_bytes(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;
|
||||
void
|
||||
am79c930_gcr_setbits(struct am79c930_softc *sc, u_int8_t bits)
|
||||
{
|
||||
u_int8_t gcr = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
|
||||
|
||||
@ -400,9 +375,8 @@ void am79c930_gcr_setbits (sc, bits)
|
||||
* Clear bits in GCR.
|
||||
*/
|
||||
|
||||
void am79c930_gcr_clearbits (sc, bits)
|
||||
struct am79c930_softc *sc;
|
||||
u_int8_t bits;
|
||||
void
|
||||
am79c930_gcr_clearbits(struct am79c930_softc *sc, u_int8_t bits)
|
||||
{
|
||||
u_int8_t gcr = bus_space_read_1 (sc->sc_iot, sc->sc_ioh, AM79C930_GCR);
|
||||
|
||||
@ -411,15 +385,15 @@ void am79c930_gcr_clearbits (sc, 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;
|
||||
u_int8_t
|
||||
am79c930_gcr_read(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;
|
||||
void
|
||||
am79c930_regdump(struct am79c930_softc *sc)
|
||||
{
|
||||
u_int8_t buf[8];
|
||||
int i;
|
||||
@ -437,9 +411,8 @@ void am79c930_regdump (sc)
|
||||
}
|
||||
#endif
|
||||
|
||||
void am79c930_chip_init (sc, how)
|
||||
struct am79c930_softc *sc;
|
||||
int how;
|
||||
void
|
||||
am79c930_chip_init(struct am79c930_softc *sc, int how)
|
||||
{
|
||||
/* zero the bank select register, and leave it that way.. */
|
||||
bus_space_write_1(sc->sc_iot, sc->sc_ioh, AM79C930_BSS, 0);
|
||||
@ -448,5 +421,3 @@ void am79c930_chip_init (sc, how)
|
||||
else
|
||||
sc->sc_ops = &iospace_ops;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: am79c930reg.h,v 1.3 2000/03/22 11:22:22 onoe Exp $ */
|
||||
/* $NetBSD: am79c930reg.h,v 1.4 2003/11/02 11:07:45 wiz Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*-
|
||||
@ -99,7 +99,7 @@
|
||||
#define AM79C930_LMA_HI_ISAPWRDWN 0x80
|
||||
|
||||
/*
|
||||
* mmm, inconsistancy in chip documentation:
|
||||
* 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
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD$ */
|
||||
/* $NetBSD: am79c930var.h,v 1.3 2004/01/15 09:33:48 onoe Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*-
|
||||
|
3729
sys/dev/awi/awi.c
3729
sys/dev/awi/awi.c
File diff suppressed because it is too large
Load Diff
@ -1,533 +0,0 @@
|
||||
/* $NetBSD: awi_wep.c,v 1.4 2000/08/14 11:28:03 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* 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/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/sockio.h>
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 400000
|
||||
#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>
|
||||
#else
|
||||
#include <net/if_ether.h>
|
||||
#endif
|
||||
#include <net/if_media.h>
|
||||
|
||||
#include <net80211/ieee80211.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#include <dev/ic/am79c930reg.h>
|
||||
#include <dev/ic/am79c930var.h>
|
||||
#include <dev/ic/awireg.h>
|
||||
#include <dev/ic/awivar.h>
|
||||
|
||||
#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, src, dst, 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 */
|
||||
|
||||
/* 1: normal wep (arc4) */
|
||||
{ "arc4", arc4_ctxlen, arc4_setkey,
|
||||
arc4_encrypt, arc4_encrypt },
|
||||
|
||||
/* 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__
|
||||
#if __FreeBSD_version < 500028
|
||||
suerr = suser(curproc);
|
||||
#else
|
||||
suerr = suser(curthread);
|
||||
#endif
|
||||
#else
|
||||
suerr = suser(curproc->p_ucred, &curproc->p_acflag);
|
||||
#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_MOVE_PKTHDR(n, m);
|
||||
len = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN;
|
||||
if (txflag) {
|
||||
n->m_pkthdr.len += len;
|
||||
} else {
|
||||
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 = random();
|
||||
/*
|
||||
* 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[IEEE80211_WEP_IVLEN] = kid << 6; /* pad and keyid */
|
||||
noff += IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN;
|
||||
} else {
|
||||
ivp = mtod(m, u_int8_t *) + moff;
|
||||
kid = ivp[IEEE80211_WEP_IVLEN] >> 6;
|
||||
moff += IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN;
|
||||
}
|
||||
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;
|
||||
for (noff = 0; noff < sizeof(crcbuf); noff += len) {
|
||||
len = sizeof(crcbuf) - noff;
|
||||
if (len > m->m_len - moff)
|
||||
len = m->m_len - moff;
|
||||
if (len > 0)
|
||||
awa->awa_decrypt(ctx, crcbuf + noff,
|
||||
mtod(m, caddr_t) + moff, len);
|
||||
m = m->m_next;
|
||||
moff = 0;
|
||||
}
|
||||
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);
|
||||
}
|
@ -1,634 +0,0 @@
|
||||
/* $NetBSD: awi_wicfg.c,v 1.3 2000/07/06 17:22:25 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* WaveLAN compatible configuration support routines for the awi driver.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/sockio.h>
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 400000
|
||||
#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>
|
||||
#else
|
||||
#include <net/if_ether.h>
|
||||
#endif
|
||||
#include <net/if_media.h>
|
||||
|
||||
#include <net80211/ieee80211.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#include <dev/ic/am79c930reg.h>
|
||||
#include <dev/ic/am79c930var.h>
|
||||
#include <dev/ic/awireg.h>
|
||||
#include <dev/ic/awivar.h>
|
||||
|
||||
#include <dev/pcmcia/if_wi_ieee.h> /* XXX */
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
#include <dev/awi/am79c930reg.h>
|
||||
#include <dev/awi/am79c930var.h>
|
||||
|
||||
#undef _KERNEL /* XXX */
|
||||
#include <dev/wi/if_wavelan_ieee.h> /* XXX */
|
||||
#define _KERNEL /* XXX */
|
||||
#include <dev/awi/awireg.h>
|
||||
#include <dev/awi/awivar.h>
|
||||
#endif
|
||||
|
||||
static int awi_cfgget(struct ifnet *ifp, u_long cmd, caddr_t data);
|
||||
static int awi_cfgset(struct ifnet *ifp, u_long cmd, caddr_t data);
|
||||
|
||||
int
|
||||
awi_wicfg(ifp, cmd, data)
|
||||
struct ifnet *ifp;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
{
|
||||
int error;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCGWAVELAN:
|
||||
error = awi_cfgget(ifp, cmd, data);
|
||||
break;
|
||||
case SIOCSWAVELAN:
|
||||
#ifdef __FreeBSD__
|
||||
#if __FreeBSD_version < 500028
|
||||
error = suser(curproc);
|
||||
#else
|
||||
error = suser(curthread);
|
||||
#endif
|
||||
#else
|
||||
error = suser(curproc->p_ucred, &curproc->p_acflag);
|
||||
#endif
|
||||
if (error)
|
||||
break;
|
||||
error = awi_cfgset(ifp, cmd, data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
awi_cfgget(ifp, cmd, data)
|
||||
struct ifnet *ifp;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
{
|
||||
int i, error, keylen;
|
||||
char *p;
|
||||
struct awi_softc *sc = (struct awi_softc *)ifp->if_softc;
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
struct wi_ltv_keys *keys;
|
||||
struct wi_key *k;
|
||||
struct wi_req wreq;
|
||||
#ifdef WICACHE
|
||||
struct wi_sigcache wsc;
|
||||
struct awi_bss *bp;
|
||||
#endif /* WICACHE */
|
||||
|
||||
error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
|
||||
if (error)
|
||||
return error;
|
||||
switch (wreq.wi_type) {
|
||||
case WI_RID_SERIALNO:
|
||||
memcpy(wreq.wi_val, sc->sc_banner, AWI_BANNER_LEN);
|
||||
wreq.wi_len = (AWI_BANNER_LEN + 1) / 2;
|
||||
break;
|
||||
case WI_RID_NODENAME:
|
||||
strcpy((char *)&wreq.wi_val[1], hostname);
|
||||
wreq.wi_val[0] = strlen(hostname);
|
||||
wreq.wi_len = (1 + wreq.wi_val[0] + 1) / 2;
|
||||
break;
|
||||
case WI_RID_OWN_SSID:
|
||||
p = sc->sc_ownssid;
|
||||
wreq.wi_val[0] = p[1];
|
||||
memcpy(&wreq.wi_val[1], p + 2, p[1]);
|
||||
wreq.wi_len = (1 + wreq.wi_val[0] + 1) / 2;
|
||||
break;
|
||||
case WI_RID_CURRENT_SSID:
|
||||
if (ifp->if_flags & IFF_RUNNING) {
|
||||
p = sc->sc_bss.essid;
|
||||
wreq.wi_val[0] = p[1];
|
||||
memcpy(&wreq.wi_val[1], p + 2, p[1]);
|
||||
} else {
|
||||
wreq.wi_val[0] = 0;
|
||||
wreq.wi_val[1] = '\0';
|
||||
}
|
||||
wreq.wi_len = (1 + wreq.wi_val[0] + 1) / 2;
|
||||
break;
|
||||
case WI_RID_DESIRED_SSID:
|
||||
p = sc->sc_mib_mac.aDesired_ESS_ID;
|
||||
wreq.wi_val[0] = p[1];
|
||||
memcpy(&wreq.wi_val[1], p + 2, p[1]);
|
||||
wreq.wi_len = (1 + wreq.wi_val[0] + 1) / 2;
|
||||
break;
|
||||
case WI_RID_CURRENT_BSSID:
|
||||
if (ifp->if_flags & IFF_RUNNING)
|
||||
memcpy(wreq.wi_val, sc->sc_bss.bssid, ETHER_ADDR_LEN);
|
||||
else
|
||||
memset(wreq.wi_val, 0, ETHER_ADDR_LEN);
|
||||
wreq.wi_len = ETHER_ADDR_LEN / 2;
|
||||
break;
|
||||
case WI_RID_CHANNEL_LIST:
|
||||
if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) {
|
||||
wreq.wi_val[0] = sc->sc_scan_min;
|
||||
wreq.wi_val[1] = sc->sc_scan_max;
|
||||
wreq.wi_len = 2;
|
||||
} else {
|
||||
wreq.wi_val[0] = 0;
|
||||
for (i = sc->sc_scan_min; i <= sc->sc_scan_max; i++)
|
||||
wreq.wi_val[0] |= 1 << (i - 1);
|
||||
wreq.wi_len = 1;
|
||||
}
|
||||
break;
|
||||
case WI_RID_OWN_CHNL:
|
||||
wreq.wi_val[0] = sc->sc_ownch;
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_CURRENT_CHAN:
|
||||
if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH)
|
||||
wreq.wi_val[0] = sc->sc_bss.pattern;
|
||||
else
|
||||
wreq.wi_val[0] = sc->sc_bss.chanset;
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_COMMS_QUALITY:
|
||||
wreq.wi_val[0] = 0; /* quality */
|
||||
wreq.wi_val[1] = sc->sc_bss.rssi; /* signal */
|
||||
wreq.wi_val[2] = 0; /* noise */
|
||||
wreq.wi_len = 3;
|
||||
break;
|
||||
case WI_RID_PROMISC:
|
||||
wreq.wi_val[0] = sc->sc_mib_mac.aPromiscuous_Enable;
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_PORTTYPE:
|
||||
if (sc->sc_mib_local.Network_Mode)
|
||||
wreq.wi_val[0] = 1;
|
||||
else if (!sc->sc_no_bssid)
|
||||
wreq.wi_val[0] = 2;
|
||||
else
|
||||
wreq.wi_val[0] = 3;
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_MAC_NODE:
|
||||
memcpy(wreq.wi_val, sc->sc_mib_addr.aMAC_Address,
|
||||
ETHER_ADDR_LEN);
|
||||
wreq.wi_len = ETHER_ADDR_LEN / 2;
|
||||
break;
|
||||
case WI_RID_TX_RATE:
|
||||
case WI_RID_CUR_TX_RATE:
|
||||
wreq.wi_val[0] = sc->sc_tx_rate / 10;
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_RTS_THRESH:
|
||||
wreq.wi_val[0] = LE_READ_2(&sc->sc_mib_mac.aRTS_Threshold);
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_CREATE_IBSS:
|
||||
wreq.wi_val[0] = sc->sc_start_bss;
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_SYSTEM_SCALE:
|
||||
wreq.wi_val[0] = 1; /* low density ... not supported */
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_PM_ENABLED:
|
||||
wreq.wi_val[0] = sc->sc_mib_local.Power_Saving_Mode_Dis ? 0 : 1;
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_MAX_SLEEP:
|
||||
wreq.wi_val[0] = 0; /* not implemented */
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_WEP_AVAIL:
|
||||
wreq.wi_val[0] = 1;
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_ENCRYPTION:
|
||||
wreq.wi_val[0] = awi_wep_getalgo(sc);
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_TX_CRYPT_KEY:
|
||||
wreq.wi_val[0] = sc->sc_wep_defkid;
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_DEFLT_CRYPT_KEYS:
|
||||
keys = (struct wi_ltv_keys *)&wreq;
|
||||
/* do not show keys to non-root user */
|
||||
#ifdef __FreeBSD__
|
||||
#if __FreeBSD_version < 500028
|
||||
error = suser(curproc);
|
||||
#else
|
||||
error = suser(curthread);
|
||||
#endif
|
||||
#else
|
||||
error = suser(curproc->p_ucred, &curproc->p_acflag);
|
||||
#endif
|
||||
if (error) {
|
||||
memset(keys, 0, sizeof(*keys));
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < IEEE80211_WEP_NKID; i++) {
|
||||
k = &keys->wi_keys[i];
|
||||
keylen = sizeof(k->wi_keydat);
|
||||
error = awi_wep_getkey(sc, i, k->wi_keydat, &keylen);
|
||||
if (error)
|
||||
break;
|
||||
k->wi_keylen = keylen;
|
||||
}
|
||||
wreq.wi_len = sizeof(*keys) / 2;
|
||||
break;
|
||||
case WI_RID_MAX_DATALEN:
|
||||
wreq.wi_val[0] = LE_READ_2(&sc->sc_mib_mac.aMax_Frame_Length);
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_IFACE_STATS:
|
||||
/* not implemented yet */
|
||||
wreq.wi_len = 0;
|
||||
break;
|
||||
#ifdef WICACHE
|
||||
case WI_RID_READ_CACHE:
|
||||
for (bp = TAILQ_FIRST(&sc->sc_scan), i = 0;
|
||||
bp != NULL && i < MAXWICACHE;
|
||||
bp = TAILQ_NEXT(bp, list), i++) {
|
||||
memcpy(wsc.macsrc, bp->esrc, ETHER_ADDR_LEN);
|
||||
/*XXX*/
|
||||
memcpy(&wsc.ipsrc, bp->bssid, sizeof(wsc.ipsrc));
|
||||
wsc.signal = bp->rssi;
|
||||
wsc.noise = 0;
|
||||
wsc.quality = 0;
|
||||
memcpy((caddr_t)wreq.wi_val + sizeof(wsc) * i,
|
||||
&wsc, sizeof(wsc));
|
||||
}
|
||||
wreq.wi_len = sizeof(wsc) * i / 2;
|
||||
break;
|
||||
#endif /* WICACHE */
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (error == 0) {
|
||||
wreq.wi_len++;
|
||||
error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
awi_cfgset(ifp, cmd, data)
|
||||
struct ifnet *ifp;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
{
|
||||
int i, error, rate, oregion;
|
||||
u_int8_t *phy_rates;
|
||||
struct awi_softc *sc = (struct awi_softc *)ifp->if_softc;
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
struct wi_ltv_keys *keys;
|
||||
struct wi_key *k;
|
||||
struct wi_req wreq;
|
||||
|
||||
error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
|
||||
if (error)
|
||||
return error;
|
||||
if (wreq.wi_len-- < 1)
|
||||
return EINVAL;
|
||||
switch (wreq.wi_type) {
|
||||
case WI_RID_SERIALNO:
|
||||
case WI_RID_NODENAME:
|
||||
error = EPERM;
|
||||
break;
|
||||
case WI_RID_OWN_SSID:
|
||||
if (wreq.wi_len < (1 + wreq.wi_val[0] + 1) / 2) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (wreq.wi_val[0] > IEEE80211_NWID_LEN) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
memset(sc->sc_ownssid, 0, AWI_ESS_ID_SIZE);
|
||||
sc->sc_ownssid[0] = IEEE80211_ELEMID_SSID;
|
||||
sc->sc_ownssid[1] = wreq.wi_val[0];
|
||||
memcpy(&sc->sc_ownssid[2], &wreq.wi_val[1], wreq.wi_val[0]);
|
||||
if (!sc->sc_mib_local.Network_Mode &&
|
||||
!sc->sc_no_bssid && sc->sc_start_bss)
|
||||
error = ENETRESET;
|
||||
break;
|
||||
case WI_RID_CURRENT_SSID:
|
||||
error = EPERM;
|
||||
break;
|
||||
case WI_RID_DESIRED_SSID:
|
||||
if (wreq.wi_len < (1 + wreq.wi_val[0] + 1) / 2) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (wreq.wi_val[0] > IEEE80211_NWID_LEN) {
|
||||
error = EINVAL;
|
||||
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] = wreq.wi_val[0];
|
||||
memcpy(&sc->sc_mib_mac.aDesired_ESS_ID[2], &wreq.wi_val[1],
|
||||
wreq.wi_val[0]);
|
||||
if (sc->sc_mib_local.Network_Mode || !sc->sc_no_bssid)
|
||||
error = ENETRESET;
|
||||
break;
|
||||
case WI_RID_CURRENT_BSSID:
|
||||
error = EPERM;
|
||||
break;
|
||||
case WI_RID_CHANNEL_LIST:
|
||||
if (wreq.wi_len != 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
oregion = sc->sc_mib_phy.aCurrent_Reg_Domain;
|
||||
if (wreq.wi_val[0] == oregion)
|
||||
break;
|
||||
sc->sc_mib_phy.aCurrent_Reg_Domain = wreq.wi_val[0];
|
||||
error = awi_init_region(sc);
|
||||
if (error) {
|
||||
sc->sc_mib_phy.aCurrent_Reg_Domain = oregion;
|
||||
break;
|
||||
}
|
||||
error = ENETRESET;
|
||||
break;
|
||||
case WI_RID_OWN_CHNL:
|
||||
if (wreq.wi_len != 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (wreq.wi_val[0] < sc->sc_scan_min ||
|
||||
wreq.wi_val[0] > sc->sc_scan_max) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
sc->sc_ownch = wreq.wi_val[0];
|
||||
if (!sc->sc_mib_local.Network_Mode)
|
||||
error = ENETRESET;
|
||||
break;
|
||||
case WI_RID_CURRENT_CHAN:
|
||||
error = EPERM;
|
||||
break;
|
||||
case WI_RID_COMMS_QUALITY:
|
||||
error = EPERM;
|
||||
break;
|
||||
case WI_RID_PROMISC:
|
||||
if (wreq.wi_len != 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (ifp->if_flags & IFF_PROMISC) {
|
||||
if (wreq.wi_val[0] == 0) {
|
||||
ifp->if_flags &= ~IFF_PROMISC;
|
||||
error = ENETRESET;
|
||||
}
|
||||
} else {
|
||||
if (wreq.wi_val[0] != 0) {
|
||||
ifp->if_flags |= IFF_PROMISC;
|
||||
error = ENETRESET;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WI_RID_PORTTYPE:
|
||||
if (wreq.wi_len != 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
switch (wreq.wi_val[0]) {
|
||||
case 1:
|
||||
sc->sc_mib_local.Network_Mode = 1;
|
||||
sc->sc_no_bssid = 0;
|
||||
error = ENETRESET;
|
||||
break;
|
||||
case 2:
|
||||
sc->sc_mib_local.Network_Mode = 0;
|
||||
sc->sc_no_bssid = 0;
|
||||
error = ENETRESET;
|
||||
break;
|
||||
case 3:
|
||||
if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
sc->sc_mib_local.Network_Mode = 0;
|
||||
sc->sc_no_bssid = 1;
|
||||
error = ENETRESET;
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WI_RID_MAC_NODE:
|
||||
/* XXX: should be implemented? */
|
||||
error = EPERM;
|
||||
break;
|
||||
case WI_RID_TX_RATE:
|
||||
if (wreq.wi_len != 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
phy_rates = sc->sc_mib_phy.aSuprt_Data_Rates;
|
||||
switch (wreq.wi_val[0]) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 5:
|
||||
case 11:
|
||||
rate = wreq.wi_val[0] * 10;
|
||||
if (rate == 50)
|
||||
rate += 5; /*XXX*/
|
||||
break;
|
||||
case 3:
|
||||
case 6:
|
||||
case 7:
|
||||
/* auto rate */
|
||||
phy_rates = sc->sc_mib_phy.aSuprt_Data_Rates;
|
||||
rate = AWI_RATE_1MBIT;
|
||||
for (i = 0; i < phy_rates[1]; i++) {
|
||||
if (AWI_80211_RATE(phy_rates[2 + i]) > rate)
|
||||
rate = AWI_80211_RATE(phy_rates[2 + i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rate = 0;
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (error)
|
||||
break;
|
||||
for (i = 0; i < phy_rates[1]; i++) {
|
||||
if (rate == AWI_80211_RATE(phy_rates[2 + i]))
|
||||
break;
|
||||
}
|
||||
if (i == phy_rates[1]) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
sc->sc_tx_rate = rate;
|
||||
break;
|
||||
case WI_RID_CUR_TX_RATE:
|
||||
error = EPERM;
|
||||
break;
|
||||
case WI_RID_RTS_THRESH:
|
||||
if (wreq.wi_len != 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
LE_WRITE_2(&sc->sc_mib_mac.aRTS_Threshold, wreq.wi_val[0]);
|
||||
error = ENETRESET;
|
||||
break;
|
||||
case WI_RID_CREATE_IBSS:
|
||||
if (wreq.wi_len != 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
sc->sc_start_bss = wreq.wi_val[0] ? 1 : 0;
|
||||
error = ENETRESET;
|
||||
break;
|
||||
case WI_RID_SYSTEM_SCALE:
|
||||
if (wreq.wi_len != 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (wreq.wi_val[0] != 1)
|
||||
error = EINVAL; /* not supported */
|
||||
break;
|
||||
case WI_RID_PM_ENABLED:
|
||||
if (wreq.wi_len != 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (wreq.wi_val[0] != 0)
|
||||
error = EINVAL; /* not implemented */
|
||||
break;
|
||||
case WI_RID_MAX_SLEEP:
|
||||
error = EINVAL; /* not implemented */
|
||||
break;
|
||||
case WI_RID_WEP_AVAIL:
|
||||
error = EPERM;
|
||||
break;
|
||||
case WI_RID_ENCRYPTION:
|
||||
if (wreq.wi_len != 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
error = awi_wep_setalgo(sc, wreq.wi_val[0]);
|
||||
if (error)
|
||||
break;
|
||||
error = ENETRESET;
|
||||
break;
|
||||
case WI_RID_TX_CRYPT_KEY:
|
||||
if (wreq.wi_len != 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (wreq.wi_val[0] >= IEEE80211_WEP_NKID) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
sc->sc_wep_defkid = wreq.wi_val[1];
|
||||
break;
|
||||
case WI_RID_DEFLT_CRYPT_KEYS:
|
||||
if (wreq.wi_len != sizeof(*keys) / 2) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
keys = (struct wi_ltv_keys *)&wreq;
|
||||
for (i = 0; i < IEEE80211_WEP_NKID; i++) {
|
||||
k = &keys->wi_keys[i];
|
||||
error = awi_wep_setkey(sc, i, k->wi_keydat,
|
||||
k->wi_keylen);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WI_RID_MAX_DATALEN:
|
||||
if (wreq.wi_len != 1) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (wreq.wi_val[0] < 350 || wreq.wi_val[0] > 2304) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
LE_WRITE_2(&sc->sc_mib_mac.aMax_Frame_Length, wreq.wi_val[0]);
|
||||
break;
|
||||
case WI_RID_IFACE_STATS:
|
||||
error = EPERM;
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (error == ENETRESET) {
|
||||
if (sc->sc_enabled) {
|
||||
awi_stop(sc);
|
||||
error = awi_init(sc);
|
||||
} else
|
||||
error = 0;
|
||||
}
|
||||
return error;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: awireg.h,v 1.3 2000/03/22 11:22:22 onoe Exp $ */
|
||||
/* $NetBSD: awireg.h,v 1.8 2003/01/20 05:30:06 simonb Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*-
|
||||
@ -37,6 +37,9 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _DEV_IC_AWIREG_H
|
||||
#define _DEV_IC_AWIREG_H
|
||||
|
||||
/*
|
||||
* The firmware typically loaded onto Am79C930-based 802.11 interfaces
|
||||
* uses a 32k or larger shared memory buffer to communicate with the
|
||||
@ -92,70 +95,65 @@
|
||||
|
||||
#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_CA_MIB_TYPE (AWI_CMD_PARAMS + 0x0)
|
||||
#define AWI_CA_MIB_SIZE (AWI_CMD_PARAMS + 0x1)
|
||||
#define AWI_CA_MIB_INDEX (AWI_CMD_PARAMS + 0x2)
|
||||
#define AWI_CA_MIB_DATA (AWI_CMD_PARAMS + 0x4)
|
||||
#define AWI_MIB_LOCAL 0
|
||||
#define AWI_MIB_ADDR 2
|
||||
#define AWI_MIB_MAC 3
|
||||
#define AWI_MIB_STAT 4
|
||||
#define AWI_MIB_MGT 5
|
||||
#define AWI_MIB_DRVR 6
|
||||
#define AWI_MIB_PHY 7
|
||||
|
||||
#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_CA_TX_LEN 20
|
||||
#define AWI_CA_TX_DATA (AWI_CMD_PARAMS + 0x0)
|
||||
#define AWI_CA_TX_MGT (AWI_CMD_PARAMS + 0x4)
|
||||
#define AWI_CA_TX_BCAST (AWI_CMD_PARAMS + 0x8)
|
||||
#define AWI_CA_TX_PS (AWI_CMD_PARAMS + 0xc)
|
||||
#define AWI_CA_TX_CF (AWI_CMD_PARAMS + 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_CA_FTX_LEN 5
|
||||
#define AWI_CA_FTX_DATA (AWI_CMD_PARAMS + 0x0)
|
||||
#define AWI_CA_FTX_MGT (AWI_CMD_PARAMS + 0x1)
|
||||
#define AWI_CA_FTX_BCAST (AWI_CMD_PARAMS + 0x2)
|
||||
#define AWI_CA_FTX_PS (AWI_CMD_PARAMS + 0x3)
|
||||
#define AWI_CA_FTX_CF (AWI_CMD_PARAMS + 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_CA_IRX_DATA_DESC (AWI_CMD_PARAMS + 0x0) /* return */
|
||||
#define AWI_CA_IRX_PS_DESC (AWI_CMD_PARAMS + 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_CA_SLEEP_LEN 8
|
||||
#define AWI_CA_WAKEUP (AWI_CMD_PARAMS + 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_CA_SCAN_LEN 6
|
||||
#define AWI_CA_SCAN_DURATION (AWI_CMD_PARAMS + 0x0)
|
||||
#define AWI_CA_SCAN_SET (AWI_CMD_PARAMS + 0x2)
|
||||
#define AWI_CA_SCAN_PATTERN (AWI_CMD_PARAMS + 0x3)
|
||||
#define AWI_CA_SCAN_IDX (AWI_CMD_PARAMS + 0x4)
|
||||
#define AWI_CA_SCAN_SUSP (AWI_CMD_PARAMS + 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_CA_SYNC_LEN 20
|
||||
#define AWI_CA_SYNC_SET (AWI_CMD_PARAMS + 0x0)
|
||||
#define AWI_CA_SYNC_PATTERN (AWI_CMD_PARAMS + 0x1)
|
||||
#define AWI_CA_SYNC_IDX (AWI_CMD_PARAMS + 0x2)
|
||||
#define AWI_CA_SYNC_STARTBSS (AWI_CMD_PARAMS + 0x3)
|
||||
#define AWI_CA_SYNC_DWELL (AWI_CMD_PARAMS + 0x4)
|
||||
#define AWI_CA_SYNC_MBZ (AWI_CMD_PARAMS + 0x6)
|
||||
#define AWI_CA_SYNC_TIMESTAMP (AWI_CMD_PARAMS + 0x8)
|
||||
#define AWI_CA_SYNC_REFTIME (AWI_CMD_PARAMS + 0x10)
|
||||
|
||||
#define AWI_CMD_RESUME 0xc
|
||||
|
||||
@ -228,7 +226,7 @@
|
||||
#define AWI_INTMASK2 0x4fd
|
||||
|
||||
/* Bits in AWI_INTSTAT2/INTMASK2 */
|
||||
#define AWI_INT2_RXMGT 0x80 /* mgt/ps recieved */
|
||||
#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 */
|
||||
@ -261,7 +259,9 @@
|
||||
#define AWI_DRV_RXLED 0x40
|
||||
#define AWI_DRV_TXLED 0x80
|
||||
|
||||
#define AWI_VBM 0x500 /* Virtual Bit Map */
|
||||
#define AWI_VBM_OFFSET 0x500 /* Virtual Bit Map */
|
||||
#define AWI_VBM_LENGTH 0x501
|
||||
#define AWI_VBM_BITMAP 0x502
|
||||
|
||||
#define AWI_BUFFERS 0x600 /* Buffers */
|
||||
#define AWI_BUFFERS_END 0x6000
|
||||
@ -357,7 +357,7 @@ struct awi_mib_local {
|
||||
u_int8_t Rx_Buffer_Size[4];
|
||||
u_int8_t Acting_as_AP;
|
||||
u_int8_t Fill_CFP;
|
||||
};
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct awi_mib_mac {
|
||||
u_int8_t _Reserved1[2];
|
||||
@ -379,7 +379,7 @@ struct awi_mib_mac {
|
||||
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];
|
||||
};
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct awi_mib_stat {
|
||||
u_int8_t aTransmitted_MPDU_Count[4];
|
||||
@ -401,7 +401,7 @@ struct awi_mib_stat {
|
||||
u_int8_t aFCS_Error_Count[4];
|
||||
u_int8_t aError_Count[4];
|
||||
u_int8_t aWEP_Undecryptable_Count[4];
|
||||
};
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct awi_mib_mgt {
|
||||
u_int8_t aPower_Mgt_Mode;
|
||||
@ -413,6 +413,8 @@ struct awi_mib_mgt {
|
||||
u_int8_t aDTIM_Period;
|
||||
u_int8_t aATIM_Window[2];
|
||||
u_int8_t Wep_Required;
|
||||
#define AWI_WEP_ON 0x10
|
||||
#define AWI_WEP_OFF 0x00
|
||||
u_int8_t _Reserved1;
|
||||
u_int8_t aBeacon_Period[2];
|
||||
u_int8_t aPassive_Scan_Duration[2];
|
||||
@ -425,7 +427,7 @@ struct awi_mib_mgt {
|
||||
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];
|
||||
};
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define AWI_GROUP_ADDR_SIZE 4
|
||||
struct awi_mib_addr {
|
||||
@ -433,7 +435,7 @@ struct awi_mib_addr {
|
||||
u_int8_t aGroup_Addresses[AWI_GROUP_ADDR_SIZE][ETHER_ADDR_LEN];
|
||||
u_int8_t aTransmit_Enable_Status;
|
||||
u_int8_t _Reserved1;
|
||||
};
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define AWI_PWR_LEVEL_SIZE 4
|
||||
struct awi_mib_phy {
|
||||
@ -457,4 +459,6 @@ struct awi_mib_phy {
|
||||
#define AWI_PHY_TYPE_DS 2
|
||||
#define AWI_PHY_TYPE_IR 3
|
||||
u_int8_t RCR_33A_Bits[8];
|
||||
};
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#endif /* _DEV_IC_AWIREG_H */
|
||||
|
@ -1,8 +1,8 @@
|
||||
/* $NetBSD: awivar.h,v 1.12 2000/07/21 04:48:56 onoe Exp $ */
|
||||
/* $NetBSD: awivar.h,v 1.20 2004/01/15 09:39:15 onoe Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1999,2000,2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -37,6 +37,9 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _DEV_IC_AWIVAR_H
|
||||
#define _DEV_IC_AWIVAR_H
|
||||
|
||||
/* timer values in msec */
|
||||
#define AWI_SELFTEST_TIMEOUT 5000
|
||||
#define AWI_CMD_TIMEOUT 2000
|
||||
@ -45,96 +48,67 @@
|
||||
#define AWI_ASCAN_WAIT 3000
|
||||
#define AWI_PSCAN_DURATION 200
|
||||
#define AWI_PSCAN_WAIT 5000
|
||||
#define AWI_TRANS_TIMEOUT 2000
|
||||
#define AWI_TRANS_TIMEOUT 5000
|
||||
|
||||
#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
|
||||
enum awi_sub_state {
|
||||
AWI_ST_NONE,
|
||||
AWI_ST_SCAN_INIT,
|
||||
AWI_ST_SCAN_SETMIB,
|
||||
AWI_ST_SCAN_SCCMD,
|
||||
AWI_ST_SUB_INIT,
|
||||
AWI_ST_SUB_SETSS,
|
||||
AWI_ST_SUB_SYNC
|
||||
};
|
||||
|
||||
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];
|
||||
#define AWI_WAIT 0 /* must wait for completion */
|
||||
#define AWI_NOWAIT 1 /* do not wait */
|
||||
|
||||
struct awi_chanset {
|
||||
u_int8_t cs_type;
|
||||
u_int8_t cs_region;
|
||||
u_int8_t cs_min;
|
||||
u_int8_t cs_max;
|
||||
u_int8_t cs_def;
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
struct awi_softc {
|
||||
#ifdef __NetBSD__
|
||||
struct device sc_dev;
|
||||
struct ethercom sc_ec;
|
||||
void *sc_ih; /* interrupt handler */
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
#if __FreeBSD_version >= 40000
|
||||
struct {
|
||||
char dv_xname[64]; /*XXX*/
|
||||
} sc_dev;
|
||||
#else
|
||||
struct device sc_dev;
|
||||
#endif
|
||||
struct arpcom sc_ec;
|
||||
#ifdef __FreeBSD__
|
||||
device_t sc_dev;
|
||||
#endif
|
||||
struct am79c930_softc sc_chip;
|
||||
struct ifnet *sc_ifp;
|
||||
struct ieee80211com sc_ic;
|
||||
u_char sc_banner[AWI_BANNER_LEN];
|
||||
int (*sc_enable)(struct awi_softc *);
|
||||
void (*sc_disable)(struct awi_softc *);
|
||||
void (*sc_power)(struct awi_softc *, int);
|
||||
|
||||
struct ifmedia sc_media;
|
||||
enum awi_status sc_status;
|
||||
unsigned int sc_enabled:1,
|
||||
int (*sc_newstate)(struct ieee80211com *,
|
||||
enum ieee80211_state, int);
|
||||
void (*sc_recv_mgmt)(struct ieee80211com *,
|
||||
struct mbuf *, struct ieee80211_node *,
|
||||
int, int, u_int32_t);
|
||||
int (*sc_send_mgmt)(struct ieee80211com *,
|
||||
struct ieee80211_node *, int, int);
|
||||
|
||||
void *sc_sdhook; /* shutdown hook */
|
||||
void *sc_powerhook; /* power management hook */
|
||||
unsigned int sc_attached:1,
|
||||
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;
|
||||
sc_adhoc_ap:1,
|
||||
sc_invalid:1;
|
||||
enum ieee80211_state sc_nstate;
|
||||
enum awi_sub_state sc_substate;
|
||||
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;
|
||||
u_int8_t sc_cmd_inprog;
|
||||
u_int8_t sc_cur_chan;
|
||||
|
||||
int sc_rx_timer;
|
||||
u_int32_t sc_rxdoff;
|
||||
@ -142,20 +116,11 @@ struct awi_softc
|
||||
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;
|
||||
@ -167,7 +132,8 @@ struct awi_softc
|
||||
#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_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)
|
||||
@ -182,59 +148,13 @@ struct awi_softc
|
||||
awi_write_1(sc, AWI_DRIVERSTATE, \
|
||||
((state) | AWI_DRV_AUTORXLED|AWI_DRV_AUTOTXLED))
|
||||
|
||||
/* unalligned 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 *);
|
||||
int awi_detach(struct awi_softc *);
|
||||
#ifdef __NetBSD__
|
||||
int awi_activate(struct device *, enum devact);
|
||||
int awi_detach(struct awi_softc *);
|
||||
void awi_power(struct awi_softc *, int);
|
||||
void awi_power(int, void *);
|
||||
#endif
|
||||
void awi_shutdown(void *);
|
||||
int awi_intr(void *);
|
||||
|
||||
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);
|
||||
|
||||
#ifndef SIOCS80211NWKEY
|
||||
/*
|
||||
* This structure is part of the NetBSD public ioctl interface but
|
||||
* used internally by the driver. Declare it here for non-NetBSD
|
||||
* systems.
|
||||
*/
|
||||
/* the first member must be matched with struct ifreq */
|
||||
struct ieee80211_nwkey {
|
||||
char i_name[IFNAMSIZ]; /* if_name, e.g. "wi0" */
|
||||
int i_wepon; /* wep enabled flag */
|
||||
int i_defkid; /* default encrypt key id */
|
||||
struct {
|
||||
int i_keylen;
|
||||
u_int8_t *i_keydat;
|
||||
} i_key[IEEE80211_WEP_NKID];
|
||||
};
|
||||
#endif
|
||||
|
||||
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);
|
||||
#endif /* _DEV_IC_AWIVAR_H */
|
||||
|
@ -43,7 +43,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <net/if_media.h>
|
||||
#include <net/ethernet.h>
|
||||
|
||||
#include <net80211/ieee80211.h>
|
||||
#include <net80211/ieee80211_var.h>
|
||||
|
||||
#include <dev/awi/am79c930reg.h>
|
||||
#include <dev/awi/am79c930var.h>
|
||||
@ -80,6 +80,14 @@ static const struct pccard_product awi_pccard_products[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static int awi_pccard_match(device_t);
|
||||
static int awi_pccard_probe(device_t);
|
||||
static int awi_pccard_attach(device_t);
|
||||
static int awi_pccard_detach(device_t);
|
||||
static void awi_pccard_shutdown(device_t);
|
||||
static int awi_pccard_enable(struct awi_softc *);
|
||||
static void awi_pccard_disable(struct awi_softc *);
|
||||
|
||||
static int
|
||||
awi_pccard_match(device_t dev)
|
||||
{
|
||||
@ -106,14 +114,15 @@ awi_pccard_probe(device_t dev)
|
||||
|
||||
psc->sc_port_rid = 0;
|
||||
psc->sc_port_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
|
||||
&psc->sc_port_rid, 0, ~0, 16, RF_ACTIVE);
|
||||
&psc->sc_port_rid, 0, ~0, AM79C930_IO_SIZE,
|
||||
rman_make_alignment_flags(AM79C930_IO_ALIGN) | RF_ACTIVE);
|
||||
if (!psc->sc_port_res)
|
||||
return ENOMEM;
|
||||
|
||||
sc->sc_chip.sc_iot = rman_get_bustag(psc->sc_port_res);
|
||||
sc->sc_chip.sc_ioh = rman_get_bushandle(psc->sc_port_res);
|
||||
am79c930_chip_init(&sc->sc_chip, 0);
|
||||
DELAY(1000);
|
||||
tsleep(sc, PWAIT, "awiprb", 1);
|
||||
|
||||
awi_read_bytes(sc, AWI_BANNER, psc->sc_version, AWI_BANNER_LEN);
|
||||
if (memcmp(psc->sc_version, "PCnetMobile:", 12) != 0) {
|
||||
@ -124,6 +133,7 @@ awi_pccard_probe(device_t dev)
|
||||
device_set_desc(dev, psc->sc_version);
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, psc->sc_port_rid,
|
||||
psc->sc_port_res);
|
||||
psc->sc_port_res = 0;
|
||||
|
||||
return error;
|
||||
}
|
||||
@ -133,7 +143,6 @@ awi_pccard_attach(device_t dev)
|
||||
{
|
||||
struct awi_pccard_softc *psc = device_get_softc(dev);
|
||||
struct awi_softc *sc = &psc->sc_awi;
|
||||
struct ifnet *ifp = &sc->sc_ec.ac_if;
|
||||
int error = 0;
|
||||
|
||||
psc->sc_port_res = 0;
|
||||
@ -141,13 +150,10 @@ awi_pccard_attach(device_t dev)
|
||||
psc->sc_mem_res = 0;
|
||||
psc->sc_intrhand = 0;
|
||||
|
||||
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
|
||||
strlcpy(sc->sc_dev.dv_xname, ifp->if_xname,
|
||||
sizeof(sc->sc_dev.dv_xname));
|
||||
|
||||
psc->sc_port_rid = 0;
|
||||
psc->sc_port_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
|
||||
&psc->sc_port_rid, 0, ~0, 16, RF_ACTIVE);
|
||||
&psc->sc_port_rid, 0, ~0, 16,
|
||||
rman_make_alignment_flags(64) | RF_ACTIVE);
|
||||
if (!psc->sc_port_res) {
|
||||
device_printf(dev, "awi_pccard_attach: port alloc failed\n");
|
||||
goto fail;
|
||||
@ -169,6 +175,7 @@ awi_pccard_attach(device_t dev)
|
||||
* XXX: awi needs to access memory with 8bit,
|
||||
* but pccardd apparently maps memory with MDF_16BITS flag.
|
||||
* So memory mapped access is disabled and use IO port instead.
|
||||
* Also, memory mapping is not yet supported on pccard.
|
||||
*/
|
||||
psc->sc_mem_res = 0;
|
||||
#else
|
||||
@ -182,43 +189,23 @@ awi_pccard_attach(device_t dev)
|
||||
} else
|
||||
am79c930_chip_init(&sc->sc_chip, 0);
|
||||
|
||||
error = bus_setup_intr(dev, psc->sc_irq_res, INTR_TYPE_NET,
|
||||
(void (*)(void *))awi_intr, sc, &psc->sc_intrhand);
|
||||
if (error) {
|
||||
device_printf(dev, "awi_pccard_attach: intr setup failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sc->sc_dev = dev;
|
||||
sc->sc_cansleep = 1;
|
||||
sc->sc_enabled = 1;
|
||||
sc->sc_ifp = &sc->sc_ec.ac_if;
|
||||
sc->sc_enable = awi_pccard_enable;
|
||||
sc->sc_disable = awi_pccard_disable;
|
||||
|
||||
if (awi_pccard_enable(sc))
|
||||
goto fail;
|
||||
sc->sc_enabled = 1;
|
||||
error = awi_attach(sc);
|
||||
sc->sc_enabled = 0; /*XXX*/
|
||||
awi_pccard_disable(sc);
|
||||
if (error == 0)
|
||||
return 0;
|
||||
device_printf(dev, "awi_pccard_attach: awi_attach failed\n");
|
||||
|
||||
fail:
|
||||
if (psc->sc_intrhand) {
|
||||
bus_teardown_intr(dev, psc->sc_irq_res, psc->sc_intrhand);
|
||||
psc->sc_intrhand = 0;
|
||||
}
|
||||
if (psc->sc_port_res) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, psc->sc_port_rid,
|
||||
psc->sc_port_res);
|
||||
psc->sc_port_res = 0;
|
||||
}
|
||||
if (psc->sc_irq_res) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, psc->sc_irq_rid,
|
||||
psc->sc_irq_res);
|
||||
psc->sc_irq_res = 0;
|
||||
}
|
||||
if (psc->sc_mem_res) {
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, psc->sc_mem_rid,
|
||||
psc->sc_mem_res);
|
||||
psc->sc_mem_res = 0;
|
||||
}
|
||||
awi_pccard_detach(dev);
|
||||
if (error == 0)
|
||||
error = ENXIO;
|
||||
return error;
|
||||
@ -229,37 +216,72 @@ awi_pccard_detach(device_t dev)
|
||||
{
|
||||
struct awi_pccard_softc *psc = device_get_softc(dev);
|
||||
struct awi_softc *sc = &psc->sc_awi;
|
||||
struct ifnet *ifp = &sc->sc_ec.ac_if;
|
||||
|
||||
ether_ifdetach(ifp);
|
||||
ifp->if_flags &= ~IFF_RUNNING;
|
||||
if (psc->sc_intrhand) {
|
||||
bus_teardown_intr(dev, psc->sc_irq_res, psc->sc_intrhand);
|
||||
psc->sc_intrhand = 0;
|
||||
}
|
||||
if (psc->sc_port_res) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, psc->sc_port_rid,
|
||||
psc->sc_port_res);
|
||||
psc->sc_port_res = 0;
|
||||
awi_detach(sc);
|
||||
if (psc->sc_mem_res) {
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, psc->sc_mem_rid,
|
||||
psc->sc_mem_res);
|
||||
psc->sc_mem_res = 0;
|
||||
}
|
||||
if (psc->sc_irq_res) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, psc->sc_irq_rid,
|
||||
psc->sc_irq_res);
|
||||
psc->sc_irq_res = 0;
|
||||
}
|
||||
if (psc->sc_mem_res) {
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, psc->sc_mem_rid,
|
||||
psc->sc_mem_res);
|
||||
psc->sc_mem_res = 0;
|
||||
if (psc->sc_port_res) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, psc->sc_port_rid,
|
||||
psc->sc_port_res);
|
||||
psc->sc_port_res = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
awi_pccard_shutdown(device_t dev)
|
||||
{
|
||||
struct awi_pccard_softc *psc = device_get_softc(dev);
|
||||
struct awi_softc *sc = &psc->sc_awi;
|
||||
|
||||
awi_shutdown(sc);
|
||||
}
|
||||
|
||||
static int
|
||||
awi_pccard_enable(struct awi_softc *sc)
|
||||
{
|
||||
device_t dev = sc->sc_dev;
|
||||
struct awi_pccard_softc *psc = device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
if (psc->sc_intrhand == 0) {
|
||||
error = bus_setup_intr(dev, psc->sc_irq_res, INTR_TYPE_NET,
|
||||
(void (*)(void *))awi_intr, sc, &psc->sc_intrhand);
|
||||
if (error) {
|
||||
device_printf(dev,
|
||||
"couldn't establish interrupt error=%d\n", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
awi_pccard_disable(struct awi_softc *sc)
|
||||
{
|
||||
device_t dev = sc->sc_dev;
|
||||
struct awi_pccard_softc *psc = device_get_softc(dev);
|
||||
|
||||
if (psc->sc_intrhand) {
|
||||
bus_teardown_intr(dev, psc->sc_irq_res, psc->sc_intrhand);
|
||||
psc->sc_intrhand = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static device_method_t awi_pccard_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, pccard_compat_probe),
|
||||
DEVMETHOD(device_attach, pccard_compat_attach),
|
||||
DEVMETHOD(device_detach, awi_pccard_detach),
|
||||
DEVMETHOD(device_shutdown, awi_pccard_shutdown),
|
||||
|
||||
/* Card interface */
|
||||
DEVMETHOD(card_compat_match, awi_pccard_match),
|
||||
@ -278,4 +300,5 @@ static driver_t awi_pccard_driver = {
|
||||
extern devclass_t awi_devclass;
|
||||
|
||||
DRIVER_MODULE(awi, pccard, awi_pccard_driver, awi_devclass, 0, 0);
|
||||
MODULE_DEPEND(awi, rc4, 1, 1, 1);
|
||||
MODULE_DEPEND(awi, wlan, 1, 1, 1);
|
||||
MODULE_DEPEND(awi, pccard, 1, 1, 1);
|
||||
|
@ -3,7 +3,7 @@
|
||||
.PATH: ${.CURDIR}/../../dev/awi
|
||||
|
||||
KMOD= if_awi
|
||||
SRCS= am79c930.c awi.c awi_wep.c awi_wicfg.c if_awi_pccard.c
|
||||
SRCS= am79c930.c awi.c if_awi_pccard.c
|
||||
SRCS+= bus_if.h card_if.h device_if.h opt_inet.h
|
||||
|
||||
opt_inet.h:
|
||||
|
Loading…
Reference in New Issue
Block a user