diff options
author | 2008-04-23 13:28:58 +0000 | |
---|---|---|
committer | 2008-04-23 13:28:58 +0000 | |
commit | b43a0bace643314a32425f11e63b77ab24415a0c (patch) | |
tree | af44b4589ea70807a9a906af19bcf4d5ff659d8f | |
parent | unbreak compilationg with option MPLS but without option MPLS_DEBUG (diff) | |
download | wireguard-openbsd-b43a0bace643314a32425f11e63b77ab24415a0c.tar.xz wireguard-openbsd-b43a0bace643314a32425f11e63b77ab24415a0c.zip |
Remove driver for pre 802.11 RangeLAN2 wireless devices.
It doesn't compile, was never finished, is now irrelevant, and miod
has taken it apon himself to scare good boys and girls by suggesting
they read the code.
ok dlg@
-rw-r--r-- | share/man/man4/Makefile | 4 | ||||
-rw-r--r-- | share/man/man4/pcmcia.4 | 6 | ||||
-rw-r--r-- | share/man/man4/rln.4 | 153 | ||||
-rw-r--r-- | sys/conf/files | 7 | ||||
-rw-r--r-- | sys/dev/ic/rln.c | 1224 | ||||
-rw-r--r-- | sys/dev/ic/rln.h | 39 | ||||
-rw-r--r-- | sys/dev/ic/rlncmd.h | 247 | ||||
-rw-r--r-- | sys/dev/ic/rlnreg.h | 283 | ||||
-rw-r--r-- | sys/dev/ic/rlnsubr.c | 941 | ||||
-rw-r--r-- | sys/dev/ic/rlnvar.h | 146 | ||||
-rw-r--r-- | sys/dev/isa/files.isa | 6 | ||||
-rw-r--r-- | sys/dev/isa/if_rln_isa.c | 146 | ||||
-rw-r--r-- | sys/dev/pcmcia/files.pcmcia | 6 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_rln_pcmcia.c | 312 |
14 files changed, 7 insertions, 3513 deletions
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index a88494a762b..77371ee9bb7 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.448 2008/04/22 05:17:20 deraadt Exp $ +# $OpenBSD: Makefile,v 1.449 2008/04/23 13:28:58 jsg Exp $ MAN= aac.4 ac97.4 acphy.4 \ acpi.4 acpiac.4 acpibat.4 acpibtn.4 acpicpu.4 acpidock.4 \ @@ -40,7 +40,7 @@ MAN= aac.4 ac97.4 acphy.4 \ pf.4 pflog.4 pfsync.4 pgt.4 piixpm.4 pim.4 \ pms.4 ppb.4 ppp.4 pppoe.4 pty.4 puc.4 pwdog.4 qsphy.4 radio.4 raid.4 \ ral.4 random.4 ray.4 rd.4 re.4 rgephy.4 ricohrtc.4 \ - rl.4 rln.4 rlphy.4 route.4 rt.4 rum.4 \ + rl.4 rlphy.4 route.4 rt.4 rum.4 \ rtfps.4 rtii.4 rtw.4 safe.4 safte.4 san.4 sbt.4 sbus.4 scsi.4 sd.4 \ sdmmc.4 sdhc.4 ses.4 \ sequencer.4 sf.4 sf2r.4 sfr.4 sili.4 siop.4 sis.4 sk.4 sl.4 sli.4 \ diff --git a/share/man/man4/pcmcia.4 b/share/man/man4/pcmcia.4 index 9500b3fa9b7..29d2b3e732b 100644 --- a/share/man/man4/pcmcia.4 +++ b/share/man/man4/pcmcia.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pcmcia.4,v 1.54 2007/05/31 19:19:51 jmc Exp $ +.\" $OpenBSD: pcmcia.4,v 1.55 2008/04/23 13:28:58 jsg Exp $ .\" $NetBSD: pcmcia.4,v 1.4 1998/06/07 09:10:30 enami Exp $ .\" .\" Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: May 31 2007 $ +.Dd $Mdocdate: April 23 2008 $ .Dt PCMCIA 4 .Os .Sh NAME @@ -93,8 +93,6 @@ serial communications interface 3Com EtherLink III and Fast EtherLink III 10/100 Ethernet device .It Xr ne 4 NE2000 and compatible 10/100 Ethernet device -.It Xr rln 4 -Proxim RangeLAN2 wireless network device .It Xr sm 4 SMC91C9x and SMC91C1xx-based 10/100 Ethernet device .It Xr xe 4 diff --git a/share/man/man4/rln.4 b/share/man/man4/rln.4 deleted file mode 100644 index b0b063f0753..00000000000 --- a/share/man/man4/rln.4 +++ /dev/null @@ -1,153 +0,0 @@ -.\" $OpenBSD: rln.4,v 1.25 2007/05/31 19:19:51 jmc Exp $ -.\" -.\" David Leonard <d@openbsd.org>, 1999. Public Domain. -.\" -.\" Driver for the Proxim RangeLAN2 wireless network adaptor. -.\" -.\" Information and ideas gleaned from disassembly of Dave Koberstein's -.\" <davek@komacke.com> Linux driver (apparently based on Proxim source), -.\" from Yoichi Shinoda's <shinoda@cs.washington.edu> BSDI driver, and -.\" Geoff Voelker's <voelker@cs.washington.edu> Linux port of the same. -.\" -.\" -.Dd $Mdocdate: May 31 2007 $ -.Dt RLN 4 -.Os -.Sh NAME -.Nm rln -.Nd Proxim RangeLAN2 wireless network device -.Sh SYNOPSIS -.Cd "rln0 at isa? port 0x270 flags 0x00" -.\" .Cd "rln* at isapnp? flags 0x00" -.Cd "rln* at pcmcia? flags 0x00" -.Sh DESCRIPTION -The -.Nm -device driver supports at least the following cards: -.Bl -bullet -compact -.It -Proxim RangeLAN2 7100 ISA Card -.\" .It -.\" Proxim RangeLAN2 630x Mini ISA OEM Module -.\" .It -.\" Proxim RangeLAN2 633x Micro design-in module -.It -Symphony PC Cards -.\" .It -.\" Symphony PnP ISA Card -.It -Proxim RangeLAN2 7200 Two Piece PC Card -.It -Proxim RangeLAN2 7400 One Piece PC Card -.It -Digital RoamAbout FH 2400 PC-Card -.It -AMP Wireless PC-Card -.El -.Pp -The Proxim RangeLAN2 air protocol is incompatible with the older -RangeLAN(1) cards, Lucent Technologies' WaveLAN cards, and with -the newer 802.11 cards in general. -.Pp -The RangeLAN2 cards communicate using an Ethernet-like protocol -over the 2.4\(em2.483GHz part of the spectrum. -This frequency happens to coincide with that of strong harmonics emitted -by common consumer microwave ovens. -You can guess the rest. -Depending on the channel condition, the NICs operate in one of two -modes: 1.6Mb/s or 0.8Mb/s signalling rate. -.\" .Sh CONFIGURATION -.\" Because there is no reliable way to determine between -.\" the different types of cards listed above, -.\" the following flags can be specified in the kernel config file: -.\" .Pp -.\" .Bl -tag -offset indent -width 10n -compact -.\" .It RangeLAN2 630x series (Mini ISA) -.\" .Cd flags 1 -.\" .It RangeLAN2 633x series (Micro ISA) -.\" .Cd flags 3 -.\" .It Symphony PnP ISA -.\" .Cd flags 3 -.\" .El -.\" .Pp -.\" Flags can be omitted for devices not listed here, and PC-Card devices. -.Pp -In the event of errors, the card can be reset by using -.Xr ifconfig 8 -to bring the card down, then up. -.Sh MEDIA SELECTION -Not supported. -The medium used by the device is always air. -.Sh DIAGNOSTICS -.Bl -diag -.It "rln0: hardware fault" -The card reported a hardware fault condition. -Check the antenna. -The interface is automatically marked down. -.It "rln0: synchronised to ? (?) channel ?/?" -The card has successfully synchronised with a nearby unit. -Packets are only transmitted when the unit has synchronised with -another. -.It "rln0: lost sync" -Synchronisation was lost. -Check for microwave ovens being used. -.It "rln0: nothing to sync to; now master" -The card was unsuccessful in (re-)synchronising with any other unit, -and was configured as an alternate master. -.It "rln0: packet too big (? > ?)" -The card generated a message bigger than the maximum size allowable for -Ethernet. -.It "rln0: command error 0x?? command ??" -The card reported an error condition in the host-card protocol. -.It "rln0: reset timeout" -An attempt to hard reset the card failed. -This is either a serious hardware fault, or a bus conflict. -.It "rln0: tx_request timed out, status 0x??" -The host-to-card message transfer protocol timed out. -This could mean a duplex transfer is in progress and the interrupt service -routine has not run. -Check the CPU load. -.It "rln0: lost message ?? seq ?" -An expected response to the command did not appear within a reasonable time. -.It "rln0: unknown RangeLAN2 wireless network card" -The card model was not matched in the known-card tables. -.El -.Sh SEE ALSO -.Xr intro 4 , -.Xr isa 4 , -.\" .Xr isapnp 4 , -.Xr netintro 4 , -.Xr pcmcia 4 , -.Xr ifconfig 8 -.Pa http://www.proxim.com/ -.Sh AUTHORS -David Leonard, -Dept Computer Science and Electrical Engineering, University of Queensland -.Aq david.leonard@csee.uq.edu.au . -.Pp -Information and ideas gleaned from disassembly of Dave Koberstein's -.Aq davek@komacke.com -Linux driver (which apparently uses Proxim code), -from Yoichi Shinoda's -.Aq shinoda@cs.washington.edu -BSDI driver, and -Geoff Voelker's -.Aq voelker@cs.washington.edu -Linux port of the same. -.Sh BUGS -This driver has not been tested with lots of cards, so there are bound -to be subtle timing problems with different hardware. -It should also work with the Symphony PC cards. -.Pp -I couldn't figure out how to make roaming work, nor how to interpret -the RSSI link quality values. -.Pp -There is no way to change the channel or security ID on the card, or -to make it a master, except through source code. -This is because it is currently impossible under -.Ox -to trigger such changes through calls to -.Xr ioctl 2 -on the interface. -.Pp -Oh, and transmit doesn't seem to work. diff --git a/sys/conf/files b/sys/conf/files index 5ceb3897e72..fbc9879a964 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.429 2008/04/23 10:55:13 norby Exp $ +# $OpenBSD: files,v 1.430 2008/04/23 13:28:58 jsg Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -246,11 +246,6 @@ file dev/ic/if_wi_hostap.c wi device an: ether, ifnet, ifmedia, wlan file dev/ic/an.c an -# RangeLAN2 -device rln: ether, ifnet -file dev/ic/rln.c rln -file dev/ic/rlnsubr.c rln - # LANCE and PCnet Ethernet controllers device le: ether, ifnet, ifmedia file dev/ic/am7990.c le diff --git a/sys/dev/ic/rln.c b/sys/dev/ic/rln.c deleted file mode 100644 index 5f0820abff2..00000000000 --- a/sys/dev/ic/rln.c +++ /dev/null @@ -1,1224 +0,0 @@ -/* $OpenBSD: rln.c,v 1.18 2006/03/25 22:41:43 djm Exp $ */ -/* - * David Leonard <d@openbsd.org>, 1999. Public Domain. - * - * Driver for the Proxim RangeLAN2 wireless network adaptor. - * - * Information and ideas gleaned from disassembly of Dave Koberstein's - * <davek@komacke.com> Linux driver (apparently based on Proxim source), - * from Yoichi Shinoda's <shinoda@cs.washington.edu> BSDI driver, and - * Geoff Voelker's <voelker@cs.washington.edu> Linux port of the same. - * - */ - -#include "bpfilter.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/mbuf.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <sys/syslog.h> -#include <sys/device.h> -#include <sys/kernel.h> - -#include <net/if.h> -#include <net/if_media.h> - -#ifdef INET -#include <netinet/in.h> -#include <netinet/if_ether.h> -#endif - -#if NBPFILTER > 0 -#include <net/bpf.h> -#endif - -#include <machine/bus.h> -#include <machine/intr.h> - -#include <dev/ic/rln.h> -#include <dev/ic/rlnvar.h> -#include <dev/ic/rlnreg.h> -#include <dev/ic/rlncmd.h> - -/* Autoconfig definition of driver back-end. */ -struct cfdriver rln_cd = { - NULL, "rln", DV_IFNET -}; - -void rlninit(struct rln_softc *); -void rlnstart(struct ifnet*); -void rlnwatchdog(struct ifnet*); -int rlnioctl(struct ifnet *, u_long, caddr_t); -void rlnstop(struct rln_softc *); - -/* Interrupt handler. */ -void rlnsoftintr(void *); - -/* Packet I/O. */ -int rln_transmit(struct rln_softc *, struct mbuf *, - int, int); -struct mbuf * rlnget(struct rln_softc *, struct rln_mm_cmd *, - int); - -/* Card protocol-level functions. */ -int rln_getenaddr(struct rln_softc *, u_int8_t *); -int rln_getpromvers(struct rln_softc *, char *, int); -int rln_sendinit(struct rln_softc *); -#if notyet -int rln_roamconfig(struct rln_softc *); -int rln_roam(struct rln_softc *); -int rln_multicast(struct rln_softc *, int); -int rln_searchsync(struct rln_softc *); -int rln_iosetparam(struct rln_softc *, struct rln_param *); -int rln_lockprom(struct rln_softc *); -int rln_ito(struct rln_softc *); -int rln_standby(struct rln_softc *); -#endif - -/* Back-end attach and configure. Assumes card has been reset. */ -void -rlnconfig(sc) - struct rln_softc * sc; -{ - struct ifnet * ifp = &sc->sc_arpcom.ac_if; - char promvers[7]; - int i; - - dprintf(" [attach %p]", sc); - - /* Use the flags supplied from config. */ - sc->sc_cardtype |= sc->sc_dev.dv_cfdata->cf_flags; - - /* Initialise values in the soft state. */ - sc->sc_pktseq = 0; /* rln_newseq() */ - sc->sc_txseq = 0; - sc->sc_state = 0; - - /* Initialise user-configurable params. */ - sc->sc_param.rp_roam_config = RLN_ROAM_NORMAL; - sc->sc_param.rp_security = RLN_SECURITY_DEFAULT; - sc->sc_param.rp_station_type = RLN_STATIONTYPE_ALTMASTER; - sc->sc_param.rp_domain = 0; - sc->sc_param.rp_channel = 1; - sc->sc_param.rp_subchannel = 1; - - bzero(sc->sc_param.rp_master, sizeof sc->sc_param.rp_master); - - /* Initialise the message mailboxes. */ - for (i = 0; i < RLN_NMBOX; i++) - sc->sc_mbox[i].mb_state = RLNMBOX_VOID; - - /* Probe for some properties. */ - printf(", %s-piece", - (sc->sc_cardtype & RLN_CTYPE_ONE_PIECE) ? "one" : "two"); - if (sc->sc_cardtype & RLN_CTYPE_OEM) - printf(" oem"); - if (sc->sc_cardtype & RLN_CTYPE_UISA) - printf(" micro-isa"); - - /* Read the card's PROM revision. */ - if (rln_getpromvers(sc, promvers, sizeof promvers)) { - printf(": could not read PROM version\n"); - return; - } - printf(", fw %.7s", promvers); - - /* Fetch the card's MAC address. */ - if (rln_getenaddr(sc, sc->sc_arpcom.ac_enaddr)) { - printf(": could not read MAC address\n"); - return; - } - printf(", addr %s", ether_sprintf(sc->sc_arpcom.ac_enaddr)); - - timeout_set(&sc->sc_timeout, rlnsoftintr, sc); - - /* Attach as a network interface. */ - bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); - ifp->if_softc = sc; - ifp->if_start = rlnstart; - ifp->if_ioctl = rlnioctl; - ifp->if_watchdog = rlnwatchdog; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; - IFQ_SET_READY(&ifp->if_snd); - if_attach(ifp); - ether_ifattach(ifp); -} - -/* Bring device up. */ -void -rlninit(sc) - struct rln_softc * sc; -{ - /* LLDInit() */ - struct ifnet * ifp = &sc->sc_arpcom.ac_if; - int s; - - s = splnet(); - dprintf(" [init]"); - - sc->sc_intsel = 0; - sc->sc_status = 0; - sc->sc_control = 0; - ifp->if_flags &= ~IFF_RUNNING; - ifp->if_flags &= ~IFF_OACTIVE; - - /* Do a hard reset. */ - if (rln_reset(sc)) { - printf("%s: could not reset card\n", sc->sc_dev.dv_xname); - goto fail; - } - sc->sc_state = 0; /* Also clears RLN_STATE_NEEDINIT. */ - - /* Use this host's name as a master name. */ - if (!cold && sc->sc_param.rp_master[0] == '\0') { - bcopy(hostname, sc->sc_param.rp_master, - min(hostnamelen, sizeof sc->sc_param.rp_master)); - } - - rln_enable(sc, 1); - - /* Initialise operational params. */ - if (rln_sendinit(sc)) { - printf("%s: could not set card parameters\n", - sc->sc_dev.dv_xname); - goto fail; - } -#if 0 - rln_roamconfig(sc); - /* rln_lockprom(sc); */ - /* SendSetITO() */ - rln_multicast(sc, 1); - rln_roam(sc); - - /* Synchronise with something. */ - rln_searchsync(sc); -#endif - ifp->if_flags |= IFF_RUNNING; - rlnstart(ifp); - splx(s); - - return; - - fail: - ifp->if_flags &= ~IFF_UP; - splx(s); - return; -} - -/* Start outputting on interface. This is always called at splnet(). */ -void -rlnstart(ifp) - struct ifnet * ifp; -{ - struct rln_softc * sc = (struct rln_softc *)ifp->if_softc; - struct mbuf * m0; - int len, pad, ret, s; - - dprintf(" start["); - - if (sc->sc_state & RLN_STATE_NEEDINIT) - rlninit(sc); - - /* Don't transmit if interface is busy or not running. */ - if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) { - dprintf(" %s] ", (ifp->if_flags & IFF_OACTIVE) ? - "busy" : "stopped"); - return; - } - - /* Don't transmit if we are not synchronised. */ - if ((sc->sc_state & RLN_STATE_SYNC) == 0) { - dprintf(" nosync]"); - return; - } - - rln_enable(sc, 1); - - startagain: - s = splnet(); - IFQ_DEQUEUE(&ifp->if_snd, m0); - splx(s); - - if (m0 == NULL) { - dprintf(" empty]"); - return; - } - -#if NBPFILTER > 0 - /* Tap packet stream here for BPF listeners. */ - if (ifp->if_bpf) - bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT); -#endif - - /* We need to use m->m_pkthdr.len, so require the header. */ - if ((m0->m_flags & M_PKTHDR) == 0) { - printf("%s: no mbuf header\n", sc->sc_dev.dv_xname); - goto oerror; - } - - len = m0->m_pkthdr.len; - -#define PACKETMIN (sizeof (struct ether_header) + ETHERMIN) -#define PACKETMAX (sizeof (struct ether_header) + ETHERMTU + 4) - - /* Packet size has to be an even number between 60 and 1518 octets. */ - pad = len & 1; - if (len + pad < PACKETMIN) - pad = PACKETMIN - len; - - if (len + pad > PACKETMAX) { - printf("%s: packet too big (%d > %d)\n", - sc->sc_dev.dv_xname, len + pad, - PACKETMAX); - ++ifp->if_oerrors; - m_freem(m0); - goto startagain; - } - - ret = rln_transmit(sc, m0, len, pad); - if (ret) - goto oerror; - - ifp->if_flags |= IFF_OACTIVE; - m_freem(m0); - - dprintf(" sent]"); - return; - -oerror: - ++ifp->if_oerrors; - m_freem(m0); - rln_need_reset(sc); - return; -} - -/* Transmit one packet. */ -int -rln_transmit(sc, m0, len, pad) - struct rln_softc * sc; - struct mbuf * m0; - int len; - int pad; -{ - struct mbuf * m; - int zfirst; - int actlen; - int tlen = len + pad; - struct rln_msg_tx_state state; - static u_int8_t zeroes[60]; - struct rln_mm_sendpacket cmd = { RLN_MM_SENDPACKET }; - - /* Does the packet start with a zero bit? */ - zfirst = ((*mtod(m0, u_int8_t *) & 1) == 0); - - cmd.mode = - RLN_MM_SENDPACKET_MODE_BIT7 | - (zfirst ? RLN_MM_SENDPACKET_MODE_ZFIRST : 0) | - (0 ? RLN_MM_SENDPACKET_MODE_QFSK : 0), /* sc->qfsk? */ - cmd.power = 0x70; /* 0x70 or 0xf0 */ - cmd.length_lo = htons(4 + tlen) & 0xff; - cmd.length_hi = (htons(4 + tlen) >> 8) & 0xff; - cmd.xxx1 = 0; - cmd.xxx2 = 0; - cmd.xxx3 = 0; - - /* A unique packet-level sequence number, independent of sc_seq. */ - cmd.sequence = sc->sc_txseq; - sc->sc_txseq++; - if (sc->sc_txseq > RLN_MAXSEQ) - sc->sc_txseq = 0; - - dprintf(" T[%d+%d", len, pad); - - if (rln_msg_tx_start(sc, &cmd, sizeof cmd + tlen, &state)) - goto error; - - cmd.mm_cmd.cmd_seq = rln_newseq(sc); - - /* Send the SENDPACKET command header */ -#ifdef RLNDUMP - printf("%s: send %c%d seq %d data ", sc->sc_dev.dv_xname, - cmd.mm_cmd.cmd_letter, cmd.mm_cmd.cmd_fn, cmd.mm_cmd.cmd_seq); - RLNDUMPHEX(&cmd, sizeof cmd); - printf(":"); -#endif - rln_msg_tx_data(sc, &cmd, sizeof cmd, &state); - - /* XXX do we need to insert a hardware header here??? */ - - /* Follow the header immediately with the packet payload */ - actlen = 0; - for (m = m0; m; m = m->m_next) { - if (m->m_len) { -#ifdef RLNDUMP - RLNDUMPHEX(mtod(m, void *), m->m_len); -#endif - rln_msg_tx_data(sc, mtod(m, void *), m->m_len, &state); - } - if (m->m_next) - printf("|"); - actlen += m->m_len; - } -#ifdef DIAGNOSTIC - if (actlen != len) - panic("rln_transmit: len %d != %d", actlen, len); - if (pad > sizeof zeroes) - panic("rln_transmit: pad %d > %d", pad, sizeof zeroes); -#endif - if (pad) { -#ifdef RLNDUMP - printf(":"); - RLNDUMPHEX(zeroes, pad); -#endif - rln_msg_tx_data(sc, zeroes, pad, &state); - } - -#ifdef RLNDUMP - printf("\n"); -#endif - if (rln_msg_tx_end(sc, &state)) - goto error; - return (0); - - error: - dprintf(" error]"); - return (-1); -} - -/* (Supposedly) called when interrupts are suspiciously absent. */ -void -rlnwatchdog(ifp) - struct ifnet * ifp; -{ - struct rln_softc * sc = (struct rln_softc *)ifp->if_softc; - - log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); - ++sc->sc_arpcom.ac_if.if_oerrors; - rlninit(sc); - rln_enable(sc, 1); -} - -/* Handle single card interrupt. */ -int -rlnintr(arg) - void * arg; -{ - struct rln_softc * sc = (struct rln_softc *)arg; - - dprintf("!"); - - /* Tell card not to interrupt any more. */ - rln_enable(sc, 0); - - if (cold) - /* During autoconfig - must handle interrupts now. */ - rlnsoftintr(sc); - else - /* Handle later. */ - timeout_add(&sc->sc_timeout, 1); - - return (1); -} - -/* Process earlier card interrupt at splsoftnet. */ -void -rlnsoftintr(arg) - void * arg; -{ - struct rln_softc *sc = (struct rln_softc *)arg; - struct ifnet *ifp = &sc->sc_arpcom.ac_if; - int len; - u_int8_t w; - struct rln_mm_cmd hdr; - int s; - - s = splsoftnet(); - dprintf(" si("); - - again: - /* Save wakeup state. */ - w = rln_wakeup(sc, RLN_WAKEUP_SET); - - if ((len = rln_rx_request(sc, 300)) < 0) { - /* Error in transfer. */ - rln_need_reset(sc); - rln_rx_end(sc); - } else if (len < sizeof hdr) { - /* Short message. */ - rln_rx_end(sc); - printf("%s: short msg (%d)\n", sc->sc_dev.dv_xname, len); - ifp->if_ierrors++; - } else { - /* Valid message: read header and process. */ - rln_rx_data(sc, &hdr, sizeof hdr); - rlnread(sc, &hdr, len); - } - - /* Ensure that wakeup state is unchanged if transmitting. */ - if (ifp->if_flags & IFF_OACTIVE) - w |= RLN_WAKEUP_NOCHANGE; - rln_wakeup(sc, w); - - /* Check for more interrupts. */ - if ((sc->sc_state & RLN_STATE_NEEDINIT) == 0 && - rln_status_rx_ready(sc)) { - if (rln_status_rx_read(sc) == RLN_STATUS_RX_ERROR) { -#ifdef DIAGNOSTIC - printf("%s: protocol error\n", sc->sc_dev.dv_xname); -#endif - DELAY(100 * 1000); /* Woah, baby. */ - rln_clear_nak(sc); - } else { -#ifdef DIAGNOSTIC - printf("%s: intr piggyback\n", sc->sc_dev.dv_xname); -#endif - goto again; - } - } - - rln_eoi(sc); - rln_enable(sc, 1); - - dprintf(")"); - splx(s); -} - -/* Read and process a message from the card. */ -void -rlnread(sc, hdr, len) - struct rln_softc *sc; - struct rln_mm_cmd *hdr; - int len; -{ - struct ifnet *ifp = &sc->sc_arpcom.ac_if; - struct mbuf *m; - u_int8_t data[1538]; - u_int8_t *buf; - size_t buflen; - struct rln_pdata pd = RLN_PDATA_INIT; - struct rln_mm_synchronised * syncp = (struct rln_mm_synchronised *)data; - int s; - - dprintf(" [read]"); - - /* Were we waiting for this message? */ - if (rln_mbox_lock(sc, hdr->cmd_seq, (void **)&buf, &buflen) == 0) { -#ifdef DIAGNOSTIC - if (buflen < sizeof *hdr) - panic("rlnread buflen"); -#endif - bcopy(hdr, buf, sizeof *hdr); - buf += sizeof *hdr; - len -= sizeof *hdr; - buflen -= sizeof *hdr; - if (len) { - if (len == buflen) /* Expected size */ - rln_rx_pdata(sc, buf, len, &pd); - else if (len < buflen) { /* Underfill */ -#ifdef DIAGNOSTIC - printf("%s: underfill %d<%d, cmd %c%d\n", - sc->sc_dev.dv_xname, - len, buflen, - hdr->cmd_letter, hdr->cmd_fn); -#endif - rln_rx_pdata(sc, buf, len, &pd); - } else { /* Overflow */ -#ifdef DIAGNOSTIC - printf("%s: overflow %d>%d, cmd %c%d\n", - sc->sc_dev.dv_xname, - len, buflen, - hdr->cmd_letter, hdr->cmd_fn); -#endif - rln_rx_pdata(sc, buf, buflen, &pd); - /* Drain the rest somewhere. */ - rln_rx_pdata(sc, data, len - buflen, &pd); - } - } - rln_rx_end(sc); - - /* This message can now be handled by the waiter. */ - rln_mbox_unlock(sc, hdr->cmd_seq, len + sizeof *hdr); - return; - } - - /* Otherwise, handle the message, right here, right now. */ - - /* Check if we can cope with the size of this message. */ - if (len > sizeof data) { - printf("%s: msg too big (%d)\n", sc->sc_dev.dv_xname, len); - ifp->if_ierrors++; - rln_rx_end(sc); - /* rln_need_reset(sc); */ - return; - } - - /* Check for error results. */ - if (hdr->cmd_error & 0x80) { - printf("%s: command error 0x%02x command %c%d len=%d\n", - sc->sc_dev.dv_xname, - hdr->cmd_error & ~0x80, - hdr->cmd_letter, hdr->cmd_fn, - len); - ifp->if_ierrors++; - rln_rx_end(sc); - rln_need_reset(sc); - return; - } - - /* - * "b1": Receiving a packet is a special case. - * We wish to read the data with pio straight into an - * mbuf to avoid a memory-memory copy. - */ - if (hdr->cmd_letter == 'b' && hdr->cmd_fn == 1) { - m = rlnget(sc, hdr, len); - rln_rx_end(sc); - if (m == NULL) - return; - ifp->if_ipackets++; -#ifdef DIAGNOSTIC - if (bcmp(mtod(m, u_int8_t *), "prox", 4) == 0) { - printf("%s: proxim special packet received\n", - sc->sc_dev.dv_xname); - } -#endif - -#if NBPFILTER > 0 - if (ifp->if_bpf) - bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN); -#endif - - ether_input_mbuf(ifp, m); - return; - } - - - /* Otherwise we read the packet into a buffer on the stack. */ - bcopy(hdr, data, sizeof *hdr); - if (len > sizeof *hdr) - rln_rx_pdata(sc, data + sizeof *hdr, len - sizeof *hdr, &pd); - rln_rx_end(sc); - -#ifdef RLNDUMP - printf("%s: recv %c%d seq %d data ", sc->sc_dev.dv_xname, - hdr->cmd_letter, hdr->cmd_fn, hdr->cmd_seq); - RLNDUMPHEX(hdr, sizeof hdr); - printf(":"); - RLNDUMPHEX(data + sizeof hdr, len - sizeof hdr); - printf("\n"); -#endif - - switch (RLN_MM_CMD(hdr->cmd_letter, hdr->cmd_fn)) { - case RLN_MM_CMD('b', 0): /* b0: Transmit done. */ -#ifdef DIAGNOSTIC - if (len != 7) - printf("%s: 'b0' len %d != 7\n", - sc->sc_dev.dv_xname, len); -#endif - ifp->if_flags &= ~IFF_OACTIVE; - ifp->if_opackets++; - s = splnet(); - rlnstart(ifp); - splx(s); - break; - - case RLN_MM_CMD('a', 20): /* a20: Card fault. */ - printf("%s: hardware fault\n", sc->sc_dev.dv_xname); - break; - - case RLN_MM_CMD('a', 4): /* a4: Sync'd. */ - if (bcmp(syncp->enaddr, sc->sc_arpcom.ac_enaddr, - ETHER_ADDR_LEN) == 0) { - /* Sync'd to own enaddr. */ - /* - * From http://www.proxim.com/support/faq/7400.shtml - * 3. RLNSETUP reports that I'm synchronized to my own MAC address. What - * does that mean? - * You are the acting Master for this network. Either you are - * configured as the Master or as an Alternate Master. If you are an - * Alternate Master, you may be out of range or on a different Domain - * and Security ID from the true Master. - */ - - printf("%s: nothing to sync to; now master ", - sc->sc_dev.dv_xname); - } - else - printf("%s: synchronised to ", sc->sc_dev.dv_xname); - printf("%.11s (%s) channel %d/%d\n", - syncp->mastername, - ether_sprintf(syncp->enaddr), - syncp->channel, - syncp->subchannel); - - /* Record the new circumstances. */ - sc->sc_param.rp_channel = syncp->channel; - sc->sc_param.rp_subchannel = syncp->subchannel; - sc->sc_state |= RLN_STATE_SYNC; - - /* Resume sending. */ - s = splnet(); - rlnstart(ifp); - splx(s); - break; - - case RLN_MM_CMD('a', 5): /* a4: Lost sync. */ - printf("%s: lost sync\n", sc->sc_dev.dv_xname); - sc->sc_state &= ~RLN_STATE_SYNC; - break; - - case RLN_MM_CMD('a', 18): /* a18: Roaming. */ - printf("%s: roaming\n", sc->sc_dev.dv_xname); - break; - default: -#ifdef DIAGNOSTIC - printf("%s: msg `%c%d' seq %d data {", - sc->sc_dev.dv_xname, - hdr->cmd_letter, hdr->cmd_fn, hdr->cmd_seq); - RLNDUMPHEX(hdr, sizeof hdr); - printf(":"); - RLNDUMPHEX(data, len); - printf("}\n"); -#endif - break; - } - -} - -/* Extract a received network packet from the card. */ -struct mbuf * -rlnget(sc, hdr, totlen) - struct rln_softc *sc; - struct rln_mm_cmd *hdr; - int totlen; -{ - struct ifnet *ifp = &sc->sc_arpcom.ac_if; - int len; - int pad; - struct mbuf *m, **mp, *top; - struct rln_pdata pd = RLN_PDATA_INIT; - struct { - u_int8_t rssi; - u_int8_t xxx1; /* always 00? */ - u_int16_t len; /* payload length */ - u_int8_t xxx2; /* always 00? */ - u_int8_t xxx3; /* always c0? */ - u_int8_t seq; - u_int8_t xxx4; - struct ether_addr to; /* destination station addr */ - struct ether_addr from; /* sending station addr */ - } hwhdr; - - dprintf(" [get]"); - -#ifdef RLNDUMP - /* Decode the command header: */ - printf("%s: recv %c%d seq %d data ", sc->sc_dev.dv_xname, - hdr->cmd_letter, hdr->cmd_fn, hdr->cmd_seq); - RLNDUMPHEX(hdr, sizeof hdr); - printf(":"); -#endif - totlen -= sizeof *hdr; - -#ifdef DIAGNOSTIC - if (totlen <= 0) { - printf("%s: empty packet", sc->sc_dev.dv_xname); - goto drop; - } -#endif - - /* Decode the hardware header: */ - rln_rx_pdata(sc, &hwhdr, sizeof hwhdr, &pd); - totlen -= sizeof hwhdr; -#ifdef RLNDUMP - RLNDUMPHEX(&hwhdr, sizeof hwhdr); - printf("/"); -#endif - /* (Most of the following code fleeced from elink3.c.) */ - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) - goto drop; - m->m_pkthdr.rcvif = ifp; - m->m_pkthdr.len = totlen; - /* - * Insert some leading padding in the mbuf, so that payload data is - * aligned. - */ - pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header); - m->m_data += pad; - len = MHLEN - pad; - top = 0; - mp = ⊤ - - while (totlen > 0) { - if (top) { - MGET(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - m_freem(top); - goto drop; - } - len = MLEN; - } - if (totlen >= MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if (m->m_flags & M_EXT) { - len = MCLBYTES; - if (!top) { - m->m_data += pad; - len -= pad; - } - } - } - len = min(totlen, len); - rln_rx_pdata(sc, mtod(m, u_int8_t *), len, &pd); -#ifdef RLNDUMP - RLNDUMPHEX(mtod(m, u_int8_t *), len); - if (totlen != len) - printf("|"); -#endif - m->m_len = len; - totlen -= len; - *mp = m; - mp = &m->m_next; - } -#ifdef RLNDUMP - printf("\n"); -#endif - return top; - -drop: -#ifdef RLNDUMP - printf(": drop\n"); -#endif - ifp->if_iqdrops++; - return NULL; -} - -/* Interface control. */ -int -rlnioctl(ifp, cmd, data) - struct ifnet *ifp; - u_long cmd; - caddr_t data; -{ - struct rln_softc *sc = ifp->if_softc; - struct ifaddr *ifa = (struct ifaddr *)data; - int s, error; - int need_init; - - printf("%s: ioctl cmd[%c/%d] data=%x\n", sc->sc_dev.dv_xname, - IOCGROUP(cmd), IOCBASECMD(cmd), data); - - s = splnet(); - if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) != 0) { - splx(s); - return error; - } - - switch (cmd) { - case SIOCSIFADDR: - /* Set address. */ - ifp->if_flags |= IFF_UP; - - switch (ifa->ifa_addr->sa_family) { -#ifdef INET - case AF_INET: - rlninit(sc); - arp_ifinit(&sc->sc_arpcom, ifa); - break; -#endif - default: - rlninit(sc); - break; - } - break; - - case SIOCSIFFLAGS: - need_init = 0; - - if ((ifp->if_flags & IFF_UP) == 0 && - (ifp->if_flags & IFF_RUNNING) != 0) { - /* Was running, want down: stop. */ - rlnstop(sc); - } else if ((ifp->if_flags & IFF_UP) != 0 && - (ifp->if_flags & IFF_RUNNING) == 0) { - /* Was not running, want up: start. */ - need_init = 1; - } - - if (ifp->if_flags & IFF_RUNNING) { - if ((ifp->if_flags & IFF_PROMISC) && - (sc->sc_state & RLN_STATE_PROMISC) == 0) { - sc->sc_state |= RLN_STATE_PROMISC; - need_init = 1; - } - else if ((ifp->if_flags & IFF_PROMISC) == 0 && - (sc->sc_state & RLN_STATE_PROMISC)) { - sc->sc_state &= ~RLN_STATE_PROMISC; - need_init = 1; - } - } - - if (need_init) - rlninit(sc); - - break; - - case SIOCADDMULTI: - case SIOCDELMULTI: - error = EOPNOTSUPP; - break; - -#if notyet - case RLNIOSPARAM: - error = rln_iosetparam(sc, (struct rln_param *)&data); - break; - - case RLNIOGPARAM: - bcopy(&sc->sc_param, (struct rln_param *)&data, - sizeof sc->sc_param); - break; -#endif - - default: - error = EINVAL; - break; - } - - splx(s); - return (error); -} - -/* Stop output from the card. */ -void -rlnstop(sc) - struct rln_softc *sc; -{ - struct ifnet *ifp = &sc->sc_arpcom.ac_if; - - dprintf(" [stop]"); - ifp->if_flags &= ~IFF_RUNNING; - rln_enable(sc, 0); -} - -/* Get MAC address from card. */ -int -rln_getenaddr(sc, enaddr) - struct rln_softc *sc; - u_int8_t * enaddr; -{ - struct rln_mm_cmd query = RLN_MM_GETENADDR; - struct rln_mm_gotenaddr response = { RLN_MM_GETENADDR }; - - if (rln_msg_txrx(sc, &query, sizeof query, - &response, sizeof response)) - return (-1); - bcopy(response.enaddr, enaddr, sizeof response.enaddr); - return (0); -}; - -/* Get firmware version string from card. */ -int -rln_getpromvers(sc, ver, verlen) - struct rln_softc *sc; - char *ver; - int verlen; -{ - struct rln_mm_cmd query = RLN_MM_GETPROMVERSION; - struct rln_mm_gotpromversion response = { RLN_MM_GOTPROMVERSION }; - int i; - -#ifdef DIAGNOSTIC - if (verlen != sizeof response.version) - panic("rln_getpromvers"); -#endif - - if (rln_msg_txrx(sc, &query, sizeof query, - &response, sizeof response)) - return (-1); - bcopy(response.version, ver, verlen); - /* Nul trailing spaces. */ - for (i = verlen - 1; i >= 0 && ver[i] <= ' '; i--) - ver[i] = '\0'; - return (0); -}; - -/* Set default operational parameters on card. */ -int -rln_sendinit(sc) - struct rln_softc *sc; -{ - struct rln_mm_init init = { RLN_MM_INIT }; - struct rln_mm_initted iresponse; -#if 0 - struct rln_mm_setmagic magic = { RLN_MM_SETMAGIC }; - struct rln_mm_disablehopping hop = { RLN_MM_DISABLEHOPPING }; - struct rln_mm_cmd response; -#endif - - bzero((char *)&init + sizeof init.mm_cmd, - sizeof init - sizeof init.mm_cmd); - - dprintf(" [setting parameters]"); - init.opmode = (sc->sc_state & RLN_STATE_PROMISC ? - RLN_MM_INIT_OPMODE_PROMISC : RLN_MM_INIT_OPMODE_NORMAL); - init.stationtype = sc->sc_param.rp_station_type; - - /* Spread-spectrum frequency hopping. */ - init.hop_period = 1; - init.bfreq = 2; - init.sfreq = 7; - - /* Choose channel. */ - init.channel = sc->sc_param.rp_channel; - init.subchannel = sc->sc_param.rp_subchannel; - init.domain = sc->sc_param.rp_domain; - - /* Name of this station when acting as master. */ - bcopy(sc->sc_param.rp_master, init.mastername, sizeof init.mastername); - - /* Security params. */ - init.sec1 = (sc->sc_param.rp_security & 0x0000ff) >> 0; - init.sec2 = (sc->sc_param.rp_security & 0x00ff00) >> 8; - init.sec3 = (sc->sc_param.rp_security & 0xff0000) >> 16; - - init.sync_to = 1; - bzero(init.syncname, sizeof init.syncname); - - if (rln_msg_txrx(sc, &init, sizeof init, - &iresponse, sizeof iresponse)) - return (-1); -#if 0 - dprintf(" [setting magic]"); - magic.fairness_slot = 3; /* lite: 1, norm: 3, off: -1 */ - magic.deferral_slot = 3; /* lite: 0, norm: 3, off: -1 */ - magic.regular_mac_retry = 7; - magic.frag_mac_retry = 10; - magic.regular_mac_qfsk = 2; - magic.frag_mac_qfsk = 5; - magic.xxx1 = 0xff; - magic.xxx2 = 0xff; - magic.xxx3 = 0xff; - magic.xxx4 = 0x00; - if (rln_msg_txrx(sc, &magic, sizeof magic, - &response, sizeof response)) - return (-1); - - dprintf(" [disabling freq hopping]"); - hop.hopflag = RLN_MM_DISABLEHOPPING_HOPFLAG_DISABLE; - if (rln_msg_txrx(sc, &hop, sizeof hop, - &response, sizeof response)) - return (-1); - -#endif - return (0); -} - -#if notyet -/* Configure the way the card leaves a basestation. */ -int -rln_roamconfig(sc) - struct rln_softc *sc; -{ - struct rln_mm_setroaming roam = { RLN_MM_SETROAMING }; - struct rln_mm_cmd response; - static int retry[3] = { 6, 6, 4 }; - static int rssi[3] = { 5, 15, 5 }; - - dprintf(" [roamconfig]"); -#ifdef DIAGNOSTIC - if (sc->sc_param.rp_roam_config > 2) - panic("roamconfig"); -#endif - roam.sync_alarm = 0; - roam.retry_thresh = retry[sc->sc_param.rp_roam_config]; - roam.rssi_threshold = rssi[sc->sc_param.rp_roam_config]; - roam.xxx1 = 0x5a; - roam.sync_rssi_threshold = 0; - roam.xxx2 = 0x5a; - roam.missed_sync = 0x4; - if (rln_msg_txrx(sc, &roam, sizeof roam, - &response, sizeof response)) - return (-1); - - return (0); -} - -/* Enable roaming. */ -int -rln_roam(sc) - struct rln_softc *sc; -{ - struct rln_mm_cmd roam = RLN_MM_ROAM; - struct rln_mm_cmd response; - - return (rln_msg_txrx(sc, &roam, sizeof roam, - &response, sizeof response)); -} - -/* Enable multicast capability. */ -int -rln_multicast(sc, enable) - struct rln_softc *sc; - int enable; -{ - struct ifnet *ifp = &sc->sc_arpcom.ac_if; - struct rln_mm_multicast mcast = { RLN_MM_MULTICAST }; - struct rln_mm_cmd response; - int ret; - - mcast.enable = enable; - - ret = rln_msg_txrx(sc, &mcast, sizeof mcast, - &response, sizeof response); - if (ret == 0) { - if (enable) - ifp->if_flags |= IFF_MULTICAST; - else - ifp->if_flags &= ~IFF_MULTICAST; - } - return (ret); -} - -/* Search for and sync with any master. */ -int -rln_searchsync(sc) - struct rln_softc *sc; -{ - struct rln_mm_search search = { RLN_MM_SEARCH }; - struct rln_mm_searching response; - - bzero(search.xxx1, sizeof search.xxx1); - search.domain = sc->sc_param.rp_domain; - search.roaming = 1; - search.xxx3 = 0; - search.xxx4 = 1; - search.xxx5 = 0; - bzero(search.xxx6, sizeof search.xxx6); - - return (rln_msg_txrx(sc, &search, sizeof search, - &response, sizeof response)); -} - -/* Set values from an external parameter block. */ -int -rln_iosetparam(sc, param) - struct rln_softc *sc; - struct rln_param *param; -{ - int error = 0; - - if (param->rp_roam_config > 2) - error = EINVAL; - if (param->rp_security > 0x00ffffff) - error = EINVAL; - if (param->rp_station_type > 2) - error = EINVAL; - if (param->rp_channel > 15) - error = EINVAL; - if (param->rp_subchannel > 15) - error = EINVAL; - if (error == 0) { - /* Apply immediately. */ - bcopy(param, &sc->sc_param, sizeof *param); - if (rln_sendinit(sc)) - error = EIO; - } - return (error); -} - -/* Protect the eeprom from storing a security ID(?) */ -int -rln_lockprom(sc) - struct rln_softc *sc; -{ - struct rln_mm_cmd lock = RLN_MM_EEPROM_PROTECT; - struct rln_mm_cmd response; - - /* XXX Always yields an error? */ - return (rln_msg_txrx(sc, &lock, sizeof lock, - &response, sizeof response)); -} - -/* Set the h/w Inactivity Time Out timer on the card. */ -int -rln_ito(sc) - struct rln_softc * sc; -{ - struct rln_mm_setito ito = { RLN_MM_MULTICAST }; - struct rln_mm_cmd response; - - ito.xxx = 3; - ito.timeout = LLDInactivityTimeOut /* enabler, 0 or 1 */; - ito.bd_wakeup = LLDBDWakeup /* 0 */; - ito.pm_sync = LLDPMSync /* 0 */; - ito.sniff_time = ito.timeout ? LLDSniffTime /* 0 */ : 0; - - if (rln_msg_txrx(sc, &ito, sizeof ito, - &response, sizeof response)) - return (-1); -} - -/* Put the card into standby mode. */ -int -rln_standby(sc) - struct rln_softc * sc; -{ - struct rln_mm_standby standby = { RLN_MM_STANDBY }; - - standby.xxx = 0; - if (rln_msg_txrx(sc, &ito, sizeof ito, NULL, 0)) - return (-1); -} - -void -rln_crypt(userkey, cardkey) - char *userkey; /* User's string (max 20 chars). */ - u_int8_t *cardkey; /* 20 bits (3 bytes) */ -{ - /* - * From <http://www.proxim.com/learn/whiteppr/rl2security.shtml> - * "RangeLAN2 Security Features": - * - * The Security ID is a unique, 20 character alphanumeric - * string defined and configured by the user. It must be - * identically configured in every radio intended to - * communicate with others in the same network. Once - * configured, the Security ID is reduced to 20 bits by a - * proprietary algorithm confidential to Proxim. It is - * merged with the radio MAC address (a 12 character field - * unique to every radio), scrambled and stored using another - * proprietary, confidential algorithm. - */ - int32_t key; - int8_t ret; - int i; - int len; - int32_t multiplicand = 0x80000181; - int64_t res; - - /* - * This algorithm is `compatible' with Proxim's first - * `proprietary confidential algorithm': i.e., it appears - * to be functionally identical. - */ - len = strlen(s); - key = 0x030201; - for (i = 0; i < len; i++) { - - key *= userkey[i]; - res = (int64_t)multiplicand * key; - key = key - 0xfffffd * - (((key + (int32_t)(res >> 32)) >> 23) - (key >> 31)); - } - - cardkey[0] = (key >> 16) & 0xff; - cardkey[1] = (key >> 8) & 0xff; - cardkey[2] = key & 0xff; - - cardkey[0] |= 0x03; /* Restrict key space by 2 bits. */ -} -#endif diff --git a/sys/dev/ic/rln.h b/sys/dev/ic/rln.h deleted file mode 100644 index fa4b7b2e799..00000000000 --- a/sys/dev/ic/rln.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $OpenBSD: rln.h,v 1.1 1999/07/30 13:43:36 d Exp $ */ -/* - * David Leonard <d@openbsd.org>, 1999. Public domain. - * - * Proxim RangeLAN2 parameters. - */ - -/* - * Eventually, there should be a way of getting and setting these - * from user space. Ideally, via ioctl(). - */ - -/* User-configurable station parameters. */ -struct rln_param { - u_int32_t rp_security; /* Security ID */ -#define RLN_SECURITY_DEFAULT 0x0010203 - u_int8_t rp_station_type; /* Station type */ -#define RLN_STATIONTYPE_SLAVE 0 -#define RLN_STATIONTYPE_ALTMASTER 1 -#define RLN_STATIONTYPE_MASTER 2 - u_int8_t rp_domain; /* Network domain */ - u_int8_t rp_channel; /* Phys channel when master */ - u_int8_t rp_subchannel; /* Logical master subchannel */ - char rp_master[11]; /* Name when master */ - u_int8_t rp_mac_optimize; -#define RLN_MAC_OPTIM_LIGHT 0 -#define RLN_MAC_OPTIM_NORMAL 1 - u_int8_t rp_roam_config; /* Roaming speed */ -#define RLN_ROAM_SLOW 0 -#define RLN_ROAM_NORMAL 1 -#define RLN_ROAM_FAST 2 - u_int8_t rp_peer_to_peer; /* Ability to talk to peers */ -}; - -#ifdef notyet -#define RLNIOSPARAM _IOW('2', 1, struct rln_param) /* set params */ -#define RLNIOGPARAM _IOR('2', 2, struct rln_param) /* get params */ -#endif - diff --git a/sys/dev/ic/rlncmd.h b/sys/dev/ic/rlncmd.h deleted file mode 100644 index efaed3dcde1..00000000000 --- a/sys/dev/ic/rlncmd.h +++ /dev/null @@ -1,247 +0,0 @@ -/* $OpenBSD: rlncmd.h,v 1.1 1999/07/30 13:43:36 d Exp $ */ -/* - * David Leonard <d@openbsd.org>, 1999. Public Domain. - * - * RangeLAN2 host-to-card message protocol. - */ - -/* Micro-message command header. */ -struct rln_mm_cmd { - u_int8_t cmd_letter; /* Command letter */ - u_int8_t cmd_seq; /* Incremented on each command */ -#define RLN_MAXSEQ 0x7c - u_int8_t cmd_fn; /* Function number */ - u_int8_t cmd_error; /* Reserved */ -}; -#define RLN_MM_CMD(l,n) ((((unsigned int)l)<<8) | ((unsigned int)n)) -#define RLN_MM_CMD_LETTER(cmd) ((unsigned char)(((cmd) & 0xff00)>>8)) -#define RLN_MM_CMD_FUNCTION(cmd) ((unsigned char)((cmd) & 0xff)) -#define RLN_CMDCODE(letter, num) ((((letter) & 0xff) << 8) | ((num) & 0xff)) - -/* Initialise card, and set operational parameters. */ -struct rln_mm_init { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_INIT { 'A', 0, 0, 0 } - u_int8_t enaddr[6]; - u_int8_t opmode; -#define RLN_MM_INIT_OPMODE_NORMAL 0 -#define RLN_MM_INIT_OPMODE_PROMISC 1 -#define RLN_MM_INIT_OPMODE_PROTOCOL 2 - u_int8_t stationtype; /* RLN_STATIONTYPE_... */ - u_int8_t hop_period; - u_int8_t bfreq; - u_int8_t sfreq; - u_char channel : 4; /* lower bits */ - u_char subchannel : 4; /* upper bits */ - char mastername[11]; - u_char sec1 : 4; /* default 3 */ - u_char domain : 4; /* default 0 */ - u_int8_t sec2; /* default 2 */ - u_int8_t sec3; /* default 1 */ - u_int8_t sync_to; /* 1 if roaming */ - u_int8_t xxx_pad; /* zero */ - char syncname[11]; -}; - -/* Result of initialisation. */ -struct rln_mm_initted { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_INITTED { 'a', 0, 0, 0 } - u_int8_t xxx; -}; - -/* Start searching for other masters. */ -struct rln_mm_search { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_SEARCH { 'A', 0, 1, 0 } - u_int8_t xxx1[23]; - u_char xxx2 : 4; - u_char domain : 4; - u_int8_t roaming; - u_int8_t xxx3; /* default 0 */ - u_int8_t xxx4; /* default 1 */ - u_int8_t xxx5; /* default 0 */ - u_int8_t xxx6[11]; -}; - -/* Notification that searching has started. */ -struct rln_mm_searching { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_SEARCHING { 'a', 0, 1, 0 } - u_int8_t xxx; -}; - -/* Terminate search. */ -#define RLN_MM_ABORTSEARCH { 'A', 0, 3, 0 } - -/* Station synchronised to a master. */ -struct rln_mm_synchronised { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_SYNCHRONISED { 'a', 0, 4, 0 } - u_char channel : 4; /* lower bits */ - u_char subchannel : 4; /* upper bits */ - char mastername[11]; - u_int8_t enaddr[6]; -}; - -/* Station lost synchronisation with a master. */ -#define RLN_MM_UNSYNCHRONISED { 'a', 0, 5, 0 } - -/* Send card to sleep. (See rln_wakeup().) */ -struct rln_mm_standby { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_STANDBY { 'A', 0, 6, 0 } - u_int8_t xxx; /* default 0 */ -}; - -/* Set ITO (inactivity timeout timer). */ -struct rln_mm_setito { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_SETITO { 'A', 0, 7, 0 } - u_int8_t xxx; /* default 3 */ - u_int8_t timeout; - u_char bd_wakeup : 1; - u_char pm_sync : 7; - u_int8_t sniff_time; -}; - -/* ITO acknowledgment */ -#define RLN_MM_GOTITO { 'a', 0, 7, 0 } - -/* Send keepalive protocol message (?). */ -#define RLN_MM_SENDKEEPALIVE { 'A', 0, 8, 0 } - -/* Set multicast mode. */ -struct rln_mm_multicast { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_MULTICAST { 'A', 0, 9, 0 } - u_int8_t enable; -}; - -/* Ack multicast mode change. */ -#define RLN_MM_MULTICASTING { 'a', 0, 9, 0 } - -/* Request statistics. */ -#define RLN_MM_GETSTATS { 'A', 0, 11, 0 } - -/* Statistics results. */ -#define RLN_MM_GOTSTATS { 'a', 0, 11, 0 } - -/* Set security ID used in channel. */ -struct rln_mm_setsecurity { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_SETSECURITY { 'A', 0, 12, 0 } - u_int8_t sec1; - u_int8_t sec2; - u_int8_t sec3; -}; - -/* Ack set security ID. */ -#define RLN_MM_GOTSECURITY { 'a', 0, 12, 0 } - -/* Request firmware version. */ -#define RLN_MM_GETPROMVERSION { 'A', 0, 13, 0 } - -/* Reply with firmware version. */ -struct rln_mm_gotpromversion { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_GOTPROMVERSION { 'a', 0, 13, 0 } - u_int8_t xxx; /* sizeof version? */ - char version[7]; -}; - -/* Request station's MAC address (same as ethernet). */ -#define RLN_MM_GETENADDR { 'A', 0, 14, 0 } - -/* Reply with station's MAC address. */ -struct rln_mm_gotenaddr { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_GOTENADDR { 'a', 0, 14, 0 } - u_int8_t xxx; - u_int8_t enaddr[6]; -}; - -/* Tune various channel parameters. */ -struct rln_mm_setmagic { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_SETMAGIC { 'A', 0, 16, 0 } - u_char fairness_slot : 3; - u_char deferral_slot : 5; - u_int8_t regular_mac_retry; /* default 0x07 */ - u_int8_t frag_mac_retry; /* default 0x0a */ - u_int8_t regular_mac_qfsk; /* default 0x02 */ - u_int8_t frag_mac_qfsk; /* default 0x05 */ - u_int8_t xxx1; /* default 0xff */ - u_int8_t xxx2; /* default 0xff */ - u_int8_t xxx3; /* default 0xff */ - u_int8_t xxx4; /* zero */ -}; - -/* Ack channel tuning. */ -#define RLN_MM_GOTMAGIC { 'a', 0, 16, 0 } - -/* Set roaming parameters - used when multiple masters available. */ -struct rln_mm_setroaming { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_SETROAMING { 'A', 0, 17, 0 } - u_int8_t sync_alarm; - u_int8_t retry_thresh; - u_int8_t rssi_threshold; - u_int8_t xxx1; /* default 0x5a */ - u_int8_t sync_rssi_threshold; - u_int8_t xxx2; /* default 0xa5 */ - u_int8_t missed_sync; -}; - -/* Ack roaming parameter change. */ -#define RLN_MM_GOTROAMING { 'a', 0, 17, 0 } - -#define RLN_MM_ROAMING { 'a', 0, 18, 0 } -#define RLN_MM_ROAM { 'A', 0, 19, 0 } - -/* Hardware fault notification. (Usually the antenna.) */ -#define RLN_MM_FAULT { 'a', 0, 20, 0 } - -#define RLN_MM_EEPROM_PROTECT { 'A', 0, 23, 0 } -#define RLN_MM_EEPROM_PROTECTED { 'a', 0, 23, 0 } -#define RLN_MM_EEPROM_UNPROTECT { 'A', 0, 24, 0 } -#define RLN_MM_EEPROM_UNPROTECTED { 'a', 0, 24, 0 } - -/* Receive hop statistics. */ -#define RLN_MM_HOP_STATISTICS { 'a', 0, 35, 0 } - -/* Transmit a frame on the channel. */ -struct rln_mm_sendpacket { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_SENDPACKET { 'B', 0, 0, 0 } - u_int8_t mode; -#define RLN_MM_SENDPACKET_MODE_BIT7 0x80 -#define RLN_MM_SENDPACKET_MODE_ZFIRST 0x20 -#define RLN_MM_SENDPACKET_MODE_QFSK 0x03 - u_int8_t power; /* default 0x70 */ - u_int8_t length_lo; - u_int8_t length_hi; - u_int8_t xxx1; /* default 0 */ - u_int8_t xxx2; /* default 0 */ - u_int8_t sequence; /* must increment */ - u_int8_t xxx3; /* default 0 */ -}; - -/* Ack packet transmission. */ -#define RLN_MM_SENTPACKET { 'b', 0, 0, 0 } - -/* Notification of frame received from channel. */ -struct rln_mm_recvpacket { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_RECVPACKET { 'b', 0, 1, 0 } - u_int8_t xxx[8]; -}; - -/* Disable hopping. (?) */ -struct rln_mm_disablehopping { - struct rln_mm_cmd mm_cmd; -#define RLN_MM_DISABLEHOPPING { 'C', 0, 9, 0 } - u_int8_t hopflag; -#define RLN_MM_DISABLEHOPPING_HOPFLAG_DISABLE 0x52 -}; - diff --git a/sys/dev/ic/rlnreg.h b/sys/dev/ic/rlnreg.h deleted file mode 100644 index 8d78101270a..00000000000 --- a/sys/dev/ic/rlnreg.h +++ /dev/null @@ -1,283 +0,0 @@ -/* $OpenBSD: rlnreg.h,v 1.3 2002/03/14 01:26:55 millert Exp $ */ -/* - * David Leonard <d@openbsd.org>, 1999. Public Domain. - * - * RangeLAN2 registers - */ - -/* - * The RangeLAN2 cards provide four control registers for transferring - * messaged between the host and the card using programmed i/o. - * - * A transfer protocol is followed when sending asynchronous messages to, - * and receiving messages from, the card. - * - * DATA - * 7 6 5 4 3 2 1 0 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | data | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * - * STATUS - * 7 6 5 4 3 2 1 0 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * |WAKEUP | tx message state |CLRNAK | rx message state | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * - * CONTROL - * 7 6 5 4 3 2 1 0 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | | | 16BIT | RESET | | | TXINT | RXINT | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * - * INTSEL - * 7 6 5 4 3 2 1 0 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | | | |ENABLE | interrupt line | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - */ - -/* Register offsets. */ -#define RLN_REG_DATA 0 -#define RLN_REG_STATUS 2 -#define RLN_REG_CONTROL 4 -#define RLN_REG_EOI 5 -#define RLN_REG_INTSEL 6 -#define RLN_NPORTS 8 - -/* - * A short delay is needed (16ms?) after register writes on some cards. - * XXX This is done by performing an innocent and harmless bus read. (i386) - * This is what Proxim's driver does, anyway. - */ -#define _rln_regacc_delay() \ - bus_space_read_1(I386_BUS_SPACE_IO, 0, 0x61) - -static void _rln_register_write_1(struct rln_softc *, u_int8_t, - u_int8_t); -static void _rln_register_write_2(struct rln_softc *, u_int8_t, - u_int16_t); -static u_int8_t _rln_register_read_1(struct rln_softc *, u_int8_t); -static u_int16_t _rln_register_read_2(struct rln_softc *, u_int8_t); -static int rln_status_rx_ready(struct rln_softc *); - -/* Write to a register. */ -static inline void -_rln_register_write_1(sc, regoff, value) - struct rln_softc *sc; - u_int8_t regoff; - u_int8_t value; -{ - -#ifdef RLNDEBUG_REG - printf(" %c<%02x", "DDS3CEI7"[regoff], value); -#endif - bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (regoff), (value)); - _rln_regacc_delay(); -} - -static inline void -_rln_register_write_2(sc, regoff, value) - struct rln_softc *sc; - u_int8_t regoff; - u_int16_t value; -{ - -#ifdef RLNDEBUG_REG - printf(" %c<%04x", "DDS3CEI7"[regoff], value); -#endif - bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, (regoff), (value)); - _rln_regacc_delay(); -} - -/* Read from a register. */ -static inline u_int8_t -_rln_register_read_1(sc, regoff) - struct rln_softc *sc; - u_int8_t regoff; -{ - u_int8_t ret; - - ret = bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (regoff)); -#ifdef RLNDEBUG_REG - if (ret != (sc)->dbg_oreg[regoff]) { - /* avoid spewing out too much debug info */ - printf(" %c>%02x", "DDS3CEI7"[regoff], ret); - (sc)->dbg_oreg[regoff] = ret; - } -#endif - return (ret); -} - - -static inline u_int16_t -_rln_register_read_2(sc, regoff) - struct rln_softc *sc; - u_int8_t regoff; -{ - u_int16_t ret; - - ret = bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, (regoff)); -#ifdef RLNDEBUG_REG - if (ret != (sc)->dbg_oreg[regoff]) { - printf(" %c>%04x", "DDS3CEI7"[regoff], ret); - (sc)->dbg_oreg[regoff] = ret; - } -#endif - return (ret); -} - -/* 8-bit data register access. */ -#define rln_data_write_1(sc, value) \ - _rln_register_write_1(sc, RLN_REG_DATA, (value)) -#define rln_data_read_1(sc) \ - _rln_register_read_1(sc, RLN_REG_DATA) -#define rln_data_write_multi_1(sc, buf, len) \ - bus_space_write_multi_1((sc)->sc_iot, (sc)->sc_ioh, \ - RLN_REG_DATA, (buf), (len)) -#define rln_data_read_multi_1(sc, buf, len) \ - bus_space_read_multi_1((sc)->sc_iot, (sc)->sc_ioh, \ - RLN_REG_DATA, (buf), (len)) - -/* 16-bit data register access. */ -#define rln_data_write_2(sc, value) \ - _rln_register_write_2(sc, RLN_REG_DATA, (value)) -#define rln_data_read_2(sc) \ - _rln_register_read_2(sc, RLN_REG_DATA) -#define rln_data_write_multi_2(sc, buf, len) \ - bus_space_write_multi_2((sc)->sc_iot, (sc)->sc_ioh, \ - RLN_REG_DATA, (buf), (len)) -#define rln_data_read_multi_2(sc, buf, len) \ - bus_space_read_multi_2((sc)->sc_iot, (sc)->sc_ioh, \ - RLN_REG_DATA, (buf), (len)) - -/* Status register. */ -#define RLN_STATUS_CLRNAK 0x08 -#define RLN_STATUS_WAKEUP 0x80 - -#define RLN_STATUS_TX_IDLE 0x00 -#define RLN_STATUS_TX_HILEN_AVAIL 0x01 -#define RLN_STATUS_TX_HILEN_ACCEPT 0x02 -#define RLN_STATUS_TX_XFR_COMPLETE 0x03 -#define RLN_STATUS_TX_XFR 0x04 -#define RLN_STATUS_TX_ERROR 0x05 -#define RLN_STATUS_TX_LOLEN_AVAIL 0x06 -#define RLN_STATUS_TX_LOLEN_ACCEPT 0x07 -#define RLN_STATUS_TX_MASK 0x0f - -#define RLN_STATUS_RX_IDLE 0x00 -#define RLN_STATUS_RX_HILEN_AVAIL 0x10 -#define RLN_STATUS_RX_HILEN_ACCEPT 0x20 -#define RLN_STATUS_RX_XFR_COMPLETE 0x30 -#define RLN_STATUS_RX_XFR 0x40 -#define RLN_STATUS_RX_ERROR 0x50 -#define RLN_STATUS_RX_LOLEN_AVAIL 0x60 -#define RLN_STATUS_RX_LOLEN_ACCEPT 0x70 -#define RLN_STATUS_RX_MASK 0x70 - -#define rln_status_write(sc, value) \ - _rln_register_write_1(sc, RLN_REG_STATUS, (value)) -#define rln_status_set(sc, bits) \ - rln_status_write(sc, (sc)->sc_status |= (bits)) -#define rln_status_clear(sc, bits) \ - rln_status_write(sc, (sc)->sc_status &= ~(bits)) -#define _rln_status_setmask(sc, mask, bits) \ -do { \ - int _s; \ - \ - _s = splhigh(); \ - (sc)->sc_status = ((sc)->sc_status & (mask)) | (bits); \ - rln_status_write(sc, (sc)->sc_status); \ - splx(_s); \ -} while (0); -#define rln_status_rx_write(sc, state) \ - _rln_status_setmask((sc), ~RLN_STATUS_RX_MASK, state) -#define rln_status_tx_write(sc, state) \ - _rln_status_setmask((sc), ~RLN_STATUS_TX_MASK, state) -#define rln_status_read(sc) \ - _rln_register_read_1(sc, RLN_REG_STATUS) -#define rln_status_rx_read(sc) \ - (rln_status_read(sc) & ~RLN_STATUS_TX_MASK) -#define rln_status_tx_read(sc) \ - (rln_status_read(sc) & ~RLN_STATUS_RX_MASK) - -static inline int -rln_status_rx_ready(sc) - struct rln_softc *sc; -{ - u_int8_t status; - - status = rln_status_rx_read(sc); - return (status == RLN_STATUS_RX_LOLEN_AVAIL || - status == RLN_STATUS_RX_HILEN_AVAIL || - status == RLN_STATUS_RX_ERROR); -} - -#define rln_status_tx_int(sc) do { \ - int _s = splhigh(); \ - \ - rln_control_clear(sc, RLN_CONTROL_TXINT); \ - rln_control_set(sc, RLN_CONTROL_TXINT); \ - splx(_s); \ -} while (0) -#define rln_status_rx_int(sc) do { \ - int _s = splhigh(); \ - \ - rln_control_clear(sc, RLN_CONTROL_RXINT); \ - rln_control_set(sc, RLN_CONTROL_RXINT); \ - splx(_s); \ -} while (0) - -/* Control register. */ -#define RLN_CONTROL_RXINT 0x01 -#define RLN_CONTROL_TXINT 0x02 -#define RLN_CONTROL_BIT2 0x04 -#define RLN_CONTROL_BIT3 0x08 -#define RLN_CONTROL_RESET 0x10 -#define RLN_CONTROL_16BIT 0x20 -#define RLN_CONTROL_MASK 0x3f - -#define rln_control_write(sc, value) \ - _rln_register_write_1(sc, RLN_REG_CONTROL, \ - (sc)->sc_control = (value)) -#define rln_control_read(sc) \ - _rln_register_read_1(sc, RLN_REG_CONTROL) -#define rln_control_set(sc, bits) \ - rln_control_write(sc, (sc)->sc_control | (bits)) -#define rln_control_clear(sc, bits) \ - rln_control_write(sc, (sc)->sc_control & ~(bits)) -#define rln_control_outofstandby(sc) do { \ - rln_control_write(sc, (sc)->sc_control | RLN_CONTROL_RESET);\ - DELAY(30000); \ - rln_control_write(sc, (sc)->sc_control); \ -} while (0) - -/* Interrupt selection register. */ -#define RLN_INTSEL_IRQMASK 0x07 -#define RLN_INTSEL_ENABLE 0x10 -#define RLN_INTSEL_BIT7 0x80 - -#define rln_intsel_disable(sc) do { \ - int _s; \ - \ - _s = splhigh(); \ - _rln_register_write_1(sc, RLN_REG_INTSEL, \ - (sc)->sc_intsel &= ~RLN_INTSEL_ENABLE); \ - splx(_s); \ -} while (0) -#define rln_intsel_enable(sc) do { \ - int _s; \ - \ - _s = splhigh(); \ - _rln_register_write_1(sc, RLN_REG_INTSEL, \ - (sc)->sc_intsel |= RLN_INTSEL_ENABLE); \ - splx(_s); \ -} while (0) -#define rln_intsel_write(sc, value) \ - _rln_register_write_1(sc, RLN_REG_INTSEL, \ - (sc)->sc_intsel |= (value)) - -/* End of interrupt signal, used on some newer cards. */ -#define rln_eoi(sc) \ - (void) _rln_register_read_1(sc, RLN_REG_EOI) - diff --git a/sys/dev/ic/rlnsubr.c b/sys/dev/ic/rlnsubr.c deleted file mode 100644 index 7c4d2f95196..00000000000 --- a/sys/dev/ic/rlnsubr.c +++ /dev/null @@ -1,941 +0,0 @@ -/* $OpenBSD: rlnsubr.c,v 1.5 2002/03/14 01:26:55 millert Exp $ */ -/* - * David Leonard <d@openbsd.org>, 1999. Public Domain. - * - * Low level card protocol access to the Proxim RangeLAN2 wireless - * network adaptor. - * - * Information and ideas gleaned from - * - disassembly of Dave Koberstein's <davek@komacke.com> Linux driver - * (which is built with Proxim source), - * - Yoichi Shinoda's <shinoda@cs.washington.edu> BSDI driver, and - * - Geoff Voelker's <voelker@cs.washington.edu> Linux port of the same. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/mbuf.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <sys/syslog.h> -#include <sys/device.h> -#include <sys/queue.h> -#include <sys/proc.h> -#include <sys/kernel.h> - -#include <net/if.h> - -#ifdef INET -#include <netinet/in.h> -#include <netinet/if_ether.h> -#endif - -#include <machine/bus.h> -#include <machine/intr.h> - -#include <dev/ic/rln.h> -#include <dev/ic/rlnvar.h> -#include <dev/ic/rlnreg.h> -#include <dev/ic/rlncmd.h> - -static int rln_tx_request(struct rln_softc *, u_int16_t); -static int rln_tx_end(struct rln_softc *); - -/* - * Disables or enables interrupts from the card. Returns the old - * interrupt-enable state. - */ -int -rln_enable(sc, enable) - struct rln_softc * sc; - int enable; -{ - int s; - int was_enabled; - - s = splhigh(); - was_enabled = (sc->sc_intsel & RLN_INTSEL_ENABLE) ? 1 : 0; - if (enable != was_enabled) { - if (enable) - sc->sc_intsel |= RLN_INTSEL_ENABLE; - else - sc->sc_intsel &=~RLN_INTSEL_ENABLE; - _rln_register_write_1(sc, RLN_REG_INTSEL, sc->sc_intsel); - } - splx(s); - return (was_enabled); -} - -/* - * Perform a hard reset of the card. Determines bus width (8 or - * 16 bit), if sc->sc_width is unset. Returns 0 on success. - * Note: takes about 200ms at splhigh, meaning this is an expensive call, - * but normal (error-free) operation of the card will not need more than - * two resets - one at probe time, and the other when the interface is - * brought up. - */ -int -rln_reset(sc) - struct rln_softc * sc; -{ - int s; - int i; - int status; - u_int8_t op = 0x00; - - s = splhigh(); - dprintf(" R["); - if (sc->sc_cardtype & (RLN_CTYPE_UISA | RLN_CTYPE_ONE_PIECE)) - op = 0x04; - if (rln_status_read(sc) & RLN_STATUS_WAKEUP) { - rln_control_write(sc, op); - rln_control_write(sc, op | RLN_CONTROL_RESET); - dprintf(" 7ms"); - DELAY(7000); - rln_control_write(sc, op); - dprintf(" 7ms"); - DELAY(7000); - } - rln_control_write(sc, op); - rln_control_write(sc, op); - rln_control_write(sc, op | RLN_CONTROL_BIT3); - dprintf(" 67ms"); - DELAY(67000); - rln_status_write(sc, 0x00); - if (sc->sc_cardtype & (RLN_CTYPE_UISA | RLN_CTYPE_ONE_PIECE)) - rln_control_write(sc, 0x38); - /* RLN_CONTROL_BIT3 | RLN_CONTROL_RESET | RLN_CONTROL_16BIT */ - else - rln_control_write(sc, 0x2c); - /* RLN_CONTROL_BIT3 | RLN_CONTROL_BIT2 | RLN_CONTROL_16BIT */ - dprintf(" 67ms"); - DELAY(67000); - rln_data_write_2(sc, 0xaa55); - rln_status_write(sc, 0x5a); - splx(s); - for (i = 0; i < 200 * 10; i++) { /* Proxim says 200. */ - if ((status = rln_status_read(sc)) == 0x5a) - break; - DELAY(1000); - } - dprintf(" (%dms)", i); - s = splhigh(); - if (status != 0x5a) { - splx(s); - /* Only winge if bus width not yet probed */ - if (sc->sc_width != 0) - printf("%s: reset timeout\n", sc->sc_dev.dv_xname); - dprintf("]=-1"); - return (-1); - } - if (sc->sc_width == 8) { - if (sc->sc_cardtype & (RLN_CTYPE_UISA | RLN_CTYPE_ONE_PIECE)) - rln_control_write(sc, RLN_CONTROL_BIT3); - else - rln_control_write(sc, RLN_CONTROL_BIT3 | - RLN_CONTROL_BIT2); - rln_data_write_1(sc, 0x20); - } else if (sc->sc_width == 16) { - rln_data_write_2(sc, 0x0000); - } else { - if (rln_data_read_2(sc) == 0x55aa) { - rln_data_write_2(sc, 0x0000); - sc->sc_width = 16; - } else { - if (sc->sc_cardtype & (RLN_CTYPE_UISA | - RLN_CTYPE_ONE_PIECE)) - rln_control_write(sc, RLN_CONTROL_BIT3); - else - rln_control_write(sc, RLN_CONTROL_BIT3 | - RLN_CONTROL_BIT2); - rln_data_write_1(sc, 0x20); - sc->sc_width = 8; - } - /* printf("%s: %d bit bus\n", sc->sc_dev.dv_xname, - sc->sc_width); */ - } - rln_status_write(sc, 0x00); - sc->sc_intsel = 0; - rln_intsel_write(sc, sc->sc_irq); - splx(s); - dprintf("]"); - return (0); -} - -/* - * Sets the new 'wakeup' state. Returns the old wakeup state. - * The special state value RLN_WAKEUP_SET should be used to wake the - * card up. The card can be partially put to sleep (presumably to save - * power) by sending it the 'Standby' command. - */ -u_int8_t -rln_wakeup(sc, wnew) - struct rln_softc * sc; - u_int8_t wnew; -{ - u_int8_t wold, s; - int i; - - /* Save what the last-written values were. */ - wold = (sc->sc_status & RLN_STATUS_WAKEUP) | - (sc->sc_control & RLN_CONTROL_RESET); - - if (wnew == RLN_WAKEUP_SET) { - /* SetWakeupBit() */ - dprintf(" Ws["); - rln_status_set(sc, RLN_STATUS_WAKEUP); - if (0/*LLDInactivityTimeOut && - (sc->sc_cardtype & RLN_CTYPE_OEM)*/) { - dprintf (" 167ms"); - DELAY(167000); - } else { - dprintf (" .1ms"); - DELAY(100); - } - s = rln_status_read(sc); - rln_control_set(sc, RLN_CONTROL_RESET); - if ((s & RLN_STATUS_WAKEUP) != 0) - for (i = 0; i < 9; i++) { - dprintf(" 2ms"); - DELAY(2000); - rln_status_set(sc, RLN_STATUS_WAKEUP); - } - dprintf("]"); - } else { - /* ClearWakeupBit() */ - dprintf(" Wc["); - if ((wnew & RLN_STATUS_WAKEUP) == 0) - rln_status_clear(sc, RLN_STATUS_WAKEUP); - if ((wnew & RLN_CONTROL_RESET) == 0) - rln_control_clear(sc, RLN_CONTROL_RESET); - dprintf("]"); - } - return (wold); -} - -/* - * Performs the first (request) stage of transmitting a command message - * to the card. 'len' is the expected length of the message is needed. - * Returns: 0 on success - * 1 on timeout - * 2 on NAK (card busy, and will need a rln_clear_nak() after 100ms) - */ -static int -rln_tx_request(sc, len) - struct rln_softc * sc; - u_int16_t len; -{ - /* TxRequest() */ - int s; - int i; - u_int8_t status; - - /* u_int8_t w; */ - /* w = rln_wakeup(sc, RLN_WAKEUP_SET); */ - - dprintf(" Tr["); - if (sc->sc_width == 16) { - rln_status_tx_write(sc, RLN_STATUS_TX_HILEN_AVAIL); - rln_data_write_2(sc, len); - rln_status_tx_int(sc); - - s = spl0(); - for (i = 0; i < 600; i++) { - status = rln_status_tx_read(sc); - if (status == RLN_STATUS_TX_HILEN_ACCEPT || - status == RLN_STATUS_TX_ERROR) - break; - DELAY(1000); - } - splx(s); - dprintf(" %dms", i); - if (status == RLN_STATUS_TX_HILEN_ACCEPT) - goto success; - if (status == RLN_STATUS_TX_ERROR) - goto error; - } else if (sc->sc_width == 8) { - rln_status_tx_write(sc, RLN_STATUS_TX_LOLEN_AVAIL); - rln_data_write_1(sc, len & 0xff); - rln_status_tx_int(sc); - s = spl0(); - for (i = 0; i < 6800; i++) { - status = rln_status_tx_read(sc); - if (status == RLN_STATUS_TX_LOLEN_ACCEPT) - break; - DELAY(1000); - } - splx(s); - dprintf(" %dms", i); - if (status == RLN_STATUS_TX_LOLEN_ACCEPT) { - rln_data_write_1(sc, (len >> 8) & 0xff); - rln_status_tx_write(sc, RLN_STATUS_TX_HILEN_AVAIL); - s = spl0(); - for (i = 0; i < 600; i++) { - status = rln_status_tx_read(sc); - if (status == RLN_STATUS_TX_HILEN_ACCEPT || - status == RLN_STATUS_TX_ERROR) - break; - DELAY(1000); - } - splx(s); - dprintf(" %dms", i); - if (status == RLN_STATUS_TX_HILEN_ACCEPT) - goto success; - if (status == RLN_STATUS_TX_ERROR) - goto error; - } - } -#ifdef DIAGNOSTIC - else - panic("rln: bus width"); -#endif - - printf("%s: tx_request timed out, status 0x%02x", - sc->sc_dev.dv_xname, status); - dprintf("]=(1)"); - return (1); - -error: - /* Will need to clear nak within 100 ms. */ - dprintf("]=2"); -#ifdef DIAGNOSTIC - printf("%s: tx protocol fault (nak)\n", sc->sc_dev.dv_xname); -#endif - return (2); - -success: - /* rln_wakeup(sc, w); */ - dprintf("]=0"); - return (0); -} - -/* - * Performs the third (and final) stage of transmitting a command - * message to the card. - * Returns: 0 on command success. - * non-zero on failure (card will need reset) - */ -static int -rln_tx_end(sc) - struct rln_softc * sc; -{ - /* EndOfTx() */ - int i; - int s; - u_int8_t status; - - dprintf(" Te["); - s = spl0(); - for (i = 0; i < 600; i++) { - status = rln_status_tx_read(sc); - if (status == RLN_STATUS_TX_XFR_COMPLETE) - break; - DELAY(1000); - } - splx(s); - if (status == RLN_STATUS_TX_XFR_COMPLETE) { - rln_status_tx_write(sc, RLN_STATUS_TX_IDLE); - dprintf("]=0"); - return (0); - } else { - printf("%s: tx cmd failed (%02x)\n", sc->sc_dev.dv_xname, - status); - rln_need_reset(sc); - dprintf("]=-1"); - return (-1); - } -} - -/* - * Performs first (request) stage of receiving a message from the card. - * Returns: 0 on failure, - * n>0 on success, where 'n' is the length of the message - */ - -int -rln_rx_request(sc, timeo) - struct rln_softc * sc; - int timeo; /* milliseconds */ -{ - /* RxRequest */ - int s; - int len = 0; - int i; - u_int8_t status; - u_int8_t hi, lo; - - dprintf(" Rr["); - status = rln_status_rx_read(sc); - - /* Short wait for states 1|5|6. */ - s = spl0(); - for (i = 0; i < timeo; i++) { - if (status == RLN_STATUS_RX_LOLEN_AVAIL || - status == RLN_STATUS_RX_HILEN_AVAIL || - status == RLN_STATUS_RX_ERROR) - break; - DELAY(1000); - status = rln_status_rx_read(sc); - } - splx(s); - dprintf(" (%dms)",i); - - if (sc->sc_width == 16) { - if (status != RLN_STATUS_RX_HILEN_AVAIL) - goto badstatus_quiet; - /* Read 2 octets. */ - len = rln_data_read_2(sc); - } else if (sc->sc_width == 8) { - if (status != RLN_STATUS_RX_LOLEN_AVAIL) - goto badstatus_quiet; - /* Read low octet. */ - lo = rln_data_read_1(sc); - rln_status_rx_write(sc, RLN_STATUS_RX_LOLEN_ACCEPT); - rln_status_rx_int(sc); - s = spl0(); - for (i = 0; i < 600; i++) { - status = rln_status_rx_read(sc); - if (status == RLN_STATUS_RX_HILEN_AVAIL) - break; - DELAY(1000); - } - splx(s); - if (status != RLN_STATUS_RX_HILEN_AVAIL) - goto badstatus; - /* Read high octet. */ - hi = rln_data_read_1(sc); - len = lo | (hi << 8); - } -#ifdef DIAGNOSTIC - else - panic("rln: bus width %d", sc->sc_width); -#endif - - dprintf(" len=%d]", len); - return (len); - -badstatus: - printf("%s: rx_request timed out, status %02x\n", - sc->sc_dev.dv_xname, status); -badstatus_quiet: - if (status == RLN_STATUS_RX_ERROR) - printf("%s: rx protocol error (nak)\n", sc->sc_dev.dv_xname); - dprintf("]"); - return (-1); -} - -/* Performs part of the second (transfer) stage of receiving a data message. */ -void -rln_rx_pdata(sc, buf, len, pd) - struct rln_softc * sc; - void * buf; - int len; - struct rln_pdata * pd; -{ - char * data = (char *)buf; - - if (pd->p_nremain) { - *data++ = pd->p_data; - if (--len == 0) - return; - } - - pd->p_nremain = 0; - - if (sc->sc_width == 16) { - /* Round down to the closest even multiple. */ - rln_data_read_multi_2(sc, data, len / 2); -#ifdef RLNDEBUG_REG - dprintf(" D>"); - dprinthex(data, len); -#endif - if (len & 1) { - /* Read the last octet plus a bit extra. */ - union { - u_int16_t w; - u_int8_t b[2]; - } u; - - u.w = rln_data_read_2(sc); - data[len - 1] = u.b[0]; - pd->p_data = u.b[1]; - pd->p_nremain = 1; -#ifdef RLNDEBUG_REG - dprintf(" D>{%02x%02x}", u.b[0], u.b[1]); -#endif - } - } else if (sc->sc_width == 8) { - rln_data_read_multi_1(sc, data, len); -#ifdef RLNDEBUG_REG - dprintf(" D>"); - dprinthex(data, len); -#endif - if (len & 1) { - /* Must read multiples of two. */ - pd->p_data = rln_data_read_1(sc); - pd->p_nremain = 1; -#ifdef RLNDEBUG_REG - dprintf(" D>{%02x}", pd->p_data); -#endif - } - } - -} - -int -rln_rx_data(sc, buf, len) - struct rln_softc * sc; - void * buf; - int len; -{ - /* RxData() */ - struct rln_pdata pd = { 0, 0 }; - int s; - int i; - u_int8_t status; - - dprintf(" Rd["); - rln_status_rx_write(sc, RLN_STATUS_RX_HILEN_ACCEPT); - rln_status_rx_int(sc); - s = spl0(); - for (i = 0; i < 600; i++) { - status = rln_status_rx_read(sc); - if (status == RLN_STATUS_RX_XFR) - break; - DELAY(1000); - } - splx(s); - if (status != RLN_STATUS_RX_XFR) { - dprintf("]=-1"); - return (-1); - } - - rln_rx_pdata(sc, buf, len, &pd); -#ifdef DIAGNOSTIC - /* We should have nothing left over. */ - if (pd.p_nremain || len & 1) - panic("rln_rx_data: leftover"); -#endif - - dprintf("]=0"); - return (0); -} - -void -rln_rx_end(sc) - struct rln_softc * sc; -{ - /* EndOfRx() */ - - dprintf(" Re["); - rln_status_rx_write(sc, RLN_STATUS_RX_XFR_COMPLETE); - rln_status_rx_int(sc); - /* rln_wakeup(sc, 0); */ - dprintf("]"); -} - -/* Clear a transmission NAK from the card. */ -void -rln_clear_nak(sc) - struct rln_softc * sc; -{ - /* ClearNAK() */ - - rln_status_tx_write(sc, RLN_STATUS_CLRNAK); - rln_status_tx_int(sc); -} - -/* - * Send a command message to the card. Returns; - * 2: NAK - * -1: failure - * 0: success - */ -int -rln_msg_tx_start(sc, buf, pktlen, state) - struct rln_softc * sc; - void * buf; - int pktlen; - struct rln_msg_tx_state * state; -{ - struct rln_mm_cmd * cmd = (struct rln_mm_cmd *)buf; - int ret; - - state->ien = rln_enable(sc, 0); - state->pd.p_nremain = 0; - - if (!(cmd->cmd_letter == 'A' && cmd->cmd_fn == 6)) /* Standby. */ - state->w = rln_wakeup(sc, RLN_WAKEUP_SET); - else - state->w = RLN_WAKEUP_NOCHANGE; - - ret = rln_tx_request(sc, pktlen); - if (ret == 2) { - rln_clear_nak(sc); - if (sc->sc_cardtype & RLN_CTYPE_OEM) - rln_need_reset(sc); - ret = 2; - } - else if (ret == 1) { - /* Timeout. */ - rln_status_tx_write(sc, RLN_STATUS_TX_XFR); - ret = -1; - } - return (ret); -} - -void -rln_msg_tx_data(sc, buf, len, state) - struct rln_softc * sc; - void * buf; - u_int16_t len; - struct rln_msg_tx_state * state; -{ - char * data = (char *)buf; - - if (sc->sc_width == 16 && state->pd.p_nremain) { - /* XXX htons() needed? */ - union { - u_int8_t b[2]; - u_int16_t w; - } u; - - u.b[0] = state->pd.p_data; - if (len) { - u.b[1] = *data++; - len--; - } else - u.b[1] = '\0'; -#ifdef RLNDEBUG_REG - dprintf(" D<%02x%02x", u.b[0], u.b[1]); -#endif - rln_data_write_2(sc, u.w); - state->pd.p_nremain = 0; - } - - if (len) { - if (sc->sc_width == 16) { - if (len >= 2) - rln_data_write_multi_2(sc, buf, len / 2); - if (len & 1) { - state->pd.p_nremain = 1; - state->pd.p_data = data[len - 1]; - } - } else if (sc->sc_width == 8) - rln_data_write_multi_1(sc, buf, len); -#ifdef DIAGNOSTIC - else - panic("rln_msg_tx_data width %d", sc->sc_width); -#endif -#ifdef RLNDEBUG_REG - dprintf(" D<"); - dprinthex(data, len); -#endif - } -} - - -int -rln_msg_tx_end(sc, state) - struct rln_softc * sc; - struct rln_msg_tx_state * state; -{ - int ret; - - /* Flush the tx buffer. */ - if (state->pd.p_nremain) - rln_msg_tx_data(sc, NULL, 0, state); - -#ifdef DIAGNOSTIC - if (state->pd.p_nremain) - panic("rln_msg_tx_end remain %d", state->pd.p_nremain); -#endif - ret = rln_tx_end(sc); - if (sc->sc_arpcom.ac_if.if_flags & IFF_OACTIVE) - state->w = RLN_WAKEUP_NOCHANGE; - rln_wakeup(sc, state->w); - rln_enable(sc, state->ien); - return (ret); -} - -/* Return the next unique sequence number to use for a transmitted command */ -u_int8_t -rln_newseq(sc) - struct rln_softc * sc; -{ - int s; - u_int8_t seq; - - s = splhigh(); - seq = sc->sc_pktseq++; - if (sc->sc_pktseq > RLN_MAXSEQ) - sc->sc_pktseq = 0; - splx(s); - return (seq); -} - -/* - * Transmit a command message to, and (optionally) receive a response - * message from the card. Each transmitted message has a sequence - * number, and corresponding reply messages have the same sequence - * number. We use the sequence numbers to index the mailboxes so - * that rlnsoftintr() can signal this routine when it has serviced - * and correctly received a response. - */ - -int -rln_msg_txrx(sc, tx, txlen, rx, rxlen) - struct rln_softc * sc; - void * tx; - int txlen; - void * rx; - int rxlen; -{ - struct rln_mm_cmd * txc = (struct rln_mm_cmd *)tx; - struct rln_mm_cmd * rxc = (struct rln_mm_cmd *)rx; - struct rln_msg_tx_state state; - int ien; - int ret; - -#ifdef DIAGNOSTIC - if (rx != NULL && rxlen < sizeof *rxc) - panic("rln_msg_txrx"); -#endif - - txc->cmd_seq = rln_newseq(sc); - -#ifdef RLNDUMP - printf("%s: send %c%d seq %d data ", sc->sc_dev.dv_xname, - txc->cmd_letter, txc->cmd_fn, txc->cmd_seq); - RLNDUMPHEX(txc, sizeof *txc); - printf(":"); - RLNDUMPHEX((char *)tx + sizeof *txc, txlen - sizeof *txc); - printf("\n"); -#endif - - if (rx != NULL) - if (rln_mbox_create(sc, txc->cmd_seq, rx, rxlen) < 0) - /* Mailbox collision. */ - return (-1); - - /* Start the transfer. */ - if ((ret = rln_msg_tx_start(sc, tx, txlen, &state))) { - if (rx != NULL) - rln_mbox_wait(sc, txc->cmd_seq, -1); - return (ret); - } - - /* Always send an even number of octets. */ - rln_msg_tx_data(sc, tx, (txlen + 1) & ~1, &state); - - /* End the transmission. */ - if ((ret = rln_msg_tx_end(sc, &state))) { - /* Destroy mailbox. */ - if (rx != NULL) - rln_mbox_wait(sc, txc->cmd_seq, -1); - return (ret); - } - - /* Don't wait for reply if there is nowhere to put it. */ - if (rx == NULL) - return (0); - - /* Enable interrupts if not already. */ - ien = rln_enable(sc, 1); - - /* Wait for the reply message. */ - if (rln_mbox_wait(sc, txc->cmd_seq, 4000) <= 0) { - printf("%s: lost message %c%d seq %d\n", sc->sc_dev.dv_xname, - txc->cmd_letter, txc->cmd_fn, txc->cmd_seq); - rln_enable(sc, ien); - return (-1); - } - rln_enable(sc, ien); - -#ifdef RLNDUMP - printf("%s: recv %c%d seq %d data ", sc->sc_dev.dv_xname, - rxc->cmd_letter, rxc->cmd_fn, rxc->cmd_seq); - RLNDUMPHEX(rxc, sizeof *rxc); - printf(":"); - RLNDUMPHEX(((char *)rx) + sizeof *rxc, rxlen - sizeof *rxc); - printf("\n"); -#endif - - /* Check for errors in the received message. */ - if (rxc->cmd_error & 0x80) { - printf("%s: command error 0x%02x command %c%d\n", - sc->sc_dev.dv_xname, - rxc->cmd_error & ~0x80, - rxc->cmd_letter, rxc->cmd_fn); - return (-1); - } - - return (0); -} - -/* - * Mailboxes provide a simple way to tell the interrupt - * service routine that someone is expecting a reply message. - * Mailboxes are identified by the message sequence number - * and also hold a pointer to storage supplied by the waiter. - * The interrupt service routine signals the mailbox when it - * gets the reply message. - */ - -/* Create a mailbox for filling. */ -int -rln_mbox_create(sc, seq, buf, len) - struct rln_softc * sc; - u_int8_t seq; - void * buf; - size_t len; -{ - int s; - struct rln_mbox * mb = &sc->sc_mbox[seq]; - - dprintf(" <create %d", seq); - -#ifdef DIAGNOSTIC - if (seq > RLN_NMBOX) - panic("mbox create"); -#endif - - s = splhigh(); - if (mb->mb_state != RLNMBOX_VOID) { -#ifdef DIAGNOSTIC - printf("mbox collision"); -#endif - splx(s); - return (-1); - } - mb->mb_buf = buf; - mb->mb_len = len; - mb->mb_actlen = 0; - mb->mb_state = RLNMBOX_EMPTY; - dprintf(" empty>"); - splx(s); - return (0); -} - - -/* Wait for a mailbox to be filled. */ -int -rln_mbox_wait(sc, seq, timeo) - struct rln_softc * sc; - u_int8_t seq; - int timeo; -{ - int i; - int s; - int ret; - volatile struct rln_mbox * mb = &sc->sc_mbox[seq]; - - dprintf(" <wait %d", seq); - -#ifdef DIAGNOSTIC - if (seq > RLN_NMBOX) - panic("mbox wait"); -#endif - -#if defined(RLN_TSLEEP) - if (!cold) { - tsleep((void *)mb, PRIBIO, "rlnmbox", hz * timeo / 1000); - if (mb->mb_state == RLNMBOX_FILLING) { - /* Must wait until filled. */ - s = spl0(); - while (mb->mb_state == RLNMBOX_FILLING) - ; - splx(s); - } - } else { - /* Autoconfiguration - spin at spl0. */ -#endif - s = spl0(); - i = 0; - while (mb->mb_state == RLNMBOX_EMPTY && i < timeo) { - DELAY(1000); - i++; - } - if (i) - dprintf(" %dms", i); - while (mb->mb_state == RLNMBOX_FILLING) - ; - splx(s); -#if defined(RLN_TSLEEP) - } -#endif - - s = splhigh(); - -#ifdef DIAGNOSTIC - if (mb->mb_state != RLNMBOX_EMPTY && mb->mb_state != RLNMBOX_FILLED) - panic("mbox wait %d", mb->mb_state); -#endif - ret = mb->mb_actlen; - mb->mb_state = RLNMBOX_VOID; - dprintf(" void>=%d", ret); - splx(s); - return (ret); -} - -/* Lock a mailbox for filling. */ -int -rln_mbox_lock(sc, seq, bufp, lenp) - struct rln_softc * sc; - u_int8_t seq; - void ** bufp; - size_t * lenp; -{ - int s; - struct rln_mbox * mb = &sc->sc_mbox[seq]; - - dprintf(" <lock %d", seq); - - s = splhigh(); -#ifdef DIAGNOSTIC - if (seq > RLN_NMBOX) - panic("mbox lock"); -#endif - if (mb->mb_state != RLNMBOX_EMPTY) { - splx(s); - dprintf(" ?>"); - return (-1); - } - - mb->mb_state = RLNMBOX_FILLING; - dprintf(" filling>"); - *bufp = mb->mb_buf; - *lenp = mb->mb_len; - - splx(s); - return (0); -} - -/* Unlock a mailbox and inform the waiter of the actual number of octets. */ -void -rln_mbox_unlock(sc, seq, actlen) - struct rln_softc * sc; - u_int8_t seq; - size_t actlen; -{ - int s; - struct rln_mbox * mb = &sc->sc_mbox[seq]; - - dprintf(" <unlock %d", seq); - - s = splhigh(); -#ifdef DIAGNOSTIC - if (seq > RLN_NMBOX) - panic("mbox unlock seq"); - if (mb->mb_state != RLNMBOX_FILLING) - panic("mbox unlock"); -#endif - mb->mb_state = RLNMBOX_FILLED; - dprintf(" filled>"); - mb->mb_actlen = actlen; -#if defined(RLN_TSLEEP) - wakeup(mb); -#endif - splx(s); -} - diff --git a/sys/dev/ic/rlnvar.h b/sys/dev/ic/rlnvar.h deleted file mode 100644 index e522638fcca..00000000000 --- a/sys/dev/ic/rlnvar.h +++ /dev/null @@ -1,146 +0,0 @@ -/* $OpenBSD: rlnvar.h,v 1.7 2002/06/09 03:14:18 todd Exp $ */ -/* - * David Leonard <d@openbsd.org>, 1999. Public domain. - * - * Proxim RangeLAN2 soft state copy. - */ - -#include <sys/timeout.h> - -/* - * Mailboxes are used to communicate card-initiated messages - * from the interrupt handler to other kernel threads. - */ -struct rln_mbox { - void * mb_buf; /* Message buffer */ - size_t mb_len; /* Message buffer size */ - size_t mb_actlen; /* Actual message size */ - u_int8_t mb_state; /* Mailbox state */ -#define RLNMBOX_VOID 0 -#define RLNMBOX_EMPTY 1 -#define RLNMBOX_FILLING 2 -#define RLNMBOX_FILLED 3 -}; - -#define RLN_NMBOX 0x7c /* Same as max msg seq number */ - -/* Soft state */ -struct rln_softc { - struct device sc_dev; - void *sc_ih; /* Interrupt handler */ - struct arpcom sc_arpcom; /* Ethernet common part */ - bus_space_tag_t sc_iot; /* Bus cookie */ - bus_space_handle_t sc_ioh; /* Bus i/o handle */ - struct timeout sc_timeout; - - u_int8_t sc_width; /* Bus transfer width */ - u_int8_t sc_irq; /* IRQ for card */ - - u_int16_t sc_cardtype; /* Set from config flags */ -#define RLN_CTYPE_OEM 0x01 -#define RLN_CTYPE_UISA 0x02 -#define RLN_CTYPE_ONE_PIECE 0x04 - - u_int8_t sc_intsel; /* Copy of INTSEL */ - u_int8_t sc_status; /* Copy of STATUS */ - u_int8_t sc_control; /* Copy of CONTROL */ -#ifdef RLNDEBUG_REG - u_int16_t dbg_oreg[8]; /* Last reg value written */ -#endif - - u_int8_t sc_pktseq; /* Card message seq no */ - u_int8_t sc_txseq; /* Tx packet seq no */ - - u_int16_t sc_state; /* Soft state. */ -#define RLN_STATE_SYNC 0x0001 /* Card is synchronised */ -#define RLN_STATE_NEEDINIT 0x0002 /* Card needs reset+init */ -#define RLN_STATE_PROMISC 0x0004 /* Receive all packets */ - - struct rln_mbox sc_mbox[0x80]; /* Per-message mailboxes */ - struct rln_param sc_param; /* User controlled parameters */ -}; - -#define rln_need_reset(sc) \ - (sc)->sc_state |= RLN_STATE_NEEDINIT - -/* Structure used to hold partial read state for rln_rx_pdata() */ -struct rln_pdata { - u_int8_t p_data; /* extra data read but not consumed */ - int p_nremain; /* size of unconsumed data */ -}; -#define RLN_PDATA_INIT {0,0} - -/* Structure used to hold partial transmit state for rln_msg_tx_*() */ -struct rln_msg_tx_state { - int ien; /* saved interrupt state */ - u_int8_t w; /* saved wakup state */ - struct rln_pdata pd; /* saved partial write state */ -}; - -struct rln_mm_cmd; /* fwd decl */ - -#define RLN_WAKEUP_SET 0xff -#define RLN_WAKEUP_NOCHANGE (0x80|0x10) - -void rlnconfig(struct rln_softc *); -int rlnintr(void *); -void rlninit(struct rln_softc *); -void rlnstop(struct rln_softc *); -void rlnread(struct rln_softc *, struct rln_mm_cmd *, int); -int rln_enable(struct rln_softc *, int); -int rln_reset(struct rln_softc *); -u_int8_t rln_wakeup(struct rln_softc *, u_int8_t); -int rln_rx_request(struct rln_softc *, int); -int rln_rx_data(struct rln_softc *, void *, int); -void rln_rx_pdata(struct rln_softc *, void *, int, - struct rln_pdata *); -void rln_rx_end(struct rln_softc *); -void rln_clear_nak(struct rln_softc *); -u_int8_t rln_newseq(struct rln_softc *); - -void rln_msg_tx_data(struct rln_softc *, void *, u_int16_t, - struct rln_msg_tx_state *); -int rln_msg_tx_start(struct rln_softc *, void *, int, - struct rln_msg_tx_state *); -int rln_msg_tx_end(struct rln_softc *, - struct rln_msg_tx_state *); -int rln_msg_txrx(struct rln_softc *, void *, int, - void *, int); - -int rln_mbox_create(struct rln_softc *, u_int8_t, void *, - size_t); -int rln_mbox_wait(struct rln_softc *, u_int8_t, int); -int rln_mbox_lock(struct rln_softc *, u_int8_t, void **, - size_t*); -void rln_mbox_unlock(struct rln_softc *, u_int8_t, size_t); - -/* debug all card operations */ -#ifdef RLNDEBUG -#define dprintf(fmt, args...) printf(fmt , ## args) - /* log(LOG_DEBUG, fmt , ## args) */ -#define dprinthex(buf, len) do { \ - unsigned char *_b = (unsigned char *)(buf); \ - int _i, _l=(len); \ - printf("{"); \ - for(_i = 0; _i < _l; _i++) { \ - printf("%02x", _b[_i]); \ - if (_i % 4 == 3 && _i != _l - 1) \ - printf(","); \ - } \ - printf("}"); \ -} while (0) -#else -#define dprintf(fmt, args...) /* nothing */ -#define dprinthex(buf, len) /* nothing */ -#endif - -/* debug messages to/from card. prints 4-octet groups separated by commas */ -#define RLNDUMP -#define RLNDUMPHEX(buf, buflen) do { \ - int _i; \ - for (_i = 0; _i < (buflen); _i++) { \ - printf("%02x", ((unsigned char *)(buf))[_i]); \ - if (_i != (buflen) - 1 && _i % 4 == 3) \ - printf(","); \ - } \ -} while (0) diff --git a/sys/dev/isa/files.isa b/sys/dev/isa/files.isa index 71f606987e1..e9051b11971 100644 --- a/sys/dev/isa/files.isa +++ b/sys/dev/isa/files.isa @@ -1,4 +1,4 @@ -# $OpenBSD: files.isa,v 1.103 2008/04/05 06:20:46 form Exp $ +# $OpenBSD: files.isa,v 1.104 2008/04/23 13:28:59 jsg Exp $ # $NetBSD: files.isa,v 1.21 1996/05/16 03:45:55 mycroft Exp $ # # Config file and device description for machine-independent ISA code. @@ -206,10 +206,6 @@ file dev/isa/if_le_isa.c le_isa attach sm at isa with sm_isa file dev/isa/if_sm_isa.c sm_isa -# RangeLAN2 wireless network -attach rln at isa with rln_isa -file dev/isa/if_rln_isa.c rln_isa - # # ISA Sound hardware # diff --git a/sys/dev/isa/if_rln_isa.c b/sys/dev/isa/if_rln_isa.c deleted file mode 100644 index 874df69165c..00000000000 --- a/sys/dev/isa/if_rln_isa.c +++ /dev/null @@ -1,146 +0,0 @@ -/* $OpenBSD: if_rln_isa.c,v 1.2 2002/03/14 01:26:56 millert Exp $ */ - -/* - * David Leonard <d@openbsd.org>, 1999. Public domain. - * - * RangeLAN2 ISA card. - * - * The DIP switch settings on the card to set the i/o base address are - * - * addr: 1 2 3 4 5 6 7 ['X' = on = down = towards the red/green leds] - * 100: - - - - - X - - * 120: - - X - - X - - * 140: - - - X - X - - * 218: X X - - - - X - * 270: - X X X - - X [default] - * 280: - - - - X - X - * 290: - X - - X - X - * 298: X X - - X - X - * 2a0: - - X - X - X - * 2a8: X - X - X - X - * 2e0: - - X X X - X - * 300: - - - - - X X - * 310: - X - - - X X - * 358: X X - X - X X - * 360: - - X X - X X - * 368: X - X X - X X - * - * PnP: - * PXM0100 "Symphony Cordless PnP ISA Card" - */ - -#include "bpfilter.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/socket.h> -#include <sys/device.h> -#include <sys/queue.h> - -#include <net/if.h> - -#ifdef INET -#include <netinet/in.h> -#include <netinet/if_ether.h> -#endif - -#include <machine/cpu.h> -#include <machine/bus.h> -#include <machine/intr.h> - -#include <dev/ic/rln.h> -#include <dev/ic/rlnvar.h> -#include <dev/ic/rlnreg.h> - -#include <dev/isa/isavar.h> - -static int rln_isa_probe(struct device *, void *, void *); -static void rln_isa_attach(struct device *, struct device *, void *); - -struct cfattach rln_isa_ca = { - sizeof(struct rln_softc), rln_isa_probe, rln_isa_attach -}; - -static const int rln_irq[] = { - 3, 4, 5, 7, 10, 11, 12, 15 -}; -#define NRLN_IRQ (sizeof(rln_irq) / sizeof(rln_irq[0])) - -static int -rln_isa_probe(parent, match, aux) - struct device *parent; - void *match, *aux; -{ - struct isa_attach_args *ia = aux; - struct rln_softc *sc = match; - - /* - * The i/o base addr is set by the dip switches - * and must be specified in the kernel config. - */ - if (ia->ia_iobase == IOBASEUNK) - return (0); - - /* Attempt a card reset through the io ports */ - sc->sc_iot = ia->ia_iot; - sc->sc_width = 0; /* Force width probe */ - if (bus_space_map(sc->sc_iot, ia->ia_iobase, RLN_NPORTS, 0, - &sc->sc_ioh)) - return (0); - - if (rln_reset(sc)) { - bus_space_unmap(sc->sc_iot, sc->sc_ioh, RLN_NPORTS); - return (0); - } - - ia->ia_iosize = RLN_NPORTS; - return (1); -} - -static void -rln_isa_attach(parent, self, aux) - struct device *parent, *self; - void *aux; -{ - struct rln_softc *sc = (void *)self; - struct isa_attach_args *ia = aux; - int irq = ia->ia_irq; - int mask; - int i; - - if (irq == IRQUNK) { - /* Allocate a valid IRQ. */ - mask = 0; - for (i = 0; i < NRLN_IRQ; i++) - mask |= (1 << rln_irq[i]); - if (isa_intr_alloc(ia->ia_ic, mask, IST_EDGE, &irq)) - panic("rln_isa_attach: can't allocate irq"); - } -#ifdef DIAGNOSTIC - else { - /* Check given IRQ is valid. */ - for (i = 0; i < NRLN_IRQ; i++) - if (irq == rln_irq[i]) - break; - if (i == NRLN_IRQ) - printf("rln_isa_probe: using invalid irq %d\n", irq); - } -#endif - - printf(":"); - - sc->sc_ih = isa_intr_establish(ia->ia_ic, irq, IST_EDGE, - IPL_NET, rlnintr, sc, sc->sc_dev.dv_xname); -#ifdef DIAGNOSTIC - if (sc->sc_ih == NULL) - panic("rln_isa_attach: couldn't establish interrupt"); -#endif - - /* Tell the card which IRQ to use. */ - sc->sc_irq = irq; - sc->sc_width = 0; /* re-probe width */ - - printf("%s: RangeLAN2 7100", sc->sc_dev.dv_xname); - rlnconfig(sc); - printf("\n"); -} diff --git a/sys/dev/pcmcia/files.pcmcia b/sys/dev/pcmcia/files.pcmcia index 5190c0f366b..417a9143b0b 100644 --- a/sys/dev/pcmcia/files.pcmcia +++ b/sys/dev/pcmcia/files.pcmcia @@ -1,4 +1,4 @@ -# $OpenBSD: files.pcmcia,v 1.41 2007/05/25 05:33:51 mglocker Exp $ +# $OpenBSD: files.pcmcia,v 1.42 2008/04/23 13:28:59 jsg Exp $ # $NetBSD: files.pcmcia,v 1.9 1998/06/21 18:45:41 christos Exp $ # # Config.new file and device description for machine-independent PCMCIA code. @@ -54,10 +54,6 @@ file dev/pcmcia/if_xe.c xe_pcmcia #attach fdc at pcmcia with fdc_pcmcia #file dev/pcmcia/fdc_pcmcia.c fdc_pcmcia -# Proxim RangeLAN2 PC-Card -attach rln at pcmcia with rln_pcmcia -file dev/pcmcia/if_rln_pcmcia.c rln_pcmcia - # PCMCIA multi-port serial cards #device pcmcom {[slave = -1]} #attach pcmcom at pcmcia diff --git a/sys/dev/pcmcia/if_rln_pcmcia.c b/sys/dev/pcmcia/if_rln_pcmcia.c deleted file mode 100644 index 785f8791533..00000000000 --- a/sys/dev/pcmcia/if_rln_pcmcia.c +++ /dev/null @@ -1,312 +0,0 @@ -/* $OpenBSD: if_rln_pcmcia.c,v 1.15 2005/01/27 17:04:56 millert Exp $ */ -/* - * David Leonard <d@openbsd.org>, 1999. Public domain. - * - * Proxim RangeLAN2 PC-Card and compatibles - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/socket.h> -#include <sys/device.h> -#include <sys/queue.h> - -#include <net/if.h> - -#ifdef INET -#include <netinet/in.h> -#include <netinet/if_ether.h> -#endif - -#include <machine/bus.h> -#include <machine/intr.h> - -#include <dev/ic/rln.h> -#include <dev/ic/rlnvar.h> -#include <dev/ic/rlnreg.h> - -#include <dev/pcmcia/pcmciareg.h> -#include <dev/pcmcia/pcmciavar.h> -#include <dev/pcmcia/pcmciadevs.h> - -struct rln_pcmcia_softc { - struct rln_softc psc_rln; /* real "rln" softc */ - - struct pcmcia_io_handle psc_pcioh; /* PCMCIA i/o information */ - int sc_io_window; /* i/o window for the card */ - struct pcmcia_function *psc_pf; /* our PCMCIA function */ - void *psc_ih; /* our interrupt handle */ -}; - -static int rln_pcmcia_match(struct device *, void *, void *); -static struct rln_pcmcia_product * rln_pcmcia_product_lookup(struct pcmcia_attach_args *); -static void rln_pcmcia_attach(struct device *, struct device *, void *); -static int rln_pcmcia_detach(struct device *, int); -static int rln_pcmcia_activate(struct device *, enum devact); -static int rlnintr_pcmcia(void *arg); - -struct cfattach rln_pcmcia_ca = { - sizeof(struct rln_pcmcia_softc), rln_pcmcia_match, rln_pcmcia_attach, - rln_pcmcia_detach, rln_pcmcia_activate -}; - -static struct rln_pcmcia_product { - u_int16_t manufacturer; - u_int16_t product; - const char *cis[4]; - u_int8_t flags; -} rln_pcmcia_products[] = { - /* Digital RoamAbout 2400 FH, from d@openbsd.org */ - { PCMCIA_VENDOR_PROXIM, - PCMCIA_PRODUCT_PROXIM_ROAMABOUT_2400FH, - PCMCIA_CIS_PROXIM_ROAMABOUT_2400FH, - 0 }, - /* AMP Wireless, from jimduchek@ou.edu */ - { PCMCIA_VENDOR_COMPEX, - PCMCIA_PRODUCT_COMPEX_AMP_WIRELESS, - PCMCIA_CIS_COMPEX_AMP_WIRELESS, - 0 }, - /* Proxim RangeLAN2 7401, from louis@bertrandtech.on.ca */ - { PCMCIA_VENDOR_PROXIM, - PCMCIA_PRODUCT_PROXIM_RANGELAN2_7401, - PCMCIA_CIS_PROXIM_RANGELAN2_7401, - 0 }, - /* Generic and clone cards matched by CIS alone */ - { PCMCIA_VENDOR_INVALID, - PCMCIA_PRODUCT_INVALID, - PCMCIA_CIS_PROXIM_RL2_7200, - 0 }, - { PCMCIA_VENDOR_INVALID, - PCMCIA_PRODUCT_INVALID, - PCMCIA_CIS_PROXIM_RL2_7400, - 0 }, - { PCMCIA_VENDOR_INVALID, - PCMCIA_PRODUCT_INVALID, - PCMCIA_CIS_PROXIM_SYMPHONY, - 0 } -}; -#define NPRODUCTS (sizeof rln_pcmcia_products / sizeof rln_pcmcia_products[0]) - -/* Match the card information with known card types */ -static struct rln_pcmcia_product * -rln_pcmcia_product_lookup(pa) - struct pcmcia_attach_args *pa; -{ - int i, j; - struct rln_pcmcia_product *rpp; - - for (i = 0; i < NPRODUCTS; i++) { - rpp = &rln_pcmcia_products[i]; - if (rpp->manufacturer != PCMCIA_VENDOR_INVALID && - rpp->manufacturer != pa->manufacturer) - continue; - if (rpp->product != PCMCIA_PRODUCT_INVALID && - rpp->product != pa->product) - continue; - for (j = 0; j < 4; j++) { - if (rpp->cis[j] == NULL) - return rpp; - if (pa->card->cis1_info[j] && - strcmp(pa->card->cis1_info[j], rpp->cis[j]) != 0) - break; - } - if (j == 4) - return rpp; - } - return NULL; -} - -/* Do we know this card? */ -static int -rln_pcmcia_match(parent, match, aux) - struct device *parent; - void *match, *aux; -{ - struct pcmcia_attach_args *pa = aux; - - return (rln_pcmcia_product_lookup(pa) != NULL); -} - -/* Attach and configure */ -void -rln_pcmcia_attach(parent, self, aux) - struct device *parent, *self; - void *aux; -{ - struct rln_pcmcia_softc *psc = (void *) self; - struct rln_softc *sc = &psc->psc_rln; - struct pcmcia_attach_args *pa = aux; - struct pcmcia_config_entry *cfe; - struct rln_pcmcia_product *rpp; - const char *intrstr; - - psc->psc_pf = pa->pf; - cfe = SIMPLEQ_FIRST(&psc->psc_pf->cfe_head); - - /* Guess the transfer width we will be using */ - if (cfe->flags & PCMCIA_CFE_IO16) - sc->sc_width = 16; - else if (cfe->flags & PCMCIA_CFE_IO8) - sc->sc_width = 8; - else - sc->sc_width = 0; - -#ifdef DIAGNOSTIC - /* We only expect one i/o region and no memory region */ - if (cfe->num_memspace != 0) - printf(": unexpected number of memory spaces (%d)\n", - cfe->num_memspace); - if (cfe->num_iospace != 1) - printf(": unexpected number of i/o spaces (%d)\n", - cfe->num_iospace); - else if (cfe->iospace[0].length != RLN_NPORTS) - printf(": unexpected size of i/o space (0x%x)\n", - cfe->iospace[0].length); - if (sc->sc_width == 0) - printf(": unknown bus width\n"); -#endif /* DIAGNOSTIC */ - - pcmcia_function_init(psc->psc_pf, cfe); - - /* Allocate i/o space */ - if (pcmcia_io_alloc(psc->psc_pf, 0, RLN_NPORTS, - RLN_NPORTS, &psc->psc_pcioh)) { - printf(": can't allocate i/o space\n"); - return; - } - - sc->sc_iot = psc->psc_pcioh.iot; - sc->sc_ioh = psc->psc_pcioh.ioh; - - /* Map i/o space */ - if (pcmcia_io_map(psc->psc_pf, ((sc->sc_width == 8) ? PCMCIA_WIDTH_IO8 : - (sc->sc_width == 16) ? PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_AUTO), - 0, RLN_NPORTS, &psc->psc_pcioh, &psc->sc_io_window)) { - printf(": can't map i/o space\n"); - return; - } - printf(" port 0x%lx/%d", psc->psc_pcioh.addr, RLN_NPORTS); - - /* Enable the card */ - if (pcmcia_function_enable(psc->psc_pf)) { - printf(": function enable failed\n"); - return; - } - -#ifdef notyet - sc->enable = rln_pcmcia_enable; - sc->disable = rln_pcmcia_disable; -#endif - - rpp = rln_pcmcia_product_lookup(pa); - - /* Check if the device has a separate antenna module */ - sc->sc_cardtype = 0; - switch (psc->psc_pf->ccr_base) { - case 0x0100: - sc->sc_cardtype |= RLN_CTYPE_ONE_PIECE; - break; - case 0x0800: - sc->sc_cardtype &= ~RLN_CTYPE_ONE_PIECE; - break; -#ifdef DIAGNOSTIC - default: - printf(": cannot tell if one or two piece (ccr addr %x)\n", - sc->sc_dev.dv_xname, psc->psc_pf->ccr_base); -#endif - } - - /* The PC-card needs to be told to use 'irq' 15 */ - sc->sc_irq = 15; - - /* - * We need to get an interrupt before configuring, since - * polling registers (the alternative) to reading card - * responses, causes hard lock-ups. - */ - psc->psc_ih = pcmcia_intr_establish(psc->psc_pf, IPL_NET, - rlnintr_pcmcia, sc, sc->sc_dev.dv_xname); - intrstr = pcmcia_intr_string(psc->sc_pf, psc->sc_ih); - if (*intrstr) - printf(", %s", intrstr); - sc->sc_ih = NULL; - -#ifdef DIAGNOSTIC - if (rpp->manufacturer == PCMCIA_VENDOR_INVALID) - printf(" manf %04x prod %04x", pa->manufacturer, pa->product); -#endif - - rln_reset(sc); - rlnconfig(sc); - printf("\n"); -} - -static int -rln_pcmcia_detach(dev, flags) - struct device *dev; - int flags; -{ - struct rln_pcmcia_softc *psc = (struct rln_pcmcia_softc *)dev; - struct rln_softc *sc = (struct rln_softc *)dev; - struct ifnet *ifp = &sc->sc_arpcom.ac_if; - int rv = 0; - - pcmcia_io_unmap(psc->psc_pf, psc->sc_io_window); - pcmcia_io_free(psc->psc_pf, &psc->psc_pcioh); - - ether_ifdetach(ifp); - if_detach(ifp); - - return (rv); -} - -static int -rln_pcmcia_activate(dev, act) - struct device *dev; - enum devact act; -{ - struct rln_pcmcia_softc *psc = (struct rln_pcmcia_softc *)dev; - struct rln_softc *sc = (struct rln_softc *)dev; - struct ifnet *ifp = &sc->sc_arpcom.ac_if; - int s; - - s = splnet(); - switch (act) { - case DVACT_ACTIVATE: - pcmcia_function_enable(psc->psc_pf); - psc->psc_ih = pcmcia_intr_establish(psc->psc_pf, IPL_NET, - rlnintr_pcmcia, psc, sc->sc_dev.dv_xname); - rlninit(sc); - break; - - case DVACT_DEACTIVATE: - ifp->if_timer = 0; - if (ifp->if_flags & IFF_RUNNING) - rlnstop(sc); - pcmcia_intr_disestablish(psc->psc_pf, psc->psc_ih); - pcmcia_function_disable(psc->psc_pf); - break; - } - splx(s); - return (0); -} - -/* Interrupt handler */ -static int -rlnintr_pcmcia(arg) - void *arg; -{ - struct rln_softc *sc = (struct rln_softc *)arg; - struct rln_pcmcia_softc *psc = (struct rln_pcmcia_softc *)sc; - int opt; - int ret; - - /* Need to immediately read/write the option register for PC-card */ - opt = pcmcia_ccr_read(psc->psc_pf, PCMCIA_CCR_OPTION); - pcmcia_ccr_write(psc->psc_pf, PCMCIA_CCR_OPTION, opt); - - /* Call actual interrupt handler */ - ret = rlnintr(sc); - - return (ret); -} |