Newbusify.

Temporarily disable PC98 until I bring it up to date.
This commit is contained in:
Paul Richards 2000-12-16 01:33:28 +00:00
parent 6aa623bf53
commit 232b06012c
6 changed files with 644 additions and 561 deletions

View File

@ -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;
int unit = device_get_unit(dev);
lnc_softc_t *sc = device_get_softc(dev);
int i;
int skip;
/*
* 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
}
}
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;

View File

@ -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,190 +31,41 @@
*/
#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 struct isa_pnp_id lnc_pnp_ids[] = {
{0, NULL}
};
static int dec_macaddr_extract __P((u_char[], lnc_softc_t *));
static ointhand2_t lncintr;
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);
extern int lnc_attach_sc __P((lnc_softc_t *, int));
extern void lncintr_sc __P((lnc_softc_t *));
static lnc_softc_t *
lnc_getsoftc(int unit)
{
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);
return sc[unit];
}
int
ne2100_probe(lnc_softc_t *sc, unsigned iobase)
{
int i;
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;
/* 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);
}
}
int
bicc_probe(lnc_softc_t *sc, unsigned iobase)
{
int i;
/*
* There isn't any way to determine if a NIC is a BICC. Basically, if
* the lance probe succeeds using the i/o addresses of the BICC then
* we assume it's a BICC.
*
*/
sc->rap = iobase + BICC_RAP;
sc->rdp = iobase + BICC_RDP;
/* I think all these cards us the Am7990 */
if ((sc->nic.ic = lance_probe(sc))) {
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);
} else {
return (0);
}
}
/*
* 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)
{
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);
}
}
return (0);
}
int
depca_probe(lnc_softc_t *sc, unsigned iobase)
{
int i;
unsigned char maddr_ring[DEPCA_ADDR_ROM_SIZE];
sc->rap = iobase + DEPCA_RAP;
sc->rdp = iobase + DEPCA_RDP;
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);
}
}
return (0);
}
int
lance_probe(lnc_softc_t *sc)
lance_probe(struct lnc_softc *sc)
{
write_csr(sc, CSR0, STOP);
if ((inw(sc->rdp) & STOP) && !(read_csr(sc, CSR3))) {
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
@ -229,105 +80,237 @@ lance_probe(lnc_softc_t *sc)
return (UNKNOWN);
}
int
pcnet_probe(lnc_softc_t *sc)
static int
lnc_legacy_probe(device_t dev)
{
u_long chip_id;
int type;
struct lnc_softc *sc = device_get_softc(dev);
/*
* 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->portrid = 0;
sc->portres = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->portrid,
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->portres) {
device_printf(dev, "Failed to allocate I/O ports\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;
sc->lnc_btag = rman_get_bustag(sc->portres);
sc->lnc_bhandle = rman_get_bushandle(sc->portres);
#ifdef DIAGNOSTIC
int vsw;
vsw = inw(isa_dev->id_iobase + PCNET_VSW);
printf("Vendor Specific Word = %x\n", vsw);
#endif
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);
}
int
lnc_attach(struct isa_device * isa_dev)
{
int unit = isa_dev->id_unit;
lnc_softc_t *sc = lnc_getsoftc(unit);
int result;
isa_dev->id_ointr = lncintr;
result = lnc_attach_sc (sc, unit);
if (result == 0)
return (0);
#ifndef PC98
/*
* XXX - is it safe to call isa_dmacascade() after
* ether_ifattach() has been called in lnc_attach() ???
* There isn't any way to determine if a NIC is a BICC. Basically, if
* the lance probe succeeds using the i/o addresses of the BICC then
* we assume it's a BICC.
*
*/
if ((sc->nic.mem_mode != SHMEM) &&
(sc->nic.ic < PCnet_32))
isa_dmacascade(isa_dev->id_drq);
#endif
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 */
return result;
if ((sc->nic.ic = lance_probe(sc))) {
device_set_desc(dev, "BICC Isolan");
sc->nic.ident = BICC;
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);
}
}
}
static int
lnc_isa_probe(device_t dev)
{
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);
}
}
static void
lncintr(int unit)
lnc_alloc_callback(void *arg, bus_dma_segment_t *seg, int nseg, int error)
{
lncintr_sc(lnc_getsoftc(unit));
/* Do nothing */
return;
}
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;
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);
}
sc->drqrid = 0;
sc->drqres = bus_alloc_resource(dev, SYS_RES_DRQ, &sc->drqrid,
0, ~0, 1, RF_ACTIVE);
if (! sc->drqres) {
device_printf(dev, "Failed to allocate DMA channel\n");
lnc_release_resources(dev);
return (ENXIO);
}
if (isa_get_irq(dev) == -1)
bus_set_resource(dev, SYS_RES_IRQ, 0, 10, 1);
sc->irqrid = 0;
sc->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqrid, 0, ~0, 1,
RF_ACTIVE);
if (! sc->irqres) {
device_printf(dev, "Failed to allocate irq\n");
lnc_release_resources(dev);
return (ENXIO);
}
err = bus_setup_intr(dev, sc->irqres, INTR_TYPE_NET, lncintr,
sc, &sc->intrhand);
if (err) {
device_printf(dev, "Failed to setup irq handler\n");
lnc_release_resources(dev);
return (err);
}
/* XXX temp setting for nic */
sc->nic.mem_mode = DMA_FIXED;
sc->nrdre = NRDRE;
sc->ntdre = NTDRE;
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;
}
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));
/* 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 int
lnc_isa_detach(device_t dev)
{
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);

View File

@ -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 */

View File

@ -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 <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_arp.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#include <sys/socket.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <dev/lnc/if_lnc.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#define AMD_VENDOR_ID 0x1022
#define PCI_DEVICE_ID_PCNet_PCI 0x2000
#define PCI_DEVICE_ID_PCHome_PCI 0x2001
#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
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;
static struct pci_device lnc_pci_driver = {
"lnc",
lnc_pci_probe,
lnc_pci_attach,
&lnc_pci_count,
NULL
};
COMPAT_PCI_DRIVER (lnc_pci, lnc_pci_driver);
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 (ENXIO);
}
static void
lnc_alloc_callback(void *arg, bus_dma_segment_t *seg, int nseg, int error)
{
/* 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);
}
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);
}
void lncintr_sc (void*);
static void
lnc_pci_attach(config_id, unit)
pcici_t config_id;
int unit;
static int
lnc_pci_detach(device_t dev)
{
lnc_softc_t *sc;
unsigned iobase;
unsigned data; /* scratch to make this device a bus master*/
int i;
lnc_softc_t *sc = device_get_softc(dev);
int s = splimp();
if ( !pci_map_port(config_id,PCI_MAP_REG_START,(u_short *)&iobase) )
printf("lnc%d: pci_port_map_attach failed?!\n",unit);
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);
/* Make this device a bus master. This was implictly done by
pci_map_port under 2.2.x -- tvf */
bus_dmamap_unload(sc->dmat, sc->dmamap);
bus_dmamem_free(sc->dmat, sc->recv_ring, sc->dmamap);
bus_dma_tag_destroy(sc->dmat);
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);
}
}
return;
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);

View File

@ -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 */

View File

@ -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;