Newbusify the driver.

Add support, kinda, for megaheartz xjack nic cards.  This support
works well for one machine per ethernet segment because it hard codes
the MAC address.  The pccardd in -current doesn't have support to
parse the ethernet address from the CIS in the funky way that the
megaheartz card does things (it includes it in the info tuple, as
ascii, which is non-standard).  I'd rather kludge this for the moment
and work to read the CIS from the kernel rather than mess with
pccardd.

The isa attachment is untested.  The pccard attachment is known to
work since I'm committing over it.

Card Obtained from: Chris D. Faulhaber <jedger@fxp.org>
This commit is contained in:
Warner Losh 1999-12-22 08:44:13 +00:00
parent 19b132d78b
commit b616727984
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=54994
5 changed files with 390 additions and 341 deletions

View File

@ -78,25 +78,25 @@
* Multicast support by Kei TANAKA <kei@pal.xerox.com>
* Special thanks to itojun@itojun.org
*/
#include "sn.h"
#if NSN > 0
#undef SN_DEBUG /* (by hosokawa) */
#include <sys/param.h>
#if defined(__FreeBSD__)
#include <sys/systm.h>
#include <sys/kernel.h>
#endif
#include <sys/errno.h>
#include <sys/sockio.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/syslog.h>
#if defined(__NetBSD__)
#include <sys/select.h>
#endif
#include <sys/module.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>
@ -120,43 +120,24 @@
#include <net/bpf.h>
#include <net/bpfdesc.h>
#if defined(__FreeBSD__)
#include <machine/clock.h>
#endif
#include <i386/isa/isa_device.h>
/* PCCARD suport */
#define NCARD 0
#if NCARD > 0
#include <sys/select.h>
#include <sys/module.h>
#include <pccard/cardinfo.h>
#include <pccard/slot.h>
#include <pccard/driver.h>
#endif /* NCARD > 0 */
#include <dev/sn/if_snreg.h>
#include <dev/sn/if_snvar.h>
/* for PCMCIA Ethernet */
static int sn_pccard[NSN]; /* set to 1 if it's PCMCIA card */
static u_char sn_pccard_macaddr[NSN][6];
static int sn_import_macaddr[NSN];
/* Exported variables */
devclass_t sn_devclass;
static int snprobe __P((struct isa_device *));
static int snattach __P((struct isa_device *));
static int snioctl __P((struct ifnet * ifp, u_long, caddr_t));
static int snioctl(struct ifnet * ifp, u_long, caddr_t);
static int smc_probe __P((int ioaddr, int pccard));
static void snresume __P((struct ifnet *));
static void snresume(struct ifnet *);
void sninit __P((void *));
static ointhand2_t snintr;
void snread __P((struct ifnet *));
void snreset __P((int));
void snstart __P((struct ifnet *));
void snstop __P((int));
void snwatchdog __P((struct ifnet *));
void sninit(void *);
void snread(struct ifnet *);
void snreset(struct sn_softc *);
void snstart(struct ifnet *);
void snstop(struct sn_softc *);
void snwatchdog(struct ifnet *);
static void sn_setmcast(struct sn_softc *);
static int sn_getmcf(struct arpcom *ac, u_char *mcf);
@ -167,152 +148,40 @@ static u_int smc_crc(u_char *);
*/
#define SW_PAD
struct sn_softc sn_softc[NSN];
/* XXX KLUDGE XXX */
u_char sn_pccard_macaddr[6] = { 0x00, 0x00, 0x86, 0x10, 0x2b, 0xc0 };
struct isa_driver sndriver = {
snprobe,
snattach,
"sn",
0
static const char *chip_ids[15] = {
NULL, NULL, NULL,
/* 3 */ "SMC91C90/91C92",
/* 4 */ "SMC91C94",
/* 5 */ "SMC91C95",
NULL,
/* 7 */ "SMC91C100",
NULL, NULL, NULL, NULL,
NULL, NULL, NULL
};
/* PCCARD Support */
#if NCARD > 0
/*
* PC-Card (PCMCIA) specific code.
*/
static int sn_card_intr(struct pccard_devinfo *); /* Interrupt handler */
static void snunload(struct pccard_devinfo *); /* Disable driver */
static int sn_card_init(struct pccard_devinfo *); /* init device */
PCCARD_MODULE(sn,sn_card_init,snunload,sn_card_intr,0,net_imask);
static int
sn_card_init(struct pccard_devinfo *devi)
{
int unit = devi->pd_unit;
struct sn_softc *sc = &sn_softc[devi->pd_unit];
sn_pccard[unit] = 1;
sn_import_macaddr[unit] = 0;
if (devi->misc[0] | devi->misc[1] | devi->misc[2]) {
int i;
for (i = 0; i < 6; i++) {
sn_pccard_macaddr[unit][i] = devi->misc[i];
}
sn_import_macaddr[unit] = 1;
}
sc->gone = 0;
/*
* validate unit number.
*/
if (unit >= NSN)
return ENODEV;
/*
* Probe the device. If a value is returned, the
* device was found at the location.
*/
#ifdef SN_DEBUG
printf("snprobe()\n");
#endif
if (snprobe(&devi->isahd)==0)
return ENXIO;
#ifdef SN_DEBUG
printf("snattach()\n");
#endif
if (snattach(&devi->isahd)==0)
return ENXIO;
/* initialize interface dynamically */
sc->arpcom.ac_if.if_snd.ifq_maxlen = ifqmaxlen;
return 0;
}
static void
snunload(struct pccard_devinfo *devi)
{
int unit = devi->pd_unit;
struct sn_softc *sc = &sn_softc[devi->pd_unit];
struct ifnet *ifp = &sc->arpcom.ac_if;
if (sc->gone) {
printf("sn%d: already unloaded.\n", unit);
return;
}
snstop(unit);
sc->gone = 1;
ifp->if_flags &= ~IFF_RUNNING;
if_down(ifp);
printf("sn%d: unload.\n", unit);
}
static int
sn_card_intr(struct pccard_devinfo *devi)
{
int unit = devi->pd_unit;
snintr(unit);
return(1);
}
#endif /* NCARD > 0 */
int
snprobe(struct isa_device *is)
sn_attach(device_t dev)
{
/*
* Device was configured with 'port ?' In this case we complain
*/
if (is->id_iobase == -1) { /* port? */
printf("sn%d: SMC91Cxx cannot determine ioaddr\n", is->id_unit);
return 0;
}
/*
* Device was configured with 'irq ?' In this case we complain
*/
if (is->id_irq == 0) {
printf("sn%d: SMC91Cxx cannot determine irq\n", is->id_unit);
return (0);
}
/*
* Device was configured with 'port xxx', 'irq xx' In this case we
* search for the card with that address
*/
if (smc_probe(is->id_iobase, sn_pccard[is->id_unit]) != 0)
return (0);
return (SMC_IO_EXTENT);
}
static int
snattach(struct isa_device *is)
{
struct sn_softc *sc = &sn_softc[is->id_unit];
struct sn_softc *sc = device_get_softc(dev);
struct ifnet *ifp = &sc->arpcom.ac_if;
u_short i;
int j;
u_char *p;
struct ifaddr *ifa;
struct sockaddr_dl *sdl;
int rev;
u_short address;
#if NCARD > 0
static int alredy_ifatch[NSN];
#endif
snstop(is->id_unit);
is->id_ointr = snintr;
sn_activate(dev);
/*
* This is the value used for BASE
*/
sc->sn_io_addr = is->id_iobase;
snstop(sc);
sc->dev = dev;
sc->pages_wanted = -1;
printf("sn%d: ", is->id_unit);
device_printf(dev, " ");
SMC_SELECT_BANK(3);
rev = inw(BASE + REVISION_REG_W);
@ -323,12 +192,16 @@ snattach(struct isa_device *is)
i = inw(BASE + CONFIG_REG_W);
printf(i & CR_AUI_SELECT ? "AUI" : "UTP");
if (sn_import_macaddr[is->id_unit]) {
if (1) {
/* XXX The pccard probe routine for megahearts needs to */
/* XXX snag this from your info 2 */
int j;
for (j = 0; j < 3; j++) {
u_short w;
w = (u_short)sn_pccard_macaddr[is->id_unit][j * 2] |
(((u_short)sn_pccard_macaddr[is->id_unit][j * 2 + 1]) << 8);
w = (u_short)sn_pccard_macaddr[j * 2] |
(((u_short)sn_pccard_macaddr[j * 2 + 1]) << 8);
outw(BASE + IAR_ADDR0_REG_W + j * 2, w);
}
}
@ -346,7 +219,7 @@ snattach(struct isa_device *is)
}
printf(" MAC address %6D\n", sc->arpcom.ac_enaddr, ":");
ifp->if_softc = sc;
ifp->if_unit = is->id_unit;
ifp->if_unit = device_get_unit(dev);
ifp->if_name = "sn";
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
@ -355,18 +228,13 @@ snattach(struct isa_device *is)
ifp->if_ioctl = snioctl;
ifp->if_watchdog = snwatchdog;
ifp->if_init = sninit;
ifp->if_snd.ifq_maxlen = 8;
ifp->if_timer = 0;
#if NCARD > 0
if (alredy_ifatch[is->id_unit] != 1) {
if_attach( ifp );
alredy_ifatch[is->id_unit] = 1;
}
#else
if_attach(ifp);
#endif
ether_ifattach(ifp);
/*
* Fill the hardware address into ifa_addr if we find an AF_LINK
* entry. We need to do this so bpf's can get the hardware addr of
@ -387,7 +255,7 @@ snattach(struct isa_device *is)
bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
return 1;
return 0;
}
@ -397,17 +265,12 @@ snattach(struct isa_device *is)
void
sninit(void *xsc)
{
/* register struct sn_softc *sc = &sn_softc[unit]; */
register struct sn_softc *sc = xsc;
register struct ifnet *ifp = &sc->arpcom.ac_if;
int s;
int flags;
int mask;
#if NCARD > 0
if (sc->gone)
return;
#endif
s = splimp();
/*
@ -501,7 +364,7 @@ sninit(void *xsc)
void
snstart(struct ifnet *ifp)
{
register struct sn_softc *sc = &sn_softc[ifp->if_unit];
register struct sn_softc *sc = ifp->if_softc;
register u_int len;
register struct mbuf *m;
struct mbuf *top;
@ -512,11 +375,6 @@ snstart(struct ifnet *ifp)
u_char packet_no;
int time_out;
#if NCARD > 0
if (sc->gone)
return;
#endif
s = splimp();
if (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) {
@ -553,9 +411,7 @@ snstart(struct ifnet *ifp)
* them instead?
*/
if (len + pad > ETHER_MAX_LEN - ETHER_CRC_LEN) {
printf("sn%d: large packet discarded (A)\n", ifp->if_unit);
++sc->arpcom.ac_if.if_oerrors;
IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
m_freem(m);
@ -735,7 +591,7 @@ snstart(struct ifnet *ifp)
static void
snresume(struct ifnet *ifp)
{
register struct sn_softc *sc = &sn_softc[ifp->if_unit];
register struct sn_softc *sc = ifp->if_softc;
register u_int len;
register struct mbuf *m;
struct mbuf *top;
@ -774,9 +630,7 @@ snresume(struct ifnet *ifp)
* them instead?
*/
if (len + pad > ETHER_MAX_LEN - ETHER_CRC_LEN) {
printf("sn%d: large packet discarded (B)\n", ifp->if_unit);
++sc->arpcom.ac_if.if_oerrors;
IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
m_freem(m);
@ -812,13 +666,9 @@ snresume(struct ifnet *ifp)
*/
packet_no = inb(BASE + ALLOC_RESULT_REG_B);
if (packet_no & ARR_FAILED) {
printf("sn%d: Memory allocation failed. Weird.\n", ifp->if_unit);
sc->arpcom.ac_if.if_timer = 1;
goto try_start;
return;
}
/*
* We have a packet number, so tell the card to use it.
@ -830,9 +680,7 @@ snresume(struct ifnet *ifp)
* memory allocation was initiated.
*/
if (pages_wanted != numPages) {
printf("sn%d: memory allocation wrong size. Weird.\n", ifp->if_unit);
/*
* If the allocation was the wrong size we simply release the
* memory once it is granted. Wait for the MMU to be un-busy.
@ -932,10 +780,10 @@ snresume(struct ifnet *ifp)
void
snintr(int unit)
sn_intr(void *arg)
{
int status, interrupts;
register struct sn_softc *sc = &sn_softc[unit];
register struct sn_softc *sc = (struct sn_softc *) arg;
struct ifnet *ifp = &sc->arpcom.ac_if;
int x;
@ -947,11 +795,6 @@ snintr(int unit)
u_short tx_status;
u_short card_stats;
#if NCARD > 0
if (sc->gone)
return;
#endif
/*
* if_ep.c did this, so I do too. Yet if_ed.c doesn't. I wonder...
*/
@ -1062,7 +905,8 @@ snintr(int unit)
tx_status = inw(BASE + DATA_REG_W);
if (tx_status & EPHSR_TX_SUC) {
printf("sn%d: Successful packet caused interrupt\n", unit);
device_printf(sc->dev,
"Successful packet caused interrupt\n");
} else {
++sc->arpcom.ac_if.if_oerrors;
}
@ -1138,7 +982,7 @@ snintr(int unit)
* Some other error. Try to fix it by resetting the adapter.
*/
if (status & IM_EPH_INT) {
snstop(unit);
snstop(sc);
sninit(sc);
}
@ -1166,7 +1010,7 @@ snintr(int unit)
void
snread(register struct ifnet *ifp)
{
struct sn_softc *sc = &sn_softc[ifp->if_unit];
struct sn_softc *sc = ifp->if_softc;
struct ether_header *eh;
struct mbuf *m;
short status;
@ -1320,18 +1164,8 @@ snread(register struct ifnet *ifp)
static int
snioctl(register struct ifnet *ifp, u_long cmd, caddr_t data)
{
struct sn_softc *sc = &sn_softc[ifp->if_unit];
struct sn_softc *sc = ifp->if_softc;
int s, error = 0;
#if !defined(__FreeBSD__) || __FreeBSD_version < 300000
struct ifreq *ifr = (struct ifreq *) data;
#endif
#if NCARD > 0
if (sc->gone) {
ifp->if_flags &= ~IFF_RUNNING;
return ENXIO;
}
#endif
s = splimp();
@ -1345,7 +1179,7 @@ snioctl(register struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCSIFFLAGS:
if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) {
ifp->if_flags &= ~IFF_RUNNING;
snstop(ifp->if_unit);
snstop(sc);
break;
} else {
/* reinitialize card on any parameter change */
@ -1362,32 +1196,14 @@ snioctl(register struct ifnet *ifp, u_long cmd, caddr_t data)
#endif
case SIOCADDMULTI:
#if defined(__FreeBSD__) && __FreeBSD_version >= 300000
/* update multicast filter list. */
sn_setmcast(sc);
error = 0;
#else
error = ether_addmulti(ifr, &sc->arpcom);
if (error == ENETRESET) {
/* update multicast filter list. */
sn_setmcast(sc);
error = 0;
}
#endif
break;
case SIOCDELMULTI:
#if defined(__FreeBSD__) && __FreeBSD_version >= 300000
/* update multicast filter list. */
sn_setmcast(sc);
error = 0;
#else
error = ether_delmulti(ifr, &sc->arpcom);
if (error == ENETRESET) {
/* update multicast filter list. */
sn_setmcast(sc);
error = 0;
}
#endif
break;
default:
error = EINVAL;
@ -1399,17 +1215,12 @@ snioctl(register struct ifnet *ifp, u_long cmd, caddr_t data)
}
void
snreset(int unit)
snreset(struct sn_softc *sc)
{
int s;
struct sn_softc *sc = &sn_softc[unit];
#if NCARD > 0
if (sc->gone)
return;
#endif
s = splimp();
snstop(unit);
snstop(sc);
sninit(sc);
splx(s);
@ -1419,14 +1230,8 @@ void
snwatchdog(struct ifnet *ifp)
{
int s;
#if NCARD > 0
struct sn_softc *sc = &sn_softc[ifp->if_unit];
if (sc->gone)
return;
#endif
s = splimp();
snintr(ifp->if_unit);
sn_intr(ifp->if_softc);
splx(s);
}
@ -1436,15 +1241,11 @@ snwatchdog(struct ifnet *ifp)
* 3. clear the enable xmit flags
*/
void
snstop(int unit)
snstop(struct sn_softc *sc)
{
struct sn_softc *sc = &sn_softc[unit];
struct ifnet *ifp = &sc->arpcom.ac_if;
#if NCARD > 0
if (sc->gone)
return;
#endif
/*
* Clear interrupt mask; disable all interrupts.
*/
@ -1465,9 +1266,63 @@ snstop(int unit)
}
int
sn_activate(device_t dev)
{
struct sn_softc *sc = device_get_softc(dev);
int err;
sc->port_rid = 0;
sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid,
0, ~0, SMC_IO_EXTENT, RF_ACTIVE);
if (!sc->port_res) {
#ifdef SN_DEBUG
device_printf(dev, "Cannot allocate ioport\n");
#endif
return ENOMEM;
}
sc->irq_rid = 0;
sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
0, ~0, 1, RF_ACTIVE);
if (!sc->irq_res) {
#ifdef SN_DEBUG
deivce_printf(dev, "Cannot allocate irq\n");
#endif
sn_deactivate(dev);
return ENOMEM;
}
if ((err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, sn_intr, sc,
&sc->intrhand)) != 0) {
sn_deactivate(dev);
return err;
}
sc->sn_io_addr = rman_get_start(sc->port_res);
return (0);
}
void
sn_deactivate(device_t dev)
{
struct sn_softc *sc = device_get_softc(dev);
if (sc->intrhand)
bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
sc->intrhand = 0;
if (sc->port_res)
bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid,
sc->port_res);
sc->port_res = 0;
if (sc->irq_res)
bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
sc->irq_res);
sc->irq_res = 0;
return;
}
/*
* Function: smc_probe( int ioaddr, int pccard )
* Function: sn_probe( device_t dev, int pccard )
*
* Purpose:
* Tests to see if a given ioaddr points to an SMC9xxx chip.
@ -1481,12 +1336,20 @@ snstop(int unit)
*
*
*/
static int
smc_probe(int ioaddr, int pccard)
int
sn_probe(device_t dev, int pccard)
{
struct sn_softc *sc = device_get_softc(dev);
u_int bank;
u_short revision_register;
u_short base_address_register;
u_short ioaddr;
int err;
if ((err = sn_activate(dev)) != 0)
return err;
ioaddr = sc->sn_io_addr;
/*
* First, see if the high byte is 0x33
@ -1494,9 +1357,9 @@ smc_probe(int ioaddr, int pccard)
bank = inw(ioaddr + BANK_SELECT_REG_W);
if ((bank & BSR_DETECT_MASK) != BSR_DETECT_VALUE) {
#ifdef SN_DEBUG
printf("test1 failed\n");
device_printf(dev, "test1 failed\n");
#endif
return -ENODEV;
goto error;
}
/*
* The above MIGHT indicate a device, but I need to write to further
@ -1507,9 +1370,9 @@ printf("test1 failed\n");
bank = inw(ioaddr + BANK_SELECT_REG_W);
if ((bank & BSR_DETECT_MASK) != BSR_DETECT_VALUE) {
#ifdef SN_DEBUG
printf("test2 failed\n");
device_printf(dev, "test2 failed\n");
#endif
return -ENODEV;
goto error;
}
/*
* well, we've already written once, so hopefully another time won't
@ -1537,10 +1400,11 @@ printf("test2 failed\n");
*/
#ifdef SN_DEBUG
printf("test3 failed ioaddr = 0x%x, base_address_register = 0x%x\n",
ioaddr, base_address_register >> 3 & 0x3E0);
device_printf(dev, "test3 failed ioaddr = 0x%x, "
"base_address_register = 0x%x\n", ioaddr,
base_address_register >> 3 & 0x3E0);
#endif
return -ENODEV;
goto error;
}
/*
* Check if the revision register is something that I recognize.
@ -1554,22 +1418,21 @@ printf("test3 failed ioaddr = 0x%x, base_address_register = 0x%x\n",
/*
* I don't regonize this chip, so...
*/
/*
* printf("sn: ioaddr %x unrecognized revision register:
* %x\n", ioaddr, revision_register );
*/
#ifdef SN_DEBUG
printf("test4 failed\n");
device_printf(dev, "test4 failed\n");
#endif
return -ENODEV;
goto error;
}
/*
* at this point I'll assume that the chip is an SMC9xxx. It might be
* prudent to check a listing of MAC addresses against the hardware
* address, or do some other tests.
*/
sn_deactivate(dev);
return 0;
error:
sn_deactivate(dev);
return ENXIO;
}
#define MCFSZ 8
@ -1612,7 +1475,6 @@ sn_setmcast(struct sn_softc *sc)
outw(BASE + RECV_CONTROL_REG_W, flags);
}
#if defined(__FreeBSD__) && __FreeBSD_version >= 300000
static int
sn_getmcf(struct arpcom *ac, u_char *mcf)
{
@ -1638,36 +1500,6 @@ sn_getmcf(struct arpcom *ac, u_char *mcf)
}
return 1; /* use multicast filter */
}
#else
static int
sn_getmcf(struct arpcom *ac, u_char *mcf)
{
int i;
struct ether_multi *enm;
struct ether_multistep step;
u_int a, b;
bzero(mcf, MCFSZ);
ETHER_FIRST_MULTI(step, ac, enm);
while (enm) {
if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
/* impossible to hash */
bzero(mcf, MCFSZ);
return 0;
}
a = smc_crc(enm->enm_addrlo) & 0x3f;
b = 0;
for (i=0; i < 6; i++) {
b <<= 1;
b |= (a & 0x01);
a >>= 1;
}
mcf[b >> 3] |= 1 << (b & 7);
ETHER_NEXT_MULTI(step, enm);
}
return 1; /* use multicast filter */
}
#endif
static u_int
smc_crc(u_char *s)
@ -1687,4 +1519,3 @@ smc_crc(u_char *s)
}
return v;
}
#endif

