This mega-merge brings Matt Thomas' 960801 FDDI driver (almost) up

to -current.

Thanks goes to Ulrike Nitzsche <ulrike@ifw-dresden.de> for giving me
a chance to test this.  Only the PCI driver is tested though.

One final patch will follow in a separate commit.  This is so that
everything up to here can be dragged into 2.2, if we decide so.

Reviewed by:	joerg
Submitted by:	Matt Thomas <matt@3am-software.com>
This commit is contained in:
Joerg Wunsch 1997-01-17 23:54:45 +00:00
parent 0e224fbc11
commit e4107dcf00
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=21830
16 changed files with 261 additions and 3776 deletions

View File

@ -308,16 +308,17 @@ pci/if_de.c optional de device-driver
pci/if_ed_p.c optional ed device-driver
pci/if_fxp.c optional fxp device-driver
pci/if_lnc_p.c optional lnc device-driver
pci/if_pdq.c optional fea device-driver
pci/if_pdq.c optional fpa device-driver
dev/pdq/pdq.c optional fea device-driver
dev/pdq/pdq_ifsubr.c optional fea device-driver
pci/if_fpa.c optional fpa device-driver
dev/pdq/pdq.c optional fpa device-driver
dev/pdq/pdq_ifsubr.c optional fpa device-driver
pci/if_sr_p.c optional sr device-driver
pci/if_vx_pci.c optional vx device-driver
pci/meteor.c optional meteor device-driver
pci/ncr.c optional ncr device-driver
pci/pci.c optional pci device-driver
pci/pcisupport.c optional pci
pci/pdq.c optional fea device-driver
pci/pdq.c optional fpa device-driver
pci/tek390.c optional amd device-driver
scsi/cd.c optional cd
scsi/ch.c optional ch

View File

@ -36,6 +36,7 @@ i386/eisa/aha1742.c optional ahb device-driver
i386/eisa/bt74x.c optional bt device-driver
i386/eisa/eisaconf.c optional eisa
i386/eisa/if_vx_eisa.c optional vx device-driver
i386/eisa/if_fea.c optional fea device-driver
i386/i386/autoconf.c standard device-driver
i386/i386/cons.c standard
i386/i386/db_disasm.c optional ddb

View File

@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: if_fea.c,v 1.7 1996/07/31 21:38:44 thomas Exp $
* $Id: if_fea.c,v 1.1.1.1 1997/01/17 23:19:49 joerg Exp $
*/
/*
@ -39,9 +39,7 @@
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#if defined(__FreeBSD__)
#include <sys/devconf.h>
#elif defined(__bsdi__) || defined(__NetBSD__)
#if defined(__bsdi__) || defined(__NetBSD__)
#include <sys/device.h>
#endif
@ -176,7 +174,7 @@ pdq_eisa_devinit(
}
#if defined(__FreeBSD__)
static int pdq_eisa_shutdown(struct kern_devconf *kdc, int force);
static void pdq_eisa_shutdown(int howto, void *sc);
static int pdq_eisa_probe(void);
static int pdq_eisa_attach(struct eisa_device *ed);
@ -188,23 +186,13 @@ static struct eisa_driver pdq_eisa_driver = {
DATA_SET(eisadriver_set, pdq_eisa_driver);
static struct kern_devconf kdc_pdq_eisa = {
0, 0, 0, /* filled in by dev_attach */
"fea", 0, { MDDT_EISA, 0, "net" },
eisa_generic_externalize, 0, pdq_eisa_shutdown, EISA_EXTERNALLEN,
&kdc_eisa0, /* parent */
0, /* parentdata */
DC_BUSY, /* host adapters are always ``in use'' */
"DEC DEFEA EISA FDDI Controller",
DC_CLS_NETIF
};
static const char *
pdq_eisa_match(
eisa_id_t type)
{
if ((type >> 8) == 0x10a330)
return kdc_pdq_eisa.kdc_description;
return ("DEC DEFEA EISA FDDI Controller");
return NULL;
}
@ -223,7 +211,7 @@ pdq_eisa_probe(
pdq_eisa_subprobe(PDQ_BUS_EISA, iobase, &maddr, &msize, &irq);
eisa_add_mspace(ed, maddr, msize, RESVADDR_NONE);
eisa_add_intr(ed, irq);
eisa_registerdev(ed, &pdq_eisa_driver, &kdc_pdq_eisa);
eisa_registerdev(ed, &pdq_eisa_driver);
}
return count;
}
@ -308,20 +296,17 @@ pdq_eisa_attach(
bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6);
pdq_ifattach(sc, pdq_eisa_ifwatchdog);
ed->kdc->kdc_state = DC_BUSY; /* host adapters always busy */
at_shutdown(pdq_eisa_shutdown, (void *) sc, SHUTDOWN_POST_SYNC);
return 0;
}
static int
static void
pdq_eisa_shutdown(
struct kern_devconf *kdc,
int force)
int howto,
void *sc)
{
pdq_hwreset(PDQ_EISA_UNIT_TO_SOFTC(kdc->kdc_unit)->sc_pdq);
(void) dev_detach(kdc);
return 0;
pdq_hwreset(((pdq_softc_t *)sc)->sc_pdq);
}
#endif /* __FreeBSD__ */

View File

