Make the MI LANCE driver standalone, and use cfattach to resolve

naming conflicts between bus attachments on ports that can have
multiple instances of the LANCE.

Changed struct ifnet to have a pointer to the softc of the underlying
device and a printable "external name" (name + unit number), thus eliminating
if_name and if_unit.  Updated interface to (*if_watchdog)() and (*if_start)()
to take a struct ifnet *, rather than a unit number.
This commit is contained in:
thorpej 1996-05-07 01:38:35 +00:00
parent 69351e2be6
commit 16e78eb3fb
2 changed files with 295 additions and 146 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: am7990.c,v 1.18 1996/04/22 02:40:50 christos Exp $ */
/* $NetBSD: am7990.c,v 1.19 1996/05/07 01:38:35 thorpej Exp $ */
/*-
* Copyright (c) 1995 Charles M. Hannum. All rights reserved.
@ -39,10 +39,23 @@
* @(#)if_le.c 8.2 (Berkeley) 11/16/93
*/
#include "bpfilter.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/syslog.h>
#include <sys/socket.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <net/if.h>
#ifdef INET
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
@ -66,31 +79,81 @@
#include <net/bpfdesc.h>
#endif
#include <dev/ic/am7990reg.h>
#include <dev/ic/am7990var.h>
#ifdef LEDEBUG
void recv_print __P((struct le_softc *, int));
void xmit_print __P((struct le_softc *, int));
void am7990_recv_print __P((struct am7990_softc *, int));
void am7990_xmit_print __P((struct am7990_softc *, int));
#endif
integrate void am7990_rint __P((struct am7990_softc *));
integrate void am7990_tint __P((struct am7990_softc *));
integrate int am7990_put __P((struct am7990_softc *, int, struct mbuf *));
integrate struct mbuf *am7990_get __P((struct am7990_softc *, int, int));
integrate void am7990_read __P((struct am7990_softc *, int, int));
hide void am7990_shutdown __P((void *));
#define ifp (&sc->sc_arpcom.ac_if)
#if 0 /* XXX what do we do about this?! --thorpej */
static inline u_int16_t ether_cmp __P((void *, void *));
/*
* Compare two Ether/802 addresses for equality, inlined and
* unrolled for speed. I'd love to have an inline assembler
* version of this... XXX: Who wanted that? mycroft?
* I wrote one, but the following is just as efficient.
* This expands to 10 short m68k instructions! -gwr
* Note: use this like bcmp()
*/
static inline u_short
ether_cmp(one, two)
void *one, *two;
{
register u_int16_t *a = (u_short *) one;
register u_int16_t *b = (u_short *) two;
register u_int16_t diff;
diff = *a++ - *b++;
diff |= *a++ - *b++;
diff |= *a++ - *b++;
return (diff);
}
#define ETHER_CMP ether_cmp
#endif /* XXX */
#ifndef ETHER_CMP
#define ETHER_CMP(a, b) bcmp((a), (b), ETHER_ADDR_LEN)
#endif
/*
* am7990 configuration driver. Attachments are provided by
* machine-dependent driver front-ends.
*/
struct cfdriver le_cd = {
NULL, "le", DV_IFNET
};
void
leconfig(sc)
struct le_softc *sc;
am7990_config(sc)
struct am7990_softc *sc;
{
int mem;
/* Make sure the chip is stopped. */
lestop(sc);
am7990_stop(sc);
/* Initialize ifnet structure. */
ifp->if_unit = sc->sc_dev.dv_unit;
ifp->if_start = lestart;
ifp->if_ioctl = leioctl;
ifp->if_watchdog = lewatchdog;
bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
ifp->if_softc = sc;
ifp->if_start = am7990_start;
ifp->if_ioctl = am7990_ioctl;
ifp->if_watchdog = am7990_watchdog;
ifp->if_flags =
IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
#ifdef LANCE_REVC_BUG
@ -123,13 +186,17 @@ leconfig(sc)
sc->sc_ntbuf = 8;
break;
default:
panic("leconfig: weird memory size");
panic("am7990_config: weird memory size");
}
printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
printf("%s: %d receive buffers, %d transmit buffers\n",
sc->sc_dev.dv_xname, sc->sc_nrbuf, sc->sc_ntbuf);
sc->sc_sh = shutdownhook_establish(am7990_shutdown, sc);
if (sc->sc_sh == NULL)
panic("am7990_config: can't establish shutdownhook");
mem = 0;
sc->sc_initaddr = mem;
mem += sizeof(struct leinit);
@ -148,34 +215,22 @@ leconfig(sc)
}
void
lereset(sc)
struct le_softc *sc;
am7990_reset(sc)
struct am7990_softc *sc;
{
int s;
s = splimp();
leinit(sc);
am7990_init(sc);
splx(s);
}
void
lewatchdog(unit)
int unit;
{
struct le_softc *sc = LE_SOFTC(unit);
log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
++ifp->if_oerrors;
lereset(sc);
}
/*
* Set up the initialization block and the descriptor rings.
*/
void
lememinit(sc)
register struct le_softc *sc;
am7990_meminit(sc)
register struct am7990_softc *sc;
{
u_long a;
int bix;
@ -195,7 +250,7 @@ lememinit(sc)
(sc->sc_arpcom.ac_enaddr[3] << 8) | sc->sc_arpcom.ac_enaddr[2];
init.init_padr[2] =
(sc->sc_arpcom.ac_enaddr[5] << 8) | sc->sc_arpcom.ac_enaddr[4];
lesetladrf(&sc->sc_arpcom, init.init_ladrf);
am7990_setladrf(&sc->sc_arpcom, init.init_ladrf);
sc->sc_last_rd = 0;
sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;
@ -240,11 +295,11 @@ lememinit(sc)
}
void
lestop(sc)
struct le_softc *sc;
am7990_stop(sc)
struct am7990_softc *sc;
{
lewrcsr(sc, LE_CSR0, LE_C0_STOP);
(*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_STOP);
}
/*
@ -252,45 +307,47 @@ lestop(sc)
* and transmit/receive descriptor rings.
*/
void
leinit(sc)
register struct le_softc *sc;
am7990_init(sc)
register struct am7990_softc *sc;
{
register int timo;
u_long a;
lewrcsr(sc, LE_CSR0, LE_C0_STOP);
LE_DELAY(100);
(*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_STOP);
DELAY(100);
/* Set the correct byte swapping mode, etc. */
lewrcsr(sc, LE_CSR3, sc->sc_conf3);
(*sc->sc_wrcsr)(sc, LE_CSR3, sc->sc_conf3);
/* Set up LANCE init block. */
lememinit(sc);
am7990_meminit(sc);
/* Give LANCE the physical address of its init block. */
a = sc->sc_addr + LE_INITADDR(sc);
lewrcsr(sc, LE_CSR1, a);
lewrcsr(sc, LE_CSR2, a >> 16);
(*sc->sc_wrcsr)(sc, LE_CSR1, a);
(*sc->sc_wrcsr)(sc, LE_CSR2, a >> 16);
/* Try to initialize the LANCE. */
LE_DELAY(100);
lewrcsr(sc, LE_CSR0, LE_C0_INIT);
DELAY(100);
(*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INIT);
/* Wait for initialization to finish. */
for (timo = 100000; timo; timo--)
if (lerdcsr(sc, LE_CSR0) & LE_C0_IDON)
if ((*sc->sc_rdcsr)(sc, LE_CSR0) & LE_C0_IDON)
break;
if (lerdcsr(sc, LE_CSR0) & LE_C0_IDON) {
if ((*sc->sc_rdcsr)(sc, LE_CSR0) & LE_C0_IDON) {
/* Start the LANCE. */
lewrcsr(sc, LE_CSR0, LE_C0_INEA | LE_C0_STRT | LE_C0_IDON);
(*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_STRT |
LE_C0_IDON);
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
ifp->if_timer = 0;
lestart(ifp);
am7990_start(ifp);
} else
printf("%s: card failed to initialize\n", sc->sc_dev.dv_xname);
lehwinit(sc);
if (sc->sc_hwinit)
(*sc->sc_hwinit)(sc);
}
/*
@ -298,8 +355,8 @@ leinit(sc)
* network buffer memory.
*/
integrate int
leput(sc, boff, m)
struct le_softc *sc;
am7990_put(sc, boff, m)
struct am7990_softc *sc;
int boff;
register struct mbuf *m;
{
@ -331,8 +388,8 @@ leput(sc, boff, m)
* we copy into clusters.
*/
integrate struct mbuf *
leget(sc, boff, totlen)
struct le_softc *sc;
am7990_get(sc, boff, totlen)
struct am7990_softc *sc;
int boff, totlen;
{
register struct mbuf *m;
@ -379,8 +436,8 @@ leget(sc, boff, totlen)
* Pass a packet to the higher levels.
*/
integrate void
leread(sc, boff, len)
register struct le_softc *sc;
am7990_read(sc, boff, len)
register struct am7990_softc *sc;
int boff, len;
{
struct mbuf *m;
@ -397,7 +454,7 @@ leread(sc, boff, len)
}
/* Pull packet off interface. */
m = leget(sc, boff, len);
m = am7990_get(sc, boff, len);
if (m == 0) {
ifp->if_ierrors++;
return;
@ -453,8 +510,8 @@ leread(sc, boff, len)
}
integrate void
lerint(sc)
struct le_softc *sc;
am7990_rint(sc)
struct am7990_softc *sc;
{
register int bix;
int rp;
@ -499,9 +556,10 @@ lerint(sc)
} else {
#ifdef LEDEBUG
if (sc->sc_debug)
recv_print(sc, sc->sc_last_rd);
am7990_recv_print(sc, sc->sc_last_rd);
#endif
leread(sc, LE_RBUFADDR(sc, bix), (int)rmd.rmd3 - 4);
am7990_read(sc, LE_RBUFADDR(sc, bix),
(int)rmd.rmd3 - 4);
}
rmd.rmd1_bits = LE_R1_OWN;
@ -527,8 +585,8 @@ lerint(sc)
}
integrate void
letint(sc)
register struct le_softc *sc;
am7990_tint(sc)
register struct am7990_softc *sc;
{
register int bix;
struct letmd tmd;
@ -558,20 +616,23 @@ letint(sc)
if (tmd.tmd1_bits & LE_T1_ERR) {
if (tmd.tmd3 & LE_T3_BUFF)
printf("%s: transmit buffer error\n", sc->sc_dev.dv_xname);
printf("%s: transmit buffer error\n",
sc->sc_dev.dv_xname);
else if (tmd.tmd3 & LE_T3_UFLO)
printf("%s: underflow\n", sc->sc_dev.dv_xname);
if (tmd.tmd3 & (LE_T3_BUFF | LE_T3_UFLO)) {
lereset(sc);
am7990_reset(sc);
return;
}
if (tmd.tmd3 & LE_T3_LCAR)
printf("%s: lost carrier\n", sc->sc_dev.dv_xname);
printf("%s: lost carrier\n",
sc->sc_dev.dv_xname);
if (tmd.tmd3 & LE_T3_LCOL)
ifp->if_collisions++;
if (tmd.tmd3 & LE_T3_RTRY) {
printf("%s: excessive collisions, tdr %d\n",
sc->sc_dev.dv_xname, tmd.tmd3 & LE_T3_TDR_MASK);
sc->sc_dev.dv_xname,
tmd.tmd3 & LE_T3_TDR_MASK);
ifp->if_collisions += 16;
}
ifp->if_oerrors++;
@ -592,7 +653,7 @@ letint(sc)
sc->sc_first_td = bix;
lestart(ifp);
am7990_start(ifp);
if (sc->sc_no_td == 0)
ifp->if_timer = 0;
@ -602,22 +663,22 @@ letint(sc)
* Controller interrupt.
*/
int
leintr(arg)
am7990_intr(arg)
register void *arg;
{
register struct le_softc *sc = arg;
register struct am7990_softc *sc = arg;
register u_int16_t isr;
isr = lerdcsr(sc, LE_CSR0);
isr = (*sc->sc_rdcsr)(sc, LE_CSR0);
#ifdef LEDEBUG
if (sc->sc_debug)
printf("%s: leintr entering with isr=%04x\n",
printf("%s: am7990_intr entering with isr=%04x\n",
sc->sc_dev.dv_xname, isr);
#endif
if ((isr & LE_C0_INTR) == 0)
return (0);
lewrcsr(sc, LE_CSR0,
(*sc->sc_wrcsr)(sc, LE_CSR0,
isr & (LE_C0_INEA | LE_C0_BABL | LE_C0_MISS | LE_C0_MERR |
LE_C0_RINT | LE_C0_TINT | LE_C0_IDON));
if (isr & LE_C0_ERR) {
@ -641,7 +702,7 @@ leintr(arg)
}
if (isr & LE_C0_MERR) {
printf("%s: memory error\n", sc->sc_dev.dv_xname);
lereset(sc);
am7990_reset(sc);
return (1);
}
}
@ -649,26 +710,38 @@ leintr(arg)
if ((isr & LE_C0_RXON) == 0) {
printf("%s: receiver disabled\n", sc->sc_dev.dv_xname);
ifp->if_ierrors++;
lereset(sc);
am7990_reset(sc);
return (1);
}
if ((isr & LE_C0_TXON) == 0) {
printf("%s: transmitter disabled\n", sc->sc_dev.dv_xname);
ifp->if_oerrors++;
lereset(sc);
am7990_reset(sc);
return (1);
}
if (isr & LE_C0_RINT)
lerint(sc);
am7990_rint(sc);
if (isr & LE_C0_TINT)
letint(sc);
am7990_tint(sc);
return (1);
}
#undef ifp
void
am7990_watchdog(ifp)
struct ifnet *ifp;
{
struct am7990_softc *sc = ifp->if_softc;
log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
++ifp->if_oerrors;
am7990_reset(sc);
}
/*
* Setup output on interface.
* Get another datagram to send off of the interface queue, and map it to the
@ -676,10 +749,10 @@ leintr(arg)
* Called only at splimp or interrupt level.
*/
void
lestart(ifp)
am7990_start(ifp)
register struct ifnet *ifp;
{
register struct le_softc *sc = LE_SOFTC(ifp->if_unit);
register struct am7990_softc *sc = ifp->if_softc;
register int bix;
register struct mbuf *m;
struct letmd tmd;
@ -717,7 +790,7 @@ lestart(ifp)
/*
* Copy the mbuf chain into the transmit buffer.
*/
len = leput(sc, LE_TBUFADDR(sc, bix), m);
len = am7990_put(sc, LE_TBUFADDR(sc, bix), m);
#ifdef LEDEBUG
if (len > ETHERMTU + sizeof(struct ether_header))
@ -737,10 +810,10 @@ lestart(ifp)
#ifdef LEDEBUG
if (sc->sc_debug)
xmit_print(sc, sc->sc_last_td);
am7990_xmit_print(sc, sc->sc_last_td);
#endif
lewrcsr(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD);
(*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD);
if (++bix == sc->sc_ntbuf)
bix = 0;
@ -759,12 +832,12 @@ lestart(ifp)
* Process an ioctl request.
*/
int
leioctl(ifp, cmd, data)
am7990_ioctl(ifp, cmd, data)
register struct ifnet *ifp;
u_long cmd;
caddr_t data;
{
struct le_softc *sc = LE_SOFTC(ifp->if_unit);
register struct am7990_softc *sc = ifp->if_softc;
struct ifaddr *ifa = (struct ifaddr *)data;
struct ifreq *ifr = (struct ifreq *)data;
int s, error = 0;
@ -779,7 +852,7 @@ leioctl(ifp, cmd, data)
switch (ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET:
leinit(sc);
am7990_init(sc);
arp_ifinit(&sc->sc_arpcom, ifa);
break;
#endif
@ -796,12 +869,12 @@ leioctl(ifp, cmd, data)
sc->sc_arpcom.ac_enaddr,
sizeof(sc->sc_arpcom.ac_enaddr));
/* Set new address. */
leinit(sc);
am7990_init(sc);
break;
}
#endif
default:
leinit(sc);
am7990_init(sc);
break;
}
break;
@ -812,7 +885,7 @@ leioctl(ifp, cmd, data)
ifa->ifa_rtrequest = cons_rtrequest; /* XXX */
error = x25_llcglue(PRC_IFUP, ifa->ifa_addr);
if (error == 0)
leinit(sc);
am7990_init(sc);
break;
#endif /* CCITT && LLC */
@ -823,7 +896,7 @@ leioctl(ifp, cmd, data)
* If interface is marked down and it is running, then
* stop it.
*/
lestop(sc);
am7990_stop(sc);
ifp->if_flags &= ~IFF_RUNNING;
} else if ((ifp->if_flags & IFF_UP) != 0 &&
(ifp->if_flags & IFF_RUNNING) == 0) {
@ -831,14 +904,14 @@ leioctl(ifp, cmd, data)
* If interface is marked up and it is stopped, then
* start it.
*/
leinit(sc);
am7990_init(sc);
} else {
/*
* Reset the interface to pick up changes in any other
* flags that affect hardware registers.
*/
/*lestop(sc);*/
leinit(sc);
/*am7990_stop(sc);*/
am7990_init(sc);
}
#ifdef LEDEBUG
if (ifp->if_flags & IFF_DEBUG)
@ -859,7 +932,7 @@ leioctl(ifp, cmd, data)
* Multicast list has changed; set the hardware filter
* accordingly.
*/
lereset(sc);
am7990_reset(sc);
error = 0;
}
break;
@ -873,10 +946,18 @@ leioctl(ifp, cmd, data)
return (error);
}
hide void
am7990_shutdown(arg)
void *arg;
{
am7990_stop((struct am7990_softc *)arg);
}
#ifdef LEDEBUG
void
recv_print(sc, no)
struct le_softc *sc;
am7990_recv_print(sc, no)
struct am7990_softc *sc;
int no;
{
struct lermd rmd;
@ -887,7 +968,8 @@ recv_print(sc, no)
len = rmd.rmd3;
printf("%s: receive buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
len);
printf("%s: status %04x\n", sc->sc_dev.dv_xname, lerdcsr(sc, LE_CSR0));
printf("%s: status %04x\n", sc->sc_dev.dv_xname,
(*sc->sc_rdcsr)(sc, LE_CSR0));
printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
sc->sc_dev.dv_xname,
rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits, rmd.rmd2, rmd.rmd3);
@ -901,8 +983,8 @@ recv_print(sc, no)
}
void
xmit_print(sc, no)
struct le_softc *sc;
am7990_xmit_print(sc, no)
struct am7990_softc *sc;
int no;
{
struct letmd tmd;
@ -913,7 +995,8 @@ xmit_print(sc, no)
len = -tmd.tmd2;
printf("%s: transmit buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
len);
printf("%s: status %04x\n", sc->sc_dev.dv_xname, lerdcsr(sc, LE_CSR0));
printf("%s: status %04x\n", sc->sc_dev.dv_xname,
(*sc->sc_rdcsr)(sc, LE_CSR0));
printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
sc->sc_dev.dv_xname,
tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, tmd.tmd2, tmd.tmd3);
@ -931,7 +1014,7 @@ xmit_print(sc, no)
* Set up the logical address filter.
*/
void
lesetladrf(ac, af)
am7990_setladrf(ac, af)
struct arpcom *ac;
u_int16_t *af;
{
@ -1008,7 +1091,6 @@ allmulti:
* (3) gap16 (16 bytes of data followed by 16 bytes of padding).
*/
#ifdef LE_NEED_BUF_CONTIG
/*
* contig: contiguous data with no padding.
*
@ -1017,7 +1099,7 @@ allmulti:
void
am7990_copytobuf_contig(sc, from, boff, len)
struct le_softc *sc;
struct am7990_softc *sc;
void *from;
int boff, len;
{
@ -1031,7 +1113,7 @@ am7990_copytobuf_contig(sc, from, boff, len)
void
am7990_copyfrombuf_contig(sc, to, boff, len)
struct le_softc *sc;
struct am7990_softc *sc;
void *to;
int boff, len;
{
@ -1045,7 +1127,7 @@ am7990_copyfrombuf_contig(sc, to, boff, len)
void
am7990_zerobuf_contig(sc, boff, len)
struct le_softc *sc;
struct am7990_softc *sc;
int boff, len;
{
volatile caddr_t buf = sc->sc_mem;
@ -1055,9 +1137,13 @@ am7990_zerobuf_contig(sc, boff, len)
*/
bzero(buf + boff, len);
}
#endif /* LE_NEED_BUF_CONTIG */
#ifdef LE_NEED_BUF_GAP2
#if 0
/*
* Examples only; duplicate these and tweak (if necessary) in
* machine-specific front-ends.
*/
/*
* gap2: two bytes of data followed by two bytes of pad.
*
@ -1067,7 +1153,7 @@ am7990_zerobuf_contig(sc, boff, len)
void
am7990_copytobuf_gap2(sc, fromv, boff, len)
struct le_softc *sc;
struct am7990_softc *sc;
void *fromv;
int boff;
register int len;
@ -1096,7 +1182,7 @@ am7990_copytobuf_gap2(sc, fromv, boff, len)
void
am7990_copyfrombuf_gap2(sc, tov, boff, len)
struct le_softc *sc;
struct am7990_softc *sc;
void *tov;
int boff, len;
{
@ -1126,7 +1212,7 @@ am7990_copyfrombuf_gap2(sc, tov, boff, len)
void
am7990_zerobuf_gap2(sc, boff, len)
struct le_softc *sc;
struct am7990_softc *sc;
int boff, len;
{
volatile caddr_t buf = sc->sc_mem;
@ -1145,9 +1231,7 @@ am7990_zerobuf_gap2(sc, boff, len)
len -= 2;
}
}
#endif /* LE_NEED_BUF_GAP2 */
#ifdef LE_NEED_BUF_GAP16
/*
* gap16: 16 bytes of data followed by 16 bytes of pad.
*
@ -1156,7 +1240,7 @@ am7990_zerobuf_gap2(sc, boff, len)
void
am7990_copytobuf_gap16(sc, fromv, boff, len)
struct le_softc *sc;
struct am7990_softc *sc;
void *fromv;
int boff;
register int len;
@ -1181,7 +1265,7 @@ am7990_copytobuf_gap16(sc, fromv, boff, len)
void
am7990_copyfrombuf_gap16(sc, tov, boff, len)
struct le_softc *sc;
struct am7990_softc *sc;
void *tov;
int boff, len;
{
@ -1205,7 +1289,7 @@ am7990_copyfrombuf_gap16(sc, tov, boff, len)
void
am7990_zerobuf_gap16(sc, boff, len)
struct le_softc *sc;
struct am7990_softc *sc;
int boff, len;
{
volatile caddr_t buf = sc->sc_mem;
@ -1223,4 +1307,4 @@ am7990_zerobuf_gap16(sc, boff, len)
xfer = min(len, 16);
}
}
#endif /* LE_NEED_BUF_GAP16 */
#endif /* Example only */