91
sys/dev/sn/if_sn_isa.c Normal file
View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 1999 M. Warner Losh
* 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, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Herb Peyerl.
* 4. The name of Herb Peyerl may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR 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/kernel.h>
#include <sys/socket.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/if_media.h>
#include <machine/clock.h>
#include <isa/isavar.h>
#include <isa/pnpvar.h>
#include <dev/sn/if_snreg.h>
#include <dev/sn/if_snvar.h>
static int sn_isa_probe (device_t);
static int sn_isa_attach (device_t);
static int
sn_isa_probe (device_t dev)
{
if (sn_probe(dev, 0) != 0)
return (0);
return (ENXIO);
}
static int
sn_isa_attach (device_t dev)
{
return (0);
}
static device_method_t sn_isa_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, sn_isa_probe),
DEVMETHOD(device_attach, sn_isa_attach),
{ 0, 0 }
};
static driver_t sn_isa_driver = {
"sn",
sn_isa_methods,
sizeof(struct sn_softc),
};
extern devclass_t sn_devclass;
DRIVER_MODULE(sn, isa, sn_isa_driver, sn_devclass, 0, 0);

99
sys/dev/sn/if_sn_pccard.c Normal file
View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 1999 M. Warner Losh <imp@village.org>
* 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, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR 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$
*/
/*
* Modifications for Megahertz X-Jack Ethernet Card (XJ-10BT)
*
* Copyright (c) 1996 by Tatsumi Hosokawa <hosokawa@jp.FreeBSD.org>
* BSD-nomads, Tokyo, Japan.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/if_media.h>
#include <machine/clock.h>
#include <dev/sn/if_snreg.h>
#include <dev/sn/if_snvar.h>
/*
* Initialize the device - called from Slot manager.
*/
static int
sn_pccard_probe(device_t dev)
{
return (sn_probe(dev, 1));
}
static int
sn_pccard_attach(device_t dev)
{
return (sn_attach(dev));
}
static int
sn_pccard_detach(device_t dev)
{
struct sn_softc *sc = device_get_softc(dev);
sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
if_detach(&sc->arpcom.ac_if);
sn_deactivate(dev);
return 0;
}
static device_method_t sn_pccard_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, sn_pccard_probe),
DEVMETHOD(device_attach, sn_pccard_attach),
DEVMETHOD(device_detach, sn_pccard_detach),
{ 0, 0 }
};
static driver_t sn_pccard_driver = {
"sn",
sn_pccard_methods,
sizeof(struct sn_softc),
};
extern devclass_t sn_devclass;
DRIVER_MODULE(sn, pccard, sn_pccard_driver, sn_devclass, 0, 0);

