diff options
-rw-r--r-- | sys/conf/NOTES | 1 | ||||
-rw-r--r-- | sys/conf/files | 1 | ||||
-rw-r--r-- | sys/dev/lmc/if_lmc.c | 916 | ||||
-rw-r--r-- | sys/dev/lmc/if_lmc_common.c | 8 | ||||
-rw-r--r-- | sys/dev/lmc/if_lmc_fbsd3.c | 31 | ||||
-rw-r--r-- | sys/dev/lmc/if_lmc_media.c | 29 | ||||
-rw-r--r-- | sys/dev/lmc/if_lmcioctl.h | 6 | ||||
-rw-r--r-- | sys/dev/lmc/if_lmcvar.h | 180 | ||||
-rw-r--r-- | sys/i386/conf/LINT | 1 | ||||
-rw-r--r-- | sys/i386/conf/NOTES | 1 |
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: |