aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ObsoleteFiles.inc4
-rw-r--r--release/doc/en_US.ISO8859-1/hardware/article.xml3
-rw-r--r--share/man/man4/man4.i386/Makefile3
-rw-r--r--share/man/man4/man4.i386/wl.4193
-rw-r--r--sys/conf/files1
-rw-r--r--sys/conf/options2
-rw-r--r--sys/dev/wl/if_wl.c2620
-rw-r--r--sys/dev/wl/if_wl.h133
-rw-r--r--sys/dev/wl/if_wl_i82586.h266
-rw-r--r--sys/i386/conf/NOTES5
-rw-r--r--sys/modules/Makefile2
-rw-r--r--sys/modules/wl/Makefile10
-rw-r--r--targets/pseudo/userland/Makefile.depend3
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc6
-rw-r--r--tools/kerneldoc/subsys/Doxyfile-dev_wl21
-rw-r--r--usr.sbin/Makefile.i3863
-rw-r--r--usr.sbin/wlconfig/Makefile9
-rw-r--r--usr.sbin/wlconfig/Makefile.depend16
-rw-r--r--usr.sbin/wlconfig/wlconfig.8143
-rw-r--r--usr.sbin/wlconfig/wlconfig.c417
20 files changed, 6 insertions, 3854 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 1b0710ac5203..e13a87c30fea 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -38,6 +38,10 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20160819: Remove wl(4) and wlconfig(8)
+OLD_FILES+=usr/share/man/man4/i386/wl.4.gz
+OLD_FILES+=usr/sbin/wlconfig
+OLD_FILES+=usr/share/man/man8/i386/wlconfig.8.gz
# 20160819: Remove si(4) and sicontrol(8)
OLD_FILES+=usr/share/man/man4/si.4.gz
OLD_FILES+=usr/sbin/sicontrol
diff --git a/release/doc/en_US.ISO8859-1/hardware/article.xml b/release/doc/en_US.ISO8859-1/hardware/article.xml
index bffb5820e8cc..795709e0547c 100644
--- a/release/doc/en_US.ISO8859-1/hardware/article.xml
+++ b/release/doc/en_US.ISO8859-1/hardware/article.xml
@@ -1023,9 +1023,6 @@
Intersil PRISM-2.5, Intersil Prism-3, and Symbol Spectrum24
chipsets (&man.wi.4; driver)</para>
- <para>[&arch.i386;] NCR / AT&amp;T / Lucent Technologies WaveLan
- T1-speed ISA/radio LAN cards (&man.wl.4; driver)</para>
-
<para>[&arch.i386;, &arch.amd64;] Intel PRO/Wireless 3945ABG
MiniPCI network adapters (&man.wpi.4; driver)</para>
diff --git a/share/man/man4/man4.i386/Makefile b/share/man/man4/man4.i386/Makefile
index 7b25eca28c62..21cff03c68db 100644
--- a/share/man/man4/man4.i386/Makefile
+++ b/share/man/man4/man4.i386/Makefile
@@ -31,8 +31,7 @@ MAN= aic.4 \
streams.4 \
svr4.4 \
vpd.4 \
- vx.4 \
- wl.4
+ vx.4
MLINKS= CPU_ELAN.4 CPU_SOEKRIS.4
MLINKS+=pae.4 PAE.4
diff --git a/share/man/man4/man4.i386/wl.4 b/share/man/man4/man4.i386/wl.4
deleted file mode 100644
index e697d2318a26..000000000000
--- a/share/man/man4/man4.i386/wl.4
+++ /dev/null
@@ -1,193 +0,0 @@
-.\"
-.\" Copyright (c) 1997, Jim Binkley
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by Jim Binkley
-.\" 4. The name of the author may not be used to endorse or promote products
-.\" derived from this software without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.Dd September 29, 2006
-.Dt WL 4 i386
-.Os
-.Sh NAME
-.Nm wl
-.Nd T1 speed ISA/radio lan card
-.Sh SYNOPSIS
-.Cd "device wl0 at isa? port 0x300 irq 5"
-.Sh DESCRIPTION
-The
-.Nm
-driver controls a radio lan card system made originally by
-NCR, then ATT, now Lucent.
-The system is spread-spectrum radio
-at around 915 MHz (or 2.4 GHz).
-With the supplied omni-directional antennae,
-about 400 feet (indoors, more outdoors) can be covered in circumference.
-This card can talk to the companion (wlp0) pccard.
-Speeds vary
-from 1 megabit to theoretically 2 megabits (roughly T1 in speed).
-.Pp
-The card has three fundamental hardware
-units, a so-called PSA or programmable storage area, a radio modem,
-and a Ethernet lan controller.
-The latter component is the
-ancient (and not very honorable) Intel 82586 Ethernet chip.
-Fundamentally it appears to the operating system as an Ethernet system,
-and speaks IEEE MAC addresses.
-The radio modem simply translates
-Ethernet packets to/from radio packets, that are either at 2.4 GHz
-or 915 MHz depending on the radio modem.
-It supports a collision
-avoidance scheme.
-The lan controller
-supports promiscuous mode, broadcast, and multicasting
-(although there is a glitch
-in the latter).
-"It thinks it is Ethernet".
-.Pp
-How it is used
-depends on the kind of antennae deployed with it.
-Point to point
-applications are possible as are Ethernet-like lan use.
-The vendor
-ships an omni-directional antennae that works in the
-vicinity of 400 feet (indoors).
-Point to point antennae can be purchased that will go miles.
-.Sh SETUP
-The card can either be initialized with the vendor supplied DOS setup software.
-Typically minimally an IRQ, port, and Network ID must be supplied.
-Michael Smith's
-.Xr wlconfig 8
-utility can now be used to do this work from
-the UNIX side.
-The card is "not" plug and play.
-The network id controls whether one set of cards can hear another.
-If different, cards will read physical packets, but they will be discarded
-by the radio modem.
-.Sh CONTROL
-In addition to the config utility, there are several sysctl
-switches that can be used to modify runtime parameters.
-The
-.Xr sysctl 8
-variables are as follows:
-.Bl -diag
-.It "machdep.wl_xmit_delay <useconds>"
-This variable will cause the driver to insert a delay on transmit.
-250 is the default.
-The delay should probably be a bit longer
-on faster cpus and less on slower cpus.
-It exists because the 82586
-was not designed to work with Pentium-speed cpu systems and if overdriven
-will have copious xmit side errors.
-.It machdep.wl_ignore_nwid <0 | 1>
-This switch defaults to 0; i.e., the nwid is not ignored.
-It can
-be set to 1 to cause the nwid to not be used.
-This may be useful
-when the device is in promiscuous mode as one can watch for all
-packets and ignore nwid differences.
-.It machdep.wl_xmit_watch <milliseconds>
-This switch is not currently useful.
-.It machdep.wl_gather_snr <milliseconds>
-This switch is not currently useful.
-.Pp
-There is also a signal strength cache in the driver.
-It may be interrogated
-with
-.Xr wlconfig 8 .
-Incoming packets
-are checked for certain hardware radio-modem values including signal
-strength, silence, and quality, which range fro 0..63, 0..63, and 0..15
-respectively.
-Thus one can read out signal strenth values to see
-how close/far peer nodes are.
-The signal strength cache is indexed by
-sender MAC address.
-There are two sysctls that change how it filters packets.
-Both are on
-by default.
-.It machdep.wl_wlcache_mcastonly <0 | 1>
-By default this switch is on.
-It forces the cache to filter out
-unicast packets.
-Only broadcast or multicast packets are accepted.
-.It machdep.wl_wlcache_iponly <0 | 1>
-By default this switch is on.
-It forces the driver to discard non-IP
-packets and also stores the IP src address.
-ARP packets are ignored,
-as are any other network protocol barring IPv4 packets.
-.El
-.Sh SEE ALSO
-.Xr sysctl 8 ,
-.Xr wlconfig 8
-.Pp
-.Pa http://www.wavelan.com
-.Sh HISTORY
-The
-.Nm
-driver was written by
-.An Anders Klemets
-(thousands of years ago?) and
-appears to be based on an even older Intel 82586 driver.
-The 82586
-controller was one of the first (if not the first?) integrated lan
-controller on the block.
-That does not mean it was the best either.
-Anders ported and or created a driver for the ISA wavelan and PCCARD
-wavelan system too (wlp).
-.An Robert T. Morris, Jr.
-ported the Mach drivers to BSDI.
-.An Jim Binkley
-ported them to
-.Fx 2.1 .
-.An Michael Smith
-ported the
-.Nm
-driver only to 2.2.2.
-Jim and Michael have been
-maintaining them.
-The current state of the driver is NOT ANYONE'S
-FAULT.
-Thanks to
-.An Bernie Doehner
-and
-.An Robert Buaas
-for contributions.
-.Sh AUTHORS
-Too numerous to mention.
-See above.
-.Sh CAVEATS
-The 82586 has numerous defects.
-It may experience transmit-side
-errors when modern faster cpus send packets at it faster than it can handle.
-The driver (and probably the chip) does not support an all multicast mode.
-As a result, it can be used with applications like
-.Xr mrouted 8 Pq Pa ports/net/mrouted ,
-but it must go into promiscuous mode for that to work.
-The driver
-is slow to change modes from "normal" to promiscuous mode, presumably
-due to delays in the configuration code.
diff --git a/sys/conf/files b/sys/conf/files
index 8b2c5032fe4b..1ce19df4ed3d 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2933,7 +2933,6 @@ dev/wb/if_wb.c optional wb pci
dev/wi/if_wi.c optional wi
dev/wi/if_wi_pccard.c optional wi pccard
dev/wi/if_wi_pci.c optional wi pci
-dev/wl/if_wl.c optional wl isa
dev/wpi/if_wpi.c optional wpi pci
wpifw.c optional wpifw \
compile-with "${AWK} -f $S/tools/fw_stub.awk wpi.fw:wpifw:153229 -mwpi -c${.TARGET}" \
diff --git a/sys/conf/options b/sys/conf/options
index f115e7e14212..aa6318bc5943 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -218,8 +218,6 @@ SW_WATCHDOG opt_watchdog.h
TURNSTILE_PROFILING
UMTX_PROFILING
VERBOSE_SYSINIT
-WLCACHE opt_wavelan.h
-WLDEBUG opt_wavelan.h
# POSIX kernel options
P1003_1B_MQUEUE opt_posix.h
diff --git a/sys/dev/wl/if_wl.c b/sys/dev/wl/if_wl.c
deleted file mode 100644
index 08d0fc87c771..000000000000
--- a/sys/dev/wl/if_wl.c
+++ /dev/null
@@ -1,2620 +0,0 @@
-/*-
- * 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 all copyright
- * notices, this list of conditions and the following disclaimer.
- * 2. The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
- *
- */
-/*
- * if_wl.c - original MACH, then BSDI ISA wavelan driver
- * ported to mach by Anders Klemets
- * to BSDI by Robert Morris
- * to FreeBSD by Jim Binkley
- * to FreeBSD 2.2+ by Michael Smith
- *
- * 2.2 update:
- * Changed interface to match 2.1-2.2 differences.
- * Implement IRQ selection logic in wlprobe()
- * Implement PSA updating.
- * Pruned heading comments for relevance.
- * Ripped out all the 'interface counters' cruft.
- * Cut the missing-interrupt timer back to 100ms.
- * 2.2.1 update:
- * now supports all multicast mode (mrouted will work),
- * but unfortunately must do that by going into promiscuous mode
- * NWID sysctl added so that normally promiscuous mode is NWID-specific
- * but can be made NWID-inspecific
- * 7/14/97 jrb
- *
- * Work done:
- * Ported to FreeBSD, got promiscuous mode working with bpfs,
- * and rewired timer routine. The i82586 will hang occasionally on output
- * and the watchdog timer will kick it if so and log an entry.
- * 2 second timeout there. Apparently the chip loses an interrupt.
- * Code borrowed from if_ie.c for watchdog timer.
- *
- * The wavelan card is a 2mbit radio modem that emulates ethernet;
- * i.e., it uses MAC addresses. This should not be a surprise since
- * it uses an ethernet controller as a major hw item.
- * It can broadcast, unicast or apparently multicast in a base cell
- * using an omni-directional antennae that is
- * about 800 feet around the base cell barring walls and metal.
- * With directional antennae, it can be used point to point over a mile
- * or so apparently (haven't tried that).
- *
- * There are ISA and pcmcia versions (not supported by this code).
- * The ISA card has an Intel 82586 lan controller on it. It consists
- * of 2 pieces of hw, the lan controller (intel) and a radio-modem.
- * The latter has an extra set of controller registers that has nothing
- * to do with the i82586 and allows setting and monitoring of radio
- * signal strength, etc. There is a nvram area called the PSA that
- * contains a number of setup variables including the IRQ and so-called
- * NWID or Network ID. The NWID must be set the same for all radio
- * cards to communicate (unless you are using the ATT/NCR roaming feature
- * with their access points. There is no support for that here. Roaming
- * involves a link-layer beacon sent out from the access points. End
- * stations monitor the signal strength and only use the strongest
- * access point). This driver assumes that the base ISA port, IRQ,
- * and NWID are first set in nvram via the dos-side "instconf.exe" utility
- * supplied with the card. This driver takes the ISA port from
- * the kernel configuration setup, and then determines the IRQ either
- * from the kernel config (if an explicit IRQ is set) or from the
- * PSA on the card if not.
- * The hw also magically just uses the IRQ set in the nvram.
- * The NWID is used magically as well by the radio-modem
- * to determine which packets to keep or throw out.
- *
- * sample config:
- *
- * device wl0 at isa? port 0x300 net irq ?
- *
- * Ifdefs:
- * 1. WLDEBUG. (off) - if turned on enables IFF_DEBUG set via ifconfig debug
- * 2. MULTICAST (on) - turned on and works up to and including mrouted
- * 3. WLCACHE (off) - define to turn on a signal strength
- * (and other metric) cache that is indexed by sender MAC address.
- * Apps can read this out to learn the remote signal strength of a
- * sender. Note that it has a switch so that it only stores
- * broadcast/multicast senders but it could be set to store unicast
- * too only. Size is hardwired in if_wl_wavelan.h
- *
- * one further note: promiscuous mode is a curious thing. In this driver,
- * promiscuous mode apparently CAN catch ALL packets and ignore the NWID
- * setting. This is probably more useful in a sense (for snoopers) if
- * you are interested in all traffic as opposed to if you are interested
- * in just your own. There is a driver specific sysctl to turn promiscuous
- * from just promiscuous to wildly promiscuous...
- *
- * This driver also knows how to load the synthesizers in the 2.4 Gz
- * ISA Half-card, Product number 847647476 (USA/FCC IEEE Channel set).
- * This product consists of a "mothercard" that contains the 82586,
- * NVRAM that holds the PSA, and the ISA-buss interface custom ASIC.
- * The radio transceiver is a "daughtercard" called the WaveMODEM which
- * connects to the mothercard through two single-inline connectors: a
- * 20-pin connector provides DC-power and modem signals, and a 3-pin
- * connector which exports the antenna connection. The code herein
- * loads the receive and transmit synthesizers and the corresponding
- * transmitter output power value from an EEPROM controlled through
- * additional registers via the MMC. The EEPROM address selected
- * are those whose values are preset by the DOS utility programs
- * provided with the product, and this provides compatible operation
- * with the DOS Packet Driver software. A future modification will
- * add the necessary functionality to this driver and to the wlconfig
- * utility to completely replace the DOS Configuration Utilities.
- * The 2.4 Gz WaveMODEM is described in document number 407-024692/E,
- * and is available through Lucent Technologies OEM supply channels.
- * --RAB 1997/06/08.
- */
-
-#define MULTICAST 1
-
-/*
- * Olivetti PC586 Mach Ethernet driver v1.0
- * Copyright Ing. C. Olivetti & C. S.p.A. 1988, 1989
- * All rights reserved.
- *
- */
-/*
- Copyright 1988, 1989 by Olivetti Advanced Technology Center, Inc.,
-Cupertino, California.
-
- All Rights Reserved
-
- Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appears in all
-copies and that both the copyright notice and this permission notice
-appear in supporting documentation, and that the name of Olivetti
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-
- OLIVETTI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL OLIVETTI BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
-NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION
-WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-/*
- Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appears in all
-copies and that both the copyright notice and this permission notice
-appear in supporting documentation, and that the name of Intel
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-
-INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
-NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * NOTE:
- * by rvb:
- * 1. The best book on the 82586 is:
- * LAN Components User's Manual by Intel
- * The copy I found was dated 1984. This really tells you
- * what the state machines are doing
- * 2. In the current design, we only do one write at a time,
- * though the hardware is capable of chaining and possibly
- * even batching. The problem is that we only make one
- * transmit buffer available in sram space.
- */
-
-#include "opt_wavelan.h"
-#include "opt_inet.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/priv.h>
-#include <sys/socket.h>
-#include <sys/syslog.h>
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/bus.h>
-#include <sys/rman.h>
-
-#include <sys/sysctl.h>
-
-#include <net/ethernet.h>
-#include <net/if.h>
-#include <net/if_var.h>
-#include <net/if_arp.h>
-#include <net/if_dl.h>
-#include <net/if_types.h>
-
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
-#endif
-
-#include <net/bpf.h>
-#include <isa/isavar.h>
-
-/* was 1000 in original, fed to DELAY(x) */
-#define DELAYCONST 1000
-#include <dev/wl/if_wl_i82586.h> /* Definitions for the Intel chip */
-#include <dev/wl/if_wl.h>
-#include <machine/if_wl_wavelan.h>
-
-static char t_packet[ETHERMTU + sizeof(struct ether_header) + sizeof(long)];
-
-struct wl_softc {
- device_t dev;
- struct ifnet *ifp;
- u_char psa[0x40];
- u_char nwid[2]; /* current radio modem nwid */
- int flags;
- int tbusy; /* flag to determine if xmit is busy */
- u_short begin_fd;
- u_short end_fd;
- u_short end_rbd;
- u_short hacr; /* latest host adapter CR command */
- short mode;
- u_char chan24; /* 2.4 Gz: channel number/EEPROM Area # */
- u_short freq24; /* 2.4 Gz: resulting frequency */
- int rid_ioport;
- int rid_irq;
- struct resource *res_ioport;
- struct resource *res_irq;
- void *intr_cookie;
- struct mtx wl_mtx;
- struct callout watchdog_timer;
-#ifdef WLCACHE
- int w_sigitems; /* number of cached entries */
- /* array of cache entries */
- struct w_sigcache w_sigcache[ MAXCACHEITEMS ];
- int w_nextcache; /* next free cache entry */
- int w_wrapindex; /* next "free" cache entry */
-#endif
-};
-
-#define WL_LOCK(_sc) mtx_lock(&(_sc)->wl_mtx)
-#define WL_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->wl_mtx, MA_OWNED)
-#define WL_UNLOCK(_sc) mtx_unlock(&(_sc)->wl_mtx)
-
-static int wlprobe(device_t);
-static int wlattach(device_t);
-static int wldetach(device_t);
-
-static device_method_t wl_methods[] = {
- DEVMETHOD(device_probe, wlprobe),
- DEVMETHOD(device_attach, wlattach),
- DEVMETHOD(device_detach, wldetach),
- { 0, 0}
-};
-
-static driver_t wl_driver = {
- "wl",
- wl_methods,
- sizeof (struct wl_softc)
-};
-
-devclass_t wl_devclass;
-DRIVER_MODULE(wl, isa, wl_driver, wl_devclass, 0, 0);
-MODULE_DEPEND(wl, isa, 1, 1, 1);
-MODULE_DEPEND(wl, ether, 1, 1, 1);
-
-static struct isa_pnp_id wl_ids[] = {
- {0, NULL}
-};
-
-/*
- * XXX The Wavelan appears to be prone to dropping stuff if you talk to
- * it too fast. This disgusting hack inserts a delay after each packet
- * is queued which helps avoid this behaviour on fast systems.
- */
-static int wl_xmit_delay = 250;
-SYSCTL_INT(_machdep, OID_AUTO, wl_xmit_delay, CTLFLAG_RW, &wl_xmit_delay, 0, "");
-
-/*
- * not XXX, but ZZZ (bizarre).
- * promiscuous mode can be toggled to ignore NWIDs. By default,
- * it does not. Caution should be exercised about combining
- * this mode with IFF_ALLMULTI which puts this driver in
- * promiscuous mode.
- */
-static int wl_ignore_nwid = 0;
-SYSCTL_INT(_machdep, OID_AUTO, wl_ignore_nwid, CTLFLAG_RW, &wl_ignore_nwid, 0, "");
-
-/*
- * Emit diagnostics about transmission problems
- */
-static int xmt_watch = 0;
-SYSCTL_INT(_machdep, OID_AUTO, wl_xmit_watch, CTLFLAG_RW, &xmt_watch, 0, "");
-
-/*
- * Collect SNR statistics
- */
-static int gathersnr = 0;
-SYSCTL_INT(_machdep, OID_AUTO, wl_gather_snr, CTLFLAG_RW, &gathersnr, 0, "");
-
-static int wl_allocate_resources(device_t device);
-static int wl_deallocate_resources(device_t device);
-static void wlstart(struct ifnet *ifp);
-static void wlstart_locked(struct ifnet *ifp);
-static void wlinit(void *xsc);
-static void wlinit_locked(struct wl_softc *sc);
-static int wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
-static void wlwatchdog(void *arg);
-static void wlintr(void *arg);
-static void wlxmt(struct wl_softc *sc, struct mbuf *m);
-static int wldiag(struct wl_softc *sc);
-static int wlconfig(struct wl_softc *sc);
-static int wlcmd(struct wl_softc *sc, char *str);
-static void wlmmcstat(struct wl_softc *sc);
-static u_short wlbldru(struct wl_softc *sc);
-static u_short wlmmcread(struct wl_softc *sc, u_short reg);
-static void wlinitmmc(struct wl_softc *sc);
-static int wlhwrst(struct wl_softc *sc);
-static void wlrustrt(struct wl_softc *sc);
-static void wlbldcu(struct wl_softc *sc);
-static int wlack(struct wl_softc *sc);
-static int wlread(struct wl_softc *sc, u_short fd_p);
-static void getsnr(struct wl_softc *sc);
-static void wlrcv(struct wl_softc *sc);
-static int wlrequeue(struct wl_softc *sc, u_short fd_p);
-static void wlsftwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp, struct wl_softc *sc);
-static void wlhdwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp, struct wl_softc *sc);
-#ifdef WLDEBUG
-static void wltbd(struct wl_softc *sc);
-#endif
-static void wlgetpsa(struct wl_softc *sc, u_char *buf);
-static void wlsetpsa(struct wl_softc *sc);
-static u_short wlpsacrc(u_char *buf);
-static void wldump(struct wl_softc *sc);
-#ifdef WLCACHE
-static void wl_cache_store(struct wl_softc *, struct ether_header *, struct mbuf *);
-static void wl_cache_zero(struct wl_softc *sc);
-#endif
-
-/* array for maping irq numbers to values for the irq parameter register */
-static int irqvals[16] = {
- 0, 0, 0, 0x01, 0x02, 0x04, 0, 0x08, 0, 0, 0x10, 0x20, 0x40, 0, 0, 0x80
-};
-
-/*
- * wlprobe:
- *
- * This function "probes" or checks for the WaveLAN board on the bus to
- * see if it is there. As far as I can tell, the best break between this
- * routine and the attach code is to simply determine whether the board
- * is configured in properly. Currently my approach to this is to write
- * and read a word from the SRAM on the board being probed. If the word
- * comes back properly then we assume the board is there. The config
- * code expects to see a successful return from the probe routine before
- * attach will be called.
- *
- * input : address device is mapped to, and unit # being checked
- * output : a '1' is returned if the board exists, and a 0 otherwise
- *
- */
-static int
-wlprobe(device_t device)
-{
- struct wl_softc *sc;
- char *str = "wl%d: board out of range [0..%d]\n";
- u_char inbuf[100];
- rman_res_t junk, sirq;
- int error, irq;
-
- error = ISA_PNP_PROBE(device_get_parent(device), device, wl_ids);
- if (error == ENXIO || error == 0)
- return (error);
-
- sc = device_get_softc(device);
- error = wl_allocate_resources(device);
- if (error)
- goto errexit;
-
- /* TBD. not true.
- * regular CMD() will not work, since no softc yet
- */
-#define PCMD(sc, hacr) WL_WRITE_2((sc), HACR, (hacr))
-
- PCMD(sc, HACR_RESET); /* reset the board */
- DELAY(DELAYCONST); /* >> 4 clocks at 6MHz */
- PCMD(sc, HACR_RESET); /* reset the board */
- DELAY(DELAYCONST); /* >> 4 clocks at 6MHz */
-
- /* clear reset command and set PIO#1 in autoincrement mode */
- PCMD(sc, HACR_DEFAULT);
- PCMD(sc, HACR_DEFAULT);
- WL_WRITE_2(sc, PIOR1, 0); /* go to beginning of RAM */
- WL_WRITE_MULTI_2(sc, PIOP1, str, strlen(str)/2+1); /* write string */
-
- WL_WRITE_2(sc, PIOR1, 0); /* rewind */
- WL_READ_MULTI_2(sc, PIOP1, inbuf, strlen(str)/2+1); /* read result */
-
- if (bcmp(str, inbuf, strlen(str))) {
- error = ENXIO;
- goto errexit;
- }
-
- sc->chan24 = 0; /* 2.4 Gz: config channel */
- sc->freq24 = 0; /* 2.4 Gz: frequency */
-
- /* read the PSA from the board into temporary storage */
- wlgetpsa(sc, inbuf);
-
- /* We read the IRQ value from the PSA on the board. */
- for (irq = 15; irq >= 0; irq--)
- if (irqvals[irq] == inbuf[WLPSA_IRQNO])
- break;
- if ((irq == 0) || (irqvals[irq] == 0)){
- device_printf(device, "PSA corrupt (invalid IRQ value)\n");
- } else {
- /*
- * If the IRQ requested by the PSA is already claimed by another
- * device, the board won't work, but the user can still access the
- * driver to change the IRQ.
- */
- if (bus_get_resource(device, SYS_RES_IRQ, 0, &sirq, &junk))
- goto errexit;
- if (irq != (int)sirq)
- device_printf(device, "board is configured for interrupt %d\n",
- irq);
- }
- wl_deallocate_resources(device);
- return (0);
-
-errexit:
- wl_deallocate_resources(device);
- return (error);
-}
-
-/*
- * wlattach:
- *
- * This function attaches a WaveLAN board to the "system". The rest of
- * runtime structures are initialized here (this routine is called after
- * a successful probe of the board). Once the ethernet address is read
- * and stored, the board's ifnet structure is attached and readied.
- *
- * input : isa_dev structure setup in autoconfig
- * output : board structs and ifnet is setup
- *
- */
-static int
-wlattach(device_t device)
-{
- struct wl_softc *sc;
- int error, i, j;
- struct ifnet *ifp;
- u_char eaddr[6];
-
- sc = device_get_softc(device);
- sc->dev = device;
- ifp = sc->ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- device_printf(device, "can not if_alloc()\n");
- return (ENOSPC);
- }
-
- mtx_init(&sc->wl_mtx, device_get_nameunit(device), MTX_NETWORK_LOCK,
- MTX_DEF);
- callout_init_mtx(&sc->watchdog_timer, &sc->wl_mtx, 0);
-
- error = wl_allocate_resources(device);
- if (error) {
- wl_deallocate_resources(device);
- return (ENXIO);
- }
-
-#ifdef WLDEBUG
- printf("wlattach: base %jx, unit %d\n", rman_get_start(sc->res_ioport),
- device_get_unit(device));
-#endif
-
- sc->flags = 0;
- sc->mode = 0;
- sc->hacr = HACR_RESET;
- CMD(sc); /* reset the board */
- DELAY(DELAYCONST); /* >> 4 clocks at 6MHz */
-
- /* clear reset command and set PIO#2 in parameter access mode */
- sc->hacr = (HACR_DEFAULT & ~HACR_16BITS);
- CMD(sc);
-
- /* Read the PSA from the board for our later reference */
- wlgetpsa(sc, sc->psa);
-
- /* fetch NWID */
- sc->nwid[0] = sc->psa[WLPSA_NWID];
- sc->nwid[1] = sc->psa[WLPSA_NWID+1];
-
- /* fetch MAC address - decide which one first */
- if (sc->psa[WLPSA_MACSEL] & 1)
- j = WLPSA_LOCALMAC;
- else
- j = WLPSA_UNIMAC;
- for (i=0; i < WAVELAN_ADDR_SIZE; ++i)
- eaddr[i] = sc->psa[j + i];
-
- /* enter normal 16 bit mode operation */
- sc->hacr = HACR_DEFAULT;
- CMD(sc);
-
- wlinitmmc(sc);
- WL_WRITE_2(sc, PIOR1, OFFSET_SCB + 8); /* address of scb_crcerrs */
- WL_WRITE_2(sc, PIOP1, 0); /* clear scb_crcerrs */
- WL_WRITE_2(sc, PIOP1, 0); /* clear scb_alnerrs */
- WL_WRITE_2(sc, PIOP1, 0); /* clear scb_rscerrs */
- WL_WRITE_2(sc, PIOP1, 0); /* clear scb_ovrnerrs */
-
- ifp->if_softc = sc;
- ifp->if_mtu = WAVELAN_MTU;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
-#ifdef WLDEBUG
- ifp->if_flags |= IFF_DEBUG;
-#endif
-#if MULTICAST
- ifp->if_flags |= IFF_MULTICAST;
-#endif /* MULTICAST */
- if_initname(ifp, device_get_name(device), device_get_unit(device));
- ifp->if_init = wlinit;
- ifp->if_start = wlstart;
- ifp->if_ioctl = wlioctl;
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
- /* no entries
- ifp->if_done
- ifp->if_reset
- */
- ether_ifattach(ifp, eaddr);
-
- if_printf(ifp, "NWID 0x%02x%02x", sc->nwid[0], sc->nwid[1]);
- if (sc->freq24)
- printf(", Freq %d MHz",sc->freq24); /* 2.4 Gz */
- printf("\n"); /* 2.4 Gz */
-
- bus_setup_intr(device, sc->res_irq, INTR_TYPE_NET, NULL, wlintr, sc, &sc->intr_cookie);
-
- if (bootverbose)
- wldump(sc);
- return (0);
-}
-
-static int
-wldetach(device_t device)
-{
- struct wl_softc *sc = device_get_softc(device);
- struct ifnet *ifp;
-
- ifp = sc->ifp;
- ether_ifdetach(ifp);
-
- WL_LOCK(sc);
-
- /* reset the board */
- sc->hacr = HACR_RESET;
- CMD(sc);
- sc->hacr = HACR_DEFAULT;
- CMD(sc);
- callout_stop(&sc->watchdog_timer);
- WL_UNLOCK(sc);
- callout_drain(&sc->watchdog_timer);
-
- if (sc->intr_cookie != NULL) {
- bus_teardown_intr(device, sc->res_irq, sc->intr_cookie);
- sc->intr_cookie = NULL;
- }
-
- wl_deallocate_resources(device);
- if_free(ifp);
- mtx_destroy(&sc->wl_mtx);
- return (0);
-}
-
-static int
-wl_allocate_resources(device_t device)
-{
- struct wl_softc *sc = device_get_softc(device);
- int ports = 16; /* Number of ports */
-
- sc->res_ioport = bus_alloc_resource_anywhere(device, SYS_RES_IOPORT,
- &sc->rid_ioport, ports, RF_ACTIVE);
- if (sc->res_ioport == NULL)
- goto errexit;
-
- sc->res_irq = bus_alloc_resource_any(device, SYS_RES_IRQ,
- &sc->rid_irq, RF_SHAREABLE|RF_ACTIVE);
- if (sc->res_irq == NULL)
- goto errexit;
- return (0);
-
-errexit:
- wl_deallocate_resources(device);
- return (ENXIO);
-}
-
-static int
-wl_deallocate_resources(device_t device)
-{
- struct wl_softc *sc = device_get_softc(device);
-
- if (sc->res_irq != 0) {
- bus_release_resource(device, SYS_RES_IRQ,
- sc->rid_irq, sc->res_irq);
- sc->res_irq = 0;
- }
- if (sc->res_ioport != 0) {
- bus_release_resource(device, SYS_RES_IOPORT,
- sc->rid_ioport, sc->res_ioport);
- sc->res_ioport = 0;
- }
- return (0);
-}
-
-/*
- * Print out interesting information about the 82596.
- */
-static void
-wldump(struct wl_softc *sc)
-{
- int i;
-
- printf("hasr %04x\n", WL_READ_2(sc, HASR));
-
- printf("scb at %04x:\n ", OFFSET_SCB);
- WL_WRITE_2(sc, PIOR1, OFFSET_SCB);
- for (i = 0; i < 8; i++)
- printf("%04x ", WL_READ_2(sc, PIOP1));
- printf("\n");
-
- printf("cu at %04x:\n ", OFFSET_CU);
- WL_WRITE_2(sc, PIOR1, OFFSET_CU);
- for (i = 0; i < 8; i++)
- printf("%04x ", WL_READ_2(sc, PIOP1));
- printf("\n");
-
- printf("tbd at %04x:\n ", OFFSET_TBD);
- WL_WRITE_2(sc, PIOR1, OFFSET_TBD);
- for (i = 0; i < 4; i++)
- printf("%04x ", WL_READ_2(sc, PIOP1));
- printf("\n");
-}
-
-/* Initialize the Modem Management Controller */
-static void
-wlinitmmc(struct wl_softc *sc)
-{
- int configured;
- int mode = sc->mode;
- int i; /* 2.4 Gz */
-
- /* enter 8 bit operation */
- sc->hacr = (HACR_DEFAULT & ~HACR_16BITS);
- CMD(sc);
-
- configured = sc->psa[WLPSA_CONFIGURED] & 1;
-
- /*
- * Set default modem control parameters. Taken from NCR document
- * 407-0024326 Rev. A
- */
- MMC_WRITE(MMC_JABBER_ENABLE, 0x01);
- MMC_WRITE(MMC_ANTEN_SEL, 0x02);
- MMC_WRITE(MMC_IFS, 0x20);
- MMC_WRITE(MMC_MOD_DELAY, 0x04);
- MMC_WRITE(MMC_JAM_TIME, 0x38);
- MMC_WRITE(MMC_DECAY_PRM, 0x00); /* obsolete ? */
- MMC_WRITE(MMC_DECAY_UPDAT_PRM, 0x00);
- if (!configured) {
- MMC_WRITE(MMC_LOOPT_SEL, 0x00);
- if (sc->psa[WLPSA_COMPATNO] & 1) {
- MMC_WRITE(MMC_THR_PRE_SET, 0x01); /* 0x04 for AT and 0x01 for MCA */
- } else {
- MMC_WRITE(MMC_THR_PRE_SET, 0x04); /* 0x04 for AT and 0x01 for MCA */
- }
- MMC_WRITE(MMC_QUALITY_THR, 0x03);
- } else {
- /* use configuration defaults from parameter storage area */
- if (sc->psa[WLPSA_NWIDENABLE] & 1) {
- if ((mode & (MOD_PROM | MOD_ENAL)) && wl_ignore_nwid) {
- MMC_WRITE(MMC_LOOPT_SEL, 0x40);
- } else {
- MMC_WRITE(MMC_LOOPT_SEL, 0x00);
- }
- } else {
- MMC_WRITE(MMC_LOOPT_SEL, 0x40); /* disable network id check */
- }
- MMC_WRITE(MMC_THR_PRE_SET, sc->psa[WLPSA_THRESH]);
- MMC_WRITE(MMC_QUALITY_THR, sc->psa[WLPSA_QUALTHRESH]);
- }
- MMC_WRITE(MMC_FREEZE, 0x00);
- MMC_WRITE(MMC_ENCR_ENABLE, 0x00);
-
- MMC_WRITE(MMC_NETW_ID_L,sc->nwid[1]); /* set NWID */
- MMC_WRITE(MMC_NETW_ID_H,sc->nwid[0]);
-
- /* enter normal 16 bit mode operation */
- sc->hacr = HACR_DEFAULT;
- CMD(sc);
- CMD(sc); /* virtualpc1 needs this! */
-
- if (sc->psa[WLPSA_COMPATNO]== /* 2.4 Gz: half-card ver */
- WLPSA_COMPATNO_WL24B) { /* 2.4 Gz */
- i=sc->chan24<<4; /* 2.4 Gz: position ch # */
- MMC_WRITE(MMC_EEADDR,i+0x0f); /* 2.4 Gz: named ch, wc=16 */
- MMC_WRITE(MMC_EECTRL,MMC_EECTRL_DWLD+ /* 2.4 Gz: Download Synths */
- MMC_EECTRL_EEOP_READ); /* 2.4 Gz: Read EEPROM */
- for (i=0; i<1000; ++i) { /* 2.4 Gz: wait for download */
- DELAY(40); /* 2.4 Gz */
- if ((wlmmcread(sc, MMC_EECTRLstat) /* 2.4 Gz: check DWLD and */
- &(MMC_EECTRLstat_DWLD /* 2.4 Gz: EEBUSY */
- +MMC_EECTRLstat_EEBUSY))==0) /* 2.4 Gz: */
- break; /* 2.4 Gz: download finished */
- } /* 2.4 Gz */
- if (i==1000) printf("wl: synth load failed\n"); /* 2.4 Gz */
- MMC_WRITE(MMC_EEADDR,0x61); /* 2.4 Gz: default pwr, wc=2 */
- MMC_WRITE(MMC_EECTRL,MMC_EECTRL_DWLD+ /* 2.4 Gz: Download Xmit Pwr */
- MMC_EECTRL_EEOP_READ); /* 2.4 Gz: Read EEPROM */
- for (i=0; i<1000; ++i) { /* 2.4 Gz: wait for download */
- DELAY(40); /* 2.4 Gz */
- if ((wlmmcread(sc, MMC_EECTRLstat) /* 2.4 Gz: check DWLD and */
- &(MMC_EECTRLstat_DWLD /* 2.4 Gz: EEBUSY */
- +MMC_EECTRLstat_EEBUSY))==0) /* 2.4 Gz: */
- break; /* 2.4 Gz: download finished */
- } /* 2.4 Gz */
- if (i==1000) printf("wl: xmit pwr load failed\n"); /* 2.4 Gz */
- MMC_WRITE(MMC_ANALCTRL, /* 2.4 Gz: EXT ant+polarity */
- MMC_ANALCTRL_ANTPOL + /* 2.4 Gz: */
- MMC_ANALCTRL_EXTANT); /* 2.4 Gz: */
- i=sc->chan24<<4; /* 2.4 Gz: position ch # */
- MMC_WRITE(MMC_EEADDR,i); /* 2.4 Gz: get frequency */
- MMC_WRITE(MMC_EECTRL, /* 2.4 Gz: EEPROM read */
- MMC_EECTRL_EEOP_READ); /* 2.4 Gz: */
- DELAY(40); /* 2.4 Gz */
- i = wlmmcread(sc, MMC_EEDATALrv) /* 2.4 Gz: freq val */
- + (wlmmcread(sc, MMC_EEDATAHrv)<<8); /* 2.4 Gz */
- sc->freq24 = (i>>6)+2400; /* 2.4 Gz: save real freq */
- }
-}
-
-/*
- * wlinit:
- *
- * Another routine that interfaces the "if" layer to this driver.
- * Simply resets the structures that are used by "upper layers".
- * As well as calling wlhwrst that does reset the WaveLAN board.
- *
- * input : softc pointer for this interface
- * output : structures (if structs) and board are reset
- *
- */
-static void
-wlinit(void *xsc)
-{
- struct wl_softc *sc = xsc;
-
- WL_LOCK(sc);
- wlinit_locked(sc);
- WL_UNLOCK(sc);
-}
-
-static void
-wlinit_locked(struct wl_softc *sc)
-{
- struct ifnet *ifp = sc->ifp;
- int stat;
-
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(ifp, "entered wlinit()\n");
-#endif
- WL_LOCK_ASSERT(sc);
- if ((stat = wlhwrst(sc)) == TRUE) {
- sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; /* same as DSF_RUNNING */
- /*
- * OACTIVE is used by upper-level routines
- * and must be set
- */
- sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; /* same as tbusy below */
-
- sc->flags |= DSF_RUNNING;
- sc->tbusy = 0;
- callout_stop(&sc->watchdog_timer);
-
- wlstart_locked(ifp);
- } else {
- if_printf(ifp, "init(): trouble resetting board.\n");
- }
-}
-
-/*
- * wlhwrst:
- *
- * This routine resets the WaveLAN board that corresponds to the
- * board number passed in.
- *
- * input : board number to do a hardware reset
- * output : board is reset
- *
- */
-static int
-wlhwrst(struct wl_softc *sc)
-{
-
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(sc->ifp, "entered wlhwrst()\n");
-#endif
- sc->hacr = HACR_RESET;
- CMD(sc); /* reset the board */
-
- /* clear reset command and set PIO#1 in autoincrement mode */
- sc->hacr = HACR_DEFAULT;
- CMD(sc);
-
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- wlmmcstat(sc); /* Display MMC registers */
-#endif /* WLDEBUG */
- wlbldcu(sc); /* set up command unit structures */
-
- if (wldiag(sc) == 0)
- return(0);
-
- if (wlconfig(sc) == 0)
- return(0);
- /*
- * insert code for loopback test here
- */
- wlrustrt(sc); /* start receive unit */
-
- /* enable interrupts */
- sc->hacr = (HACR_DEFAULT | HACR_INTRON);
- CMD(sc);
-
- return(1);
-}
-
-/*
- * wlbldcu:
- *
- * This function builds up the command unit structures. It inits
- * the scp, iscp, scb, cb, tbd, and tbuf.
- *
- */
-static void
-wlbldcu(struct wl_softc *sc)
-{
- scp_t scp;
- iscp_t iscp;
- scb_t scb;
- ac_t cb;
- tbd_t tbd;
- int i;
-
- bzero(&scp, sizeof(scp));
- scp.scp_sysbus = 0;
- scp.scp_iscp = OFFSET_ISCP;
- scp.scp_iscp_base = 0;
- WL_WRITE_2(sc, PIOR1, OFFSET_SCP);
- WL_WRITE_MULTI_2(sc, PIOP1, &scp, sizeof(scp_t)/2);
-
- bzero(&iscp, sizeof(iscp));
- iscp.iscp_busy = 1;
- iscp.iscp_scb_offset = OFFSET_SCB;
- iscp.iscp_scb = 0;
- iscp.iscp_scb_base = 0;
- WL_WRITE_2(sc, PIOR1, OFFSET_ISCP);
- WL_WRITE_MULTI_2(sc, PIOP1, &iscp, sizeof(iscp_t)/2);
-
- scb.scb_status = 0;
- scb.scb_command = SCB_RESET;
- scb.scb_cbl_offset = OFFSET_CU;
- scb.scb_rfa_offset = OFFSET_RU;
- scb.scb_crcerrs = 0;
- scb.scb_alnerrs = 0;
- scb.scb_rscerrs = 0;
- scb.scb_ovrnerrs = 0;
- WL_WRITE_2(sc, PIOR1, OFFSET_SCB);
- WL_WRITE_MULTI_2(sc, PIOP1, &scb, sizeof(scb_t)/2);
-
- SET_CHAN_ATTN(sc);
-
- WL_WRITE_2(sc, PIOR0, OFFSET_ISCP + 0); /* address of iscp_busy */
- for (i = 1000000; WL_READ_2(sc, PIOP0) && (i-- > 0); )
- continue;
- if (i <= 0)
- device_printf(sc->dev, "bldcu(): iscp_busy timeout.\n");
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 0); /* address of scb_status */
- for (i = STATUS_TRIES; i-- > 0; ) {
- if (WL_READ_2(sc, PIOP0) == (SCB_SW_CX|SCB_SW_CNA))
- break;
- }
- if (i <= 0)
- device_printf(sc->dev, "bldcu(): not ready after reset.\n");
- wlack(sc);
-
- cb.ac_status = 0;
- cb.ac_command = AC_CW_EL; /* NOP */
- cb.ac_link_offset = OFFSET_CU;
- WL_WRITE_2(sc, PIOR1, OFFSET_CU);
- WL_WRITE_MULTI_2(sc, PIOP1, &cb, 6/2);
-
- tbd.act_count = 0;
- tbd.next_tbd_offset = I82586NULL;
- tbd.buffer_addr = 0;
- tbd.buffer_base = 0;
- WL_WRITE_2(sc, PIOR1, OFFSET_TBD);
- WL_WRITE_MULTI_2(sc, PIOP1, &tbd, sizeof(tbd_t)/2);
-}
-
-/*
- * wlstart:
- *
- * send a packet
- *
- * input : board number
- * output : stuff sent to board if any there
- *
- */
-static void
-wlstart(struct ifnet *ifp)
-{
- struct wl_softc *sc = ifp->if_softc;
-
- WL_LOCK(sc);
- wlstart_locked(ifp);
- WL_UNLOCK(sc);
-}
-
-static void
-wlstart_locked(struct ifnet *ifp)
-{
- struct mbuf *m;
- struct wl_softc *sc = ifp->if_softc;
- int scb_status, cu_status, scb_command;
-
- WL_LOCK_ASSERT(sc);
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(ifp, "entered wlstart()\n");
-#endif
-
- WL_WRITE_2(sc, PIOR1, OFFSET_CU);
- cu_status = WL_READ_2(sc, PIOP1);
- WL_WRITE_2(sc, PIOR0,OFFSET_SCB + 0); /* scb_status */
- scb_status = WL_READ_2(sc, PIOP0);
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 2);
- scb_command = WL_READ_2(sc, PIOP0);
-
- /*
- * don't need OACTIVE check as tbusy here checks to see
- * if we are already busy
- */
- if (sc->tbusy) {
- if ((scb_status & 0x0700) == SCB_CUS_IDLE &&
- (cu_status & AC_SW_B) == 0){
- sc->tbusy = 0;
- callout_stop(&sc->watchdog_timer);
- sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- /*
- * This is probably just a race. The xmt'r is just
- * became idle but WE have masked interrupts so ...
- */
-#ifdef WLDEBUG
- if_printf(ifp, "CU idle, scb %04x %04x cu %04x\n",
- scb_status, scb_command, cu_status);
-#endif
- if (xmt_watch) printf("!!");
- } else {
- return; /* genuinely still busy */
- }
- } else if ((scb_status & 0x0700) == SCB_CUS_ACTV ||
- (cu_status & AC_SW_B)){
-#ifdef WLDEBUG
- if_printf(ifp, "CU unexpectedly busy; scb %04x cu %04x\n",
- scb_status, cu_status);
-#endif
- if (xmt_watch)
- if_printf(ifp, "busy?!\n");
- return; /* hey, why are we busy? */
- }
-
- /* get ourselves some data */
- IF_DEQUEUE(&ifp->if_snd, m);
- if (m != NULL) {
- /* let BPF see it before we commit it */
- BPF_MTAP(ifp, m);
- sc->tbusy++;
- /* set the watchdog timer so that if the board
- * fails to interrupt we will restart
- */
- /* try 10 ms, not very long */
- callout_reset(&sc->watchdog_timer, hz / 100, wlwatchdog, sc);
- sc->ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1);
- wlxmt(sc, m);
- } else {
- sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- }
- return;
-}
-
-/*
- * wlread:
- *
- * This routine does the actual copy of data (including ethernet header
- * structure) from the WaveLAN to an mbuf chain that will be passed up
- * to the "if" (network interface) layer. NOTE: we currently
- * don't handle trailer protocols, so if that is needed, it will
- * (at least in part) be added here. For simplicities sake, this
- * routine copies the receive buffers from the board into a local (stack)
- * buffer until the frame has been copied from the board. Once in
- * the local buffer, the contents are copied to an mbuf chain that
- * is then enqueued onto the appropriate "if" queue.
- *
- * input : board number, and a frame descriptor address
- * output : the packet is put into an mbuf chain, and passed up
- * assumes : if any errors occur, packet is "dropped on the floor"
- *
- */
-static int
-wlread(struct wl_softc *sc, u_short fd_p)
-{
- struct ifnet *ifp = sc->ifp;
- fd_t fd;
- struct ether_header *eh;
- struct mbuf *m;
- rbd_t rbd;
- u_char *mb_p;
- u_short mlen, len;
- u_short bytes_in_msg, bytes_in_mbuf, bytes;
-
- WL_LOCK_ASSERT(sc);
-
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(ifp, "entered wlread()\n");
-#endif
- if (!((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))) {
- if_printf(ifp, "read(): board is not running.\n");
- sc->hacr &= ~HACR_INTRON;
- CMD(sc); /* turn off interrupts */
- }
-
- /*
- * Collect message size.
- */
- WL_WRITE_2(sc, PIOR1, fd_p);
- WL_READ_MULTI_2(sc, PIOP1, &fd, sizeof(fd_t)/2);
- if (fd.rbd_offset == I82586NULL) {
- if (wlhwrst(sc) != TRUE) {
- sc->hacr &= ~HACR_INTRON;
- CMD(sc); /* turn off interrupts */
- if_printf(ifp, "read(): hwrst trouble.\n");
- }
- return 0;
- }
-
- WL_WRITE_2(sc, PIOR1, fd.rbd_offset);
- WL_READ_MULTI_2(sc, PIOP1, &rbd, sizeof(rbd_t)/2);
- bytes_in_msg = rbd.status & RBD_SW_COUNT;
-
- /*
- * Allocate a cluster'd mbuf to receive the packet.
- */
- m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
- if (m == NULL) {
- if (wlhwrst(sc) != TRUE) {
- sc->hacr &= ~HACR_INTRON;
- CMD(sc); /* turn off interrupts */
- if_printf(ifp, "read(): hwrst trouble.\n");
- }
- return 0;
- }
- m->m_pkthdr.len = m->m_len = MCLBYTES;
- m_adj(m, ETHER_ALIGN); /* align IP header */
-
- /*
- * Collect the message data.
- */
- mlen = 0;
- mb_p = mtod(m, u_char *);
- bytes_in_mbuf = m->m_len;
-
- /* Put the ethernet header inside the mbuf. */
- bcopy(&fd.destination[0], mb_p, 14);
- mb_p += 14;
- mlen += 14;
- bytes_in_mbuf -= 14;
-
- bytes = min(bytes_in_mbuf, bytes_in_msg);
- for (;;) {
- if (bytes & 1) {
- len = bytes + 1;
- } else {
- len = bytes;
- }
- WL_WRITE_2(sc, PIOR1, rbd.buffer_addr);
- WL_READ_MULTI_2(sc, PIOP1, mb_p, len/2);
- mlen += bytes;
-
- if (bytes > bytes_in_mbuf) {
- /* XXX something wrong, a packet should fit in 1 cluster */
- m_freem(m);
- if_printf(ifp, "read(): packet too large (%u > %u)\n",
- bytes, bytes_in_mbuf);
- if (wlhwrst(sc) != TRUE) {
- sc->hacr &= ~HACR_INTRON;
- CMD(sc); /* turn off interrupts */
- if_printf(ifp, "read(): hwrst trouble.\n");
- }
- return 0;
- }
- mb_p += bytes;
- bytes_in_mbuf -= bytes;
- bytes_in_msg -= bytes;
- if (bytes_in_msg == 0) {
- if (rbd.status & RBD_SW_EOF || rbd.next_rbd_offset == I82586NULL) {
- break;
- }
- WL_WRITE_2(sc, PIOR1, rbd.next_rbd_offset);
- WL_READ_MULTI_2(sc, PIOP1, &rbd, sizeof(rbd_t)/2);
- bytes_in_msg = rbd.status & RBD_SW_COUNT;
- } else {
- rbd.buffer_addr += bytes;
- }
-
- bytes = min(bytes_in_mbuf, bytes_in_msg);
- }
-
- m->m_pkthdr.len = m->m_len = mlen;
- m->m_pkthdr.rcvif = ifp;
-
- /*
- * If hw is in promiscuous mode (note that I said hardware, not if
- * IFF_PROMISC is set in ifnet flags), then if this is a unicast
- * packet and the MAC dst is not us, drop it. This check in normally
- * inside ether_input(), but IFF_MULTI causes hw promisc without
- * a bpf listener, so this is wrong.
- * Greg Troxel <gdt@ir.bbn.com>, 1998-08-07
- */
- /*
- * TBD: also discard packets where NWID does not match.
- * However, there does not appear to be a way to read the nwid
- * for a received packet. -gdt 1998-08-07
- */
- /* XXX verify mbuf length */
- eh = mtod(m, struct ether_header *);
- if (
-#ifdef WL_USE_IFNET_PROMISC_CHECK /* not defined */
- (sc->ifp->if_flags & (IFF_PROMISC|IFF_ALLMULTI))
-#else
- /* hw is in promisc mode if this is true */
- (sc->mode & (MOD_PROM | MOD_ENAL))
-#endif
- &&
- (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
- bcmp(eh->ether_dhost, IF_LLADDR(sc->ifp),
- sizeof(eh->ether_dhost)) != 0 ) {
- m_freem(m);
- return 1;
- }
-
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(ifp, "wlrecv %u bytes\n", mlen);
-#endif
-
-#ifdef WLCACHE
- wl_cache_store(sc, eh, m);
-#endif
-
- /*
- * received packet is now in a chain of mbuf's. next step is
- * to pass the packet upwards.
- */
- WL_UNLOCK(sc);
- (*ifp->if_input)(ifp, m);
- WL_LOCK(sc);
- return 1;
-}
-
-/*
- * wlioctl:
- *
- * This routine processes an ioctl request from the "if" layer
- * above.
- *
- * input : pointer the appropriate "if" struct, command, and data
- * output : based on command appropriate action is taken on the
- * WaveLAN board(s) or related structures
- * return : error is returned containing exit conditions
- *
- */
-static int
-wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct ifreq *ifr = (struct ifreq *)data;
- struct wl_softc *sc = ifp->if_softc;
- short mode = 0;
- int error = 0;
- struct thread *td = curthread; /* XXX */
- int irq, irqval, i, isroot;
- char psa_buf[0x40];
- char eeprom_buf[0x80];
-#ifdef WLCACHE
- size_t size;
- char * cpt;
-#endif
-
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(ifp, "entered wlioctl()\n");
-#endif
- switch (cmd) {
- case SIOCSIFFLAGS:
- WL_LOCK(sc);
- if (ifp->if_flags & IFF_ALLMULTI) {
- mode |= MOD_ENAL;
- }
- if (ifp->if_flags & IFF_PROMISC) {
- mode |= MOD_PROM;
- }
- if (ifp->if_flags & IFF_LINK0) {
- mode |= MOD_PROM;
- }
- /*
- * force a complete reset if the receive multicast/
- * promiscuous mode changes so that these take
- * effect immediately.
- *
- */
- if (sc->mode != mode) {
- sc->mode = mode;
- if (sc->flags & DSF_RUNNING) {
- sc->flags &= ~DSF_RUNNING;
- wlinit_locked(sc);
- }
- }
- /* if interface is marked DOWN and still running then
- * stop it.
- */
- if ((ifp->if_flags & IFF_UP) == 0 && sc->flags & DSF_RUNNING) {
- if_printf(ifp, "ioctl(): board is not running\n");
- sc->flags &= ~DSF_RUNNING;
- sc->hacr &= ~HACR_INTRON;
- CMD(sc); /* turn off interrupts */
- }
- /* else if interface is UP and RUNNING, start it
- */
- else if (ifp->if_flags & IFF_UP && (sc->flags & DSF_RUNNING) == 0) {
- wlinit_locked(sc);
- }
-
- /* if WLDEBUG set on interface, then printf rf-modem regs
- */
- if (ifp->if_flags & IFF_DEBUG)
- wlmmcstat(sc);
- WL_UNLOCK(sc);
- break;
-#if MULTICAST
- case SIOCADDMULTI:
- case SIOCDELMULTI:
-
- wlinit(sc);
- break;
-#endif /* MULTICAST */
-
- /* DEVICE SPECIFIC */
-
-
- /* copy the PSA out to the caller */
- case SIOCGWLPSA:
- /* work out if they're root */
- isroot = (priv_check(td, PRIV_NET80211_GETKEY) == 0);
-
- bzero(psa_buf, sizeof(psa_buf));
- WL_LOCK(sc);
- for (i = 0; i < 0x40; i++) {
- /* don't hand the DES key out to non-root users */
- if ((i > WLPSA_DESKEY) && (i < (WLPSA_DESKEY + 8)) && !isroot)
- continue;
- psa_buf[i] = sc->psa[i];
- }
- WL_UNLOCK(sc);
-
- error = copyout(psa_buf, ifr->ifr_data, sizeof(psa_buf));
- break;
-
-
- /* copy the PSA in from the caller; we only copy _some_ values */
- case SIOCSWLPSA:
- /* root only */
- if ((error = priv_check(td, PRIV_DRIVER)))
- break;
-
- error = copyin(ifr->ifr_data, psa_buf, sizeof(psa_buf));
- if (error)
- break;
-
- /* check IRQ value */
- irqval = psa_buf[WLPSA_IRQNO];
- for (irq = 15; irq >= 0; irq--)
- if (irqvals[irq] == irqval)
- break;
- if (irq == 0) /* oops */
- break;
- WL_LOCK(sc);
- /* new IRQ */
- sc->psa[WLPSA_IRQNO] = irqval;
-
- /* local MAC */
- for (i = 0; i < 6; i++)
- sc->psa[WLPSA_LOCALMAC + i] = psa_buf[WLPSA_LOCALMAC + i];
-
- /* MAC select */
- sc->psa[WLPSA_MACSEL] = psa_buf[WLPSA_MACSEL];
-
- /* default nwid */
- sc->psa[WLPSA_NWID] = psa_buf[WLPSA_NWID];
- sc->psa[WLPSA_NWID + 1] = psa_buf[WLPSA_NWID + 1];
-
- wlsetpsa(sc); /* update the PSA */
- WL_UNLOCK(sc);
- break;
-
-
- /* get the current NWID out of the sc since we stored it there */
- case SIOCGWLCNWID:
- WL_LOCK(sc);
- ifr->ifr_data = (caddr_t) (sc->nwid[0] << 8 | sc->nwid[1]);
- WL_UNLOCK(sc);
- break;
-
-
- /*
- * change the nwid dynamically. This
- * ONLY changes the radio modem and does not
- * change the PSA.
- *
- * 2 steps:
- * 1. save in softc "soft registers"
- * 2. save in radio modem (MMC)
- */
- case SIOCSWLCNWID:
- /* root only */
- if ((error = priv_check(td, PRIV_DRIVER)))
- break;
- WL_LOCK(sc);
- if (!(ifp->if_flags & IFF_UP)) {
- error = EIO; /* only allowed while up */
- } else {
- /*
- * soft c nwid shadows radio modem setting
- */
- sc->nwid[0] = (int)ifr->ifr_data >> 8;
- sc->nwid[1] = (int)ifr->ifr_data & 0xff;
- MMC_WRITE(MMC_NETW_ID_L,sc->nwid[1]);
- MMC_WRITE(MMC_NETW_ID_H,sc->nwid[0]);
- }
- WL_UNLOCK(sc);
- break;
-
- /* copy the EEPROM in 2.4 Gz WaveMODEM out to the caller */
- case SIOCGWLEEPROM:
- /* root only */
- if ((error = priv_check(td, PRIV_DRIVER)))
- break;
-
- bzero(eeprom_buf, sizeof(eeprom_buf));
- WL_LOCK(sc);
- for (i=0x00; i<0x80; ++i) { /* 2.4 Gz: size of EEPROM */
- MMC_WRITE(MMC_EEADDR,i); /* 2.4 Gz: get frequency */
- MMC_WRITE(MMC_EECTRL, /* 2.4 Gz: EEPROM read */
- MMC_EECTRL_EEOP_READ); /* 2.4 Gz: */
- DELAY(40); /* 2.4 Gz */
- eeprom_buf[2 * i] = /* 2.4 Gz: pass low byte of */
- wlmmcread(sc, MMC_EEDATALrv); /* 2.4 Gz: EEPROM word */
- eeprom_buf[2 * i + 1] = /* 2.4 Gz: pass hi byte of */
- wlmmcread(sc, MMC_EEDATALrv); /* 2.4 Gz: EEPROM word */
- }
- WL_UNLOCK(sc);
- error = copyout(ifr->ifr_data, eeprom_buf, sizeof(eeprom_buf));
- break;
-
-#ifdef WLCACHE
- /* zero (Delete) the wl cache */
- case SIOCDWLCACHE:
- /* root only */
- if ((error = priv_check(td, PRIV_DRIVER)))
- break;
- WL_LOCK(sc);
- wl_cache_zero(sc);
- WL_UNLOCK(sc);
- break;
-
- /* read out the number of used cache elements */
- case SIOCGWLCITEM:
- WL_LOCK(sc);
- ifr->ifr_data = (caddr_t) sc->w_sigitems;
- WL_UNLOCK(sc);
- break;
-
- /* read out the wl cache */
- case SIOCGWLCACHE:
- WL_LOCK(sc);
- size = sc->w_sigitems * sizeof(struct w_sigcache);
- cpt = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (cpt == NULL) {
- WL_UNLOCK(sc);
- return (ENOMEM);
- }
-
- bcopy(sc->w_sigcache, cpt, size);
- WL_UNLOCK(sc);
-
- error = copyout(cpt, ifr->ifr_data, size);
- free(cpt, M_DEVBUF);
- break;
-#endif
-
- default:
- error = ether_ioctl(ifp, cmd, data);
- break;
- }
- return (error);
-}
-
-/*
- * wlwatchdog():
- *
- * Called if the timer set in wlstart expires before an interrupt is received
- * from the wavelan. It seems to lose interrupts sometimes.
- * The watchdog routine gets called if the transmitter failed to interrupt
- *
- * input : which board is timing out
- * output : board reset
- *
- */
-static void
-wlwatchdog(void *vsc)
-{
- struct wl_softc *sc = vsc;
-
- log(LOG_ERR, "%s: wavelan device timeout on xmit\n", sc->ifp->if_xname);
- if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
- wlinit_locked(sc);
-}
-
-/*
- * wlintr:
- *
- * This function is the interrupt handler for the WaveLAN
- * board. This routine will be called whenever either a packet
- * is received, or a packet has successfully been transferred and
- * the unit is ready to transmit another packet.
- *
- * input : board number that interrupted
- * output : either a packet is received, or a packet is transferred
- *
- */
-static void
-wlintr(void *arg)
-{
- struct wl_softc *sc = (struct wl_softc *)arg;
- int ac_status;
- u_short int_type, int_type1;
-
- WL_LOCK(sc);
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(sc->ifp, "wlintr() called\n");
-#endif
-
- if ((int_type = WL_READ_2(sc, HASR)) & HASR_MMC_INTR) {
- /* handle interrupt from the modem management controller */
- /* This will clear the interrupt condition */
- (void) wlmmcread(sc, MMC_DCE_STATUS); /* ignored for now */
- }
-
- if (!(int_type & HASR_INTR)){ /* return if no interrupt from 82586 */
- /* commented out. jrb. it happens when reinit occurs
- printf("wlintr: int_type %x, dump follows\n", int_type);
- wldump(sc);
- */
- WL_UNLOCK(sc);
- return;
- }
-
- if (gathersnr)
- getsnr(sc);
- for (;;) {
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 0); /* get scb status */
- int_type = (WL_READ_2(sc, PIOP0) & SCB_SW_INT);
- if (int_type == 0) /* no interrupts left */
- break;
-
- int_type1 = wlack(sc); /* acknowledge interrupt(s) */
- /* make sure no bits disappeared (others may appear) */
- if ((int_type & int_type1) != int_type)
- printf("wlack() int bits disappeared : %04x != int_type %04x\n",
- int_type1, int_type);
- int_type = int_type1; /* go with the new status */
- /*
- * incoming packet
- */
- if (int_type & SCB_SW_FR) {
- if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1);
- wlrcv(sc);
- }
- /*
- * receiver not ready
- */
- if (int_type & SCB_SW_RNR) {
- if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(sc->ifp, "intr(): receiver overrun! begin_fd = %x\n",
- sc->begin_fd);
-#endif
- wlrustrt(sc);
- }
- /*
- * CU not ready
- */
- if (int_type & SCB_SW_CNA) {
- /*
- * At present, we don't care about CNA's. We
- * believe they are a side effect of XMT.
- */
- }
- if (int_type & SCB_SW_CX) {
- /*
- * At present, we only request Interrupt for
- * XMT.
- */
- WL_WRITE_2(sc, PIOR1, OFFSET_CU); /* get command status */
- ac_status = WL_READ_2(sc, PIOP1);
-
- if (xmt_watch) { /* report some anomalies */
-
- if (sc->tbusy == 0) {
- if_printf(sc->ifp, "xmt intr but not busy, CU %04x\n",
- ac_status);
- }
- if (ac_status == 0) {
- if_printf(sc->ifp, "xmt intr but ac_status == 0\n");
- }
- if (ac_status & AC_SW_A) {
- if_printf(sc->ifp, "xmt aborted\n");
- }
-#ifdef notdef
- if (ac_status & TC_CARRIER) {
- if_printf(sc->ifp, "no carrier\n");
- }
-#endif /* notdef */
- if (ac_status & TC_CLS) {
- if_printf(sc->ifp, "no CTS\n");
- }
- if (ac_status & TC_DMA) {
- if_printf(sc->ifp, "DMA underrun\n");
- }
- if (ac_status & TC_DEFER) {
- if_printf(sc->ifp, "xmt deferred\n");
- }
- if (ac_status & TC_SQE) {
- if_printf(sc->ifp, "heart beat\n");
- }
- if (ac_status & TC_COLLISION) {
- if_printf(sc->ifp, "too many collisions\n");
- }
- }
- /* if the transmit actually failed, or returned some status */
- if ((!(ac_status & AC_SW_OK)) || (ac_status & 0xfff)) {
- if (ac_status & (TC_COLLISION | TC_CLS | TC_DMA)) {
- if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
- }
- /* count collisions */
- if_inc_counter(sc->ifp, IFCOUNTER_COLLISIONS, (ac_status & 0xf));
- /* if TC_COLLISION set and collision count zero, 16 collisions */
- if ((ac_status & 0x20) == 0x20) {
- if_inc_counter(sc->ifp, IFCOUNTER_COLLISIONS, 0x10);
- }
- }
- sc->tbusy = 0;
- callout_stop(&sc->watchdog_timer);
- sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- wlstart_locked(sc->ifp);
- }
- }
- WL_UNLOCK(sc);
- return;
-}
-
-/*
- * wlrcv:
- *
- * This routine is called by the interrupt handler to initiate a
- * packet transfer from the board to the "if" layer above this
- * driver. This routine checks if a buffer has been successfully
- * received by the WaveLAN. If so, the routine wlread is called
- * to do the actual transfer of the board data (including the
- * ethernet header) into a packet (consisting of an mbuf chain).
- *
- * input : number of the board to check
- * output : if a packet is available, it is "sent up"
- *
- */
-static void
-wlrcv(struct wl_softc *sc)
-{
- u_short fd_p, status, offset, link_offset;
-
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(sc->ifp, "entered wlrcv()\n");
-#endif
- for (fd_p = sc->begin_fd; fd_p != I82586NULL; fd_p = sc->begin_fd) {
-
- WL_WRITE_2(sc, PIOR0, fd_p + 0); /* address of status */
- status = WL_READ_2(sc, PIOP0);
- WL_WRITE_2(sc, PIOR1, fd_p + 4); /* address of link_offset */
- link_offset = WL_READ_2(sc, PIOP1);
- offset = WL_READ_2(sc, PIOP1); /* rbd_offset */
- if (status == 0xffff || offset == 0xffff /*I82586NULL*/) {
- if (wlhwrst(sc) != TRUE)
- if_printf(sc->ifp, "rcv(): hwrst ffff trouble.\n");
- return;
- } else if (status & AC_SW_C) {
- if (status == (RFD_DONE|RFD_RSC)) {
- /* lost one */
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(sc->ifp, "RCV: RSC %x\n", status);
-#endif
- if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
- } else if (!(status & RFD_OK)) {
- if_printf(sc->ifp, "RCV: !OK %x\n", status);
- if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
- } else if (status & 0xfff) { /* can't happen */
- if_printf(sc->ifp, "RCV: ERRs %x\n", status);
- if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
- } else if (!wlread(sc, fd_p))
- return;
-
- if (!wlrequeue(sc, fd_p)) {
- /* abort on chain error */
- if (wlhwrst(sc) != TRUE)
- if_printf(sc->ifp, "rcv(): hwrst trouble.\n");
- return;
- }
- sc->begin_fd = link_offset;
- } else {
- break;
- }
- }
- return;
-}
-
-/*
- * wlrequeue:
- *
- * This routine puts rbd's used in the last receive back onto the
- * free list for the next receive.
- *
- */
-static int
-wlrequeue(struct wl_softc *sc, u_short fd_p)
-{
- fd_t fd;
- u_short l_rbdp, f_rbdp, rbd_offset;
-
- WL_WRITE_2(sc, PIOR0, fd_p + 6);
- rbd_offset = WL_READ_2(sc, PIOP0);
- if ((f_rbdp = rbd_offset) != I82586NULL) {
- l_rbdp = f_rbdp;
- for (;;) {
- WL_WRITE_2(sc, PIOR0, l_rbdp + 0); /* address of status */
- if (WL_READ_2(sc, PIOP0) & RBD_SW_EOF)
- break;
- WL_WRITE_2(sc, PIOP0, 0);
- WL_WRITE_2(sc, PIOR0, l_rbdp + 2); /* next_rbd_offset */
- if ((l_rbdp = WL_READ_2(sc, PIOP0)) == I82586NULL)
- break;
- }
- WL_WRITE_2(sc, PIOP0, 0);
- WL_WRITE_2(sc, PIOR0, l_rbdp + 2); /* next_rbd_offset */
- WL_WRITE_2(sc, PIOP0, I82586NULL);
- WL_WRITE_2(sc, PIOR0, l_rbdp + 8); /* address of size */
- WL_WRITE_2(sc, PIOP0, WL_READ_2(sc, PIOP0) | AC_CW_EL);
- WL_WRITE_2(sc, PIOR0, sc->end_rbd + 2);
- WL_WRITE_2(sc, PIOP0, f_rbdp); /* end_rbd->next_rbd_offset */
- WL_WRITE_2(sc, PIOR0, sc->end_rbd + 8); /* size */
- WL_WRITE_2(sc, PIOP0, WL_READ_2(sc, PIOP0) & ~AC_CW_EL);
- sc->end_rbd = l_rbdp;
- }
-
- fd.status = 0;
- fd.command = AC_CW_EL;
- fd.link_offset = I82586NULL;
- fd.rbd_offset = I82586NULL;
- WL_WRITE_2(sc, PIOR1, fd_p);
- WL_WRITE_MULTI_2(sc, PIOP1, &fd, 8/2);
-
- WL_WRITE_2(sc, PIOR1, sc->end_fd + 2); /* addr of command */
- WL_WRITE_2(sc, PIOP1, 0); /* command = 0 */
- WL_WRITE_2(sc, PIOP1, fd_p); /* end_fd->link_offset = fd_p */
- sc->end_fd = fd_p;
-
- return 1;
-}
-
-#ifdef WLDEBUG
-static int xmt_debug = 0;
-#endif /* WLDEBUG */
-
-/*
- * wlxmt:
- *
- * This routine fills in the appropriate registers and memory
- * locations on the WaveLAN board and starts the board off on
- * the transmit.
- *
- * input : pointers to board of interest's softc and the mbuf
- * output : board memory and registers are set for xfer and attention
- *
- */
-static void
-wlxmt(struct wl_softc *sc, struct mbuf *m)
-{
- u_short xmtdata_p = OFFSET_TBUF;
- u_short xmtshort_p;
- struct mbuf *tm_p = m;
- struct ether_header *eh_p = mtod(m, struct ether_header *);
- u_char *mb_p = mtod(m, u_char *) + sizeof(struct ether_header);
- u_short count = m->m_len - sizeof(struct ether_header);
- ac_t cb;
- u_short tbd_p = OFFSET_TBD;
- u_short len, clen = 0;
- int spin;
-
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(sc->ifp, "entered wlxmt()\n");
-#endif
-
- cb.ac_status = 0;
- cb.ac_command = (AC_CW_EL|AC_TRANSMIT|AC_CW_I);
- cb.ac_link_offset = I82586NULL;
- WL_WRITE_2(sc, PIOR1, OFFSET_CU);
- WL_WRITE_MULTI_2(sc, PIOP1, &cb, 6/2);
- WL_WRITE_2(sc, PIOP1, OFFSET_TBD); /* cb.cmd.transmit.tbd_offset */
- WL_WRITE_MULTI_2(sc, PIOP1, eh_p->ether_dhost, WAVELAN_ADDR_SIZE/2);
- WL_WRITE_2(sc, PIOP1, eh_p->ether_type);
-
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG) {
- if (xmt_debug) {
- printf("XMT mbuf: L%d @%p ", count, (void *)mb_p);
- printf("ether type %x\n", eh_p->ether_type);
- }
- }
-#endif /* WLDEBUG */
- WL_WRITE_2(sc, PIOR0, OFFSET_TBD);
- WL_WRITE_2(sc, PIOP0, 0); /* act_count */
- WL_WRITE_2(sc, PIOR1, OFFSET_TBD + 4);
- WL_WRITE_2(sc, PIOP1, xmtdata_p); /* buffer_addr */
- WL_WRITE_2(sc, PIOP1, 0); /* buffer_base */
- for (;;) {
- if (count) {
- if (clen + count > WAVELAN_MTU)
- break;
- if (count & 1)
- len = count + 1;
- else
- len = count;
- WL_WRITE_2(sc, PIOR1, xmtdata_p);
- WL_WRITE_MULTI_2(sc, PIOP1, mb_p, len/2);
- clen += count;
- WL_WRITE_2(sc, PIOR0, tbd_p); /* address of act_count */
- WL_WRITE_2(sc, PIOP0, WL_READ_2(sc, PIOP0) + count);
- xmtdata_p += len;
- if ((tm_p = tm_p->m_next) == (struct mbuf *)0)
- break;
- if (count & 1) {
- /* go to the next descriptor */
- WL_WRITE_2(sc, PIOR0, tbd_p + 2);
- tbd_p += sizeof (tbd_t);
- WL_WRITE_2(sc, PIOP0, tbd_p); /* next_tbd_offset */
- WL_WRITE_2(sc, PIOR0, tbd_p);
- WL_WRITE_2(sc, PIOP0, 0); /* act_count */
- WL_WRITE_2(sc, PIOR1, tbd_p + 4);
- WL_WRITE_2(sc, PIOP1, xmtdata_p); /* buffer_addr */
- WL_WRITE_2(sc, PIOP1, 0); /* buffer_base */
- /* at the end -> coallesce remaining mbufs */
- if (tbd_p == OFFSET_TBD + (N_TBD-1) * sizeof (tbd_t)) {
- wlsftwsleaze(&count, &mb_p, &tm_p, sc);
- continue;
- }
- /* next mbuf short -> coallesce as needed */
- if ( (tm_p->m_next == (struct mbuf *) 0) ||
-#define HDW_THRESHOLD 55
- tm_p->m_len > HDW_THRESHOLD)
- /* ok */;
- else {
- wlhdwsleaze(&count, &mb_p, &tm_p, sc);
- continue;
- }
- }
- } else if ((tm_p = tm_p->m_next) == (struct mbuf *)0)
- break;
- count = tm_p->m_len;
- mb_p = mtod(tm_p, u_char *);
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if (xmt_debug)
- printf("mbuf+ L%d @%p ", count, (void *)mb_p);
-#endif /* WLDEBUG */
- }
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if (xmt_debug)
- printf("CLEN = %d\n", clen);
-#endif /* WLDEBUG */
- WL_WRITE_2(sc, PIOR0, tbd_p);
- if (clen < ETHERMIN) {
- WL_WRITE_2(sc, PIOP0, WL_READ_2(sc, PIOP0) + ETHERMIN - clen);
- WL_WRITE_2(sc, PIOR1, xmtdata_p);
- for (xmtshort_p = xmtdata_p; clen < ETHERMIN; clen += 2)
- WL_WRITE_2(sc, PIOP1, 0);
- }
- WL_WRITE_2(sc, PIOP0, WL_READ_2(sc, PIOP0) | TBD_SW_EOF);
- WL_WRITE_2(sc, PIOR0, tbd_p + 2);
- WL_WRITE_2(sc, PIOP0, I82586NULL);
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG) {
- if (xmt_debug) {
- wltbd(sc);
- printf("\n");
- }
- }
-#endif /* WLDEBUG */
-
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 2); /* address of scb_command */
- /*
- * wait for 586 to clear previous command, complain if it takes
- * too long
- */
- for (spin = 1;;spin = (spin + 1) % 10000) {
- if (WL_READ_2(sc, PIOP0) == 0) { /* it's done, we can go */
- break;
- }
- if ((spin == 0) && xmt_watch) { /* not waking up, and we care */
- if_printf(sc->ifp, "slow accepting xmit\n");
- }
- }
- WL_WRITE_2(sc, PIOP0, SCB_CU_STRT); /* new command */
- SET_CHAN_ATTN(sc);
-
- m_freem(m);
-
- /* XXX
- * Pause to avoid transmit overrun problems.
- * The required delay tends to vary with platform type, and may be
- * related to interrupt loss.
- */
- if (wl_xmit_delay) {
- DELAY(wl_xmit_delay);
- }
- return;
-}
-
-/*
- * wlbldru:
- *
- * This function builds the linear linked lists of fd's and
- * rbd's. Based on page 4-32 of 1986 Intel microcom handbook.
- *
- */
-static u_short
-wlbldru(struct wl_softc *sc)
-{
- fd_t fd;
- rbd_t rbd;
- u_short fd_p = OFFSET_RU;
- u_short rbd_p = OFFSET_RBD;
- int i;
-
- sc->begin_fd = fd_p;
- for (i = 0; i < N_FD; i++) {
- fd.status = 0;
- fd.command = 0;
- fd.link_offset = fd_p + sizeof(fd_t);
- fd.rbd_offset = I82586NULL;
- WL_WRITE_2(sc, PIOR1, fd_p);
- WL_WRITE_MULTI_2(sc, PIOP1, &fd, 8/2);
- fd_p = fd.link_offset;
- }
- fd_p -= sizeof(fd_t);
- sc->end_fd = fd_p;
- WL_WRITE_2(sc, PIOR1, fd_p + 2);
- WL_WRITE_2(sc, PIOP1, AC_CW_EL); /* command */
- WL_WRITE_2(sc, PIOP1, I82586NULL); /* link_offset */
- fd_p = OFFSET_RU;
-
- WL_WRITE_2(sc, PIOR0, fd_p + 6); /* address of rbd_offset */
- WL_WRITE_2(sc, PIOP0, rbd_p);
- WL_WRITE_2(sc, PIOR1, rbd_p);
- for (i = 0; i < N_RBD; i++) {
- rbd.status = 0;
- rbd.buffer_addr = rbd_p + sizeof(rbd_t) + 2;
- rbd.buffer_base = 0;
- rbd.size = RCVBUFSIZE;
- if (i != N_RBD-1) {
- rbd_p += sizeof(ru_t);
- rbd.next_rbd_offset = rbd_p;
- } else {
- rbd.next_rbd_offset = I82586NULL;
- rbd.size |= AC_CW_EL;
- sc->end_rbd = rbd_p;
- }
- WL_WRITE_MULTI_2(sc, PIOP1, &rbd, sizeof(rbd_t)/2);
- WL_WRITE_2(sc, PIOR1, rbd_p);
- }
- return sc->begin_fd;
-}
-
-/*
- * wlrustrt:
- *
- * This routine starts the receive unit running. First checks if the
- * board is actually ready, then the board is instructed to receive
- * packets again.
- *
- */
-static void
-wlrustrt(struct wl_softc *sc)
-{
- u_short rfa;
-
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(sc->ifp, "entered wlrustrt()\n");
-#endif
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB);
- if (WL_READ_2(sc, PIOP0) & SCB_RUS_READY){
- printf("wlrustrt: RUS_READY\n");
- return;
- }
-
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 2);
- WL_WRITE_2(sc, PIOP0, SCB_RU_STRT); /* command */
- rfa = wlbldru(sc);
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 6); /* address of scb_rfa_offset */
- WL_WRITE_2(sc, PIOP0, rfa);
-
- SET_CHAN_ATTN(sc);
- return;
-}
-
-/*
- * wldiag:
- *
- * This routine does a 586 op-code number 7, and obtains the
- * diagnose status for the WaveLAN.
- *
- */
-static int
-wldiag(struct wl_softc *sc)
-{
- short status;
-
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(sc->ifp, "entered wldiag()\n");
-#endif
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB);
- status = WL_READ_2(sc, PIOP0);
- if (status & SCB_SW_INT) {
- /* state is 2000 which seems ok
- if_printf(sc->ifp, "diag(): unexpected initial state %\n",
- WL_READ_2(sc, PIOP0));
- */
- wlack(sc);
- }
- WL_WRITE_2(sc, PIOR1, OFFSET_CU);
- WL_WRITE_2(sc, PIOP1, 0); /* ac_status */
- WL_WRITE_2(sc, PIOP1, AC_DIAGNOSE|AC_CW_EL);/* ac_command */
- if (wlcmd(sc, "diag()") == 0)
- return 0;
- WL_WRITE_2(sc, PIOR0, OFFSET_CU);
- if (WL_READ_2(sc, PIOP0) & 0x0800) {
- if_printf(sc->ifp, "i82586 Self Test failed!\n");
- return 0;
- }
- return TRUE;
-}
-
-/*
- * wlconfig:
- *
- * This routine does a standard config of the WaveLAN board.
- *
- */
-static int
-wlconfig(struct wl_softc *sc)
-{
- configure_t configure;
-
-#if MULTICAST
- struct ifmultiaddr *ifma;
- u_char *addrp;
- int cnt = 0;
-#endif /* MULTICAST */
-
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(sc->ifp, "entered wlconfig()\n");
-#endif
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB);
- if (WL_READ_2(sc, PIOP0) & SCB_SW_INT) {
- /*
- if_printf(sc->ifp, "config(): unexpected initial state %x\n",
- WL_READ_2(sc, PIOP0));
- */
- }
- wlack(sc);
-
- WL_WRITE_2(sc, PIOR1, OFFSET_CU);
- WL_WRITE_2(sc, PIOP1, 0); /* ac_status */
- WL_WRITE_2(sc, PIOP1, AC_CONFIGURE|AC_CW_EL); /* ac_command */
-
-/* jrb hack */
- configure.fifolim_bytecnt = 0x080c;
- configure.addrlen_mode = 0x0600;
- configure.linprio_interframe = 0x2060;
- configure.slot_time = 0xf200;
- configure.hardware = 0x0008; /* tx even w/o CD */
- configure.min_frame_len = 0x0040;
-#if 0
- /* This is the configuration block suggested by Marc Meertens
- * <mmeerten@obelix.utrecht.NCR.COM> in an e-mail message to John
- * Ioannidis on 10 Nov 92.
- */
- configure.fifolim_bytecnt = 0x040c;
- configure.addrlen_mode = 0x0600;
- configure.linprio_interframe = 0x2060;
- configure.slot_time = 0xf000;
- configure.hardware = 0x0008; /* tx even w/o CD */
- configure.min_frame_len = 0x0040;
-#else
- /*
- * below is the default board configuration from p2-28 from 586 book
- */
- configure.fifolim_bytecnt = 0x080c;
- configure.addrlen_mode = 0x2600;
- configure.linprio_interframe = 0x7820; /* IFS=120, ACS=2 */
- configure.slot_time = 0xf00c; /* slottime=12 */
- configure.hardware = 0x0008; /* tx even w/o CD */
- configure.min_frame_len = 0x0040;
-#endif
- if (sc->mode & (MOD_PROM | MOD_ENAL))
- configure.hardware |= 1;
- WL_WRITE_2(sc, PIOR1, OFFSET_CU + 6);
- WL_WRITE_MULTI_2(sc, PIOP1, &configure, sizeof(configure_t)/2);
-
- if (wlcmd(sc, "config()-configure") == 0)
- return 0;
-#if MULTICAST
- WL_WRITE_2(sc, PIOR1, OFFSET_CU);
- WL_WRITE_2(sc, PIOP1, 0); /* ac_status */
- WL_WRITE_2(sc, PIOP1, AC_MCSETUP|AC_CW_EL); /* ac_command */
- WL_WRITE_2(sc, PIOR1, OFFSET_CU + 8);
- if_maddr_rlock(sc->ifp);
- TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
-
- addrp = LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
- WL_WRITE_2(sc, PIOP1, addrp[0] + (addrp[1] << 8));
- WL_WRITE_2(sc, PIOP1, addrp[2] + (addrp[3] << 8));
- WL_WRITE_2(sc, PIOP1, addrp[4] + (addrp[5] << 8));
- ++cnt;
- }
- if_maddr_runlock(sc->ifp);
- WL_WRITE_2(sc, PIOR1, OFFSET_CU + 6); /* mc-cnt */
- WL_WRITE_2(sc, PIOP1, cnt * WAVELAN_ADDR_SIZE);
- if (wlcmd(sc, "config()-mcaddress") == 0)
- return 0;
-#endif /* MULTICAST */
-
- WL_WRITE_2(sc, PIOR1, OFFSET_CU);
- WL_WRITE_2(sc, PIOP1, 0); /* ac_status */
- WL_WRITE_2(sc, PIOP1, AC_IASETUP|AC_CW_EL); /* ac_command */
- WL_WRITE_2(sc, PIOR1, OFFSET_CU + 6);
- WL_WRITE_MULTI_2(sc, PIOP1, IF_LLADDR(sc->ifp), WAVELAN_ADDR_SIZE/2);
-
- if (wlcmd(sc, "config()-address") == 0)
- return(0);
-
- wlinitmmc(sc);
-
- return(1);
-}
-
-/*
- * wlcmd:
- *
- * Set channel attention bit and busy wait until command has
- * completed. Then acknowledge the command completion.
- */
-static int
-wlcmd(struct wl_softc *sc, char *str)
-{
- int i;
-
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 2); /* address of scb_command */
- WL_WRITE_2(sc, PIOP0, SCB_CU_STRT);
-
- SET_CHAN_ATTN(sc);
-
- WL_WRITE_2(sc, PIOR0, OFFSET_CU);
- for (i = 0; i < 0xffff; i++)
- if (WL_READ_2(sc, PIOP0) & AC_SW_C)
- break;
- if (i == 0xffff || !(WL_READ_2(sc, PIOP0) & AC_SW_OK)) {
- if_printf(sc->ifp, "%s failed; status = %d, inw = %x, outw = %x\n",
- str, WL_READ_2(sc, PIOP0) & AC_SW_OK, WL_READ_2(sc, PIOP0),
- WL_READ_2(sc, PIOR0));
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB);
- printf("scb_status %x\n", WL_READ_2(sc, PIOP0));
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB+2);
- printf("scb_command %x\n", WL_READ_2(sc, PIOP0));
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB+4);
- printf("scb_cbl %x\n", WL_READ_2(sc, PIOP0));
- WL_WRITE_2(sc, PIOR0, OFFSET_CU+2);
- printf("cu_cmd %x\n", WL_READ_2(sc, PIOP0));
- return(0);
- }
-
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB);
- if ((WL_READ_2(sc, PIOP0) & SCB_SW_INT) &&
- (WL_READ_2(sc, PIOP0) != SCB_SW_CNA)) {
- /*
- if_printf(sc->ifp, "%s: unexpected final state %x\n",
- str, WL_READ_2(sc, PIOP0));
- */
- }
- wlack(sc);
- return(TRUE);
-}
-
-/*
- * wlack: if the 82596 wants attention because it has finished
- * sending or receiving a packet, acknowledge its desire and
- * return bits indicating the kind of attention. wlack() returns
- * these bits so that the caller can service exactly the
- * conditions that wlack() acknowledged.
- */
-static int
-wlack(struct wl_softc *sc)
-{
- int i;
- u_short cmd;
-
- WL_WRITE_2(sc, PIOR1, OFFSET_SCB);
- if (!(cmd = (WL_READ_2(sc, PIOP1) & SCB_SW_INT)))
- return(0);
-#ifdef WLDEBUG
- if (sc->ifp->if_flags & IFF_DEBUG)
- if_printf(sc->ifp, "doing a wlack()\n");
-#endif
- WL_WRITE_2(sc, PIOP1, cmd);
- SET_CHAN_ATTN(sc);
- WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 2); /* address of scb_command */
- for (i = 1000000; WL_READ_2(sc, PIOP0) && (i-- > 0); )
- continue;
- if (i < 1)
- if_printf(sc->ifp, "wlack(): board not accepting command.\n");
- return(cmd);
-}
-
-#ifdef WLDEBUG
-static void
-wltbd(struct wl_softc *sc)
-{
- u_short tbd_p = OFFSET_TBD;
- tbd_t tbd;
- int i = 0;
- int sum = 0;
-
- for (;;) {
- WL_WRITE_2(sc, PIOR1, tbd_p);
- WL_READ_MULTI_2(sc, PIOP1, &tbd, sizeof(tbd_t)/2);
- sum += (tbd.act_count & ~TBD_SW_EOF);
- printf("%d: addr %x, count %d (%d), next %x, base %x\n",
- i++, tbd.buffer_addr,
- (tbd.act_count & ~TBD_SW_EOF), sum,
- tbd.next_tbd_offset, tbd.buffer_base);
- if (tbd.act_count & TBD_SW_EOF)
- break;
- tbd_p = tbd.next_tbd_offset;
- }
-}
-#endif
-
-static void
-wlhdwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp, struct wl_softc *sc)
-{
- struct mbuf *tm_p = *tm_pp;
- u_char *mb_p = *mb_pp;
- u_short count = 0;
- u_char *cp;
- int len;
-
- /*
- * can we get a run that will be coallesced or
- * that terminates before breaking
- */
- do {
- count += tm_p->m_len;
- if (tm_p->m_len & 1)
- break;
- } while ((tm_p = tm_p->m_next) != (struct mbuf *)0);
- if ( (tm_p == (struct mbuf *)0) ||
- count > HDW_THRESHOLD) {
- *countp = (*tm_pp)->m_len;
- *mb_pp = mtod((*tm_pp), u_char *);
- return;
- }
-
- /* we need to copy */
- tm_p = *tm_pp;
- mb_p = *mb_pp;
- count = 0;
- cp = (u_char *) t_packet;
- for (;;) {
- bcopy(mtod(tm_p, u_char *), cp, len = tm_p->m_len);
- count += len;
- if (count > HDW_THRESHOLD)
- break;
- cp += len;
- if (tm_p->m_next == (struct mbuf *)0)
- break;
- tm_p = tm_p->m_next;
- }
- *countp = count;
- *mb_pp = (u_char *) t_packet;
- *tm_pp = tm_p;
- return;
-}
-
-
-static void
-wlsftwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp, struct wl_softc *sc)
-{
- struct mbuf *tm_p = *tm_pp;
- u_short count = 0;
- u_char *cp = (u_char *) t_packet;
- int len;
-
- /* we need to copy */
- for (;;) {
- bcopy(mtod(tm_p, u_char *), cp, len = tm_p->m_len);
- count += len;
- cp += len;
- if (tm_p->m_next == (struct mbuf *)0)
- break;
- tm_p = tm_p->m_next;
- }
-
- *countp = count;
- *mb_pp = (u_char *) t_packet;
- *tm_pp = tm_p;
- return;
-}
-
-static void
-wlmmcstat(struct wl_softc *sc)
-{
- u_short tmp;
-
- device_printf(sc->dev, "DCE_STATUS: 0x%x, ",
- wlmmcread(sc, MMC_DCE_STATUS) & 0x0f);
- tmp = wlmmcread(sc, MMC_CORRECT_NWID_H) << 8;
- tmp |= wlmmcread(sc, MMC_CORRECT_NWID_L);
- printf("Correct NWID's: %d, ", tmp);
- tmp = wlmmcread(sc, MMC_WRONG_NWID_H) << 8;
- tmp |= wlmmcread(sc, MMC_WRONG_NWID_L);
- printf("Wrong NWID's: %d\n", tmp);
- printf("THR_PRE_SET: 0x%x, ", wlmmcread(sc, MMC_THR_PRE_SET));
- printf("SIGNAL_LVL: %d, SILENCE_LVL: %d\n",
- wlmmcread(sc, MMC_SIGNAL_LVL),
- wlmmcread(sc, MMC_SILENCE_LVL));
- printf("SIGN_QUAL: 0x%x, NETW_ID: %x:%x, DES: %d\n",
- wlmmcread(sc, MMC_SIGN_QUAL),
- wlmmcread(sc, MMC_NETW_ID_H),
- wlmmcread(sc, MMC_NETW_ID_L),
- wlmmcread(sc, MMC_DES_AVAIL));
-}
-
-static u_short
-wlmmcread(struct wl_softc *sc, u_short reg)
-{
- while (WL_READ_2(sc, HASR) & HASR_MMC_BUSY)
- continue;
- WL_WRITE_2(sc, MMCR,reg << 1);
- while (WL_READ_2(sc, HASR) & HASR_MMC_BUSY)
- continue;
- return (u_short)WL_READ_2(sc, MMCR) >> 8;
-}
-
-static void
-getsnr(struct wl_softc *sc)
-{
- MMC_WRITE(MMC_FREEZE,1);
- /*
- * SNR retrieval procedure :
- *
- * read signal level : wlmmcread(sc, MMC_SIGNAL_LVL);
- * read silence level : wlmmcread(sc, MMC_SILENCE_LVL);
- */
- MMC_WRITE(MMC_FREEZE,0);
- /*
- * SNR is signal:silence ratio.
- */
-}
-
-/*
-** wlgetpsa
-**
-** Reads the psa for the wavelan at (sc) into (buf)
-*/
-static void
-wlgetpsa(struct wl_softc *sc, u_char *buf)
-{
- int i;
-
- PCMD(sc, HACR_DEFAULT & ~HACR_16BITS);
- PCMD(sc, HACR_DEFAULT & ~HACR_16BITS);
-
- for (i = 0; i < 0x40; i++) {
- WL_WRITE_2(sc, PIOR2, i);
- buf[i] = WL_READ_1(sc, PIOP2);
- }
- PCMD(sc, HACR_DEFAULT);
- PCMD(sc, HACR_DEFAULT);
-}
-
-/*
-** wlsetpsa
-**
-** Writes the psa for wavelan (unit) from the softc back to the
-** board. Updates the CRC and sets the CRC OK flag.
-**
-** Do not call this when the board is operating, as it doesn't
-** preserve the hacr.
-*/
-static void
-wlsetpsa(struct wl_softc *sc)
-{
- int i;
- u_short crc;
-
- crc = wlpsacrc(sc->psa); /* calculate CRC of PSA */
- sc->psa[WLPSA_CRCLOW] = crc & 0xff;
- sc->psa[WLPSA_CRCHIGH] = (crc >> 8) & 0xff;
- sc->psa[WLPSA_CRCOK] = 0x55; /* default to 'bad' until programming complete */
-
- PCMD(sc, HACR_DEFAULT & ~HACR_16BITS);
- PCMD(sc, HACR_DEFAULT & ~HACR_16BITS);
-
- for (i = 0; i < 0x40; i++) {
- DELAY(DELAYCONST);
- WL_WRITE_2(sc, PIOR2, i); /* write param memory */
- DELAY(DELAYCONST);
- WL_WRITE_1(sc, PIOP2, sc->psa[i]);
- }
- DELAY(DELAYCONST);
- WL_WRITE_2(sc, PIOR2, WLPSA_CRCOK); /* update CRC flag*/
- DELAY(DELAYCONST);
- sc->psa[WLPSA_CRCOK] = 0xaa; /* OK now */
- WL_WRITE_1(sc, PIOP2, 0xaa); /* all OK */
- DELAY(DELAYCONST);
-
- PCMD(sc, HACR_DEFAULT);
- PCMD(sc, HACR_DEFAULT);
-}
-
-/*
-** CRC routine provided by Christopher Giordano <cgiordan@gdeb.com>,
-** from original code by Tomi Mikkonen (tomitm@remedy.fi)
-*/
-
-static u_int crc16_table[16] = {
- 0x0000, 0xCC01, 0xD801, 0x1400,
- 0xF001, 0x3C00, 0x2800, 0xE401,
- 0xA001, 0x6C00, 0x7800, 0xB401,
- 0x5000, 0x9C01, 0x8801, 0x4400
-};
-
-static u_short
-wlpsacrc(u_char *buf)
-{
- u_short crc = 0;
- int i, r1;
-
- for (i = 0; i < 0x3d; i++, buf++) {
- /* lower 4 bits */
- r1 = crc16_table[crc & 0xF];
- crc = (crc >> 4) & 0x0FFF;
- crc = crc ^ r1 ^ crc16_table[*buf & 0xF];
-
- /* upper 4 bits */
- r1 = crc16_table[crc & 0xF];
- crc = (crc >> 4) & 0x0FFF;
- crc = crc ^ r1 ^ crc16_table[(*buf >> 4) & 0xF];
- }
- return(crc);
-}
-#ifdef WLCACHE
-
-/*
- * wl_cache_store
- *
- * take input packet and cache various radio hw characteristics
- * indexed by MAC address.
- *
- * Some things to think about:
- * note that no space is malloced.
- * We might hash the mac address if the cache were bigger.
- * It is not clear that the cache is big enough.
- * It is also not clear how big it should be.
- * The cache is IP-specific. We don't care about that as
- * we want it to be IP-specific.
- * The last N recv. packets are saved. This will tend
- * to reward agents and mobile hosts that beacon.
- * That is probably fine for mobile ip.
- */
-
-/* globals for wavelan signal strength cache */
-/* this should go into softc structure above.
-*/
-
-/* set true if you want to limit cache items to broadcast/mcast
- * only packets (not unicast)
- */
-static int wl_cache_mcastonly = 1;
-SYSCTL_INT(_machdep, OID_AUTO, wl_cache_mcastonly, CTLFLAG_RW,
- &wl_cache_mcastonly, 0, "");
-
-/* set true if you want to limit cache items to IP packets only
-*/
-static int wl_cache_iponly = 1;
-SYSCTL_INT(_machdep, OID_AUTO, wl_cache_iponly, CTLFLAG_RW,
- &wl_cache_iponly, 0, "");
-
-/* zero out the cache
-*/
-static void
-wl_cache_zero(struct wl_softc *sc)
-{
-
- bzero(&sc->w_sigcache[0], sizeof(struct w_sigcache) * MAXCACHEITEMS);
- sc->w_sigitems = 0;
- sc->w_nextcache = 0;
- sc->w_wrapindex = 0;
-}
-
-/* store hw signal info in cache.
- * index is MAC address, but an ip src gets stored too
- * There are two filters here controllable via sysctl:
- * throw out unicast (on by default, but can be turned off)
- * throw out non-ip (on by default, but can be turned off)
- */
-static
-void wl_cache_store (struct wl_softc *sc, struct ether_header *eh,
- struct mbuf *m)
-{
-#ifdef INET
- struct ip *ip = NULL; /* Avoid GCC warning */
- int i;
- int signal, silence;
- int w_insertcache; /* computed index for cache entry storage */
- int ipflag = wl_cache_iponly;
-#endif
-
- /* filters:
- * 1. ip only
- * 2. configurable filter to throw out unicast packets,
- * keep multicast only.
- */
-
-#ifdef INET
- /* reject if not IP packet
- */
- if ( wl_cache_iponly && (ntohs(eh->ether_type) != 0x800)) {
- return;
- }
-
- /* check if broadcast or multicast packet. we toss
- * unicast packets
- */
- if (wl_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
- return;
- }
-
- /* find the ip header. we want to store the ip_src
- * address. use the mtod macro(in mbuf.h)
- * to typecast m to struct ip *
- */
- if (ipflag) {
- ip = mtod(m, struct ip *);
- }
-
- /* do a linear search for a matching MAC address
- * in the cache table
- * . MAC address is 6 bytes,
- * . var w_nextcache holds total number of entries already cached
- */
- for (i = 0; i < sc->w_nextcache; i++) {
- if (! bcmp(eh->ether_shost, sc->w_sigcache[i].macsrc, 6 )) {
- /* Match!,
- * so we already have this entry,
- * update the data, and LRU age
- */
- break;
- }
- }
-
- /* did we find a matching mac address?
- * if yes, then overwrite a previously existing cache entry
- */
- if (i < sc->w_nextcache ) {
- w_insertcache = i;
- }
- /* else, have a new address entry,so
- * add this new entry,
- * if table full, then we need to replace entry
- */
- else {
-
- /* check for space in cache table
- * note: w_nextcache also holds number of entries
- * added in the cache table
- */
- if ( sc->w_nextcache < MAXCACHEITEMS ) {
- w_insertcache = sc->w_nextcache;
- sc->w_nextcache++;
- sc->w_sigitems = sc->w_nextcache;
- }
- /* no space found, so simply wrap with wrap index
- * and "zap" the next entry
- */
- else {
- if (sc->w_wrapindex == MAXCACHEITEMS) {
- sc->w_wrapindex = 0;
- }
- w_insertcache = sc->w_wrapindex++;
- }
- }
-
- /* invariant: w_insertcache now points at some slot
- * in cache.
- */
- if (w_insertcache < 0 || w_insertcache >= MAXCACHEITEMS) {
- log(LOG_ERR,
- "wl_cache_store, bad index: %d of [0..%d], gross cache error\n",
- w_insertcache, MAXCACHEITEMS);
- return;
- }
-
- /* store items in cache
- * .ipsrc
- * .macsrc
- * .signal (0..63) ,silence (0..63) ,quality (0..15)
- */
- if (ipflag) {
- sc->w_sigcache[w_insertcache].ipsrc = ip->ip_src.s_addr;
- }
- bcopy( eh->ether_shost, sc->w_sigcache[w_insertcache].macsrc, 6);
- signal = sc->w_sigcache[w_insertcache].signal = wlmmcread(sc, MMC_SIGNAL_LVL) & 0x3f;
- silence = sc->w_sigcache[w_insertcache].silence = wlmmcread(sc, MMC_SILENCE_LVL) & 0x3f;
- sc->w_sigcache[w_insertcache].quality = wlmmcread(sc, MMC_SIGN_QUAL) & 0x0f;
- if (signal > 0)
- sc->w_sigcache[w_insertcache].snr =
- signal - silence;
- else
- sc->w_sigcache[w_insertcache].snr = 0;
-#endif /* INET */
-
-}
-#endif /* WLCACHE */
diff --git a/sys/dev/wl/if_wl.h b/sys/dev/wl/if_wl.h
deleted file mode 100644
index 77a24cc12bdf..000000000000
--- a/sys/dev/wl/if_wl.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*-
- * 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 all copyright
- * notices, this list of conditions and the following disclaimer.
- * 2. The names of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-/* Definitions for WaveLAN driver */
-
-#ifndef _IF_WL_H
-#define _IF_WL_H
-
-#define STATUS_TRIES 15000
-
-#define N_FD 100
-#define N_RBD 100
-#define N_TBD 72
-#define RCVBUFSIZE 540
-#define I82586NULL 0xffff
-
-#define DSF_RUNNING 1
-
-#define MOD_ENAL 1
-#define MOD_PROM 2
-
-typedef struct {
- rbd_t r;
- char rbd_pad[2];
- char rbuffer[RCVBUFSIZE];
-} ru_t;
-
-/* Board 64k RAM layout. Offsets from 0x0000 */
-
-#define OFFSET_RU 0x0000 /* 0x64 * fd_t = 0x898 */
-#define OFFSET_RBD 0x0900 /* 0x64 * ru_t = 0xd7a0 */
-#define OFFSET_CU 0xe0a0 /* 0x100 */
-#define OFFSET_TBD 0xe1a0 /* 0x48 * tbd_t = 0x240 */
-#define OFFSET_TBUF 0xe3e0 /* 0x1bfe */
-#define OFFSET_SCB 0xffde /* 0x1 * scb_t = 0x10 */
-#define OFFSET_ISCP 0xffee /* 0x1 * iscp_t = 0x8 */
-#define OFFSET_SCP 0xfff6 /* 0x1 * scp_t = 0xa */
-
-/* WaveLAN host interface definitions */
-
-#define HACR 0x0 /* Host Adapter Command Register */
-#define HASR 0x0 /* Host Adapter Status Register */
-#define MMCR 0x2 /* Modem Management Ctrl Register */
-#define PIOR0 0x4 /* Program I/O Address Register 0 */
-#define PIOP0 0x6 /* Program I/O Port 0 */
-#define PIOR1 0x8 /* Program I/O Address Register 1 */
-#define PIOP1 0xa /* Program I/O Port 1 */
-#define PIOR2 0xc /* Program I/O Address Register 2 */
-#define PIOP2 0xe /* Program I/O Port 2 */
-
-/* Program I/O Mode Register values */
-
-#define STATIC_PIO 0 /* Mode 1: static mode */
-#define AUTOINCR_PIO 1 /* Mode 2: auto increment mode */
-#define AUTODECR_PIO 2 /* Mode 3: auto decrement mode */
-#define PARAM_ACCESS_PIO 3 /* Mode 4: LAN parameter access mode */
-#define PIO_MASK 3 /* register mask */
-#define PIOM(cmd,piono) ((u_short)cmd << 10 << (piono * 2))
-
-/* Host Adapter status register definitions */
-
-#define HASR_INTR 0x0001 /* Interrupt request from 82586 */
-#define HASR_MMC_INTR 0x0002 /* Interrupt request from MMC */
-#define HASR_MMC_BUSY 0x0004 /* MMC busy indication */
-#define HASR_PARA_BUSY 0x0008 /* LAN parameter storage area busy */
-
-/* Host Adapter command register definitions */
-
-#define HACR_RESET 0x0001 /* Reset board */
-#define HACR_CA 0x0002 /* Set Channel Attention for 82586 */
-#define HACR_16BITS 0x0004 /* 1==16 bits operation, 0==8 bits */
-#define HACR_OUT1 0x0008 /* General purpose output pin */
-#define HACR_OUT2 0x0010 /* General purpose output pin */
-#define HACR_MASK_82586 0x0020 /* Mask 82586 interrupts, 1==unmask */
-#define HACR_MASK_MMC 0x0040 /* Mask MMC interrupts, 1==unmask */
-#define HACR_INTR_CLEN 0x0080 /* interrupt status clear enable */
-
-#define HACR_DEFAULT (HACR_OUT1 | HACR_OUT2 | HACR_16BITS | PIOM(STATIC_PIO, 0) | PIOM(AUTOINCR_PIO, 1) | PIOM(PARAM_ACCESS_PIO, 2))
-#define HACR_INTRON (HACR_MASK_82586 | HACR_MASK_MMC | HACR_INTR_CLEN)
-
-#define WL_READ_1(sc, reg) bus_read_1((sc)->res_ioport, (reg))
-#define WL_READ_2(sc, reg) bus_read_2((sc)->res_ioport, (reg))
-#define WL_READ_MULTI_2(sc, reg, buf, len) \
- bus_read_multi_2((sc)->res_ioport, (reg), (uint16_t *)(buf), (len))
-#define WL_WRITE_1(sc, reg, val) \
- bus_write_1((sc)->res_ioport, (reg), (val))
-#define WL_WRITE_2(sc, reg, val) \
- bus_write_2((sc)->res_ioport, (reg), (val))
-#define WL_WRITE_MULTI_2(sc, reg, buf, len) \
- bus_write_multi_2((sc)->res_ioport, (reg), (uint16_t *)(buf), (len))
-
-#define CMD(sc) \
- { \
- WL_WRITE_2(sc, HACR, sc->hacr); \
- /* delay for 50 us, might only be needed sometimes */ \
- DELAY(DELAYCONST); \
- }
-
-/* macro for setting the channel attention bit. No delays here since
- * it is used in critical sections
- */
-#define SET_CHAN_ATTN(sc) \
- { \
- WL_WRITE_2(sc, HACR, sc->hacr | HACR_CA); \
- }
-
-
-#define MMC_WRITE(cmd,val) \
- while (WL_READ_2(sc, HASR) & HASR_MMC_BUSY) ; \
- WL_WRITE_2(sc, MMCR, \
- (u_short)(((u_short)(val) << 8) | ((cmd) << 1) | 1))
-
-#endif /* _IF_WL_H */
-
diff --git a/sys/dev/wl/if_wl_i82586.h b/sys/dev/wl/if_wl_i82586.h
deleted file mode 100644
index fc08adcc5226..000000000000
--- a/sys/dev/wl/if_wl_i82586.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/*-
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- *
- * $FreeBSD$
- */
-/*
- Copyright 1988, 1989 by Olivetti Advanced Technology Center, Inc.,
-Cupertino, California.
-
- All Rights Reserved
-
- Permission to use, copy, modify, and distribute this software and
-its documentation for any purpose and without fee is hereby
-granted, provided that the above copyright notice appears in all
-copies and that both the copyright notice and this permission notice
-appear in supporting documentation, and that the name of Olivetti
-not be used in advertising or publicity pertaining to distribution
-of the software without specific, written prior permission.
-
- OLIVETTI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL OLIVETTI BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
-NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION
-WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-/*
- * Defines for managing the status word of the 82586 cpu. For details see
- * the Intel LAN Component User's Manual starting at p. 2-14.
- *
- */
-
-#define SCB_SW_INT 0xf000
-#define SCB_SW_CX 0x8000 /* CU finished w/ int. bit set */
-#define SCB_SW_FR 0x4000 /* RU finished receiving a frame */
-#define SCB_SW_CNA 0x2000 /* CU left active state */
-#define SCB_SW_RNR 0x1000 /* RU left ready state */
-
-/*
- * Defines for managing the Command Unit Status portion of the 82586
- * System Control Block.
- *
- */
-
-#define SCB_CUS_IDLE 0x0000
-#define SCB_CUS_SUSPND 0x0100
-#define SCB_CUS_ACTV 0x0200
-
-/*
- * Defines for managing the Receive Unit Status portion of the System
- * Control Block.
- *
- */
-
-#define SCB_RUS_IDLE 0x0000
-#define SCB_RUS_SUSPND 0x0010
-#define SCB_RUS_NORESRC 0x0020
-#define SCB_RUS_READY 0x0040
-
-/*
- * Defines that manage portions of the Command Word in the System Control
- * Block of the 82586. Below are the Interrupt Acknowledge Bits and their
- * appropriate masks.
- *
- */
-
-#define SCB_ACK_CX 0x8000
-#define SCB_ACK_FR 0x4000
-#define SCB_ACK_CNA 0x2000
-#define SCB_ACK_RNR 0x1000
-
-/*
- * Defines for managing the Command Unit Control word, and the Receive
- * Unit Control word. The software RESET bit is also defined.
- *
- */
-
-#define SCB_CU_STRT 0x0100
-#define SCB_CU_RSUM 0x0200
-#define SCB_CU_SUSPND 0x0300
-#define SCB_CU_ABRT 0x0400
-
-#define SCB_RESET 0x0080
-
-#define SCB_RU_STRT 0x0010
-#define SCB_RU_RSUM 0x0020
-#define SCB_RU_SUSPND 0x0030
-#define SCB_RU_ABRT 0x0040
-
-
-/*
- * The following define Action Commands for the 82586 chip.
- *
- */
-
-#define AC_NOP 0x00
-#define AC_IASETUP 0x01
-#define AC_CONFIGURE 0x02
-#define AC_MCSETUP 0x03
-#define AC_TRANSMIT 0x04
-#define AC_TDR 0x05
-#define AC_DUMP 0x06
-#define AC_DIAGNOSE 0x07
-
-
-/*
- * Defines for General Format for Action Commands, both Status Words, and
- * Command Words.
- *
- */
-
-#define AC_SW_C 0x8000
-#define AC_SW_B 0x4000
-#define AC_SW_OK 0x2000
-#define AC_SW_A 0x1000
-#define TC_CARRIER 0x0400
-#define TC_CLS 0x0200
-#define TC_DMA 0x0100
-#define TC_DEFER 0x0080
-#define TC_SQE 0x0040
-#define TC_COLLISION 0x0020
-#define AC_CW_EL 0x8000
-#define AC_CW_S 0x4000
-#define AC_CW_I 0x2000
-
-/*
- * Specific defines for the transmit action command.
- *
- */
-
-#define TBD_SW_EOF 0x8000
-#define TBD_SW_COUNT 0x3fff
-
-/*
- * Specific defines for the receive frame actions.
- *
- */
-
-#define RBD_SW_EOF 0x8000
-#define RBD_SW_COUNT 0x3fff
-
-#define RFD_DONE 0x8000
-#define RFD_BUSY 0x4000
-#define RFD_OK 0x2000
-#define RFD_CRC 0x0800
-#define RFD_ALN 0x0400
-#define RFD_RSC 0x0200
-#define RFD_DMA 0x0100
-#define RFD_SHORT 0x0080
-#define RFD_EOF 0x0040
-#define RFD_EL 0x8000
-#define RFD_SUSP 0x4000
-/*
- * 82586 chip specific structure definitions. For details, see the Intel
- * LAN Components manual.
- *
- */
-
-
-typedef struct {
- u_short scp_sysbus;
- u_short scp_unused[2];
- u_short scp_iscp;
- u_short scp_iscp_base;
-} scp_t;
-
-
-typedef struct {
- u_short iscp_busy;
- u_short iscp_scb_offset;
- u_short iscp_scb;
- u_short iscp_scb_base;
-} iscp_t;
-
-
-typedef struct {
- u_short scb_status;
- u_short scb_command;
- u_short scb_cbl_offset;
- u_short scb_rfa_offset;
- u_short scb_crcerrs;
- u_short scb_alnerrs;
- u_short scb_rscerrs;
- u_short scb_ovrnerrs;
-} scb_t;
-
-
-typedef struct {
- u_short tbd_offset;
- u_char dest_addr[6];
- u_short length;
-} transmit_t;
-
-
-typedef struct {
- u_short fifolim_bytecnt;
- u_short addrlen_mode;
- u_short linprio_interframe;
- u_short slot_time;
- u_short hardware;
- u_short min_frame_len;
-} configure_t;
-
-
-typedef struct {
- u_short ac_status;
- u_short ac_command;
- u_short ac_link_offset;
- union {
- transmit_t transmit;
- configure_t configure;
- u_char iasetup[6];
- } cmd;
-} ac_t;
-
-
-typedef struct {
- u_short act_count;
- u_short next_tbd_offset;
- u_short buffer_addr;
- u_short buffer_base;
-} tbd_t;
-
-
-typedef struct {
- u_short status;
- u_short command;
- u_short link_offset;
- u_short rbd_offset;
- u_char destination[6];
- u_char source[6];
- u_short length;
-} fd_t;
-
-
-typedef struct {
- u_short status;
- u_short next_rbd_offset;
- u_short buffer_addr;
- u_short buffer_base;
- u_short size;
-} rbd_t;
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index 1c972820922f..632db68576df 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -648,11 +648,6 @@ hint.sbni.0.port="0x210"
hint.sbni.0.irq="0xefdead"
hint.sbni.0.flags="0"
device vmx # VMware VMXNET3 Ethernet
-device wl
-hint.wl.0.at="isa"
-hint.wl.0.port="0x300"
-options WLCACHE # enables the signal-strength cache
-options WLDEBUG # enables verbose debugging output
device wpi # Intel 3945ABG wireless NICs.
# IEEE 802.11 adapter firmware modules
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index c089aa974d0a..7395e7a584b3 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -391,7 +391,6 @@ SUBDIR= \
wb \
${_wbwd} \
${_wi} \
- ${_wl} \
wlan \
wlan_acl \
wlan_amrr \
@@ -728,7 +727,6 @@ _ctau= ctau
.endif
_dpt= dpt
_ex= ex
-_wl= wl
.elif ${MACHINE} == "pc98"
_canbepm= canbepm
_canbus= canbus
diff --git a/sys/modules/wl/Makefile b/sys/modules/wl/Makefile
deleted file mode 100644
index c46891cc0707..000000000000
--- a/sys/modules/wl/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../dev/wl
-
-KMOD= if_wl
-SRCS= if_wl.c
-SRCS+= bus_if.h device_if.h isa_if.h
-SRCS+= opt_inet.h opt_wavelan.h
-
-.include <bsd.kmod.mk>
diff --git a/targets/pseudo/userland/Makefile.depend b/targets/pseudo/userland/Makefile.depend
index e0a404ba38f9..80d05d3cdd19 100644
--- a/targets/pseudo/userland/Makefile.depend
+++ b/targets/pseudo/userland/Makefile.depend
@@ -865,8 +865,7 @@ DIRDEPS.i386= \
usr.sbin/spkrtest \
usr.sbin/zzz \
usr.sbin/acpi \
- usr.sbin/boot0cfg \
- usr.sbin/wlconfig
+ usr.sbin/boot0cfg
DIRDEPS.arm64= \
usr.sbin/acpi \
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index bf452d5a40fb..4edd5f7c2c87 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -8744,9 +8744,6 @@ OLD_FILES+=usr/sbin/hostapd
OLD_FILES+=usr/sbin/hostapd_cli
OLD_FILES+=usr/sbin/ndis_events
OLD_FILES+=usr/sbin/wlandebug
-.if ${TARGET_ARCH} == "i386"
-OLD_FILES+=usr/sbin/wlconfig
-.endif
OLD_FILES+=usr/sbin/wpa_cli
OLD_FILES+=usr/sbin/wpa_passphrase
OLD_FILES+=usr/sbin/wpa_supplicant
@@ -8761,9 +8758,6 @@ OLD_FILES+=usr/share/man/man5/wpa_supplicant.conf.5.gz
OLD_FILES+=usr/share/man/man8/ancontrol.8.gz
OLD_FILES+=usr/share/man/man8/hostapd.8.gz
OLD_FILES+=usr/share/man/man8/hostapd_cli.8.gz
-.if ${TARGET_ARCH} == "i386"
-OLD_FILES+=usr/share/man/man8/i386/wlconfig.8.gz
-.endif
OLD_FILES+=usr/share/man/man8/ndis_events.8.gz
OLD_FILES+=usr/share/man/man8/wlandebug.8.gz
OLD_FILES+=usr/share/man/man8/wpa_cli.8.gz
diff --git a/tools/kerneldoc/subsys/Doxyfile-dev_wl b/tools/kerneldoc/subsys/Doxyfile-dev_wl
deleted file mode 100644
index 2203b594652c..000000000000
--- a/tools/kerneldoc/subsys/Doxyfile-dev_wl
+++ /dev/null
@@ -1,21 +0,0 @@
-# Doxyfile 1.5.2
-
-# $FreeBSD$
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-PROJECT_NAME = "FreeBSD kernel WL device code"
-OUTPUT_DIRECTORY = $(DOXYGEN_DEST_PATH)/dev_wl/
-EXTRACT_ALL = YES # for undocumented src, no warnings enabled
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-INPUT = $(DOXYGEN_SRC_PATH)/dev/wl/ \
- $(NOTREVIEWED)
-
-GENERATE_TAGFILE = dev_wl/dev_wl.tag
-
-@INCLUDE_PATH = $(DOXYGEN_INCLUDE_PATH)
-@INCLUDE = common-Doxyfile
-
diff --git a/usr.sbin/Makefile.i386 b/usr.sbin/Makefile.i386
index c754dc690381..e8a44c4d8d74 100644
--- a/usr.sbin/Makefile.i386
+++ b/usr.sbin/Makefile.i386
@@ -29,9 +29,6 @@ SUBDIR+= boot0cfg
.if ${MK_HYPERV} != "no"
SUBDIR+= hyperv
.endif
-.if ${MK_WIRELESS} != "no"
-SUBDIR+= wlconfig
-.endif
.elif ${MACHINE} == "pc98"
SUBDIR+= boot98cfg
.endif
diff --git a/usr.sbin/wlconfig/Makefile b/usr.sbin/wlconfig/Makefile
deleted file mode 100644
index 8bc62629a0d8..000000000000
--- a/usr.sbin/wlconfig/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD$
-
-PROG= wlconfig
-MAN= wlconfig.8
-MANSUBDIR= /i386
-
-WARNS?= 2
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/wlconfig/Makefile.depend b/usr.sbin/wlconfig/Makefile.depend
deleted file mode 100644
index 79eb58b4a779..000000000000
--- a/usr.sbin/wlconfig/Makefile.depend
+++ /dev/null
@@ -1,16 +0,0 @@
-# $FreeBSD$
-# Autogenerated - do NOT edit!
-
-DIRDEPS = \
- gnu/lib/libgcc \
- include \
- include/xlocale \
- lib/${CSU_DIR} \
- lib/libc \
-
-
-.include <dirdeps.mk>
-
-.if ${DEP_RELDIR} == ${_DEP_RELDIR}
-# local dependencies - needed for -jN in clean tree
-.endif
diff --git a/usr.sbin/wlconfig/wlconfig.8 b/usr.sbin/wlconfig/wlconfig.8
deleted file mode 100644
index b4483394d3f0..000000000000
--- a/usr.sbin/wlconfig/wlconfig.8
+++ /dev/null
@@ -1,143 +0,0 @@
-.\" $FreeBSD$
-.\"
-.Dd December 26, 1996
-.Dt WLCONFIG 8 i386
-.Os
-.Sh NAME
-.Nm wlconfig
-.Nd read/write wavelan config parameters
-.Sh SYNOPSIS
-.Nm
-.Ar ifname
-.Op Ar param value ...
-.Sh DESCRIPTION
-The
-.Nm
-utility can be used to read and set parameters for the NCR/AT&T Wavelan
-radio LAN card.
-Various parameters stored in the non-volatile Parameter
-Storage Area (PSA) on the card can be modified with this program, replacing
-the DOS-based
-.Nm instconf.exe
-program.
-It can also be used to interrogate the optional signal
-strength cache which may have been compiled into the driver.
-.Pp
-The
-.Ar ifname
-parameter specifies the wavelan interface name (eg.
-.Pa wl0 ) .
-If no other arguments are supplied, the current contents of the PSA
-are interpreted and displayed.
-.Pp
-The
-.Ar param
-and
-.Ar value
-arguments can be used to change the value of several parameters.
-Any number of
-.Ar param value
-pairs may be supplied.
-.Bl -tag -width 15n -offset indent
-.It Va param
-.Va value
-.It irq
-IRQ value (used at next reset), may be one of 3,4,5,6,10,11,12,15.
-.It mac
-Local MAC value (ethernet address).
-.It macsel
-.Sq soft
-(as set by the
-.Sq mac
-parameter) or
-.Sq default
-(as set at the factory).
-.It nwid
-The NWID is a 2-byte parameter passed to the card's radio modem.
-NWIDs allow multiple logically discrete networks to operate
-independently whilst occupying the same airspace.
-Packets with a different NWID are simply ignored by the modem.
-In the hardware, NWIDs are stored long-term in non-volatile memory
-(called the PSA or programmable storage area), and are loaded by
-software into the radio modem when the driver is
-initialized.
-This sets the default NWID loaded at startup.
-.It currnwid
-This sets the current operating NWID (but does not save it to the
-PSA).
-.It cache
-The driver may maintain a per interface fixed size cache of signal strength,
-silence, and quality levels, which are indexed by sender MAC addresses.
-Input packets are stored in the cache, and when received, the values
-stored in the radio modem are interrogated and stored.
-There are also two sysctl values (iponly and multicast only) which
-can be used for filtering out some input packets.
-By default, the
-cache mechanism stores only non-unicast IP packets, but this can
-be changed with
-.Xr sysctl 8 .
-Each non-filtered
-input packet causes a cache update, hence one can monitor
-the antennae signal strength to a remote system.
-There are three commands that can be given as values:
-.Sq raw ,
-which prints out the raw signal strength data as found in the radio
-modem hardware value,
-.Sq scale ,
-which scales the raw hardware values to 0..100%, and
-.Sq zero
-which clears out the cache in case you want to store new samples.
-.El
-.Pp
-Note that if the IRQ on the Wavelan card is incorrect, the interface
-will be configured, but will not function.
-The
-.Nm
-utility should then be used to reconfigure the card to a sensible
-value.
-.Sh EXAMPLES
-Set the NWID to 0x1234:
-.Bd -literal -offset indent
-# wlconfig wl0 nwid 0x1234
-.Ed
-.Pp
-Show the current settings:
-.Bd -literal -offset indent
-# wlconfig wl0
-Board type : ISA
-Base address options : 0x300, 0x390, 0x3c0, 0x3e0
-Waitstates : 0
-Bus mode : ISA
-IRQ : 10
-Default MAC address : 08:00:0e:20:3d:4b
-Soft MAC address : 00:00:00:00:00:00
-Current MAC address : Default
-Adapter compatibility : PC-AT 2.4GHz
-Threshold preset : 1
-Call code required : NO
-Subband : 2425MHz
-Quality threshold : 3
-Hardware version : 0 (Rel1/Rel2)
-Network ID enable : YES
-NWID : 0xdead
-Datalink security : NO
-Databus width : 16 (variable)
-Configuration state : unconfigured
-CRC-16 : 0x3c26
-CRC status : OK
-.Ed
-.Pp
-Print a scaled version of the signal strength cache:
-.Bd -literal -offset indent
-# wlconfig wl0 cache scale
-.Ed
-.Sh SEE ALSO
-.Xr wl 4 ,
-.Xr sysctl 8
-.Sh HISTORY
-This implementation of the
-.Nm
-utility is completely new, written for Hilink Internet by
-.An Michael Smith ,
-and updated by
-.An Jim Binkley &c .
diff --git a/usr.sbin/wlconfig/wlconfig.c b/usr.sbin/wlconfig/wlconfig.c
deleted file mode 100644
index f361b2cb99fb..000000000000
--- a/usr.sbin/wlconfig/wlconfig.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Copyright (C) 1996
- * Michael Smith. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY Michael Smith 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 Michael Smith 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.
- */
-
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-/*
- * wlconfig.c
- *
- * utility to read out and change various WAVELAN parameters.
- * Currently supports NWID and IRQ values.
- *
- * The NWID is used by 2 or more wavelan controllers to determine
- * if packets should be received or not. It is a filter that
- * is roughly analogous to the "channel" setting with a garage
- * door controller. Two companies side by side with wavelan devices
- * that could actually hear each other can use different NWIDs
- * and ignore packets. In truth however, the air space is shared,
- * and the NWID is a virtual filter.
- *
- * In the current set of wavelan drivers, ioctls changed only
- * the runtime radio modem registers which act in a manner analogous
- * to an ethernet transceiver. The ioctls do not change the
- * stored nvram PSA (or parameter storage area). At boot, the PSA
- * values are stored in the radio modem. Thus when the
- * system reboots it will restore the wavelan NWID to the value
- * stored in the PSA. The NCR/ATT dos utilities must be used to
- * change the initial NWID values in the PSA. The wlconfig utility
- * may be used to set a different NWID at runtime; this is only
- * permitted while the interface is up and running.
- *
- * By contrast, the IRQ value can only be changed while the
- * Wavelan card is down and unconfigured, and it will remain
- * disabled after an IRQ change until reboot.
- *
- */
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <machine/if_wl_wavelan.h>
-
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <limits.h>
-
-/* translate IRQ bit to number */
-/* array for maping irq numbers to values for the irq parameter register */
-static int irqvals[16] = {
- 0, 0, 0, 0x01, 0x02, 0x04, 0, 0x08, 0, 0, 0x10, 0x20, 0x40, 0, 0, 0x80
-};
-
-/* cache */
-static int w_sigitems; /* count of valid items */
-static struct w_sigcache wsc[MAXCACHEITEMS];
-
-int
-wlirq(int irqval)
-{
- int irq;
-
- for(irq = 0; irq < 16; irq++)
- if(irqvals[irq] == irqval)
- return(irq);
- return 0;
-}
-
-char *compat_type[] = {
- "PC-AT 915MHz",
- "PC-MC 915MHz",
- "PC-AT 2.4GHz",
- "PC-MC 2.4GHz",
- "PCCARD or 1/2 size AT, 915MHz or 2.4GHz"
-};
-
-char *subband[] = {
- "915MHz/see WaveModem",
- "2425MHz",
- "2460MHz",
- "2484MHz",
- "2430.5MHz"
-};
-
-
-/*
-** print_psa
-**
-** Given a pointer to a PSA structure, print it out
-*/
-void
-print_psa(u_char *psa, int currnwid)
-{
- int nwid;
-
- /*
- ** Work out what sort of board we have
- */
- if (psa[0] == 0x14) {
- printf("Board type : Microchannel\n");
- } else {
- if (psa[1] == 0) {
- printf("Board type : PCCARD\n");
- } else {
- printf("Board type : ISA");
- if ((psa[4] == 0) &&
- (psa[5] == 0) &&
- (psa[6] == 0))
- printf(" (DEC OEM)");
- printf("\n");
- printf("Base address options : 0x300, 0x%02x0, 0x%02x0, 0x%02x0\n",
- (int)psa[1], (int)psa[2], (int)psa[3]);
- printf("Waitstates : %d\n",psa[7] & 0xf);
- printf("Bus mode : %s\n",(psa[7] & 0x10) ? "EISA" : "ISA");
- printf("IRQ : %d\n",wlirq(psa[8]));
- }
- }
- printf("Default MAC address : %02x:%02x:%02x:%02x:%02x:%02x\n",
- psa[0x10],psa[0x11],psa[0x12],psa[0x13],psa[0x14],psa[0x15]);
- printf("Soft MAC address : %02x:%02x:%02x:%02x:%02x:%02x\n",
- psa[0x16],psa[0x17],psa[0x18],psa[0x19],psa[0x1a],psa[0x1b]);
- printf("Current MAC address : %s\n",(psa[0x1c] & 0x1) ? "Soft" : "Default");
- printf("Adapter compatibility : ");
- if (psa[0x1d] < 5) {
- printf("%s\n",compat_type[psa[0x1d]]);
- } else {
- printf("unknown\n");
- }
- printf("Threshold preset : %d\n",psa[0x1e]);
- printf("Call code required : %s\n",(psa[0x1f] & 0x1) ? "YES" : "NO");
- if (psa[0x1f] & 0x1)
- printf("Call code : 0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
- psa[0x30],psa[0x31],psa[0x32],psa[0x33],psa[0x34],psa[0x35],psa[0x36],psa[0x37]);
- printf("Subband : %s\n",subband[psa[0x20] & 0xf]);
- printf("Quality threshold : %d\n",psa[0x21]);
- printf("Hardware version : %d (%s)\n",psa[0x22],psa[0x22] ? "Rel3" : "Rel1/Rel2");
- printf("Network ID enable : %s\n",(psa[0x25] & 0x1) ? "YES" : "NO");
- if (psa[0x25] & 0x1) {
- nwid = (psa[0x23] << 8) + psa[0x24];
- printf("NWID : 0x%04x\n",nwid);
- if (nwid != currnwid) {
- printf("Current NWID : 0x%04x\n",currnwid);
- }
- }
- printf("Datalink security : %s\n",(psa[0x26] & 0x1) ? "YES" : "NO");
- if (psa[0x26] & 0x1) {
- printf("Encryption key : ");
- if (psa[0x27] == 0) {
- printf("DENIED\n");
- } else {
- printf("0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
- psa[0x27],psa[0x28],psa[0x29],psa[0x2a],psa[0x2b],psa[0x2c],psa[0x2d],psa[0x2e]);
- }
- }
- printf("Databus width : %d (%s)\n",
- (psa[0x2f] & 0x1) ? 16 : 8, (psa[0x2f] & 0x80) ? "fixed" : "variable");
- printf("Configuration state : %sconfigured\n",(psa[0x38] & 0x1) ? "" : "un");
- printf("CRC-16 : 0x%02x%02x\n",psa[0x3e],psa[0x3d]);
- printf("CRC status : ");
- switch(psa[0x3f]) {
- case 0xaa:
- printf("OK\n");
- break;
- case 0x55:
- printf("BAD\n");
- break;
- default:
- printf("Error\n");
- break;
- }
-}
-
-
-static void
-usage()
-{
- fprintf(stderr,"usage: wlconfig ifname [param value ...]\n");
- exit(1);
-}
-
-
-void
-get_cache(int sd, struct ifreq *ifr)
-{
- /* get the cache count */
- if (ioctl(sd, SIOCGWLCITEM, (caddr_t)ifr))
- err(1, "SIOCGWLCITEM - get cache count");
- w_sigitems = (int) ifr->ifr_data;
-
- ifr->ifr_data = (caddr_t) &wsc;
- /* get the cache */
- if (ioctl(sd, SIOCGWLCACHE, (caddr_t)ifr))
- err(1, "SIOCGWLCACHE - get cache count");
-}
-
-static int
-scale_value(int value, int max)
-{
- double dmax = (double) max;
- if (value > max)
- return(100);
- return((value/dmax) * 100);
-}
-
-static void
-dump_cache(int rawFlag)
-{
- int i;
- int signal, silence, quality;
-
- if (rawFlag)
- printf("signal range 0..63: silence 0..63: quality 0..15\n");
- else
- printf("signal range 0..100: silence 0..100: quality 0..100\n");
-
- /* after you read it, loop through structure,i.e. wsc
- * print each item:
- */
- for(i = 0; i < w_sigitems; i++) {
- printf("[%d:%d]>\n", i+1, w_sigitems);
- printf("\tip: %d.%d.%d.%d,",((wsc[i].ipsrc >> 0) & 0xff),
- ((wsc[i].ipsrc >> 8) & 0xff),
- ((wsc[i].ipsrc >> 16) & 0xff),
- ((wsc[i].ipsrc >> 24) & 0xff));
- printf(" mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
- wsc[i].macsrc[0]&0xff,
- wsc[i].macsrc[1]&0xff,
- wsc[i].macsrc[2]&0xff,
- wsc[i].macsrc[3]&0xff,
- wsc[i].macsrc[4]&0xff,
- wsc[i].macsrc[5]&0xff);
- if (rawFlag) {
- signal = wsc[i].signal;
- silence = wsc[i].silence;
- quality = wsc[i].quality;
- }
- else {
- signal = scale_value(wsc[i].signal, 63);
- silence = scale_value(wsc[i].silence, 63);
- quality = scale_value(wsc[i].quality, 15);
- }
- printf("\tsignal: %d, silence: %d, quality: %d, ",
- signal,
- silence,
- quality);
- printf("snr: %d\n", signal - silence);
- }
-}
-
-#define raw_cache() dump_cache(1)
-#define scale_cache() dump_cache(0)
-
-int
-main(int argc, char *argv[])
-{
- int sd;
- struct ifreq ifr;
- u_char psabuf[0x40];
- int val, argind, i;
- char *cp, *param, *value;
- struct ether_addr *ea;
- int work = 0;
- int currnwid;
-
- if ((argc < 2) || (argc % 2))
- usage();
-
- /* get a socket */
- sd = socket(AF_INET, SOCK_DGRAM, 0);
- if (sd < 0)
- err(1,"socket");
- strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name));
- ifr.ifr_addr.sa_family = AF_INET;
-
- /* get the PSA */
- ifr.ifr_data = (caddr_t)psabuf;
- if (ioctl(sd, SIOCGWLPSA, (caddr_t)&ifr))
- err(1,"get PSA");
-
- /* get the current NWID */
- if (ioctl(sd, SIOCGWLCNWID, (caddr_t)&ifr))
- err(1,"get NWID");
- currnwid = (int)ifr.ifr_data;
-
- /* just dump and exit? */
- if (argc == 2) {
- print_psa(psabuf, currnwid);
- exit(0);
- }
-
- /* loop reading arg pairs */
- for (argind = 2; argind < argc; argind += 2) {
-
- param = argv[argind];
- value = argv[argind+1];
-
- /* What to do? */
-
- if (!strcasecmp(param,"currnwid")) { /* set current NWID */
- val = strtol(value,&cp,0);
- if ((val < 0) || (val > 0xffff) || (cp == value))
- errx(1,"bad NWID '%s'",value);
-
- ifr.ifr_data = (caddr_t)val;
- if (ioctl(sd, SIOCSWLCNWID, (caddr_t)&ifr))
- err(1,"set NWID (interface not up?)");
- continue ;
- }
-
- if (!strcasecmp(param,"irq")) {
- val = strtol(value,&cp,0);
- val = irqvals[val];
- if ((val == 0) || (cp == value))
- errx(1,"bad IRQ '%s'",value);
- psabuf[WLPSA_IRQNO] = (u_char)val;
- work = 1;
- continue;
- }
-
- if (!strcasecmp(param,"mac")) {
- if ((ea = ether_aton(value)) == NULL)
- errx(1,"bad ethernet address '%s'",value);
- for (i = 0; i < 6; i++)
- psabuf[WLPSA_LOCALMAC + i] = ea->octet[i];
- work = 1;
- continue;
- }
-
- if (!strcasecmp(param,"macsel")) {
- if (!strcasecmp(value,"local")) {
- psabuf[WLPSA_MACSEL] |= 0x1;
- work = 1;
- continue;
- }
- if (!strcasecmp(value,"universal")) {
- psabuf[WLPSA_MACSEL] &= ~0x1;
- work = 1;
- continue;
- }
- errx(1,"bad macsel value '%s'",value);
- }
-
- if (!strcasecmp(param,"nwid")) {
- val = strtol(value,&cp,0);
- if ((val < 0) || (val > 0xffff) || (cp == value))
- errx(1,"bad NWID '%s'",value);
- psabuf[WLPSA_NWID] = (val >> 8) & 0xff;
- psabuf[WLPSA_NWID+1] = val & 0xff;
- work = 1;
- continue;
- }
- if (!strcasecmp(param,"cache")) {
-
- /* raw cache dump
- */
- if (!strcasecmp(value,"raw")) {
- get_cache(sd, &ifr);
- raw_cache();
- continue;
- }
- /* scaled cache dump
- */
- else if (!strcasecmp(value,"scale")) {
- get_cache(sd, &ifr);
- scale_cache();
- continue;
- }
- /* zero out cache
- */
- else if (!strcasecmp(value,"zero")) {
- if (ioctl(sd, SIOCDWLCACHE, (caddr_t)&ifr))
- err(1,"zero cache");
- continue;
- }
- errx(1,"unknown value '%s'", value);
- }
- errx(1,"unknown parameter '%s'",param);
- }
- if (work) {
- ifr.ifr_data = (caddr_t)psabuf;
- if (ioctl(sd, SIOCSWLPSA, (caddr_t)&ifr))
- err(1,"set PSA");
- }
- return(0);
-}