diff --git a/sys/conf/files b/sys/conf/files index 3d31c005dfa9..f543378b2f9a 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -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 diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 7f963ff4e5b4..82795b0f83db 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -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 diff --git a/sys/dev/pdq/if_fea.c b/sys/dev/pdq/if_fea.c index 3c17bf66ac2e..05798e09d2ca 100644 --- a/sys/dev/pdq/if_fea.c +++ b/sys/dev/pdq/if_fea.c @@ -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 #include #include -#if defined(__FreeBSD__) -#include -#elif defined(__bsdi__) || defined(__NetBSD__) +#if defined(__bsdi__) || defined(__NetBSD__) #include #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__ */ diff --git a/sys/dev/pdq/if_fpa.c b/sys/dev/pdq/if_fpa.c index 40757ba8ceb3..4ea3abe331e3 100644 --- a/sys/dev/pdq/if_fpa.c +++ b/sys/dev/pdq/if_fpa.c @@ -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 #include #include -#if defined(__FreeBSD__) -#include -#elif defined(__bsdi__) || defined(__NetBSD__) +#if defined(__bsdi__) || defined(__NetBSD__) #include #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 diff --git a/sys/dev/pdq/pdq.c b/sys/dev/pdq/pdq.c index ad0b5a7e6088..e183726ba52f 100644 --- a/sys/dev/pdq/pdq.c +++ b/sys/dev/pdq/pdq.c @@ -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 +#include +#else #include "pdqvar.h" #include "pdqreg.h" +#endif #define PDQ_ROUNDUP(n, x) (((n) + ((x) - 1)) & ~((x) - 1)) #define PDQ_CMD_RX_ALIGNMENT 16 diff --git a/sys/dev/pdq/pdq_ifsubr.c b/sys/dev/pdq/pdq_ifsubr.c index 224e4e8e86d4..b6223fb90472 100644 --- a/sys/dev/pdq/pdq_ifsubr.c +++ b/sys/dev/pdq/pdq_ifsubr.c @@ -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 #include #include -#if defined(__FreeBSD__) -#include -#elif defined(__bsdi__) || defined(__NetBSD__) +#if defined(__bsdi__) || defined(__NetBSD__) #include #endif @@ -84,8 +82,13 @@ #include #include +#if defined(__FreeBSD__) +#include +#include +#else #include "pdqvar.h" #include "pdqreg.h" +#endif #if defined(__bsdi__) && _BSDI_VERSION < 199506 /* XXX */ static void diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386 index 7f963ff4e5b4..82795b0f83db 100644 --- a/sys/i386/conf/files.i386 +++ b/sys/i386/conf/files.i386 @@ -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 diff --git a/sys/i386/eisa/if_fea.c b/sys/i386/eisa/if_fea.c index 3c17bf66ac2e..05798e09d2ca 100644 --- a/sys/i386/eisa/if_fea.c +++ b/sys/i386/eisa/if_fea.c @@ -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 #include #include -#if defined(__FreeBSD__) -#include -#elif defined(__bsdi__) || defined(__NetBSD__) +#if defined(__bsdi__) || defined(__NetBSD__) #include #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__ */ diff --git a/sys/net/fddi.h b/sys/net/fddi.h index 838c84d46c87..fc6acc6c9c8f 100644 --- a/sys/net/fddi.h +++ b/sys/net/fddi.h @@ -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 diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c index 47982a590560..fad3c65ccb2b 100644 --- a/sys/net/if_fddisubr.c +++ b/sys/net/if_fddisubr.c @@ -1,4 +1,6 @@ /* + * Copyright (c) 1995, 1996 + * Matt Thomas . All rights reserved. * Copyright (c) 1982, 1989, 1993 * The Regents of the University of California. All rights reserved. * @@ -45,6 +47,8 @@ #include #include +#include + #include #include #include @@ -57,10 +61,14 @@ #include #endif #include +#if defined(__FreeBSD__) #include +#else +#include +#endif #ifdef IPX -#include +#include #include #endif @@ -80,17 +88,29 @@ #include #endif -#include "bpfilter.h" - #ifdef LLC #include #include #endif +#ifdef NETATALK +#include +#include +#include + +#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; + } } diff --git a/sys/netinet/if_fddi.h b/sys/netinet/if_fddi.h index 838c84d46c87..fc6acc6c9c8f 100644 --- a/sys/netinet/if_fddi.h +++ b/sys/netinet/if_fddi.h @@ -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 diff --git a/sys/pci/if_fpa.c b/sys/pci/if_fpa.c index 40757ba8ceb3..4ea3abe331e3 100644 --- a/sys/pci/if_fpa.c +++ b/sys/pci/if_fpa.c @@ -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 #include #include -#if defined(__FreeBSD__) -#include -#elif defined(__bsdi__) || defined(__NetBSD__) +#if defined(__bsdi__) || defined(__NetBSD__) #include #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 diff --git a/sys/pci/if_pdq.c b/sys/pci/if_pdq.c deleted file mode 100644 index 83dbc9743630..000000000000 --- a/sys/pci/if_pdq.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "bpfilter.h" -#if NBPFILTER > 0 -#include -#include -#endif - -#ifdef INET -#include -#include -#include -#include -#include -#endif -#include - -#ifdef NS -#include -#include -#endif - -#include -#include - -#if NFPA > 0 -#include -#include -#endif - -#if NFEA > 0 -#include -#ifdef __FreeBSD__ -#include -#endif -#ifdef __bsdi__ -#include -#include -#include -#endif -#endif - -#include -#include - -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 */ diff --git a/sys/pci/pdq.c b/sys/pci/pdq.c deleted file mode 100644 index ad0041046777..000000000000 --- a/sys/pci/pdq.c +++ /dev/null @@ -1,1577 +0,0 @@ -/*- - * Copyright (c) 1995 Matt Thomas (matt@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$ - * - * Revision 1.8 1995/03/14 01:52:52 thomas - * Update for new FreeBSD PCI Interrupt interface - * - * Revision 1.7 1995/03/07 23:03:16 thomas - * Fix SMT queue processing - * - * Revision 1.6 1995/03/06 18:03:47 thomas - * restart trasmitter once link is available - * - * Revision 1.5 1995/03/06 17:07:56 thomas - * Add copyright/disclaimer - * Add error recovery code. - * Add BPF SMT support - * - * Revision 1.3 1995/03/03 13:48:35 thomas - * more fixes - * - * - */ - -/* - * DEC PDQ FDDI Controller O/S independent code - * - * Written by Matt Thomas - * - * This module should work any PDQ based board. Note that changes for - * MIPS and Alpha architectures (or any other architecture which requires - * a flushing of memory or write buffers and/or has incoherent caches) - * have yet to be made. - */ - -#include -#include - -#define PDQ_ROUNDUP(n, x) (((n) + ((x) - 1)) & ~((x) - 1)) -#define PDQ_CMD_RX_ALIGNMENT 16 - -#if defined(PDQTEST) && !defined(PDQ_NOPRINTF) -#define PDQ_PRINTF(x) printf x -#else -#define PDQ_PRINTF(x) -#endif - -static void pdq_process_transmitted_data(pdq_t *pdq); -static void pdq_flush_transmitter(pdq_t *pdq); -static void pdq_print_fddi_chars(pdq_t *pdq, const pdq_response_status_chars_get_t *rsp); - -static void pdq_init_csrs(pdq_csrs_t *csrs, void *csrs_va, size_t csr_size); -static void pdq_init_pci_csrs(pdq_pci_csrs_t *csrs, void *csrs_va, size_t csr_size); - -static void pdq_flush_databuf_queue(pdq_databuf_queue_t *q); - -static pdq_boolean_t pdq_do_port_control(const pdq_csrs_t * const csrs, pdq_uint32_t cmd); -static void pdq_read_mla(const pdq_csrs_t * const csrs, pdq_lanaddr_t *hwaddr); -static void pdq_read_fwrev(const pdq_csrs_t * const csrs, pdq_fwrev_t *fwrev); -static pdq_boolean_t pdq_read_error_log(pdq_t *pdq, pdq_response_error_log_get_t *log_entry); -static pdq_chip_rev_t pdq_read_chiprev(const pdq_csrs_t * const csrs); - -static void pdq_queue_commands(pdq_t *pdq); -static void pdq_process_command_responses(pdq_t *pdq); -static void pdq_process_unsolicited_events(pdq_t *pdq); - -static void pdq_process_received_data(pdq_t *pdq, pdq_rx_info_t *rx, - pdq_rxdesc_t *receives, - pdq_uint32_t completion_goal, - pdq_uint32_t ring_mask); - -static const char * const pdq_halt_codes[] = { - "Selftest Timeout", "Host Bus Parity Error", "Host Directed Fault", - "Software Fault", "Hardware Fault", "PC Trace Path Test", - "DMA Error", "Image CRC Error", "Adapter Processer Error" -}; - -static const char * const pdq_adapter_states[] = { - "Reset", "Upgrade", "DMA Unavailable", "DMA Available", - "Link Available", "Link Unavailable", "Halted", "Ring Member" -}; - -/* - * The following are used in conjunction with - * unsolicited events - */ -static const char * const pdq_entities[] = { - "Station", "Link", "Phy Port" -}; - -static const char * const pdq_station_events[] = { - "Trace Received" -}; - -static const char * const pdq_station_arguments[] = { - "Reason" -}; - -static const char * const pdq_link_events[] = { - "Transmit Underrun", - "Transmit Failed", - "Block Check Error (CRC)", - "Frame Status Error", - "PDU Length Error", - NULL, - NULL, - "Receive Data Overrun", - NULL, - "No User Buffer", - "Ring Initialization Initiated", - "Ring Initialization Received", - "Ring Beacon Initiated", - "Duplicate Address Failure", - "Duplicate Token Detected", - "Ring Purger Error", - "FCI Strip Error", - "Trace Initiated", - "Directed Beacon Received", -}; - -static const char * const pdq_link_arguments[] = { - "Reason", - "Data Link Header", - "Source", - "Upstream Neighbor" -}; - -static const char * const pdq_phy_events[] = { - "LEM Error Monitor Reject", - "Elasticy Buffer Error", - "Link Confidence Test Reject" -}; - -static const char * const pdq_phy_arguments[] = { - "Direction" -}; - -static const char * const * const pdq_event_arguments[] = { - pdq_station_arguments, - pdq_link_arguments, - pdq_phy_arguments -}; - -static const char * const * const pdq_event_codes[] = { - pdq_station_events, - pdq_link_events, - pdq_phy_events -}; - -static const char * const pdq_station_types[] = { - "SAS", "DAC", "SAC", "NAC", "DAS" -}; - -static const char * const pdq_smt_versions[] = { "", "V6.2", "V7.2" }; - -static const char pdq_phy_types[] = "ABSM"; - -static const char * const pdq_pmd_types0[] = { - "ANSI Multi-Mode", "ANSI Single-Mode Type 1", "ANSI Single-Mode Type 2", - "ANSI Sonet" -}; - -static const char * const pdq_pmd_types100[] = { - "Low Power", "Thin Wire", "Shielded Twisted Pair", - "Unshielded Twisted Pair" -}; - -static const char * const * const pdq_pmd_types[] = { - pdq_pmd_types0, pdq_pmd_types100 -}; - -static const char * const pdq_descriptions[] = { - "DEFPA PCI", - "DEFEA EISA", -}; - -static void -pdq_print_fddi_chars( - pdq_t *pdq, - const pdq_response_status_chars_get_t *rsp) -{ - - printf(PDQ_OS_PREFIX "DEC %s FDDI %s Controller\n", - PDQ_OS_PREFIX_ARGS, pdq_descriptions[pdq->pdq_type], - pdq_station_types[rsp->status_chars_get.station_type]); - - printf(PDQ_OS_PREFIX "FDDI address %6D, FW=%4.4s, HW=%c", - PDQ_OS_PREFIX_ARGS, pdq->pdq_hwaddr.lanaddr_bytes, ":", - pdq->pdq_fwrev.fwrev_bytes, - rsp->status_chars_get.module_rev.fwrev_bytes[0]); - - if (rsp->status_chars_get.smt_version_id < PDQ_ARRAY_SIZE(pdq_smt_versions)) { - printf(", SMT %s\n", pdq_smt_versions[rsp->status_chars_get.smt_version_id]); - } - - printf(PDQ_OS_PREFIX "FDDI Port%s = %c (PMD = %s)", - PDQ_OS_PREFIX_ARGS, - rsp->status_chars_get.station_type == PDQ_STATION_TYPE_DAS ? "[A]" : "", - pdq_phy_types[rsp->status_chars_get.phy_type[0]], - pdq_pmd_types[rsp->status_chars_get.pmd_type[0] / 100][rsp->status_chars_get.pmd_type[0] % 100]); - - if (rsp->status_chars_get.station_type == PDQ_STATION_TYPE_DAS) - printf(", FDDI Port[B] = %c (PMD = %s)", - pdq_phy_types[rsp->status_chars_get.phy_type[1]], - pdq_pmd_types[rsp->status_chars_get.pmd_type[1] / 100][rsp->status_chars_get.pmd_type[1] % 100]); - - printf("\n"); -} - -static void -pdq_init_csrs( - pdq_csrs_t *csrs, - void *csr_va, - size_t csrsize) -{ - volatile pdq_uint32_t *csr_base = (volatile pdq_uint32_t *) csr_va; - - csrs->csr_port_reset = &csr_base[0 * csrsize]; - csrs->csr_host_data = &csr_base[1 * csrsize]; - csrs->csr_port_control = &csr_base[2 * csrsize]; - csrs->csr_port_data_a = &csr_base[3 * csrsize]; - csrs->csr_port_data_b = &csr_base[4 * csrsize]; - csrs->csr_port_status = &csr_base[5 * csrsize]; - csrs->csr_host_int_type_0 = &csr_base[6 * csrsize]; - csrs->csr_host_int_enable = &csr_base[7 * csrsize]; - csrs->csr_type_2_producer = &csr_base[8 * csrsize]; - csrs->csr_cmd_response_producer = &csr_base[10 * csrsize]; - csrs->csr_cmd_request_producer = &csr_base[11 * csrsize]; - csrs->csr_host_smt_producer = &csr_base[12 * csrsize]; - csrs->csr_unsolicited_producer = &csr_base[13 * csrsize]; -} - -static void -pdq_init_pci_csrs( - pdq_pci_csrs_t *csrs, - void *csr_va, - size_t csrsize) -{ - volatile pdq_uint32_t *csr_base = (volatile pdq_uint32_t *) csr_va; - - csrs->csr_pfi_mode_control = &csr_base[16 * csrsize]; - csrs->csr_pfi_status = &csr_base[17 * csrsize]; - csrs->csr_fifo_write = &csr_base[18 * csrsize]; - csrs->csr_fifo_read = &csr_base[19 * csrsize]; -} - -static void -pdq_flush_databuf_queue( - pdq_databuf_queue_t *q) -{ - PDQ_OS_DATABUF_T *pdu; - for (;;) { - PDQ_OS_DATABUF_DEQUEUE(q, pdu); - if (pdu == NULL) - return; - PDQ_OS_DATABUF_FREE(pdu); - } -} - -static pdq_boolean_t -pdq_do_port_control( - const pdq_csrs_t * const csrs, - pdq_uint32_t cmd) -{ - int cnt = 0; - *csrs->csr_host_int_type_0 = PDQ_HOST_INT_CSR_CMD_DONE; - *csrs->csr_port_control = PDQ_PCTL_CMD_ERROR | cmd; - while ((*csrs->csr_host_int_type_0 & PDQ_HOST_INT_CSR_CMD_DONE) == 0 && cnt < 33000000) - cnt++; - PDQ_PRINTF(("CSR cmd spun %d times\n", cnt)); - if (*csrs->csr_host_int_type_0 & PDQ_HOST_INT_CSR_CMD_DONE) { - *csrs->csr_host_int_type_0 = PDQ_HOST_INT_CSR_CMD_DONE; - return (*csrs->csr_port_control & PDQ_PCTL_CMD_ERROR) ? PDQ_FALSE : PDQ_TRUE; - } - /* adapter failure */ - PDQ_ASSERT(0); - return PDQ_FALSE; -} - -static void -pdq_read_mla( - const pdq_csrs_t * const csrs, - pdq_lanaddr_t *hwaddr) -{ - pdq_uint32_t data; - - *csrs->csr_port_data_a = 0; - pdq_do_port_control(csrs, PDQ_PCTL_MLA_READ); - data = *csrs->csr_host_data; - - hwaddr->lanaddr_bytes[0] = (data >> 0) & 0xFF; - hwaddr->lanaddr_bytes[1] = (data >> 8) & 0xFF; - hwaddr->lanaddr_bytes[2] = (data >> 16) & 0xFF; - hwaddr->lanaddr_bytes[3] = (data >> 24) & 0xFF; - - *csrs->csr_port_data_a = 1; - pdq_do_port_control(csrs, PDQ_PCTL_MLA_READ); - data = *csrs->csr_host_data; - - hwaddr->lanaddr_bytes[4] = (data >> 0) & 0xFF; - hwaddr->lanaddr_bytes[5] = (data >> 8) & 0xFF; -} - -static void -pdq_read_fwrev( - const pdq_csrs_t * const csrs, - pdq_fwrev_t *fwrev) -{ - pdq_uint32_t data; - - pdq_do_port_control(csrs, PDQ_PCTL_FW_REV_READ); - data = *csrs->csr_host_data; - - fwrev->fwrev_bytes[3] = (data >> 0) & 0xFF; - fwrev->fwrev_bytes[2] = (data >> 8) & 0xFF; - fwrev->fwrev_bytes[1] = (data >> 16) & 0xFF; - fwrev->fwrev_bytes[0] = (data >> 24) & 0xFF; -} - -static pdq_boolean_t -pdq_read_error_log( - pdq_t *pdq, - pdq_response_error_log_get_t *log_entry) -{ - const pdq_csrs_t * const csrs = &pdq->pdq_csrs; - pdq_uint32_t *ptr = (pdq_uint32_t *) log_entry; - - pdq_do_port_control(csrs, PDQ_PCTL_ERROR_LOG_START); - - while (pdq_do_port_control(csrs, PDQ_PCTL_FW_REV_READ) == PDQ_TRUE) { - *ptr++ = *csrs->csr_host_data; - if ((pdq_uint8_t *) ptr - (pdq_uint8_t *) log_entry == sizeof(*log_entry)) - break; - } - return (ptr == (pdq_uint32_t *) log_entry) ? PDQ_FALSE : PDQ_TRUE; -} - -static pdq_chip_rev_t -pdq_read_chiprev( - const pdq_csrs_t * const csrs) -{ - pdq_uint32_t data; - - *csrs->csr_port_data_a = PDQ_SUB_CMD_PDQ_REV_GET; - pdq_do_port_control(csrs, PDQ_PCTL_SUB_CMD); - data = *csrs->csr_host_data; - - return (pdq_chip_rev_t) data; -} - -static const struct { - size_t cmd_len; - size_t rsp_len; - const char *cmd_name; -} pdq_cmd_info[] = { - { sizeof(pdq_cmd_generic_t), /* 0 - PDQC_START */ - sizeof(pdq_response_generic_t), - "Start" - }, - { sizeof(pdq_cmd_filter_set_t), /* 1 - PDQC_FILTER_SET */ - sizeof(pdq_response_generic_t), - "Filter Set" - }, - { sizeof(pdq_cmd_generic_t), /* 2 - PDQC_FILTER_GET */ - sizeof(pdq_response_filter_get_t), - "Filter Get" - }, - { sizeof(pdq_cmd_chars_set_t), /* 3 - PDQC_CHARS_SET */ - sizeof(pdq_response_generic_t), - "Chars Set" - }, - { sizeof(pdq_cmd_generic_t), /* 4 - PDQC_STATUS_CHARS_GET */ - sizeof(pdq_response_status_chars_get_t), - "Status Chars Get" - }, -#if 0 - { sizeof(pdq_cmd_generic_t), /* 5 - PDQC_COUNTERS_GET */ - sizeof(pdq_response_counters_get_t), - "Counters Get" - }, - { sizeof(pdq_cmd_counters_set_t), /* 6 - PDQC_COUNTERS_SET */ - sizeof(pdq_response_generic_t), - "Counters Set" - }, -#else - { 0, 0, "Counters Get" }, - { 0, 0, "Counters Set" }, -#endif - { sizeof(pdq_cmd_addr_filter_set_t), /* 7 - PDQC_ADDR_FILTER_SET */ - sizeof(pdq_response_generic_t), - "Addr Filter Set" - }, - { sizeof(pdq_cmd_generic_t), /* 8 - PDQC_ADDR_FILTER_GET */ - sizeof(pdq_response_addr_filter_get_t), - "Addr Filter Get" - }, -#if 0 - { sizeof(pdq_cmd_generic_t), /* 9 - PDQC_ERROR_LOG_CLEAR */ - sizeof(pdq_response_generic_t), - "Error Log Clear" - }, - { sizeof(pdq_cmd_generic_t), /* 10 - PDQC_ERROR_LOG_SET */ - sizeof(pdq_response_generic_t), - "Error Log Set" - }, - { sizeof(pdq_cmd_generic_t), /* 11 - PDQC_FDDI_MIB_GET */ - sizeof(pdq_response_generic_t), - "FDDI MIB Get" - }, - { sizeof(pdq_cmd_generic_t), /* 12 - PDQC_DEC_EXT_MIB_GET */ - sizeof(pdq_response_generic_t), - "DEC Ext MIB Get" - }, - { sizeof(pdq_cmd_generic_t), /* 13 - PDQC_DEC_SPECIFIC_GET */ - sizeof(pdq_response_generic_t), - "DEC Specific Get" - }, - { sizeof(pdq_cmd_generic_t), /* 14 - PDQC_SNMP_SET */ - sizeof(pdq_response_generic_t), - "SNMP Set" - }, - { 0, 0, "N/A" }, - { sizeof(pdq_cmd_generic_t), /* 16 - PDQC_SMT_MIB_GET */ - sizeof(pdq_response_generic_t), - "SMT MIB Get" - }, - { sizeof(pdq_cmd_generic_t), /* 17 - PDQC_SMT_MIB_SET */ - sizeof(pdq_response_generic_t), - "SMT MIB Set", - }, -#endif -}; - -static void -pdq_queue_commands( - pdq_t *pdq) -{ - const pdq_csrs_t * const csrs = &pdq->pdq_csrs; - pdq_command_info_t *ci = &pdq->pdq_command_info; - pdq_descriptor_block_t *dbp = pdq->pdq_dbp; - pdq_txdesc_t *txd; - pdq_rxdesc_t *rxd; - pdq_cmd_code_t op; - pdq_uint32_t cmdlen, rsplen; - pdq_uint8_t *bufptr; - unsigned cmds; - - for (cmds = 0; ci->ci_pending_commands != 0; cmds++) { - pdq_uint32_t mask; - /* - * If there is no free space in the queues, stop queuing - * commands. - */ - if (ci->ci_request_free == 0 || ci->ci_response_free == 0) - break; - /* - * If there are no commands nor responses pending, then reset - * the command/response buffer back to the start. - */ - if (ci->ci_request_free == ci->ci_request_max - && ci->ci_response_free == ci->ci_response_max) { - ci->ci_bufptr = ci->ci_bufstart; - ci->ci_buffree = sizeof(pdq->pdq_dbp->pdqdb_command_pool); - } - /* - * Determine which commands need to be queued. - */ - op = PDQC_SMT_MIB_SET; - for (mask = 1 << ((int) op); (mask & ci->ci_pending_commands) == 0; mask >>= 1) - op = (pdq_cmd_code_t) ((int) op - 1); - /* - * Obtain the sizes needed for the command and response. - * Round up to PDQ_CMD_RX_ALIGNMENT so the receive buffer is - * always properly aligned. - */ - cmdlen = PDQ_ROUNDUP(pdq_cmd_info[op].cmd_len, PDQ_CMD_RX_ALIGNMENT); - rsplen = PDQ_ROUNDUP(pdq_cmd_info[op].rsp_len, PDQ_CMD_RX_ALIGNMENT); - if (cmdlen < rsplen) - cmdlen = rsplen; - /* - * If there's not enough space or if there isn't enough continguous - * space, then wait for some to be freed. - */ - if (cmdlen > ci->ci_buffree) - break; - if (cmdlen > ci->ci_bufend - ci->ci_bufptr) - break; - - /* - * Allocate the space for the command and the repsonse. - */ - bufptr = ci->ci_bufptr; - ci->ci_bufptr += cmdlen; - ci->ci_buffree -= cmdlen; - if (ci->ci_bufptr == ci->ci_bufend) - ci->ci_bufptr = ci->ci_bufstart; - - /* - * Obtain and fill in the descriptor for the command - */ - txd = &dbp->pdqdb_command_requests[ci->ci_request_producer]; - PDQ_ADVANCE(ci->ci_request_producer, 1, PDQ_RING_MASK(dbp->pdqdb_command_requests)); - ci->ci_request_free--; - - txd->txd_pa_lo = ci->ci_pa_bufstart + (bufptr - ci->ci_bufstart); - txd->txd_eop = txd->txd_sop = 1; - txd->txd_seg_len = cmdlen; - txd->txd_pa_hi = 0; - - /* - * Obtain and fill in the descriptor for the response - */ - rxd = &dbp->pdqdb_command_responses[ci->ci_response_producer]; - PDQ_ADVANCE(ci->ci_response_producer, 1, PDQ_RING_MASK(dbp->pdqdb_command_responses)); - ci->ci_response_free--; - - rxd->rxd_pa_lo = ci->ci_pa_bufstart + (bufptr - ci->ci_bufstart); - rxd->rxd_sop = 1; - rxd->rxd_seg_cnt = 0; - rxd->rxd_seg_len_lo = 0; - rxd->rxd_seg_len_hi = cmdlen / 16; - rxd->rxd_pa_hi = 0; - - /* - * Clear the command area, set the opcode, and the command from the pending - * mask. - */ - - PDQ_OS_MEMZERO(bufptr, cmdlen); - *(pdq_cmd_code_t *) bufptr = op; - ci->ci_pending_commands &= ~mask; - - /* - * Fill in the command area, if needed. - */ - switch (op) { - case PDQC_FILTER_SET: { - pdq_cmd_filter_set_t *filter_set = (pdq_cmd_filter_set_t *) bufptr; - unsigned idx = 0; - filter_set->filter_set_items[idx].item_code = PDQI_IND_GROUP_PROM; - filter_set->filter_set_items[idx].filter_state = (pdq->pdq_flags & PDQ_PROMISC ? PDQ_FILTER_PASS : PDQ_FILTER_BLOCK); - idx++; - filter_set->filter_set_items[idx].item_code = PDQI_GROUP_PROM; - filter_set->filter_set_items[idx].filter_state = (pdq->pdq_flags & PDQ_ALLMULTI ? PDQ_FILTER_PASS : PDQ_FILTER_BLOCK); - idx++; - filter_set->filter_set_items[idx].item_code = PDQI_SMT_PROM; - filter_set->filter_set_items[idx].filter_state = ((pdq->pdq_flags & (PDQ_PROMISC|PDQ_PASS_SMT)) == (PDQ_PROMISC|PDQ_PASS_SMT) ? PDQ_FILTER_PASS : PDQ_FILTER_BLOCK); - idx++; - filter_set->filter_set_items[idx].item_code = PDQI_SMT_USER; - filter_set->filter_set_items[idx].filter_state = (pdq->pdq_flags & PDQ_PASS_SMT ? PDQ_FILTER_PASS : PDQ_FILTER_BLOCK); - idx++; - filter_set->filter_set_items[idx].item_code = PDQI_EOL; - break; - } - case PDQC_ADDR_FILTER_SET: { - pdq_cmd_addr_filter_set_t *addr_filter_set = (pdq_cmd_addr_filter_set_t *) bufptr; - pdq_lanaddr_t *addr = addr_filter_set->addr_filter_set_addresses; - addr->lanaddr_bytes[0] = 0xFF; - addr->lanaddr_bytes[1] = 0xFF; - addr->lanaddr_bytes[2] = 0xFF; - addr->lanaddr_bytes[3] = 0xFF; - addr->lanaddr_bytes[4] = 0xFF; - addr->lanaddr_bytes[5] = 0xFF; - addr++; - pdq_os_addr_fill(pdq, addr, 61); - break; - } - default: - break; - } - /* - * At this point the command is done. All that needs to be done is to - * produce it to the PDQ. That will be done after the loop exits. - */ - PDQ_PRINTF(("PDQ Queue Command Request: %s queued\n", - pdq_cmd_info[op].cmd_name)); - } - if (cmds > 0) { - *csrs->csr_cmd_response_producer = ci->ci_response_producer | (ci->ci_response_completion << 8); - *csrs->csr_cmd_request_producer = ci->ci_request_producer | (ci->ci_request_completion << 8); - } -} - -static void -pdq_process_command_responses( - pdq_t *pdq) -{ - const pdq_csrs_t * const csrs = &pdq->pdq_csrs; - pdq_command_info_t *ci = &pdq->pdq_command_info; - volatile const pdq_consumer_block_t *cbp = pdq->pdq_cbp; - pdq_descriptor_block_t *dbp = pdq->pdq_dbp; - pdq_txdesc_t *txd; - pdq_rxdesc_t *rxd; - const pdq_response_generic_t *rspgen; - unsigned cmds; - - /* - * We have to process the command and response in tandem so - * just wait for the response to be consumed. If it has been - * consumed then the command must have been as well. - */ - - for (cmds = 0; cbp->pdqcb_command_response != ci->ci_response_completion; cmds = 1) { - PDQ_ASSERT (cbp->pdqcb_command_request != ci->ci_request_completion); - - txd = &dbp->pdqdb_command_requests[ci->ci_request_completion]; - rxd = &dbp->pdqdb_command_responses[ci->ci_response_completion]; - - rspgen = (const pdq_response_generic_t *) (ci->ci_bufstart + rxd->rxd_pa_lo - ci->ci_pa_bufstart); - PDQ_ASSERT(rspgen->generic_status == PDQR_SUCCESS); - PDQ_PRINTF(("PDQ Process Command Response: %s completed\n", - pdq_cmd_info[rspgen->generic_op].cmd_name)); - - if (rspgen->generic_op == PDQC_STATUS_CHARS_GET && (pdq->pdq_flags & PDQ_PRINTCHARS)) { - pdq->pdq_flags &= ~PDQ_PRINTCHARS; - pdq_print_fddi_chars(pdq, (const pdq_response_status_chars_get_t *) rspgen); - } - - PDQ_ADVANCE(ci->ci_request_completion, 1, PDQ_RING_MASK(dbp->pdqdb_command_requests)); - PDQ_ADVANCE(ci->ci_response_completion, 1, PDQ_RING_MASK(dbp->pdqdb_command_responses)); - ci->ci_response_free++; - ci->ci_request_free++; - ci->ci_buffree += txd->txd_seg_len; - } - - if (cmds > 0) { - *csrs->csr_cmd_response_producer = ci->ci_response_producer | (ci->ci_response_completion << 8); - *csrs->csr_cmd_request_producer = ci->ci_request_producer | (ci->ci_request_completion << 8); - if (ci->ci_pending_commands != 0) - pdq_queue_commands(pdq); - } -} - -/* - * This following routine processes unsolicited events. - * In addition, it also fills the unsolicited queue with - * event buffers so it can be used to initialize the queue - * as well. - */ -static void -pdq_process_unsolicited_events( - pdq_t *pdq) -{ - const pdq_csrs_t * const csrs = &pdq->pdq_csrs; - pdq_unsolicited_info_t *ui = &pdq->pdq_unsolicited_info; - volatile const pdq_consumer_block_t *cbp = pdq->pdq_cbp; - pdq_descriptor_block_t *dbp = pdq->pdq_dbp; - const pdq_unsolicited_event_t *event; - pdq_rxdesc_t *rxd; - - /* - * Process each unsolicited event (if any). - */ - - while (cbp->pdqcb_unsolicited_event != ui->ui_completion) { - rxd = &dbp->pdqdb_unsolicited_events[ui->ui_completion]; - event = &ui->ui_events[ui->ui_completion & (PDQ_NUM_UNSOLICITED_EVENTS-1)]; - - switch (event->event_type) { - case PDQ_UNSOLICITED_EVENT: { - printf(PDQ_OS_PREFIX "Unsolicited Event: %s: %s", - PDQ_OS_PREFIX_ARGS, - pdq_entities[event->event_entity], - pdq_event_codes[event->event_entity][event->event_code.value]); - if (event->event_type == PDQ_ENTITY_PHY_PORT) - printf("[%d]", event->event_index); - printf("\n"); - break; - } - case PDQ_UNSOLICITED_COUNTERS: { - break; - } - } - PDQ_ADVANCE(ui->ui_completion, 1, PDQ_RING_MASK(dbp->pdqdb_unsolicited_events)); - ui->ui_free++; - } - - /* - * Now give back the event buffers back to the PDQ. - */ - PDQ_ADVANCE(ui->ui_producer, ui->ui_free, PDQ_RING_MASK(dbp->pdqdb_unsolicited_events)); - ui->ui_free = 0; - - *csrs->csr_unsolicited_producer = ui->ui_producer | (ui->ui_completion << 8); -} - -static void -pdq_process_received_data( - pdq_t *pdq, - pdq_rx_info_t *rx, - pdq_rxdesc_t *receives, - pdq_uint32_t completion_goal, - pdq_uint32_t ring_mask) -{ - pdq_uint32_t completion = rx->rx_completion; - pdq_uint32_t producer = rx->rx_producer; - PDQ_OS_DATABUF_T **buffers = (PDQ_OS_DATABUF_T **) rx->rx_buffers; - pdq_rxdesc_t *rxd; - pdq_uint32_t idx; - - while (completion != completion_goal) { - PDQ_OS_DATABUF_T *fpdu, *lpdu, *npdu; - pdq_uint8_t *dataptr; - pdq_uint32_t fc, datalen, pdulen, segcnt; - pdq_rxstatus_t status; - - fpdu = lpdu = buffers[completion]; - PDQ_ASSERT(fpdu != NULL); - - dataptr = PDQ_OS_DATABUF_PTR(fpdu); - status = *(pdq_rxstatus_t *) dataptr; - if ((status.rxs_status & 0x200000) == 0) { - datalen = status.rxs_status & 0x1FFF; - fc = dataptr[PDQ_RX_FC_OFFSET]; - switch (fc & (PDQ_FDDIFC_C|PDQ_FDDIFC_L|PDQ_FDDIFC_F)) { - case PDQ_FDDI_LLC_ASYNC: - case PDQ_FDDI_LLC_SYNC: - case PDQ_FDDI_IMP_ASYNC: - case PDQ_FDDI_IMP_SYNC: { - if (datalen > PDQ_FDDI_MAX || datalen < PDQ_FDDI_LLC_MIN) { - printf("discard: bad length %d\n", datalen); - goto discard_frame; - } - break; - } - case PDQ_FDDI_SMT: { - if (datalen > PDQ_FDDI_MAX || datalen < PDQ_FDDI_SMT_MIN) - goto discard_frame; - break; - } - default: { - printf("discard: bad fc 0x%x\n", fc); - goto discard_frame; - } - } - /* - * Update the lengths of the data buffers now that we know - * the real length. - */ - pdulen = datalen - 4 /* CRC */ + 1 /* FC */; - segcnt = (pdulen + PDQ_RX_FC_OFFSET + PDQ_OS_DATABUF_SIZE - 1) / PDQ_OS_DATABUF_SIZE; - PDQ_OS_DATABUF_ALLOC(npdu); - if (npdu == NULL) { - printf("discard: no databuf #0\n"); - goto discard_frame; - } - buffers[completion] = npdu; - for (idx = 1; idx < segcnt; idx++) { - PDQ_OS_DATABUF_ALLOC(npdu); - if (npdu == NULL) { - PDQ_OS_DATABUF_NEXT_SET(lpdu, NULL); - PDQ_OS_DATABUF_FREE(fpdu); - goto discard_frame; - } - PDQ_OS_DATABUF_NEXT_SET(lpdu, buffers[(completion + idx) & ring_mask]); - lpdu = PDQ_OS_DATABUF_NEXT(lpdu); - buffers[(completion + idx) & ring_mask] = npdu; - } - PDQ_OS_DATABUF_NEXT_SET(lpdu, NULL); - for (idx = 0; idx < PDQ_RX_SEGCNT; idx++) { - buffers[(producer + idx) & ring_mask] = - buffers[(completion + idx) & ring_mask]; - buffers[(completion + idx) & ring_mask] = NULL; - } - PDQ_OS_DATABUF_PTR_ADJ(fpdu, PDQ_RX_FC_OFFSET); - if (segcnt == 1) { - PDQ_OS_DATABUF_LEN_SET(fpdu, pdulen); - } else { - PDQ_OS_DATABUF_LEN_SET(lpdu, pdulen + PDQ_RX_FC_OFFSET - (segcnt - 1) * PDQ_OS_DATABUF_SIZE); - PDQ_OS_DATABUF_LEN_ADJ(fpdu, -PDQ_RX_FC_OFFSET); - } - pdq_os_receive_pdu(pdq, fpdu, pdulen); - rx->rx_free += PDQ_RX_SEGCNT; - PDQ_ADVANCE(producer, PDQ_RX_SEGCNT, ring_mask); - PDQ_ADVANCE(completion, PDQ_RX_SEGCNT, ring_mask); - continue; - } else { - printf("discard: bad pdu 0x%x(%d.%d.%d.%d.%d)\n", status.rxs_status, - status.rxs_rcc_badpdu, status.rxs_rcc_badcrc, - status.rxs_rcc_reason, status.rxs_fsc, status.rxs_fsb_e); - if (status.rxs_rcc_reason == 7) - goto discard_frame; - if (status.rxs_rcc_reason != 0) - /* hardware fault */ - if (status.rxs_rcc_badcrc) { - /* rx->rx_badcrc++; */ - } else if (status.rxs_fsc == 0 | status.rxs_fsb_e == 1) { - /* rx->rx_frame_status_errors++; */ - } else { - /* hardware fault */ - } - } - discard_frame: - /* - * Discarded frames go right back on the queue; therefore - * ring entries were freed. - */ - for (idx = 0; idx < PDQ_RX_SEGCNT; idx++) { - buffers[producer] = buffers[completion]; - buffers[completion] = NULL; - rxd = &receives[rx->rx_producer]; - if (idx == 0) { - rxd->rxd_sop = 1; rxd->rxd_seg_cnt = PDQ_RX_SEGCNT - 1; - } else { - rxd->rxd_sop = 0; rxd->rxd_seg_cnt = 0; - } - rxd->rxd_pa_hi = 0; - rxd->rxd_seg_len_hi = PDQ_OS_DATABUF_SIZE / 16; - rxd->rxd_pa_lo = PDQ_OS_VA_TO_PA(PDQ_OS_DATABUF_PTR(buffers[rx->rx_producer])); - PDQ_ADVANCE(rx->rx_producer, 1, ring_mask); - PDQ_ADVANCE(producer, 1, ring_mask); - PDQ_ADVANCE(completion, 1, ring_mask); - } - } - rx->rx_completion = completion; - - while (rx->rx_free > PDQ_RX_SEGCNT && rx->rx_free > rx->rx_target) { - PDQ_OS_DATABUF_T *pdu; - /* - * Allocate the needed number of data buffers. - * Try to obtain them from our free queue before - * asking the system for more. - */ - for (idx = 0; idx < PDQ_RX_SEGCNT; idx++) { - if ((pdu = buffers[(rx->rx_producer + idx) & ring_mask]) == NULL) { - PDQ_OS_DATABUF_ALLOC(pdu); - if (pdu == NULL) - break; - buffers[(rx->rx_producer + idx) & ring_mask] = pdu; - } - rxd = &receives[(rx->rx_producer + idx) & ring_mask]; - if (idx == 0) { - rxd->rxd_sop = 1; rxd->rxd_seg_cnt = PDQ_RX_SEGCNT - 1; - } else { - rxd->rxd_sop = 0; rxd->rxd_seg_cnt = 0; - } - rxd->rxd_pa_hi = 0; - rxd->rxd_seg_len_hi = PDQ_OS_DATABUF_SIZE / 16; - rxd->rxd_pa_lo = PDQ_OS_VA_TO_PA(PDQ_OS_DATABUF_PTR(pdu)); - } - if (idx < PDQ_RX_SEGCNT) { - /* - * We didn't get all databufs required to complete a new - * receive buffer. Keep the ones we got and retry a bit - * later for the rest. - */ - break; - } - PDQ_ADVANCE(rx->rx_producer, PDQ_RX_SEGCNT, ring_mask); - rx->rx_free -= PDQ_RX_SEGCNT; - } -} - -pdq_boolean_t -pdq_queue_transmit_data( - pdq_t *pdq, - PDQ_OS_DATABUF_T *pdu) -{ - pdq_tx_info_t *tx = &pdq->pdq_tx_info; - pdq_descriptor_block_t *dbp = pdq->pdq_dbp; - pdq_uint32_t producer = tx->tx_producer; - pdq_txdesc_t *eop = NULL; - PDQ_OS_DATABUF_T *pdu0; - pdq_uint32_t freecnt; - - dbp->pdqdb_transmits[producer] = tx->tx_hdrdesc; - PDQ_ADVANCE(producer, 1, PDQ_RING_MASK(dbp->pdqdb_transmits)); - - for (freecnt = tx->tx_free - 1, pdu0 = pdu; pdu0 != NULL && freecnt > 0;) { - pdq_uint32_t fraglen, datalen = PDQ_OS_DATABUF_LEN(pdu0); - const pdq_uint8_t *dataptr = PDQ_OS_DATABUF_PTR(pdu0); - - /* - * The first segment is limited to the space remaining in - * page. All segments after that can be up to a full page - * in size. - */ - fraglen = PDQ_OS_PAGESIZE - ((dataptr - (pdq_uint8_t *) NULL) & (PDQ_OS_PAGESIZE-1)); - while (datalen > 0 && freecnt > 0) { - pdq_uint32_t seglen = (fraglen < datalen ? fraglen : datalen); - - /* - * Initialize the transmit descriptor - */ - eop = &dbp->pdqdb_transmits[producer]; - eop->txd_seg_len = seglen; - eop->txd_pa_lo = PDQ_OS_VA_TO_PA(dataptr); - eop->txd_sop = eop->txd_eop = eop->txd_pa_hi = 0; - - datalen -= seglen; - dataptr += seglen; - fraglen = PDQ_OS_PAGESIZE; - freecnt--; - PDQ_ADVANCE(producer, 1, PDQ_RING_MASK(dbp->pdqdb_transmits)); - } - pdu0 = PDQ_OS_DATABUF_NEXT(pdu0); - } - if (pdu0 != NULL) { - PDQ_ASSERT(free == 0); - /* - * If we still have data to process then the ring was too full - * to store the PDU. Return FALSE so the caller will requeue - * the PDU for later. - */ - return PDQ_FALSE; - } - /* - * Everything went fine. Finish it up. - */ - tx->tx_descriptor_count[tx->tx_producer] = tx->tx_free - freecnt; - eop->txd_eop = 1; - PDQ_OS_DATABUF_ENQUEUE(&tx->tx_txq, pdu); - tx->tx_producer = producer; - tx->tx_free = freecnt; - PDQ_DO_TYPE2_PRODUCER(pdq); - return PDQ_TRUE; -} - -static void -pdq_process_transmitted_data( - pdq_t *pdq) -{ - pdq_tx_info_t *tx = &pdq->pdq_tx_info; - volatile const pdq_consumer_block_t *cbp = pdq->pdq_cbp; - pdq_descriptor_block_t *dbp = pdq->pdq_dbp; - pdq_uint32_t completion = tx->tx_completion; - - while (completion != cbp->pdqcb_transmits) { - PDQ_OS_DATABUF_T *pdu; - pdq_uint32_t descriptor_count = tx->tx_descriptor_count[completion]; - PDQ_ASSERT(dbp->pdqdb_transmits[tx->tx_completion].txd_sop == 1); - PDQ_ASSERT(dbp->pdqdb_transmits[(completion + descriptor_count - 1) & PDQ_RING_MASK(dbp->pdqdb_transmits)].txd_eop == 1); - PDQ_OS_DATABUF_DEQUEUE(&tx->tx_txq, pdu); - pdq_os_transmit_done(pdq, pdu); - tx->tx_free += descriptor_count; - - PDQ_ADVANCE(completion, descriptor_count, PDQ_RING_MASK(dbp->pdqdb_transmits)); - } - if (tx->tx_completion != completion) { - tx->tx_completion = completion; - pdq_os_restart_transmitter(pdq); - } - PDQ_DO_TYPE2_PRODUCER(pdq); -} - -static void -pdq_flush_transmitter( - pdq_t *pdq) -{ - volatile pdq_consumer_block_t *cbp = pdq->pdq_cbp; - pdq_tx_info_t *tx = &pdq->pdq_tx_info; - - for (;;) { - PDQ_OS_DATABUF_T *pdu; - PDQ_OS_DATABUF_DEQUEUE(&tx->tx_txq, pdu); - if (pdu == NULL) - break; - /* - * Don't call transmit done since the packet never made it - * out on the wire. - */ - PDQ_OS_DATABUF_FREE(pdu); - } - - tx->tx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_transmits); - tx->tx_completion = cbp->pdqcb_transmits = tx->tx_producer; - - PDQ_DO_TYPE2_PRODUCER(pdq); -} - -/* - * The following routine brings the PDQ from whatever state it is - * in to DMA_UNAVAILABLE (ie. like a RESET but without doing a RESET). - */ -pdq_state_t -pdq_stop( - pdq_t *pdq) -{ - pdq_state_t state; - const pdq_csrs_t * const csrs = &pdq->pdq_csrs; - int cnt, pass = 0, idx; - PDQ_OS_DATABUF_T **buffers; - - restart: - state = PDQ_PSTS_ADAPTER_STATE(*csrs->csr_port_status); - if (state != PDQS_DMA_UNAVAILABLE) { - *csrs->csr_port_data_a = (state == PDQS_HALTED) ? 0 : PDQ_PRESET_SKIP_SELFTEST; - *csrs->csr_port_reset = 1; - PDQ_OS_USEC_DELAY(100); - *csrs->csr_port_reset = 0; - for (cnt = 45000;;cnt--) { - PDQ_OS_USEC_DELAY(1000); - state = PDQ_PSTS_ADAPTER_STATE(*csrs->csr_port_status); - if (state == PDQS_DMA_UNAVAILABLE || cnt == 0) - break; - } - PDQ_PRINTF(("PDQ Reset spun %d cycles\n", 45000 - cnt)); - PDQ_OS_USEC_DELAY(10000); - state = PDQ_PSTS_ADAPTER_STATE(*csrs->csr_port_status); - PDQ_ASSERT(state == PDQS_DMA_UNAVAILABLE); - PDQ_ASSERT(cnt > 0); - } -#if 0 - switch (state) { - case PDQS_RING_MEMBER: - case PDQS_LINK_UNAVAILABLE: - case PDQS_LINK_AVAILABLE: { - *csrs->csr_port_data_a = PDQ_SUB_CMD_LINK_UNINIT; - *csrs->csr_port_data_b = 0; - pdq_do_port_control(csrs, PDQ_PCTL_SUB_CMD); - state = PDQ_PSTS_ADAPTER_STATE(*csrs->csr_port_status); - PDQ_ASSERT(state == PDQS_DMA_AVAILABLE); - /* FALL THROUGH */ - } - case PDQS_DMA_AVAILABLE: { - *csrs->csr_port_data_a = 0; - *csrs->csr_port_data_b = 0; - pdq_do_port_control(csrs, PDQ_PCTL_DMA_UNINIT); - state = PDQ_PSTS_ADAPTER_STATE(*csrs->csr_port_status); - PDQ_ASSERT(state == PDQS_DMA_UNAVAILABLE); - /* FALL THROUGH */ - } - case PDQS_DMA_UNAVAILABLE: { - break; - } - } -#endif - /* - * Now we should be in DMA_UNAVAILABLE. So bring the PDQ into - * DMA_AVAILABLE. - */ - - /* - * Obtain the hardware address and firmware revisions - * (MLA = my long address which is FDDI speak for hardware address) - */ - pdq_read_mla(&pdq->pdq_csrs, &pdq->pdq_hwaddr); - pdq_read_fwrev(&pdq->pdq_csrs, &pdq->pdq_fwrev); - pdq->pdq_chip_rev = pdq_read_chiprev(&pdq->pdq_csrs); - - if (pdq->pdq_type == PDQ_DEFPA) { - /* - * Disable interrupts and DMA. - */ - *pdq->pdq_pci_csrs.csr_pfi_mode_control = 0; - *pdq->pdq_pci_csrs.csr_pfi_status = 0x10; - } - - /* - * Flush all the databuf queues. - */ - pdq_flush_databuf_queue(&pdq->pdq_tx_info.tx_txq); - buffers = (PDQ_OS_DATABUF_T **) pdq->pdq_rx_info.rx_buffers; - for (idx = 0; idx < PDQ_RING_SIZE(pdq->pdq_dbp->pdqdb_receives); idx++) { - if (buffers[idx] != NULL) { - PDQ_OS_DATABUF_FREE(buffers[idx]); - buffers[idx] = NULL; - } - } - pdq->pdq_rx_info.rx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_receives); - buffers = (PDQ_OS_DATABUF_T **) pdq->pdq_host_smt_info.rx_buffers; - for (idx = 0; idx < PDQ_RING_SIZE(pdq->pdq_dbp->pdqdb_host_smt); idx++) { - if (buffers[idx] != NULL) { - PDQ_OS_DATABUF_FREE(buffers[idx]); - buffers[idx] = NULL; - } - } - pdq->pdq_host_smt_info.rx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_host_smt); - - /* - * Reset the consumer indexes to 0. - */ - pdq->pdq_cbp->pdqcb_receives = 0; - pdq->pdq_cbp->pdqcb_transmits = 0; - pdq->pdq_cbp->pdqcb_host_smt = 0; - pdq->pdq_cbp->pdqcb_unsolicited_event = 0; - pdq->pdq_cbp->pdqcb_command_response = 0; - pdq->pdq_cbp->pdqcb_command_request = 0; - - /* - * Reset the producer and completion indexes to 0. - */ - pdq->pdq_command_info.ci_request_producer = 0; - pdq->pdq_command_info.ci_response_producer = 0; - pdq->pdq_command_info.ci_request_completion = 0; - pdq->pdq_command_info.ci_response_completion = 0; - pdq->pdq_unsolicited_info.ui_producer = 0; - pdq->pdq_unsolicited_info.ui_completion = 0; - pdq->pdq_rx_info.rx_producer = 0; - pdq->pdq_rx_info.rx_completion = 0; - pdq->pdq_tx_info.tx_producer = 0; - pdq->pdq_tx_info.tx_completion = 0; - pdq->pdq_host_smt_info.rx_producer = 0; - pdq->pdq_host_smt_info.rx_completion = 0; - - pdq->pdq_command_info.ci_request_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_command_requests); - pdq->pdq_command_info.ci_response_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_command_responses); - pdq->pdq_unsolicited_info.ui_free = PDQ_NUM_UNSOLICITED_EVENTS; - pdq->pdq_tx_info.tx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_transmits); - - /* - * Allow the DEFPA to do DMA. Then program the physical - * addresses of the consumer and descriptor blocks. - */ - if (pdq->pdq_type == PDQ_DEFPA) { -#ifdef PDQTEST - *pdq->pdq_pci_csrs.csr_pfi_mode_control = PDQ_PFI_MODE_DMA_ENABLE; -#else - *pdq->pdq_pci_csrs.csr_pfi_mode_control = PDQ_PFI_MODE_DMA_ENABLE - |PDQ_PFI_MODE_PFI_PCI_INTR|PDQ_PFI_MODE_PDQ_PCI_INTR; -#endif - } - - /* - * Make the unsolicited queue has events ... - */ - pdq_process_unsolicited_events(pdq); - - *csrs->csr_port_data_b = PDQ_DMA_BURST_8LW; - *csrs->csr_port_data_a = PDQ_SUB_CMD_DMA_BURST_SIZE_SET; - pdq_do_port_control(csrs, PDQ_PCTL_SUB_CMD); - - *csrs->csr_port_data_b = 0; - *csrs->csr_port_data_a = PDQ_OS_VA_TO_PA(pdq->pdq_cbp); - pdq_do_port_control(csrs, PDQ_PCTL_CONSUMER_BLOCK); - - *csrs->csr_port_data_b = 0; - *csrs->csr_port_data_a = PDQ_OS_VA_TO_PA(pdq->pdq_dbp) | PDQ_DMA_INIT_LW_BSWAP_DATA; - pdq_do_port_control(csrs, PDQ_PCTL_DMA_INIT); - - for (cnt = 0; cnt < 1000; cnt++) { - state = PDQ_PSTS_ADAPTER_STATE(*csrs->csr_port_status); - if (state == PDQS_HALTED) { - if (pass > 0) - return PDQS_HALTED; - pass = 1; - goto restart; - } - if (state == PDQS_DMA_AVAILABLE) { - PDQ_PRINTF(("Transition to DMA Available took %d spins\n", cnt)); - break; - } - PDQ_OS_USEC_DELAY(1000); - } - PDQ_ASSERT(state == PDQS_DMA_AVAILABLE); - - *csrs->csr_host_int_type_0 = 0xFF; - *csrs->csr_host_int_enable = 0 /* PDQ_HOST_INT_STATE_CHANGE - |PDQ_HOST_INT_FATAL_ERROR|PDQ_HOST_INT_CMD_RSP_ENABLE - |PDQ_HOST_INT_UNSOL_ENABLE */; - - /* - * Any other command but START should be valid. - */ - pdq->pdq_command_info.ci_pending_commands &= ~(PDQ_BITMASK(PDQC_START)); - if (pdq->pdq_flags & PDQ_PRINTCHARS) - pdq->pdq_command_info.ci_pending_commands |= PDQ_BITMASK(PDQC_STATUS_CHARS_GET); - pdq_queue_commands(pdq); - - if (pdq->pdq_flags & PDQ_PRINTCHARS) { - /* - * Now wait (up to 100ms) for the command(s) to finish. - */ - for (cnt = 0; cnt < 1000; cnt++) { - pdq_process_command_responses(pdq); - if (pdq->pdq_command_info.ci_response_producer == pdq->pdq_command_info.ci_response_completion) - break; - PDQ_OS_USEC_DELAY(1000); - } - state = PDQ_PSTS_ADAPTER_STATE(*csrs->csr_port_status); - } - - return state; -} - -void -pdq_run( - pdq_t *pdq) -{ - const pdq_csrs_t * const csrs = &pdq->pdq_csrs; - pdq_state_t state; - - state = PDQ_PSTS_ADAPTER_STATE(*csrs->csr_port_status); - PDQ_ASSERT(state != PDQS_DMA_UNAVAILABLE); - PDQ_ASSERT(state != PDQS_RESET); - PDQ_ASSERT(state != PDQS_HALTED); - PDQ_ASSERT(state != PDQS_UPGRADE); - PDQ_ASSERT(state != PDQS_RING_MEMBER); - switch (state) { - case PDQS_DMA_AVAILABLE: { - /* - * The PDQ after being reset screws up some of its state. - * So we need to clear all the errors/interrupts so the real - * ones will get through. - */ - *csrs->csr_host_int_type_0 = 0xFF; - *csrs->csr_host_int_enable = PDQ_HOST_INT_STATE_CHANGE|PDQ_HOST_INT_XMT_DATA_FLUSH - |PDQ_HOST_INT_FATAL_ERROR|PDQ_HOST_INT_CMD_RSP_ENABLE|PDQ_HOST_INT_UNSOL_ENABLE - |PDQ_HOST_INT_RX_ENABLE|PDQ_HOST_INT_TX_ENABLE|PDQ_HOST_INT_HOST_SMT_ENABLE; - /* - * Set the MAC and address filters and start up the PDQ. - */ - pdq_process_unsolicited_events(pdq); - pdq_process_received_data(pdq, &pdq->pdq_rx_info, - pdq->pdq_dbp->pdqdb_receives, - pdq->pdq_cbp->pdqcb_receives, - PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_receives)); - PDQ_DO_TYPE2_PRODUCER(pdq); - if (pdq->pdq_flags & PDQ_PASS_SMT) { - pdq_process_received_data(pdq, &pdq->pdq_host_smt_info, - pdq->pdq_dbp->pdqdb_host_smt, - pdq->pdq_cbp->pdqcb_host_smt, - PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_host_smt)); - *csrs->csr_host_smt_producer = pdq->pdq_host_smt_info.rx_producer | (pdq->pdq_host_smt_info.rx_completion << 8); - } - pdq->pdq_command_info.ci_pending_commands = PDQ_BITMASK(PDQC_FILTER_SET) - | PDQ_BITMASK(PDQC_ADDR_FILTER_SET) | PDQ_BITMASK(PDQC_START); - if (pdq->pdq_flags & PDQ_PRINTCHARS) - pdq->pdq_command_info.ci_pending_commands |= PDQ_BITMASK(PDQC_STATUS_CHARS_GET); - pdq_queue_commands(pdq); - break; - } - case PDQS_LINK_UNAVAILABLE: - case PDQS_LINK_AVAILABLE: { - pdq->pdq_command_info.ci_pending_commands = PDQ_BITMASK(PDQC_FILTER_SET) - | PDQ_BITMASK(PDQC_ADDR_FILTER_SET); - if (pdq->pdq_flags & PDQ_PRINTCHARS) - pdq->pdq_command_info.ci_pending_commands |= PDQ_BITMASK(PDQC_STATUS_CHARS_GET); - if (pdq->pdq_flags & PDQ_PASS_SMT) { - pdq_process_received_data(pdq, &pdq->pdq_host_smt_info, - pdq->pdq_dbp->pdqdb_host_smt, - pdq->pdq_cbp->pdqcb_host_smt, - PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_host_smt)); - *csrs->csr_host_smt_producer = pdq->pdq_host_smt_info.rx_producer | (pdq->pdq_host_smt_info.rx_completion << 8); - } - pdq_process_unsolicited_events(pdq); - pdq_queue_commands(pdq); - break; - } - case PDQS_RING_MEMBER: { - } - break; - default: - break; - } -} - -int -pdq_interrupt( - pdq_t *pdq) -{ - const pdq_csrs_t * const csrs = &pdq->pdq_csrs; - pdq_uint32_t data; - int progress = 0; - - if (pdq->pdq_type == PDQ_DEFPA) - if (*pdq->pdq_pci_csrs.csr_pfi_status & 0x10) - *pdq->pdq_pci_csrs.csr_pfi_status = 0x10; - - while ((data = *csrs->csr_port_status) & PDQ_PSTS_INTR_PENDING) { - progress = 1; - PDQ_PRINTF(("PDQ Interrupt: Status = 0x%08x\n", data)); - if (data & PDQ_PSTS_RCV_DATA_PENDING) { - pdq_process_received_data(pdq, &pdq->pdq_rx_info, - pdq->pdq_dbp->pdqdb_receives, - pdq->pdq_cbp->pdqcb_receives, - PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_receives)); - PDQ_DO_TYPE2_PRODUCER(pdq); - } - if (data & PDQ_PSTS_HOST_SMT_PENDING) { - pdq_process_received_data(pdq, &pdq->pdq_host_smt_info, - pdq->pdq_dbp->pdqdb_host_smt, - pdq->pdq_cbp->pdqcb_host_smt, - PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_host_smt)); - *csrs->csr_host_smt_producer = pdq->pdq_host_smt_info.rx_producer | (pdq->pdq_host_smt_info.rx_completion << 8); - } - if (data & PDQ_PSTS_XMT_DATA_PENDING) - pdq_process_transmitted_data(pdq); - if (data & PDQ_PSTS_UNSOL_PENDING) - pdq_process_unsolicited_events(pdq); - if (data & PDQ_PSTS_CMD_RSP_PENDING) - pdq_process_command_responses(pdq); - if (data & PDQ_PSTS_TYPE_0_PENDING) { - data = *csrs->csr_host_int_type_0; - if (data & PDQ_HOST_INT_STATE_CHANGE) { - pdq_state_t state = PDQ_PSTS_ADAPTER_STATE(*csrs->csr_port_status); - printf(PDQ_OS_PREFIX "%s", PDQ_OS_PREFIX_ARGS, pdq_adapter_states[state]); - if (state == PDQS_LINK_UNAVAILABLE) { - pdq->pdq_flags &= ~PDQ_TXOK; - } else if (state == PDQS_LINK_AVAILABLE) { - pdq->pdq_flags |= PDQ_TXOK; - pdq_os_restart_transmitter(pdq); - } else if (state == PDQS_HALTED) { - pdq_response_error_log_get_t log_entry; - pdq_halt_code_t halt_code = PDQ_PSTS_HALT_ID(*csrs->csr_port_status); - printf(": halt code = %d (%s)\n", - halt_code, pdq_halt_codes[halt_code]); - if (halt_code == PDQH_DMA_ERROR) { - PDQ_PRINTF(("\tPFI status = 0x%x, Host 0 Fatal Interrupt = 0x%x\n", - *pdq->pdq_pci_csrs.csr_pfi_status, - data & PDQ_HOST_INT_FATAL_ERROR)); - } - pdq_read_error_log(pdq, &log_entry); - pdq_stop(pdq); - if (pdq->pdq_flags & PDQ_RUNNING) - pdq_run(pdq); - return 1; - } - printf("\n"); - *csrs->csr_host_int_type_0 = PDQ_HOST_INT_STATE_CHANGE; - } - if (data & PDQ_HOST_INT_FATAL_ERROR) { - pdq_stop(pdq); - if (pdq->pdq_flags & PDQ_RUNNING) - pdq_run(pdq); - return 1; - } - if (data & PDQ_HOST_INT_XMT_DATA_FLUSH) { - printf(PDQ_OS_PREFIX "Flushing transmit queue\n", PDQ_OS_PREFIX_ARGS); - pdq->pdq_flags &= ~PDQ_TXOK; - pdq_flush_transmitter(pdq); - pdq_do_port_control(csrs, PDQ_PCTL_XMT_DATA_FLUSH_DONE); - *csrs->csr_host_int_type_0 = PDQ_HOST_INT_XMT_DATA_FLUSH; - } - } - if (pdq->pdq_type == PDQ_DEFPA) - if (*pdq->pdq_pci_csrs.csr_pfi_status & 0x10) - *pdq->pdq_pci_csrs.csr_pfi_status = 0x10; - } - return progress; -} - -pdq_t * -pdq_initialize( - void *csr_va, - const char *name, - int unit, - void *ctx, - pdq_type_t type) -{ - pdq_t *pdq; - pdq_state_t state; - const pdq_uint32_t contig_bytes = (sizeof(pdq_descriptor_block_t) * 2) - PDQ_OS_PAGESIZE; - pdq_uint8_t *p; - int idx; - - PDQ_ASSERT(sizeof(pdq_descriptor_block_t) == 8192); - PDQ_ASSERT(sizeof(pdq_consumer_block_t) == 64); - PDQ_ASSERT(sizeof(pdq_response_filter_get_t) == PDQ_SIZE_RESPONSE_FILTER_GET); - PDQ_ASSERT(sizeof(pdq_cmd_addr_filter_set_t) == PDQ_SIZE_CMD_ADDR_FILTER_SET); - PDQ_ASSERT(sizeof(pdq_response_addr_filter_get_t) == PDQ_SIZE_RESPONSE_ADDR_FILTER_GET); - PDQ_ASSERT(sizeof(pdq_response_status_chars_get_t) == PDQ_SIZE_RESPONSE_STATUS_CHARS_GET); - PDQ_ASSERT(sizeof(pdq_response_fddi_mib_get_t) == PDQ_SIZE_RESPONSE_FDDI_MIB_GET); - PDQ_ASSERT(sizeof(pdq_response_dec_ext_mib_get_t) == PDQ_SIZE_RESPONSE_DEC_EXT_MIB_GET); - PDQ_ASSERT(sizeof(pdq_unsolicited_event_t) == 512); - - pdq = (pdq_t *) PDQ_OS_MEMALLOC(sizeof(pdq_t)); - if (pdq == NULL) { - PDQ_PRINTF(("malloc(%d) failed\n", sizeof(*pdq))); - return NULL; - } - PDQ_OS_MEMZERO(pdq, sizeof(pdq_t)); - pdq->pdq_type = type; - pdq->pdq_unit = unit; - pdq->pdq_os_ctx = (void *) ctx; - pdq->pdq_os_name = name; - pdq->pdq_flags = PDQ_PRINTCHARS; - /* - * Allocate the additional data structures required by - * the PDQ driver. Allocate a contiguous region of memory - * for the descriptor block. We need to allocated enough - * to guarantee that we will a get 8KB block of memory aligned - * on a 8KB boundary. This turns to require that we allocate - * (N*2 - 1 page) pages of memory. On machine with less than - * a 8KB page size, it mean we will allocate more memory than - * we need. The extra will be used for the unsolicited event - * buffers (though on machines with 8KB pages we will to allocate - * them separately since there will be nothing left overs.) - */ - p = (pdq_uint8_t *) PDQ_OS_MEMALLOC_CONTIG(contig_bytes); - if (p != NULL) { - pdq_physaddr_t physaddr = PDQ_OS_VA_TO_PA(p) & 0x1FFF; - if (physaddr) { - pdq->pdq_unsolicited_info.ui_events = (pdq_unsolicited_event_t *) p; - pdq->pdq_dbp = (pdq_descriptor_block_t *) &p[0x2000 - physaddr]; - } else { - pdq->pdq_dbp = (pdq_descriptor_block_t *) p; - pdq->pdq_unsolicited_info.ui_events = (pdq_unsolicited_event_t *) &p[0x2000]; - } - } - if (contig_bytes == sizeof(pdq_descriptor_block_t)) { - pdq->pdq_unsolicited_info.ui_events = - (pdq_unsolicited_event_t *) PDQ_OS_MEMALLOC( - PDQ_NUM_UNSOLICITED_EVENTS * sizeof(pdq_unsolicited_event_t)); - } - - /* - * Make sure everything got allocated. If not, free what did - * get allocated and return. - */ - if (pdq->pdq_dbp == NULL || pdq->pdq_unsolicited_info.ui_events == NULL) { - cleanup_and_return: - if (pdq->pdq_dbp != NULL) - PDQ_OS_MEMFREE_CONTIG(pdq->pdq_dbp, contig_bytes); - if (contig_bytes == sizeof(pdq_descriptor_block_t) && pdq->pdq_unsolicited_info.ui_events != NULL) - PDQ_OS_MEMFREE(pdq->pdq_unsolicited_info.ui_events, - PDQ_NUM_UNSOLICITED_EVENTS * sizeof(pdq_unsolicited_event_t)); - PDQ_OS_MEMFREE(pdq, sizeof(pdq_t)); - return NULL; - } - - pdq->pdq_cbp = (volatile pdq_consumer_block_t *) &pdq->pdq_dbp->pdqdb_consumer; - pdq->pdq_command_info.ci_bufstart = (pdq_uint8_t *) pdq->pdq_dbp->pdqdb_command_pool; - pdq->pdq_rx_info.rx_buffers = (void *) pdq->pdq_dbp->pdqdb_receive_buffers; - - pdq->pdq_host_smt_info.rx_buffers = (void *) pdq->pdq_dbp->pdqdb_host_smt_buffers; - - PDQ_PRINTF(("PDQ Descriptor Block = %p\n", pdq->pdq_dbp)); - PDQ_PRINTF((" Recieve Queue = %p\n", pdq->pdq_dbp->pdqdb_receives)); - PDQ_PRINTF((" Transmit Queue = %p\n", pdq->pdq_dbp->pdqdb_transmits)); - PDQ_PRINTF((" Host SMT Queue = %p\n", pdq->pdq_dbp->pdqdb_host_smt)); - PDQ_PRINTF((" Command Response Queue = %p\n", pdq->pdq_dbp->pdqdb_command_responses)); - PDQ_PRINTF((" Command Request Queue = %p\n", pdq->pdq_dbp->pdqdb_command_requests)); - PDQ_PRINTF(("PDQ Consumer Block = %p\n", pdq->pdq_cbp)); - - /* - * Zero out the descriptor block. Not really required but - * it pays to be neat. This will also zero out the consumer - * block, command pool, and buffer pointers for the receive - * host_smt rings. - */ - PDQ_OS_MEMZERO(pdq->pdq_dbp, sizeof(*pdq->pdq_dbp)); - - /* - * Initialize the CSR references. - */ - pdq_init_csrs(&pdq->pdq_csrs, csr_va, 1); - switch (pdq->pdq_type) { - case PDQ_DEFPA: pdq_init_pci_csrs(&pdq->pdq_pci_csrs, csr_va, 1); break; -#ifdef PDQ_DO_EISA - case PDQ_DEFEA: pdq_init_esia_csrs(&pdq->pdq_eisa_csrs, csr_va, 1); break; -#endif - default: - break; - } - - PDQ_PRINTF(("PDQ CSRs:\n")); - PDQ_PRINTF((" Port Reset = %p [0x%08x]\n", - pdq->pdq_csrs.csr_port_reset, *pdq->pdq_csrs.csr_port_reset)); - PDQ_PRINTF((" Host Data = %p [0x%08x]\n", - pdq->pdq_csrs.csr_host_data, *pdq->pdq_csrs.csr_host_data)); - PDQ_PRINTF((" Port Control = %p [0x%08x]\n", - pdq->pdq_csrs.csr_port_control, *pdq->pdq_csrs.csr_port_control)); - PDQ_PRINTF((" Port Data A = %p [0x%08x]\n", - pdq->pdq_csrs.csr_port_data_a, *pdq->pdq_csrs.csr_port_data_a)); - PDQ_PRINTF((" Port Data B = %p [0x%08x]\n", - pdq->pdq_csrs.csr_port_data_b, *pdq->pdq_csrs.csr_port_data_b)); - PDQ_PRINTF((" Port Status = %p [0x%08x]\n", - pdq->pdq_csrs.csr_port_status, *pdq->pdq_csrs.csr_port_status)); - PDQ_PRINTF((" Host Int Type 0 = %p [0x%08x]\n", - pdq->pdq_csrs.csr_host_int_type_0, *pdq->pdq_csrs.csr_host_int_type_0)); - PDQ_PRINTF((" Host Int Enable = %p [0x%08x]\n", - pdq->pdq_csrs.csr_host_int_enable, *pdq->pdq_csrs.csr_host_int_enable)); - PDQ_PRINTF((" Type 2 Producer = %p [0x%08x]\n", - pdq->pdq_csrs.csr_type_2_producer, *pdq->pdq_csrs.csr_type_2_producer)); - PDQ_PRINTF((" Command Response Producer = %p [0x%08x]\n", - pdq->pdq_csrs.csr_cmd_response_producer, *pdq->pdq_csrs.csr_cmd_response_producer)); - PDQ_PRINTF((" Command Request Producer = %p [0x%08x]\n", - pdq->pdq_csrs.csr_cmd_request_producer, *pdq->pdq_csrs.csr_cmd_request_producer)); - PDQ_PRINTF((" Host SMT Producer = %p [0x%08x]\n", - pdq->pdq_csrs.csr_host_smt_producer, *pdq->pdq_csrs.csr_host_smt_producer)); - PDQ_PRINTF((" Unsolicited Producer = %p [0x%08x]\n", - pdq->pdq_csrs.csr_unsolicited_producer, *pdq->pdq_csrs.csr_unsolicited_producer)); - - /* - * Initialize the command information block - */ - pdq->pdq_command_info.ci_buffree = sizeof(pdq->pdq_dbp->pdqdb_command_pool); - pdq->pdq_command_info.ci_bufend = pdq->pdq_command_info.ci_bufstart + pdq->pdq_command_info.ci_buffree; - pdq->pdq_command_info.ci_bufptr = pdq->pdq_command_info.ci_bufstart; - pdq->pdq_command_info.ci_pa_bufstart = PDQ_OS_VA_TO_PA(pdq->pdq_command_info.ci_bufstart); - pdq->pdq_command_info.ci_request_max = pdq->pdq_command_info.ci_request_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_command_requests); - pdq->pdq_command_info.ci_response_max = pdq->pdq_command_info.ci_response_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_command_responses); - - /* - * Initialize the unsolicited event information block - */ - pdq->pdq_unsolicited_info.ui_free = PDQ_NUM_UNSOLICITED_EVENTS; - pdq->pdq_unsolicited_info.ui_pa_bufstart = PDQ_OS_VA_TO_PA(pdq->pdq_unsolicited_info.ui_events); - for (idx = 0; idx < sizeof(pdq->pdq_dbp->pdqdb_unsolicited_events)/sizeof(pdq->pdq_dbp->pdqdb_unsolicited_events[0]); idx++) { - pdq_rxdesc_t *rxd = &pdq->pdq_dbp->pdqdb_unsolicited_events[idx]; - pdq_unsolicited_event_t *event = &pdq->pdq_unsolicited_info.ui_events[idx & (PDQ_NUM_UNSOLICITED_EVENTS-1)]; - - rxd->rxd_sop = 1; - rxd->rxd_seg_cnt = 0; - rxd->rxd_seg_len_hi = sizeof(pdq_unsolicited_event_t) / 16; - rxd->rxd_pa_lo = pdq->pdq_unsolicited_info.ui_pa_bufstart + (const pdq_uint8_t *) event - - (const pdq_uint8_t *) pdq->pdq_unsolicited_info.ui_events; - rxd->rxd_pa_hi = 0; - } - /* - * Initialize the receive information blocks (normal and SMT). - */ - pdq->pdq_rx_info.rx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_receives); - pdq->pdq_rx_info.rx_target = pdq->pdq_rx_info.rx_free - PDQ_RX_SEGCNT * 8; - - pdq->pdq_host_smt_info.rx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_host_smt); - pdq->pdq_host_smt_info.rx_target = pdq->pdq_host_smt_info.rx_free - PDQ_RX_SEGCNT * 3; - - /* - * Initialize the transmit information block. - */ - pdq->pdq_tx_hdr[0] = PDQ_FDDI_PH0; - pdq->pdq_tx_hdr[1] = PDQ_FDDI_PH1; - pdq->pdq_tx_hdr[2] = PDQ_FDDI_PH2; - pdq->pdq_tx_info.tx_free = PDQ_RING_MASK(pdq->pdq_dbp->pdqdb_transmits); - pdq->pdq_tx_info.tx_hdrdesc.txd_seg_len = sizeof(pdq->pdq_tx_hdr); - pdq->pdq_tx_info.tx_hdrdesc.txd_sop = 1; - pdq->pdq_tx_info.tx_hdrdesc.txd_pa_lo = PDQ_OS_VA_TO_PA(pdq->pdq_tx_hdr); - - state = PDQ_PSTS_ADAPTER_STATE(*pdq->pdq_csrs.csr_port_status); - PDQ_PRINTF(("PDQ Adapter State = %s\n", pdq_adapter_states[state])); - - /* - * Stop the PDQ if it is running and put it into a known state. - */ - state = pdq_stop(pdq); - - /* state = PDQ_PSTS_ADAPTER_STATE(*pdq->pdq_csrs.csr_port_status); */ - PDQ_PRINTF(("PDQ Adapter State = %s\n", pdq_adapter_states[state])); - PDQ_ASSERT(state == PDQS_DMA_AVAILABLE); - /* - * If the adapter is not the state we expect, then the initialization - * failed. Cleanup and exit. - */ - if (state == PDQS_RESET || state == PDQS_HALTED || state == PDQS_UPGRADE) - goto cleanup_and_return; - - PDQ_PRINTF(("PDQ Hardware Address = %02x-%02x-%02x-%02x-%02x-%02x\n", - pdq->pdq_hwaddr.lanaddr_bytes[0], pdq->pdq_hwaddr.lanaddr_bytes[1], - pdq->pdq_hwaddr.lanaddr_bytes[2], pdq->pdq_hwaddr.lanaddr_bytes[3], - pdq->pdq_hwaddr.lanaddr_bytes[4], pdq->pdq_hwaddr.lanaddr_bytes[5])); - PDQ_PRINTF(("PDQ Firmware Revision = %c%c%c%c\n", - pdq->pdq_fwrev.fwrev_bytes[0], pdq->pdq_fwrev.fwrev_bytes[1], - pdq->pdq_fwrev.fwrev_bytes[2], pdq->pdq_fwrev.fwrev_bytes[3])); - PDQ_PRINTF(("PDQ Chip Revision = ")); - switch (pdq->pdq_chip_rev) { - case PDQ_CHIP_REV_A_B_OR_C: PDQ_PRINTF(("Rev C or below")); break; - case PDQ_CHIP_REV_D: PDQ_PRINTF(("Rev D")); break; - case PDQ_CHIP_REV_E: PDQ_PRINTF(("Rev E")); break; - default: PDQ_PRINTF(("Unknown Rev %d", (int) pdq->pdq_chip_rev)); - } - PDQ_PRINTF(("\n")); - - return pdq; -} diff --git a/sys/pci/pdq_os.h b/sys/pci/pdq_os.h deleted file mode 100644 index f4e51cb06495..000000000000 --- a/sys/pci/pdq_os.h +++ /dev/null @@ -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 -#elif defined(__FreeBSD__) || defined(__bsdi__) - -#include -#include -#ifndef M_MCAST -#include -#endif -#include -#include -#include -#include -#include -#include - -#ifdef __FreeBSD__ -#include -#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 -#elif defined(__bsdi__) -#include -#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 */ diff --git a/sys/pci/pdqreg.h b/sys/pci/pdqreg.h deleted file mode 100644 index 0b92bb56ed6d..000000000000 --- a/sys/pci/pdqreg.h +++ /dev/null @@ -1,1093 +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$ - * - * $Log: pdqreg.h,v $ - * Revision 1.3 1996/01/30 22:59:59 mpp - * Fix a bunch of spelling errors in the comment fields of - * a bunch of system include files. - * - * Revision 1.2 1995/05/30 08:13:15 rgrimes - * Remove trailing whitespace. - * - * Revision 1.1 1995/03/14 09:16:07 davidg - * Added support for generic FDDI and the DEC DEFEA and DEFPA FDDI adapters. - * - * Submitted by: Matt Thomas - * - * Revision 1.5 1995/03/10 17:41:55 thomas - * Add DEFTA, DEFQA, and DEFAA - * - * Revision 1.4 1995/03/06 17:07:05 thomas - * Add copyright/disclaimer - * Add EISA register definitions - * - * Revision 1.3 1995/03/03 13:48:35 thomas - * more fixes - * - * - */ - -/* - * DEC PDQ FDDI Controller; PDQ port driver definitions - * - * Written by Matt Thomas - * - */ - -#ifndef _PDQREG_H -#define _PDQREG_H - -#include -#if defined(PDQTEST) && !defined(PDQ_NDEBUG) -#include -#define PDQ_ASSERT assert -#else -#define PDQ_ASSERT(x) -#endif - -#define PDQ_RING_SIZE(array) ((sizeof(array) / sizeof(array[0]))) -#define PDQ_ARRAY_SIZE(array) ((sizeof(array) / sizeof(array[0]))) -#define PDQ_RING_MASK(array) (PDQ_RING_SIZE(array) - 1) -#define PDQ_BITMASK(n) (1L << (pdq_uint32_t) (n)) - -#define PDQ_FDDI_MAX 4495 -#define PDQ_FDDI_LLC_MIN 20 -#define PDQ_FDDI_SMT_MIN 37 - -#define PDQ_FDDI_SMT 0x40 -#define PDQ_FDDI_LLC_ASYNC 0x50 -#define PDQ_FDDI_LLC_SYNC 0xD0 -#define PDQ_FDDI_IMP_ASYNC 0x60 -#define PDQ_FDDI_IMP_SYNC 0xE0 - -#define PDQ_FDDIFC_C 0x80 -#define PDQ_FDDIFC_L 0x40 -#define PDQ_FDDIFC_F 0x30 -#define PDQ_FDDIFC_Z 0x0F - -#define PDQ_FDDI_PH0 0x20 -#define PDQ_FDDI_PH1 0x38 -#define PDQ_FDDI_PH2 0x00 - -typedef unsigned int pdq_uint32_t; -typedef unsigned short pdq_uint16_t; -typedef unsigned char pdq_uint8_t; - -typedef pdq_uint32_t pdq_physaddr_t; - -typedef struct { - pdq_uint8_t lanaddr_bytes[8]; -} pdq_lanaddr_t; - -typedef struct { - pdq_uint8_t fwrev_bytes[4]; -} pdq_fwrev_t; - -typedef enum { - PDQS_RESET=0, - PDQS_UPGRADE=1, - PDQS_DMA_UNAVAILABLE=2, - PDQS_DMA_AVAILABLE=3, - PDQS_LINK_AVAILABLE=4, - PDQS_LINK_UNAVAILABLE=5, - PDQS_HALTED=6, - PDQS_RING_MEMBER=7 -} pdq_state_t; - -typedef struct { - volatile pdq_uint32_t *csr_port_reset; /* 0x00 [RW] */ - volatile pdq_uint32_t *csr_host_data; /* 0x04 [R] */ - volatile pdq_uint32_t *csr_port_control; /* 0x08 [RW] */ - volatile pdq_uint32_t *csr_port_data_a; /* 0x0C [RW] */ - volatile pdq_uint32_t *csr_port_data_b; /* 0x10 [RW] */ - volatile pdq_uint32_t *csr_port_status; /* 0x14 [R] */ - volatile pdq_uint32_t *csr_host_int_type_0; /* 0x18 [RW] */ - volatile pdq_uint32_t *csr_host_int_enable; /* 0x1C [RW] */ - volatile pdq_uint32_t *csr_type_2_producer; /* 0x20 [RW] */ - volatile pdq_uint32_t *csr_cmd_response_producer; /* 0x28 [RW] */ - volatile pdq_uint32_t *csr_cmd_request_producer; /* 0x2C [RW] */ - volatile pdq_uint32_t *csr_host_smt_producer; /* 0x30 [RW] */ - volatile pdq_uint32_t *csr_unsolicited_producer; /* 0x34 [RW] */ -} pdq_csrs_t; - -typedef struct { - volatile pdq_uint32_t *csr_pfi_mode_control; /* 0x40 [RW] */ - volatile pdq_uint32_t *csr_pfi_status; /* 0x44 [RW] */ - volatile pdq_uint32_t *csr_fifo_write; /* 0x48 [RW] */ - volatile pdq_uint32_t *csr_fifo_read; /* 0x4C [RW] */ -} pdq_pci_csrs_t; - -#define PDQ_PFI_MODE_DMA_ENABLE 0x01 /* DMA Enable */ -#define PDQ_PFI_MODE_PFI_PCI_INTR 0x02 /* PFI-to-PCI Int Enable */ -#define PDQ_PFI_MODE_PDQ_PCI_INTR 0x04 /* PDQ-to-PCI Int Enable */ - -#define PDQ_PFI_STATUS_PDQ_INTR 0x10 /* PDQ Int received */ -#define PDQ_PFI_STATUS_DMA_ABORT 0x08 /* PDQ DMA Abort asserted */ - -#define PDQ_EISA_BURST_HOLDOFF 0x0040 -#define PDQ_EISA_SLOT_ID 0x0C80 -#define PDQ_EISA_SLOT_CTRL 0x0C84 -#define PDQ_EISA_MEM_ADD_CMP_0 0x0C85 -#define PDQ_EISA_MEM_ADD_CMP_1 0x0C86 -#define PDQ_EISA_MEM_ADD_CMP_2 0x0C87 -#define PDQ_EISA_MEM_ADD_HI_CMP_0 0x0C88 -#define PDQ_EISA_MEM_ADD_HI_CMP_1 0x0C89 -#define PDQ_EISA_MEM_ADD_HI_CMP_2 0x0C8A -#define PDQ_EISA_MEM_ADD_MASK_0 0x0C8B -#define PDQ_EISA_MEM_ADD_MASK_1 0x0C8C -#define PDQ_EISA_MEM_ADD_MASK_2 0x0C8D -#define PDQ_EISA_MEM_ADD_LO_CMP_0 0x0C8E -#define PDQ_EISA_MEM_ADD_LO_CMP_1 0x0C8F -#define PDQ_EISA_MEM_ADD_LO_CMP_2 0x0C90 -#define PDQ_EISA_IO_CMP_0_0 0x0C91 -#define PDQ_EISA_IO_CMP_0_1 0x0C92 -#define PDQ_EISA_IO_CMP_1_0 0x0C93 -#define PDQ_EISA_IO_CMP_1_1 0x0C94 -#define PDQ_EISA_IO_CMP_2_0 0x0C95 -#define PDQ_EISA_IO_CMP_2_1 0x0C96 -#define PDQ_EISA_IO_CMP_3_0 0x0C97 -#define PDQ_EISA_IO_CMP_3_1 0x0C98 -#define PDQ_EISA_IO_ADD_MASK_0_0 0x0C99 -#define PDQ_EISA_IO_ADD_MASK_0_1 0x0C9A -#define PDQ_EISA_IO_ADD_MASK_1_0 0x0C9B -#define PDQ_EISA_IO_ADD_MASK_1_1 0x0C9C -#define PDQ_EISA_IO_ADD_MASK_2_0 0x0C9D -#define PDQ_EISA_IO_ADD_MASK_2_1 0x0C9E -#define PDQ_EISA_IO_ADD_MASK_3_0 0x0C9F -#define PDQ_EISA_IO_ADD_MASK_3_1 0x0CA0 -#define PDQ_EISA_MOD_CONFIG_1 0x0CA1 -#define PDQ_EISA_MOD_CONFIG_2 0x0CA2 -#define PDQ_EISA_MOD_CONFIG_3 0x0CA3 -#define PDQ_EISA_MOD_CONFIG_4 0x0CA4 -#define PDQ_EISA_MOD_CONFIG_5 0x0CA5 -#define PDQ_EISA_MOD_CONFIG_6 0x0CA6 -#define PDQ_EISA_MOD_CONFIG_7 0x0CA7 -#define PDQ_EISA_DIP_SWITCH 0x0CA8 -#define PDQ_EISA_IO_CONFIG_STAT_0 0x0CA9 -#define PDQ_EISA_IO_CONFIG_STAT_1 0x0CAA -#define PDQ_EISA_DMA_CONFIG 0x0CAB -#define PDQ_EISA_INPUT_PORT 0x0CAC -#define PDQ_EISA_OUTPUT_PORT 0x0CAD -#define PDQ_EISA_FUNCTION_CTRL 0x0CAE - -/* - * Port Reset Data A Definitions - */ -#define PDQ_PRESET_SKIP_SELFTEST 0x0004 -#define PDQ_PRESET_SOFT_RESET 0x0002 -#define PDQ_PRESET_UPGRADE 0x0001 -/* - * Port Control Register Definitions - */ -#define PDQ_PCTL_CMD_ERROR 0x8000 -#define PDQ_PCTL_FLASH_BLAST 0x4000 -#define PDQ_PCTL_HALT 0x2000 -#define PDQ_PCTL_COPY_DATA 0x1000 -#define PDQ_PCTL_ERROR_LOG_START 0x0800 -#define PDQ_PCTL_ERROR_LOG_READ 0x0400 -#define PDQ_PCTL_XMT_DATA_FLUSH_DONE 0x0200 -#define PDQ_PCTL_DMA_INIT 0x0100 -#define PDQ_DMA_INIT_LW_BSWAP_DATA 0x02 -#define PDQ_DMA_INIT_LW_BSWAP_LITERAL 0x01 -#define PDQ_PCTL_INIT_START 0x0080 -#define PDQ_PCTL_CONSUMER_BLOCK 0x0040 -#define PDQ_PCTL_DMA_UNINIT 0x0020 -#define PDQ_PCTL_RING_MEMBER 0x0010 -#define PDQ_PCTL_MLA_READ 0x0008 -#define PDQ_PCTL_FW_REV_READ 0x0004 -#define PDQ_PCTL_DEVICE_SPECIFIC 0x0002 -#define PDQ_PCTL_SUB_CMD 0x0001 - -typedef enum { - PDQ_SUB_CMD_LINK_UNINIT=1, - PDQ_SUB_CMD_DMA_BURST_SIZE_SET=2, - PDQ_SUB_CMD_PDQ_REV_GET=4 -} pdq_sub_cmd_t; - -typedef enum { - PDQ_DMA_BURST_4LW=0, - PDQ_DMA_BURST_8LW=1, - PDQ_DMA_BURST_16LW=2, - PDQ_DMA_BURST_32LW=3 -} pdq_dma_burst_size_t; - -typedef enum { - PDQ_CHIP_REV_A_B_OR_C=0, - PDQ_CHIP_REV_D=2, - PDQ_CHIP_REV_E=4 -} pdq_chip_rev_t; -/* - * Port Status Register Definitions - */ -#define PDQ_PSTS_RCV_DATA_PENDING 0x80000000ul -#define PDQ_PSTS_XMT_DATA_PENDING 0x40000000ul -#define PDQ_PSTS_HOST_SMT_PENDING 0x20000000ul -#define PDQ_PSTS_UNSOL_PENDING 0x10000000ul -#define PDQ_PSTS_CMD_RSP_PENDING 0x08000000ul -#define PDQ_PSTS_CMD_REQ_PENDING 0x04000000ul -#define PDQ_PSTS_TYPE_0_PENDING 0x02000000ul -#define PDQ_PSTS_INTR_PENDING 0xFE000000ul -#define PDQ_PSTS_ADAPTER_STATE(sts) ((pdq_state_t) (((sts) >> 8) & 0x07)) -#define PDQ_PSTS_HALT_ID(sts) ((pdq_halt_code_t) ((sts) & 0xFF)) -/* - * Host Interrupt Register Definitions - */ -#define PDQ_HOST_INT_TX_ENABLE 0x80000000ul -#define PDQ_HOST_INT_RX_ENABLE 0x40000000ul -#define PDQ_HOST_INT_UNSOL_ENABLE 0x20000000ul -#define PDQ_HOST_INT_HOST_SMT_ENABLE 0x10000000ul -#define PDQ_HOST_INT_CMD_RSP_ENABLE 0x08000000ul -#define PDQ_HOST_INT_CMD_RQST_ENABLE 0x04000000ul - -#define PDQ_HOST_INT_1MS 0x80 -#define PDQ_HOST_INT_20MS 0x40 -#define PDQ_HOST_INT_CSR_CMD_DONE 0x20 -#define PDQ_HOST_INT_STATE_CHANGE 0x10 -#define PDQ_HOST_INT_XMT_DATA_FLUSH 0x08 -#define PDQ_HOST_INT_NXM 0x04 -#define PDQ_HOST_INT_PM_PARITY_ERROR 0x02 -#define PDQ_HOST_INT_HOST_BUS_PARITY_ERROR 0x01 -#define PDQ_HOST_INT_FATAL_ERROR 0x07 - -typedef enum { - PDQH_SELFTEST_TIMEOUT=0, - PDQH_HOST_BUS_PARITY_ERROR=1, - PDQH_HOST_DIRECTED_HALT=2, - PDQH_SOFTWARE_FAULT=3, - PDQH_HARDWARE_FAULT=4, - PDQH_PC_TRACE_PATH_TEST=5, - PDQH_DMA_ERROR=6, - PDQH_IMAGE_CRC_ERROR=7, - PDQH_ADAPTER_PROCESSOR_ERROR=8, - PDQH_MAX=9 -} pdq_halt_code_t; - -typedef struct { - pdq_uint16_t pdqcb_receives; - pdq_uint16_t pdqcb_transmits; - pdq_uint32_t pdqcb__filler1; - pdq_uint32_t pdqcb_host_smt; - pdq_uint32_t pdqcb__filler2; - pdq_uint32_t pdqcb_unsolicited_event; - pdq_uint32_t pdqcb__filler3; - pdq_uint32_t pdqcb_command_response; - pdq_uint32_t pdqcb__filler4; - pdq_uint32_t pdqcb_command_request; - pdq_uint32_t pdqcb__filler5[7]; -} pdq_consumer_block_t; - -#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN -#define PDQ_BITFIELD2(a, b) b, a -#define PDQ_BITFIELD3(a, b, c) c, b, a -#define PDQ_BITFIELD4(a, b, c, d) d, c, b, a -#define PDQ_BITFIELD5(a, b, c, d, e) e, d, c, b, a -#define PDQ_BITFIELD12(a, b, c, d, e, f, g, h, i, j, k, l) \ - l, k, j, i, h, g, f, e, d, c, b, a -#else -#define PDQ_BITFIELD2(a, b) a, b -#define PDQ_BITFIELD3(a, b, c) a, b, c -#define PDQ_BITFIELD4(a, b, c, d) a, b, c, d -#define PDQ_BITFIELD5(a, b, c, d, e) a, b, c, d, e -#define PDQ_BITFIELD12(a, b, c, d, e, f, g, h, i, j, k, l) \ - a, b, c, d, e, f, g, h, i, j, k, l -#endif - -typedef struct { - pdq_uint32_t PDQ_BITFIELD5(rxd_pa_hi : 16, - rxd_seg_cnt : 4, - rxd_seg_len_hi : 9, - rxd_seg_len_lo : 2, - rxd_sop : 1); - pdq_uint32_t rxd_pa_lo; -} pdq_rxdesc_t; - -typedef union { - pdq_uint32_t rxs_status; - pdq_uint32_t PDQ_BITFIELD12(rxs_len : 13, - rxs_rcc_ss : 2, - rxs_rcc_dd : 2, - rxs_rcc_reason : 3, - rxs_rcc_badcrc : 1, - rxs_rcc_badpdu : 1, - rxs_fsb__reserved : 2, - rxs_fsb_c : 1, - rxs_fsb_a : 1, - rxs_fsb_e : 1, - rxs_fsc : 3, - rxs__reserved : 2); -} pdq_rxstatus_t; - -typedef struct { - pdq_uint32_t PDQ_BITFIELD5(txd_pa_hi : 16, - txd_seg_len : 13, - txd_mbz : 1, - txd_eop : 1, - txd_sop : 1); - pdq_uint32_t txd_pa_lo; -} pdq_txdesc_t; - -typedef struct { - pdq_rxdesc_t pdqdb_receives[256]; /* 2048; 0x0000..0x07FF */ - pdq_txdesc_t pdqdb_transmits[256]; /* 2048; 0x0800..0x0FFF */ - pdq_rxdesc_t pdqdb_host_smt[64]; /* 512; 0x1000..0x11FF */ - pdq_rxdesc_t pdqdb_unsolicited_events[16]; /* 128; 0x1200..0x127F */ - pdq_rxdesc_t pdqdb_command_responses[16]; /* 128; 0x1280..0x12FF */ - pdq_txdesc_t pdqdb_command_requests[16]; /* 128; 0x1300..0x137F */ - /* - * The rest of the descriptor block is unused. - * As such we could use it for other things. - */ - pdq_consumer_block_t pdqdb_consumer; /* 64; 0x1380..0x13BF */ - void *pdqdb_receive_buffers[256]; /* 1024/2048; 0x13C0..0x17BF 0x13C0..0x1BBF */ - void *pdqdb_host_smt_buffers[64]; /* 256/ 512; 0x17C0..0x18BF 0x1BC0..0x1DBF */ - /* - * The maximum command size is 512 so as long as thes - * command is at least that long all will be fine. - */ -#ifdef __alpha - pdq_uint32_t pdqdb_command_pool[144]; -#else - pdq_uint32_t pdqdb_command_pool[464]; -#endif -} pdq_descriptor_block_t; - -typedef enum { - PDQ_DEFPA, /* PCI-bus */ - PDQ_DEFEA, /* EISA-bus */ - PDQ_DEFTA, /* TurboChannel */ - PDQ_DEFAA, /* FutureBus+ */ - PDQ_DEFQA /* Q-bus */ -} pdq_type_t; - -typedef struct { - /* - * These value manage the available space in command/response - * buffer area. - */ - pdq_physaddr_t ci_pa_bufstart; - pdq_uint8_t *ci_bufstart; - pdq_uint8_t *ci_bufend; - pdq_uint8_t *ci_bufptr; - size_t ci_buffree; - /* - * Bitmask of commands to sent to the PDQ - */ - pdq_uint32_t ci_pending_commands; - /* - * Variables to maintain the PDQ queues. - */ - pdq_uint32_t ci_request_free; - pdq_uint32_t ci_response_free; - pdq_uint32_t ci_request_max; - pdq_uint32_t ci_response_max; - pdq_uint32_t ci_request_producer; - pdq_uint32_t ci_response_producer; - pdq_uint32_t ci_request_completion; - pdq_uint32_t ci_response_completion; -} pdq_command_info_t; - -#define PDQ_SIZE_UNSOLICITED_EVENT 512 -#define PDQ_NUM_UNSOLICITED_EVENTS (PDQ_OS_PAGESIZE / PDQ_SIZE_UNSOLICITED_EVENT) - -typedef struct _pdq_unsolicited_event_t pdq_unsolicited_event_t; - -typedef struct { - pdq_physaddr_t ui_pa_bufstart; - pdq_unsolicited_event_t *ui_events; - - pdq_uint32_t ui_free; - pdq_uint32_t ui_producer; - pdq_uint32_t ui_completion; -} pdq_unsolicited_info_t; - -#define PDQ_RX_FC_OFFSET (sizeof(pdq_rxstatus_t) + 3) -#define PDQ_RX_SEGCNT ((PDQ_FDDI_MAX + PDQ_OS_DATABUF_SIZE - 1) / PDQ_OS_DATABUF_SIZE) -#define PDQ_DO_TYPE2_PRODUCER(pdq) \ - (*pdq->pdq_csrs.csr_type_2_producer = (pdq->pdq_rx_info.rx_producer << 0) \ - | (pdq->pdq_tx_info.tx_producer << 8) \ - | (pdq->pdq_rx_info.rx_completion << 16) \ - | (pdq->pdq_tx_info.tx_completion << 24)) -#define PDQ_ADVANCE(n, a, m) ((n) = ((n) + (a)) & (m)) - -typedef struct { - void *q_head; - void *q_tail; -} pdq_databuf_queue_t; - -typedef struct { - void *rx_buffers; - - pdq_uint32_t rx_target; - pdq_uint32_t rx_free; - pdq_uint32_t rx_producer; - pdq_uint32_t rx_completion; -} pdq_rx_info_t; - -typedef struct { - pdq_databuf_queue_t tx_txq; - pdq_txdesc_t tx_hdrdesc; - pdq_uint8_t tx_descriptor_count[256]; - - pdq_uint32_t tx_free; - pdq_uint32_t tx_producer; - pdq_uint32_t tx_completion; -} pdq_tx_info_t; - -typedef struct { - pdq_csrs_t pdq_csrs; - pdq_pci_csrs_t pdq_pci_csrs; - pdq_type_t pdq_type; - pdq_chip_rev_t pdq_chip_rev; - pdq_lanaddr_t pdq_hwaddr; - pdq_fwrev_t pdq_fwrev; - pdq_descriptor_block_t *pdq_dbp; - volatile pdq_consumer_block_t *pdq_cbp; - pdq_uint32_t pdq_flags; -#define PDQ_PROMISC 0x0001 -#define PDQ_ALLMULTI 0x0002 -#define PDQ_PASS_SMT 0x0004 -#define PDQ_RUNNING 0x0008 -#define PDQ_PRINTCHARS 0x0010 -#define PDQ_TXOK 0x0020 - const char *pdq_os_name; - void *pdq_os_ctx; - pdq_uint32_t pdq_unit; - pdq_command_info_t pdq_command_info; - pdq_unsolicited_info_t pdq_unsolicited_info; - pdq_tx_info_t pdq_tx_info; - pdq_rx_info_t pdq_rx_info; - pdq_rx_info_t pdq_host_smt_info; - pdq_uint8_t pdq_tx_hdr[3]; -} pdq_t; - -typedef enum { - PDQC_START=0, - PDQC_FILTER_SET=1, - PDQC_FILTER_GET=2, - PDQC_CHARS_SET=3, - PDQC_STATUS_CHARS_GET=4, - PDQC_COUNTERS_GET=5, - PDQC_COUNTERS_SET=6, - PDQC_ADDR_FILTER_SET=7, - PDQC_ADDR_FILTER_GET=8, - PDQC_ERROR_LOG_CLEAR=9, - PDQC_ERROR_LOG_GET=10, - PDQC_FDDI_MIB_GET=11, - PDQC_DEC_EXT_MIB_GET=12, - PDQC_DEV_SPECIFIC_GET=13, - PDQC_SNMP_SET=14, - PDQC_SMT_MIB_GET=16, - PDQC_SMT_MIB_SET=17 -} pdq_cmd_code_t; - -typedef enum { - PDQR_SUCCESS=0, - PDQR_FAILURE=1, - PDQR_WARNING=2, - PDQR_LOOP_MODE_BAD=3, - PDQR_ITEM_CODE_BAD=4, - PDQR_TVX_BAD=5, - PDQR_TREQ_BAD=6, - PDQR_RESTRICTED_TOKEN_BAD=7, - PDQR_NO_EOL=12, - PDQR_FILTER_STATE_BAD=13, - PDQR_CMD_TYPE_BAD=14, - PDQR_ADAPTER_STATE_BAD=15, - PDQR_RING_PURGER_BAD=16, - PDQR_LEM_THRESHOLD_BAD=17, - PDQR_LOOP_NOT_SUPPORTED=18, - PDQR_FLUSH_TIME_BAD=19, - PDQR_NOT_YET_IMPLEMENTED=20, - PDQR_CONFIG_POLICY_BAD=21, - PDQR_STATION_ACTION_BAD=22, - PDQR_MAC_ACTION_BAD=23, - PDQR_CON_POLICIES_BAD=24, - PDQR_MAC_LOOP_TIME_BAD=25, - PDQR_TB_MAX_BAD=26, - PDQR_LER_CUTOFF_BAD=27, - PDQR_LER_ALARM_BAD=28, - PDQR_MAC_PATHS_REQ_BAD=29, - PDQR_MAC_T_REQ_BAD=30, - PDQR_EMAC_RING_PURGER_BAD=31, - PDQR_EMAC_RTOKEN_TIMOUT_AD=32, - PDQR_NO_SUCH_ENTRY=33, - PDQR_T_NOTIFY_BAD=34, - PDQR_TR_MAX_EXP_BAD=35, - PDQR_FRAME_ERR_THRESHOLD_BAD=36, - PDQR_MAX_TREQ_BAD=37, - PDQR_FULL_DUPLEX_ENABLE_BAD=38, - PDQR_ITEM_INDEX_BAD=39 -} pdq_response_code_t; - -typedef enum { - PDQI_EOL=0, - PDQI_T_REQ=1, - PDQI_TVX=2, - PDQI_RESTRICTED_TOKEN=3, - PDQI_LEM_THRESHOLD=4, - PDQI_RING_PURGER=5, - PDQI_COUNTER_INTERVAL=6, - PDQI_IND_GROUP_PROM=7, - PDQI_GROUP_PROM=8, - PDQI_BROADCAST=9, - PDQI_SMT_PROM=10, - PDQI_SMT_USER=11, - PDQI_RESERVED=12, - PDQI_IMPLEMENTOR=13, - PDQI_LOOPBACK_MODE=14, - PDQI_SMT_CONFIG_POLICY=16, - PDQI_SMT_CONNECTION_POLICY=17, - PDQI_SMT_T_NOTIFY=18, - PDQI_SMT_STATION_ACTION=19, - PDQI_MAC_PATHS_REQUESTED=21, - PDQI_MAC_ACTION=23, - PDQI_PORT_CONNECTION_POLICIES=24, - PDQI_PORT_PATHS_REQUESTED=25, - PDQI_PORT_MAC_LOOP_TIME=26, - PDQI_PORT_TB_MAX=27, - PDQI_PORT_LER_CUTOFF=28, - PDQI_PORT_LER_ALARM=29, - PDQI_PORT_ACTION=30, - PDQI_FLUSH_TIME=32, - PDQI_SMT_USER_DATA=33, - PDQI_SMT_STATUS_REPORT_POLICY=34, - PDQI_SMT_TRACE_MAX_EXPIRATION=35, - PDQI_MAC_FRAME_ERR_THRESHOLD=36, - PDQI_MAC_UNIT_DATA_ENABLE=37, - PDQI_PATH_TVX_LOWER_BOUND=38, - PDQI_PATH_TMAX_LOWER_BOUND=39, - PDQI_PATH_MAX_TREQ=40, - PDQI_MAC_TREQ=41, - PDQI_EMAC_RING_PURGER=42, - PDQI_EMAC_RTOKEN_TIMEOUT=43, - PDQI_FULL_DUPLEX_ENABLE=44 -} pdq_item_code_t; - -typedef enum { - PDQ_FALSE=0, - PDQ_TRUE=1 -} pdq_boolean_t; - -typedef enum { - PDQ_FILTER_BLOCK=0, - PDQ_FILTER_PASS=1 -} pdq_filter_state_t; - -typedef enum { - PDQ_STATION_TYPE_SAS=0, - PDQ_STATION_TYPE_DAC=1, - PDQ_STATION_TYPE_SAC=2, - PDQ_STATION_TYPE_NAC=3, - PDQ_STATION_TYPE_DAS=4 -} pdq_station_type_t; - -typedef enum { - PDQ_STATION_STATE_OFF=0, - PDQ_STATION_STATE_ON=1, - PDQ_STATION_STATE_LOOPBACK=2 -} pdq_station_state_t; - -typedef enum { - PDQ_LINK_STATE_OFF_READY=1, - PDQ_LINK_STATE_OFF_FAULT_RECOVERY=2, - PDQ_LINK_STATE_ON_RING_INIT=3, - PDQ_LINK_STATE_ON_RING_RUN=4, - PDQ_LINK_STATE_BROKEN=5 -} pdq_link_state_t; - -typedef enum { - PDQ_DA_TEST_STATE_UNKNOWN=0, - PDQ_DA_TEST_STATE_SUCCESS=1, - PDQ_DA_TEST_STATE_DUPLICATE=2 -} pdq_da_test_state_t; - -typedef enum { - PDQ_RING_PURGER_STATE_OFF=0, - PDQ_RING_PURGER_STATE_CANDIDATE=1, - PDQ_RING_PURGER_STATE_NON_PURGER=2, - PDQ_RING_PURGER_STATE_PURGER=3 -} pdq_ring_purger_state_t; - -typedef enum { - PDQ_FRAME_STRING_MODE_SA_MATCH=0, - PDQ_FRAME_STRING_MODE_FCI_STRIP=1 -} pdq_frame_strip_mode_t; - -typedef enum { - PDQ_RING_ERROR_REASON_NO_ERROR=0, - PDQ_RING_ERROR_REASON_RING_INIT_INITIATED=5, - PDQ_RING_ERROR_REASON_RING_INIT_RECEIVED=6, - PDQ_RING_ERROR_REASON_RING_BEACONING_INITIATED=7, - PDQ_RING_ERROR_REASON_DUPLICATE_ADDRESS_DETECTED=8, - PDQ_RING_ERROR_REASON_DUPLICATE_TOKEN_DETECTED=9, - PDQ_RING_ERROR_REASON_RING_PURGER_ERROR=10, - PDQ_RING_ERROR_REASON_FCI_STRIP_ERROR=11, - PDQ_RING_ERROR_REASON_RING_OP_OSCILLATION=12, - PDQ_RING_ERROR_REASON_DIRECTED_BEACON_RECEVIED=13, - PDQ_RING_ERROR_REASON_PC_TRACE_INITIATED=14, - PDQ_RING_ERROR_REASON_PC_TRACE_RECEVIED=15 -} pdq_ring_error_reason_t; - -typedef enum { - PDQ_STATION_MODE_NORMAL=0, - PDQ_STATION_MODE_INTERNAL_LOOPBACK=1 -} pdq_station_mode_t; - -typedef enum { - PDQ_PHY_TYPE_A=0, - PDQ_PHY_TYPE_B=1, - PDQ_PHY_TYPE_S=2, - PDQ_PHY_TYPE_M=3, - PDQ_PHY_TYPE_UNKNOWN=4 -} pdq_phy_type_t; - -typedef enum { - PDQ_PMD_TYPE_ANSI_MUTLI_MODE=0, - PDQ_PMD_TYPE_ANSI_SINGLE_MODE_TYPE_1=1, - PDQ_PMD_TYPE_ANSI_SIGNLE_MODE_TYPE_2=2, - PDQ_PMD_TYPE_ANSI_SONET=3, - PDQ_PMD_TYPE_LOW_POWER=100, - PDQ_PMD_TYPE_THINWIRE=101, - PDQ_PMD_TYPE_SHIELDED_TWISTED_PAIR=102, - PDQ_PMD_TYPE_UNSHIELDED_TWISTED_PAIR=103 -} pdq_pmd_type_t; - -typedef enum { - PDQ_PMD_CLASS_ANSI_MULTI_MODE=0, - PDQ_PMD_CLASS_SINGLE_MODE_TYPE_1=1, - PDQ_PMD_CLASS_SINGLE_MODE_TYPE_2=2, - PDQ_PMD_CLASS_SONET=3, - PDQ_PMD_CLASS_LOW_COST_POWER_FIBER=4, - PDQ_PMD_CLASS_TWISTED_PAIR=5, - PDQ_PMD_CLASS_UNKNOWN=6, - PDQ_PMD_CLASS_UNSPECIFIED=7 -} pdq_pmd_class_t; - -typedef enum { - PDQ_PHY_STATE_INTERNAL_LOOPBACK=0, - PDQ_PHY_STATE_BROKEN=1, - PDQ_PHY_STATE_OFF_READY=2, - PDQ_PHY_STATE_WAITING=3, - PDQ_PHY_STATE_STARTING=4, - PDQ_PHY_STATE_FAILED=5, - PDQ_PHY_STATE_WATCH=6, - PDQ_PHY_STATE_INUSE=7 -} pdq_phy_state_t; - -typedef enum { - PDQ_REJECT_REASON_NONE=0, - PDQ_REJECT_REASON_LOCAL_LCT=1, - PDQ_REJECT_REASON_REMOTE_LCT=2, - PDQ_REJECT_REASON_LCT_BOTH_SIDES=3, - PDQ_REJECT_REASON_LEM_REJECT=4, - PDQ_REJECT_REASON_TOPOLOGY_ERROR=5, - PDQ_REJECT_REASON_NOISE_REJECT=6, - PDQ_REJECT_REASON_REMOTE_REJECT=7, - PDQ_REJECT_REASON_TRACE_IN_PROGRESS=8, - PDQ_REJECT_REASON_TRACE_RECEIVED_DISABLED=9, - PDQ_REJECT_REASON_STANDBY=10, - PDQ_REJECT_REASON_LCT_PROTOCOL_ERROR=11 -} pdq_reject_reason_t; - -typedef enum { - PDQ_BROKEN_REASON_NONE=0 -} pdq_broken_reason_t; - -typedef enum { - PDQ_RI_REASON_TVX_EXPIRED=0, - PDQ_RI_REASON_TRT_EXPIRED=1, - PDQ_RI_REASON_RING_PURGER_ELECTION_ATTEMPT_LIMIT_EXCEEDED=2, - PDQ_RI_REASON_PURGE_ERROR_LIMIT_EXCEEDED=3, - PDQ_RI_REASON_RESTRICTED_TOKEN_TIMEOUT=4 -} pdq_ri_reason_t; - -typedef enum { - PDQ_LCT_DIRECTION_LOCAL_LCT=0, - PDQ_LCT_DIRECTION_REMOTE_LCT=1, - PDQ_LCT_DIRECTION_LCT_BOTH_SIDES=2 -} pdq_lct_direction_t; - -typedef enum { - PDQ_PORT_A=0, - PDQ_PORT_B=1 -} pdq_port_type_t; - -typedef struct { - pdq_uint8_t station_id_bytes[8]; -} pdq_station_id_t; - -typedef pdq_uint32_t pdq_fdditimer_t; -/* - * Command format for Start, Filter_Get, ... commands - */ -typedef struct { - pdq_cmd_code_t generic_op; -} pdq_cmd_generic_t; - -/* - * Response format for Start, Filter_Set, ... commands - */ -typedef struct { - pdq_uint32_t generic_reserved; - pdq_cmd_code_t generic_op; - pdq_response_code_t generic_status; -} pdq_response_generic_t; - -/* - * Command format for Filter_Set command - */ -typedef struct { - pdq_cmd_code_t filter_set_op; - struct { - pdq_item_code_t item_code; - pdq_filter_state_t filter_state; - } filter_set_items[7]; - pdq_item_code_t filter_set_eol_item_code; -} pdq_cmd_filter_set_t; - -/* - * Response format for Filter_Get command. - */ -typedef struct { - pdq_uint32_t filter_get_reserved; - pdq_cmd_code_t filter_get_op; - pdq_response_code_t filter_get_status; - pdq_filter_state_t filter_get_ind_group_prom; - pdq_filter_state_t filter_get_group_prom; - pdq_filter_state_t filter_get_broadcast_all; - pdq_filter_state_t filter_get_smt_prom; - pdq_filter_state_t filter_get_smt_user; - pdq_filter_state_t filter_get_reserved_all; - pdq_filter_state_t filter_get_implementor_all; -} pdq_response_filter_get_t; - -#define PDQ_SIZE_RESPONSE_FILTER_GET 0x28 - -typedef struct { - pdq_cmd_code_t chars_set_op; - struct { - pdq_item_code_t item_code; - pdq_uint32_t item_value; - pdq_port_type_t item_port; - } chars_set_items[1]; - pdq_item_code_t chars_set_eol_item_code; -} pdq_cmd_chars_set_t; - -typedef struct { - pdq_cmd_code_t addr_filter_set_op; - pdq_lanaddr_t addr_filter_set_addresses[62]; -} pdq_cmd_addr_filter_set_t; - -#define PDQ_SIZE_CMD_ADDR_FILTER_SET 0x1F4 - -typedef struct { - pdq_uint32_t addr_filter_get_reserved; - pdq_cmd_code_t addr_filter_get_op; - pdq_response_code_t addr_filter_get_status; - pdq_lanaddr_t addr_filter_get_addresses[62]; -} pdq_response_addr_filter_get_t; - -#define PDQ_SIZE_RESPONSE_ADDR_FILTER_GET 0x1FC - -typedef struct { - pdq_uint32_t status_chars_get_reserved; - pdq_cmd_code_t status_chars_get_op; - pdq_response_code_t status_chars_get_status; - struct { - /* Station Characteristic Attributes */ - pdq_station_id_t station_id; - pdq_station_type_t station_type; - pdq_uint32_t smt_version_id; - pdq_uint32_t smt_max_version_id; - pdq_uint32_t smt_min_version_id; - /* Station Status Attributes */ - pdq_station_state_t station_state; - /* Link Characteristic Attributes */ - pdq_lanaddr_t link_address; - pdq_fdditimer_t t_req; - pdq_fdditimer_t tvx; - pdq_fdditimer_t restricted_token_timeout; - pdq_boolean_t ring_purger_enable; - pdq_link_state_t link_state; - pdq_fdditimer_t negotiated_trt; - pdq_da_test_state_t dup_addr_flag; - /* Link Status Attributes */ - pdq_lanaddr_t upstream_neighbor; - pdq_lanaddr_t old_upstream_neighbor; - pdq_boolean_t upstream_neighbor_dup_addr_flag; - pdq_lanaddr_t downstream_neighbor; - pdq_lanaddr_t old_downstream_neighbor; - pdq_ring_purger_state_t ring_purger_state; - pdq_frame_strip_mode_t frame_strip_mode; - pdq_ring_error_reason_t ring_error_reason; - pdq_boolean_t loopback; - pdq_fdditimer_t ring_latency; - pdq_lanaddr_t last_dir_beacon_sa; - pdq_lanaddr_t last_dir_beacon_una; - /* Phy Characteristic Attributes */ - pdq_phy_type_t phy_type[2]; - pdq_pmd_type_t pmd_type[2]; - pdq_uint32_t lem_threshold[2]; - /* Phy Status Attributes */ - pdq_phy_state_t phy_state[2]; - pdq_phy_type_t neighbor_phy_type[2]; - pdq_uint32_t link_error_estimate[2]; - pdq_broken_reason_t broken_reason[2]; - pdq_reject_reason_t reject_reason[2]; - /* Miscellaneous */ - pdq_uint32_t counter_interval; - pdq_fwrev_t module_rev; - pdq_fwrev_t firmware_rev; - pdq_uint32_t mop_device_type; - pdq_uint32_t fddi_led[2]; - pdq_uint32_t flush; - } status_chars_get; -} pdq_response_status_chars_get_t; - -#define PDQ_SIZE_RESPONSE_STATUS_CHARS_GET 0xF0 - -typedef struct { - pdq_uint32_t fddi_mib_get_reserved; - pdq_cmd_code_t fddi_mib_get_op; - pdq_response_code_t fddi_mib_get_status; - struct { - /* SMT Objects */ - pdq_station_id_t smt_station_id; - pdq_uint32_t smt_op_version_id; - pdq_uint32_t smt_hi_version_id; - pdq_uint32_t smt_lo_version_id; - pdq_uint32_t smt_mac_ct; - pdq_uint32_t smt_non_master_ct; - pdq_uint32_t smt_master_ct; - pdq_uint32_t smt_paths_available; - pdq_uint32_t smt_config_capabilities; - pdq_uint32_t smt_config_policy; - pdq_uint32_t smt_connection_policy; - pdq_uint32_t smt_t_notify; - pdq_uint32_t smt_status_reporting; - pdq_uint32_t smt_ecm_state; - pdq_uint32_t smt_cf_state; - pdq_uint32_t smt_hold_state; - pdq_uint32_t smt_remote_disconnect_flag; - pdq_uint32_t smt_station_action; - /* MAC Objects */ - pdq_uint32_t mac_frame_status_capabilities; - pdq_uint32_t mac_t_max_greatest_lower_bound; - pdq_uint32_t mac_tvx_greatest_lower_bound; - pdq_uint32_t mac_paths_available; - pdq_uint32_t mac_current_path; - pdq_lanaddr_t mac_upstream_neighbor; - pdq_lanaddr_t mac_old_upstream_neighbor; - pdq_uint32_t mac_dup_addr_test; - pdq_uint32_t mac_paths_requested; - pdq_uint32_t mac_downstream_port_type; - pdq_lanaddr_t mac_smt_address; - pdq_uint32_t mac_t_req; - pdq_uint32_t mac_t_neg; - pdq_uint32_t mac_t_max; - pdq_uint32_t mac_tvx_value; - pdq_uint32_t mac_t_min; - pdq_uint32_t mac_current_frame_status; - pdq_uint32_t mac_frame_error_threshold; - pdq_uint32_t mac_frame_error_ratio; - pdq_uint32_t mac_rmt_state; - pdq_uint32_t mac_da_flag; - pdq_uint32_t mac_una_da_flag; - pdq_uint32_t mac_frame_condition; - pdq_uint32_t mac_chip_set; - pdq_uint32_t mac_action; - /* Port Objects */ - pdq_uint32_t port_pc_type[2]; - pdq_uint32_t port_pc_neighbor[2]; - pdq_uint32_t port_connection_policies[2]; - pdq_uint32_t port_remote_mac_indicated[2]; - pdq_uint32_t port_ce_state[2]; - pdq_uint32_t port_paths_requested[2]; - pdq_uint32_t port_mac_placement[2]; - pdq_uint32_t port_available_paths[2]; - pdq_uint32_t port_mac_loop_time[2]; - pdq_uint32_t port_tb_max[2]; - pdq_uint32_t port_bs_flag[2]; - pdq_uint32_t port_ler_estimate[2]; - pdq_uint32_t port_ler_cutoff[2]; - pdq_uint32_t port_ler_alarm[2]; - pdq_uint32_t port_connect_state[2]; - pdq_uint32_t port_pcm_state[2]; - pdq_uint32_t port_pc_withhold[2]; - pdq_uint32_t port_ler_condition[2]; - pdq_uint32_t port_chip_set[2]; - pdq_uint32_t port_action[2]; - /* Attachment Objects */ - pdq_uint32_t attachment_class; - pdq_uint32_t attachment_optical_bypass_present; - pdq_uint32_t attachment_imax_expiration; - pdq_uint32_t attachment_inserted_status; - pdq_uint32_t attachment_insert_policy; - } fddi_mib_get; -} pdq_response_fddi_mib_get_t; - -#define PDQ_SIZE_RESPONSE_FDDI_MIB_GET 0x17C - -typedef enum { - PDQ_FDX_STATE_IDLE=0, - PDQ_FDX_STATE_REQUEST=1, - PDQ_FDX_STATE_CONFIRM=2, - PDQ_FDX_STATE_OPERATION=3 -} pdq_fdx_state_t; - -typedef struct { - pdq_uint32_t dec_ext_mib_get_reserved; - pdq_cmd_code_t dec_ext_mib_get_op; - pdq_response_code_t dec_ext_mib_get_response; - struct { - /* SMT Objects */ - pdq_uint32_t esmt_station_type; - /* MAC Objects */ - pdq_uint32_t emac_link_state; - pdq_uint32_t emac_ring_purger_state; - pdq_uint32_t emac_ring_purger_enable; - pdq_uint32_t emac_frame_strip_mode; - pdq_uint32_t emac_ring_error_reason; - pdq_uint32_t emac_upstream_nbr_dupl_address_flag; - pdq_uint32_t emac_restricted_token_timeout; - /* Port Objects */ - pdq_uint32_t eport_pmd_type[2]; - pdq_uint32_t eport_phy_state[2]; - pdq_uint32_t eport_reject_reason[2]; - /* Full Duplex Objects */ - pdq_boolean_t fdx_enable; - pdq_boolean_t fdx_operational; - pdq_fdx_state_t fdx_state; - } dec_ext_mib_get; -} pdq_response_dec_ext_mib_get_t; - -#define PDQ_SIZE_RESPONSE_DEC_EXT_MIB_GET 0x50 - -typedef enum { - PDQ_CALLER_ID_NONE=0, - PDQ_CALLER_ID_SELFTEST=1, - PDQ_CALLER_ID_MFG=2, - PDQ_CALLER_ID_FIRMWARE=5, - PDQ_CALLER_ID_CONSOLE=8 -} pdq_caller_id_t; - -typedef struct { - pdq_uint32_t error_log_get__reserved; - pdq_cmd_code_t error_log_get_op; - pdq_response_code_t error_log_get_status; - /* Error Header */ - pdq_uint32_t error_log_get_event_status; - /* Event Information Block */ - pdq_caller_id_t error_log_get_caller_id; - pdq_uint32_t error_log_get_timestamp[2]; - pdq_uint32_t error_log_get_write_count; - /* Diagnostic Information */ - pdq_uint32_t error_log_get_fru_implication_mask; - pdq_uint32_t error_log_get_test_id; - pdq_uint32_t error_log_get_diag_reserved[6]; - /* Firmware Information */ - pdq_uint32_t error_log_get_fw_reserved[112]; -} pdq_response_error_log_get_t; - - -/* - * Definitions for the Unsolicited Event Queue. - */ -typedef enum { - PDQ_UNSOLICITED_EVENT=0, - PDQ_UNSOLICITED_COUNTERS=1 -} pdq_event_t; - -typedef enum { - PDQ_ENTITY_STATION=0, - PDQ_ENTITY_LINK=1, - PDQ_ENTITY_PHY_PORT=2 -} pdq_entity_t; - -typedef enum { - PDQ_STATION_EVENT_TRACE_RECEIVED=1 -} pdq_station_event_t; - -typedef enum { - PDQ_STATION_EVENT_ARGUMENT_REASON=0, /* pdq_uint32_t */ - PDQ_STATION_EVENT_ARGUMENT_EOL=0xFF -} pdq_station_event_argument_t; - -typedef enum { - PDQ_LINK_EVENT_TRANSMIT_UNDERRUN=0, - PDQ_LINK_EVENT_TRANSMIT_FAILED=1, - PDQ_LINK_EVENT_BLOCK_CHECK_ERROR=2, - PDQ_LINK_EVENT_FRAME_STATUS_ERROR=3, - PDQ_LINK_EVENT_PDU_LENGTH_ERROR=4, - PDQ_LINK_EVENT_RECEIVE_DATA_OVERRUN=7, - PDQ_LINK_EVENT_NO_USER_BUFFER=9, - PDQ_LINK_EVENT_RING_INITIALIZATION_INITIATED=10, - PDQ_LINK_EVENT_RING_INITIALIZATION_RECEIVED=11, - PDQ_LINK_EVENT_RING_BEACON_INITIATED=12, - PDQ_LINK_EVENT_DUPLICATE_ADDRESS_FAILURE=13, - PDQ_LINK_EVENT_DUPLICATE_TOKEN_DETECTED=14, - PDQ_LINK_EVENT_RING_PURGE_ERROR=15, - PDQ_LINK_EVENT_FCI_STRIP_ERROR=16, - PDQ_LINK_EVENT_TRACE_INITIATED=17, - PDQ_LINK_EVENT_DIRECTED_BEACON_RECEIVED=18 -} pdq_link_event_t; - -typedef enum { - PDQ_LINK_EVENT_ARGUMENT_REASON=0, /* pdq_rireason_t */ - PDQ_LINK_EVENT_ARGUMENT_DATA_LINK_HEADER=1, /* pdq_dlhdr_t */ - PDQ_LINK_EVENT_ARGUMENT_SOURCE=2, /* pdq_lanaddr_t */ - PDQ_LINK_EVENT_ARGUMENT_UPSTREAM_NEIGHBOR=3,/* pdq_lanaddr_t */ - PDQ_LINK_EVENT_ARGUMENT_EOL=0xFF -} pdq_link_event_argument_t; - -typedef enum { - PDQ_PHY_EVENT_LEM_ERROR_MONITOR_REJECT=0, - PDQ_PHY_EVENT_ELASTICITY_BUFFER_ERROR=1, - PDQ_PHY_EVENT_LINK_CONFIDENCE_TEST_REJECT=2 -} pdq_phy_event_t; - -typedef enum { - PDQ_PHY_EVENT_ARGUMENT_DIRECTION=0, /* pdq_lct_direction_t */ - PDQ_PHY_EVENT_ARGUMENT_EOL=0xFF -} pdq_phy_event_arguments; - -struct _pdq_unsolicited_event_t { - pdq_uint32_t rvent_reserved; - pdq_event_t event_type; - pdq_entity_t event_entity; - pdq_uint32_t event_index; - union { - pdq_station_event_t station_event; - pdq_link_event_t link_event; - pdq_phy_event_t phy_event; - pdq_uint32_t value; - } event_code; - /* - * The remainder of this event is an argument list. - */ - pdq_uint32_t event__filler[123]; -}; - -#endif /* _PDQREG_H */