@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: if_fpa.c,v 1.9 1996/07/31 21:38:44 thomas Exp $
* $Id: if_fpa.c,v 1.1.1.1 1997/01/17 23:19:49 joerg Exp $
*
*/
@ -40,9 +40,7 @@
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#if defined(__FreeBSD__)
#include <sys/devconf.h>
#elif defined(__bsdi__) || defined(__NetBSD__)
#if defined(__bsdi__) || defined(__NetBSD__)
#include <sys/device.h>
#endif
@ -161,6 +159,8 @@ pdq_pci_ifintr(
#endif /* __FreeBSD && BSD */
#if defined(__FreeBSD__)
static void pdq_pci_shutdown(int, void *);
/*
* This is the PCI configuration support. Since the PDQ is available
* on both EISA and PCI boards, one must be careful in how defines the
@ -223,17 +223,16 @@ pdq_pci_attach(
pdqs_pci[unit] = sc;
pdq_ifattach(sc, pdq_pci_ifwatchdog);
pci_map_int(config_id, pdq_pci_ifintr, (void*) sc, &net_imask);
at_shutdown(pdq_pci_shutdown, (void *) sc, SHUTDOWN_POST_SYNC);
}
static int
static void
pdq_pci_shutdown(
struct kern_devconf *kdc,
int force)
int howto,
void *sc)
{
if (kdc->kdc_unit < NFPA)
pdq_hwreset(PDQ_PCI_UNIT_TO_SOFTC(kdc->kdc_unit)->sc_pdq);
(void) dev_detach(kdc);
return 0;
pdq_hwreset(((pdq_softc_t *)sc)->sc_pdq);
}
static u_long pdq_pci_count;
@ -243,7 +242,7 @@ struct pci_device fpadevice = {
pdq_pci_probe,
pdq_pci_attach,
&pdq_pci_count,
pdq_pci_shutdown,
NULL
};
#ifdef DATA_SET

View File

@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: pdq.c,v 1.28 1996/07/31 21:38:44 thomas Exp $
* $Id: pdq.c,v 1.1.1.1 1997/01/17 23:19:48 joerg Exp $
*
*/
@ -39,8 +39,13 @@
#define PDQ_HWSUPPORT /* for pdq.h */
#if defined(__FreeBSD__)
#include <dev/pdq/pdqvar.h>
#include <dev/pdq/pdqreg.h>
#else
#include "pdqvar.h"
#include "pdqreg.h"
#endif
#define PDQ_ROUNDUP(n, x) (((n) + ((x) - 1)) & ~((x) - 1))
#define PDQ_CMD_RX_ALIGNMENT 16

View File

@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: pdq_ifsubr.c,v 1.8 1996/07/31 21:38:44 thomas Exp $
* $Id: pdq_ifsubr.c,v 1.1.1.1 1997/01/17 23:19:49 joerg Exp $
*
*/
@ -41,9 +41,7 @@
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#if defined(__FreeBSD__)
#include <sys/devconf.h>
#elif defined(__bsdi__) || defined(__NetBSD__)
#if defined(__bsdi__) || defined(__NetBSD__)
#include <sys/device.h>
#endif
@ -84,8 +82,13 @@
#include <vm/vm_kern.h>
#include <vm/vm_param.h>
#if defined(__FreeBSD__)
#include <dev/pdq/pdqvar.h>
#include <dev/pdq/pdqreg.h>
#else
#include "pdqvar.h"
#include "pdqreg.h"
#endif
#if defined(__bsdi__) && _BSDI_VERSION < 199506 /* XXX */
static void

View File

@ -36,6 +36,7 @@ i386/eisa/aha1742.c optional ahb device-driver
i386/eisa/bt74x.c optional bt device-driver
i386/eisa/eisaconf.c optional eisa
i386/eisa/if_vx_eisa.c optional vx device-driver
i386/eisa/if_fea.c optional fea device-driver
i386/i386/autoconf.c standard device-driver
i386/i386/cons.c standard
i386/i386/db_disasm.c optional ddb

View File

@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: if_fea.c,v 1.7 1996/07/31 21:38:44 thomas Exp $
* $Id: if_fea.c,v 1.1.1.1 1997/01/17 23:19:49 joerg Exp $
*/
/*
@ -39,9 +39,7 @@
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#if defined(__FreeBSD__)
#include <sys/devconf.h>
#elif defined(__bsdi__) || defined(__NetBSD__)
#if defined(__bsdi__) || defined(__NetBSD__)
#include <sys/device.h>
#endif
@ -176,7 +174,7 @@ pdq_eisa_devinit(
}
#if defined(__FreeBSD__)
static int pdq_eisa_shutdown(struct kern_devconf *kdc, int force);
static void pdq_eisa_shutdown(int howto, void *sc);
static int pdq_eisa_probe(void);
static int pdq_eisa_attach(struct eisa_device *ed);
@ -188,23 +186,13 @@ static struct eisa_driver pdq_eisa_driver = {
DATA_SET(eisadriver_set, pdq_eisa_driver);
static struct kern_devconf kdc_pdq_eisa = {
0, 0, 0, /* filled in by dev_attach */
"fea", 0, { MDDT_EISA, 0, "net" },
eisa_generic_externalize, 0, pdq_eisa_shutdown, EISA_EXTERNALLEN,
&kdc_eisa0, /* parent */
0, /* parentdata */
DC_BUSY, /* host adapters are always ``in use'' */
"DEC DEFEA EISA FDDI Controller",
DC_CLS_NETIF
};
static const char *
pdq_eisa_match(
eisa_id_t type)
{
if ((type >> 8) == 0x10a330)
return kdc_pdq_eisa.kdc_description;
return ("DEC DEFEA EISA FDDI Controller");
return NULL;
}
@ -223,7 +211,7 @@ pdq_eisa_probe(
pdq_eisa_subprobe(PDQ_BUS_EISA, iobase, &maddr, &msize, &irq);
eisa_add_mspace(ed, maddr, msize, RESVADDR_NONE);
eisa_add_intr(ed, irq);
eisa_registerdev(ed, &pdq_eisa_driver, &kdc_pdq_eisa);
eisa_registerdev(ed, &pdq_eisa_driver);
}
return count;
}
@ -308,20 +296,17 @@ pdq_eisa_attach(
bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6);
pdq_ifattach(sc, pdq_eisa_ifwatchdog);
ed->kdc->kdc_state = DC_BUSY; /* host adapters always busy */
at_shutdown(pdq_eisa_shutdown, (void *) sc, SHUTDOWN_POST_SYNC);
return 0;
}
static int
static void
pdq_eisa_shutdown(
struct kern_devconf *kdc,
int force)
int howto,
void *sc)
{
pdq_hwreset(PDQ_EISA_UNIT_TO_SOFTC(kdc->kdc_unit)->sc_pdq);
(void) dev_detach(kdc);
return 0;
pdq_hwreset(((pdq_softc_t *)sc)->sc_pdq);
}
#endif /* __FreeBSD__ */

View File

