Changes from Denny Gentry <denny1@home.com>:
Change in the way receive buffer areas are handled. Before we gave the chip 16 buffers, each 1536 bytes (big enough for one packet). Now we're handing the chip 8 buffers, each 4 Kbytes, and letting the chip fit as many packets as it can in each one. This should help keep it from running out of buffer space. Also make some of the performance-crucial routines inline. It made no measurable difference except to make me feel better Changes from Bob Nestor <rnestor@metronet.com> to get closer to support for his Apple SONIC-based nubus card. Changes from me to try to get SONIC's MAC address from MacOS settings if we can't read the PROM space.
This commit is contained in:
parent
574874a2a9
commit
6287b4096d
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_sn.c,v 1.8 1997/03/30 19:51:44 briggs Exp $ */
|
||||
/* $NetBSD: if_sn.c,v 1.9 1997/04/10 03:22:45 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* National Semiconductor SONIC Driver
|
||||
@ -59,7 +59,7 @@ typedef unsigned char uchar;
|
||||
static void snwatchdog __P((struct ifnet *));
|
||||
static int sninit __P((struct sn_softc *sc));
|
||||
static int snstop __P((struct sn_softc *sc));
|
||||
static int sonicput __P((struct sn_softc *sc, struct mbuf *m0));
|
||||
static inline int sonicput __P((struct sn_softc *sc, struct mbuf *m0));
|
||||
static int snioctl __P((struct ifnet *ifp, u_long cmd, caddr_t data));
|
||||
static void snstart __P((struct ifnet *ifp));
|
||||
static void snreset __P((struct sn_softc *sc));
|
||||
@ -130,10 +130,10 @@ snsetup(sc, lladdr)
|
||||
* Put the pup in reset mode (sninit() will fix it later),
|
||||
* stop the timer, disable all interrupts and clear any interrupts.
|
||||
*/
|
||||
NIC_PUT(sc, SNR_CR, CR_RST);
|
||||
wbflush();
|
||||
NIC_PUT(sc, SNR_CR, CR_STP);
|
||||
wbflush();
|
||||
NIC_PUT(sc, SNR_CR, CR_RST);
|
||||
wbflush();
|
||||
NIC_PUT(sc, SNR_IMR, 0);
|
||||
wbflush();
|
||||
NIC_PUT(sc, SNR_ISR, ISR_ALL);
|
||||
@ -206,9 +206,8 @@ snsetup(sc, lladdr)
|
||||
|
||||
p = pp + NBPG;
|
||||
|
||||
for (i = 0; i < NRBA; i+=2) {
|
||||
for (i = 0; i < NRBA; i++) {
|
||||
sc->rbuf[i] = (caddr_t) p;
|
||||
sc->rbuf[i+1] = (caddr_t)(p + (NBPG/2));
|
||||
p += NBPG;
|
||||
}
|
||||
|
||||
@ -542,7 +541,7 @@ snwatchdog(ifp)
|
||||
/*
|
||||
* stuff packet into sonic (at splnet)
|
||||
*/
|
||||
static int
|
||||
static inline int
|
||||
sonicput(sc, m0)
|
||||
struct sn_softc *sc;
|
||||
struct mbuf *m0;
|
||||
@ -632,8 +631,8 @@ sonicput(sc, m0)
|
||||
static void sonictxint __P((struct sn_softc *));
|
||||
static void sonicrxint __P((struct sn_softc *));
|
||||
|
||||
static int sonic_read __P((struct sn_softc *, caddr_t, int));
|
||||
static struct mbuf *sonic_get __P((struct sn_softc *, struct ether_header *, int));
|
||||
static inline int sonic_read __P((struct sn_softc *, caddr_t, int));
|
||||
static inline struct mbuf *sonic_get __P((struct sn_softc *, struct ether_header *, int));
|
||||
|
||||
/*
|
||||
* CAM support
|
||||
@ -829,10 +828,11 @@ initialise_rra(sc)
|
||||
unsigned int v;
|
||||
int bitmode = sc->bitmode;
|
||||
|
||||
if (bitmode) /* eobc must be >= MAXETHERPKT */
|
||||
if (bitmode)
|
||||
NIC_PUT(sc, SNR_EOBC, RBASIZE(sc) / 2 - 2);
|
||||
else
|
||||
NIC_PUT(sc, SNR_EOBC, RBASIZE(sc) / 2 - 1);
|
||||
|
||||
NIC_PUT(sc, SNR_URRA, UPPER(sc->v_rra[0]));
|
||||
NIC_PUT(sc, SNR_RSA, LOWER(sc->v_rra[0]));
|
||||
/* rea must point just past the end of the rra space */
|
||||
@ -844,8 +844,8 @@ initialise_rra(sc)
|
||||
v = kvtop(sc->rbuf[i]);
|
||||
SWO(bitmode, sc->p_rra[i], RXRSRC_PTRHI, UPPER(v));
|
||||
SWO(bitmode, sc->p_rra[i], RXRSRC_PTRLO, LOWER(v));
|
||||
SWO(bitmode, sc->p_rra[i], RXRSRC_WCHI, UPPER(RBASIZE(sc) / 2));
|
||||
SWO(bitmode, sc->p_rra[i], RXRSRC_WCLO, LOWER(RBASIZE(sc) / 2));
|
||||
SWO(bitmode, sc->p_rra[i], RXRSRC_WCHI, UPPER(NBPG/2));
|
||||
SWO(bitmode, sc->p_rra[i], RXRSRC_WCLO, LOWER(NBPG/2));
|
||||
}
|
||||
sc->sc_rramark = NRBA;
|
||||
NIC_PUT(sc, SNR_RWP, LOWER(sc->v_rra[sc->sc_rramark]));
|
||||
@ -874,11 +874,11 @@ snintr(arg, slot)
|
||||
NIC_PUT(sc, SNR_ISR, isr);
|
||||
wbflush();
|
||||
|
||||
if (isr & (ISR_BR | ISR_LCD | ISR_PINT | ISR_TC))
|
||||
if (isr & (ISR_BR | ISR_LCD | ISR_TC))
|
||||
printf("%s: unexpected interrupt status 0x%x\n",
|
||||
sc->sc_dev.dv_xname, isr);
|
||||
|
||||
if (isr & (ISR_TXDN | ISR_TXER))
|
||||
if (isr & (ISR_TXDN | ISR_TXER | ISR_PINT))
|
||||
sonictxint(sc);
|
||||
|
||||
if (isr & ISR_PKTRX)
|
||||
@ -995,22 +995,20 @@ sonicrxint(sc)
|
||||
int rramark;
|
||||
int rdamark;
|
||||
int bitmode = sc->bitmode;
|
||||
void *tmp1;
|
||||
void *tmp2;
|
||||
u_int16_t rxpkt_ptr;
|
||||
|
||||
rda = sc->p_rda[sc->sc_rxmark];
|
||||
|
||||
while (SRO(bitmode, rda, RXPKT_INUSE) == 0) {
|
||||
unsigned status = SRO(bitmode, rda, RXPKT_STATUS);
|
||||
if ((status & RCR_LPKT) == 0)
|
||||
printf("%s: more than one packet in RBA!\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
|
||||
orra = RBASEQ(SRO(bitmode, rda, RXPKT_SEQNO)) & RRAMASK;
|
||||
rxpkt_ptr = SRO(bitmode, rda, RXPKT_PTRLO);
|
||||
len = SRO(bitmode, rda, RXPKT_BYTEC) -
|
||||
sizeof(struct ether_header) - FCSSIZE;
|
||||
if (status & RCR_PRX) {
|
||||
if (sonic_read(sc, sc->rbuf[orra & RBAMASK], len)) {
|
||||
caddr_t pkt = sc->rbuf[orra & RBAMASK] + (rxpkt_ptr & PGOFSET);
|
||||
if (sonic_read(sc, pkt, len)) {
|
||||
sc->sc_if.if_ipackets++;
|
||||
sc->sc_sum.ls_ipacks++;
|
||||
sc->sc_missed = 0;
|
||||
@ -1021,8 +1019,9 @@ sonicrxint(sc)
|
||||
/*
|
||||
* give receive buffer area back to chip.
|
||||
*
|
||||
* orra is now empty of packets and can be freed if
|
||||
* sonic read didnt copy it out then we would have to
|
||||
* If this was the last packet in the RRA, give the RRA to
|
||||
* the chip again.
|
||||
* If sonic read didnt copy it out then we would have to
|
||||
* wait !!
|
||||
* (dont bother add it back in again straight away)
|
||||
*
|
||||
@ -1030,25 +1029,29 @@ sonicrxint(sc)
|
||||
* we have to use the macros because SONIC might be in
|
||||
* 16 or 32 bit mode.
|
||||
*/
|
||||
rramark = sc->sc_rramark;
|
||||
tmp1 = sc->p_rra[rramark];
|
||||
tmp2 = sc->p_rra[orra];
|
||||
SWO(bitmode, tmp1, RXRSRC_PTRLO,
|
||||
SRO(bitmode, tmp2, RXRSRC_PTRLO));
|
||||
SWO(bitmode, tmp1, RXRSRC_PTRHI,
|
||||
SRO(bitmode, tmp2, RXRSRC_PTRHI));
|
||||
SWO(bitmode, tmp1, RXRSRC_WCLO,
|
||||
SRO(bitmode, tmp2, RXRSRC_WCLO));
|
||||
SWO(bitmode, tmp1, RXRSRC_WCHI,
|
||||
SRO(bitmode, tmp2, RXRSRC_WCHI));
|
||||
if (status & RCR_LPKT) {
|
||||
void *tmp1, *tmp2;
|
||||
|
||||
/* zap old rra for fun */
|
||||
SWO(bitmode, tmp2, RXRSRC_WCHI, 0);
|
||||
SWO(bitmode, tmp2, RXRSRC_WCLO, 0);
|
||||
rramark = sc->sc_rramark;
|
||||
tmp1 = sc->p_rra[rramark];
|
||||
tmp2 = sc->p_rra[orra];
|
||||
SWO(bitmode, tmp1, RXRSRC_PTRLO,
|
||||
SRO(bitmode, tmp2, RXRSRC_PTRLO));
|
||||
SWO(bitmode, tmp1, RXRSRC_PTRHI,
|
||||
SRO(bitmode, tmp2, RXRSRC_PTRHI));
|
||||
SWO(bitmode, tmp1, RXRSRC_WCLO,
|
||||
SRO(bitmode, tmp2, RXRSRC_WCLO));
|
||||
SWO(bitmode, tmp1, RXRSRC_WCHI,
|
||||
SRO(bitmode, tmp2, RXRSRC_WCHI));
|
||||
|
||||
sc->sc_rramark = (++rramark) & RRAMASK;
|
||||
NIC_PUT(sc, SNR_RWP, LOWER(sc->v_rra[rramark]));
|
||||
wbflush();
|
||||
/* zap old rra for fun */
|
||||
SWO(bitmode, tmp2, RXRSRC_WCHI, 0);
|
||||
SWO(bitmode, tmp2, RXRSRC_WCLO, 0);
|
||||
|
||||
sc->sc_rramark = (++rramark) & RRAMASK;
|
||||
NIC_PUT(sc, SNR_RWP, LOWER(sc->v_rra[rramark]));
|
||||
wbflush();
|
||||
}
|
||||
|
||||
/*
|
||||
* give receive descriptor back to chip simple
|
||||
@ -1072,7 +1075,7 @@ sonicrxint(sc)
|
||||
* sonic_read -- pull packet off interface and forward to
|
||||
* appropriate protocol handler
|
||||
*/
|
||||
static int
|
||||
static inline int
|
||||
sonic_read(sc, pkt, len)
|
||||
struct sn_softc *sc;
|
||||
caddr_t pkt;
|
||||
@ -1129,7 +1132,7 @@ sonic_read(sc, pkt, len)
|
||||
* because we are using stupid buffer management this
|
||||
* is slow.
|
||||
*/
|
||||
static struct mbuf *
|
||||
static inline struct mbuf *
|
||||
sonic_get(sc, eh, datalen)
|
||||
struct sn_softc *sc;
|
||||
struct ether_header *eh;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_sn_nubus.c,v 1.3 1997/03/30 19:51:47 briggs Exp $ */
|
||||
/* $NetBSD: if_sn_nubus.c,v 1.4 1997/04/10 03:22:47 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997 Allen Briggs
|
||||
@ -59,6 +59,8 @@
|
||||
static int sn_nubus_match __P((struct device *, struct cfdata *, void *));
|
||||
static void sn_nubus_attach __P((struct device *, struct device *, void *));
|
||||
static int sn_nb_card_vendor __P((struct nubus_attach_args *));
|
||||
static int sn_nb_get_enaddr __P((struct nubus_attach_args *,
|
||||
u_int8_t *, int));
|
||||
|
||||
struct cfattach sn_nubus_ca = {
|
||||
sizeof(struct sn_softc), sn_nubus_match, sn_nubus_attach
|
||||
@ -87,7 +89,7 @@ sn_nubus_match(parent, cf, aux)
|
||||
default:
|
||||
break;
|
||||
|
||||
/* This is it for now... */
|
||||
case AE_VENDOR_APPLE:
|
||||
case AE_VENDOR_DAYNA:
|
||||
rv = 1;
|
||||
break;
|
||||
@ -160,6 +162,22 @@ sn_nubus_attach(parent, self, aux)
|
||||
success = 1;
|
||||
break;
|
||||
|
||||
case AE_VENDOR_APPLE:
|
||||
sc->snr_dcr = DCR_ASYNC | DCR_WAIT0 | DCR_DW32 |
|
||||
DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
|
||||
sc->snr_dcr2 = 0;
|
||||
|
||||
if (bus_space_subregion(bst, bsh, 0x00180000, SN_REGSIZE,
|
||||
&sc->sc_regh)) {
|
||||
printf(": failed to map register space.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (sn_nb_get_enaddr(na, myaddr, 0x8) == 0)
|
||||
success = 1;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* You can't actually get this default, the snmatch
|
||||
@ -170,6 +188,7 @@ sn_nubus_attach(parent, self, aux)
|
||||
sc->snr_dcr = DCR_SYNC | DCR_WAIT0 | DCR_DW32 |
|
||||
DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
|
||||
sc->snr_dcr2 = 0;
|
||||
printf(": attachment incomplete.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -202,6 +221,15 @@ sn_nb_card_vendor(na)
|
||||
|
||||
switch (na->drsw) {
|
||||
case NUBUS_DRSW_3COM:
|
||||
switch (na->drhw) {
|
||||
case NUBUS_DRHW_APPLE_SN:
|
||||
vendor = AE_VENDOR_APPLE;
|
||||
break;
|
||||
default:
|
||||
vendor = AE_VENDOR_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NUBUS_DRSW_APPLE:
|
||||
case NUBUS_DRSW_TECHWORKS:
|
||||
vendor = AE_VENDOR_APPLE;
|
||||
@ -241,3 +269,25 @@ sn_nb_card_vendor(na)
|
||||
}
|
||||
return vendor;
|
||||
}
|
||||
|
||||
static int
|
||||
sn_nb_get_enaddr(na, ep, rsrc1)
|
||||
struct nubus_attach_args *na;
|
||||
u_int8_t *ep;
|
||||
int rsrc1;
|
||||
{
|
||||
nubus_dir dir;
|
||||
nubus_dirent dirent;
|
||||
|
||||
nubus_get_main_dir(na->fmt, &dir);
|
||||
if (nubus_find_rsrc(na->fmt, &dir, na->rsrcid, &dirent) <= 0)
|
||||
return 1;
|
||||
nubus_get_dir_from_rsrc(na->fmt, &dirent, &dir);
|
||||
if (nubus_find_rsrc(na->fmt, &dir, rsrc1, &dirent) <= 0)
|
||||
return 1;
|
||||
if (nubus_get_ind_data(na->fmt, &dirent, ep, ETHER_ADDR_LEN) <= 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_sn_obio.c,v 1.6 1997/04/04 14:54:44 briggs Exp $ */
|
||||
/* $NetBSD: if_sn_obio.c,v 1.7 1997/04/10 03:22:48 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997 Allen Briggs
|
||||
@ -61,7 +61,8 @@
|
||||
|
||||
static int sn_obio_match __P((struct device *, struct cfdata *, void *));
|
||||
static void sn_obio_attach __P((struct device *, struct device *, void *));
|
||||
static void sn_obio_getaddr __P((struct sn_softc *, u_int8_t *));
|
||||
static int sn_obio_getaddr __P((struct sn_softc *, u_int8_t *));
|
||||
static int sn_obio_getaddr_kludge __P((struct sn_softc *, u_int8_t *));
|
||||
|
||||
struct cfattach sn_obio_ca = {
|
||||
sizeof(struct sn_softc), sn_obio_match, sn_obio_attach
|
||||
@ -96,18 +97,9 @@ sn_obio_attach(parent, self, aux)
|
||||
sc->snr_dcr2 = 0;
|
||||
|
||||
switch (current_mac_model->machineid) {
|
||||
case MACH_MACQ700: /* only tested on Q700 */
|
||||
case MACH_MACQ900:
|
||||
case MACH_MACQ950:
|
||||
sc->snr_dcr |= DCR_SYNC | DCR_LBR | DCR_DW32;
|
||||
sc->bitmode = 1;
|
||||
break;
|
||||
|
||||
case MACH_MACQ800:
|
||||
case MACH_MACQ650:
|
||||
case MACH_MACC650:
|
||||
case MACH_MACC610:
|
||||
case MACH_MACQ610:
|
||||
case MACH_MACQ700: case MACH_MACQ900: case MACH_MACQ950:
|
||||
case MACH_MACQ800: case MACH_MACQ650: case MACH_MACC650:
|
||||
case MACH_MACC610: case MACH_MACQ610:
|
||||
sc->snr_dcr |= DCR_EXBUS | DCR_DW32;
|
||||
sc->bitmode = 1;
|
||||
break;
|
||||
@ -118,25 +110,33 @@ sn_obio_attach(parent, self, aux)
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unsupported machine type\n");
|
||||
printf(": unsupported machine type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_regt = oa->oa_tag;
|
||||
|
||||
if (bus_space_map(sc->sc_regt, SONIC_REG_BASE, SN_REGSIZE,
|
||||
0, &sc->sc_regh)) {
|
||||
panic("failed to map space for SONIC regs.\n");
|
||||
panic(": failed to map space for SONIC regs.\n");
|
||||
}
|
||||
|
||||
sc->slotno = 9;
|
||||
|
||||
sn_obio_getaddr(sc, myaddr);
|
||||
|
||||
/* regs are addressed as words, big-endian. */
|
||||
for (i = 0; i < SN_NREGS; i++) {
|
||||
sc->sc_reg_map[i] = (bus_size_t)((i * 4) + 2);
|
||||
}
|
||||
|
||||
if (sn_obio_getaddr(sc, myaddr)) {
|
||||
printf(": failed to get MAC address. Trying kludge.\n");
|
||||
if (sn_obio_getaddr_kludge(sc, myaddr)) {
|
||||
printf("Kludge failed, too. Attachment failing.\n");
|
||||
bus_space_unmap(sc->sc_regt, sc->sc_regh, SN_REGSIZE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* snsetup returns 1 if something fails */
|
||||
if (snsetup(sc, myaddr)) {
|
||||
bus_space_unmap(sc->sc_regt, sc->sc_regh, SN_REGSIZE);
|
||||
@ -149,7 +149,7 @@ sn_obio_attach(parent, self, aux)
|
||||
static u_char bbr4[] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
|
||||
#define bbr(v) ((bbr4[(v)&0xf] << 4) | bbr4[((v)>>4) & 0xf])
|
||||
|
||||
static void
|
||||
static int
|
||||
sn_obio_getaddr(sc, lladdr)
|
||||
struct sn_softc *sc;
|
||||
u_int8_t *lladdr;
|
||||
@ -162,6 +162,11 @@ sn_obio_getaddr(sc, lladdr)
|
||||
panic("failed to map space to read SONIC address.\n");
|
||||
}
|
||||
|
||||
if (!bus_probe(sc->sc_regt, bsh, 0, 1)) {
|
||||
bus_space_unmap(sc->sc_regt, bsh, NBPG);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* For reasons known only to Apple, MAC addresses in the ethernet
|
||||
* PROM are stored in Token Ring (IEEE 802.5) format, that is
|
||||
@ -204,4 +209,51 @@ sn_obio_getaddr(sc, lladdr)
|
||||
}
|
||||
|
||||
bus_space_unmap(sc->sc_regt, bsh, NBPG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume that the SONIC was initialized in MacOS. This should go away
|
||||
* when we can properly get the MAC address on the PBs.
|
||||
*/
|
||||
static int
|
||||
sn_obio_getaddr_kludge(sc, lladdr)
|
||||
struct sn_softc *sc;
|
||||
u_int8_t *lladdr;
|
||||
{
|
||||
int i, ors=0;
|
||||
|
||||
/* Shut down NIC */
|
||||
NIC_PUT(sc, SNR_CR, CR_RST);
|
||||
wbflush();
|
||||
|
||||
NIC_PUT(sc, SNR_CEP, 15); /* For some reason, Apple fills top first. */
|
||||
wbflush();
|
||||
i = NIC_GET(sc, SNR_CAP2);
|
||||
wbflush();
|
||||
|
||||
ors |= i;
|
||||
lladdr[5] = i >> 8;
|
||||
lladdr[4] = i;
|
||||
|
||||
i = NIC_GET(sc, SNR_CAP1);
|
||||
wbflush();
|
||||
|
||||
ors |= i;
|
||||
lladdr[3] = i >> 8;
|
||||
lladdr[2] = i;
|
||||
|
||||
i = NIC_GET(sc, SNR_CAP0);
|
||||
wbflush();
|
||||
|
||||
ors |= i;
|
||||
lladdr[1] = i >> 8;
|
||||
lladdr[0] = i;
|
||||
|
||||
NIC_PUT(sc, SNR_CR, 0);
|
||||
wbflush();
|
||||
|
||||
if (ors == 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_snvar.h,v 1.4 1997/03/30 19:51:55 briggs Exp $ */
|
||||
/* $NetBSD: if_snvar.h,v 1.5 1997/04/10 03:22:47 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991 Algorithmics Ltd (http://www.algor.co.uk)
|
||||
@ -47,12 +47,12 @@
|
||||
* 1 Rda is 4 words == 16 bytes
|
||||
*/
|
||||
|
||||
#define NRBA 16 /* # receive buffers < NRRA */
|
||||
#define RBAMASK 0x0f
|
||||
#define NRDA NRBA
|
||||
#define NRBA 8 /* # receive buffers < NRRA */
|
||||
#define RBAMASK (NRBA-1)
|
||||
#define NRDA NRBA*4
|
||||
#define NTDA 4 /* # transmit descriptors */
|
||||
#define NRRA 32 /* # receive resource descriptors */
|
||||
#define RRAMASK 0x1f /* the reason why it must be power of two */
|
||||
#define RRAMASK (NRRA-1) /* the reason why it must be power of two */
|
||||
|
||||
#define FCSSIZE 4 /* size of FCS appended to packets */
|
||||
|
||||
@ -203,7 +203,7 @@ typedef struct sn_softc {
|
||||
* Transmit Descriptor
|
||||
* This structure holds information about packets to be transmitted.
|
||||
*/
|
||||
#define FRAGMAX 16 /* maximum number of fragments in a packet */
|
||||
#define FRAGMAX 8 /* maximum number of fragments in a packet */
|
||||
|
||||
#define TXP_STATUS 0 /* + transmitted packet status */
|
||||
#define TXP_CONFIG 1 /* transmission configuration */
|
||||
@ -216,7 +216,7 @@ typedef struct sn_softc {
|
||||
#define TXP_FPTRHI 1 /* ptr to packet fragment HI */
|
||||
#define TXP_FSIZE 2 /* fragment size */
|
||||
|
||||
#define TXP_WORDS TXP_FRAGOFF + FRAGMAX*TXP_FSIZE + 1 /* 1 for tlink */
|
||||
#define TXP_WORDS TXP_FRAGOFF + (FRAGMAX*TXP_FRAGSIZE) + 1 /* 1 for tlink */
|
||||
#define TXP_SIZE(sc) ((sc->bitmode) ? (TXP_WORDS*4) : (TXP_WORDS*2))
|
||||
|
||||
#define EOL 0x0001 /* end of list marker for link fields */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_sn_nubus.c,v 1.3 1997/03/30 19:51:47 briggs Exp $ */
|
||||
/* $NetBSD: if_sn_nubus.c,v 1.4 1997/04/10 03:22:47 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997 Allen Briggs
|
||||
@ -59,6 +59,8 @@
|
||||
static int sn_nubus_match __P((struct device *, struct cfdata *, void *));
|
||||
static void sn_nubus_attach __P((struct device *, struct device *, void *));
|
||||
static int sn_nb_card_vendor __P((struct nubus_attach_args *));
|
||||
static int sn_nb_get_enaddr __P((struct nubus_attach_args *,
|
||||
u_int8_t *, int));
|
||||
|
||||
struct cfattach sn_nubus_ca = {
|
||||
sizeof(struct sn_softc), sn_nubus_match, sn_nubus_attach
|
||||
@ -87,7 +89,7 @@ sn_nubus_match(parent, cf, aux)
|
||||
default:
|
||||
break;
|
||||
|
||||
/* This is it for now... */
|
||||
case AE_VENDOR_APPLE:
|
||||
case AE_VENDOR_DAYNA:
|
||||
rv = 1;
|
||||
break;
|
||||
@ -160,6 +162,22 @@ sn_nubus_attach(parent, self, aux)
|
||||
success = 1;
|
||||
break;
|
||||
|
||||
case AE_VENDOR_APPLE:
|
||||
sc->snr_dcr = DCR_ASYNC | DCR_WAIT0 | DCR_DW32 |
|
||||
DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
|
||||
sc->snr_dcr2 = 0;
|
||||
|
||||
if (bus_space_subregion(bst, bsh, 0x00180000, SN_REGSIZE,
|
||||
&sc->sc_regh)) {
|
||||
printf(": failed to map register space.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (sn_nb_get_enaddr(na, myaddr, 0x8) == 0)
|
||||
success = 1;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* You can't actually get this default, the snmatch
|
||||
@ -170,6 +188,7 @@ sn_nubus_attach(parent, self, aux)
|
||||
sc->snr_dcr = DCR_SYNC | DCR_WAIT0 | DCR_DW32 |
|
||||
DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
|
||||
sc->snr_dcr2 = 0;
|
||||
printf(": attachment incomplete.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -202,6 +221,15 @@ sn_nb_card_vendor(na)
|
||||
|
||||
switch (na->drsw) {
|
||||
case NUBUS_DRSW_3COM:
|
||||
switch (na->drhw) {
|
||||
case NUBUS_DRHW_APPLE_SN:
|
||||
vendor = AE_VENDOR_APPLE;
|
||||
break;
|
||||
default:
|
||||
vendor = AE_VENDOR_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NUBUS_DRSW_APPLE:
|
||||
case NUBUS_DRSW_TECHWORKS:
|
||||
vendor = AE_VENDOR_APPLE;
|
||||
@ -241,3 +269,25 @@ sn_nb_card_vendor(na)
|
||||
}
|
||||
return vendor;
|
||||
}
|
||||
|
||||
static int
|
||||
sn_nb_get_enaddr(na, ep, rsrc1)
|
||||
struct nubus_attach_args *na;
|
||||
u_int8_t *ep;
|
||||
int rsrc1;
|
||||
{
|
||||
nubus_dir dir;
|
||||
nubus_dirent dirent;
|
||||
|
||||
nubus_get_main_dir(na->fmt, &dir);
|
||||
if (nubus_find_rsrc(na->fmt, &dir, na->rsrcid, &dirent) <= 0)
|
||||
return 1;
|
||||
nubus_get_dir_from_rsrc(na->fmt, &dirent, &dir);
|
||||
if (nubus_find_rsrc(na->fmt, &dir, rsrc1, &dirent) <= 0)
|
||||
return 1;
|
||||
if (nubus_get_ind_data(na->fmt, &dirent, ep, ETHER_ADDR_LEN) <= 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_sn_obio.c,v 1.6 1997/04/04 14:54:44 briggs Exp $ */
|
||||
/* $NetBSD: if_sn_obio.c,v 1.7 1997/04/10 03:22:48 briggs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1997 Allen Briggs
|
||||
@ -61,7 +61,8 @@
|
||||
|
||||
static int sn_obio_match __P((struct device *, struct cfdata *, void *));
|
||||
static void sn_obio_attach __P((struct device *, struct device *, void *));
|
||||
static void sn_obio_getaddr __P((struct sn_softc *, u_int8_t *));
|
||||
static int sn_obio_getaddr __P((struct sn_softc *, u_int8_t *));
|
||||
static int sn_obio_getaddr_kludge __P((struct sn_softc *, u_int8_t *));
|
||||
|
||||
struct cfattach sn_obio_ca = {
|
||||
sizeof(struct sn_softc), sn_obio_match, sn_obio_attach
|
||||
@ -96,18 +97,9 @@ sn_obio_attach(parent, self, aux)
|
||||
sc->snr_dcr2 = 0;
|
||||
|
||||
switch (current_mac_model->machineid) {
|
||||
case MACH_MACQ700: /* only tested on Q700 */
|
||||
case MACH_MACQ900:
|
||||
case MACH_MACQ950:
|
||||
sc->snr_dcr |= DCR_SYNC | DCR_LBR | DCR_DW32;
|
||||
sc->bitmode = 1;
|
||||
break;
|
||||
|
||||
case MACH_MACQ800:
|
||||
case MACH_MACQ650:
|
||||
case MACH_MACC650:
|
||||
case MACH_MACC610:
|
||||
case MACH_MACQ610:
|
||||
case MACH_MACQ700: case MACH_MACQ900: case MACH_MACQ950:
|
||||
case MACH_MACQ800: case MACH_MACQ650: case MACH_MACC650:
|
||||
case MACH_MACC610: case MACH_MACQ610:
|
||||
sc->snr_dcr |= DCR_EXBUS | DCR_DW32;
|
||||
sc->bitmode = 1;
|
||||
break;
|
||||
@ -118,25 +110,33 @@ sn_obio_attach(parent, self, aux)
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unsupported machine type\n");
|
||||
printf(": unsupported machine type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_regt = oa->oa_tag;
|
||||
|
||||
if (bus_space_map(sc->sc_regt, SONIC_REG_BASE, SN_REGSIZE,
|
||||
0, &sc->sc_regh)) {
|
||||
panic("failed to map space for SONIC regs.\n");
|
||||
panic(": failed to map space for SONIC regs.\n");
|
||||
}
|
||||
|
||||
sc->slotno = 9;
|
||||
|
||||
sn_obio_getaddr(sc, myaddr);
|
||||
|
||||
/* regs are addressed as words, big-endian. */
|
||||
for (i = 0; i < SN_NREGS; i++) {
|
||||
sc->sc_reg_map[i] = (bus_size_t)((i * 4) + 2);
|
||||
}
|
||||
|
||||
if (sn_obio_getaddr(sc, myaddr)) {
|
||||
printf(": failed to get MAC address. Trying kludge.\n");
|
||||
if (sn_obio_getaddr_kludge(sc, myaddr)) {
|
||||
printf("Kludge failed, too. Attachment failing.\n");
|
||||
bus_space_unmap(sc->sc_regt, sc->sc_regh, SN_REGSIZE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* snsetup returns 1 if something fails */
|
||||
if (snsetup(sc, myaddr)) {
|
||||
bus_space_unmap(sc->sc_regt, sc->sc_regh, SN_REGSIZE);
|
||||
@ -149,7 +149,7 @@ sn_obio_attach(parent, self, aux)
|
||||
static u_char bbr4[] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
|
||||
#define bbr(v) ((bbr4[(v)&0xf] << 4) | bbr4[((v)>>4) & 0xf])
|
||||
|
||||
static void
|
||||
static int
|
||||
sn_obio_getaddr(sc, lladdr)
|
||||
struct sn_softc *sc;
|
||||
u_int8_t *lladdr;
|
||||
@ -162,6 +162,11 @@ sn_obio_getaddr(sc, lladdr)
|
||||
panic("failed to map space to read SONIC address.\n");
|
||||
}
|
||||
|
||||
if (!bus_probe(sc->sc_regt, bsh, 0, 1)) {
|
||||
bus_space_unmap(sc->sc_regt, bsh, NBPG);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* For reasons known only to Apple, MAC addresses in the ethernet
|
||||
* PROM are stored in Token Ring (IEEE 802.5) format, that is
|
||||
@ -204,4 +209,51 @@ sn_obio_getaddr(sc, lladdr)
|
||||
}
|
||||
|
||||
bus_space_unmap(sc->sc_regt, bsh, NBPG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume that the SONIC was initialized in MacOS. This should go away
|
||||
* when we can properly get the MAC address on the PBs.
|
||||
*/
|
||||
static int
|
||||
sn_obio_getaddr_kludge(sc, lladdr)
|
||||
struct sn_softc *sc;
|
||||
u_int8_t *lladdr;
|
||||
{
|
||||
int i, ors=0;
|
||||
|
||||
/* Shut down NIC */
|
||||
NIC_PUT(sc, SNR_CR, CR_RST);
|
||||
wbflush();
|
||||
|
||||
NIC_PUT(sc, SNR_CEP, 15); /* For some reason, Apple fills top first. */
|
||||
wbflush();
|
||||
i = NIC_GET(sc, SNR_CAP2);
|
||||
wbflush();
|
||||
|
||||
ors |= i;
|
||||
lladdr[5] = i >> 8;
|
||||
lladdr[4] = i;
|
||||
|
||||
i = NIC_GET(sc, SNR_CAP1);
|
||||
wbflush();
|
||||
|
||||
ors |= i;
|
||||
lladdr[3] = i >> 8;
|
||||
lladdr[2] = i;
|
||||
|
||||
i = NIC_GET(sc, SNR_CAP0);
|
||||
wbflush();
|
||||
|
||||
ors |= i;
|
||||
lladdr[1] = i >> 8;
|
||||
lladdr[0] = i;
|
||||
|
||||
NIC_PUT(sc, SNR_CR, 0);
|
||||
wbflush();
|
||||
|
||||
if (ors == 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user