summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2000-04-26 20:16:56 +0000
committerphk <phk@FreeBSD.org>2000-04-26 20:16:56 +0000
commitc816580dfb530d84c2396d9f0d10a9f8e44d4ea4 (patch)
tree9754dfd8db6a41796c38824d131bd2d9369933e2
parenta0363301237e7450b90e5d8fe9242958c75bd43d (diff)
downloadFreeBSD-src-c816580dfb530d84c2396d9f0d10a9f8e44d4ea4.zip
FreeBSD-src-c816580dfb530d84c2396d9f0d10a9f8e44d4ea4.tar.gz
Driver for DEC "Tulip" based WAN cards from LanMedia Corporation.
This driver should support both the SSI (V.35 etc) E1/T1 unchannelized, DS3 and HSSI cards. Only tested on the SSI card. More info at: http://www.lanmedia.com Thanks to LanMedia for donating two LMC1000P cards. if_de.c driver modified by: LanMedia NetGraphification by: Stephen Kiernan <sk-ports@vegamuse.org>
-rw-r--r--sys/conf/NOTES1
-rw-r--r--sys/conf/files1
-rw-r--r--sys/dev/lmc/if_lmc.c916
-rw-r--r--sys/dev/lmc/if_lmc_common.c8
-rw-r--r--sys/dev/lmc/if_lmc_fbsd3.c31
-rw-r--r--sys/dev/lmc/if_lmc_media.c29
-rw-r--r--sys/dev/lmc/if_lmcioctl.h6
-rw-r--r--sys/dev/lmc/if_lmcvar.h180
-rw-r--r--sys/i386/conf/LINT1
-rw-r--r--sys/i386/conf/NOTES1
10 files changed, 605 insertions, 569 deletions
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index e78cbb8..3df5e53 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -408,6 +408,7 @@ options NETGRAPH_UI
options NETGRAPH_VJC
device mn # Munich32x/Falc54 Nx64kbit/sec cards.
+device lmc # tulip based LanMedia WAN cards
#
# Network interfaces:
diff --git a/sys/conf/files b/sys/conf/files
index 5fe9fdd..b19184b 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -169,6 +169,7 @@ dev/iicbus/iicsmb.c optional iicsmb \
dev/isp/isp.c optional isp
dev/isp/isp_freebsd.c optional isp
dev/isp/isp_target.c optional isp
+dev/lmc/if_lmc.c optional lmc
dev/mca/mca_bus.c optional mca
dev/md/md.c optional md
dev/mii/amphy.c optional miibus
diff --git a/sys/dev/lmc/if_lmc.c b/sys/dev/lmc/if_lmc.c
index 0753c72..f230620 100644
--- a/sys/dev/lmc/if_lmc.c
+++ b/sys/dev/lmc/if_lmc.c
@@ -1,10 +1,7 @@
-/* $FreeBSD$ */
-/* From NetBSD: if_de.c,v 1.56.2.1 1997/10/27 02:13:25 thorpej Exp */
-/* $Id: if_lmc.c,v 1.9 1999/02/19 15:08:42 explorer Exp $ */
-
/*-
* Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
* Copyright (c) LAN Media Corporation 1998, 1999.
+ * Copyright (c) 2000 Stephen Kiernan (sk-ports@vegamuse.org)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,103 +22,40 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ * From NetBSD: if_de.c,v 1.56.2.1 1997/10/27 02:13:25 thorpej Exp
+ * $Id: if_lmc.c,v 1.9 1999/02/19 15:08:42 explorer Exp $
*/
char lmc_version[] = "BSD 1.1";
+#include "opt_netgraph.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
-#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
-#include <sys/proc.h> /* only for declaration of wakeup() used by vm.h */
-#if defined(__FreeBSD__)
#include <machine/clock.h>
-#elif defined(__bsdi__) || defined(__NetBSD__)
-#include <sys/device.h>
-#endif
-
-#if defined(__NetBSD__)
-#include <dev/pci/pcidevs.h>
-#include "rnd.h"
-#if NRND > 0
-#include <sys/rnd.h>
-#endif
-#endif
#include <net/if.h>
-#include <net/if_types.h>
-#include <net/if_dl.h>
-#include <net/netisr.h>
-
-#include "bpfilter.h"
-#if NBPFILTER > 0
-#include <net/bpf.h>
-#include <net/bpfdesc.h>
-#endif
+#include <sys/syslog.h>
#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_kern.h>
-
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-#include <net/if_sppp.h>
-#endif
-#if defined(__bsdi__)
-#if INET
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#endif
-
-#include <net/netisr.h>
-#include <net/if.h>
-#include <net/netisr.h>
-#include <net/if_types.h>
-#include <net/if_p2p.h>
-#include <net/if_c_hdlc.h>
-#endif
+#include <netgraph/ng_message.h>
+#include <netgraph/ng_parse.h>
+#include <netgraph/netgraph.h>
-#if defined(__FreeBSD__)
#include <vm/pmap.h>
#include <pci.h>
-#if NPCI > 0
#include <pci/pcivar.h>
#include <pci/dc21040reg.h>
-#define INCLUDE_PATH_PREFIX "pci/"
-#endif
-#endif /* __FreeBSD__ */
-
-#if defined(__bsdi__)
-#include <i386/pci/ic/dc21040.h>
-#include <i386/isa/isa.h>
-#include <i386/isa/icu.h>
-#include <i386/isa/dma.h>
-#include <i386/isa/isavar.h>
-#include <i386/pci/pci.h>
-
-#define INCLUDE_PATH_PREFIX "i386/pci/"
-#endif /* __bsdi__ */
-
-#if defined(__NetBSD__)
-#include <machine/bus.h>
-#if defined(__alpha__)
-#include <machine/intr.h>
-#endif
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-#include <dev/ic/dc21040reg.h>
-#define INCLUDE_PATH_PREFIX "dev/pci/"
-#endif /* __NetBSD__ */
+#define INCLUDE_PATH_PREFIX "dev/lmc/"
-/*
- * Intel CPUs should use I/O mapped access. XXXMLG Is this true on NetBSD
- * too?
- */
+/* Intel CPUs should use I/O mapped access. */
#if defined(__i386__)
#define LMC_IOMAPPED
#endif
@@ -130,8 +64,7 @@ char lmc_version[] = "BSD 1.1";
* This turns on all sort of debugging stuff and make the
* driver much larger.
*/
-#if 0
-#define LMC_DEBUG
+#ifdef LMC_DEBUG
#define DP(x) printf x
#else
#define DP(x)
@@ -153,41 +86,112 @@ typedef struct lmc___softc lmc_softc_t;
typedef struct lmc___media lmc_media_t;
typedef struct lmc___ctl lmc_ctl_t;
-/*
- * Sigh. Every OS puts these in different places. NetBSD and FreeBSD use
- * a C preprocessor that allows this hack, but BSDI does not.
- */
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-#include INCLUDE_PATH_PREFIX "if_lmcioctl.h"
-#include INCLUDE_PATH_PREFIX "if_lmcvar.h"
-#include INCLUDE_PATH_PREFIX "if_lmc_common.c"
-#include INCLUDE_PATH_PREFIX "if_lmc_media.c"
-#else /* BSDI */
-#include "i386/pci/if_lmcioctl.h"
-#include "i386/pci/if_lmcvar.h"
-#include "i386/pci/if_lmc_common.c"
-#include "i386/pci/if_lmc_media.c"
-#endif
+#include "dev/lmc/if_lmcioctl.h"
+#include "dev/lmc/if_lmcvar.h"
+#include "dev/lmc/if_lmc_common.c"
+#include "dev/lmc/if_lmc_media.c"
/*
* This module supports
* the DEC 21140A pass 2.2 PCI Fast Ethernet Controller.
*/
static lmc_intrfunc_t lmc_intr_normal(void *);
-static ifnet_ret_t lmc_ifstart_one(struct ifnet *ifp);
-static ifnet_ret_t lmc_ifstart(struct ifnet *ifp);
+static ifnet_ret_t lmc_ifstart(lmc_softc_t * const sc );
+static ifnet_ret_t lmc_ifstart_one(lmc_softc_t * const sc);
static struct mbuf *lmc_txput(lmc_softc_t * const sc, struct mbuf *m);
static void lmc_rx_intr(lmc_softc_t * const sc);
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-static void lmc_watchdog(struct ifnet *ifp);
-#endif
-#if defined(__bsdi__)
-static int lmc_watchdog(int);
-#endif
+static void lmc_watchdog(lmc_softc_t * const sc);
static void lmc_ifup(lmc_softc_t * const sc);
static void lmc_ifdown(lmc_softc_t * const sc);
+#ifdef LMC_DEBUG
+static void ng_lmc_dump_packet(struct mbuf *m);
+#endif /* LMC_DEBUG */
+static void ng_lmc_watchdog_frame(void *arg);
+static void ng_lmc_init(void *ignored);
+
+static ng_constructor_t ng_lmc_constructor;
+static ng_rcvmsg_t ng_lmc_rcvmsg;
+static ng_shutdown_t ng_lmc_rmnode;
+static ng_newhook_t ng_lmc_newhook;
+/*static ng_findhook_t ng_lmc_findhook; */
+static ng_connect_t ng_lmc_connect;
+static ng_rcvdata_t ng_lmc_rcvdata;
+static ng_disconnect_t ng_lmc_disconnect;
+
+/* Parse type for struct lmc_ctl */
+static const struct ng_parse_fixedarray_info ng_lmc_ctl_cardspec_info = {
+ &ng_parse_int32_type,
+ 7,
+ NULL
+};
+
+static const struct ng_parse_type ng_lmc_ctl_cardspec_type = {
+ &ng_parse_fixedarray_type,
+ &ng_lmc_ctl_cardspec_info
+};
+
+static const struct ng_parse_struct_info ng_lmc_ctl_type_info = {
+ {
+ { "cardtype", &ng_parse_int32_type },
+ { "clock_source", &ng_parse_int32_type },
+ { "clock_rate", &ng_parse_int32_type },
+ { "crc_length", &ng_parse_int32_type },
+ { "cable_length", &ng_parse_int32_type },
+ { "scrambler_onoff", &ng_parse_int32_type },
+ { "cable_type", &ng_parse_int32_type },
+ { "keepalive_onoff", &ng_parse_int32_type },
+ { "ticks", &ng_parse_int32_type },
+ { "cardspec", &ng_lmc_ctl_cardspec_type },
+ { "circuit_type", &ng_parse_int32_type },
+ { NULL },
+ }
+};
+
+static const struct ng_parse_type ng_lmc_ctl_type = {
+ &ng_parse_struct_type,
+ &ng_lmc_ctl_type_info
+};
+
+
+/* List of commands and how to convert arguments to/from ASCII */
+static const struct ng_cmdlist ng_lmc_cmdlist[] = {
+ {
+ NG_LMC_COOKIE,
+ NGM_LMC_GET_CTL,
+ "getctl",
+ NULL,
+ &ng_lmc_ctl_type,
+ },
+ {
+ NG_LMC_COOKIE,
+ NGM_LMC_SET_CTL,
+ "setctl",
+ &ng_lmc_ctl_type,
+ NULL
+ },
+ { 0 }
+};
+
+static struct ng_type typestruct = {
+ NG_VERSION,
+ NG_LMC_NODE_TYPE,
+ NULL,
+ ng_lmc_constructor,
+ ng_lmc_rcvmsg,
+ ng_lmc_rmnode,
+ ng_lmc_newhook,
+ NULL,
+ ng_lmc_connect,
+ ng_lmc_rcvdata,
+ ng_lmc_rcvdata,
+ ng_lmc_disconnect,
+ ng_lmc_cmdlist
+};
+
+static int ng_lmc_done_init = 0;
+
/*
* Code the read the SROM and MII bit streams (I2C)
@@ -381,22 +385,9 @@ lmc_read_macaddr(lmc_softc_t * const sc)
* Check to make certain there is a signal from the modem, and flicker
* lights as needed.
*/
-#if defined(__NetBSD__) || defined(__FreeBSD__)
static void
-lmc_watchdog(struct ifnet *ifp)
-#endif
-#if defined(__bsdi__)
-static int
-lmc_watchdog(int unit)
-#endif
+lmc_watchdog(lmc_softc_t * const sc)
{
-#if defined(__NetBSD__) || defined(__FreeBSD__)
- lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
-#endif
-#if defined(__bsdi__)
- lmc_softc_t * const sc = LMC_UNIT_TO_SOFTC(unit);
- struct ifnet *ifp = &sc->lmc_if;
-#endif
int state;
u_int32_t ostatus;
u_int32_t link_status;
@@ -439,7 +430,7 @@ lmc_watchdog(int unit)
LMC_CSR_WRITE(sc, csr_gp_timer, 0xffffffffUL);
sc->ictl.ticks = 0x0000ffff - (ticks & 0x0000ffff);
- ifp->if_timer = 1;
+ sc->lmc_out_dog = LMC_DOG_HOLDOFF;
}
/*
@@ -449,7 +440,8 @@ lmc_watchdog(int unit)
static void
lmc_ifup(lmc_softc_t * const sc)
{
- sc->lmc_if.if_timer = 0;
+ untimeout(ng_lmc_watchdog_frame, sc, sc->lmc_handle);
+ sc->lmc_running = 0;
lmc_dec_reset(sc);
lmc_reset(sc);
@@ -478,7 +470,9 @@ lmc_ifup(lmc_softc_t * const sc)
sc->lmc_cmdmode |= TULIP_CMD_RXRUN;
LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
- sc->lmc_if.if_timer = 1;
+ untimeout(ng_lmc_watchdog_frame, sc, sc->lmc_handle);
+ sc->lmc_handle = timeout(ng_lmc_watchdog_frame, sc, hz);
+ sc->lmc_running = 1;
}
/*
@@ -488,7 +482,8 @@ lmc_ifup(lmc_softc_t * const sc)
static void
lmc_ifdown(lmc_softc_t * const sc)
{
- sc->lmc_if.if_timer = 0;
+ untimeout(ng_lmc_watchdog_frame, sc, sc->lmc_handle);
+ sc->lmc_running = 0;
sc->lmc_flags &= ~LMC_IFUP;
sc->lmc_media->set_link_status(sc, 0);
@@ -503,7 +498,6 @@ static void
lmc_rx_intr(lmc_softc_t * const sc)
{
lmc_ringinfo_t * const ri = &sc->lmc_rxinfo;
- struct ifnet * const ifp = &sc->lmc_if;
int fillok = 1;
sc->lmc_rxtick++;
@@ -584,32 +578,23 @@ lmc_rx_intr(lmc_softc_t * const sc)
else
total_len -= 4;
+ sc->lmc_inbytes += total_len;
+ sc->lmc_inlast = 0;
+
if ((sc->lmc_flags & LMC_RXIGNORE) == 0
&& ((eop->d_status & LMC_DSTS_ERRSUM) == 0
-#ifdef BIG_PACKET
- || (total_len <= sc->lmc_if.if_mtu + PPP_HEADER_LEN
- && (eop->d_status & TULIP_DSTS_RxOVERFLOW) == 0)
-#endif
)) {
me->m_len = total_len - last_offset;
-#if NBPFILTER > 0
- if (sc->lmc_bpf != NULL) {
- if (me == ms)
- LMC_BPF_TAP(sc, mtod(ms, caddr_t), total_len);
- else
- LMC_BPF_MTAP(sc, ms);
- }
-#endif
sc->lmc_flags |= LMC_RXACT;
accept = 1;
} else {
- ifp->if_ierrors++;
+ sc->lmc_ierrors++;
if (eop->d_status & TULIP_DSTS_RxOVERFLOW) {
sc->lmc_dot3stats.dot3StatsInternalMacReceiveErrors++;
}
}
- ifp->if_ipackets++;
+ sc->lmc_ipackets++;
if (++eop == ri->ri_last)
eop = ri->ri_first;
ri->ri_nextin = eop;
@@ -640,13 +625,8 @@ lmc_rx_intr(lmc_softc_t * const sc)
}
if (accept) {
ms->m_pkthdr.len = total_len;
- ms->m_pkthdr.rcvif = ifp;
-#if defined(__NetBSD__) || defined(__FreeBSD__)
- sppp_input(ifp, ms);
-#endif
-#if defined(__bsdi__)
- sc->lmc_p2pcom.p2p_input(&sc->lmc_p2pcom, ms);
-#endif
+ ms->m_pkthdr.rcvif = NULL;
+ ng_send_data(sc->lmc_hook, ms, NULL);
}
ms = m0;
}
@@ -711,7 +691,7 @@ lmc_tx_intr(lmc_softc_t * const sc)
}
xmits++;
if (d_status & LMC_DSTS_ERRSUM) {
- sc->lmc_if.if_oerrors++;
+ sc->lmc_oerrors++;
if (d_status & TULIP_DSTS_TxUNDERFLOW)
sc->lmc_dot3stats.dot3StatsInternalTransmitUnderflows++;
} else {
@@ -725,13 +705,14 @@ lmc_tx_intr(lmc_softc_t * const sc)
ri->ri_free++;
descs++;
- sc->lmc_if.if_flags &= ~IFF_OACTIVE;
+ /*sc->lmc_if.if_flags &= ~IFF_OACTIVE;*/
+ sc->lmc_out_deficit++;
}
/*
* If nothing left to transmit, disable the timer.
* Else if progress, reset the timer back to 2 ticks.
*/
- sc->lmc_if.if_opackets += xmits;
+ sc->lmc_opackets += xmits;
return descs;
}
@@ -749,12 +730,6 @@ lmc_intr_handler(lmc_softc_t * const sc, int *progress_p)
while ((csr = LMC_CSR_READ(sc, csr_status)) & sc->lmc_intrmask) {
-#if defined(__NetBSD__)
-#if NRND > 0
- rnd_add_uint32(&sc->lmc_rndsource, csr);
-#endif
-#endif
-
*progress_p = 1;
LMC_CSR_WRITE(sc, csr_status, csr);
@@ -825,7 +800,7 @@ lmc_intr_handler(lmc_softc_t * const sc, int *progress_p)
lmc_tx_intr(sc);
if (sc->lmc_flags & LMC_WANTTXSTART)
- lmc_ifstart(&sc->lmc_if);
+ lmc_ifstart(sc);
}
}
@@ -1065,7 +1040,8 @@ lmc_txput(lmc_softc_t * const sc, struct mbuf *m)
* switch back to the single queueing ifstart.
*/
sc->lmc_flags &= ~LMC_WANTTXSTART;
- sc->lmc_if.if_start = lmc_ifstart_one;
+ sc->lmc_xmit_busy = 0;
+ sc->lmc_out_dog = 0;
/*
* If we want a txstart, there must be not enough space in the
@@ -1077,297 +1053,455 @@ lmc_txput(lmc_softc_t * const sc, struct mbuf *m)
* WANTTXSTART thereby causing TXINTR to be cleared.
*/
finish:
- if (sc->lmc_flags & LMC_WANTTXSTART) {
- sc->lmc_if.if_flags |= IFF_OACTIVE;
- sc->lmc_if.if_start = lmc_ifstart;
- }
return m;
}
/*
- * This routine is entered at splnet() (splsoftnet() on NetBSD)
+ * These routines gets called at device spl
*/
-static int
-lmc_ifioctl(struct ifnet * ifp, ioctl_cmd_t cmd, caddr_t data)
-{
- lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
-#if defined(__NetBSD__) || defined(__FreeBSD__)
- lmc_spl_t s;
-#endif
- int error = 0;
- struct ifreq *ifr = (struct ifreq *)data;
- u_int32_t new_state;
- u_int32_t old_state;
- lmc_ctl_t ctl;
-
-#if defined(__NetBSD__) || defined(__FreeBSD__)
- s = LMC_RAISESPL();
-#endif
-
- switch (cmd) {
- case LMCIOCGINFO:
- error = copyout(&sc->ictl, ifr->ifr_data, sizeof(lmc_ctl_t));
- goto out;
- break;
-
- case LMCIOCSINFO:
-#if 0 /* XXX */
- error = suser(p->p_ucred, &p->p_acflag);
- if (error)
- goto out;
-#endif
-
- error = copyin(ifr->ifr_data, &ctl, sizeof(lmc_ctl_t));
- if (error != 0)
- goto out;
+static ifnet_ret_t
+lmc_ifstart(lmc_softc_t * const sc)
+{
+ struct mbuf *m;
- sc->lmc_media->set_status(sc, &ctl);
+ if (sc->lmc_flags & LMC_IFUP) {
+ sc->lmc_xmit_busy = 1;
+ for(;;) {
+ struct ifqueue *q = &sc->lmc_xmitq_hipri;
+ IF_DEQUEUE(q, m);
+ if (m == NULL) {
+ q = &sc->lmc_xmitq;
+ IF_DEQUEUE(q, m);
+ }
+ if (m) {
+ sc->lmc_outbytes = m->m_pkthdr.len;
+ sc->lmc_opackets++;
+ if ((m = lmc_txput(sc, m)) != NULL) {
+ IF_PREPEND(q, m);
+ printf(LMC_PRINTF_FMT
+ ": lmc_txput failed\n",
+ LMC_PRINTF_ARGS);
+ break;
+ }
+ LMC_CSR_WRITE(sc, csr_txpoll, 1);
+ }
+ else
+ break;
+ }
+ }
+}
- goto out;
- break;
+static ifnet_ret_t
+lmc_ifstart_one(lmc_softc_t * const sc)
+{
+ struct mbuf *m;
-#if defined(__NetBSD__) || defined(__FreeBSD__)
- case SIOCSIFMTU:
- /*
- * Don't allow the MTU to get larger than we can handle
- */
- if (ifr->ifr_mtu > LMC_MTU) {
- error = EINVAL;
- goto out;
+ if ((sc->lmc_flags & LMC_IFUP)) {
+ struct ifqueue *q = &sc->lmc_xmitq_hipri;
+ IF_DEQUEUE(q, m);
+ if (m == NULL) {
+ q = &sc->lmc_xmitq;
+ IF_DEQUEUE(q, m);
+ }
+ if (m) {
+ sc->lmc_outbytes += m->m_pkthdr.len;
+ sc->lmc_opackets++;
+ if ((m = lmc_txput(sc, m)) != NULL) {
+ IF_PREPEND(q, m);
+ }
+ LMC_CSR_WRITE(sc, csr_txpoll, 1);
}
-#endif
}
+}
-#if defined(__NetBSD__) || defined(__FreeBSD__)
+/*
+ * Set up the OS interface magic and attach to the operating system
+ * network services.
+ */
+static int
+lmc_attach(lmc_softc_t * const sc)
+{
/*
- * call the sppp ioctl layer
+ * we have found a node, make sure our 'type' is availabe.
*/
- error = sppp_ioctl(ifp, cmd, data);
- if (error != 0)
- goto out;
-#endif
-
-#if defined(__bsdi__)
- error = p2p_ioctl(ifp, cmd, data);
-#endif
+ if (ng_lmc_done_init == 0) ng_lmc_init(NULL);
+ if (ng_make_node_common(&typestruct, &sc->lmc_node) != 0)
+ return (0);
+ sc->lmc_node->private = sc;
+ callout_handle_init(&sc->lmc_handle);
+ sc->lmc_xmitq.ifq_maxlen = IFQ_MAXLEN;
+ sc->lmc_xmitq_hipri.ifq_maxlen = IFQ_MAXLEN;
+ sprintf(sc->lmc_nodename, "%s%d", NG_LMC_NODE_TYPE, sc->lmc_unit);
+ if (ng_name_node(sc->lmc_node, sc->lmc_nodename)) {
+ ng_rmnode(sc->lmc_node);
+ ng_unref(sc->lmc_node);
+ return (0);
+ }
+ sc->lmc_running = 0;
-#if defined(__NetBSD__) || defined(__FreeBSD__)
/*
- * If we are transitioning from up to down or down to up, call
- * our init routine.
+ * turn off those LEDs...
*/
- new_state = ifp->if_flags & IFF_UP;
- old_state = sc->lmc_flags & LMC_IFUP;
-
- if (new_state && !old_state)
- lmc_ifup(sc);
- else if (!new_state && old_state)
- lmc_ifdown(sc);
-#endif
-
- out:
-#if defined(__NetBSD__) || defined(__FreeBSD__)
- LMC_RESTORESPL(s);
-#endif
+ sc->lmc_miireg16 |= LMC_MII16_LED_ALL;
+ lmc_led_on(sc, LMC_MII16_LED0);
- return error;
+ return 1;
}
-/*
- * These routines gets called at device spl (from sppp_output).
- */
+static void
+lmc_initring(lmc_softc_t * const sc, lmc_ringinfo_t * const ri,
+ tulip_desc_t *descs, int ndescs)
+{
+ ri->ri_max = ndescs;
+ ri->ri_first = descs;
+ ri->ri_last = ri->ri_first + ri->ri_max;
+ bzero((caddr_t) ri->ri_first, sizeof(ri->ri_first[0]) * ri->ri_max);
+ ri->ri_last[-1].d_flag = TULIP_DFLAG_ENDRING;
+}
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-static ifnet_ret_t
-lmc_ifstart(struct ifnet * const ifp)
+
+
+#ifdef LMC_DEBUG
+static void
+ng_lmc_dump_packet(struct mbuf *m)
{
- lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
- struct mbuf *m;
+ int i;
- if (sc->lmc_flags & LMC_IFUP) {
- while (sppp_isempty(ifp) == 0) {
- m = sppp_dequeue(ifp);
- if ((m = lmc_txput(sc, m)) != NULL) {
- IF_PREPEND(&((struct sppp *)ifp)->pp_fastq, m);
- break;
- }
+ printf("mbuf: %d bytes, %s packet\n", m->m_len,
+ (m->m_type == MT_DATA)?"data":"other");
+
+ for (i=0; i < m->m_len; i++) {
+ if( (i % 8) == 0 ) {
+ if( i ) printf("\n");
+ printf("\t");
}
- LMC_CSR_WRITE(sc, csr_txpoll, 1);
+ else
+ printf(" ");
+ printf( "0x%02x", m->m_dat[i] );
}
+ printf("\n");
}
+#endif /* LMC_DEBUG */
-static ifnet_ret_t
-lmc_ifstart_one(struct ifnet * const ifp)
+/* Device timeout/watchdog routine */
+static void
+ng_lmc_watchdog_frame(void *arg)
{
- lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
- struct mbuf *m;
-
- if ((sc->lmc_flags & LMC_IFUP) && (sppp_isempty(ifp) == 0)) {
- m = sppp_dequeue(ifp);
- if ((m = lmc_txput(sc, m)) != NULL) {
- IF_PREPEND(&((struct sppp *)ifp)->pp_fastq, m);
- }
- LMC_CSR_WRITE(sc, csr_txpoll, 1);
+ lmc_softc_t * sc = (lmc_softc_t *) arg;
+ int s;
+ int speed;
+
+ if(sc->lmc_running == 0)
+ return; /* if we are not running let timeouts die */
+ /*
+ * calculate the apparent throughputs
+ * XXX a real hack
+ */
+ s = splimp();
+ speed = sc->lmc_inbytes - sc->lmc_lastinbytes;
+ sc->lmc_lastinbytes = sc->lmc_inbytes;
+ if ( sc->lmc_inrate < speed )
+ sc->lmc_inrate = speed;
+ speed = sc->lmc_outbytes - sc->lmc_lastoutbytes;
+ sc->lmc_lastoutbytes = sc->lmc_outbytes;
+ if ( sc->lmc_outrate < speed )
+ sc->lmc_outrate = speed;
+ sc->lmc_inlast++;
+ splx(s);
+
+ if ((sc->lmc_inlast > LMC_QUITE_A_WHILE)
+ && (sc->lmc_out_deficit > LMC_LOTS_OF_PACKETS)) {
+ log(LOG_ERR, "%s%d: No response from remote end\n",
+ sc->lmc_name, sc->lmc_unit);
+ s = splimp();
+ lmc_ifdown(sc);
+ lmc_ifup(sc);
+ sc->lmc_inlast = sc->lmc_out_deficit = 0;
+ splx(s);
+ } else if (sc->lmc_xmit_busy) {
+ if (sc->lmc_out_dog == 0) {
+ log(LOG_ERR, "ar%d: Transmit failure.. no clock?\n",
+ sc->lmc_unit);
+ s = splimp();
+ lmc_watchdog(sc);
+#if 0
+ lmc_ifdown(sc);
+ lmc_ifup(sc);
+#endif
+ splx(s);
+ sc->lmc_inlast = sc->lmc_out_deficit = 0;
+ } else {
+ sc->lmc_out_dog--;
+ }
}
+ lmc_watchdog(sc);
+ sc->lmc_handle = timeout(ng_lmc_watchdog_frame, sc, hz);
}
-#endif
-#if defined(__bsdi__)
-static ifnet_ret_t
-lmc_ifstart(struct ifnet * const ifp)
+/***********************************************************************
+ * This section contains the methods for the Netgraph interface
+ ***********************************************************************/
+/*
+ * It is not possible or allowable to create a node of this type.
+ * If the hardware exists, it will already have created it.
+ */
+static int
+ng_lmc_constructor(node_p *nodep)
{
- lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
- struct mbuf *m;
- struct ifqueue *ifq;
+ return (EINVAL);
+}
- if ((sc->lmc_flags & LMC_IFUP) == 0)
- return;
+/*
+ * give our ok for a hook to be added...
+ * If we are not running this should kick the device into life.
+ * We allow hooks called "control", "rawdata", and "debug".
+ * The hook's private info points to our stash of info about that
+ * device.
+ */
+static int
+ng_lmc_newhook(node_p node, hook_p hook, const char *name)
+{
+ lmc_softc_t * sc = (lmc_softc_t *) node->private;
+
+ /*
+ * check if it's our friend the debug hook
+ */
+ if (strcmp(name, NG_LMC_HOOK_DEBUG) == 0) {
+ hook->private = NULL; /* paranoid */
+ sc->lmc_debug_hook = hook;
+ return (0);
+ }
+
+ /*
+ * Check for raw mode hook.
+ */
+ if (strcmp(name, NG_LMC_HOOK_RAW) != 0) {
+ return (EINVAL);
+ }
+ hook->private = sc;
+ sc->lmc_hook = hook;
+ sc->lmc_datahooks++;
+ lmc_ifup(sc);
+ return (0);
+}
- for (;;) {
- ifq = &sc->lmc_p2pcom.p2p_isnd;
+/*
+ * incoming messages.
+ * Just respond to the generic TEXT_STATUS message
+ */
+static int
+ng_lmc_rcvmsg(node_p node,
+ struct ng_mesg *msg, const char *retaddr, struct ng_mesg **rptr)
+{
+ lmc_softc_t *sc = (lmc_softc_t *) node->private;
+ struct ng_mesg *resp = NULL;
+ int error = 0;
- m = ifq->ifq_head;
- if (m == NULL) {
- ifq = &sc->lmc_if.if_snd;
- m = ifq->ifq_head;
- }
- if (m == NULL)
- break;
- IF_DEQUEUE(ifq, m);
+ switch (msg->header.typecookie) {
+ case NG_LMC_COOKIE:
+ switch (msg->header.cmd) {
+ case NGM_LMC_GET_CTL:
+ {
+ lmc_ctl_t *ctl;
- m = lmc_txput(sc, m);
- if (m != NULL) {
- IF_PREPEND(ifq, m);
+ NG_MKRESPONSE(resp, msg, sizeof(*ctl), M_NOWAIT);
+ if (!resp) {
+ error = ENOMEM;
+ break;
+ }
+ ctl = (lmc_ctl_t *) resp->data;
+ memcpy( ctl, &sc->ictl, sizeof(*ctl) );
break;
- }
- }
-
- LMC_CSR_WRITE(sc, csr_txpoll, 1);
-}
-
-static ifnet_ret_t
-lmc_ifstart_one(struct ifnet * const ifp)
-{
- lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
- struct mbuf *m;
- struct ifqueue *ifq;
+ }
+ case NGM_LMC_SET_CTL:
+ {
+ lmc_ctl_t *ctl;
- if ((sc->lmc_flags & LMC_IFUP) == 0)
- return;
+ if (msg->header.arglen != sizeof(*ctl)) {
+ error = EINVAL;
+ break;
+ }
- ifq = &sc->lmc_p2pcom.p2p_isnd;
+ ctl = (lmc_ctl_t *) msg->data;
+ sc->lmc_media->set_status(sc, ctl);
+ break;
+ }
+ default:
+ error = EINVAL; /* unknown command */
+ break;
+ }
+ break;
+ case NGM_GENERIC_COOKIE:
+ switch(msg->header.cmd) {
+ case NGM_TEXT_STATUS: {
+ char *arg;
+ int pos = 0;
+ int resplen = sizeof(struct ng_mesg) + 512;
+ MALLOC(resp, struct ng_mesg *, resplen, M_NETGRAPH,
+ M_NOWAIT);
+ if (resp == NULL) {
+ error = ENOMEM;
+ break;
+ }
+ bzero(resp, resplen);
+ arg = (resp)->data;
- m = ifq->ifq_head;
- if (m == NULL) {
- ifq = &sc->lmc_if.if_snd;
- m = ifq->ifq_head;
+ /*
+ * Put in the throughput information.
+ */
+ pos = sprintf(arg, "%ld bytes in, %ld bytes out\n"
+ "highest rate seen: %ld B/S in, "
+ "%ld B/S out\n",
+ sc->lmc_inbytes, sc->lmc_outbytes,
+ sc->lmc_inrate, sc->lmc_outrate);
+ pos += sprintf(arg + pos, "%ld output errors\n",
+ sc->lmc_oerrors);
+ pos += sprintf(arg + pos, "%ld input errors\n",
+ sc->lmc_ierrors);
+
+ resp->header.version = NG_VERSION;
+ resp->header.arglen = strlen(arg) + 1;
+ resp->header.token = msg->header.token;
+ resp->header.typecookie = NG_LMC_COOKIE;
+ resp->header.cmd = msg->header.cmd;
+ strncpy(resp->header.cmdstr, "status",
+ NG_CMDSTRLEN);
+ }
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ break;
+ default:
+ error = EINVAL;
+ break;
}
- if (m == NULL)
- return 0;
- IF_DEQUEUE(ifq, m);
- m = lmc_txput(sc, m);
- if (m != NULL)
- IF_PREPEND(ifq, m);
+ /* Take care of synchronous response, if any */
+ if (rptr)
+ *rptr = resp;
+ else if (resp)
+ FREE(resp, M_NETGRAPH);
- LMC_CSR_WRITE(sc, csr_txpoll, 1);
+ free(msg, M_NETGRAPH);
+ return (error);
}
-#endif
-
-#if defined(__bsdi__)
-int
-lmc_getmdm(struct p2pcom *pp, caddr_t b)
-{
- lmc_softc_t *sc = LMC_UNIT_TO_SOFTC(pp->p2p_if.if_unit);
-
- if (sc->lmc_media->get_link_status(sc)) {
- *(int *)b = TIOCM_CAR;
- } else {
- *(int *)b = 0;
- }
- return (0);
+/*
+ * get data from another node and transmit it to the line
+ */
+static int
+ng_lmc_rcvdata(hook_p hook, struct mbuf *m, meta_p meta)
+{
+ int s;
+ int error = 0;
+ lmc_softc_t * sc = (lmc_softc_t *) hook->node->private;
+ struct ifqueue *xmitq_p;
+
+ /*
+ * data doesn't come in from just anywhere (e.g control hook)
+ */
+ if ( hook->private == NULL) {
+ error = ENETDOWN;
+ goto bad;
+ }
+
+ /*
+ * Now queue the data for when it can be sent
+ */
+ if (meta && meta->priority > 0) {
+ xmitq_p = (&sc->lmc_xmitq_hipri);
+ } else {
+ xmitq_p = (&sc->lmc_xmitq);
+ }
+ s = splimp();
+ if (IF_QFULL(xmitq_p)) {
+ IF_DROP(xmitq_p);
+ splx(s);
+ error = ENOBUFS;
+ goto bad;
+ }
+ IF_ENQUEUE(xmitq_p, m);
+ lmc_ifstart_one(sc);
+ splx(s);
+ return (0);
+
+bad:
+ /*
+ * It was an error case.
+ * check if we need to free the mbuf, and then return the error
+ */
+ NG_FREE_DATA(m, meta);
+ return (error);
}
-int
-lmc_mdmctl(struct p2pcom *pp, int flag)
+/*
+ * do local shutdown processing..
+ * this node will refuse to go away, unless the hardware says to..
+ * don't unref the node, or remove our name. just clear our links up.
+ */
+static int
+ng_lmc_rmnode(node_p node)
{
- lmc_softc_t *sc = LMC_UNIT_TO_SOFTC(pp->p2p_if.if_unit);
+ lmc_softc_t * sc = (lmc_softc_t *) node->private;
- sc->lmc_media->set_link_status(sc, flag);
-
- if (flag)
- if ((sc->lmc_flags & LMC_IFUP) == 0)
- lmc_ifup(sc);
- else
- if ((sc->lmc_flags & LMC_IFUP) == LMC_IFUP)
- lmc_ifdown(sc);
-
- return (0);
+ lmc_ifdown(sc);
+ ng_cutlinks(node);
+ node->flags &= ~NG_INVALID; /* bounce back to life */
+ return (0);
+}
+/* already linked */
+static int
+ng_lmc_connect(hook_p hook)
+{
+ /* be really amiable and just say "YUP that's OK by me! " */
+ return (0);
}
-#endif
/*
- * Set up the OS interface magic and attach to the operating system
- * network services.
+ * notify on hook disconnection (destruction)
+ *
+ * For this type, removal of the last link resets tries to destroy the node.
+ * As the device still exists, the shutdown method will not actually
+ * destroy the node, but reset the device and leave it 'fresh' :)
+ *
+ * The node removal code will remove all references except that owned by the
+ * driver.
*/
-static void
-lmc_attach(lmc_softc_t * const sc)
+static int
+ng_lmc_disconnect(hook_p hook)
{
- struct ifnet * const ifp = &sc->lmc_if;
-
- ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
- ifp->if_ioctl = lmc_ifioctl;
- ifp->if_start = lmc_ifstart;
- ifp->if_watchdog = lmc_watchdog;
- ifp->if_timer = 1;
- ifp->if_mtu = LMC_MTU;
-
-#if defined(__bsdi__)
- ifp->if_type = IFT_NONE;
- ifp->if_unit = (sc->lmc_dev.dv_unit);
-#endif
-
- if_attach(ifp);
-
-#if defined(__NetBSD__) || defined(__FreeBSD__)
- sppp_attach((struct ifnet *)&sc->lmc_sppp);
- sc->lmc_sppp.pp_flags = PP_CISCO | PP_KEEPALIVE;
-#endif
-#if defined(__bsdi__)
- sc->lmc_p2pcom.p2p_mdmctl = lmc_mdmctl;
- sc->lmc_p2pcom.p2p_getmdm = lmc_getmdm;
- p2p_attach(&sc->lmc_p2pcom);
-#endif
-
-#if NBPFILTER > 0
- LMC_BPF_ATTACH(sc);
-#endif
-
-#if defined(__NetBSD__) && NRND > 0
- rnd_attach_source(&sc->lmc_rndsource, sc->lmc_dev.dv_xname,
- RND_TYPE_NET);
-#endif
-
- /*
- * turn off those LEDs...
- */
- sc->lmc_miireg16 |= LMC_MII16_LED_ALL;
- lmc_led_on(sc, LMC_MII16_LED0);
+ lmc_softc_t * sc = (lmc_softc_t *) hook->node->private;
+ int s;
+ /*
+ * If it's the data hook, then free resources etc.
+ */
+ if (hook->private) {
+ s = splimp();
+ sc->lmc_datahooks--;
+ if (sc->lmc_datahooks == 0)
+ lmc_ifdown(sc);
+ splx(s);
+ } else {
+ sc->lmc_debug_hook = NULL;
+ }
+ return (0);
}
-
+
+/*
+ * called during bootup
+ * or LKM loading to put this type into the list of known modules
+ */
static void
-lmc_initring(lmc_softc_t * const sc, lmc_ringinfo_t * const ri,
- tulip_desc_t *descs, int ndescs)
+ng_lmc_init(void *ignored)
{
- ri->ri_max = ndescs;
- ri->ri_first = descs;
- ri->ri_last = ri->ri_first + ri->ri_max;
- bzero((caddr_t) ri->ri_first, sizeof(ri->ri_first[0]) * ri->ri_max);
- ri->ri_last[-1].d_flag = TULIP_DFLAG_ENDRING;
+ if (ng_newtype(&typestruct))
+ printf("ng_lmc install failed\n");
+ ng_lmc_done_init = 1;
}
/*
@@ -1385,12 +1519,4 @@ lmc_initring(lmc_softc_t * const sc, lmc_ringinfo_t * const ri,
-#if defined(__NetBSD__)
-#include "dev/pci/if_lmc_nbsd.c"
-#elif defined(__FreeBSD__)
-#include "pci/if_lmc_fbsd.c"
-#elif defined(__bsdi__)
-#include "i386/pci/if_lmc_bsdi.c"
-#else
-#error "This driver only works on NetBSD, FreeBSD, or BSDi"
-#endif
+#include "dev/lmc/if_lmc_fbsd3.c"
diff --git a/sys/dev/lmc/if_lmc_common.c b/sys/dev/lmc/if_lmc_common.c
index d4ab484..69514cf 100644
--- a/sys/dev/lmc/if_lmc_common.c
+++ b/sys/dev/lmc/if_lmc_common.c
@@ -1,7 +1,3 @@
-/* $FreeBSD$ */
-/* From NetBSD: if_de.c,v 1.56.2.1 1997/10/27 02:13:25 thorpej Exp */
-/* $Id: if_lmc_common.c,v 1.12 1999/03/01 15:22:37 explorer Exp $ */
-
/*-
* Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
* Copyright (c) LAN Media Corporation 1998, 1999.
@@ -25,6 +21,10 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ * From NetBSD: if_de.c,v 1.56.2.1 1997/10/27 02:13:25 thorpej Exp
+ * $Id: if_lmc_common.c,v 1.12 1999/03/01 15:22:37 explorer Exp $
*/
/*
diff --git a/sys/dev/lmc/if_lmc_fbsd3.c b/sys/dev/lmc/if_lmc_fbsd3.c
index f2344f4..ce7c947 100644
--- a/sys/dev/lmc/if_lmc_fbsd3.c
+++ b/sys/dev/lmc/if_lmc_fbsd3.c
@@ -1,9 +1,7 @@
-/* $FreeBSD$ */
-/* $Id: if_lmc_fbsd.c,v 1.3 1999/01/12 13:27:42 explorer Exp $ */
-
/*-
* Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
* Copyright (c) LAN Media Corporation 1998, 1999.
+ * Copyright (c) 2000 Stephen Kiernan (sk-ports@vegamuse.org)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,6 +22,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ * $Id: if_lmc_fbsd.c,v 1.3 1999/01/12 13:27:42 explorer Exp $
*/
/*
@@ -35,7 +36,9 @@
#define PCI_GETBUSDEVINFO(sc) (sc)->lmc_pci_busno = (config_id->bus), \
(sc)->lmc_pci_devno = (config_id->slot)
+#if 0
static void lmc_shutdown(int howto, void * arg);
+#endif
#if defined(LMC_DEVCONF)
static int
@@ -51,7 +54,7 @@ lmc_pci_shutdown(struct kern_devconf * const kdc, int force)
}
#endif
-static char*
+static const char*
lmc_pci_probe(pcici_t config_id, pcidi_t device_id)
{
u_int32_t id;
@@ -104,13 +107,17 @@ struct pci_device lmcdevice = {
#endif
};
-DATA_SET (pcidevice_set, lmcdevice);
+#ifdef COMPAT_PCI_DRIVER
+COMPAT_PCI_DRIVER(ti, lmcdevice);
+#else
+DATA_SET(pcidevice_set, lmcdevice);
+#endif /* COMPAT_PCI_DRIVER */
static void
lmc_pci_attach(pcici_t config_id, int unit)
{
lmc_softc_t *sc;
- int retval, idx;
+ int retval;
u_int32_t revinfo, cfdainfo, id, ssid;
#if !defined(LMC_IOMAPPED)
vm_offset_t pa_csrs;
@@ -119,7 +126,6 @@ lmc_pci_attach(pcici_t config_id, int unit)
unsigned csrsize = LMC_PCI_CSRSIZE;
lmc_csrptr_t csr_base;
lmc_spl_t s;
- lmc_intrfunc_t (*intr_rtn)(void *) = lmc_intr_normal;
if (unit >= LMC_MAX_DEVICES) {
printf("lmc%d", unit);
@@ -185,9 +191,6 @@ lmc_pci_attach(pcici_t config_id, int unit)
sc->lmc_unit = unit;
sc->lmc_name = "lmc";
sc->lmc_revinfo = revinfo;
-#if BSD >= 199506
- sc->lmc_if.if_softc = sc;
-#endif
#if defined(LMC_IOMAPPED)
retval = pci_map_port(config_id, PCI_CBIO, &csr_base);
#else
@@ -240,19 +243,21 @@ lmc_pci_attach(pcici_t config_id, int unit)
}
lmc_read_macaddr(sc);
- printf("pass %d.%d, serial " LMC_EADDR_FMT "\n",
+ printf("lmc%d: pass %d.%d, serial " LMC_EADDR_FMT "\n", unit,
(sc->lmc_revinfo & 0xF0) >> 4, sc->lmc_revinfo & 0x0F,
LMC_EADDR_ARGS(sc->lmc_enaddr));
- if (!pci_map_int (config_id, intr_rtn, (void*) sc, &net_imask)) {
+ if (!pci_map_int (config_id, lmc_intr_normal, (void*) sc, &net_imask)) {
printf(LMC_PRINTF_FMT ": couldn't map interrupt\n",
LMC_PRINTF_ARGS);
return;
}
+#if 0
#if !defined(LMC_DEVCONF)
at_shutdown(lmc_shutdown, sc, SHUTDOWN_POST_SYNC);
#endif
+#endif
s = LMC_RAISESPL();
lmc_dec_reset(sc);
@@ -261,6 +266,7 @@ lmc_pci_attach(pcici_t config_id, int unit)
LMC_RESTORESPL(s);
}
+#if 0
static void
lmc_shutdown(int howto, void * arg)
{
@@ -272,3 +278,4 @@ lmc_shutdown(int howto, void * arg)
printf("lmc: 5\n");
lmc_led_on(sc, LMC_MII16_LED_ALL);
}
+#endif
diff --git a/sys/dev/lmc/if_lmc_media.c b/sys/dev/lmc/if_lmc_media.c
index a96afa7..ab11dfd 100644
--- a/sys/dev/lmc/if_lmc_media.c
+++ b/sys/dev/lmc/if_lmc_media.c
@@ -1,9 +1,7 @@
-/* $FreeBSD$ */
-/* $Id: if_lmc_media.c,v 1.23 1999/03/01 15:12:24 explorer Exp $ */
-
-/*-
+/*
* Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
* Copyright (c) LAN Media Corporation 1998, 1999.
+ * Copyright (c) 2000 Stephen Kiernan (sk-ports@vegamuse.org)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,6 +22,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ * $Id: if_lmc_media.c,v 1.23 1999/03/01 15:12:24 explorer Exp $
*/
/*
@@ -684,24 +685,6 @@ lmc_set_protocol(lmc_softc_t * const sc, lmc_ctl_t *ctl)
return;
}
-
-#if defined(__NetBSD__) || defined(__FreeBSD__)
- if (ctl->keepalive_onoff != sc->ictl.keepalive_onoff) {
- switch (ctl->keepalive_onoff) {
- case LMC_CTL_ON:
- printf(LMC_PRINTF_FMT ": enabling keepalive\n",
- LMC_PRINTF_ARGS);
- sc->ictl.keepalive_onoff = LMC_CTL_ON;
- sc->lmc_sppp.pp_flags = PP_CISCO | PP_KEEPALIVE;
- break;
- case LMC_CTL_OFF:
- printf(LMC_PRINTF_FMT ": disabling keepalive\n",
- LMC_PRINTF_ARGS);
- sc->ictl.keepalive_onoff = LMC_CTL_OFF;
- sc->lmc_sppp.pp_flags = PP_CISCO;
- }
- }
-#endif
}
/*
@@ -718,6 +701,7 @@ static void lmc_t1_write(lmc_softc_t * const sc, int a, int d)
lmc_mii_writereg(sc, 0, 18, d);
}
+#if 0
/* XXX future to be integtrated with if_lmc.c for alarms */
static int lmc_t1_read(lmc_softc_t * const sc, int a)
@@ -725,6 +709,7 @@ static int lmc_t1_read(lmc_softc_t * const sc, int a)
lmc_mii_writereg(sc, 0, 17, a);
return lmc_mii_readreg(sc, 0, 18);
}
+#endif
static void
lmc_t1_init(lmc_softc_t * const sc)
diff --git a/sys/dev/lmc/if_lmcioctl.h b/sys/dev/lmc/if_lmcioctl.h
index 13afd3a..113ba5e 100644
--- a/sys/dev/lmc/if_lmcioctl.h
+++ b/sys/dev/lmc/if_lmcioctl.h
@@ -1,6 +1,3 @@
-/* $FreeBSD$ */
-/* $Id: if_lmcioctl.h,v 1.9 1999/02/18 10:30:18 explorer Exp $ */
-
/*-
* Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
* Copyright (c) LAN Media Corporation 1998, 1999.
@@ -24,6 +21,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ * $Id: if_lmcioctl.h,v 1.9 1999/02/18 10:30:18 explorer Exp $
*/
/*
diff --git a/sys/dev/lmc/if_lmcvar.h b/sys/dev/lmc/if_lmcvar.h
index 48bee6b..58b02b0 100644
--- a/sys/dev/lmc/if_lmcvar.h
+++ b/sys/dev/lmc/if_lmcvar.h
@@ -1,10 +1,7 @@
-/* $FreeBSD$ */
-/* From NetBSD: if_devar.h,v 1.21 1997/10/16 22:02:32 matt Exp */
-/* $Id: if_lmcvar.h,v 1.6 1999/01/12 14:16:58 explorer Exp $ */
-
/*-
* Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
* Copyright (c) LAN Media Corporation 1998, 1999.
+ * Copyright (c) 2000 Stephen Kiernan (sk-ports@vegamuse.org)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,10 +22,14 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ * From NetBSD: if_devar.h,v 1.21 1997/10/16 22:02:32 matt Exp
+ * $Id: if_lmcvar.h,v 1.6 1999/01/12 14:16:58 explorer Exp $
*/
-#if !defined(_DEVAR_H)
-#define _DEVAR_H
+#if !defined(_DEV_LMC_IF_LMCVAR_H)
+#define _DEV_LMC_IF_LMCVAR_H
#define LMC_MTU 1500
#define PPP_HEADER_LEN 4
@@ -50,33 +51,12 @@
#define PCI_PRODUCT_LMC_T1 0x0006
#endif
-#if defined(__NetBSD__)
-
-#include "rnd.h"
-#if NRND > 0
-#include <sys/rnd.h>
-#endif
-
-typedef bus_addr_t lmc_csrptr_t;
-
-#define LMC_CSR_READ(sc, csr) \
- bus_space_read_4((sc)->lmc_bustag, (sc)->lmc_bushandle, (sc)->lmc_csrs.csr)
-#define LMC_CSR_WRITE(sc, csr, val) \
- bus_space_write_4((sc)->lmc_bustag, (sc)->lmc_bushandle, (sc)->lmc_csrs.csr, (val))
-
-#define LMC_CSR_READBYTE(sc, csr) \
- bus_space_read_1((sc)->lmc_bustag, (sc)->lmc_bushandle, (sc)->lmc_csrs.csr)
-#define LMC_CSR_WRITEBYTE(sc, csr, val) \
- bus_space_write_1((sc)->lmc_bustag, (sc)->lmc_bushandle, (sc)->lmc_csrs.csr, (val))
-#endif /* __NetBSD__ */
-
#ifdef LMC_IOMAPPED
#define LMC_EISA_CSRSIZE 16
#define LMC_EISA_CSROFFSET 0
#define LMC_PCI_CSRSIZE 8
#define LMC_PCI_CSROFFSET 0
-#if !defined(__NetBSD__)
typedef u_int16_t lmc_csrptr_t;
#define LMC_CSR_READ(sc, csr) (inl((sc)->lmc_csrs.csr))
@@ -84,14 +64,12 @@ typedef u_int16_t lmc_csrptr_t;
#define LMC_CSR_READBYTE(sc, csr) (inb((sc)->lmc_csrs.csr))
#define LMC_CSR_WRITEBYTE(sc, csr, val) outb((sc)->lmc_csrs.csr, val)
-#endif /* __NetBSD__ */
#else /* LMC_IOMAPPED */
#define LMC_PCI_CSRSIZE 8
#define LMC_PCI_CSROFFSET 0
-#if !defined(__NetBSD__)
typedef volatile u_int32_t *lmc_csrptr_t;
/*
@@ -101,7 +79,6 @@ typedef volatile u_int32_t *lmc_csrptr_t;
*/
#define LMC_CSR_READ(sc, csr) (0 + *(sc)->lmc_csrs.csr)
#define LMC_CSR_WRITE(sc, csr, val) ((void)(*(sc)->lmc_csrs.csr = (val)))
-#endif /* __NetBSD__ */
#endif /* LMC_IOMAPPED */
@@ -257,29 +234,9 @@ typedef struct {
*
*/
struct lmc___softc {
-#if defined(__bsdi__)
- struct device lmc_dev; /* base device */
- struct isadev lmc_id; /* ISA device */
- struct intrhand lmc_ih; /* intrrupt vectoring */
- struct atshutdown lmc_ats; /* shutdown hook */
- struct p2pcom lmc_p2pcom; /* point-to-point common stuff */
-
-#define lmc_if lmc_p2pcom.p2p_if /* network-visible interface */
-#endif /* __bsdi__ */
-
-#if defined(__NetBSD__)
- struct device lmc_dev; /* base device */
- void *lmc_ih; /* intrrupt vectoring */
- void *lmc_ats; /* shutdown hook */
- bus_space_tag_t lmc_bustag;
- bus_space_handle_t lmc_bushandle; /* CSR region handle */
- pci_chipset_tag_t lmc_pc;
-#endif
-#if defined(__NetBSD__) || defined(__FreeBSD__)
- struct sppp lmc_sppp;
-#define lmc_if lmc_sppp.pp_if
-#endif
+ const char *lmc_name;
+ int lmc_unit;
u_int8_t lmc_enaddr[6]; /* yes, a small hack... */
lmc_regfile_t lmc_csrs;
@@ -312,29 +269,54 @@ struct lmc___softc {
lmc_ctl_t ictl;
LMC_XINFO lmc_xinfo;
-#if defined(__NetBSD__)
- struct device *lmc_pci_busno; /* needed for multiport boards */
-#else
u_int8_t lmc_pci_busno; /* needed for multiport boards */
-#endif
u_int8_t lmc_pci_devno; /* needed for multiport boards */
-#if defined(__FreeBSD__)
tulip_desc_t *lmc_rxdescs;
tulip_desc_t *lmc_txdescs;
-#else
- tulip_desc_t lmc_rxdescs[LMC_RXDESCS];
- tulip_desc_t lmc_txdescs[LMC_TXDESCS];
-#endif
-#if defined(__NetBSD__) && NRND > 0
- rndsource_element_t lmc_rndsource;
-#endif
u_int32_t lmc_crcSize;
char lmc_timing; /* for HSSI and SSI */
u_int16_t t1_alarm1_status;
u_int16_t t1_alarm2_status;
+ int lmc_running;
+ char lmc_nodename[NG_NODELEN + 1];
+ int lmc_datahooks;
+ node_p lmc_node;
+ hook_p lmc_hook;
+ hook_p lmc_debug_hook;
+ struct ifqueue lmc_xmitq_hipri;
+ struct ifqueue lmc_xmitq;
+ struct callout_handle lmc_handle;
+ char lmc_xmit_busy;
+ int lmc_out_dog;
+ u_long lmc_inbytes, lmc_outbytes; /* stats */
+ u_long lmc_lastinbytes, lmc_lastoutbytes; /* a second ago */
+ u_long lmc_inrate, lmc_outrate; /* highest rate seen */
+ u_long lmc_inlast; /* last input N secs ago */
+ u_long lmc_out_deficit; /* output since last input */
+ u_long lmc_oerrors, lmc_ierrors;
+ u_long lmc_opackets, lmc_ipackets;
+};
+
+
+#define LMC_DOG_HOLDOFF 6 /* dog holds off for 6 secs */
+#define LMC_QUITE_A_WHILE 300 /* 5 MINUTES */
+#define LMC_LOTS_OF_PACKETS 100
+
+/* Node type name and type cookie */
+#define NG_LMC_NODE_TYPE "lmc"
+#define NG_LMC_COOKIE 956095698
+/* Netgraph hooks */
+#define NG_LMC_HOOK_DEBUG "debug"
+#define NG_LMC_HOOK_CONTROL "control"
+#define NG_LMC_HOOK_RAW "rawdata"
+
+/* Netgraph commands understood by this node type */
+enum {
+ NGM_LMC_SET_CTL = 1,
+ NGM_LMC_GET_CTL,
};
/*
@@ -432,70 +414,19 @@ static const char * const lmc_status_bits[] = {
*/
#define LMC_MAX_DEVICES 32
-#if defined(__FreeBSD__)
typedef void ifnet_ret_t;
typedef int ioctl_cmd_t;
static lmc_softc_t *tulips[LMC_MAX_DEVICES];
-#if BSD >= 199506
#define LMC_IFP_TO_SOFTC(ifp) ((lmc_softc_t *)((ifp)->if_softc))
-#if NBPFILTER > 0
-#define LMC_BPF_MTAP(sc, m) bpf_mtap(&(sc)->lmc_sppp.pp_if, m)
-#define LMC_BPF_TAP(sc, p, l) bpf_tap(&(sc)->lmc_sppp.pp_if, p, l)
-#define LMC_BPF_ATTACH(sc) bpfattach(&(sc)->lmc_sppp.pp_if, DLT_PPP, PPP_HEADER_LEN)
-#endif
#define lmc_intrfunc_t void
#define LMC_VOID_INTRFUNC
#define IFF_NOTRAILERS 0
#define CLBYTES PAGE_SIZE
#define LMC_EADDR_FMT "%6D"
#define LMC_EADDR_ARGS(addr) addr, ":"
-#else
-extern int bootverbose;
-#define LMC_IFP_TO_SOFTC(ifp) (LMC_UNIT_TO_SOFTC((ifp)->if_unit))
-#include <sys/devconf.h>
-#define LMC_DEVCONF
-#endif
#define LMC_UNIT_TO_SOFTC(unit) (tulips[unit])
#define LMC_BURSTSIZE(unit) pci_max_burst_len
#define loudprintf if (bootverbose) printf
-#endif
-
-#if defined(__bsdi__)
-typedef int ifnet_ret_t;
-typedef u_long ioctl_cmd_t;
-extern struct cfdriver lmccd;
-#define LMC_UNIT_TO_SOFTC(unit) ((lmc_softc_t *)lmccd.cd_devs[unit])
-#define LMC_IFP_TO_SOFTC(ifp) (LMC_UNIT_TO_SOFTC((ifp)->if_unit))
-#define loudprintf aprint_verbose
-#define MCNT(x) (sizeof(x) / sizeof(struct ifmedia_entry))
-#define lmc_unit lmc_dev.dv_unit
-#define lmc_name lmc_p2pcom.p2p_if.if_name
-#define LMC_BPF_MTAP(sc, m)
-#define LMC_BPF_TAP(sc, p, l)
-#define LMC_BPF_ATTACH(sc)
-#endif /* __bsdi__ */
-
-#if defined(__NetBSD__)
-typedef void ifnet_ret_t;
-typedef u_long ioctl_cmd_t;
-extern struct cfattach de_ca;
-extern struct cfdriver de_cd;
-#define LMC_UNIT_TO_SOFTC(unit) ((lmc_softc_t *) de_cd.cd_devs[unit])
-#define LMC_IFP_TO_SOFTC(ifp) ((lmc_softc_t *)((ifp)->if_softc))
-#define lmc_unit lmc_dev.dv_unit
-#define lmc_xname lmc_if.if_xname
-#define LMC_RAISESPL() splnet()
-#define LMC_RAISESOFTSPL() splsoftnet()
-#define LMC_RESTORESPL(s) splx(s)
-#define lmc_enaddr lmc_enaddr
-#define loudprintf printf
-#define LMC_PRINTF_FMT "%s"
-#define LMC_PRINTF_ARGS sc->lmc_xname
-#if defined(__alpha__)
-/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */
-#define LMC_KVATOPHYS(sc, va) alpha_XXX_dmamap((vm_offset_t)(va))
-#endif
-#endif /* __NetBSD__ */
#ifndef LMC_PRINTF_FMT
#define LMC_PRINTF_FMT "%s%d"
@@ -508,23 +439,6 @@ extern struct cfdriver de_cd;
#define LMC_BURSTSIZE(unit) 3
#endif
-#ifndef lmc_unit
-#define lmc_unit lmc_sppp.pp_if.if_unit
-#endif
-
-#ifndef lmc_name
-#define lmc_name lmc_sppp.pp_if.if_name
-#endif
-
-#if !defined(lmc_bpf)
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-#define lmc_bpf lmc_sppp.pp_if.if_bpf
-#endif
-#if defined(__bsdi__)
-#define lmc_bpf lmc_if.if_bpf
-#endif
-#endif
-
#if !defined(lmc_intrfunc_t)
#define lmc_intrfunc_t int
#endif
@@ -575,4 +489,4 @@ extern struct cfdriver de_cd;
typedef int lmc_spl_t;
-#endif /* !defined(_DEVAR_H) */
+#endif /* !defined(_DEV_LMC_IF_LMCVAR_H) */
diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT
index e78cbb8..3df5e53 100644
--- a/sys/i386/conf/LINT
+++ b/sys/i386/conf/LINT
@@ -408,6 +408,7 @@ options NETGRAPH_UI
options NETGRAPH_VJC
device mn # Munich32x/Falc54 Nx64kbit/sec cards.
+device lmc # tulip based LanMedia WAN cards
#
# Network interfaces:
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index e78cbb8..3df5e53 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -408,6 +408,7 @@ options NETGRAPH_UI
options NETGRAPH_VJC
device mn # Munich32x/Falc54 Nx64kbit/sec cards.
+device lmc # tulip based LanMedia WAN cards
#
# Network interfaces:
OpenPOWER on IntegriCloud