@ -1,6 +1,8 @@
/*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1995 Matt Thomas (thomas@lkg.dec.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -46,6 +48,7 @@ struct fddi_header {
u_char fddi_shost[6];
};
#define FDDIIPMTU 4352
#define FDDIMTU 4470
#define FDDIMIN 3
@ -66,17 +69,18 @@ struct fddi_header {
#define FDDIFC_LLC_SYNC 0xd0
#define FDDIFC_SMT 0x40
#ifdef KERNEL
#if defined(KERNEL) || defined(_KERNEL)
#define fddibroadcastaddr etherbroadcastaddr
#define fddi_ipmulticast_min ether_ipmulticast_min
#define fddi_ipmulticast_max ether_ipmulticast_max
#define fddi_addmulti ether_addmulti
#define fddi_delmulti ether_delmulti
#define fddi_sprintf ether_sprintf
void fddi_ifattach __P((struct ifnet *));
void fddi_input __P((struct ifnet *, struct fddi_header *, struct mbuf *));
int fddi_output __P((struct ifnet *,
struct mbuf *, struct sockaddr *, struct rtentry *));
struct mbuf *, struct sockaddr *, struct rtentry *));
#endif

View File

@ -1,4 +1,6 @@
/*
* Copyright (c) 1995, 1996
* Matt Thomas <matt@3am-software.com>. All rights reserved.
* Copyright (c) 1982, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
@ -45,6 +47,8 @@
#include <sys/errno.h>
#include <sys/syslog.h>
#include <machine/cpu.h>
#include <net/if.h>
#include <net/netisr.h>
#include <net/route.h>
@ -57,10 +61,14 @@
#include <netinet/in_var.h>
#endif
#include <netinet/if_ether.h>
#if defined(__FreeBSD__)
#include <netinet/if_fddi.h>
#else
#include <net/if_fddi.h>
#endif
#ifdef IPX
#include <netipx/ipx.h>
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#endif
@ -80,17 +88,29 @@
#include <netiso/iso_snpac.h>
#endif
#include "bpfilter.h"
#ifdef LLC
#include <netccitt/dll.h>
#include <netccitt/llc_var.h>
#endif
#ifdef NETATALK
#include <netatalk/at.h>
#include <netatalk/at_var.h>
#include <netatalk/at_extern.h>
#define llc_snap_org_code llc_un.type_snap.org_code
#define llc_snap_ether_type llc_un.type_snap.ether_type
extern u_char at_org_code[ 3 ];
extern u_char aarp_org_code[ 3 ];
#endif /* NETATALK */
#if defined(LLC) && defined(CCITT)
extern struct ifqueue pkintrq;
#endif
#include "bpfilter.h"
#define senderr(e) { error = (e); goto bad;}
/*
@ -100,11 +120,11 @@ extern struct ifqueue pkintrq;
#define llc_snap llc_un.type_snap
#endif
#ifdef __bsdi__
#define RTALLOC1(a, b) rtalloc1(a, b)
#if defined(__bsdi__) || defined(__NetBSD__)
#define RTALLOC1(a, b) rtalloc1(a, b)
#define ARPRESOLVE(a, b, c, d, e, f) arpresolve(a, b, c, d, e)
#else
#define RTALLOC1(a, b) rtalloc1(a, b, 0UL)
#elif defined(__FreeBSD__)
#define RTALLOC1(a, b) rtalloc1(a, b, 0UL)
#define ARPRESOLVE(a, b, c, d, e, f) arpresolve(a, b, c, d, e, f)
#endif
/*
@ -121,22 +141,24 @@ fddi_output(ifp, m0, dst, rt0)
struct sockaddr *dst;
struct rtentry *rt0;
{
short type;
u_int16_t type;
int s, error = 0;
u_char edst[6];
register struct mbuf *m = m0;
register struct rtentry *rt;
struct mbuf *mcopy = (struct mbuf *)0;
register struct fddi_header *fh;
struct mbuf *mcopy = (struct mbuf *)0;
struct arpcom *ac = (struct arpcom *)ifp;
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
senderr(ENETDOWN);
ifp->if_lastchange = time;
#if !defined(__bsdi__) || _BSDI_VERSION >= 199401
if (rt = rt0) {
if ((rt->rt_flags & RTF_UP) == 0) {
if (rt0 = rt = RTALLOC1(dst, 1))
rt->rt_refcnt--;
else
else
senderr(EHOSTUNREACH);
}
if (rt->rt_flags & RTF_GATEWAY) {
@ -154,21 +176,29 @@ fddi_output(ifp, m0, dst, rt0)
time.tv_sec < rt->rt_rmx.rmx_expire)
senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
}
#endif
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
case AF_INET: {
#if !defined(__bsdi__) || _BSDI_VERSION >= 199401
if (!ARPRESOLVE(ac, rt, m, dst, edst, rt0))
return (0); /* if not yet resolved */
#else
int usetrailers;
if (!arpresolve(ac, m, &((struct sockaddr_in *)dst)->sin_addr, edst, &usetrailers))
return (0); /* if not yet resolved */
#endif
/* If broadcasting on a simplex interface, loopback a copy */
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
mcopy = m_copy(m, 0, (int)M_COPYALL);
type = ETHERTYPE_IP;
type = htons(ETHERTYPE_IP);
break;
}
#endif
#ifdef IPX
case AF_IPX:
type = ETHERTYPE_IPX;
type = htons(ETHERTYPE_IPX);
bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host),
(caddr_t)edst, sizeof (edst));
if (!bcmp((caddr_t)edst, (caddr_t)&ipx_thishost, sizeof(edst)))
@ -178,9 +208,50 @@ fddi_output(ifp, m0, dst, rt0)
mcopy = m_copy(m, 0, (int)M_COPYALL);
break;
#endif
#ifdef NETATALK
case AF_APPLETALK: {
struct at_ifaddr *aa;
if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) {
#ifdef NETATALKDEBUG
extern char *prsockaddr(struct sockaddr *);
printf("aarpresolv: failed for %s\n", prsockaddr(dst));
#endif
return (0);
}
/*
* ifaddr is the first thing in at_ifaddr
*/
if ((aa = (struct at_ifaddr *)at_ifawithnet(
(struct sockaddr_at *)dst, ifp->if_addrlist))
== 0)
goto bad;
/*
* In the phase 2 case, we need to prepend an mbuf for the llc header.
* Since we must preserve the value of m, which is passed to us by
* value, we m_copy() the first mbuf, and use it for our llc header.
*/
if (aa->aa_flags & AFA_PHASE2) {
struct llc llc;
M_PREPEND(m, sizeof(struct llc), M_WAIT);
if (m == 0)
senderr(ENOBUFS);
llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
llc.llc_control = LLC_UI;
bcopy(at_org_code, llc.llc_snap_org_code, sizeof(at_org_code));
llc.llc_snap_ether_type = htons(ETHERTYPE_AT);
bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc));
type = 0;
} else {
type = htons(ETHERTYPE_AT);
}
break;
}
#endif /* NETATALK */
#ifdef NS
case AF_NS:
type = ETHERTYPE_NS;
type = htons(ETHERTYPE_NS);
bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
(caddr_t)edst, sizeof (edst));
if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst)))
@ -236,14 +307,12 @@ fddi_output(ifp, m0, dst, rt0)
#ifdef LLC
/* case AF_NSAP: */
case AF_CCITT: {
register struct sockaddr_dl *sdl =
register struct sockaddr_dl *sdl =
(struct sockaddr_dl *) rt -> rt_gateway;
if (sdl && sdl->sdl_family == AF_LINK
&& sdl->sdl_alen > 0) {
bcopy(LLADDR(sdl), (char *)edst,
sizeof(edst));
} else goto bad; /* Not a link interface ? Funny ... */
if (sdl && sdl->sdl_family != AF_LINK && sdl->sdl_alen <= 0)
goto bad; /* Not a link interface ? Funny ... */
bcopy(LLADDR(sdl), (char *)edst, sizeof(edst));
if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
(mcopy = m_copy(m, 0, (int)M_COPYALL))) {
M_PREPEND(mcopy, sizeof (*fh), M_DONTWAIT);
@ -265,14 +334,14 @@ fddi_output(ifp, m0, dst, rt0)
printf("fddi_output: sending LLC2 pkt to: ");
for (i=0; i<6; i++)
printf("%x ", edst[i] & 0xff);
printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n",
printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n",
type & 0xff, l->llc_dsap & 0xff, l->llc_ssap &0xff,
l->llc_control & 0xff);
}
#endif /* LLC_DEBUG */
} break;
#endif /* LLC */
#endif /* LLC */
case AF_UNSPEC:
{
@ -338,9 +407,8 @@ fddi_output(ifp, m0, dst, rt0)
l->llc_control = LLC_UI;
l->llc_dsap = l->llc_ssap = LLC_SNAP_LSAP;
l->llc_snap.org_code[0] = l->llc_snap.org_code[1] = l->llc_snap.org_code[2] = 0;
type = ntohs(type);
(void)memcpy((caddr_t) &l->llc_snap.ether_type, (caddr_t) &type,
sizeof(u_short));
sizeof(u_int16_t));
}
/*
* Add local net header. If no space in first mbuf,
@ -399,28 +467,58 @@ fddi_input(ifp, fh, m)
m_freem(m);
return;
}
ifp->if_lastchange = time;
ifp->if_ibytes += m->m_pkthdr.len + sizeof (*fh);
if (bcmp((caddr_t)fddibroadcastaddr, (caddr_t)fh->fddi_dhost,
sizeof(fddibroadcastaddr)) == 0)
m->m_flags |= M_BCAST;
else if (fh->fddi_dhost[0] & 1)
m->m_flags |= M_MCAST;
if (m->m_flags & (M_BCAST|M_MCAST))
if (fh->fddi_dhost[0] & 1) {
if (bcmp((caddr_t)fddibroadcastaddr, (caddr_t)fh->fddi_dhost,
sizeof(fddibroadcastaddr)) == 0)
m->m_flags |= M_BCAST;
else
m->m_flags |= M_MCAST;
ifp->if_imcasts++;
}
#ifdef M_LINK0
/*
* If this has a LLC priority of 0, then mark it so upper
* layers have a hint that it really came via a FDDI/Ethernet
* bridge.
*/
if ((fh->fddi_fc & FDDIFC_LLC_PRIO7) == FDDIFC_LLC_PRIO0)
m->m_flags |= M_LINK0;
#endif
l = mtod(m, struct llc *);
switch (l->llc_dsap) {
#if defined(INET) || defined(NS) || defined(DECNET)
#if defined(INET) || defined(NS) || defined(DECNET) || defined(IPX) || defined(NETATALK)
case LLC_SNAP_LSAP:
{
unsigned fddi_type;
u_int16_t type;
if (l->llc_control != LLC_UI || l->llc_ssap != LLC_SNAP_LSAP)
goto dropanyway;
#ifdef NETATALK
if (Bcmp(&(l->llc_snap_org_code)[0], at_org_code,
sizeof(at_org_code)) == 0 &&
ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) {
inq = &atintrq2;
m_adj( m, sizeof( struct llc ));
schednetisr(NETISR_ATALK);
break;
}
if (Bcmp(&(l->llc_snap_org_code)[0], aarp_org_code,
sizeof(aarp_org_code)) == 0 &&
ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) {
m_adj( m, sizeof( struct llc ));
aarpinput((struct arpcom *)ifp, m); /* XXX */
return;
}
#endif /* NETATALK */
if (l->llc_snap.org_code[0] != 0 || l->llc_snap.org_code[1] != 0|| l->llc_snap.org_code[2] != 0)
goto dropanyway;
fddi_type = ntohs(l->llc_snap.ether_type);
type = ntohs(l->llc_snap.ether_type);
m_adj(m, 8);
switch (fddi_type) {
switch (type) {
#ifdef INET
case ETHERTYPE_IP:
schednetisr(NETISR_IP);
@ -428,10 +526,21 @@ fddi_input(ifp, fh, m)
break;
case ETHERTYPE_ARP:
#if !defined(__bsdi__) || _BSDI_VERSION >= 199401
schednetisr(NETISR_ARP);
inq = &arpintrq;
break;
#else
arpinput((struct arpcom *)ifp, m);
return;
#endif
#endif
#ifdef IPX
case ETHERTYPE_IPX:
schednetisr(NETISR_IPX);
inq = &ipxintrq;
break;
#endif
#ifdef NS
case ETHERTYPE_NS:
schednetisr(NETISR_NS);
@ -439,12 +548,23 @@ fddi_input(ifp, fh, m)
break;
#endif
#ifdef DECNET
case ETHERTYPE_DECENT:
case ETHERTYPE_DECNET:
schednetisr(NETISR_DECNET);
inq = &decnetintrq;
break;
#endif
#ifdef NETATALK
case ETHERTYPE_AT:
schednetisr(NETISR_ATALK);
inq = &atintrq1;
break;
case ETHERTYPE_AARP:
/* probably this should be done with a NETISR as well */
aarpinput((struct arpcom *)ifp, m); /* XXX */
return;
#endif /* NETATALK */
default:
/* printf("fddi_input: unknown protocol 0x%x\n", type); */
ifp->if_noproto++;
goto dropanyway;
}
@ -452,7 +572,7 @@ fddi_input(ifp, fh, m)
}
#endif /* INET || NS */
#ifdef ISO
case LLC_ISO_LSAP:
case LLC_ISO_LSAP:
switch (l->llc_control) {
case LLC_UI:
/* LLC_UI_P forbidden in class 1 service */
@ -474,7 +594,7 @@ fddi_input(ifp, fh, m)
break;
}
goto dropanyway;
case LLC_XID:
case LLC_XID_P:
if(m->m_len < 6)
@ -488,7 +608,8 @@ fddi_input(ifp, fh, m)
case LLC_TEST_P:
{
struct sockaddr sa;
register struct ether_header *eh2;
register struct ether_header *eh;
struct arpcom *ac = (struct arpcom *) ifp;
int i;
u_char c = l->llc_dsap;
@ -499,14 +620,12 @@ fddi_input(ifp, fh, m)
(caddr_t)eh->ether_dhost, 6);
sa.sa_family = AF_UNSPEC;
sa.sa_len = sizeof(sa);
eh2 = (struct ether_header *)sa.sa_data;
eh = (struct ether_header *)sa.sa_data;
for (i = 0; i < 6; i++) {
eh2->ether_shost[i] = c = eh->fddi_dhost[i];
eh2->ether_dhost[i] =
eh->ether_dhost[i] = eh->fddi_shost[i];
eh2->ether_shost[i] = c;
eh->ether_shost[i] = fh->fddi_dhost[i];
eh->ether_dhost[i] = fh->fddi_shost[i];
}
eh2->ether_type = 0;
eh->ether_type = 0;
ifp->if_output(ifp, m, &sa, NULL);
return;
}
@ -523,7 +642,7 @@ fddi_input(ifp, fh, m)
if (m == 0)
return;
if ( !sdl_sethdrif(ifp, fh->fddi_shost, LLC_X25_LSAP,
fh->fddi_dhost, LLC_X25_LSAP, 6,
fh->fddi_dhost, LLC_X25_LSAP, 6,
mtod(m, struct sdl_hdr *)))
panic("ETHER cons addr failure");
mtod(m, struct sdl_hdr *)->sdlhdr_len = m->m_pkthdr.len - sizeof(struct sdl_hdr);
@ -535,9 +654,9 @@ fddi_input(ifp, fh, m)
break;
}
#endif /* LLC */
default:
printf("fddi_input: unknown dsap 0x%x\n", l->llc_dsap);
/* printf("fddi_input: unknown dsap 0x%x\n", l->llc_dsap); */
ifp->if_noproto++;
dropanyway:
m_freem(m);
@ -555,6 +674,10 @@ fddi_input(ifp, fh, m)
/*
* Perform common duties while attaching to interface list
*/
#ifdef __NetBSD__
#define ifa_next ifa_list.tqe_next
#endif
void
fddi_ifattach(ifp)
register struct ifnet *ifp;
@ -567,9 +690,21 @@ fddi_ifattach(ifp)
ifp->if_hdrlen = 21;
ifp->if_mtu = FDDIMTU;
ifp->if_baudrate = 100000000;
ifa = ifnet_addrs[ifp->if_index - 1];
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
sdl->sdl_type = IFT_FDDI;
sdl->sdl_alen = ifp->if_addrlen;
bcopy(((struct arpcom *)ifp)->ac_enaddr, LLADDR(sdl), ifp->if_addrlen);
#ifdef IFF_NOTRAILERS
ifp->if_flags |= IFF_NOTRAILERS;
#endif
#if defined(__NetBSD__)
LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs);
for (ifa = ifp->if_addrlist.tqh_first; ifa != NULL; ifa = ifa->ifa_list.tqe_next)
#else
for (ifa = ifp->if_addrlist; ifa != NULL; ifa = ifa->ifa_next)
#endif
if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
sdl->sdl_family == AF_LINK) {
sdl->sdl_type = IFT_FDDI;
sdl->sdl_alen = ifp->if_addrlen;
bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
LLADDR(sdl), ifp->if_addrlen);
break;
}
}