View File

@ -1,4 +1,4 @@
/* $NetBSD: am7990var.h,v 1.6 1996/04/22 02:40:49 christos Exp $ */
/* $NetBSD: am7990var.h,v 1.7 1996/05/07 01:38:37 thorpej Exp $ */
/*
* Copyright (c) 1995 Charles M. Hannum. All rights reserved.
@ -31,30 +31,97 @@
#ifdef DDB
#define integrate
#define hide
#else
#define integrate static __inline
#define hide static
#endif
void leconfig __P((struct le_softc *));
void leinit __P((struct le_softc *));
int leioctl __P((struct ifnet *, u_long, caddr_t));
void lememinit __P((struct le_softc *));
void lereset __P((struct le_softc *));
void lesetladrf __P((struct arpcom *, u_int16_t *));
void lestart __P((struct ifnet *));
void lestop __P((struct le_softc *));
void lewatchdog __P((int));
/*
* Ethernet software status per device.
*
* Each interface is referenced by a network interface structure,
* arpcom.ac_if, which the routing code uses to locate the interface.
* This structure contains the output queue for the interface, its address, ...
*
* NOTE: this structure MUST be the first element in machine-dependent
* le_softc structures! This is designed SPECIFICALLY to make it possible
* to simply cast a "void *" to "struct le_softc *" or to
* "struct am7990_softc *". Among other things, this saves a lot of hair
* in the interrupt handlers.
*/
struct am7990_softc {
struct device sc_dev; /* base device glue */
struct arpcom sc_arpcom; /* Ethernet common part */
integrate void lehwinit __P((struct le_softc *));
integrate u_int16_t lerdcsr __P((struct le_softc *, u_int16_t));
integrate void lewrcsr __P((struct le_softc *, u_int16_t, u_int16_t));
/*
* Memory functions:
*
* copy to/from descriptor
* copy to/from buffer
* zero bytes in buffer
*/
void (*sc_copytodesc)
__P((struct am7990_softc *, void *, int, int));
void (*sc_copyfromdesc)
__P((struct am7990_softc *, void *, int, int));
void (*sc_copytobuf)
__P((struct am7990_softc *, void *, int, int));
void (*sc_copyfrombuf)
__P((struct am7990_softc *, void *, int, int));
void (*sc_zerobuf)
__P((struct am7990_softc *, int, int));
integrate void lerint __P((struct le_softc *));
integrate void letint __P((struct le_softc *));
/*
* Machine-dependent functions:
*
* read/write CSR
* hardware init hook - may be NULL
*/
u_int16_t (*sc_rdcsr)
__P((struct am7990_softc *, u_int16_t));
void (*sc_wrcsr)
__P((struct am7990_softc *, u_int16_t, u_int16_t));
void (*sc_hwinit) __P((struct am7990_softc *));
integrate int leput __P((struct le_softc *, int, struct mbuf *));
integrate struct mbuf *leget __P((struct le_softc *, int, int));
integrate void leread __P((struct le_softc *, int, int));
void *sc_sh; /* shutdownhook cookie */
u_int16_t sc_conf3; /* CSR3 value */
void *sc_mem; /* base address of RAM -- CPU's view */
u_long sc_addr; /* base address of RAM -- LANCE's view */
u_long sc_memsize; /* size of RAM */
int sc_nrbuf; /* number of receive buffers */
int sc_ntbuf; /* number of transmit buffers */
int sc_last_rd;
int sc_first_td, sc_last_td, sc_no_td;
int sc_initaddr;
int sc_rmdaddr;
int sc_tmdaddr;
int sc_rbufaddr;
int sc_tbufaddr;
#ifdef LEDEBUG
int sc_debug;
#endif
};
/* Export this to machine-dependent drivers. */
extern struct cfdriver le_cd;
void am7990_config __P((struct am7990_softc *));
void am7990_init __P((struct am7990_softc *));
int am7990_ioctl __P((struct ifnet *, u_long, caddr_t));
void am7990_meminit __P((struct am7990_softc *));
void am7990_reset __P((struct am7990_softc *));
void am7990_setladrf __P((struct arpcom *, u_int16_t *));
void am7990_start __P((struct ifnet *));
void am7990_stop __P((struct am7990_softc *));
void am7990_watchdog __P((struct ifnet *));
int am7990_intr __P((void *));
/*
* The following functions are only useful on certain cpu/bus
@ -62,18 +129,16 @@ integrate void leread __P((struct le_softc *, int, int));
* maximum efficiency, but machine-independent versions are provided
* for drivers that have not yet been optimized.
*/
#ifdef LE_NEED_BUF_CONTIG
void am7990_copytobuf_contig __P((struct le_softc *, void *, int, int));
void am7990_copyfrombuf_contig __P((struct le_softc *, void *, int, int));
void am7990_zerobuf_contig __P((struct le_softc *, int, int));
#endif /* LE_NEED_BUF_CONTIG */
#ifdef LE_NEED_BUF_GAP2
void am7990_copytobuf_gap2 __P((struct le_softc *, void *, int, int));
void am7990_copyfrombuf_gap2 __P((struct le_softc *, void *, int, int));
void am7990_zerobuf_gap2 __P((struct le_softc *, int, int));
#endif /* LE_NEED_BUF_GAP2 */
#ifdef LE_NEED_BUF_GAP16
void am7990_copytobuf_gap16 __P((struct le_softc *, void *, int, int));
void am7990_copyfrombuf_gap16 __P((struct le_softc *, void *, int, int));
void am7990_zerobuf_gap16 __P((struct le_softc *, int, int));
#endif /* LE_NEED_BUF_GAP16 */
void am7990_copytobuf_contig __P((struct am7990_softc *, void *, int, int));
void am7990_copyfrombuf_contig __P((struct am7990_softc *, void *, int, int));
void am7990_zerobuf_contig __P((struct am7990_softc *, int, int));
#if 0 /* Example only - see am7990.c */
void am7990_copytobuf_gap2 __P((struct am7990_softc *, void *, int, int));
void am7990_copyfrombuf_gap2 __P((struct am7990_softc *, void *, int, int));
void am7990_zerobuf_gap2 __P((struct am7990_softc *, int, int));
void am7990_copytobuf_gap16 __P((struct am7990_softc *, void *, int, int));
void am7990_copyfrombuf_gap16 __P((struct am7990_softc *, void *, int, int));
void am7990_zerobuf_gap16 __P((struct am7990_softc *, int, int));
#endif /* Example only */