mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-13 05:41:26 +01:00
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:
parent
0e224fbc11
commit
e4107dcf00
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=21830
@ -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
|
||||
|
@ -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
|
||||
|
@ -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__ */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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__ */
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
801
sys/pci/if_pdq.c
801
sys/pci/if_pdq.c
@ -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 */
|
1577
sys/pci/pdq.c
1577
sys/pci/pdq.c
File diff suppressed because it is too large
Load Diff
166
sys/pci/pdq_os.h
166
sys/pci/pdq_os.h
@ -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 */
|
1093
sys/pci/pdqreg.h
1093
sys/pci/pdqreg.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user