View File

@ -1,6 +1,8 @@
/*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1995 Matt Thomas (thomas@lkg.dec.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -46,6 +48,7 @@ struct fddi_header {
u_char fddi_shost[6];
};
#define FDDIIPMTU 4352
#define FDDIMTU 4470
#define FDDIMIN 3
@ -66,17 +69,18 @@ struct fddi_header {
#define FDDIFC_LLC_SYNC 0xd0
#define FDDIFC_SMT 0x40
#ifdef KERNEL
#if defined(KERNEL) || defined(_KERNEL)
#define fddibroadcastaddr etherbroadcastaddr
#define fddi_ipmulticast_min ether_ipmulticast_min
#define fddi_ipmulticast_max ether_ipmulticast_max
#define fddi_addmulti ether_addmulti
#define fddi_delmulti ether_delmulti
#define fddi_sprintf ether_sprintf
void fddi_ifattach __P((struct ifnet *));
void fddi_input __P((struct ifnet *, struct fddi_header *, struct mbuf *));
int fddi_output __P((struct ifnet *,
struct mbuf *, struct sockaddr *, struct rtentry *));
struct mbuf *, struct sockaddr *, struct rtentry *));
#endif

View File

@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: if_fpa.c,v 1.9 1996/07/31 21:38:44 thomas Exp $
* $Id: if_fpa.c,v 1.1.1.1 1997/01/17 23:19:49 joerg Exp $
*
*/
@ -40,9 +40,7 @@
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#if defined(__FreeBSD__)
#include <sys/devconf.h>
#elif defined(__bsdi__) || defined(__NetBSD__)
#if defined(__bsdi__) || defined(__NetBSD__)
#include <sys/device.h>
#endif
@ -161,6 +159,8 @@ pdq_pci_ifintr(
#endif /* __FreeBSD && BSD */
#if defined(__FreeBSD__)
static void pdq_pci_shutdown(int, void *);
/*
* This is the PCI configuration support. Since the PDQ is available
* on both EISA and PCI boards, one must be careful in how defines the
@ -223,17 +223,16 @@ pdq_pci_attach(
pdqs_pci[unit] = sc;
pdq_ifattach(sc, pdq_pci_ifwatchdog);
pci_map_int(config_id, pdq_pci_ifintr, (void*) sc, &net_imask);
at_shutdown(pdq_pci_shutdown, (void *) sc, SHUTDOWN_POST_SYNC);
}
static int
static void
pdq_pci_shutdown(
struct kern_devconf *kdc,
int force)
int howto,
void *sc)
{
if (kdc->kdc_unit < NFPA)
pdq_hwreset(PDQ_PCI_UNIT_TO_SOFTC(kdc->kdc_unit)->sc_pdq);
(void) dev_detach(kdc);
return 0;
pdq_hwreset(((pdq_softc_t *)sc)->sc_pdq);
}
static u_long pdq_pci_count;
@ -243,7 +242,7 @@ struct pci_device fpadevice = {
pdq_pci_probe,
pdq_pci_attach,
&pdq_pci_count,
pdq_pci_shutdown,
NULL
};
#ifdef DATA_SET

View File

@ -1,801 +0,0 @@
/*-
* Copyright (c) 1995 Matt Thomas (thomas@lkg.dec.com)
* 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. The name of the author may not be used to endorse or promote products
* derived from this software withough 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$
*
*/
/*
* DEC PDQ FDDI Controller; code for BSD derived operating systems
*
* Written by Matt Thomas
*
* This driver supports the following FDDI controllers:
*
* Device: Config file entry:
* DEC DEFPA (PCI) device fpa0
* DEC DEFEA (EISA) device fea0 at isa0 net irq ? vector feaintr
*
* Eventually, the following adapters will also be supported:
*
* DEC DEFTA (TC) device fta0 at tc? slot * vector ftaintr
* DEC DEFQA (Q-Bus) device fta0 at uba? csr 0?? vector fqaintr
* DEC DEFAA (FB+) device faa0 at fbus? slot * vector faaintr
*/
#include "fea.h" /* DEFPA EISA FDDI */
#ifndef __bsdi__
#include "fpa.h" /* DEFPA PCI FDDI */
#endif
#if NFPA > 0 || NFEA > 0
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/conf.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/if_dl.h>
#include <net/route.h>
#include "bpfilter.h"
#if NBPFILTER > 0
#include <net/bpf.h>
#include <net/bpfdesc.h>
#endif
#ifdef INET
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#endif
#include <netinet/if_fddi.h>
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
#endif
#include <vm/vm.h>
#include <vm/vm_kern.h>
#if NFPA > 0
#include <pci/pcivar.h>
#include <i386/isa/icu.h>
#endif
#if NFEA > 0
#include <i386/isa/icu.h>
#ifdef __FreeBSD__
#include <i386/isa/isa_device.h>
#endif
#ifdef __bsdi__
#include <sys/device.h>
#include <i386/isa/isavar.h>
#include <i386/eisa/eisa.h>
#endif
#endif
#include <pci/pdqreg.h>
#include <pci/pdq_os.h>
typedef struct {
#ifdef __bsdi__
struct device sc_dev; /* base device */
struct isadev sc_id; /* ISA device */
struct intrhand sc_ih; /* intrrupt vectoring */
struct atshutdown sc_ats; /* shutdown routine */
#endif
struct arpcom sc_ac;
void (*if_init) __P((int unit));
pdq_t *sc_pdq;
#if NFEA > 0
unsigned sc_iobase;
#endif
} pdq_softc_t;
#define sc_if sc_ac.ac_if
#if defined(__FreeBSD__)
#define sc_bpf sc_if.if_bpf
typedef void ifnet_ret_t;
#elif defined(__bsdi__)
#define sc_bpf sc_if.if_bpf
typedef int ifnet_ret_t;
#endif
static void
pdq_ifreset(
pdq_softc_t *sc)
{
pdq_stop(sc->sc_pdq);
}
static void
pdq_ifinit(
pdq_softc_t *sc)
{
if (sc->sc_if.if_flags & IFF_UP) {
sc->sc_if.if_flags |= IFF_RUNNING;
if (sc->sc_if.if_flags & IFF_PROMISC) {
sc->sc_pdq->pdq_flags |= PDQ_PROMISC;
} else {
sc->sc_pdq->pdq_flags &= ~PDQ_PROMISC;
}
if (sc->sc_if.if_flags & IFF_ALLMULTI) {
sc->sc_pdq->pdq_flags |= PDQ_ALLMULTI;
} else {
sc->sc_pdq->pdq_flags &= ~PDQ_ALLMULTI;
}
if (sc->sc_if.if_flags & IFF_LINK1) {
sc->sc_pdq->pdq_flags |= PDQ_PASS_SMT;
} else {
sc->sc_pdq->pdq_flags &= ~PDQ_PASS_SMT;
}
sc->sc_pdq->pdq_flags |= PDQ_RUNNING;
pdq_run(sc->sc_pdq);
} else {
sc->sc_if.if_flags &= ~IFF_RUNNING;
sc->sc_pdq->pdq_flags &= ~PDQ_RUNNING;
pdq_stop(sc->sc_pdq);
}
}
static void
pdq_ifwatchdog(
pdq_softc_t *sc)
{
struct mbuf *m;
/*
* No progress was made on the transmit queue for PDQ_OS_TX_TRANSMIT
* seconds. Remove all queued packets.
*/
sc->sc_if.if_flags &= ~IFF_OACTIVE;
sc->sc_if.if_timer = 0;
for (;;) {
IF_DEQUEUE(&sc->sc_if.if_snd, m);
if (m == NULL)
return;
m_freem(m);
}
}
static ifnet_ret_t
pdq_ifstart(
struct ifnet *ifp)
{
pdq_softc_t *sc = (pdq_softc_t *) ((caddr_t) ifp - offsetof(pdq_softc_t, sc_ac.ac_if));
struct ifqueue *ifq = &ifp->if_snd;
struct mbuf *m;
int tx = 0;
if ((ifp->if_flags & IFF_RUNNING) == 0)
return;
if (sc->sc_if.if_timer == 0)
sc->sc_if.if_timer = PDQ_OS_TX_TIMEOUT;
if ((sc->sc_pdq->pdq_flags & PDQ_TXOK) == 0) {
sc->sc_if.if_flags |= IFF_OACTIVE;
return;
}
for (;; tx = 1) {
IF_DEQUEUE(ifq, m);
if (m == NULL)
break;
if (pdq_queue_transmit_data(sc->sc_pdq, m) == PDQ_FALSE) {
ifp->if_flags |= IFF_OACTIVE;
IF_PREPEND(ifq, m);
break;
}
}
if (tx)
PDQ_DO_TYPE2_PRODUCER(sc->sc_pdq);
}
void
pdq_os_receive_pdu(
pdq_t *pdq,
struct mbuf *m,
size_t pktlen)
{
pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx;
struct fddi_header *fh = mtod(m, struct fddi_header *);
sc->sc_if.if_ipackets++;
#if NBPFILTER > 0
if (sc->sc_bpf != NULL)
bpf_mtap(&sc->sc_if, m);
if ((fh->fddi_fc & (FDDIFC_L|FDDIFC_F)) != FDDIFC_LLC_ASYNC) {
m_freem(m);
return;
}
#endif
m->m_data += sizeof(struct fddi_header);
m->m_len -= sizeof(struct fddi_header);
m->m_pkthdr.len = pktlen - sizeof(struct fddi_header);
m->m_pkthdr.rcvif = &sc->sc_if;
fddi_input(&sc->sc_if, fh, m);
}
void
pdq_os_restart_transmitter(
pdq_t *pdq)
{
pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx;
sc->sc_if.if_flags &= ~IFF_OACTIVE;
if (sc->sc_if.if_snd.ifq_head != NULL) {
sc->sc_if.if_timer = PDQ_OS_TX_TIMEOUT;
pdq_ifstart(&sc->sc_if);
} else {
sc->sc_if.if_timer = 0;
}
}
void
pdq_os_transmit_done(
pdq_t *pdq,
struct mbuf *m)
{
pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx;
#if NBPFILTER > 0
if (sc->sc_bpf != NULL)
bpf_mtap(&sc->sc_if, m);
#endif
m_freem(m);
sc->sc_if.if_opackets++;
}
void
pdq_os_addr_fill(
pdq_t *pdq,
pdq_lanaddr_t *addr,
size_t num_addrs)
{
pdq_softc_t *sc = (pdq_softc_t *) pdq->pdq_os_ctx;
struct ifmultiaddr *ifma;
for (ifma = sc->sc_if.if_multiaddrs.lh_first; ifma && num_addrs > 0;
ifma = ifma->ifma_link.le_next) {
char *mcaddr;
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
mcaddr = LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
((u_short *) addr->lanaddr_bytes)[0] = ((u_short *) mcaddr)[0];
((u_short *) addr->lanaddr_bytes)[1] = ((u_short *) mcaddr)[1];
((u_short *) addr->lanaddr_bytes)[2] = ((u_short *) mcaddr)[2];
addr++;
num_addrs--;
}
}
static int
pdq_ifioctl(
struct ifnet *ifp,
int cmd,
caddr_t data)
{
pdq_softc_t *sc = (pdq_softc_t *) ((caddr_t) ifp - offsetof(pdq_softc_t, sc_ac.ac_if));
int s, error = 0;
s = splimp();
switch (cmd) {
case SIOCSIFADDR: {
struct ifaddr *ifa = (struct ifaddr *)data;
ifp->if_flags |= IFF_UP;
switch(ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET: {
(*sc->if_init)(ifp->if_unit);
#ifdef __FreeBSD__
arp_ifinit((struct arpcom *)ifp, ifa);
#else
((struct arpcom *)ifp)->ac_ipaddr = IA_SIN(ifa)->sin_addr;
arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
#endif
break;
}
#endif /* INET */
#ifdef NS
/* This magic copied from if_is.c; I don't use XNS,
* so I have no way of telling if this actually
* works or not.
*/
case AF_NS: {
struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
if (ns_nullhost(*ina)) {
ina->x_host = *(union ns_host *)(sc->sc_ac.ac_enaddr);
} else {
ifp->if_flags &= ~IFF_RUNNING;
bcopy((caddr_t)ina->x_host.c_host,
(caddr_t)sc->sc_ac.ac_enaddr,
sizeof sc->sc_ac.ac_enaddr);
}
(*sc->if_init)(ifp->if_unit);
break;
}
#endif /* NS */
default: {
(*sc->if_init)(ifp->if_unit);
break;
}
}
break;
}
case SIOCSIFFLAGS: {
(*sc->if_init)(ifp->if_unit);
break;
}
case SIOCADDMULTI:
case SIOCDELMULTI:
/*
* Update multicast listeners
*/
if (sc->sc_if.if_flags & IFF_RUNNING)
pdq_run(sc->sc_pdq);
error = 0;
break;
default: {
error = EINVAL;
break;
}
}
splx(s);
return error;
}
static void
pdq_ifattach(
pdq_softc_t *sc,
ifnet_ret_t (*ifinit)(int unit),
ifnet_ret_t (*ifreset)(int unit),
ifnet_ret_t (*ifwatchdog)(struct ifnet *ifp))
{
struct ifnet *ifp = &sc->sc_if;
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST;
sc->if_init = ifinit;
ifp->if_watchdog = ifwatchdog;
ifp->if_ioctl = pdq_ifioctl;
ifp->if_output = fddi_output;
ifp->if_start = pdq_ifstart;
#warning "Implement fddi_resolvemulti!"
/* ifp->if_resolvemulti = ether_resolvemulti; XXX */
if_attach(ifp);
fddi_ifattach(ifp);
#if NBPFILTER > 0
bpfattach(ifp, DLT_FDDI, sizeof(struct fddi_header));
#endif
}
#if NFPA > 0
/*
* This is the PCI configuration support. Since the PDQ is available
* on both EISA and PCI boards, one must be careful in how defines the
* PDQ in the config file.
*/
static char *pdq_pci_probe (pcici_t config_id, pcidi_t device_id);
static void pdq_pci_attach(pcici_t config_id, int unit);
static u_long pdq_pci_count;
static struct pci_device fpadevice = {
"fpa",
pdq_pci_probe,
pdq_pci_attach,
&pdq_pci_count,
NULL
};
#if defined(__FreeBSD__)
static pdq_softc_t *pdqs_pci[NFPA];
#define PDQ_PCI_UNIT_TO_SOFTC(unit) (pdqs_pci[unit])
#ifdef DATA_SET
DATA_SET (pcidevice_set, fpadevice);
#endif
#endif
#define PCI_CBMA 0x10 /* Configuration Base Memory Address */
static ifnet_ret_t
pdq_pci_ifreset(
int unit)
{
pdq_ifreset(PDQ_PCI_UNIT_TO_SOFTC(unit));
}
static ifnet_ret_t
pdq_pci_ifinit(
int unit)
{
pdq_ifinit(PDQ_PCI_UNIT_TO_SOFTC(unit));
}
static ifnet_ret_t
pdq_pci_ifwatchdog(struct ifnet *ifp)
{
pdq_ifwatchdog(PDQ_PCI_UNIT_TO_SOFTC(ifp->if_unit));
}
static
#ifdef __FreeBSD__
void
#else
int
#endif
pdq_pci_ifintr(
void *vsc)
{
pdq_softc_t *sc = vsc;
#ifndef __FreeBSD__
return
#endif
pdq_interrupt(sc->sc_pdq);
}
static char *
pdq_pci_probe(
pcici_t config_id,
pcidi_t device_id)
{
if (device_id == 0x000f1011ul)
return "Digital DEFPA PCI FDDI Controller";
return NULL;
}
static void
pdq_pci_attach(
pcici_t config_id,
int unit)
{
pdq_softc_t *sc;
vm_offset_t va_csrs, pa_csrs;
if (unit > NFPA) {
printf("fpa%d: not configured; kernel is built for only %d device%s.\n",
unit, NFPA, NFPA == 1 ? "" : "s");
return;
}
sc = (pdq_softc_t *) malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
if (sc == NULL)
return;
bzero(sc, sizeof(pdq_softc_t)); /* Zero out the softc*/
if (!pci_map_mem(config_id, PCI_CBMA, &va_csrs, &pa_csrs)) {
free((void *) sc, M_DEVBUF);
return;
}
sc->sc_if.if_name = "fpa";
sc->sc_if.if_unit = unit;
sc->sc_pdq = pdq_initialize((void *) va_csrs, "fpa", unit,
(void *) sc, PDQ_DEFPA);
if (sc->sc_pdq == NULL) {
free((void *) sc, M_DEVBUF);
return;
}
bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6);
pdqs_pci[unit] = sc;
pdq_ifattach(sc, pdq_pci_ifinit, pdq_pci_ifreset, pdq_pci_ifwatchdog);
pci_map_int(config_id, pdq_pci_ifintr, (void*) sc, &net_imask);
}
#endif /* NFPA > 0 */
#if NFEA > 0
/*
*
*/
static const int pdq_eisa_irqs[4] = { IRQ9, IRQ10, IRQ11, IRQ15 };
#ifdef __FreeBSD__
static pdq_softc_t *pdqs_eisa[NFEA];
#define PDQ_EISA_UNIT_TO_SOFTC(unit) (pdqs_eisa[unit])
#endif
#ifdef __bsdi__
extern struct cfdriver feacd;
#define PDQ_EISA_UNIT_TO_SOFTC(unit) ((pdq_softc_t *)feacd.cd_devs[unit])
#endif
static ifnet_ret_t
pdq_eisa_ifreset(
int unit)
{
pdq_ifreset(PDQ_EISA_UNIT_TO_SOFTC(unit));
}
static ifnet_ret_t
pdq_eisa_ifinit(
int unit)
{
pdq_ifinit(PDQ_EISA_UNIT_TO_SOFTC(unit));
}
static ifnet_ret_t
pdq_eisa_ifwatchdog(struct ifnet *ifp)
{
pdq_ifwatchdog(PDQ_EISA_UNIT_TO_SOFTC(ifp->if_unit));
}
#ifdef __FreeBSD__
void
#else
int
#endif
feaintr(
int unit)
{
pdq_interrupt(PDQ_EISA_UNIT_TO_SOFTC(unit)->sc_pdq);
#ifndef __FreeBSD__
return unit;
#endif
}
static void
pdq_eisa_subprobe(
pdq_uint32_t iobase,
pdq_uint32_t *maddr,
pdq_uint32_t *msize,
pdq_uint32_t *irq)
{
if (irq != NULL)
*irq = pdq_eisa_irqs[PDQ_OS_IORD_8(iobase + PDQ_EISA_IO_CONFIG_STAT_0) & 3];
*maddr = (PDQ_OS_IORD_8(iobase + PDQ_EISA_MEM_ADD_CMP_0) << 16)
| (PDQ_OS_IORD_8(iobase + PDQ_EISA_MEM_ADD_CMP_1) << 8);
*msize = (PDQ_OS_IORD_8(iobase + PDQ_EISA_MEM_ADD_MASK_0) + 4) << 8;
}
static void
pdq_eisa_devinit(
pdq_softc_t *sc)
{
pdq_uint8_t data;
/*
* Do the standard initialization for the DEFEA registers.
*/
PDQ_OS_IOWR_8(sc->sc_iobase + PDQ_EISA_FUNCTION_CTRL, 0x23);
PDQ_OS_IOWR_8(sc->sc_iobase + PDQ_EISA_IO_CMP_1_1, (sc->sc_iobase >> 8) & 0x0F);
PDQ_OS_IOWR_8(sc->sc_iobase + PDQ_EISA_IO_CMP_1_0, (sc->sc_iobase >> 8) & 0x0F);
PDQ_OS_IOWR_8(sc->sc_iobase + PDQ_EISA_SLOT_CTRL, 0x01);
data = PDQ_OS_IORD_8(sc->sc_iobase + PDQ_EISA_BURST_HOLDOFF);
PDQ_OS_IOWR_8(sc->sc_iobase + PDQ_EISA_BURST_HOLDOFF, data | 1);
data = PDQ_OS_IORD_8(sc->sc_iobase + PDQ_EISA_IO_CONFIG_STAT_0);
PDQ_OS_IOWR_8(sc->sc_iobase + PDQ_EISA_IO_CONFIG_STAT_0, data | 8);
}
#ifdef __FreeBSD__
static int pdq_eisa_slots = ~1;
static int
pdq_eisa_probe(
struct isa_device *id)
{
pdq_softc_t *sc;
int slot;
pdq_uint32_t data, irq, maddr, msize;
slot = 0x1000 * (ffs(pdq_eisa_slots) - 1);
for (; slot <= 0xF000; slot++) {
pdq_eisa_slots &= ~(1 << (slot >> 12));
data = PDQ_OS_IORD_32(slot + PDQ_EISA_SLOT_ID);
if ((data & 0xFFFFFF) != 0x30A310)
continue;
id->id_iobase = slot;
pdq_eisa_subprobe(slot, &maddr, &msize, &irq);
if (id->id_irq != 0 && irq != id->id_irq) {
printf("fea%d: error: desired IRQ of %d does not match device's actual IRQ (%d),\n",
id->id_unit,
ffs(id->id_irq) - 1, ffs(irq) - 1);
return 0;
}
id->id_irq = irq;
if (maddr == 0) {
printf("fea%d: error: memory not enabled! ECU reconfiguration required\n",
id->id_unit);
return 0;
}
id->id_maddr = (caddr_t) pmap_mapdev(maddr, msize);
if (id->id_maddr == NULL)
return 0;
id->id_msize = msize;
if (PDQ_EISA_UNIT_TO_SOFTC(id->id_unit) == NULL) {
sc = (pdq_softc_t *) malloc(sizeof(pdq_softc_t), M_DEVBUF, M_WAITOK);
if (sc == NULL)
return 0;
PDQ_EISA_UNIT_TO_SOFTC(id->id_unit) = sc;
}
return 0x1000;
}
return 0;
}
static int
pdq_eisa_attach(
struct isa_device *id)
{
pdq_softc_t *sc = PDQ_EISA_UNIT_TO_SOFTC(id->id_unit);
bzero(sc, sizeof(pdq_softc_t)); /* Zero out the softc*/
sc->sc_if.if_name = "fea";
sc->sc_if.if_unit = id->id_unit;
sc->sc_iobase = id->id_iobase;
pdq_eisa_devinit(sc);
sc->sc_pdq = pdq_initialize((void *) id->id_maddr, "fea", sc->sc_if.if_unit,
(void *) sc, PDQ_DEFEA);
if (sc->sc_pdq == NULL) {
printf("fea%d: initialization failed\n", sc->sc_if.if_unit);
return 0;
}
bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6);
pdq_ifattach(sc, pdq_eisa_ifinit, pdq_eisa_ifreset, pdq_eisa_ifwatchdog);
return 1;
}
/*
*
*/
struct isa_driver feadriver = {
pdq_eisa_probe,
pdq_eisa_attach,
"fea"
};
#endif /* __FreeBSD__ */
#ifdef __bsdi__
int
pdq_eisa_probe(
struct device *parent,
struct cfdata *cf,
void *aux)
{
struct isa_attach_args *ia = (struct isa_attach_args *) aux;
int slot;
pdq_uint32_t irq, maddr, msize;
if (isa_bustype != BUS_EISA)
return (0);
if ((slot = eisa_match(cf, ia)) == 0)
return (0);
ia->ia_iobase = slot << 12;
ia->ia_iosize = EISA_NPORT;
eisa_slotalloc(slot);
pdq_eisa_subprobe(ia->ia_iobase, &maddr, &msize, &irq);
if (ia->ia_irq != IRQUNK && irq != ia->ia_irq) {
printf("fea%d: error: desired IRQ of %d does not match device's actual IRQ (%d),\n",
cf->cf_unit,
ffs(ia->ia_irq) - 1, ffs(irq) - 1);
return 0;
}
if (ia->ia_irq == IRQUNK) {
if ((irq = isa_irqalloc(irq)) == 0)
return 0;
ia->ia_irq = irq;
}
if (maddr == 0) {
printf("fea%d: error: memory not enabled! ECU reconfiguration required\n",
cf->cf_unit);
return 0;
}
/* EISA bus masters don't use host DMA channels */
ia->ia_drq = 0; /* XXX should be DRQUNK or DRQBUSMASTER? */
#if 0
ia->ia_maddr = maddr;
ia->ia_msize = msize;
#else
ia->ia_maddr = 0;
ia->ia_msize = 0;
#endif
return 1;
}
void
pdq_eisa_attach(
struct device *parent,
struct device *self,
void *aux)
{
pdq_softc_t *sc = (pdq_softc_t *) self;
register struct isa_attach_args *ia = (struct isa_attach_args *) aux;
register struct ifnet *ifp = &sc->sc_if;
int i;
sc->sc_if.if_unit = sc->sc_dev.dv_unit;
sc->sc_if.if_name = "fea";
sc->sc_if.if_flags = 0;
sc->sc_iobase = ia->ia_iobase;
sc->sc_pdq = pdq_initialize((void *) ISA_HOLE_VADDR(ia->ia_maddr), "fea",
sc->sc_if.if_unit, (void *) sc, PDQ_DEFEA);
if (sc->sc_pdq == NULL) {
printf("fea%d: initialization failed\n", sc->sc_if.if_unit);
return;
}
bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6);
pdq_ifattach(sc, pdq_eisa_ifinit, pdq_eisa_ifreset, pdq_eisa_ifwatchdog);
isa_establish(&sc->sc_id, &sc->sc_dev);
sc->sc_ih.ih_fun = feaintr;
sc->sc_ih.ih_arg = (void *)sc;
intr_establish(ia->ia_irq, &sc->sc_ih, DV_NET);
sc->sc_ats.func = (void (*)(void *)) pdq_stop;
sc->sc_ats.arg = (void *) sc->sc_pdq;
atshutdown(&sc->sc_ats, ATSH_ADD);
}
static char *pdq_eisa_ids[] = {
"DEC3001", /* 0x0130A310 */
"DEC3002", /* 0x0230A310 */
"DEC3003", /* 0x0330A310 */
"DEC3004", /* 0x0430A310 */
};
struct cfdriver feacd = {
0, "fea", pdq_eisa_probe, pdq_eisa_attach, DV_IFNET, sizeof(pdq_softc_t),
pdq_eisa_ids
};
#endif /* __bsdi__ */
#endif /* NFEA > 0 */
#endif /* NFPA > 0 || NFEA > 0 */

