summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/files.i3862
-rw-r--r--sys/dev/arl/if_arl.c973
-rw-r--r--sys/dev/arl/if_arl_isa.c354
-rw-r--r--sys/dev/arl/if_arlreg.h310
-rw-r--r--sys/i386/conf/NOTES5
-rw-r--r--sys/modules/Makefile2
-rw-r--r--sys/modules/arl/Makefile10
7 files changed, 1656 insertions, 0 deletions
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index d0a98b8..ee0bf1a 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -122,6 +122,8 @@ dev/aic/aic_isa.c optional aic isa
dev/ar/if_ar.c optional ar
dev/ar/if_ar_pci.c optional ar pci
dev/ar/if_ar_isa.c optional ar isa
+dev/arl/if_arl.c optional arl
+dev/arl/if_arl_isa.c optional arl isa
dev/cm/if_cm_isa.c optional cm isa
dev/ctau/ctau.c optional ctau
dev/ctau/ctddk.c optional ctau
diff --git a/sys/dev/arl/if_arl.c b/sys/dev/arl/if_arl.c
new file mode 100644
index 0000000..63bb4b7
--- /dev/null
+++ b/sys/dev/arl/if_arl.c
@@ -0,0 +1,973 @@
+/*
+ * $RISS: if_arl/dev/arl/if_arl.c,v 1.5 2004/01/22 12:49:05 frol Exp $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/proc.h>
+#include <sys/conf.h>
+
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_media.h>
+#include <net/ethernet.h>
+#include <net/bpf.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <machine/clock.h>
+
+#include <dev/arl/if_arlreg.h>
+
+/*#define DEBUG */
+#ifdef DEBUG
+#define D(x) {printf("arl%d: ", sc->arl_unit); printf x; }
+#else
+#define D(x)
+#endif
+
+/*
+ * channel attention
+ */
+#define ARL_CHANNEL(sc) \
+ { \
+ D(("channel ctrl %x reg %x\n", sc->arl_control, ar->controlRegister)); \
+ ar->controlRegister = (sc->arl_control ^= ARL_CHANNEL_ATTENTION); \
+ }
+
+/*
+ * Check registration
+ */
+#define ARL_CHECKREG(sc) (ar->registrationMode && ar->registrationStatus == 0)
+
+#ifndef BPF_MTAP
+#define BPF_MTAP(_ifp,_m) \
+ do { \
+ if ((_ifp)->if_bpf) \
+ bpf_mtap((_ifp), (_m)); \
+ } while (0)
+#endif
+
+#if __FreeBSD_version < 500100
+#define BROADCASTADDR (etherbroadcastaddr)
+#define _ARL_CURPROC (curproc)
+#else
+#define BROADCASTADDR (sc->arpcom.ac_if.if_broadcastaddr)
+#define _ARL_CURPROC (curthread)
+#endif
+
+static void arl_hwreset (struct arl_softc *);
+static void arl_reset (struct arl_softc *);
+static int arl_ioctl (struct ifnet *, u_long, caddr_t);
+static void arl_init (void *);
+static void arl_start (struct ifnet *);
+
+static void arl_watchdog (struct ifnet *);
+static void arl_waitreg (struct ifnet *);
+
+static void arl_enable (struct arl_softc *);
+static void arl_config (struct arl_softc *);
+static int arl_command (struct arl_softc *);
+static void arl_put (struct arl_softc *);
+
+static void arl_read (struct arl_softc *, caddr_t, int);
+static void arl_recv (struct arl_softc *);
+static struct mbuf* arl_get (caddr_t, int, int, struct ifnet *);
+
+devclass_t arl_devclass;
+
+/*
+ * Attach device
+ */
+int
+arl_attach(dev)
+ device_t dev;
+{
+ struct arl_softc* sc = device_get_softc(dev);
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ int attached;
+
+ D(("attach\n"));
+
+ if (ar->configuredStatusFlag == 0 && bootverbose)
+ printf("arl%d: card is NOT configured\n", sc->arl_unit);
+
+ arl_reset (sc);
+ attached = (ifp->if_softc != 0);
+
+ /* Initialize ifnet structure. */
+ ifp->if_softc = sc;
+#if __FreeBSD_version < 502000
+ ifp->if_unit = sc->arl_unit;
+ ifp->if_name = "arl";
+#else
+ if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+#endif
+ ifp->if_mtu = ETHERMTU;
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_output = ether_output;
+ ifp->if_start = arl_start;
+ ifp->if_ioctl = arl_ioctl;
+ ifp->if_watchdog = arl_watchdog;
+ ifp->if_init = arl_init;
+ ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
+ ifp->if_baudrate = 2000000;
+ ifp->if_timer = 0;
+
+ /*
+ * Attach the interface
+ */
+ if (!attached) {
+#if __FreeBSD_version < 500100
+ ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
+#else
+ ether_ifattach(ifp, sc->arpcom.ac_enaddr);
+#endif
+ }
+
+ return (0);
+}
+
+/*
+ * Hardware reset
+ * reset all setting to default ( setted ARLANDGS )
+ */
+static void
+arl_hwreset(sc)
+ struct arl_softc *sc;
+{
+ D(("hw reset\n"));
+
+ ar->controlRegister = 1;
+ DELAY(ARDELAY1);
+
+ if (arl_wait_reset(sc, 0x24, ARDELAY1))
+ arl_stop(sc);
+
+ ar->controlRegister = (sc->arl_control = 1);
+ DELAY(ARDELAY1);
+}
+
+
+/*
+ * wait arlan command
+ */
+static int
+arl_command(sc)
+ struct arl_softc *sc;
+{
+ int i; /* long stuppid delay ??? */
+
+ D(("commandByte %x\n", ar->commandByte));
+
+ for (i = 100000; ar->commandByte && i; i--)
+ ;
+
+ if (i == 0)
+ ar->commandByte = 0;
+
+ return (i == 0);
+}
+
+/*
+ * Enable for recieveng
+ */
+static void
+arl_enable(sc)
+ struct arl_softc *sc;
+{
+ D(("enable\n"));
+ sc->arl_control = (ARL_INTERRUPT_ENABLE | ARL_CLEAR_INTERRUPT);
+ ar->controlRegister = sc->arl_control;
+ arl_command(sc);
+
+ ar->rxStatusVector = 0;
+ ar->commandByte = 0x83;
+ ar->commandParameter[0] = 1;
+ ARL_CHANNEL(sc);
+ arl_command(sc);
+}
+
+/*
+ * reset and set user parameters
+ */
+static void
+arl_reset(sc)
+ struct arl_softc *sc;
+{
+ D(("reset\n"));
+ arl_hwreset(sc);
+
+ ar->resetFlag1 = 1;
+ bzero((ar), 0x1FF0); /* fill memory board with 0 */
+ ar->resetFlag1 = 0;
+
+ sc->arl_control = 0;
+
+/* if (arl_wait_reset(sc, 0x168, ARDELAY1))
+ return;
+ */
+#if 1
+ {
+ int cnt = 0x168;
+ int delay = ARDELAY1;
+
+ ar->resetFlag = 0xFF; /* wish reset */
+ ar->controlRegister = 0; /* unreeze - do it */
+
+ while (ar->resetFlag && cnt--)
+ DELAY(delay);
+
+ if (cnt == 0) {
+ printf("arl%d: reset timeout\n", sc->arl_unit);
+ return;
+ }
+
+ D(("reset wait %d\n", 0x168 - cnt));
+ }
+#endif
+
+ if (ar->diagnosticInfo != 0xff) {
+ printf("arl%d: reset error\n", sc->arl_unit);
+ return;
+ }
+ arl_config(sc);
+}
+
+/*
+ * configure radio parameters
+ */
+static void
+arl_config(sc)
+ struct arl_softc *sc;
+{
+ int i;
+
+ D(("config\n"));
+
+ SET_ARL_PARAM(spreadingCode);
+ SET_ARL_PARAM(channelNumber);
+ SET_ARL_PARAM(channelSet);
+ SET_ARL_PARAM(registrationMode);
+ SET_ARL_PARAM(priority);
+ SET_ARL_PARAM(receiveMode);
+
+ bcopy(arcfg.sid, ar->systemId, 4 * sizeof(ar->systemId[0]));
+ bcopy(arcfg.specifiedRouter, ar->specifiedRouter, ETHER_ADDR_LEN);
+ bcopy(arcfg.lanCardNodeId, ar->lanCardNodeId, ETHER_ADDR_LEN);
+
+ bzero(ar->name, ARLAN_NAME_SIZE); /* clear name */
+ strncpy(ar->name, arcfg.name, ARLAN_NAME_SIZE);
+
+ ar->diagnosticInfo = 0;
+ ar->commandByte = 1;
+ ARL_CHANNEL(sc);
+ DELAY(ARDELAY1);
+/*
+ if (arl_command(sc) != 0) {
+ int i;
+
+ for (i = 0x168; ar->diagnosticInfo == 0 && i; i--) {
+ DELAY(ARDELAY1);
+ }
+
+ if (i != 0 && ar->diagnosticInfo != 0xff)
+ printf("arl%d: config error\n", sc->arl_unit);
+ else if (i == 0)
+ printf("arl%d: config timeout\n", sc->arl_unit);
+
+ } else
+ printf("arl%d: config failed\n", sc->arl_unit);
+*/
+ if (arl_command(sc)) {
+ D(("config failed\n"));
+ return;
+ }
+
+ for (i = 0x168; ar->diagnosticInfo == 0 && i; i--)
+ DELAY(ARDELAY1);
+
+ if (i == 0) {
+ D(("config timeout\n"));
+ return;
+ }
+
+ if (ar->diagnosticInfo != 0xff) {
+ D(("config error\n"));
+ return;
+ }
+
+ D(("config lanCardNodeId %6D\n", ar->lanCardNodeId, ":"));
+ D(("config channel set %d, frequency %d, spread %d, mode %d\n",
+ ar->channelSet,
+ ar->channelNumber,
+ ar->spreadingCode,
+ ar->registrationMode));
+ /* clear quality stat */
+ bzero(&(aqual), ARLAN_MAX_QUALITY * sizeof(aqual[0]));
+}
+
+/*
+ * Socket Ioctl's.
+ */
+static int
+arl_ioctl(ifp, cmd, data)
+ register struct ifnet *ifp;
+ u_long cmd;
+ caddr_t data;
+{
+ struct arl_softc *sc = ifp->if_softc;
+ struct ifreq *ifr = (struct ifreq *)data;
+ d_thread_t *td = _ARL_CURPROC;
+ struct arl_req arlan_io;
+ int count, s, error = 0;
+ caddr_t user;
+
+ D(("ioctl %lx\n", cmd));
+ s = splimp();
+
+ switch (cmd) {
+ case SIOCSIFADDR:
+ case SIOCGIFADDR:
+ case SIOCSIFMTU:
+ error = ether_ioctl(ifp, cmd, data);
+ break;
+
+ case SIOCSIFFLAGS:
+ if (ifp->if_flags & IFF_UP) {
+ if (!(ifp->if_flags & IFF_RUNNING))
+ arl_init(sc);
+ } else {
+ if (ifp->if_flags & IFF_RUNNING)
+ arl_stop(sc);
+ }
+ break;
+
+#define GET_PARAM(name) (arlan_io.cfg.name = ar->name)
+
+#define GET_COPY_PARAM(name) \
+ { \
+ bzero(arlan_io.cfg.name, sizeof(arlan_io.cfg.name)); \
+ bcopy(ar->name, arlan_io.cfg.name, sizeof(arlan_io.cfg.name)); \
+ }
+
+ case SIOCGARLALL:
+ bzero(&arlan_io, sizeof(arlan_io));
+ if (!suser(td)) {
+ bcopy(ar->systemId, arlan_io.cfg.sid, 4);
+ }
+
+ GET_COPY_PARAM(name);
+ GET_COPY_PARAM(lanCardNodeId);
+ GET_COPY_PARAM(specifiedRouter);
+ GET_PARAM(channelNumber);
+ GET_PARAM(channelSet);
+ GET_PARAM(spreadingCode);
+ GET_PARAM(registrationMode);
+ GET_PARAM(hardwareType);
+ GET_PARAM(majorHardwareVersion);
+ GET_PARAM(minorHardwareVersion);
+ GET_PARAM(radioModule);
+ GET_PARAM(priority);
+ GET_PARAM(receiveMode);
+ arlan_io.cfg.txRetry = arcfg.txRetry;
+
+ user = (void *)ifr->ifr_data;
+ for (count = 0; count < sizeof(arlan_io); count++)
+ if (subyte(user + count, ((char *)&arlan_io)[count]))
+ return (EFAULT);
+ break;
+
+#define SET_PARAM(name) \
+ do { \
+ if (arlan_io.what_set & ARLAN_SET_##name) \
+ arcfg.name = arlan_io.cfg.name; \
+ } while (0)
+#define SET_COPY_PARAM(name) \
+ do { \
+ if (arlan_io.what_set & ARLAN_SET_##name) { \
+ bzero(arcfg.name, sizeof(arcfg.name)); \
+ bcopy(arlan_io.cfg.name, arcfg.name, sizeof(arcfg.name)); \
+ } \
+ } while (0)
+
+ case SIOCSARLALL:
+ if (suser(td))
+ break;
+
+ user = (void *)ifr->ifr_data;
+ for (count = 0; count < sizeof(arlan_io); count++) {
+ if (fubyte(user + count) < 0)
+ return (EFAULT);
+ }
+
+ bcopy(user, (char *)&arlan_io, sizeof(arlan_io));
+
+ D(("need set 0x%04x\n", arlan_io.what_set));
+
+ if (arlan_io.what_set) {
+ SET_COPY_PARAM(name);
+ SET_COPY_PARAM(sid);
+ SET_COPY_PARAM(specifiedRouter);
+ SET_COPY_PARAM(lanCardNodeId);
+ SET_PARAM(channelSet);
+ SET_PARAM(channelNumber);
+ SET_PARAM(spreadingCode);
+ SET_PARAM(registrationMode);
+ SET_PARAM(priority);
+ SET_PARAM(receiveMode);
+
+ if (arlan_io.what_set & ARLAN_SET_txRetry)
+ arcfg.txRetry = arlan_io.cfg.txRetry;
+
+ arl_config(sc);
+ }
+#undef SET_COPY_PARAM
+#undef SET_PARAM
+#undef GET_COPY_PARAM
+#undef GET_PARAM
+ break;
+
+ case SIOCGARLQLT:
+ user = (void *)ifr->ifr_data;
+ for (count = 0; count < sizeof(struct arl_quality); count++) {
+ if (fubyte(user + count) < 0)
+ return (EFAULT);
+ }
+ while (ar->interruptInProgress) ; /* wait */
+ bcopy(&(aqual), (void *)ifr->ifr_data, sizeof(aqual));
+ break;
+
+ case SIOCGARLSTB:
+ user = (void *)ifr->ifr_data;
+ for (count = 0; count < sizeof(struct arl_stats); count++) {
+ if (fubyte(user + count) < 0)
+ return (EFAULT);
+ }
+
+ while (ar->lancpuLock) ;
+ ar->hostcpuLock = 1;
+ bcopy(&(ar->stat), (void *)ifr->ifr_data, sizeof(struct arl_stats));
+ ar->hostcpuLock = 0;
+ break;
+
+ default:
+ error = EINVAL;
+ }
+
+ splx(s);
+
+ return (error);
+}
+
+/*
+ * Wait registration
+ */
+static void
+arl_waitreg(ifp)
+ struct ifnet *ifp;
+{
+ struct arl_softc *sc = ifp->if_softc;
+
+ D(("wait reg\n"));
+
+ if (ifp->if_flags & IFF_RUNNING) {
+ if (ARL_CHECKREG(sc)) {
+ /* wait registration */
+ D(("wait registration\n"));
+ ifp->if_watchdog = arl_waitreg;
+ ifp->if_timer = 2;
+ } else {
+ /* registration restored */
+ D(("registration restored\n"));
+ ifp->if_timer = 0;
+ arl_init(sc);
+ }
+ }
+}
+
+/*
+ * Handle transmit timeouts.
+ */
+static void
+arl_watchdog(ifp)
+ struct ifnet *ifp;
+{
+ struct arl_softc *sc = ifp->if_softc;
+
+ if (!(ifp->if_flags & IFF_RUNNING))
+ return;
+
+ D(("device timeout\n"));
+
+ if (ARL_CHECKREG(sc)) {
+ /* Lost registratoin */
+ D(("timeout lost registration\n"));
+ ifp->if_watchdog = arl_waitreg;
+ ifp->if_timer = 2;
+ }
+}
+
+/*
+ * Initialize
+ */
+static void
+arl_init(xsc)
+ void *xsc;
+{
+ struct arl_softc *sc = xsc;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ int s;
+
+ D(("init\n"));
+
+ if (TAILQ_EMPTY(&ifp->if_addrhead))
+ return;
+
+ s = splimp();
+
+ if (ARL_CHECKREG(sc))
+ arl_reset(sc);
+
+ arl_enable(sc);
+
+ /* set flags */
+
+ ifp->if_flags |= IFF_RUNNING;
+ ifp->if_flags &= ~IFF_OACTIVE;
+
+ arl_start(ifp);
+
+ splx(s);
+ D(("init done\n"));
+}
+
+/*
+ * Put buffer into arlan buffer and start transmit
+ */
+static void
+arl_put(sc)
+ struct arl_softc *sc;
+{
+ struct arl_tx_param txp;
+ int i;
+
+ if (ARL_CHECKREG(sc))
+ sc->arpcom.ac_if.if_oerrors++;
+
+ /* copy dst adr */
+ for(i = 0; i < 6; i++)
+ txp.dest[i] = sc->arl_tx[i];
+ txp.clear = 0;
+ txp.retries = arcfg.txRetry; /* use default value */
+ txp.routing = 1;
+ txp.scrambled = 0;
+ txp.offset = (intptr_t)ar->txBuffer - (intptr_t)(ar);
+ txp.length = sc->tx_len - ARLAN_HEADER_SIZE;
+
+#ifdef SEND_ARLAN_HEADER
+ if (ar->registrationMode != 1)
+ txp.length = sc->tx_len;
+#endif
+
+ /* copy from internal buffer to adapter memory */
+#ifdef SEND_ARLAN_HEADER
+ if (ar->registrationMode)
+#endif
+ bcopy(sc->arl_tx + ARLAN_HEADER_SIZE,
+ ar->txBuffer,
+ sc->tx_len - ARLAN_HEADER_SIZE);
+#ifdef SEND_ARLAN_MODE
+ else
+ bcopy(sc->arl_tx, ar->txBuffer, sc->tx_len);
+#endif
+
+ /* copy command parametr */
+ bcopy(&txp, ar->commandParameter, 14);
+ ar->commandByte = 0x85; /* send command */
+ ARL_CHANNEL(sc);
+ if (arl_command(sc))
+ sc->arpcom.ac_if.if_oerrors++;
+}
+
+/*
+ * start output
+ */
+static void
+arl_start(ifp)
+ struct ifnet *ifp;
+{
+ struct arl_softc *sc;
+ struct mbuf *m;
+ struct mbuf *m0 = NULL;
+
+ sc = ifp->if_softc;
+
+ D(("start\n"));
+
+ /* Don't do anything if output is active */
+ if (ifp->if_flags & IFF_OACTIVE)
+ return;
+
+ /* Dequeue the next datagram */
+ IF_DEQUEUE(&ifp->if_snd, m0);
+
+ /* If there's nothing to send, return. */
+ if (m0 != NULL) {
+ ifp->if_flags |= IFF_OACTIVE;
+
+ /* Copy the datagram to the buffer. */
+ sc->tx_len = 0;
+ for(m = m0; m != NULL; m = m->m_next) {
+ if (m->m_len == 0)
+ continue;
+ bcopy(mtod(m, caddr_t),
+ sc->arl_tx + sc->tx_len, m->m_len);
+ sc->tx_len += m->m_len;
+ }
+
+ /* if packet size is less than minimum ethernet frame size,
+ * pad it with zeroes to that size */
+ if (sc->tx_len < ETHER_MIN_LEN) {
+ bzero(sc->arl_tx + sc->tx_len, ETHER_MIN_LEN - sc->tx_len);
+ sc->tx_len = ETHER_MIN_LEN;
+ }
+
+ /* Give the packet to the bpf, if any */
+ BPF_MTAP(ifp, m0);
+
+ m_freem(m0);
+
+ /* Now transmit the datagram */
+ ifp->if_timer = 1; /* wait 1 sec */
+
+ ifp->if_watchdog = arl_watchdog;
+ arl_put(sc);
+ }
+}
+
+/*
+ * stop interface
+ */
+void
+arl_stop(sc)
+ struct arl_softc *sc;
+{
+ struct ifnet *ifp;
+ int s;
+
+ s = splimp();
+
+ ifp = &sc->arpcom.ac_if;
+
+ ifp->if_timer = 0; /* disable timer */
+ ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
+ /* arl_hwreset( unit ); */
+ sc->rx_len = 0;
+ sc->tx_len = 0;
+ /* disable interrupt */
+ ar->controlRegister = 0;
+
+ splx(s);
+}
+
+/*
+ * Pull read data off a interface.
+ * Len is length of data, with local net header stripped.
+ */
+static struct mbuf*
+arl_get(buf, totlen, off0, ifp)
+ caddr_t buf;
+ int totlen;
+ int off0;
+ struct ifnet * ifp;
+{
+ struct mbuf *top, **mp, *m;
+ int off = off0, len;
+ caddr_t cp = buf;
+ char *epkt;
+
+ cp = buf;
+ epkt = cp + totlen;
+
+ if (off) {
+ cp += off + 2 * sizeof(u_short);
+ totlen -= 2 * sizeof(u_short);
+ }
+
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == 0)
+ return (0);
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = totlen;
+ m->m_len = MHLEN;
+ top = 0;
+ mp = &top;
+ while (totlen > 0) {
+ if (top) {
+ MGET(m, M_DONTWAIT, MT_DATA);
+ if (m == 0) {
+ m_freem(top);
+ return (0);
+ }
+ m->m_len = MLEN;
+ }
+ len = min(totlen, epkt - cp);
+ if (len >= MINCLSIZE) {
+ MCLGET(m, M_DONTWAIT);
+ if (m->m_flags & M_EXT)
+ m->m_len = len = min(len, MCLBYTES);
+ else
+ len = m->m_len;
+ } else {
+ /*
+ * * Place initial small packet/header at end of mbuf.
+ * */
+ if (len < m->m_len) {
+ if (top == 0 && len + max_linkhdr <= m->m_len)
+ m->m_data += max_linkhdr;
+ m->m_len = len;
+ } else
+ len = m->m_len;
+ }
+ bcopy(cp, mtod(m, caddr_t), (unsigned)len);
+ cp += len;
+ *mp = m;
+ mp = &m->m_next;
+ totlen -= len;
+ if (cp == epkt)
+ cp = buf;
+ }
+
+ return (top);
+}
+
+/* ------------------------------------------------------------------
+ * * Pass a packet up to the higher levels.
+ * */
+static void
+arl_read(sc, buf, len)
+ struct arl_softc *sc;
+ caddr_t buf;
+ int len;
+{
+ register struct ether_header *eh;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ struct mbuf *m;
+
+ eh = (struct ether_header *)buf;
+ /*
+ * Check if there's a bpf filter listening on this interface.
+ * If so, hand off the raw packet to bpf.
+ */
+ if (ifp->if_bpf) {
+ /*
+ * Note that the interface cannot be in promiscuous mode if
+ * there are no bpf listeners. And if el are in promiscuous
+ * mode, el have to check if this packet is really ours.
+ *
+ * This test does not support multicasts.
+ */
+ if ((ifp->if_flags & IFF_PROMISC)
+ && bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
+ sizeof(eh->ether_dhost)) != 0
+ && bcmp(eh->ether_dhost, BROADCASTADDR,
+ sizeof(eh->ether_dhost)) != 0)
+ return;
+ }
+ /*
+ * Pull packet off interface.
+ */
+#if __FreeBSD_version < 500100
+ buf += sizeof(struct ether_header);
+ len -= sizeof(struct ether_header);
+#endif
+ m = arl_get(buf, len, 0, ifp);
+ if (m == 0)
+ return;
+
+#if __FreeBSD_version < 500100
+ ether_input(ifp, eh, m);
+#else
+ (*ifp->if_input)(ifp, m);
+#endif
+}
+
+/*
+ * get packet from adapter
+ */
+static void
+arl_recv(sc)
+ struct arl_softc *sc;
+{
+ sc->rx_len = ar->rxLength;
+
+ if (sc->rx_len) {
+#ifdef SEND_ARLAN_HEADER
+ if (ar->registrationMode == 1) {
+#endif
+ bcopy(ar->ultimateDestAddress, sc->arl_rx, 6);
+ bcopy(ar->rxSrc, (char*)sc->arl_rx + 6, 6);
+ bcopy((char *)(ar) + ar->rxOffset,
+ (char *)sc->arl_rx + 12,
+ sc->rx_len);
+ sc->rx_len += ARLAN_HEADER_SIZE;
+#ifdef SEND_ARLAN_HEADER
+ } else {
+ bcopy((char *)(ar) + ar->rxOffset,
+ (char *)sc->arl_rx, sc->rx_len);
+ }
+#endif
+ }
+}
+
+/*
+ * Ethernet interface interrupt processor
+ */
+void
+arl_intr(arg)
+ void *arg;
+{
+ register struct arl_softc *sc = (struct arl_softc *) arg;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ /* enable interrupt */
+ ar->controlRegister = (sc->arl_control & ~ARL_CLEAR_INTERRUPT);
+ ar->controlRegister = (sc->arl_control | ARL_CLEAR_INTERRUPT);
+
+ if (ar->txStatusVector) {
+ if (ar->txStatusVector != 1)
+ sc->arpcom.ac_if.if_collisions++;
+ ifp->if_timer = 0; /* disable timer */
+ ifp->if_flags &= ~IFF_OACTIVE;
+ arl_start(ifp);
+ ar->txStatusVector = 0;
+/* (sc->quality.txLevel)[ar->txAckQuality & 0x0f]++;
+ (sc->quality.txQuality)[(ar->txAckQuality & 0xf0) >> 4]++;*/
+ }
+
+ if (ar->rxStatusVector) {
+/* (sc->quality.rxLevel)[ar->rxQuality & 0x0f]++;
+ (sc->quality.rxQuality)[(ar->rxQuality & 0xf0) >> 4]++; */
+ if (ar->rxStatusVector == 1) { /* it is data frame */
+ arl_recv(sc);
+ arl_read(sc, sc->arl_rx, sc->rx_len);
+ ifp->if_opackets++;
+ }
+ ar->rxStatusVector = 0;
+
+ ar->commandByte = 0x83;
+ ar->commandParameter[0] = 1;
+ ARL_CHANNEL(sc);
+ if (arl_command(sc))
+ ifp->if_ierrors++;
+ }
+
+ return;
+}
+
+/*
+ * waiting for resetFlag dropped
+ */
+int
+arl_wait_reset(sc, cnt, delay)
+ struct arl_softc *sc;
+ int cnt;
+ int delay;
+{
+ D(("wait_reset cnt=%d delay=%d\n", cnt, delay));
+
+ ar->resetFlag = 1; /* wish reset */
+ ar->controlRegister = 0; /* unreeze - do it */
+
+ while (ar->resetFlag && cnt--)
+ DELAY(delay);
+
+ D(("reset done. %d cycles left\n", cnt));
+
+ if (cnt == 0)
+ printf("arl%d: reset failed\n", sc->arl_unit);
+
+ return (cnt == 0);
+}
+
+/*
+ * Allocate an irq resource with the given resource id
+ */
+int
+arl_alloc_irq(dev, rid, flags)
+ device_t dev;
+ int rid;
+ int flags;
+{
+ struct arl_softc *sc = device_get_softc(dev);
+ struct resource *res;
+
+ res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+ 0ul, ~0ul, 1, (RF_ACTIVE | flags));
+ if (res) {
+ sc->irq_rid = rid;
+ sc->irq_res = res;
+ return (0);
+ } else
+ return (ENOENT);
+}
+
+/*
+ * Allocate an memory resource with the given resource id
+ */
+int
+arl_alloc_memory(dev, rid, size)
+ device_t dev;
+ int rid;
+ int size;
+{
+ struct arl_softc *sc = device_get_softc(dev);
+ struct resource *res;
+
+ res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+ 0ul, ~0ul, size, RF_ACTIVE);
+ if (res) {
+ sc->mem_rid = rid;
+ sc->mem_res = res;
+ return (0);
+ } else
+ return (ENOENT);
+}
+
+/*
+ * Release all resources
+ */
+void
+arl_release_resources(dev)
+ device_t dev;
+{
+ struct arl_softc *sc = device_get_softc(dev);
+
+ if (sc->mem_res) {
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ sc->mem_rid, sc->mem_res);
+ sc->mem_res = 0;
+ }
+ if (sc->irq_res) {
+ bus_release_resource(dev, SYS_RES_IRQ,
+ sc->irq_rid, sc->irq_res);
+ sc->irq_res = 0;
+ }
+}
diff --git a/sys/dev/arl/if_arl_isa.c b/sys/dev/arl/if_arl_isa.c
new file mode 100644
index 0000000..434407d
--- /dev/null
+++ b/sys/dev/arl/if_arl_isa.c
@@ -0,0 +1,354 @@
+/*
+ * $RISS: if_arl/dev/arl/if_arl_isa.c,v 1.4 2004/01/22 12:08:48 count Exp $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/socket.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_mib.h>
+
+#include <isa/isavar.h>
+#include <isa/pnpvar.h>
+#include <isa/isa_common.h>
+
+#include <machine/clock.h>
+#include <machine/md_var.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_param.h>
+
+#include <dev/arl/if_arlreg.h>
+
+static void arl_isa_identify(driver_t *, device_t);
+static int arl_isa_probe (device_t);
+static int arl_isa_attach (device_t);
+static int arl_isa_detach (device_t);
+static char* arl_make_desc (u_int8_t, u_int8_t);
+
+#define ARL_MAX_ATYPE_LEN 10
+static struct arl_type {
+ u_int8_t type;
+ char* desc;
+}
+arl_type_list[] = {
+ { 0, "450" },
+ { 1, "650" },
+ { 0xb, "670" },
+ { 0xc, "670E" },
+ { 0xd, "650E" },
+ { 0xe, "440LT" },
+ { 0x2e, "655" },
+ { 0x6b, "IC2200" },
+ { 0, 0 }
+};
+
+#define ARL_MAX_RTYPE_LEN 10
+struct radio_type {
+ u_int8_t type;
+ char* desc;
+} radio_type_list [] = {
+ { 1, "092/094" },
+ { 2, "020" },
+ { 3, "092A" },
+ { 4, "020B" },
+ { 5, "095" },
+ { 6, "024" },
+ { 7, "025B" },
+ { 8, "024B" },
+ { 9, "024C" },
+ {10, "025C" },
+ {11, "024-1A" },
+ {12, "025-1A" },
+};
+
+
+static char*
+arl_make_desc(hw_type, radio_mod)
+ u_int8_t hw_type;
+ u_int8_t radio_mod;
+{
+ static char desc[80];
+ char atype[ARL_MAX_ATYPE_LEN], rtype[ARL_MAX_RTYPE_LEN];
+ int i;
+
+ *atype = *rtype = 0;
+
+ /* arl type */
+ for(i = 0; arl_type_list[i].desc; i++) {
+ if (arl_type_list[i].type == hw_type)
+ break;
+ }
+
+ if (arl_type_list[i].desc)
+ strncpy(atype, arl_type_list[i].desc, ARL_MAX_ATYPE_LEN);
+ else
+ snprintf(atype, ARL_MAX_ATYPE_LEN, "(0x%x)", hw_type);
+
+ /* radio type */
+ for(i = 0; radio_type_list[i].desc; i++)
+ if (radio_type_list[i].type == radio_mod)
+ break;
+
+ if (radio_type_list[i].desc)
+ strncpy(rtype, radio_type_list[i].desc, ARL_MAX_RTYPE_LEN);
+ else
+ snprintf(rtype, ARL_MAX_RTYPE_LEN, "(0x%x)", radio_mod);
+
+ snprintf(desc, 80, "ArLan type %s, radio module %s", atype, rtype);
+
+ return desc;
+}
+
+#define ARL_ADDR2VEC(addr) (1 << ((addr - ARL_BASE_START) / ARL_BASE_STEP))
+
+static void
+arl_isa_identify (driver_t *driver, device_t parent)
+{
+ device_t child;
+ struct arl_softc *sc;
+ int chunk, found, i;
+ u_int16_t free_mem = 0xFFFF;
+
+ if (bootverbose)
+ printf("in identify\n");
+
+ /* Try avoid already added devices */
+ for (i = 0; (child = device_find_child(parent, "arl", i)) != NULL; i++) {
+ chunk = bus_get_resource_start(child, SYS_RES_MEMORY, 0);
+ if (bootverbose)
+ device_printf(child, "found at iomem = 0x%0x\n", chunk);
+ if (chunk >= ARL_BASE_START && chunk <= ARL_BASE_END)
+ free_mem ^= ARL_ADDR2VEC(chunk);
+ }
+
+ if (bootverbose)
+ printf("arl: free mem vector = 0x%x\n", free_mem);
+
+ for (chunk = ARL_BASE_START; chunk <= ARL_BASE_END; chunk += ARL_BASE_STEP) {
+ /* If device 'arl' with this chunk was found early - skip it */
+ if ( !(free_mem & ARL_ADDR2VEC(chunk)) )
+ continue;
+
+ found = 0;
+ child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "arl", -1);
+ device_set_driver(child, driver);
+ sc = device_get_softc(child);
+ bzero(sc, sizeof(*sc));
+
+ bus_set_resource(child, SYS_RES_MEMORY, sc->mem_rid, chunk,
+ ARL_BASE_STEP);
+
+ if (arl_alloc_memory(child, sc->mem_rid, ARL_BASE_STEP) == 0) {
+ ar = (struct arl_private *) rman_get_virtual(sc->mem_res);
+ if (!bcmp(ar->textRegion, ARLAN_SIGN, sizeof(ARLAN_SIGN) - 1))
+ found++;
+ }
+
+ if (bootverbose)
+ device_printf(child, "%sfound at 0x%x\n",
+ !found ? "not " : "", chunk);
+
+ arl_release_resources(child);
+ if (!found) {
+ bus_delete_resource(child, SYS_RES_MEMORY, sc->mem_rid);
+ device_delete_child(parent, child);
+ }
+
+ }
+}
+
+static int
+arl_isa_probe (device_t dev)
+{
+ struct arl_softc *sc = device_get_softc(dev);
+ int error;
+ u_char *ptr;
+ u_int8_t irq;
+
+ if (isa_get_vendorid(dev))
+ return (ENXIO);
+
+ if (bootverbose)
+ device_printf(dev, "in probe\n");
+
+ bzero(sc, sizeof(struct arl_softc));
+
+ sc->arl_unit = device_get_unit(dev);
+
+ error = arl_alloc_memory(dev, 0, ARL_BASE_STEP);
+ if (error) {
+ if (bootverbose)
+ device_printf(dev, "Error allocating memory (%d)\n", error);
+ return (error);
+ }
+
+ ar = (struct arl_private *) rman_get_virtual(sc->mem_res);
+ if (bcmp(ar->textRegion, ARLAN_SIGN, sizeof(ARLAN_SIGN) - 1)) {
+ if (bootverbose)
+ device_printf(dev, "not found\n");
+ error = ENOENT;
+ goto bad;
+ }
+
+ irq = ar->irqLevel;
+ if (irq == 2)
+ irq = 9;
+
+ error = bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1);
+ if (error)
+ goto bad;
+
+ error = arl_alloc_irq(dev, 0, 0);
+ if (error) {
+ if (bootverbose)
+ device_printf(dev, "Can't allocate IRQ %d\n", irq);
+ goto bad;
+ }
+
+ ar->controlRegister = 1; /* freeze board */
+
+ /* Memory test */
+ for (ptr = (u_char *) ar;
+ ptr < ((u_char *) ar + ARL_BASE_STEP - 1); ptr++) {
+ u_char c;
+
+ c = *ptr; *ptr = ~(*ptr);
+ if (*ptr != (u_char)~c) {
+ device_printf(dev, "board memory failed at [%lx]\n",
+ rman_get_start(sc->mem_res) + (ptr - (u_char *)ar));
+ break; /* skip memory test */
+ }
+ }
+
+ bzero((void *) ar, ARL_BASE_STEP - 1); /* clear board ram */
+
+ if (arl_wait_reset(sc, 100, ARDELAY)) {
+ error = ENXIO;
+ goto bad;
+ }
+
+ if (ar->diagnosticInfo == 0xFF) {
+ /* Copy arp to arpcom struct */
+ bcopy(ar->lanCardNodeId, sc->arpcom.ac_enaddr,
+ ETHER_ADDR_LEN);
+
+ /* copy values to local cache */
+ bzero(&arcfg, sizeof(arcfg));
+
+ bcopy(ar->lanCardNodeId, arcfg.lanCardNodeId,
+ sizeof(ar->lanCardNodeId));
+ bcopy(ar->specifiedRouter, arcfg.specifiedRouter,
+ sizeof(ar->specifiedRouter));
+
+ GET_ARL_PARAM(hardwareType);
+ GET_ARL_PARAM(majorHardwareVersion);
+ GET_ARL_PARAM(minorHardwareVersion);
+ GET_ARL_PARAM(radioModule);
+ GET_ARL_PARAM(channelSet);
+ if (!arcfg.channelSet)
+ arcfg.channelSet = ar->defaultChannelSet;
+ GET_ARL_PARAM(channelNumber);
+ GET_ARL_PARAM(registrationMode);
+ GET_ARL_PARAM(spreadingCode);
+ GET_ARL_PARAM(priority);
+ GET_ARL_PARAM(receiveMode);
+ arcfg.txRetry = 0; /* use default */
+
+ strncpy(arcfg.name, ar->name, ARLAN_NAME_SIZE);
+ bcopy(ar->systemId, arcfg.sid, 4 * sizeof(ar->systemId[0]));
+
+ device_set_desc_copy(dev, arl_make_desc(ar->hardwareType, ar->radioModule));
+ error = 0;
+ } else {
+ if (bootverbose)
+ device_printf(dev, "board self-test failed (0x%x)!\n",
+ ar->diagnosticInfo);
+ error = ENXIO;
+ }
+
+bad:
+ arl_release_resources(dev);
+
+ return (error);
+}
+
+static int
+arl_isa_attach (device_t dev)
+{
+ struct arl_softc *sc = device_get_softc(dev);
+ int error;
+
+ if (bootverbose)
+ device_printf(dev, "in attach\n");
+
+ arl_alloc_memory(dev, sc->mem_rid, ARL_BASE_STEP);
+ arl_alloc_irq(dev, sc->irq_rid, 0);
+
+ error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
+ arl_intr, sc, &sc->irq_handle);
+ if (error) {
+ arl_release_resources(dev);
+ return (error);
+ }
+
+#if __FreeBSD_version < 502108
+ device_printf(dev, "Ethernet address %6D\n", sc->arpcom.ac_enaddr, ":");
+#endif
+
+ return arl_attach(dev);
+}
+
+static int
+arl_isa_detach(device_t dev)
+{
+ struct arl_softc *sc = device_get_softc(dev);
+
+ arl_stop(sc);
+ /* ifmedia_removeall(&sc->an_ifmedia); */
+#if __FreeBSD_version < 500100
+ ether_ifdetach(&sc->arpcom.ac_if, ETHER_BPF_SUPPORTED);
+#else
+ ether_ifdetach(&sc->arpcom.ac_if);
+#endif
+ bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
+ arl_release_resources(dev);
+
+ return (0);
+}
+
+static device_method_t arl_isa_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_identify, arl_isa_identify),
+ DEVMETHOD(device_probe, arl_isa_probe),
+ DEVMETHOD(device_attach, arl_isa_attach),
+ DEVMETHOD(device_detach, arl_isa_detach),
+
+ { 0, 0 }
+};
+
+static driver_t arl_isa_driver = {
+ "arl",
+ arl_isa_methods,
+ sizeof(struct arl_softc)
+};
+
+extern devclass_t arl_devclass;
+
+DRIVER_MODULE(arl, isa, arl_isa_driver, arl_devclass, 0, 0);
+MODULE_DEPEND(arl, isa, 1, 1, 1);
+MODULE_DEPEND(arl, ether, 1, 1, 1);
diff --git a/sys/dev/arl/if_arlreg.h b/sys/dev/arl/if_arlreg.h
new file mode 100644
index 0000000..6c057aa
--- /dev/null
+++ b/sys/dev/arl/if_arlreg.h
@@ -0,0 +1,310 @@
+/*
+ * $RISS: if_arl/dev/arl/if_arlreg.h,v 1.2 2004/01/22 09:18:13 count Exp $
+ * $FreeBSD$
+ */
+
+#ifndef _IF_ARLREG_H
+#define _IF_ARLREG_H
+
+#define ARL_BASE_START 0xC0000
+#define ARL_BASE_END 0xDE000
+#define ARL_BASE_STEP 0x2000
+
+#define ARLAN_NAME_SIZE 16
+#define ARLAN_NAME "ArLan655-SCT"
+
+/*
+ * Statistics
+ */
+struct arl_stats {
+ u_int32_t numDatagramsTransmitted;
+ u_int32_t numReTransmissions;
+ u_int32_t numFramesDiscarded;
+ u_int32_t numDatagramsReceived;
+ u_int32_t numDuplicateReceivedFrames;
+ u_int32_t numDatagramsDiscarded;
+ u_int16_t maxNumReTransmitDatagram;
+ u_int16_t maxNumReTransmitFrames;
+ u_int16_t maxNumConsecutiveDuplicateFrames;
+ u_int32_t numBytesTransmitted;
+ u_int32_t numBytesReceived;
+ u_int32_t numCRCErrors;
+ u_int32_t numLengthErrors;
+ u_int32_t numAbortErrors;
+ u_int32_t numTXUnderruns;
+ u_int32_t numRXOverruns;
+ u_int32_t numHoldOffs;
+ u_int32_t numFramesTransmitted;
+ u_int32_t numFramesReceived;
+ u_int32_t numReceiveFramesLost;
+ u_int32_t numRXBufferOverflows;
+ u_int32_t numFramesDiscardedAddrMismatch;
+ u_int32_t numFramesDiscardedSIDMismatch;
+ u_int32_t numPollsTransmistted;
+ u_int32_t numPollAcknowledges;
+ u_int32_t numStatusVectorTimeouts;
+ u_int32_t numNACKReceived;
+} __attribute__((packed));
+
+/*
+ * Arlan private structure in memomory
+ */
+struct arl_private {
+ /* Header Signature */
+ char textRegion[48];
+ u_int8_t resetFlag;
+ u_int8_t diagnosticInfo;
+ u_int16_t diagnosticOffset;
+ u_int8_t _1[12];
+ u_int8_t lanCardNodeId[6];
+ u_int8_t broadcastAddress[6];
+ u_int8_t hardwareType;
+ u_int8_t majorHardwareVersion;
+ u_int8_t minorHardwareVersion;
+ u_int8_t radioModule;
+ u_int8_t defaultChannelSet;
+ u_int8_t _2[47];
+
+ /* Control/Status Block - 0x0080 */
+ u_int8_t interruptInProgress;
+ u_int8_t cntrlRegImage;
+ u_int8_t _3[14];
+ u_int8_t commandByte;
+ u_int8_t commandParameter[15];
+
+ /* Receive Status - 0x00a0 */
+ u_int8_t rxStatusVector;
+ u_int8_t rxFrmType;
+ u_int16_t rxOffset;
+ u_int16_t rxLength;
+ u_int8_t rxSrc[6];
+ u_int8_t rxBroadcastFlag;
+ u_int8_t rxQuality;
+ u_int8_t scrambled;
+ u_int8_t _4[1];
+
+ /* Transmit Status - 0x00b0 */
+ u_int8_t txStatusVector;
+ u_int8_t txAckQuality;
+ u_int8_t numRetries;
+ u_int8_t _5[14];
+ u_int8_t registeredRouter[6];
+ u_int8_t backboneRouter[6];
+ u_int8_t registrationStatus;
+ u_int8_t configuredStatusFlag;
+ u_int8_t _6[1];
+ u_int8_t ultimateDestAddress[6];
+ u_int8_t immedDestAddress[6];
+ u_int8_t immedSrcAddress[6];
+ u_int16_t rxSequenceNumber;
+ u_int8_t assignedLocaltalkAddress;
+ u_int8_t _7[27];
+
+ /* System Parameter Block */
+
+ /* - Driver Parameters (Novell Specific) */
+
+ u_int16_t txTimeout;
+ u_int16_t transportTime;
+ u_int8_t _8[4];
+
+ /* - Configuration Parameters */
+ u_int8_t irqLevel;
+ u_int8_t spreadingCode;
+ u_int8_t channelSet;
+ u_int8_t channelNumber;
+ u_int16_t radioNodeId;
+ u_int8_t _9[2];
+ u_int8_t scramblingDisable;
+ u_int8_t radioType;
+ u_int16_t routerId;
+ u_int8_t _10[9];
+ u_int8_t txAttenuation;
+ u_int8_t systemId[4]; /* on an odd address for a long !!! */
+ u_int16_t globalChecksum;
+ u_int8_t _11[4];
+ u_int16_t maxDatagramSize;
+ u_int16_t maxFrameSize;
+ u_int8_t maxRetries;
+ u_int8_t receiveMode;
+ u_int8_t priority;
+ u_int8_t rootOrRepeater;
+ u_int8_t specifiedRouter[6];
+ u_int16_t fastPollPeriod;
+ u_int8_t pollDecay;
+ u_int8_t fastPollDelay[2];
+ u_int8_t arlThreshold;
+ u_int8_t arlDecay;
+ u_int8_t _12[1];
+ u_int16_t specRouterTimeout;
+ u_int8_t _13[5];
+
+ /* Scrambled Area */
+ u_int8_t SID[4];
+ u_int8_t encryptionKey[12];
+ u_int8_t _14[2];
+ u_int8_t waitTime[2];
+ u_int8_t lParameter[2];
+ u_int8_t _15[3];
+ u_int16_t headerSize;
+ u_int16_t sectionChecksum;
+
+ u_int8_t registrationMode;
+ u_int8_t registrationFill;
+ u_int16_t pollPeriod;
+ u_int16_t refreshPeriod;
+ u_int8_t name[ARLAN_NAME_SIZE];
+ u_int8_t NID[6];
+ u_int8_t localTalkAddress;
+ u_int8_t codeFormat;
+ u_int8_t SSCode[64];
+
+ u_int8_t _16[0x140];
+
+ /* Statistics Block - 0x0300 */
+ u_int8_t hostcpuLock;
+ u_int8_t lancpuLock;
+ u_int8_t resetTime[18];
+
+ struct arl_stats stat;
+
+ u_int8_t _17[0x86];
+
+ u_int8_t txBuffer[0x800];
+ u_int8_t rxBuffer[0x800];
+
+ u_int8_t _18[0x0bfd];
+ u_int8_t resetFlag1;
+ u_int8_t _19;
+ u_int8_t controlRegister;
+};
+
+/*
+ * Transmit parametrs
+ */
+struct arl_tx_param {
+ u_int16_t offset;
+ u_int16_t length;
+ u_int8_t dest[6];
+ u_int8_t clear;
+ u_int8_t retries;
+ u_int8_t routing;
+ u_int8_t scrambled;
+};
+
+#define ARL_HARDWARE_RESET 0x01
+#define ARL_CHANNEL_ATTENTION 0x02
+#define ARL_INTERRUPT_ENABLE 0x04
+#define ARL_CLEAR_INTERRUPT 0x08
+
+/* additions for sys/sockio.h ( socket ioctl parameters for arlan card ) */
+
+#define SIOCGARLQLT _IOWR('i', 70, struct ifreq) /* get QUALITY */
+#define SIOCGARLALL _IOWR('i', 71, struct ifreq) /* get ALL */
+#define SIOCSARLALL _IOWR('i', 72, struct ifreq) /* set paramter (who_set) */
+#define SIOCGARLSTB _IOWR('i', 73, struct ifreq) /* get statistic block */
+
+/*
+ * Arlan request struct via ioctl
+ */
+struct arl_cfg_param {
+ u_char name[ARLAN_NAME_SIZE];
+ u_int8_t sid[4];
+ u_int8_t channelSet;
+ u_int8_t channelNumber;
+ u_int8_t spreadingCode;
+ u_int8_t registrationMode;
+ u_int8_t lanCardNodeId[6];
+ u_int8_t specifiedRouter[6];
+ u_int8_t hardwareType;
+ u_int8_t majorHardwareVersion;
+ u_int8_t minorHardwareVersion;
+ u_int8_t radioModule;
+ u_int8_t priority;
+ u_int8_t receiveMode;
+ u_int8_t txRetry;
+};
+
+struct arl_req {
+ u_int32_t what_set;
+ struct arl_cfg_param cfg;
+};
+
+#define ARLAN_MAX_QUALITY 16
+
+struct arl_quality {
+ u_int8_t macsrc[6];
+ int rx_quality;
+ int tx_quality;
+};
+
+#define ARLAN_SET_name 0x0001
+#define ARLAN_SET_sid 0x0002
+#define ARLAN_SET_channelSet 0x0004
+#define ARLAN_SET_channelNumber 0x0008
+#define ARLAN_SET_spreadingCode 0x0010
+#define ARLAN_SET_registrationMode 0x0020
+#define ARLAN_SET_lanCardNodeId 0x0040
+#define ARLAN_SET_specifiedRouter 0x0080
+#define ARLAN_SET_priority 0x0100
+#define ARLAN_SET_receiveMode 0x0200
+#define ARLAN_SET_txRetry 0x0400
+
+#ifdef _KERNEL
+struct arl_softc {
+ struct arpcom arpcom; /* Ethernet common */
+
+ int arl_unit;
+ struct arl_private * arl_mem; /* arlan data */
+
+ struct arl_cfg_param arl_cfg; /* arlan vars in our mem */
+ u_char arl_control;
+
+ int mem_rid; /* resource id for mem */
+ struct resource* mem_res; /* resource for mem */
+ int irq_rid; /* resource id for irq */
+ struct resource* irq_res; /* resource for irq */
+ void* irq_handle; /* handle for irq handler */
+
+ u_char arl_tx[2048];
+ int tx_len;
+ u_char arl_rx[2048];
+ int rx_len;
+
+ struct arl_quality quality[ARLAN_MAX_QUALITY];
+};
+#endif
+
+#define ARLAN_SIGN "TELESYSTEM"
+#define ARLAN_HEADER_SIZE 0x0C
+
+#define ar sc->arl_mem
+#define arcfg sc->arl_cfg
+#define aqual sc->quality
+
+#define ARDELAY 10000
+#define ARDELAY1 50000
+
+#define WAIT_RESET(cnt, delay) \
+ do { \
+ int i; \
+ for (i = cnt; i && ar->resetFlag; i--) { \
+ DELAY(delay); \
+ } \
+ } while (0);
+
+#define GET_ARL_PARAM(name) (arcfg.name = ar->name)
+#define SET_ARL_PARAM(name) (ar->name = arcfg.name)
+
+#ifdef _KERNEL
+void arl_release_resources (device_t);
+int arl_alloc_memory (device_t, int, int);
+int arl_alloc_irq (device_t, int, int);
+int arl_attach (device_t);
+int arl_wait_reset (struct arl_softc *, int, int);
+void arl_stop (struct arl_softc *);
+
+driver_intr_t arl_intr;
+#endif
+
+#endif /* _IF_ARLREG_H */
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index 8798661..952b1c6 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -493,6 +493,7 @@ hint.mse.0.irq="5"
# ar: Arnet SYNC/570i hdlc sync 2/4 port V.35/X.21 serial driver
# (requires sppp)
+# arl: Aironet Arlan 655 wireless adapters.
# ath: Atheros a/b/g WiFi adapters (requires ath_hal and wlan)
# ctau: Cronyx/Tau sync dual port V.35/RS-232/RS-530/RS-449/X.21/G.703/E1
# serial adaptor (requires sppp (default), or NETGRAPH if
@@ -521,6 +522,10 @@ hint.ar.0.at="isa"
hint.ar.0.port="0x300"
hint.ar.0.irq="10"
hint.ar.0.maddr="0xd0000"
+device arl
+hint.arl.0.at="isa"
+hint.arl.0.irq="9"
+hint.arl.0.maddr="0xd0000"
device ctau
hint.ctau.0.at="isa"
hint.ctau.0.port="0x240"
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 1bfc0cc..eb124bc 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -20,6 +20,7 @@ SUBDIR= ${_3dfx} \
${_aout} \
${_apm} \
${_ar} \
+ ${_arl} \
${_arcnet} \
${_asr} \
ath \
@@ -284,6 +285,7 @@ _amd= amd
_aout= aout
_apm= apm
_ar= ar
+_arl= arl
_arcnet= arcnet
_ath_hal= ath_hal
_awi= awi
diff --git a/sys/modules/arl/Makefile b/sys/modules/arl/Makefile
new file mode 100644
index 0000000..a7ca8d4
--- /dev/null
+++ b/sys/modules/arl/Makefile
@@ -0,0 +1,10 @@
+# $RISS: if_arl/modules/if_arl/Makefile,v 1.3 2003/01/13 08:05:29 frol Exp $
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../dev/arl
+
+KMOD= if_arl
+SRCS= if_arl.c if_arl_isa.c device_if.h bus_if.h isa_if.h
+CFLAGS= -I${.CURDIR}/../..
+
+.include <bsd.kmod.mk>
OpenPOWER on IntegriCloud