Date: Thu, 31 Dec 1998 10:34:44 -0500 (EST) From: Larry Lile <lile@stdio.com> To: hackers@FreeBSD.ORG Subject: ifmedia and token-ring (Help!!) (fwd) Message-ID: <Pine.BSF.4.05.9812311032240.5164-300000@heathers.stdio.com>
index | next in thread | raw e-mail
[-- Attachment #1 --] I am trying to get ifmedia working for my Olicom token-ring driver but I am having some strange problems. First when I have probed/attached the card and ifconfig it it comes up with this: oltr1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 18000 inet 10.0.0.1 netmask 0xffffff00 broadcast 10.0.0.255 lladdr 00:00:83:2f:c3:ad media: autoselect (<unknown type>) supported media: UTP/16Mbit UTP/4Mbit autoselect I really don't understand why I am getting "(<unknown type>)" and I can only select "UTP/4Mbit" or "autoselect" but not "UTP/16Mbit". I have attached my patches to the if_media.h file and my driver. I am not attached to to names or values for anything I changed in if_media. I also forgot to add the 4/16 Fiber values... Their is also an issue of mode, there is "classic" mode which is compatible with the old ibm type of token-ring, "dedicated" mode where you are expected to be hooked directly to a token-ring switch and also a autosense mode. I am not quite sure where this should fit in but I put it in as a type option. Any help? Larry Lile lile@stdio.com [-- Attachment #2 --] /* * Copyright (c) 1998, Larry Lile * All rights reserved. * * For latest sources and information on this driver, please * go to http://anarchy.stdio.com. * * Questions, comments or suggestions should be directed to * Larry Lile <lile@stdio.com>. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: if_oltr.c,v 1.13 1998/12/10 18:55:12 lile Exp lile $ */ #include "pci.h" #include "oltr.h" #include "opt_inet.h" #include "bpfilter.h" #if (NOLTR + NPCI) > 0 /*#define TRlldInlineIO*/ #define ISA_ADAPTERS (OC_3115 | OC_3117 | OC_3118) #define PCI_ADAPTERS (OC_3133 | OC_3136 | OC_3137 | \ OC_3139 | OC_3140 | OC_3141 | \ OC_3250 | OC_3540 ) #define PCI_VENDOR_OLICOM 0x108D char *AdapterName[] = { /* 0 */ "Olicom XT Adapter [unsupported]", /* 1 */ "Olicom OC-3115", /* 2 */ "Olicom ISA 16/4 Adapter (OC-3117)", /* 3 */ "Olicom ISA 16/4 Adapter (OC-3118)", /* 4 */ "Olicom MCA 16/4 Adapter (OC-3129) [unsupported]", /* 5 */ "Olicom MCA 16/4 Adapter (OC-3129) [unsupported]", /* 6 */ "Olicom MCA 16/4 Adapter (OC-3129) [unsupported]", /* 7 */ "Olicom EISA 16/4 Adapter (OC-3133)", /* 8 */ "Olicom EISA 16/4 Adapter (OC-3133)", /* 9 */ "Olicom EISA 16/4 Server Adapter (OC-3135)", /* 10 */ "Olicom PCI 16/4 Adapter (OC-3136)", /* 11 */ "Olicom PCI 16/4 Adapter (OC-3136)", /* 12 */ "Olicom PCI/II 16/4 Adapter (OC-3137)", /* 13 */ "Olicom PCI 16/4 Adapter (OC-3139)", /* 14 */ "Olicom RapidFire 3140 16/4 PCI Adapter (OC-3140)", /* 15 */ "Olicom RapidFire 3141 Fiber Adapter (OC-3141)", /* 16 */ "Olicom PCMCIA 16/4 Adapter (OC-3220) [unsupported]", /* 17 */ "Olicom PCMCIA 16/4 Adapter (OC-3121, OC-3230, OC-3232) [unsupported]", /* 18 */ "Olicom PCMCIA 16/4 Adapter (OC-3250)", /* 19 */ "Olicom RapidFire 3540 4/16/100 Adapter (OC-3540)" }; #include <sys/param.h> #include <sys/systm.h> #include <sys/proc.h> #include <sys/sockio.h> #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/socket.h> #include <sys/syslog.h> #include <sys/kernel.h> #include <sys/interrupt.h> #include <net/ethernet.h> #include <net/if.h> #include <net/if_arp.h> #include <net/iso88025.h> #include <net/if_media.h> #if NBPFILTER > 0 #include <net/bpf.h> #endif #if NPNP > 0 #include <i386/isa/pnp.h> #endif #include <machine/clock.h> #include <machine/md_var.h> #include <i386/isa/isa_device.h> #if NPCI > 0 #include <pci/pcivar.h> #include <pci/pcireg.h> #endif #ifndef TRLLD_SPEED_AUTO #define TRLLD_SPEED_AUTO 0 #endif void *oltr_malloc(ssize_t, TRlldAdapterConfig_t *); /* * Glue functions prototypes for PMW kit IO */ #ifndef TRlldInlineIO static void DriverOutByte __P((unsigned short, unsigned char)); static void DriverOutWord __P((unsigned short, unsigned short)); static void DriverOutDword __P((unsigned short, unsigned long)); static void DriverRepOutByte __P((unsigned short, unsigned char *, int)); static void DriverRepOutWord __P((unsigned short, unsigned short *, int)); static void DriverRepOutDword __P((unsigned short, unsigned long *, int)); static unsigned char DriverInByte __P((unsigned short)); static unsigned short DriverInWord __P((unsigned short)); static unsigned long DriverInDword __P((unsigned short)); static void DriverRepInByte __P((unsigned short, unsigned char *, int)); static void DriverRepInWord __P((unsigned short, unsigned short *, int)); static void DriverRepInDword __P((unsigned short, unsigned long *, int)); #endif /*TRlldInlineIO*/ static void DriverSuspend __P((unsigned short)); static void DriverStatus __P((void *, TRlldStatus_t *)); static void DriverCloseCompleted __P((void *)); static void DriverStatistics __P((void *, TRlldStatistics_t *)); static void DriverTransmitFrameCompleted __P((void *, void *, int)); static void DriverReceiveFrameCompleted __P((void *, int, int, void *, int)); typedef struct tx_buf { int index; char *buf; } tx_buf_t; typedef struct rx_buf { int index; char *buf; } rx_buf_t; #ifndef EXTRA_OLTR #if NPCI > 0 #define EXTRA_OLTR 8 #else #define EXTRA_OLTR 0 #endif /* NPCI */ #endif /* EXTRA_OLTR */ #ifndef OLTR_PROMISC_MODE #define OLTR_PROMISC_MODE (TRLLD_PROM_LLC) #endif #define ALL_OPTIONS (IFM_TOK_ETR | IFM_TOK_SRCRT | IFM_TOK_ALLR | IFM_TOK_DTR | IFM_TOK_CLASSIC | IFM_TOK_AUTO) /* List sizes MUST be a power of 2 */ #define TX_LIST_SIZE 16 #define RX_LIST_SIZE 16 #define TX_LIST_MASK (TX_LIST_SIZE - 1) #define RX_LIST_MASK (RX_LIST_SIZE - 1) #define RX_BUFFER_LEN 4096 #define TX_BUFFER_LEN 4096 struct oltr_softc { struct arpcom arpcom; struct ifmedia ifmedia; TRlldAdapterConfig_t *config; TRlldAdapter_t *TRlldAdapter; int unit; u_char PromiscMode; u_short AdapterMode; int hw_state; #define HW_UNKNOWN 0 /* initial/absent state */ #define HW_FOUND 1 /* found, not initialized */ #define HW_BAD 2 /* fatal error */ #define HW_FAILED 3 /* closed eg. by remove, allow manual reopen */ #define HW_LOADING 4 #define HW_CLOSING 5 #define HW_CLOSING2 6 #define HW_CLOSED 7 #define HW_OPENING 8 #define HW_OPEN 9 #define HW_ERROR 10 /* temporary error */ u_long GroupAddress; u_long FunctionalAddress; int poll_adapter; int tx_next; int tx_avail; tx_buf_t tx_buffer[TX_LIST_SIZE]; int rx_next; int rx_avail; rx_buf_t rx_buffer[RX_LIST_SIZE]; struct callout_handle oltr_ch; struct callout_handle poll_ch; }; static struct oltr_softc oltr_softc[NOLTR + EXTRA_OLTR]; /* * Driver function prototypes */ static int oltr_probe __P((struct isa_device *)); static int oltr_attach __P((struct isa_device *)); static void oltr_init __P((struct oltr_softc *)); static void oltr_intr __P((int)); static void oltr_start __P((struct ifnet *)); static void oltr_stop __P((struct oltr_softc *)); static int oltr_ioctl __P((struct ifnet *, u_long, caddr_t)); static int oltr_attach_common __P((struct oltr_softc *)); void oltr_timeout __P((void *)); void adapter_poll __P((void *)); struct isa_driver oltrdriver = { oltr_probe, oltr_attach, "oltr", 0 }; int isa_cards = 0; #if NPCI > 0 static u_long oltr_count = NOLTR; static const char *oltr_pci_probe __P((pcici_t, pcidi_t)); static void oltr_pci_attach __P((pcici_t, int)); static void oltr_pci_intr __P((void *)); static void oltr_pci_shutdown __P((int, void *)); static struct pci_device oltr_device = { "oltr", oltr_pci_probe, oltr_pci_attach, &oltr_count, NULL }; DATA_SET(pcidevice_set, oltr_device); int pci_cards = 0; #endif /* NPCI */ static int oltr_ifmedia_upd __P((struct ifnet *)); static void oltr_ifmedia_sts __P((struct ifnet *, struct ifmediareq *)); static TRlldDriver_t oltrLldDriver = { TRLLD_VERSION, #ifndef TRlldInlineIO DriverOutByte, DriverOutWord, DriverOutDword, DriverRepOutByte, DriverRepOutWord, DriverRepOutDword, DriverInByte, DriverInWord, DriverInDword, DriverRepInByte, DriverRepInWord, DriverRepInDword, #endif /*TRlldInlineIO*/ DriverSuspend, DriverStatus, DriverCloseCompleted, DriverStatistics, DriverTransmitFrameCompleted, DriverReceiveFrameCompleted, }; TRlldAdapterConfig_t oltr_config[NOLTR + EXTRA_OLTR]; void * oltr_malloc(Size, Adapter) ssize_t Size; TRlldAdapterConfig_t *Adapter; { /* If the adapter needs memory below 16M for DMA then use contigmalloc */ if (Adapter->mode & TRLLD_MODE_16M) /* Adapter using ISA DMA buffer below 16M */ return(contigmalloc(Size, M_DEVBUF, M_NOWAIT, 0ul, 0xfffffful, 1ul, 0x10000ul)); else return(malloc(Size, M_DEVBUF, M_NOWAIT)); } /* * Driver Functions */ static int oltr_probe(is) struct isa_device *is; { static int find_completed = 0, assigned[NOLTR]; struct oltr_softc *sc = &oltr_softc[is->id_unit]; int i; /* Make life easy, use the Olicom supplied find function on the first probe * to probe all of the ISA adapters. Then give them to each unit as requested. * Try to match the adapters to units based on the iobase, but if iobase? then * just give out the next available adapter. */ if (!find_completed) { isa_cards = TRlldFind(&oltrLldDriver, &oltr_config[0], ISA_ADAPTERS, NOLTR); /*for (i = 0; i < isa_cards; i++) { printf("TRlldFind: card %d - %s MAC %6D\n", i + 1, AdapterName[oltr_config[i].type], oltr_config[i].macaddress, ":"); }*/ for (i = 0; i < NOLTR; i++) assigned[i] = 0; find_completed = 1; } sc->unit = is->id_unit; sc->hw_state = HW_UNKNOWN; if (find_completed && ((isa_cards == 0) || (is->id_unit > isa_cards))) return(0); if (((is->id_iobase < 0xa00) || (is->id_iobase > 0xbe0)) && (is->id_iobase != 0xffffffff)) { printf("oltr%d: port address impossible (0x%X)\n", is->id_unit, is->id_iobase); return(0); } /* Auto assign lowest available card not already in use */ if (is->id_iobase == 0xffffffff) { printf("oltr%d: auto assigning card.\n", is->id_unit); for (i = 0; assigned[i]; i++); assigned[i] = 1; sc->config = &oltr_config[i]; is->id_iobase = sc->config->iobase0; /* Claim our port space */ if (!is->id_irq) is->id_irq = (1 << sc->config->interruptlevel); /* Claim our interrupt */ is->id_intr = (inthand2_t *)oltr_intr; register_intr(ffs(is->id_irq) - 1, is->id_id, is->id_ri_flags, is->id_intr, &net_imask, is->id_unit); if ((is->id_drq == 0xffffffff) && (sc->config->dmalevel != TRLLD_DMA_PIO)) is->id_drq = sc->config->dmalevel; /* Claim our dma channel */ printf("oltr%d: <%s> [%6D]\n", is->id_unit, AdapterName[sc->config->type], sc->config->macaddress, ":"); sc->hw_state = HW_FOUND; return(1); } else { /* Assign based on iobase address provided in kernel config */ for (i = 0; i < NOLTR; i++) { if (is->id_iobase == oltr_config[i].iobase0) { if (assigned[i]) { printf("oltr%d: adapter (0x%X) already assigned.\n", is->id_unit, is->id_iobase); return(0); } assigned[i] = 1; sc->config = &oltr_config[i]; if (is->id_irq == 0) is->id_irq = (1 << sc->config->interruptlevel); /* Claim our interrupt */ is->id_intr = (inthand2_t *)oltr_intr; register_intr(ffs(is->id_irq) - 1, is->id_id, is->id_ri_flags, is->id_intr, &net_imask, is->id_unit); if ((is->id_drq == 0xffffffff) && (sc->config->dmalevel != TRLLD_DMA_PIO)) is->id_drq = sc->config->dmalevel; /* Claim our dma channel */ printf("oltr%d: <%s> [%6D]\n", is->id_unit, AdapterName[sc->config->type], sc->config->macaddress, ":"); sc->hw_state = HW_FOUND; return(1); } } } return(0); /* Card was not found */ } #if NPCI > 0 static const char * oltr_pci_probe(config_id, device_id) pcici_t config_id; pcidi_t device_id; { u_char PCIConfigurationSpace[64]; u_long command; int i, j, rc; j = NOLTR + pci_cards; if (pci_cards == EXTRA_OLTR) return(NULL); if (((device_id & 0xffff) == PCI_VENDOR_OLICOM) && ((((device_id >> 16) & 0xffff) == 0x0001) || (((device_id >> 16) & 0xffff) == 0x0004) || (((device_id >> 16) & 0xffff) == 0x0005) || (((device_id >> 16) & 0xffff) == 0x0007) || (((device_id >> 16) & 0xffff) == 0x0008))) { for (i = 0; i < 64; i++) PCIConfigurationSpace[i] = pci_cfgread(config_id, i, /*bytes*/1); rc = TRlldPCIConfig(&oltrLldDriver, &oltr_config[j], PCIConfigurationSpace); if ((rc == TRLLD_PCICONFIG_OK) || (rc == TRLLD_PCICONFIG_SET_COMMAND)) { if (rc == TRLLD_PCICONFIG_SET_COMMAND) { printf("oltr: setting bus-master mode\n"); command = pci_conf_read(config_id, PCIR_COMMAND); pci_conf_write(config_id, PCIR_COMMAND, (command | PCIM_CMD_BUSMASTEREN)); } pci_cards++; return (AdapterName[oltr_config[j].type]); } else { if (rc == TRLLD_PCICONFIG_FAIL) printf("oltr: TRlldPCIConfig failed!\n"); if (rc == TRLLD_PCICONFIG_VERSION) printf("oltr: wrong LLD version\n"); } } return(NULL); } #endif /* NPCI */ static int oltr_attach(is) struct isa_device *is; { struct oltr_softc *sc = &oltr_softc[is->id_unit]; int rc; sc->unit = is->id_unit; if (!oltr_attach_common(sc)) return(0); /* If the kernel config does not match the current card configuration then * adjust the card settings to match the kernel. */ if ((ffs(is->id_irq) - 1) != sc->config->interruptlevel) { rc = TRlldSetInterrupt(sc->TRlldAdapter, is->id_irq); if (rc != TRLLD_CONFIG_OK) { printf("oltr%d: Unable to change adapter interrupt level (%x)\n", sc->unit, rc); return(0); } } /* Set dma level, fall back to pio if possible. (following SCO driver example) */ if (is->id_drq != sc->config->dmalevel) { rc = TRlldSetDMA(sc->TRlldAdapter, is->id_drq, &sc->config->mode); if (rc != TRLLD_CONFIG_OK) { if ((sc->config->dmalevel != TRLLD_DMA_PIO) && (TRlldSetDMA(sc->TRlldAdapter, TRLLD_DMA_PIO, &sc->config->mode) != TRLLD_CONFIG_OK)) { printf("oltr%d: unable to change dma level from %d to %d (%x)\n", sc->unit, sc->config->dmalevel, is->id_drq, rc); } printf("oltr%d: Unable to change adapter dma level, using PIO mode (%x)\n", sc->unit, rc); sc->config->dmalevel = TRLLD_DMA_PIO; rc = TRlldSetDMA(sc->TRlldAdapter, is->id_drq, &sc->config->mode); } is->id_irq = sc->config->dmalevel; } return(1); } #if NPCI > 0 static void oltr_pci_attach(config_id, unit) pcici_t config_id; int unit; { struct oltr_softc *sc = &oltr_softc[unit]; sc->unit = unit; sc->config = &oltr_config[unit]; sc->hw_state = HW_FOUND; printf("oltr%d: mac address [%6D]\n", sc->unit, sc->config->macaddress, ":"); if (!oltr_attach_common(sc)) return; /* Map our interrupt */ if (!pci_map_int(config_id, oltr_pci_intr, sc, &net_imask)) { printf("oltr%d: couldn't map interrupt\n", unit); return; } } #endif /* NPCI */ static int oltr_attach_common(sc) struct oltr_softc *sc; { struct ifnet *ifp = &sc->arpcom.ac_if; u_int bufsize; int rc, i, j; /*printf("oltr%d: attach_common called\n", sc->unit);*/ /* Allocate adapter memory buffer */ bufsize = TRlldAdapterSize(); sc->TRlldAdapter = (TRlldAdapter_t *)oltr_malloc(bufsize, sc->config); if (sc->TRlldAdapter == NULL) { printf("oltr%d: Unable to allocate adapter memory block (%d bytes)\n", sc->unit, bufsize); } /*printf("oltr%d: Adapter memory block (%p %d bytes)\n", sc->unit, sc->TRlldAdapter, bufsize);*/ /* Setup transmit pool */ for (i = 0; i < TX_LIST_SIZE; i++) { sc->tx_buffer[i].index = i; sc->tx_buffer[i].buf = (char *)oltr_malloc(TX_BUFFER_LEN, sc->config); /* If we have a failure then free everything and get out */ if (!sc->tx_buffer[i].buf) { printf("oltr%d: Unable to allocate transmit buffers.\n", sc->unit); for (j = 0; j < i; j++) free(sc->tx_buffer[j].buf, M_DEVBUF); return(0); } } sc->tx_next = 0; sc->tx_avail = TX_LIST_SIZE; /* Setup receive pool */ for (i = 0; i < RX_LIST_SIZE; i++) { sc->rx_buffer[i].index = i; sc->rx_buffer[i].buf = (char *)oltr_malloc(RX_BUFFER_LEN, sc->config); /* If we have a failure then free everything and get out */ if (!sc->rx_buffer[i].buf) { printf("oltr%d: Unable to allocate receive buffers.\n", sc->unit); for (j = 0; j < i; j++) free(sc->rx_buffer[j].buf, M_DEVBUF); return(0); } } sc->rx_next = 0; sc->rx_avail = RX_LIST_SIZE; /*printf("oltr%d: Allocated receive buffers\n", sc->unit); */ /* Set up adapter polling mechanism */ sc->poll_adapter = 1; callout_handle_init(&sc->poll_ch); sc->poll_ch = timeout(adapter_poll, (void *)sc->unit, (1*hz)/1000); callout_handle_init(&sc->oltr_ch); /* Initialize adapter */ rc = TRlldAdapterInit(&oltrLldDriver, sc->TRlldAdapter, kvtop(sc->TRlldAdapter), (void *)sc->unit, sc->config); if (rc != TRLLD_INIT_OK) { switch (rc) { case TRLLD_INIT_NOT_FOUND: printf("oltr%d: Adapter not found or malfunctioning.\n", sc->unit); sc->hw_state = HW_BAD; return(0); case TRLLD_INIT_UNSUPPORTED: printf("oltr%d: Adapter not supported by low level driver.\n", sc->unit); sc->hw_state = HW_UNKNOWN; return(0); case TRLLD_INIT_PHYS16: printf("oltr%d: Adapter memory block above 16M, must be below 16M.\n", sc->unit); return(0); case TRLLD_INIT_VERSION: printf("oltr%d: Low level driver version mismatch.\n", sc->unit); return(0); default: printf("oltr%d: Unknown initilization error occoured (%x).\n", sc->unit, rc); return(0); } } /* Download Adapter Microcode */ /*printf("oltr%d: Downloading adapter microcode...", sc->unit);*/ sc->hw_state = HW_LOADING; switch(sc->config->mactype) { case TRLLD_MAC_TMS: /* TMS microcode */ rc = TRlldDownload(sc->TRlldAdapter, TRlldMacCode); break; case TRLLD_MAC_HAWKEYE: /* Hawkeye microcode */ rc = TRlldDownload(sc->TRlldAdapter, TRlldHawkeyeMac); break; case TRLLD_MAC_BULLSEYE: /* Bullseye microcode */ rc = TRlldDownload(sc->TRlldAdapter, TRlldBullseyeMac); break; default: printf("oltr%d: unknown mactype %d\n", sc->unit, sc->config->mactype); return(0); } /*if (rc == TRLLD_DOWNLOAD_OK) printf("done\n");*/ if ((rc == TRLLD_DOWNLOAD_ERROR) || (rc == TRLLD_STATE)) { printf("oltr%d: Adapter microcode download failed! (rc = %x)\n", sc->unit, rc); sc->hw_state = HW_BAD; return(0); } TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_AUTO); sc->PromiscMode = 0; sc->AdapterMode = 0; /* Do the ifnet initialization */ ifp->if_softc = sc; ifp->if_unit = sc->unit; ifp->if_name = "oltr"; ifp->if_output = iso88025_output; ifp->if_init = (if_init_f_t *)oltr_init; ifp->if_start = oltr_start; ifp->if_ioctl = oltr_ioctl; ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX; bcopy(sc->config->macaddress, sc->arpcom.ac_enaddr, sizeof(sc->config->macaddress)); /* Set up common ifmedia options */ ifmedia_init(&sc->ifmedia, 0, oltr_ifmedia_upd, oltr_ifmedia_sts); ifmedia_add(&sc->ifmedia, IFM_TOKEN | IFM_AUTO, 0 , NULL); ifmedia_add(&sc->ifmedia, IFM_TOKEN | IFM_TOK_UTP4, 0 , NULL); ifmedia_add(&sc->ifmedia, IFM_TOKEN | IFM_TOK_UTP16, 0 , NULL); ifmedia_set(&sc->ifmedia, IFM_TOKEN | IFM_AUTO); if_attach(ifp); iso88025_ifattach(ifp); #if NBPFILTER > 0 bpfattach(ifp, DLT_IEEE802, sizeof(struct iso88025_header)); #endif return(1); } #if NPCI > 0 static void oltr_pci_shutdown(howto, sc) int howto; void *sc; { printf("oltr: oltr_pci_shutdown called\n"); } #endif /* NPCI */ static int oltr_ifmedia_upd(ifp) struct ifnet *ifp; { struct oltr_softc *sc = ifp->if_softc; struct ifmedia *ifm = &sc->ifmedia; if (IFM_TYPE(ifm->ifm_media) != IFM_TOKEN) return(EINVAL); switch(IFM_SUBTYPE(ifm->ifm_media)) { case IFM_AUTO: TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_AUTO); break; case IFM_TOK_UTP4: TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_4MBPS); break; case IFM_TOK_UTP16: TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS); default: return(EINVAL); } if (IFM_TYPE_OPTIONS(ifm->ifm_media) & IFM_TOK_ETR) printf("oltr%d: ETR not implemented\n", sc->unit); if (IFM_TYPE_OPTIONS(ifm->ifm_media) & IFM_TOK_SRCRT) printf("oltr%d: source-routing not implemented\n", sc->unit); if (IFM_TYPE_OPTIONS(ifm->ifm_media) & IFM_TOK_ALLR) printf("oltr%d: all source routes not implemented\n", sc->unit); if (IFM_TYPE_OPTIONS(ifm->ifm_media) & IFM_TOK_DTR) { sc->AdapterMode |= TRLLD_MODE_FORCE_TXI; sc->AdapterMode &= ~TRLLD_MODE_FORCE_TKP; } if (IFM_TYPE_OPTIONS(ifm->ifm_media) & IFM_TOK_CLASSIC) { sc->AdapterMode |= TRLLD_MODE_FORCE_TKP; sc->AdapterMode &= ~TRLLD_MODE_FORCE_TXI; } if (IFM_TYPE_OPTIONS(ifm->ifm_media) & IFM_TOK_AUTO) sc->AdapterMode &= ~(TRLLD_MODE_FORCE_TXI | TRLLD_MODE_FORCE_TKP); if (IFM_TYPE_OPTIONS(ifm->ifm_media) & ~ALL_OPTIONS) return(EINVAL); return(0); } static void oltr_ifmedia_sts(ifp, ifmr) struct ifnet *ifp; struct ifmediareq *ifmr; { struct oltr_softc *sc = ifp->if_softc; struct ifmedia *ifm = &sc->ifmedia; ifmr->ifm_active = IFM_TYPE(ifm->ifm_media)|IFM_SUBTYPE(ifm->ifm_media)|IFM_TYPE_OPTIONS(ifm->ifm_media); return; } void oltr_timeout(token) void *token; { struct oltr_softc *sc = &oltr_softc[(int)token]; int unit = (int)token, s; s = splimp(); printf("oltr%d: adapter timed out (%x)\n", unit, sc->hw_state); splx(s); } void adapter_poll(token) void *token; { int unit = (int)token, poll_timeout = 0, s; struct oltr_softc *sc = &oltr_softc[unit]; #if 0 static int rx_buffers = 0, tx_buffers = 0, rc; #endif s = splimp(); /* Check to make sure we are not polling a dead card */ if ((sc->hw_state == HW_BAD) || (sc->hw_state == HW_UNKNOWN)) { sc->poll_adapter = -1; splx(s); return; } /*printf("oltr%d: adapter poll.\n", unit);*/ /* If the adapter is to be polled again, then set up * next timeout poll */ if (sc->poll_adapter) { poll_timeout = TRlldPoll(sc->TRlldAdapter); sc->poll_ch = timeout(adapter_poll, (void *)unit, (poll_timeout * hz)/1000); } #if 0 rc = TRlldReceiveFree(sc->TRlldAdapter); if (rx_buffers != rc) { printf("oltr%d: %d receive buffers available\n", sc->unit, rc); rx_buffers = rc; } rc = TRlldTransmitFree(sc->TRlldAdapter); if (tx_buffers != rc) { printf("oltr%d: %d transmit buffers available\n", sc->unit, rc); tx_buffers = rc; } #endif splx(s); } static void oltr_init(sc) struct oltr_softc *sc; { struct ifnet *ifp = &sc->arpcom.ac_if; int i, rc; /*printf("oltr%d: oltr_init\n", sc->unit);*/ /* * Adapter should be freshly downloaded or previously closed before * bringing it back on line. */ if ((sc->hw_state != HW_CLOSED) && (sc->hw_state != HW_LOADING)) { printf("oltr%d: adapter not ready to be opened (%d).\n", sc->unit, sc->hw_state); return; } /* Allocate and set up the DMA channel */ if (sc->config->dmalevel != TRLLD_DMA_PIO) { rc = isa_dma_acquire(sc->config->dmalevel); isa_dmacascade(sc->config->dmalevel); } /* Open the adapter */ sc->hw_state = HW_OPENING; rc = TRlldOpen(sc->TRlldAdapter, sc->arpcom.ac_enaddr, sc->GroupAddress, sc->FunctionalAddress, ifp->if_mtu, sc->AdapterMode); if (rc != TRLLD_OPEN_OK) { printf("oltr%d: Adapter failed to open (rc = %x)\n", sc->unit, rc); sc->hw_state = HW_FAILED; } else { /*printf("oltr%d: adapter opening...\n", sc->unit);*/ /*ifp->if_flags |= (IFF_UP | IFF_RUNNING);*/ ifp->if_flags &= ~IFF_OACTIVE; } sc->oltr_ch = timeout(oltr_timeout, (void *)sc->unit, 30*hz); tsleep((void *)sc->unit, 1, "oltrop", 30*hz); /* Give the transmit buffers to the adapter */ for (i = 0; i < RX_LIST_SIZE; i++) { rc = TRlldReceiveFragment(sc->TRlldAdapter, (void *)sc->rx_buffer[sc->rx_next & RX_LIST_MASK].buf, kvtop(sc->rx_buffer[sc->rx_next & RX_LIST_MASK].buf), RX_BUFFER_LEN, (void *)sc->rx_buffer[sc->rx_next & RX_LIST_MASK].index); if (rc != TRLLD_RECEIVE_OK) { printf("oltr%d: Adapter refused fragment %d (rc = %d).\n", sc->unit, i, rc); break; } else { sc->rx_avail--; } sc->rx_next++; } return; } static void oltr_intr(unit) int unit; { struct oltr_softc *sc = &oltr_softc[unit]; int rc; /*printf("oltr%d: oltr_intr\n", unit);*/ /* Too noisy */ rc= TRlldInterruptService(sc->TRlldAdapter); if (rc == TRLLD_NO_INTERRUPT) printf("oltr%d: interrupt not serviced.\n", unit); } #if NPCI > 0 static void oltr_pci_intr(psc) void *psc; { struct oltr_softc *sc = (struct oltr_softc *)psc; int rc = 0; /*printf("oltr%d: oltr_pci_intr\n", sc->unit);*/ /* Too noisy */ rc = TRlldInterruptService(sc->TRlldAdapter); if (rc == TRLLD_NO_INTERRUPT) printf("oltr%d: pci interrupt not serviced.\n", sc->unit); } #endif /* NPCI */ static void oltr_start(ifp) struct ifnet *ifp; { struct oltr_softc *sc = &oltr_softc[ifp->if_unit]; struct mbuf *m0, *m; struct iso88025_header *th; TRlldTransmit_t frame; int len, i, rc; /*printf("oltr%d: oltr_start\n", sc->unit);*/ outloop: /* Check to see if we have enough room to transmit */ if (sc->tx_avail <= 0) { /* No free buffers, hold off the upper layers */ /*printf("oltr%d: transmit queue full.\n", sc->unit);*/ ifp->if_flags |= IFF_OACTIVE; return; } IF_DEQUEUE(&ifp->if_snd, m); if (m == 0) { /*printf("oltr%d: oltr_start NULL packet dequeued.\n", sc->unit);*/ ifp->if_flags &= ~IFF_OACTIVE; return; } th = mtod(m, struct iso88025_header *); th->ac = 0x10; th->fc = 0x40; /* Keep a pointer to the head of the packet */ m0 = m; i = (sc->tx_next & TX_LIST_MASK); /* Just to shorten thing up */ for (len = 0; m != 0; m = m->m_next) { frame.TransmitFragment[0].VirtualAddress = sc->tx_buffer[i].buf; frame.TransmitFragment[0].PhysicalAddress = kvtop(sc->tx_buffer[i].buf); bcopy(mtod(m, caddr_t), sc->tx_buffer[i].buf + len, m->m_len); len += m->m_len; } frame.FragmentCount = 1; frame.TransmitFragment[0].count = len; rc = TRlldTransmitFrame(sc->TRlldAdapter, &frame, (void *)sc->tx_buffer[i].index); if (rc != TRLLD_TRANSMIT_OK) { printf("oltr%d: TRlldTransmitFrame returned (%x)\n", sc->unit, rc); ifp->if_oerrors++; goto bad; } sc->tx_next++; sc->tx_avail--; #if NBPFILTER > 0 if (ifp->if_bpf) bpf_mtap(ifp, m0); #endif bad: m_freem(m0); goto outloop; return; } static void oltr_stop(sc) struct oltr_softc *sc; { struct ifnet *ifp = &sc->arpcom.ac_if; /*printf("oltr%d: otlr_stop\n", sc->unit);*/ ifp->if_flags &= ~(IFF_UP | IFF_RUNNING | IFF_OACTIVE); sc->hw_state = HW_CLOSING; TRlldClose(sc->TRlldAdapter, 0); sc->oltr_ch = timeout(oltr_timeout, (void *)sc->unit, 30*hz); tsleep((void *)sc->unit, 1, "oltrcl", 30*hz); } static int oltr_ioctl(ifp, cmd, data) struct ifnet *ifp; u_long cmd; caddr_t data; { struct oltr_softc *sc = &oltr_softc[ifp->if_unit]; struct ifreq *ifr = (struct ifreq *)data; int error = 0, s; /*printf("oltr%d: oltr_ioctl\n", ifp->if_unit);*/ s = splimp(); switch (cmd) { case SIOCSIFADDR: case SIOCGIFADDR: case SIOCSIFMTU: error = iso88025_ioctl(ifp, cmd, data); break; case SIOCSIFFLAGS: /* * If the interface is marked up and stopped, then start it. * If it is marked down and running, then stop it. */ if (ifp->if_flags & IFF_UP) { if ((ifp->if_flags & IFF_RUNNING) == 0) oltr_init(sc); } else { if (ifp->if_flags & IFF_RUNNING) { oltr_stop(sc); ifp->if_flags &= ~IFF_RUNNING; } } break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd); break; default: error = EINVAL; } splx(s); return(error); } /* * PMW Callback functions ---------------------------------------------------- */ static void DriverSuspend(MicroSeconds) unsigned short MicroSeconds; { DELAY(MicroSeconds); } static void DriverStatus(DriverHandle, Status) void *DriverHandle; TRlldStatus_t *Status; { struct oltr_softc *sc = &oltr_softc[(int)DriverHandle]; struct ifnet *ifp = &sc->arpcom.ac_if; switch (Status->Type) { case TRLLD_STS_ON_WIRE: if (sc->hw_state == HW_OPENING) { sc->hw_state = HW_OPEN; ifp->if_flags |= (IFF_UP | IFF_RUNNING); /*printf("oltr%d: Adapter inserted.\n", sc->unit);*/ untimeout(oltr_timeout, (void *)sc->unit, sc->oltr_ch); wakeup_one((void *)sc->unit); } break; case TRLLD_STS_SELFTEST_STATUS: if (Status->Specification.SelftestStatus == TRLLD_ST_OK) { printf("oltr%d: adapter status good. (close completed/self-test)\n", sc->unit); if ((sc->hw_state == HW_LOADING) || (sc->hw_state == HW_CLOSING) || (sc->hw_state == HW_CLOSING2)) { sc->hw_state = HW_CLOSED; break; } } else { printf("oltr%d: Self test failed: ", sc->unit); switch (Status->Specification.SelftestStatus) { case TRLLD_ST_ERROR + 0: printf("Initial Test Error\n"); break; case TRLLD_ST_ERROR + 1: printf("Adapter Software Checksum Error\n"); break; case TRLLD_ST_ERROR + 2: printf("Adapter RAM Error\n"); break; case TRLLD_ST_ERROR + 4: printf("Instruction Test Error\n"); break; case TRLLD_ST_ERROR + 5: printf("Protocol Handler/RI Hw Error\n"); break; case TRLLD_ST_ERROR + 6: printf("System Interface Register Error\n"); break; case TRLLD_ST_TIMEOUT: printf("Selftest did not complete\n"); break; default: printf("Unknown error (%x)\n", Status->Specification.SelftestStatus); } } break; case TRLLD_STS_INIT_STATUS: printf("oltr%d: Adapter initialization failed: ", sc->unit); switch(Status->Specification.InitStatus) { case TRLLD_INIT_ERROR + 0x01: printf("Invalid init block (LLD error)\n"); break; case TRLLD_INIT_ERROR + 0x02: printf("Invalid options (LLD error)\n"); break; case TRLLD_INIT_ERROR + 0x03: printf("Invalid rcv burst (LLD error)\n"); break; case TRLLD_INIT_ERROR + 0x04: printf("Invalid xmt burst (LLD error)\n"); break; case TRLLD_INIT_ERROR + 0x05: printf("Invalid DMA threshold (LLD error)\n"); break; case TRLLD_INIT_ERROR + 0x06: printf("Invalid scb addr\n"); break; case TRLLD_INIT_ERROR + 0x07: printf("Invalid ssb addr\n"); break; case TRLLD_INIT_ERROR + 0x08: printf("DIO parity error (HW error)\n"); break; case TRLLD_INIT_ERROR + 0x09: printf("DMA timeout (May be interrupt failing if PIO mode or PCI2)\n"); break; case TRLLD_INIT_ERROR + 0x0A: printf("DMA parity error (HW error)\n"); break; case TRLLD_INIT_ERROR + 0x0B: printf("DMA bus error (HW error)\n"); break; case TRLLD_INIT_ERROR + 0x0C: printf("DMA data error\n"); break; case TRLLD_INIT_ERROR + 0x0D: printf("Adapter Check\n"); break; case TRLLD_INIT_TIMEOUT: printf("Adapter initialization did not complete\n"); break; case TRLLD_INIT_DMA_ERROR: printf("Adapter cannot access system memory\n"); break; case TRLLD_INIT_INTR_ERROR: printf("Adapter cannot interrupt\n"); break; case TRLLD_OPEN_TIMEOUT: printf("Adapter did not complete open within 30 seconds\n"); break; case TRLLD_OPEN_ERROR + 0x01: printf("Invalid open options (LLD error)\n"); break; case TRLLD_OPEN_ERROR + 0x04: printf("TxBuffer count error (LLD error)\n"); break; case TRLLD_OPEN_ERROR + 0x10: printf("Buffer size error (LLD error)\n"); break; case TRLLD_OPEN_ERROR + 0x20: printf("List size error (LLD error)\n"); break; default: if (Status->Specification.InitStatus & 0x700) { switch (Status->Specification.InitStatus & 0x70F) { case TRLLD_OPEN_REPEAT + 0x01: printf("Lobe media test - "); break; case TRLLD_OPEN_REPEAT + 0x02: printf("Physical insertion - "); break; case TRLLD_OPEN_REPEAT + 0x03: printf("Address verification - "); break; case TRLLD_OPEN_REPEAT + 0x04: printf("Participation in ring poll - "); break; case TRLLD_OPEN_REPEAT + 0x05: printf("Request initialization - "); break; case TRLLD_OPEN_REPEAT + 0x09: printf("Request registration (TXI) - "); break; case TRLLD_OPEN_REPEAT + 0x0A: printf("Lobe media test (TXI) - "); break; default: printf("Unknown phase (%x) - ", Status->Specification.InitStatus & 0x00F); } switch (Status->Specification.InitStatus & 0x7F0) { case TRLLD_OPEN_REPEAT + 0x10: printf("Function failure (No cable?)\n"); break; case TRLLD_OPEN_REPEAT + 0x20: printf("Signal loss\n"); break; case TRLLD_OPEN_REPEAT + 0x50: printf("Timeout\n"); break; case TRLLD_OPEN_REPEAT + 0x60: printf("Ring failure (TKP) / Protocol error (TXI)\n"); break; case TRLLD_OPEN_REPEAT + 0x70: printf("Ring beaconing\n"); break; case TRLLD_OPEN_REPEAT + 0x80: printf("Duplicate node address (TKP) / Insert denied (TXI)\n"); break; case TRLLD_OPEN_REPEAT + 0x90: printf("Request initialization (TKP)\n"); break; case TRLLD_OPEN_REPEAT + 0xa0: printf("Remove received\n"); break; case TRLLD_OPEN_REPEAT + 0xb0: printf("C-port address changed (TXI)\n"); break; default: printf("Unknown type (%x)\n", Status->Specification.InitStatus & 0x0F0); } } else { printf("Unknown error (%x)\n", Status->Specification.InitStatus); } } break; case TRLLD_STS_RING_STATUS: if (Status->Specification.RingStatus != 0) { printf("oltr%d: Ring status change: ", sc->unit); if (Status->Specification.RingStatus & TRLLD_RS_HARD_ERROR) printf("[Hard error] "); if (Status->Specification.RingStatus & TRLLD_RS_SOFT_ERROR) printf("[Soft error] "); if (Status->Specification.RingStatus & TRLLD_RS_TRANSMIT_BEACON) printf("[Transmit beacon] "); if (Status->Specification.RingStatus & TRLLD_RS_LOBE_WIRE_FAULT) printf("[Wire fault] "); if (Status->Specification.RingStatus & TRLLD_RS_AUTO_REMOVAL_ERROR) printf("[Auto removal] "); if (Status->Specification.RingStatus & TRLLD_RS_REMOVE_RECEIVED) printf("[Remove received] "); if (Status->Specification.RingStatus & TRLLD_RS_COUNTER_OVERFLOW) printf("[Counter overflow] "); if (Status->Specification.RingStatus & TRLLD_RS_SINGLE_STATION) printf("[Single station] "); if (Status->Specification.RingStatus & TRLLD_RS_RING_RECOVERY) printf("[Ring recovery] "); printf("\n"); } break; case TRLLD_STS_ADAPTER_CHECK: printf("oltr%d: Adapter check (%x %x %x %x)\n", sc->unit, Status->Specification.AdapterCheck[0], Status->Specification.AdapterCheck[1], Status->Specification.AdapterCheck[2], Status->Specification.AdapterCheck[3]); break; case TRLLD_STS_PROMISCUOUS_STOPPED: printf("oltr%d: Promiscuous mode stopped: ", sc->unit); switch(Status->Specification.PromRemovedCause) { case TRLLD_PROM_REMOVE_RECEIVED: printf("Remove received\n"); break; case TRLLD_PROM_POLL_FAILURE: printf("Poll failure\n"); break; default: printf("Unknown (%x)\n", Status->Specification.PromRemovedCause); } break; case TRLLD_STS_LLD_ERROR: printf("oltr%d: LLD error (%x %x %x %x) ", sc->unit, Status->Specification.InternalError[0], Status->Specification.InternalError[1], Status->Specification.InternalError[2], Status->Specification.InternalError[3]); break; case TRLLD_STS_ADAPTER_TIMEOUT: printf("oltr%d: Adapter operation timed out: ", sc->unit); switch(Status->Specification.AdapterTimeout) { case TRLLD_COMMAND_TIMEOUT: printf("Command\n"); case TRLLD_TRANSMIT_TIMEOUT: printf("Transmit\n"); case TRLLD_INTERRUPT_TIMEOUT: printf("Interrupt\n"); default: printf("Unknown (%x)\n", Status->Specification.AdapterTimeout); } break; default: printf("oltr%d: Unknown status type (%x)\n", sc->unit, Status->Type); } if (Status->Closed) { if (sc->hw_state > HW_BAD) { sc->hw_state = HW_FAILED; printf("oltr%d: closing adapter due to failure.\n", sc->unit); oltr_stop(sc); } } } static void DriverCloseCompleted(DriverHandle) void *DriverHandle; { struct oltr_softc *sc = &oltr_softc[(int)DriverHandle]; /*printf("oltr%d: DriverCloseCompleted\n", sc->unit);*/ untimeout(oltr_timeout, (void *)sc->unit, sc->oltr_ch); wakeup_one((void *)sc->unit); if ((sc->hw_state != HW_CLOSING) && (sc->hw_state != HW_CLOSING2) && (sc->hw_state != HW_CLOSED)) { printf("oltr%d: adapter close complete called in wrong state (%d)\n", sc->unit, sc->hw_state); return; } sc->hw_state = HW_CLOSING2; if (sc->config->dmalevel != TRLLD_DMA_PIO) isa_dma_release(sc->config->dmalevel); } static void DriverStatistics(DriverHandle, Statistics) void *DriverHandle; TRlldStatistics_t *Statistics; { printf("oltr: DriverStatistics\n"); } static void DriverTransmitFrameCompleted(DriverHandle, FrameHandle, TransmitStatus) void *DriverHandle; void *FrameHandle; int TransmitStatus; { int frame = (int)FrameHandle; struct oltr_softc *sc = &oltr_softc[(int)DriverHandle]; struct ifnet *ifp = &sc->arpcom.ac_if; if (ifp->if_flags & IFF_OACTIVE) ifp->if_flags &= ~(IFF_OACTIVE); /*printf("oltr%d: transmit complete frame %d\n", sc->unit, frame);*/ if (TransmitStatus == TRLLD_TRANSMIT_OK) { ifp->if_opackets++; } else { printf("oltr%d: DriverTransmitFrameCompleted (Frame %d status %x)\n", sc->unit, frame, TransmitStatus); ifp->if_oerrors++; } if ((frame < 0) || (frame > TX_LIST_SIZE)) { printf("oltr%d: bogus transmit buffer. (%d)\n", sc->unit, frame); return; } sc->tx_avail++; } static void DriverReceiveFrameCompleted(DriverHandle, ByteCount, FragmentCount, FragmentHandle, ReceiveStatus) void *DriverHandle; int ByteCount; int FragmentCount; void *FragmentHandle; int ReceiveStatus; { struct oltr_softc *sc = &oltr_softc[(int)DriverHandle]; struct ifnet *ifp = &sc->arpcom.ac_if; struct iso88025_header *th; struct mbuf *m; int i, j = (int)FragmentHandle, rc, frame_len = ByteCount, mac_hdr_len; char *frag = sc->rx_buffer[j].buf; if (sc->hw_state >= HW_OPEN) { /* Hardware operating normally */ if (frag != sc->rx_buffer[sc->rx_next & RX_LIST_MASK].buf) { printf("oltr%d: ring buffer pointer blown\n", sc->unit); oltr_stop(sc); return; } if (ReceiveStatus == TRLLD_RCV_OK) { /* Receive good frame */ MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) { ifp->if_ierrors++; goto out; } if (frame_len + 2 > MHLEN) { MCLGET(m, M_DONTWAIT); if ((m->m_flags & M_EXT) == 0) { printf("oltr%d: unable to get mbuf cluster during receive.\n", sc->unit); m_freem(m); ifp->if_ierrors++; goto out; } } ifp->if_ipackets++; m->m_pkthdr.rcvif = &sc->arpcom.ac_if; m->m_pkthdr.len = m->m_len = frame_len; m->m_data += 2; th = mtod(m, struct iso88025_header *); i = 0; while (frame_len > RX_BUFFER_LEN) { bcopy(frag, mtod(m, char *) + i, RX_BUFFER_LEN); i += RX_BUFFER_LEN; frame_len -= RX_BUFFER_LEN; frag = sc->rx_buffer[++j].buf; } bcopy(frag, mtod(m, char *) + i, frame_len); #if NBPFILTER > 0 if (ifp->if_bpf) bpf_mtap(ifp, m); #endif mac_hdr_len = ISO88025_HDR_LEN; if (th->iso88025_shost[0] & 0x80) /* Check for source routing info */ mac_hdr_len += (ntohs(th->rcf) & 0x1f00) >> 8; m->m_pkthdr.len = m->m_len = ByteCount - mac_hdr_len; m->m_data += mac_hdr_len; iso88025_input(&sc->arpcom.ac_if, th, m); } else { if (ReceiveStatus != TRLLD_RCV_NO_DATA) { printf("oltr%d: receive error. (ReceiveStatus=%d)\n", sc->unit, ReceiveStatus); ifp->if_ierrors++; } } out: while (FragmentCount > 0) { rc = TRlldReceiveFragment(sc->TRlldAdapter, (void *)sc->rx_buffer[sc->rx_next & RX_LIST_MASK].buf, kvtop(sc->rx_buffer[sc->rx_next & RX_LIST_MASK].buf), RX_BUFFER_LEN, (void *)sc->rx_buffer[sc->rx_next & RX_LIST_MASK].index); if (rc == TRLLD_RECEIVE_OK) { sc->rx_next++; FragmentCount--; } else { printf("oltr%d: Adapter refused fragment (%d).\n", sc->unit, sc->rx_next - 1); sc->rx_avail += FragmentCount; break; } } } else { /* Hardware being closed */ if (frag != sc->rx_buffer[sc->rx_next++ & RX_LIST_MASK].buf) { printf("oltr%d: ring buffer pointer blown\n", sc->unit); } sc->rx_avail += FragmentCount; } } /* * ---------------------------- PMW Glue ------------------------------- */ #ifndef TRlldInlineIO static void DriverOutByte(IOAddress, value) unsigned short IOAddress; unsigned char value; { outb(IOAddress, value); } static void DriverOutWord(IOAddress, value) unsigned short IOAddress; unsigned short value; { outw(IOAddress, value); } static void DriverOutDword(IOAddress, value) unsigned short IOAddress; unsigned long value; { outl(IOAddress, value); } static void DriverRepOutByte(IOAddress, DataPointer, ByteCount) unsigned short IOAddress; unsigned char *DataPointer; int ByteCount; { outsb(IOAddress, (void *)DataPointer, ByteCount); } static void DriverRepOutWord(IOAddress, DataPointer, WordCount) unsigned short IOAddress; unsigned short *DataPointer; int WordCount; { outsw(IOAddress, (void *)DataPointer, WordCount); } static void DriverRepOutDword(IOAddress, DataPointer, DWordCount) unsigned short IOAddress; unsigned long *DataPointer; int DWordCount; { outsl(IOAddress, (void *)DataPointer, DWordCount); } static unsigned char DriverInByte(IOAddress) unsigned short IOAddress; { return(inb(IOAddress)); } static unsigned short DriverInWord(IOAddress) unsigned short IOAddress; { return(inw(IOAddress)); } static unsigned long DriverInDword(IOAddress) unsigned short IOAddress; { return(inl(IOAddress)); } static void DriverRepInByte(IOAddress, DataPointer, ByteCount) unsigned short IOAddress; unsigned char *DataPointer; int ByteCount; { insb(IOAddress, (void *)DataPointer, ByteCount); } static void DriverRepInWord(IOAddress, DataPointer, WordCount) unsigned short IOAddress; unsigned short *DataPointer; int WordCount; { insw(IOAddress, (void *)DataPointer, WordCount); } static void DriverRepInDword(IOAddress, DataPointer, DWordCount) unsigned short IOAddress; unsigned long *DataPointer; int DWordCount; { insl(IOAddress, (void *)DataPointer, DWordCount); } #endif /* TRlldInlineIO */ #endif /* NOLTR */ [-- Attachment #3 --] *** if_media.h.orig Fri Dec 11 10:55:32 1998 --- if_media.h Fri Dec 11 17:14:03 1998 *************** *** 137,145 **** --- 137,150 ---- #define IFM_TOK_STP16 4 /* Shielded twisted pair 16m - DB9 */ #define IFM_TOK_UTP4 5 /* Unshielded twisted pair 4m - RJ45 */ #define IFM_TOK_UTP16 6 /* Unshielded twisted pair 16m - RJ45 */ + #define IFM_TOK_STP100 7 /* Shielded twisted pair 100m - DB9 */ + #define IFM_TOK_UTP100 8 /* Unshielded twisted pair 100m - RJ45 */ #define IFM_TOK_ETR 0x00000200 /* Early token release */ #define IFM_TOK_SRCRT 0x00000400 /* Enable source routing features */ #define IFM_TOK_ALLR 0x00000800 /* All routes / Single route bcast */ + #define IFM_TOK_DTR 0x00002000 /* Dedicated token ring */ + #define IFM_TOK_CLASSIC 0x00004000 /* Classic token ring */ + #define IFM_TOK_AUTO 0x00008000 /* Automatic Dedicate/Classic token ring */ /* * FDDI *************** *** 186,194 **** /* * Macros to extract various bits of information from the media word. */ ! #define IFM_TYPE(x) ((x) & IFM_NMASK) ! #define IFM_SUBTYPE(x) ((x) & IFM_TMASK) ! #define IFM_INST(x) (((x) & IFM_IMASK) >> IFM_ISHIFT) /* * NetBSD extension not defined in the BSDI API. This is used in various --- 191,200 ---- /* * Macros to extract various bits of information from the media word. */ ! #define IFM_TYPE(x) ((x) & IFM_NMASK) ! #define IFM_SUBTYPE(x) ((x) & IFM_TMASK) ! #define IFM_TYPE_OPTIONS(x) ((x) & IFM_OMASK) ! #define IFM_INST(x) (((x) & IFM_IMASK) >> IFM_ISHIFT) /* * NetBSD extension not defined in the BSDI API. This is used in various *************** *** 245,250 **** --- 251,258 ---- { IFM_TOK_STP16, "DB9/16Mbit" }, \ { IFM_TOK_UTP4, "UTP/4Mbit" }, \ { IFM_TOK_UTP16, "UTP/16Mbit" }, \ + { IFM_TOK_STP100, "STP/100Mbit" }, \ + { IFM_TOK_UTP100, "UTP/100Mbit" }, \ { 0, NULL }, \ } *************** *** 253,258 **** --- 261,268 ---- { IFM_TOK_STP16, "16STP" }, \ { IFM_TOK_UTP4, "4UTP" }, \ { IFM_TOK_UTP16, "16UTP" }, \ + { IFM_TOK_STP100, "100STP" }, \ + { IFM_TOK_UTP100, "100UTP" }, \ { 0, NULL }, \ } *************** *** 260,265 **** --- 270,278 ---- { IFM_TOK_ETR, "EarlyTokenRelease" }, \ { IFM_TOK_SRCRT, "SourceRouting" }, \ { IFM_TOK_ALLR, "AllRoutes" }, \ + { IFM_TOK_DTR, "Dedicated" }, \ + { IFM_TOK_CLASSIC,"Classic" }, \ + { IFM_TOK_AUTO, " " }, \ { 0, NULL }, \ }help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.05.9812311032240.5164-300000>