File diff suppressed because it is too large Load Diff

View File

@ -1,166 +0,0 @@
/*-
* Copyright (c) 1995 Matt Thomas (thomas@lkg.dec.com)
* 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. The name of the author 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$
*
*/
/*
* DEC PDQ FDDI Controller; PDQ O/S dependent definitions
*
* Written by Matt Thomas
*
*/
#ifndef _PDQ_OS_H
#define _PDQ_OS_H
#define PDQ_OS_TX_TIMEOUT 5 /* seconds */
#ifdef PDQTEST
#include <pdq_os_test.h>
#elif defined(__FreeBSD__) || defined(__bsdi__)
#include <sys/param.h>
#include <sys/systm.h>
#ifndef M_MCAST
#include <sys/mbuf.h>
#endif
#include <sys/malloc.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <vm/vm_kern.h>
#include <vm/vm_extern.h>
#ifdef __FreeBSD__
#include <machine/clock.h>
#endif
#define PDQ_USE_MBUFS
#define PDQ_OS_PREFIX "%s%d: "
#define PDQ_OS_PREFIX_ARGS pdq->pdq_os_name, pdq->pdq_unit
#define PDQ_OS_PAGESIZE PAGE_SIZE
#define PDQ_OS_USEC_DELAY(n) DELAY(n)
#define PDQ_OS_MEMZERO(p, n) bzero((caddr_t)(p), (n))
#define PDQ_OS_VA_TO_PA(p) vtophys(p)
#define PDQ_OS_MEMALLOC(n) malloc(n, M_DEVBUF, M_NOWAIT)
#define PDQ_OS_MEMFREE(p, n) free((void *) p, M_DEVBUF)
#ifdef __FreeBSD__
#define PDQ_OS_MEMALLOC_CONTIG(n) vm_page_alloc_contig(n, 0, 0xffffffff, PAGE_SIZE)
#define PDQ_OS_MEMFREE_CONTIG(p, n) kmem_free(kernel_map, (vm_offset_t) p, n)
#else
#define PDQ_OS_MEMALLOC_CONTIG PDQ_OS_MEMALLOC
#define PDQ_OS_MEMFREE_CONTIG PDQ_OS_MEMFREE
#endif
#if defined(__FreeBSD__)
#include <machine/cpufunc.h>
#elif defined(__bsdi__)
#include <machine/inline.h>
#endif
#define PDQ_OS_IORD_32(port) inl(port)
#define PDQ_OS_IOWR_32(port, data) outl(port, data)
#define PDQ_OS_IORD_8(port) inb(port)
#define PDQ_OS_IOWR_8(port, data) outb(port, data)
#endif
#ifdef PDQ_USE_MBUFS
#define PDQ_OS_DATABUF_SIZE (MCLBYTES)
#define PDQ_OS_DATABUF_FREE(b) (m_freem(b))
#define PDQ_OS_DATABUF_NEXT(b) ((b)->m_next)
#define PDQ_OS_DATABUF_NEXT_SET(b, b1) ((b)->m_next = (b1))
#define PDQ_OS_DATABUF_NEXTPKT(b) ((b)->m_nextpkt)
#define PDQ_OS_DATABUF_NEXTPKT_SET(b, b1) ((b)->m_nextpkt = (b1))
#define PDQ_OS_DATABUF_LEN(b) ((b)->m_len)
#define PDQ_OS_DATABUF_LEN_SET(b, n) ((b)->m_len = (n))
#define PDQ_OS_DATABUF_LEN_ADJ(b, n) ((b)->m_len += (n))
#define PDQ_OS_DATABUF_PTR(b) (mtod((b), pdq_uint8_t *))
#define PDQ_OS_DATABUF_PTR_ADJ(b, n) ((b)->m_data += (n))
typedef struct mbuf PDQ_OS_DATABUF_T;
#define PDQ_OS_DATABUF_ALLOC(b) do { \
PDQ_OS_DATABUF_T *x_m0; \
MGETHDR(x_m0, M_DONTWAIT, MT_DATA); \
if (x_m0 != NULL) { \
MCLGET(x_m0, M_DONTWAIT); \
if ((x_m0->m_flags & M_EXT) == 0) { \
m_free(x_m0); \
(b) = NULL; \
} else { \
(b) = x_m0; \
x_m0->m_len = PDQ_OS_DATABUF_SIZE; \
} \
} else { \
(b) = NULL; \
} \
} while (0)
#define PDQ_OS_DATABUF_RESET(b) ((b)->m_data = (b)->m_ext.ext_buf, (b)->m_len = MCLBYTES)
#endif /* PDQ_USE_MBUFS */
#ifdef PDQ_USE_STREAMS
#define PDQ_OS_DATABUF_FREE(b) (freemsg(b))
#define PDQ_OS_DATABUF_NEXT(b) ((b)->b_cont)
#define PDQ_OS_DATABUF_NEXTPKT(b) ((b)->b_next)
#define PDQ_OS_DATABUF_NEXTPKT_SET(b, b1) ((b)->b_next = (b1))
#define PDQ_OS_DATABUF_LEN(b) ((b)->b_wptr - (b)->b_rptr)
#define PDQ_OS_DATABUF_PTR(b) ((pdq_uint8_t *) (b)->b_rptr)
typedef mblk_t PDQ_OS_DATABUF_T;
#endif /* PDQ_USE_STREAMS */
#define PDQ_OS_TX_TRANSMIT 5
#define PDQ_OS_DATABUF_ENQUEUE(q, b) do { \
PDQ_OS_DATABUF_NEXTPKT_SET(b, NULL); \
if ((q)->q_tail == NULL) \
(q)->q_head = (b); \
else \
PDQ_OS_DATABUF_NEXTPKT_SET(((PDQ_OS_DATABUF_T *)(q)->q_tail), b); \
(q)->q_tail = (b); \
} while (0)
#define PDQ_OS_DATABUF_DEQUEUE(q, b) do { \
if (((b) = (PDQ_OS_DATABUF_T *) (q)->q_head) != NULL) { \
if (((q)->q_head = PDQ_OS_DATABUF_NEXTPKT(b)) == NULL) \
(q)->q_tail = NULL; \
PDQ_OS_DATABUF_NEXTPKT_SET(b, NULL); \
} \
} while (0)
extern void pdq_os_addr_fill(pdq_t *pdq, pdq_lanaddr_t *addrs, size_t numaddrs);
extern void pdq_os_receive_pdu(pdq_t *, PDQ_OS_DATABUF_T *pdu, size_t pdulen);
extern void pdq_os_restart_transmitter(pdq_t *pdq);
extern void pdq_os_transmit_done(pdq_t *pdq, PDQ_OS_DATABUF_T *pdu);
extern pdq_boolean_t pdq_queue_transmit_data(pdq_t *pdq, PDQ_OS_DATABUF_T *pdu);
extern pdq_state_t pdq_stop(pdq_t *pdq);
extern void pdq_run(pdq_t *pdq);
extern int pdq_interrupt(pdq_t *pdq);
extern pdq_t *pdq_initialize(void *csr_va, const char *name, int unit, void *ctx, pdq_type_t type);
#endif /* _PDQ_OS_H */

File diff suppressed because it is too large Load Diff