diff options
author | paul <paul@FreeBSD.org> | 2000-12-16 01:33:28 +0000 |
---|---|---|
committer | paul <paul@FreeBSD.org> | 2000-12-16 01:33:28 +0000 |
commit | 00fcc3d35ac764fd8deb0e9698adee70e7c6fb1a (patch) | |
tree | 5ab459146d5f60f89822fc6bbc21d103480060b9 | |
parent | 55b774ba6e1a3e1f4755f6ddd840757227d2d7d0 (diff) | |
download | FreeBSD-src-00fcc3d35ac764fd8deb0e9698adee70e7c6fb1a.zip FreeBSD-src-00fcc3d35ac764fd8deb0e9698adee70e7c6fb1a.tar.gz |
Newbusify.
Temporarily disable PC98 until I bring it up to date.
-rw-r--r-- | sys/dev/lnc/if_lnc.c | 262 | ||||
-rw-r--r-- | sys/dev/lnc/if_lnc_isa.c | 471 | ||||
-rw-r--r-- | sys/dev/lnc/if_lnc_pc98.c | 34 | ||||
-rw-r--r-- | sys/dev/lnc/if_lnc_pci.c | 284 | ||||
-rw-r--r-- | sys/dev/lnc/if_lncreg.h | 28 | ||||
-rw-r--r-- | sys/dev/lnc/if_lncvar.h | 92 |
6 files changed, 627 insertions, 544 deletions
diff --git a/sys/dev/lnc/if_lnc.c b/sys/dev/lnc/if_lnc.c index 1d77356..03f12be 100644 --- a/sys/dev/lnc/if_lnc.c +++ b/sys/dev/lnc/if_lnc.c @@ -30,15 +30,12 @@ * $FreeBSD$ */ -/* #define DIAGNOSTIC #define DEBUG +/* * * TODO ---- * - * This driver will need bounce buffer support when dma'ing to mbufs above the - * 16Mb mark. - * * Check all the XXX comments -- some of them are just things I've left * unfinished rather than "difficult" problems that were hacked around. * @@ -65,13 +62,18 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/bus.h> #include <sys/kernel.h> -#include <sys/sockio.h> #include <sys/malloc.h> #include <sys/mbuf.h> +#include <sys/module.h> #include <sys/socket.h> +#include <sys/sockio.h> #include <sys/syslog.h> -#include <sys/bus.h> + +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/rman.h> #include <net/ethernet.h> #include <net/if.h> @@ -85,14 +87,9 @@ #include <machine/md_var.h> -#include <i386/isa/isa_device.h> #include <dev/lnc/if_lncvar.h> #include <dev/lnc/if_lncreg.h> -#ifndef COMPAT_OLDISA -#error "The lnc device requires the old isa compatibility shims" -#endif - static char const * const nic_ident[] = { "Unknown", "BICC", @@ -116,23 +113,20 @@ static char const * const ic_ident[] = { "PCnet-Home", }; -static void lnc_setladrf __P((lnc_softc_t *sc)); -static void lnc_stop __P((lnc_softc_t *sc)); -static void lnc_reset __P((lnc_softc_t *sc)); -static void lnc_free_mbufs __P((lnc_softc_t *sc)); -static __inline int alloc_mbuf_cluster __P((lnc_softc_t *sc, +static void lnc_setladrf __P((struct lnc_softc *sc)); +static void lnc_reset __P((struct lnc_softc *sc)); +static void lnc_free_mbufs __P((struct lnc_softc *sc)); +static __inline int alloc_mbuf_cluster __P((struct lnc_softc *sc, struct host_ring_entry *desc)); -static __inline struct mbuf *chain_mbufs __P((lnc_softc_t *sc, +static __inline struct mbuf *chain_mbufs __P((struct lnc_softc *sc, int start_of_packet, int pkt_len)); -static __inline struct mbuf *mbuf_packet __P((lnc_softc_t *sc, +static __inline struct mbuf *mbuf_packet __P((struct lnc_softc *sc, int start_of_packet, int pkt_len)); -static __inline void lnc_rint __P((lnc_softc_t *sc)); -static __inline void lnc_tint __P((lnc_softc_t *sc)); -extern int lnc_probe __P((struct isa_device *isa_dev)); -int lnc_attach_sc __P((lnc_softc_t *sc, int unit)); -extern int lnc_attach __P((struct isa_device *isa_dev)); +static __inline void lnc_rint __P((struct lnc_softc *sc)); +static __inline void lnc_tint __P((struct lnc_softc *sc)); + static void lnc_init __P((void *)); static __inline int mbuf_to_buffer __P((struct mbuf *m, char *buffer)); static __inline struct mbuf *chain_to_cluster __P((struct mbuf *m)); @@ -140,29 +134,40 @@ static void lnc_start __P((struct ifnet *ifp)); static int lnc_ioctl __P((struct ifnet *ifp, u_long command, caddr_t data)); static void lnc_watchdog __P((struct ifnet *ifp)); #ifdef DEBUG -void lnc_dump_state __P((lnc_softc_t *sc)); +void lnc_dump_state __P((struct lnc_softc *sc)); void mbuf_dump_chain __P((struct mbuf *m)); #endif -void lncintr_sc __P((lnc_softc_t *sc)); +void write_csr(struct lnc_softc *, u_short, u_short); +u_short read_csr(struct lnc_softc *, u_short); +void lnc_release_resources(device_t); -struct isa_driver lncdriver = { - INTR_TYPE_NET, - lnc_probe, - lnc_attach, - "lnc" -}; -COMPAT_ISA_DRIVER(lnc, lncdriver); +u_short +read_csr(struct lnc_softc *sc, u_short port) +{ + bus_space_write_2(sc->lnc_btag, sc->lnc_bhandle, sc->rap, port); + return(bus_space_read_2(sc->lnc_btag, sc->lnc_bhandle, sc->rdp)); +} + +void +write_csr(struct lnc_softc *sc, u_short port, u_short val) +{ + bus_space_write_2(sc->lnc_btag, sc->lnc_bhandle, sc->rap, port); + bus_space_write_2(sc->lnc_btag, sc->lnc_bhandle, sc->rdp, val); +} + +#define inw(port) bus_space_read_2(sc->lnc_btag, sc->lnc_bhandle, port) +#define outw(port, val) bus_space_write_2(sc->lnc_btag, sc->lnc_bhandle, port, val) static __inline void -write_bcr(lnc_softc_t *sc, u_short port, u_short val) +write_bcr(struct lnc_softc *sc, u_short port, u_short val) { outw(sc->rap, port); outw(sc->bdp, val); } static __inline u_short -read_bcr(lnc_softc_t *sc, u_short port) +read_bcr(struct lnc_softc *sc, u_short port) { outw(sc->rap, port); return (inw(sc->bdp)); @@ -186,11 +191,36 @@ ether_crc(const u_char *ether_addr) #undef POLYNOMIAL } +void +lnc_release_resources(device_t dev) +{ + lnc_softc_t *sc = device_get_softc(dev); + + if (sc->irqres) { + bus_teardown_intr(dev, sc->irqres, sc->intrhand); + bus_release_resource(dev, SYS_RES_IRQ, sc->irqrid, sc->irqres); + } + + if (sc->portres) + bus_release_resource(dev, SYS_RES_IOPORT, + sc->portrid, sc->portres); + if (sc->drqres) + bus_release_resource(dev, SYS_RES_DRQ, sc->drqrid, sc->drqres); + + if (sc->dmat) { + if (sc->dmamap) { + bus_dmamap_unload(sc->dmat, sc->dmamap); + bus_dmamem_free(sc->dmat, sc->recv_ring, sc->dmamap); + } + bus_dma_tag_destroy(sc->dmat); + } +} + /* * Set up the logical address filter for multicast packets */ static __inline void -lnc_setladrf(lnc_softc_t *sc) +lnc_setladrf(struct lnc_softc *sc) { struct ifnet *ifp = &sc->arpcom.ac_if; struct ifmultiaddr *ifma; @@ -222,20 +252,20 @@ lnc_setladrf(lnc_softc_t *sc) } } -static void -lnc_stop(lnc_softc_t *sc) +void +lnc_stop(struct lnc_softc *sc) { write_csr(sc, CSR0, STOP); } static void -lnc_reset(lnc_softc_t *sc) +lnc_reset(struct lnc_softc *sc) { lnc_init(sc); } static void -lnc_free_mbufs(lnc_softc_t *sc) +lnc_free_mbufs(struct lnc_softc *sc) { int i; @@ -257,7 +287,7 @@ lnc_free_mbufs(lnc_softc_t *sc) } static __inline int -alloc_mbuf_cluster(lnc_softc_t *sc, struct host_ring_entry *desc) +alloc_mbuf_cluster(struct lnc_softc *sc, struct host_ring_entry *desc) { register struct mds *md = desc->md; struct mbuf *m=0; @@ -290,7 +320,7 @@ alloc_mbuf_cluster(lnc_softc_t *sc, struct host_ring_entry *desc) } static __inline struct mbuf * -chain_mbufs(lnc_softc_t *sc, int start_of_packet, int pkt_len) +chain_mbufs(struct lnc_softc *sc, int start_of_packet, int pkt_len) { struct mbuf *head, *m; struct host_ring_entry *desc; @@ -325,7 +355,7 @@ chain_mbufs(lnc_softc_t *sc, int start_of_packet, int pkt_len) } static __inline struct mbuf * -mbuf_packet(lnc_softc_t *sc, int start_of_packet, int pkt_len) +mbuf_packet(struct lnc_softc *sc, int start_of_packet, int pkt_len) { struct host_ring_entry *start; @@ -400,7 +430,7 @@ mbuf_packet(lnc_softc_t *sc, int start_of_packet, int pkt_len) static __inline void -lnc_rint(lnc_softc_t *sc) +lnc_rint(struct lnc_softc *sc) { struct host_ring_entry *next, *start; int start_of_packet; @@ -552,19 +582,18 @@ lnc_rint(lnc_softc_t *sc) * vmware ethernet hardware emulation loops * packets back to itself, violates IFF_SIMPLEX. * drop it if it is from myself. - */ + */ if (bcmp(eh->ether_shost, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN) == 0) { - m_freem(head); + m_freem(head); } else { - /* Skip over the ether header */ - head->m_data += sizeof *eh; - head->m_len -= sizeof *eh; - head->m_pkthdr.len -= sizeof *eh; + /* Skip over the ether header */ + head->m_data += sizeof *eh; + head->m_len -= sizeof *eh; + head->m_pkthdr.len -= sizeof *eh; - ether_input(&sc->arpcom.ac_if, eh, head); + ether_input(&sc->arpcom.ac_if, eh, head); } - } else { int unit = sc->arpcom.ac_if.if_unit; log(LOG_ERR,"lnc%d: Packet dropped, no mbufs\n",unit); @@ -585,7 +614,7 @@ lnc_rint(lnc_softc_t *sc) } static __inline void -lnc_tint(lnc_softc_t *sc) +lnc_tint(struct lnc_softc *sc) { struct host_ring_entry *next, *start; int start_of_packet; @@ -817,71 +846,20 @@ lnc_tint(lnc_softc_t *sc) */ outw(sc->rdp, TINT | INEA); - - /* XXX only while doing if_is comparisons */ - if (!(sc->arpcom.ac_if.if_flags & IFF_OACTIVE)) - lnc_start(&sc->arpcom.ac_if); - } int -lnc_attach_sc(lnc_softc_t *sc, int unit) +lnc_attach_common(device_t dev) { - int lnc_mem_size; - - /* - * Allocate memory for use by the controller. - * - * XXX -- the Am7990 and Am79C960 only have 24 address lines and so can - * only access the lower 16Mb of physical memory. For the moment we - * assume that malloc will allocate memory within the lower 16Mb - * range. This is not a very valid assumption but there's nothing - * that can be done about it yet. For shared memory NICs this isn't - * relevant. - * - */ - - lnc_mem_size = ((NDESC(sc->nrdre) + NDESC(sc->ntdre)) * - sizeof(struct host_ring_entry)); - - if (sc->nic.mem_mode != SHMEM) - lnc_mem_size += sizeof(struct init_block) + (sizeof(struct mds) * - (NDESC(sc->nrdre) + NDESC(sc->ntdre))) + - MEM_SLEW; - - /* If using DMA to fixed host buffers then allocate memory for them */ - - if (sc->nic.mem_mode == DMA_FIXED) - lnc_mem_size += (NDESC(sc->nrdre) * RECVBUFSIZE) + (NDESC(sc->ntdre) * TRANSBUFSIZE); - - if (sc->nic.mem_mode != SHMEM) { - if (sc->nic.ic < PCnet_32) { - /* ISA based cards */ - sc->recv_ring = contigmalloc(lnc_mem_size, M_DEVBUF, M_NOWAIT, - 0ul, 0xfffffful, 4ul, 0x1000000); - } else { - /* Non-ISA based cards, 32 bit capable */ -#ifdef notyet - /* - * For the 32 bit driver we're not fussed where we DMA to - * though it'll still need to be contiguous - */ - sc->recv_ring = malloc(lnc_mem_size, M_DEVBUF, M_NOWAIT); -#else - /* - * For now it still needs to be below 16MB because the - * descriptor's can only hold 16 bit addresses. - */ - sc->recv_ring = contigmalloc(lnc_mem_size, M_DEVBUF, M_NOWAIT, - 0ul, 0xfffffful, 4ul, 0x1000000); -#endif - } - } + int unit = device_get_unit(dev); + lnc_softc_t *sc = device_get_softc(dev); + int i; + int skip; - if (!sc->recv_ring) { - log(LOG_ERR, "lnc%d: Couldn't allocate memory for NIC\n", unit); - return (0); /* XXX -- attach failed -- not tested in - * calling routines */ + if (sc->nic.ident == BICC) { + skip = 2; + } else { + skip = 1; } /* Set default mode */ @@ -890,9 +868,8 @@ lnc_attach_sc(lnc_softc_t *sc, int unit) /* Fill in arpcom structure entries */ sc->arpcom.ac_if.if_softc = sc; - sc->arpcom.ac_if.if_name = lncdriver.name; + sc->arpcom.ac_if.if_name = "lnc"; sc->arpcom.ac_if.if_unit = unit; - sc->arpcom.ac_if.if_mtu = ETHERMTU; sc->arpcom.ac_if.if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; sc->arpcom.ac_if.if_timer = 0; sc->arpcom.ac_if.if_output = ether_output; @@ -900,11 +877,16 @@ lnc_attach_sc(lnc_softc_t *sc, int unit) sc->arpcom.ac_if.if_ioctl = lnc_ioctl; sc->arpcom.ac_if.if_watchdog = lnc_watchdog; sc->arpcom.ac_if.if_init = lnc_init; - sc->arpcom.ac_if.if_type = IFT_ETHER; - sc->arpcom.ac_if.if_addrlen = ETHER_ADDR_LEN; - sc->arpcom.ac_if.if_hdrlen = ETHER_HDR_LEN; sc->arpcom.ac_if.if_snd.ifq_maxlen = IFQ_MAXLEN; + /* Extract MAC address from PROM */ + for (i = 0; i < ETHER_ADDR_LEN; i++) + sc->arpcom.ac_enaddr[i] = inb(sc->iobase + (i * skip)); + + /* + * XXX -- should check return status of if_attach + */ + ether_ifattach(&sc->arpcom.ac_if, ETHER_BPF_SUPPORTED); printf("lnc%d: ", unit); @@ -922,14 +904,16 @@ static void lnc_init(xsc) void *xsc; { - lnc_softc_t *sc = xsc; + struct lnc_softc *sc = xsc; int s, i; char *lnc_mem; /* Check that interface has valid address */ - if (TAILQ_EMPTY(&sc->arpcom.ac_if.if_addrhead)) /* XXX unlikely */ + if (TAILQ_EMPTY(&sc->arpcom.ac_if.if_addrhead)) { /* XXX unlikely */ +printf("XXX no address?\n"); return; + } /* Shut down interface */ @@ -947,8 +931,6 @@ lnc_init(xsc) * The alignment tests are particularly paranoid. */ - - sc->recv_next = 0; sc->trans_ring = sc->recv_ring + NDESC(sc->nrdre); sc->trans_next = 0; @@ -1066,11 +1048,11 @@ lnc_init(xsc) write_csr(sc, CSR3, 0); /* Let's see if it starts */ - - write_csr(sc, CSR0, INIT); - for (i = 0; i < 1000; i++) - if (read_csr(sc, CSR0) & IDON) - break; +/* +printf("Enabling lnc interrupts\n"); + sc->arpcom.ac_if.if_timer = 10; + write_csr(sc, CSR0, INIT|INEA); +*/ /* * Now that the initialisation is complete there's no reason to @@ -1079,6 +1061,11 @@ lnc_init(xsc) * time. */ + write_csr(sc, CSR0, INIT); + for(i=0; i < 1000; i++) + if (read_csr(sc, CSR0) & IDON) + break; + if (read_csr(sc, CSR0) & IDON) { /* * Enable interrupts, start the LANCE, mark the interface as @@ -1117,8 +1104,9 @@ lnc_init(xsc) */ void -lncintr_sc(lnc_softc_t *sc) +lncintr(void *arg) { + lnc_softc_t *sc = arg; int unit = sc->arpcom.ac_if.if_unit; u_short csr0; @@ -1137,10 +1125,20 @@ lncintr_sc(lnc_softc_t *sc) * be missed. */ -/* outw(sc->rdp, IDON | CERR | BABL | MISS | MERR | RINT | TINT | INEA); */ outw(sc->rdp, csr0); + /*outw(sc->rdp, IDON | CERR | BABL | MISS | MERR | RINT | TINT | INEA);*/ - /* We don't do anything with the IDON flag */ +#ifdef notyet + if (csr0 & IDON) { +printf("IDON\n"); + sc->arpcom.ac_if.if_timer = 0; + write_csr(sc, CSR0, STRT | INEA); + sc->arpcom.ac_if.if_flags |= IFF_RUNNING; + sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE; + lnc_start(&sc->arpcom.ac_if); + continue; + } +#endif if (csr0 & ERR) { if (csr0 & CERR) { @@ -1228,7 +1226,7 @@ static void lnc_start(struct ifnet *ifp) { - lnc_softc_t *sc = ifp->if_softc; + struct lnc_softc *sc = ifp->if_softc; struct host_ring_entry *desc; int tmp; int end_of_packet; @@ -1384,7 +1382,7 @@ static int lnc_ioctl(struct ifnet * ifp, u_long command, caddr_t data) { - lnc_softc_t *sc = ifp->if_softc; + struct lnc_softc *sc = ifp->if_softc; int s, error = 0; s = splimp(); @@ -1462,7 +1460,7 @@ lnc_watchdog(struct ifnet *ifp) #ifdef DEBUG void -lnc_dump_state(lnc_softc_t *sc) +lnc_dump_state(struct lnc_softc *sc) { int i; diff --git a/sys/dev/lnc/if_lnc_isa.c b/sys/dev/lnc/if_lnc_isa.c index ce501b5..5c298d1 100644 --- a/sys/dev/lnc/if_lnc_isa.c +++ b/sys/dev/lnc/if_lnc_isa.c @@ -1,6 +1,6 @@ -/*- - * Copyright (c) 2000 - * Paul Richards. All rights reserved. +/* + * Copyright (c) 1994-2000 + * Paul Richards. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,98 +31,72 @@ */ #include <sys/param.h> -#include <sys/malloc.h> #include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/malloc.h> #include <sys/socket.h> +#include <machine/bus_memio.h> +#include <machine/bus_pio.h> +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/rman.h> + #include <net/ethernet.h> #include <net/if.h> -#include <net/if_dl.h> -#include <net/if_types.h> +#include <net/if_arp.h> -#include <netinet/in.h> -#include <netinet/if_ether.h> +#include <isa/isavar.h> -#include <i386/isa/isa_device.h> -#include <dev/lnc/if_lncvar.h> -#include <dev/lnc/if_lncreg.h> +#include <dev/lnc/if_lnc.h> -int ne2100_probe __P((lnc_softc_t *, unsigned)); -int bicc_probe __P((lnc_softc_t *, unsigned)); -int depca_probe __P((lnc_softc_t *, unsigned)); -#ifdef PC98 -int cnet98s_probe __P((lnc_softc_t *, unsigned)); -#endif -int lance_probe __P((lnc_softc_t *)); -int pcnet_probe __P((lnc_softc_t *)); -int lnc_probe __P((struct isa_device *)); -int lnc_attach __P((struct isa_device *)); - -static int dec_macaddr_extract __P((u_char[], lnc_softc_t *)); -static ointhand2_t lncintr; +static struct isa_pnp_id lnc_pnp_ids[] = { + {0, NULL} +}; -extern int lnc_attach_sc __P((lnc_softc_t *, int)); -extern void lncintr_sc __P((lnc_softc_t *)); +extern void write_csr(struct lnc_softc *, u_short, u_short); +extern u_short read_csr(struct lnc_softc *, u_short); +extern void lnc_release_resources(device_t); -static lnc_softc_t * -lnc_getsoftc(int unit) +static int +lance_probe(struct lnc_softc *sc) { - static lnc_softc_t **sc; - static int units; - - if (unit >= units) { - /* Reallocate more softc pointers */ - - lnc_softc_t **nsc; - int n; - - n = unit + 1; - nsc = malloc(sizeof(lnc_softc_t *) * n, M_DEVBUF, M_WAITOK); - if (units) - bcopy(sc, nsc, sizeof(lnc_softc_t *) * units); - bzero(nsc + units, sizeof(lnc_softc_t *) * (n - units)); - if (sc) - free(sc, M_DEVBUF); - units = n; - sc = nsc; - } - - if (sc[unit] == NULL) - sc[unit] = malloc(sizeof(lnc_softc_t), M_DEVBUF, M_WAITOK); + write_csr(sc, CSR0, STOP); - return sc[unit]; + if ((bus_space_read_2(sc->lnc_btag, sc->lnc_bhandle, sc->rdp) & STOP) && + ! (read_csr(sc, CSR3))) { + /* + * Check to see if it's a C-LANCE. For the LANCE the INEA bit + * cannot be set while the STOP bit is. This restriction is + * removed for the C-LANCE. + */ + write_csr(sc, CSR0, INEA); + if (read_csr(sc, CSR0) & INEA) + return (C_LANCE); + else + return (LANCE); + } else + return (UNKNOWN); } -int -ne2100_probe(lnc_softc_t *sc, unsigned iobase) +static int +lnc_legacy_probe(device_t dev) { - int i; + struct lnc_softc *sc = device_get_softc(dev); - sc->rap = iobase + PCNET_RAP; - sc->rdp = iobase + PCNET_RDP; - - sc->nic.ic = pcnet_probe(sc); - if ((sc->nic.ic > 0) && (sc->nic.ic < PCnet_PCI)) { - sc->nic.ident = NE2100; - sc->nic.mem_mode = DMA_FIXED; + sc->portrid = 0; + sc->portres = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->portrid, + 0, ~0, 1, RF_ACTIVE); - /* XXX - For now just use the defines */ - sc->nrdre = NRDRE; - sc->ntdre = NTDRE; - - /* Extract MAC address from PROM */ - for (i = 0; i < ETHER_ADDR_LEN; i++) - sc->arpcom.ac_enaddr[i] = inb(iobase + i); - return (NE2100_IOSIZE); - } else { - return (0); + if (! sc->portres) { + device_printf(dev, "Failed to allocate I/O ports\n"); + lnc_release_resources(dev); + return (ENXIO); } -} -int -bicc_probe(lnc_softc_t *sc, unsigned iobase) -{ - int i; + sc->lnc_btag = rman_get_bustag(sc->portres); + sc->lnc_bhandle = rman_get_bushandle(sc->portres); /* * There isn't any way to determine if a NIC is a BICC. Basically, if @@ -130,204 +104,213 @@ bicc_probe(lnc_softc_t *sc, unsigned iobase) * we assume it's a BICC. * */ - - sc->rap = iobase + BICC_RAP; - sc->rdp = iobase + BICC_RDP; - - /* I think all these cards us the Am7990 */ + sc->rap = BICC_RAP; + sc->rdp = BICC_RDP; + sc->nic.mem_mode = DMA_FIXED; + /* XXX Should set BICC_IOSIZE et al somewhere to alloc + resources correctly */ if ((sc->nic.ic = lance_probe(sc))) { + device_set_desc(dev, "BICC Isolan"); sc->nic.ident = BICC; - sc->nic.mem_mode = DMA_FIXED; - - /* XXX - For now just use the defines */ - sc->nrdre = NRDRE; - sc->ntdre = NTDRE; - - /* Extract MAC address from PROM */ - for (i = 0; i < ETHER_ADDR_LEN; i++) - sc->arpcom.ac_enaddr[i] = inb(iobase + (i * 2)); - - return (BICC_IOSIZE); + lnc_release_resources(dev); + return (0); } else { + /* It's not a BICC so try the standard NE2100 ports */ + sc->rap = PCNET_RAP; + sc->rdp = PCNET_RDP; + if ((sc->nic.ic = lance_probe(sc))) { + sc->nic.ident = NE2100; + device_set_desc(dev, "NE2100"); + lnc_release_resources(dev); return (0); + } else { + lnc_release_resources(dev); + return (ENXIO); + } } } -/* - * I don't have data sheets for the dec cards but it looks like the mac - * address is contained in a 32 byte ring. Each time you read from the port - * you get the next byte in the ring. The mac address is stored after a - * signature so keep searching for the signature first. - */ static int -dec_macaddr_extract(u_char ring[], lnc_softc_t * sc) +lnc_isa_probe(device_t dev) { - const unsigned char signature[] = {0xff, 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa}; - - int i, j, rindex; - - for (i = 0; i < sizeof ring; i++) { - for (j = 0, rindex = i; j < sizeof signature; j++) { - if (ring[rindex] != signature[j]) - break; - if (++rindex > sizeof ring) - rindex = 0; - } - if (j == sizeof signature) { - for (j = 0, rindex = i; j < ETHER_ADDR_LEN; j++) { - sc->arpcom.ac_enaddr[j] = ring[rindex]; - if (++rindex > sizeof ring) - rindex = 0; - } - return (1); - } + int pnp; + + pnp = ISA_PNP_PROBE(device_get_parent(dev), dev, lnc_pnp_ids); + if (pnp == ENOENT) { + /* It's not a PNP card, see if we support it by probing it */ + return (lnc_legacy_probe(dev)); + } else if (pnp == ENXIO) { + return (ENXIO); + } else { + /* Found PNP card we support */ + return (0); } - return (0); } -int -depca_probe(lnc_softc_t *sc, unsigned iobase) +static void +lnc_alloc_callback(void *arg, bus_dma_segment_t *seg, int nseg, int error) { - int i; - unsigned char maddr_ring[DEPCA_ADDR_ROM_SIZE]; + /* Do nothing */ + return; +} - sc->rap = iobase + DEPCA_RAP; - sc->rdp = iobase + DEPCA_RDP; +static int +lnc_isa_attach(device_t dev) +{ + lnc_softc_t *sc = device_get_softc(dev); + int err = 0; + bus_size_t lnc_mem_size; - if ((sc->nic.ic = lance_probe(sc))) { - sc->nic.ident = DEPCA; - sc->nic.mem_mode = SHMEM; - - /* Extract MAC address from PROM */ - for (i = 0; i < DEPCA_ADDR_ROM_SIZE; i++) - maddr_ring[i] = inb(iobase + DEPCA_ADP); - if (dec_macaddr_extract(maddr_ring, sc)) { - return (DEPCA_IOSIZE); - } + device_printf(dev, "Attaching %s\n", device_get_desc(dev)); + + sc->portrid = 0; + sc->portres = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->portrid, + 0, ~0, 1, RF_ACTIVE); + + if (! sc->portres) { + device_printf(dev, "Failed to allocate I/O ports\n"); + lnc_release_resources(dev); + return (ENXIO); } - return (0); -} -int -lance_probe(lnc_softc_t *sc) -{ - write_csr(sc, CSR0, STOP); + sc->drqrid = 0; + sc->drqres = bus_alloc_resource(dev, SYS_RES_DRQ, &sc->drqrid, + 0, ~0, 1, RF_ACTIVE); - if ((inw(sc->rdp) & STOP) && !(read_csr(sc, CSR3))) { - /* - * Check to see if it's a C-LANCE. For the LANCE the INEA bit - * cannot be set while the STOP bit is. This restriction is - * removed for the C-LANCE. - */ - write_csr(sc, CSR0, INEA); - if (read_csr(sc, CSR0) & INEA) - return (C_LANCE); - else - return (LANCE); - } else - return (UNKNOWN); -} + if (! sc->drqres) { + device_printf(dev, "Failed to allocate DMA channel\n"); + lnc_release_resources(dev); + return (ENXIO); + } -int -pcnet_probe(lnc_softc_t *sc) -{ - u_long chip_id; - int type; + if (isa_get_irq(dev) == -1) + bus_set_resource(dev, SYS_RES_IRQ, 0, 10, 1); - /* - * The PCnet family don't reset the RAP register on reset so we'll - * have to write during the probe :-) It does have an ID register - * though so the probe is just a matter of reading it. - */ + sc->irqrid = 0; + sc->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqrid, 0, ~0, 1, + RF_ACTIVE); - if ((type = lance_probe(sc))) { - chip_id = read_csr(sc, CSR89); - chip_id <<= 16; - chip_id |= read_csr(sc, CSR88); - if (chip_id & AMD_MASK) { - chip_id >>= 12; - switch (chip_id & PART_MASK) { - case Am79C960: - return (PCnet_ISA); - case Am79C961: - return (PCnet_ISAplus); - case Am79C961A: - return (PCnet_ISA_II); - case Am79C965: - return (PCnet_32); - case Am79C970: - return (PCnet_PCI); - case Am79C970A: - return (PCnet_PCI_II); - case Am79C971: - return (PCnet_FAST); - case Am79C972: - case Am79C973: - return (PCnet_FASTplus); - case Am79C978: - return (PCnet_Home); - default: - break; - } - } + if (! sc->irqres) { + device_printf(dev, "Failed to allocate irq\n"); + lnc_release_resources(dev); + return (ENXIO); } - return (type); -} -int -lnc_probe(struct isa_device * isa_dev) -{ - int nports; - int unit = isa_dev->id_unit; - lnc_softc_t *sc = lnc_getsoftc(unit); - unsigned iobase = isa_dev->id_iobase; - -#ifdef DIAGNOSTIC - int vsw; - vsw = inw(isa_dev->id_iobase + PCNET_VSW); - printf("Vendor Specific Word = %x\n", vsw); -#endif + err = bus_setup_intr(dev, sc->irqres, INTR_TYPE_NET, lncintr, + sc, &sc->intrhand); - nports = bicc_probe(sc, iobase); - if (nports == 0) - nports = ne2100_probe(sc, iobase); - if (nports == 0) - nports = depca_probe(sc, iobase); -#ifdef PC98 - if (nports == 0) - nports = cnet98s_probe(sc, iobase); -#endif - return (nports); -} + if (err) { + device_printf(dev, "Failed to setup irq handler\n"); + lnc_release_resources(dev); + return (err); + } -int -lnc_attach(struct isa_device * isa_dev) -{ - int unit = isa_dev->id_unit; - lnc_softc_t *sc = lnc_getsoftc(unit); - int result; + /* XXX temp setting for nic */ + sc->nic.mem_mode = DMA_FIXED; + sc->nrdre = NRDRE; + sc->ntdre = NTDRE; - isa_dev->id_ointr = lncintr; - result = lnc_attach_sc (sc, unit); - if (result == 0) - return (0); + if (sc->nic.ident == NE2100) { + sc->rap = PCNET_RAP; + sc->rdp = PCNET_RDP; + sc->bdp = PCNET_BDP; + } else { + sc->rap = BICC_RAP; + sc->rdp = BICC_RDP; + } -#ifndef PC98 - /* - * XXX - is it safe to call isa_dmacascade() after - * ether_ifattach() has been called in lnc_attach() ??? - */ - if ((sc->nic.mem_mode != SHMEM) && - (sc->nic.ic < PCnet_32)) - isa_dmacascade(isa_dev->id_drq); -#endif + printf("rap = %x\n", sc->rap); + + /* Create a DMA tag describing the ring memory we need */ + + lnc_mem_size = ((NDESC(sc->nrdre) + NDESC(sc->ntdre)) * + sizeof(struct host_ring_entry)); + + lnc_mem_size += (NDESC(sc->nrdre) * RECVBUFSIZE) + + (NDESC(sc->ntdre) * TRANSBUFSIZE); + + err = bus_dma_tag_create(NULL, /* parent */ + 4, /* alignement */ + 0, /* boundary */ + BUS_SPACE_MAXADDR_24BIT, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + lnc_mem_size, /* segsize */ + 1, /* nsegments */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ + 0, /* flags */ + &sc->dmat); + + if (err) { + device_printf(dev, "Can't create DMA tag\n"); + lnc_release_resources(dev); + return (ENOMEM); + } + + err = bus_dmamem_alloc(sc->dmat, (void **)&sc->recv_ring, + BUS_DMA_NOWAIT, &sc->dmamap); + + if (err) { + device_printf(dev, "Couldn't allocate memory\n"); + lnc_release_resources(dev); + return (ENOMEM); + } + + err = bus_dmamap_load(sc->dmat, sc->dmamap, sc->recv_ring, lnc_mem_size, + lnc_alloc_callback, sc->recv_ring, BUS_DMA_NOWAIT); + + if (err) { + device_printf(dev, "Couldn't load DMA map\n"); + lnc_release_resources(dev); + return (ENOMEM); + } + + isa_dmacascade(rman_get_start(sc->drqres)); - return result; + /* Call generic attach code */ + if (! lnc_attach_common(dev)) { + device_printf(dev, "Generic attach code failed\n"); + lnc_release_resources(dev); + return (ENXIO); + } + return (0); } -static void -lncintr(int unit) +static int +lnc_isa_detach(device_t dev) { - lncintr_sc(lnc_getsoftc(unit)); + lnc_softc_t *sc = device_get_softc(dev); + int s = splimp(); + + ether_ifdetach(&sc->arpcom.ac_if, ETHER_BPF_SUPPORTED); + splx(s); + + lnc_stop(sc); + lnc_release_resources(dev); + + return (0); } + +static device_method_t lnc_isa_methods[] = { +/* DEVMETHOD(device_identify, lnc_isa_identify), */ + DEVMETHOD(device_probe, lnc_isa_probe), + DEVMETHOD(device_attach, lnc_isa_attach), + DEVMETHOD(device_detach, lnc_isa_detach), +#ifdef notyet + DEVMETHOD(device_suspend, lnc_isa_suspend), + DEVMETHOD(device_resume, lnc_isa_resume), + DEVMETHOD(device_shutdown, lnc_isa_shutdown), +#endif + { 0, 0 } +}; + +static driver_t lnc_isa_driver = { + "lnc", + lnc_isa_methods, + sizeof(struct lnc_softc), +}; + +static devclass_t lnc_devclass; + +DRIVER_MODULE(lnc_isa, isa, lnc_isa_driver, lnc_devclass, 0, 0); diff --git a/sys/dev/lnc/if_lnc_pc98.c b/sys/dev/lnc/if_lnc_pc98.c index 4484a14..f05a3f5 100644 --- a/sys/dev/lnc/if_lnc_pc98.c +++ b/sys/dev/lnc/if_lnc_pc98.c @@ -30,6 +30,8 @@ * $FreeBSD$ */ +#ifdef notyet + #ifdef PC98 #include "lnc.h" @@ -55,35 +57,6 @@ int pcnet_probe __P((lnc_softc_t *sc)); int cnet98s_probe __P((lnc_softc_t *sc, unsigned iobase)); -/* C-NET(98)S port addresses */ -#define CNET98S_RDP 0x400 /* Register Data Port */ -#define CNET98S_RAP 0x402 /* Register Address Port */ -#define CNET98S_RESET 0x404 -#define CNET98S_IDP 0x406 -#define CNET98S_EEPROM 0x40e -/* - * XXX - The I/O address range is fragmented in the C-NET(98)S. - * This is the number of regs at iobase. - */ -#define CNET98S_IOSIZE 16 /* # of i/o addresses used. */ - -/* ISA Bus Configuration Registers */ -/* XXX - Should be in ic/Am7990.h */ -#define MSRDA 0x0000 /* ISACSR0: Master Mode Read Activity */ -#define MSWRA 0x0001 /* ISACSR1: Master Mode Write Activity */ -#define MC 0x0002 /* ISACSR2: Miscellaneous Configuration */ - -#define LED1 0x0005 /* ISACSR5: LED1 Status */ -#define LED2 0x0006 /* ISACSR6: LED2 Status */ -#define LED3 0x0007 /* ISACSR7: LED3 Status */ - -#define LED_PSE 0x0080 /* Pulse Stretcher */ -#define LED_XMTE 0x0010 /* Transmit Status */ -#define LED_RVPOLE 0x0008 /* Receive Polarity */ -#define LED_RCVE 0x0004 /* Receive Status */ -#define LED_JABE 0x0002 /* Jabber */ -#define LED_COLE 0x0001 /* Collision */ - int cnet98s_probe(lnc_softc_t *sc, unsigned iobase) { @@ -144,4 +117,7 @@ cnet98s_probe(lnc_softc_t *sc, unsigned iobase) return (CNET98S_IOSIZE); } + #endif + +#endif /* notyet */ diff --git a/sys/dev/lnc/if_lnc_pci.c b/sys/dev/lnc/if_lnc_pci.c index c69716d..7ef57d5 100644 --- a/sys/dev/lnc/if_lnc_pci.c +++ b/sys/dev/lnc/if_lnc_pci.c @@ -1,142 +1,220 @@ /* - * - * Copyright (c) 1996 Stefan Esser <se@freebsd.org> - * All rights reserved. + * Copyright (c) 1994-2000 + * Paul Richards. All rights reserved. * * 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 immediately at the beginning of the file, without modification, - * this list of conditions, and the following disclaimer. + * notice, this list of conditions and the following disclaimer, + * verbatim and that no modifications are made prior to this + * point in the file. * 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. - * 3. Absolutely no warranty of function or purpose is made by the author - * Stefan Esser. - * 4. Modifications may be freely made to this file if the above conditions - * are met. + * 3. The name Paul Richards may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PAUL RICHARDS ``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 PAUL RICHARDS 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. * * $FreeBSD$ */ #include <sys/param.h> #include <sys/systm.h> +#include <sys/socket.h> #include <sys/malloc.h> #include <sys/kernel.h> -#include <pci/pcireg.h> -#include <pci/pcivar.h> -#include <sys/socket.h> +#include <machine/bus_memio.h> +#include <machine/bus_pio.h> +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/bus.h> +#include <sys/rman.h> + #include <net/ethernet.h> #include <net/if.h> -#include <net/if_dl.h> -#include <net/if_types.h> - -#include <netinet/in.h> -#include <netinet/if_ether.h> - -#include <dev/lnc/if_lncvar.h> - -#include "lnc.h" - -#ifndef COMPAT_OLDPCI -#error "The lnc device requires the old pci compatibility shims" -#endif - -#define PCI_DEVICE_ID_PCNet_PCI 0x20001022 -#define PCI_DEVICE_ID_PCHome_PCI 0x20011022 +#include <net/if_arp.h> -extern int pcnet_probe __P((lnc_softc_t *sc)); -extern int lnc_attach_sc __P((lnc_softc_t *sc, int unit)); - -static const char* lnc_pci_probe __P((pcici_t tag, pcidi_t type)); -static void lnc_pci_attach __P((pcici_t config_id, int unit)); - -static u_long lnc_pci_count = NLNC; +#include <pci/pcireg.h> +#include <pci/pcivar.h> -static struct pci_device lnc_pci_driver = { - "lnc", - lnc_pci_probe, - lnc_pci_attach, - &lnc_pci_count, - NULL -}; +#include <dev/lnc/if_lnc.h> -COMPAT_PCI_DRIVER (lnc_pci, lnc_pci_driver); +#define AMD_VENDOR_ID 0x1022 +#define PCI_DEVICE_ID_PCNet_PCI 0x2000 +#define PCI_DEVICE_ID_PCHome_PCI 0x2001 -static const char* -lnc_pci_probe (pcici_t tag, pcidi_t type) +static int +lnc_pci_probe(device_t dev) { - switch(type) { + if (pci_get_vendor(dev) != AMD_VENDOR_ID) + return (ENXIO); + + switch(pci_get_device(dev)) { case PCI_DEVICE_ID_PCNet_PCI: - return ("PCNet/PCI Ethernet adapter"); + device_set_desc(dev, "PCNet/PCI Ethernet adapter"); + return(0); break; case PCI_DEVICE_ID_PCHome_PCI: - return ("PCHome/PCI Ethernet adapter"); + device_set_desc(dev, "PCHome/PCI Ethernet adapter"); + return(0); break; default: + return (ENXIO); break; } - return (0); + return (ENXIO); } -void lncintr_sc (void*); - static void -lnc_pci_attach(config_id, unit) - pcici_t config_id; - int unit; +lnc_alloc_callback(void *arg, bus_dma_segment_t *seg, int nseg, int error) { - lnc_softc_t *sc; - unsigned iobase; - unsigned data; /* scratch to make this device a bus master*/ - int i; - - if ( !pci_map_port(config_id,PCI_MAP_REG_START,(u_short *)&iobase) ) - printf("lnc%d: pci_port_map_attach failed?!\n",unit); - - - /* Make this device a bus master. This was implictly done by - pci_map_port under 2.2.x -- tvf */ - - data = pci_cfgread(config_id, PCIR_COMMAND, 4); - data |= PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN; - pci_cfgwrite(config_id, PCIR_COMMAND, data, 4); - - sc = malloc(sizeof *sc, M_DEVBUF, M_NOWAIT | M_ZERO); - - if (sc) { - sc->rap = iobase + PCNET_RAP; - sc->rdp = iobase + PCNET_RDP; - sc->bdp = iobase + PCNET_BDP; - - sc->nic.ic = pcnet_probe(sc); - if (sc->nic.ic >= PCnet_32) { - sc->nic.ident = NE2100; - sc->nic.mem_mode = DMA_FIXED; - - /* XXX - For now just use the defines */ - sc->nrdre = NRDRE; - sc->ntdre = NTDRE; - - /* Extract MAC address from PROM */ - for (i = 0; i < ETHER_ADDR_LEN; i++) - sc->arpcom.ac_enaddr[i] = inb(iobase + i); - - if (lnc_attach_sc(sc, unit) == 0) { - free(sc, M_DEVBUF); - sc = NULL; - } - - if(!(pci_map_int(config_id, lncintr_sc, (void *)sc, &net_imask))) { - free (sc, M_DEVBUF); - return; - } - } else { - free(sc, M_DEVBUF); - } + /* Do nothing */ + return; +} + +static int +lnc_pci_attach(device_t dev) +{ + lnc_softc_t *sc = device_get_softc(dev); + unsigned command; + int rid = 0; + int err = 0; + bus_size_t lnc_mem_size; + + device_printf(dev, "Attaching %s\n", device_get_desc(dev)); + + command = pci_read_config(dev, PCIR_COMMAND, 4); + command |= PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN; + pci_write_config(dev, PCIR_COMMAND, command, 4); + + rid = PCIR_MAPS; + sc->portres = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, + RF_ACTIVE); + + if (! sc->portres) + device_printf(dev, "Cannot allocate I/O ports\n"); + + rid = 0; + sc->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, + RF_ACTIVE|RF_SHAREABLE); + + if (! sc->irqres) + device_printf(dev, "Cannot allocate irq\n"); + + err = bus_setup_intr(dev, sc->irqres, INTR_TYPE_NET, lncintr, + sc, &sc->intrhand); + if (err) + device_printf(dev, "Cannot setup irq handler\n"); + + sc->iobase = rman_get_start(sc->portres); + + /* XXX temp setting for nic */ + sc->nic.ic = PCnet_PCI; + sc->nic.ident = NE2100; + sc->nic.mem_mode = DMA_FIXED; + sc->nrdre = NRDRE; + sc->ntdre = NTDRE; + sc->rap = sc->iobase + PCNET_RAP; + sc->rdp = sc->iobase + PCNET_RDP; + sc->bdp = sc->iobase + PCNET_BDP; + + /* Create a DMA tag describing the ring memory we need */ + + lnc_mem_size = ((NDESC(sc->nrdre) + NDESC(sc->ntdre)) * + sizeof(struct host_ring_entry)); + + lnc_mem_size += (NDESC(sc->nrdre) * RECVBUFSIZE) + + (NDESC(sc->ntdre) * TRANSBUFSIZE); + + err = bus_dma_tag_create(NULL, /* parent */ + 1, /* alignement */ + 0, /* boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + lnc_mem_size, /* segsize */ + 1, /* nsegments */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ + 0, /* flags */ + &sc->dmat); + + if (err) { + device_printf(dev, "Can't create DMA tag\n"); + /* XXX need to free currently allocated resources here */ + return (ENOMEM); } - return; + err = bus_dmamem_alloc(sc->dmat, (void **)&sc->recv_ring, + BUS_DMA_NOWAIT, &sc->dmamap); + + if (err) { + device_printf(dev, "Couldn't allocate memory\n"); + /* XXX need to free currently allocated resources here */ + return (ENOMEM); + } + + bus_dmamap_load(sc->dmat, sc->dmamap, sc->recv_ring, lnc_mem_size, + lnc_alloc_callback, sc->recv_ring, BUS_DMA_NOWAIT); + + /* Call generic attach code */ + if (! lnc_attach_common(dev)) { + device_printf(dev, "Generic attach code failed\n"); + } + return (0); +} + +static int +lnc_pci_detach(device_t dev) +{ + lnc_softc_t *sc = device_get_softc(dev); + int s = splimp(); + + ether_ifdetach(&sc->arpcom.ac_if, ETHER_BPF_SUPPORTED); + + lnc_stop(sc); + bus_teardown_intr(dev, sc->irqres, sc->intrhand); + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irqres); + bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS, sc->portres); + + bus_dmamap_unload(sc->dmat, sc->dmamap); + bus_dmamem_free(sc->dmat, sc->recv_ring, sc->dmamap); + bus_dma_tag_destroy(sc->dmat); + + splx(s); + return (0); } + +static device_method_t lnc_pci_methods[] = { + DEVMETHOD(device_probe, lnc_pci_probe), + DEVMETHOD(device_attach, lnc_pci_attach), + DEVMETHOD(device_detach, lnc_pci_detach), +#ifdef notyet + DEVMETHOD(device_suspend, lnc_pci_suspend), + DEVMETHOD(device_resume, lnc_pci_resume), + DEVMETHOD(device_shutdown, lnc_pci_shutdown), +#endif + { 0, 0 } +}; + +static driver_t lnc_pci_driver = { + "lnc", + lnc_pci_methods, + sizeof(struct lnc_softc), +}; + +static devclass_t lnc_devclass; + +DRIVER_MODULE(lnc_pci, pci, lnc_pci_driver, lnc_devclass, 0, 0); diff --git a/sys/dev/lnc/if_lncreg.h b/sys/dev/lnc/if_lncreg.h index ae584c2..a57d7ff 100644 --- a/sys/dev/lnc/if_lncreg.h +++ b/sys/dev/lnc/if_lncreg.h @@ -192,3 +192,31 @@ struct mds { #define RTRY 0x0400 /* Tried 16 times */ #define TDR 0x03FF /* Time domain reflectometry */ +/* C-NET(98)S port addresses */ +#define CNET98S_RDP 0x400 /* Register Data Port */ +#define CNET98S_RAP 0x402 /* Register Address Port */ +#define CNET98S_RESET 0x404 +#define CNET98S_IDP 0x406 +#define CNET98S_EEPROM 0x40e +/* + * XXX - The I/O address range is fragmented in the C-NET(98)S. + * This is the number of regs at iobase. + */ +#define CNET98S_IOSIZE 16 /* # of i/o addresses used. */ + +/* ISA Bus Configuration Registers */ +/* XXX - Should be in ic/Am7990.h */ +#define MSRDA 0x0000 /* ISACSR0: Master Mode Read Activity */ +#define MSWRA 0x0001 /* ISACSR1: Master Mode Write Activity */ +#define MC 0x0002 /* ISACSR2: Miscellaneous Configuration */ + +#define LED1 0x0005 /* ISACSR5: LED1 Status */ +#define LED2 0x0006 /* ISACSR6: LED2 Status */ +#define LED3 0x0007 /* ISACSR7: LED3 Status */ + +#define LED_PSE 0x0080 /* Pulse Stretcher */ +#define LED_XMTE 0x0010 /* Transmit Status */ +#define LED_RVPOLE 0x0008 /* Receive Polarity */ +#define LED_RCVE 0x0004 /* Receive Status */ +#define LED_JABE 0x0002 /* Jabber */ +#define LED_COLE 0x0001 /* Collision */ diff --git a/sys/dev/lnc/if_lncvar.h b/sys/dev/lnc/if_lncvar.h index c1ba321..df205ea 100644 --- a/sys/dev/lnc/if_lncvar.h +++ b/sys/dev/lnc/if_lncvar.h @@ -33,6 +33,8 @@ * $FreeBSD$ */ +#include <dev/lnc/if_lncreg.h> + /* * Initialize multicast address hashing registers to accept * all multicasts (only used when in promiscuous mode) @@ -76,6 +78,20 @@ /* DEPCA specific defines */ #define DEPCA_ADDR_ROM_SIZE 32 +#ifdef PC98 +/* C-NET(98)S port addresses */ +#define CNET98S_RDP 0x400 /* Register Data Port */ +#define CNET98S_RAP 0x402 /* Register Address Port */ +#define CNET98S_RESET 0x404 +#define CNET98S_IDP 0x406 +#define CNET98S_EEPROM 0x40e +/* + * XXX - The I/O address range is fragmented in the C-NET(98)S. + * This is the number of regs at iobase. + */ +#define CNET98S_IOSIZE 16 /* # of i/o addresses used. */ +#endif + /* Chip types */ #define LANCE 1 /* Am7990 */ #define C_LANCE 2 /* Am79C90 */ @@ -101,7 +117,7 @@ #define Am79C970A 0x2621 #define Am79C971 0x2623 #define Am79C972 0x2624 -#define Am79C973 0x2625 +#define Am79C972 0x2625 #define Am79C978 0x2626 /* Board types */ @@ -135,22 +151,6 @@ #define TRANS_MD3 \ "\20\6BUFF\5UFLO\4RES\3LCOL\2LCAR\1RTRY" -struct nic_info { - int ident; /* Type of card */ - int ic; /* Type of ic, Am7990, Am79C960 etc. */ - int mem_mode; - int iobase; - int mode; /* Mode setting at initialization */ -}; - -struct host_ring_entry { - struct mds *md; - union { - struct mbuf *mbuf; - char *data; - }buff; -}; - #ifdef LNC_KEEP_STATS #define LNCSTATS_STRUCT \ struct lnc_stats { \ @@ -186,17 +186,38 @@ struct host_ring_entry { #define LNCSTATS(X) #endif +struct nic_info { + int ident; /* Type of card */ + int ic; /* Type of ic, Am7990, Am79C960 etc. */ + int mem_mode; + int iobase; + int mode; /* Mode setting at initialization */ +}; + typedef struct lnc_softc { - struct arpcom arpcom; /* see ../../net/if_arp.h */ - struct nic_info nic; /* NIC specific info */ + struct resource *irqres; + int irqrid; + struct resource *drqres; + int drqrid; + struct resource *portres; + int portrid; + int iobase; + bus_space_tag_t lnc_btag; + bus_space_handle_t lnc_bhandle; + void *intrhand; + bus_dma_tag_t dmat; + bus_dmamap_t dmamap; + struct arpcom arpcom; /* see ../../net/if_arp.h */ + struct nic_info nic; /* NIC specific info */ int nrdre; struct host_ring_entry *recv_ring; /* start of alloc'd mem */ int recv_next; int ntdre; struct host_ring_entry *trans_ring; int trans_next; - struct init_block *init_block; /* Initialisation block */ - int pending_transmits; /* No. of transmit descriptors in use */ + struct init_block *init_block; /* Initialisation block */ + int pending_transmits; /* No. of transmit descriptors in + use */ int next_to_send; struct mbuf *mbufs; int mbuf_count; @@ -204,12 +225,20 @@ typedef struct lnc_softc { int rap; int rdp; int bdp; -#ifdef DEBUG + #ifdef DEBUG int lnc_debug; -#endif + #endif LNCSTATS_STRUCT } lnc_softc_t; +struct host_ring_entry { + struct mds *md; + union { + struct mbuf *mbuf; + char *data; + }buff; +}; + #define NDESC(len2) (1 << len2) #define INC_MD_PTR(ptr, no_entries) \ @@ -223,16 +252,7 @@ typedef struct lnc_softc { #define RECV_NEXT (sc->recv_ring->base + sc->recv_next) #define TRANS_NEXT (sc->trans_ring->base + sc->trans_next) -static __inline void -write_csr(lnc_softc_t *sc, u_short port, u_short val) -{ - outw(sc->rap, port); - outw(sc->rdp, val); -} - -static __inline u_short -read_csr(lnc_softc_t *sc, u_short port) -{ - outw(sc->rap, port); - return (inw(sc->rdp)); -} +/* Functional declarations */ +extern int lnc_attach_common __P((device_t)); +extern void lnc_stop __P((struct lnc_softc *)); +extern driver_intr_t lncintr; |