View File

@ -51,25 +51,6 @@
#ifndef _IF_SNREG_H_
#define _IF_SNREG_H_
#include <net/if_arp.h>
/*
* Ethernet software status per interface. The first element MUST
* be the arpcom struct since the address of the arpcom struct is
* used as a backdoor to obtain the address of this whole structure
* in many cases.
*/
struct sn_softc {
struct arpcom arpcom; /* Ethernet common part */
short sn_io_addr; /* i/o bus address (BASE) */
int pages_wanted; /* Size of outstanding MMU ALLOC */
int intr_mask; /* Most recently set interrupt mask */
#if NCARD > 0
int gone;
#endif /* NCARD > 0 */
};
/*
* Wait time for memory to be free. This probably shouldn't be
* tuned that much, as waiting for this means nothing else happens
@ -357,18 +338,6 @@ struct sn_softc {
#define CHIP_9195 5
#define CHIP_91100 7
static const char *chip_ids[15] = {
NULL, NULL, NULL,
/* 3 */ "SMC91C90/91C92",
/* 4 */ "SMC91C94",
/* 5 */ "SMC91C95",
NULL,
/* 7 */ "SMC91C100",
NULL, NULL, NULL, NULL,
NULL, NULL, NULL
};
/* When packets are stuffed into the card or sucked out of the card
* they are set up more or less as follows:
*

59
sys/dev/sn/if_snvar.h Normal file
View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 1999 M. Warner Losh <imp@village.org>
* 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, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR 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$
*/
#ifndef _IF_SNVAR_H
#define _IF_SNVAR_H
#include <net/if_arp.h>
/*
* Ethernet software status per interface. The first element MUST
* be the arpcom struct since the address of the arpcom struct is
* used as a backdoor to obtain the address of this whole structure
* in many cases.
*/
struct sn_softc {
struct arpcom arpcom; /* Ethernet common part */
short sn_io_addr; /* i/o bus address (BASE) */
int pages_wanted; /* Size of outstanding MMU ALLOC */
int intr_mask; /* Most recently set interrupt mask */
device_t dev;
void *intrhand;
struct resource *irq_res;
int irq_rid;
struct resource *port_res;
int port_rid;
};
int sn_probe(device_t, int);
int sn_attach(device_t);
void sn_intr(void *);
int sn_activate(device_t);
void sn_deactivate(device_t);
#endif /* _IF_SNVAR_H */