Added support for generic FDDI and the DEC DEFEA and DEFPA FDDI adapters.
Submitted by: Matt Thomas
This commit is contained in:
parent
78dfa6036a
commit
d41f24e742
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=7055
@ -2,7 +2,7 @@
|
||||
# LINT -- config file for checking all the sources, tries to pull in
|
||||
# as much of the source tree as it can.
|
||||
#
|
||||
# $Id: LINT,v 1.154 1995/03/12 23:43:14 swallace Exp $
|
||||
# $Id: LINT,v 1.155 1995/03/13 18:49:24 swallace Exp $
|
||||
#
|
||||
# NB: You probably don't want to try running a kernel built from this
|
||||
# file. Instead, you should start from GENERIC, and add options from
|
||||
@ -144,6 +144,7 @@ options TPCONS #ISO TP class 0 over X.25
|
||||
# The `ether' pseudo-device provides generic code to handle
|
||||
# Ethernets; it is mandatory when a Ethernet device driver is
|
||||
# configured.
|
||||
# The 'fddi' pseudo-device provides generic code to support FDDI.
|
||||
# The `sppp' pseudo-device serves a similar role for certain types
|
||||
# of synchronous PPP links (like `cx').
|
||||
# The `sl' pseudo-device implements the Serial Line IP (SLIP) service.
|
||||
@ -158,6 +159,7 @@ options TPCONS #ISO TP class 0 over X.25
|
||||
# The `tun' pseudo-device implements the User Process PPP (iijppp)
|
||||
#
|
||||
pseudo-device ether #Generic Ethernet
|
||||
pseudo-device fddi #Generic FDDI
|
||||
pseudo-device sppp #Generic Synchronous PPP
|
||||
pseudo-device loop #Network loopback device
|
||||
pseudo-device sl 2 #Serial Line IP
|
||||
@ -492,6 +494,7 @@ options DSI_SOFT_MODEM #code for DSI Softmodems
|
||||
# ed: Western Digital and SMC 80xx; Novell NE1000 and NE2000; 3Com 3C503
|
||||
# el: 3Com 3C501 (slow!)
|
||||
# ep: 3Com 3C509 (buggy)
|
||||
# fea: DEC DEFEA EISA FDDI adapter
|
||||
# ie: AT&T StarLAN 10 and EN100; 3Com 3C507; unknown NI5210
|
||||
# le: Digital Equipment EtherWorks 2 and EtherWorks 3 (DEPCA, DE100,
|
||||
# DE101, DE200, DE201, DE202, DE203, DE204, DE205, DE422)
|
||||
@ -504,11 +507,12 @@ options DSI_SOFT_MODEM #code for DSI Softmodems
|
||||
|
||||
device cx0 at isa? port 0x240 net irq 15 drq 7 vector cxintr
|
||||
device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 vector edintr
|
||||
device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr
|
||||
device lnc0 at isa? port 0x280 net irq 10 drq 0 vector lncintr
|
||||
device ep0 at isa? port 0x300 net irq 10 vector epintr
|
||||
device el0 at isa? port 0x300 net irq 9 vector elintr
|
||||
device ep0 at isa? port 0x300 net irq 10 vector epintr
|
||||
device fea0 at isa? net irq ? vector feaintr
|
||||
device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr
|
||||
device le0 at isa? port 0x300 net irq 5 iomem 0xd0000 vector le_intr
|
||||
device lnc0 at isa? port 0x280 net irq 10 drq 0 vector lncintr
|
||||
device ze0 at isa? port 0x300 net irq 5 iomem 0xd8000 vector zeintr
|
||||
device zp0 at isa? port 0x300 net irq 10 iomem 0xd8000 vector zpintr
|
||||
|
||||
@ -626,10 +630,14 @@ device apm0 at isa?
|
||||
# The `de' device provides support for the Digital Equipment DC21040
|
||||
# self-contained Ethernet adapter.
|
||||
#
|
||||
# The `fpa' device provides support for the Digital DEFPA PCI FDDI
|
||||
# adapter. pseudo-device fddi is also needed.
|
||||
#
|
||||
# The PROBE_VERBOSE option enables a long listing of chip set registers
|
||||
# for supported PCI chip sets (currently only intel Saturn and Mercury).
|
||||
#
|
||||
controller pci0
|
||||
device ncr0
|
||||
device de0
|
||||
device fpa0
|
||||
options PROBE_VERBOSE
|
||||
|
@ -147,6 +147,7 @@ net/bpf_filter.c optional bpfilter
|
||||
net/if.c standard
|
||||
net/if_disc.c optional disc
|
||||
net/if_ethersubr.c optional ether
|
||||
net/if_fddisubr.c optional fddi
|
||||
net/if_loop.c optional loop
|
||||
net/if_ppp.c optional ppp
|
||||
net/if_sl.c optional sl
|
||||
@ -277,6 +278,10 @@ pci/if_de.c optional de device-driver
|
||||
pci/ncr.c optional ncr device-driver
|
||||
pci/pci.c optional pci device-driver
|
||||
pci/pcisupport.c optional pci
|
||||
pci/if_pdq.c optional fea device-driver
|
||||
pci/pdq.c optional fea device-driver
|
||||
pci/if_pdq.c optional fpa device-driver
|
||||
pci/pdq.c optional fpa device-driver
|
||||
scsi/cd.c optional cd
|
||||
scsi/ch.c optional ch
|
||||
scsi/scsi_base.c optional scbus
|
||||
|
@ -2,7 +2,7 @@
|
||||
# LINT -- config file for checking all the sources, tries to pull in
|
||||
# as much of the source tree as it can.
|
||||
#
|
||||
# $Id: LINT,v 1.154 1995/03/12 23:43:14 swallace Exp $
|
||||
# $Id: LINT,v 1.155 1995/03/13 18:49:24 swallace Exp $
|
||||
#
|
||||
# NB: You probably don't want to try running a kernel built from this
|
||||
# file. Instead, you should start from GENERIC, and add options from
|
||||
@ -144,6 +144,7 @@ options TPCONS #ISO TP class 0 over X.25
|
||||
# The `ether' pseudo-device provides generic code to handle
|
||||
# Ethernets; it is mandatory when a Ethernet device driver is
|
||||
# configured.
|
||||
# The 'fddi' pseudo-device provides generic code to support FDDI.
|
||||
# The `sppp' pseudo-device serves a similar role for certain types
|
||||
# of synchronous PPP links (like `cx').
|
||||
# The `sl' pseudo-device implements the Serial Line IP (SLIP) service.
|
||||
@ -158,6 +159,7 @@ options TPCONS #ISO TP class 0 over X.25
|
||||
# The `tun' pseudo-device implements the User Process PPP (iijppp)
|
||||
#
|
||||
pseudo-device ether #Generic Ethernet
|
||||
pseudo-device fddi #Generic FDDI
|
||||
pseudo-device sppp #Generic Synchronous PPP
|
||||
pseudo-device loop #Network loopback device
|
||||
pseudo-device sl 2 #Serial Line IP
|
||||
@ -492,6 +494,7 @@ options DSI_SOFT_MODEM #code for DSI Softmodems
|
||||
# ed: Western Digital and SMC 80xx; Novell NE1000 and NE2000; 3Com 3C503
|
||||
# el: 3Com 3C501 (slow!)
|
||||
# ep: 3Com 3C509 (buggy)
|
||||
# fea: DEC DEFEA EISA FDDI adapter
|
||||
# ie: AT&T StarLAN 10 and EN100; 3Com 3C507; unknown NI5210
|
||||
# le: Digital Equipment EtherWorks 2 and EtherWorks 3 (DEPCA, DE100,
|
||||
# DE101, DE200, DE201, DE202, DE203, DE204, DE205, DE422)
|
||||
@ -504,11 +507,12 @@ options DSI_SOFT_MODEM #code for DSI Softmodems
|
||||
|
||||
device cx0 at isa? port 0x240 net irq 15 drq 7 vector cxintr
|
||||
device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 vector edintr
|
||||
device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr
|
||||
device lnc0 at isa? port 0x280 net irq 10 drq 0 vector lncintr
|
||||
device ep0 at isa? port 0x300 net irq 10 vector epintr
|
||||
device el0 at isa? port 0x300 net irq 9 vector elintr
|
||||
device ep0 at isa? port 0x300 net irq 10 vector epintr
|
||||
device fea0 at isa? net irq ? vector feaintr
|
||||
device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr
|
||||
device le0 at isa? port 0x300 net irq 5 iomem 0xd0000 vector le_intr
|
||||
device lnc0 at isa? port 0x280 net irq 10 drq 0 vector lncintr
|
||||
device ze0 at isa? port 0x300 net irq 5 iomem 0xd8000 vector zeintr
|
||||
device zp0 at isa? port 0x300 net irq 10 iomem 0xd8000 vector zpintr
|
||||
|
||||
@ -626,10 +630,14 @@ device apm0 at isa?
|
||||
# The `de' device provides support for the Digital Equipment DC21040
|
||||
# self-contained Ethernet adapter.
|
||||
#
|
||||
# The `fpa' device provides support for the Digital DEFPA PCI FDDI
|
||||
# adapter. pseudo-device fddi is also needed.
|
||||
#
|
||||
# The PROBE_VERBOSE option enables a long listing of chip set registers
|
||||
# for supported PCI chip sets (currently only intel Saturn and Mercury).
|
||||
#
|
||||
controller pci0
|
||||
device ncr0
|
||||
device de0
|
||||
device fpa0
|
||||
options PROBE_VERBOSE
|
||||
|
@ -2,7 +2,7 @@
|
||||
# LINT -- config file for checking all the sources, tries to pull in
|
||||
# as much of the source tree as it can.
|
||||
#
|
||||
# $Id: LINT,v 1.154 1995/03/12 23:43:14 swallace Exp $
|
||||
# $Id: LINT,v 1.155 1995/03/13 18:49:24 swallace Exp $
|
||||
#
|
||||
# NB: You probably don't want to try running a kernel built from this
|
||||
# file. Instead, you should start from GENERIC, and add options from
|
||||
@ -144,6 +144,7 @@ options TPCONS #ISO TP class 0 over X.25
|
||||
# The `ether' pseudo-device provides generic code to handle
|
||||
# Ethernets; it is mandatory when a Ethernet device driver is
|
||||
# configured.
|
||||
# The 'fddi' pseudo-device provides generic code to support FDDI.
|
||||
# The `sppp' pseudo-device serves a similar role for certain types
|
||||
# of synchronous PPP links (like `cx').
|
||||
# The `sl' pseudo-device implements the Serial Line IP (SLIP) service.
|
||||
@ -158,6 +159,7 @@ options TPCONS #ISO TP class 0 over X.25
|
||||
# The `tun' pseudo-device implements the User Process PPP (iijppp)
|
||||
#
|
||||
pseudo-device ether #Generic Ethernet
|
||||
pseudo-device fddi #Generic FDDI
|
||||
pseudo-device sppp #Generic Synchronous PPP
|
||||
pseudo-device loop #Network loopback device
|
||||
pseudo-device sl 2 #Serial Line IP
|
||||
@ -492,6 +494,7 @@ options DSI_SOFT_MODEM #code for DSI Softmodems
|
||||
# ed: Western Digital and SMC 80xx; Novell NE1000 and NE2000; 3Com 3C503
|
||||
# el: 3Com 3C501 (slow!)
|
||||
# ep: 3Com 3C509 (buggy)
|
||||
# fea: DEC DEFEA EISA FDDI adapter
|
||||
# ie: AT&T StarLAN 10 and EN100; 3Com 3C507; unknown NI5210
|
||||
# le: Digital Equipment EtherWorks 2 and EtherWorks 3 (DEPCA, DE100,
|
||||
# DE101, DE200, DE201, DE202, DE203, DE204, DE205, DE422)
|
||||
@ -504,11 +507,12 @@ options DSI_SOFT_MODEM #code for DSI Softmodems
|
||||
|
||||
device cx0 at isa? port 0x240 net irq 15 drq 7 vector cxintr
|
||||
device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 vector edintr
|
||||
device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr
|
||||
device lnc0 at isa? port 0x280 net irq 10 drq 0 vector lncintr
|
||||
device ep0 at isa? port 0x300 net irq 10 vector epintr
|
||||
device el0 at isa? port 0x300 net irq 9 vector elintr
|
||||
device ep0 at isa? port 0x300 net irq 10 vector epintr
|
||||
device fea0 at isa? net irq ? vector feaintr
|
||||
device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr
|
||||
device le0 at isa? port 0x300 net irq 5 iomem 0xd0000 vector le_intr
|
||||
device lnc0 at isa? port 0x280 net irq 10 drq 0 vector lncintr
|
||||
device ze0 at isa? port 0x300 net irq 5 iomem 0xd8000 vector zeintr
|
||||
device zp0 at isa? port 0x300 net irq 10 iomem 0xd8000 vector zpintr
|
||||
|
||||
@ -626,10 +630,14 @@ device apm0 at isa?
|
||||
# The `de' device provides support for the Digital Equipment DC21040
|
||||
# self-contained Ethernet adapter.
|
||||
#
|
||||
# The `fpa' device provides support for the Digital DEFPA PCI FDDI
|
||||
# adapter. pseudo-device fddi is also needed.
|
||||
#
|
||||
# The PROBE_VERBOSE option enables a long listing of chip set registers
|
||||
# for supported PCI chip sets (currently only intel Saturn and Mercury).
|
||||
#
|
||||
controller pci0
|
||||
device ncr0
|
||||
device de0
|
||||
device fpa0
|
||||
options PROBE_VERBOSE
|
||||
|
@ -37,7 +37,7 @@
|
||||
*
|
||||
* @(#)bpf.c 8.2 (Berkeley) 3/28/94
|
||||
*
|
||||
* $Id: bpf.c,v 1.3 1994/08/20 03:48:55 davidg Exp $
|
||||
* $Id: bpf.c,v 1.4 1994/10/09 07:35:03 davidg Exp $
|
||||
*/
|
||||
|
||||
#include "bpfilter.h"
|
||||
@ -168,9 +168,14 @@ bpf_movein(uio, linktype, mp, sockp, datlen)
|
||||
break;
|
||||
|
||||
case DLT_FDDI:
|
||||
#if defined(__FreeBSD__) || defined(__bsdi__)
|
||||
sockp->sa_family = AF_IMPLINK;
|
||||
hlen = 0;
|
||||
#else
|
||||
sockp->sa_family = AF_UNSPEC;
|
||||
/* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */
|
||||
hlen = 24;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case DLT_NULL:
|
||||
|
84
sys/net/fddi.h
Normal file
84
sys/net/fddi.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* @(#)if_fddi.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: if_fddi.h,v 1.1 1995/03/10 17:43:45 thomas Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETINET_IF_FDDI_H_
|
||||
#define _NETINET_IF_FDDI_H_
|
||||
|
||||
/*
|
||||
* Structure of an 100Mb/s FDDI header.
|
||||
*/
|
||||
struct fddi_header {
|
||||
u_char fddi_fc;
|
||||
u_char fddi_dhost[6];
|
||||
u_char fddi_shost[6];
|
||||
};
|
||||
|
||||
#define FDDIMTU 4470
|
||||
#define FDDIMIN 3
|
||||
|
||||
#define FDDIFC_C 0x80 /* 0b10000000 */
|
||||
#define FDDIFC_L 0x40 /* 0b01000000 */
|
||||
#define FDDIFC_F 0x30 /* 0b00110000 */
|
||||
#define FDDIFC_Z 0x0F /* 0b00001111 */
|
||||
|
||||
#define FDDIFC_LLC_ASYNC 0x50
|
||||
#define FDDIFC_LLC_PRIO0 0
|
||||
#define FDDIFC_LLC_PRIO1 1
|
||||
#define FDDIFC_LLC_PRIO2 2
|
||||
#define FDDIFC_LLC_PRIO3 3
|
||||
#define FDDIFC_LLC_PRIO4 4
|
||||
#define FDDIFC_LLC_PRIO5 5
|
||||
#define FDDIFC_LLC_PRIO6 6
|
||||
#define FDDIFC_LLC_PRIO7 7
|
||||
#define FDDIFC_LLC_SYNC 0xd0
|
||||
#define FDDIFC_SMT 0x40
|
||||
|
||||
#ifdef 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 *));
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
567
sys/net/if_fddisubr.c
Normal file
567
sys/net/if_fddisubr.c
Normal file
@ -0,0 +1,567 @@
|
||||
/*
|
||||
* Copyright (c) 1982, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* @(#)if_fddisubr.c 8.1 (Berkeley) 6/10/93
|
||||
* if_fddisubr.c,v 1.5 1994/12/13 22:31:45 wollman Exp
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/netisr.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_llc.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#ifdef INET
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#endif
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/if_fddi.h>
|
||||
|
||||
#ifdef NS
|
||||
#include <netns/ns.h>
|
||||
#include <netns/ns_if.h>
|
||||
#endif
|
||||
|
||||
#ifdef DECNET
|
||||
#include <netdnet/dn.h>
|
||||
#endif
|
||||
|
||||
#ifdef ISO
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_var.h>
|
||||
#include <netiso/iso_snpac.h>
|
||||
#endif
|
||||
|
||||
#include "bpfilter.h"
|
||||
|
||||
#ifdef LLC
|
||||
#include <netccitt/dll.h>
|
||||
#include <netccitt/llc_var.h>
|
||||
#endif
|
||||
|
||||
#if defined(LLC) && defined(CCITT)
|
||||
extern struct ifqueue pkintrq;
|
||||
#endif
|
||||
|
||||
extern struct ifnet loif;
|
||||
#define senderr(e) { error = (e); goto bad;}
|
||||
|
||||
/*
|
||||
* This really should be defined in if_llc.h but in case it isn't.
|
||||
*/
|
||||
#ifndef llc_snap
|
||||
#define llc_snap llc_un.type_snap
|
||||
#endif
|
||||
|
||||
#ifdef __bsdi__
|
||||
#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)
|
||||
#define ARPRESOLVE(a, b, c, d, e, f) arpresolve(a, b, c, d, e, f)
|
||||
#endif
|
||||
/*
|
||||
* FDDI output routine.
|
||||
* Encapsulate a packet of type family for the local net.
|
||||
* Use trailer local net encapsulation if enough data in first
|
||||
* packet leaves a multiple of 512 bytes of data in remainder.
|
||||
* Assumes that ifp is actually pointer to arpcom structure.
|
||||
*/
|
||||
int
|
||||
fddi_output(ifp, m0, dst, rt0)
|
||||
register struct ifnet *ifp;
|
||||
struct mbuf *m0;
|
||||
struct sockaddr *dst;
|
||||
struct rtentry *rt0;
|
||||
{
|
||||
short 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 arpcom *ac = (struct arpcom *)ifp;
|
||||
|
||||
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
|
||||
senderr(ENETDOWN);
|
||||
ifp->if_lastchange = time;
|
||||
if (rt = rt0) {
|
||||
if ((rt->rt_flags & RTF_UP) == 0) {
|
||||
if (rt0 = rt = RTALLOC1(dst, 1))
|
||||
rt->rt_refcnt--;
|
||||
else
|
||||
senderr(EHOSTUNREACH);
|
||||
}
|
||||
if (rt->rt_flags & RTF_GATEWAY) {
|
||||
if (rt->rt_gwroute == 0)
|
||||
goto lookup;
|
||||
if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
|
||||
rtfree(rt); rt = rt0;
|
||||
lookup: rt->rt_gwroute = RTALLOC1(rt->rt_gateway, 1);
|
||||
if ((rt = rt->rt_gwroute) == 0)
|
||||
senderr(EHOSTUNREACH);
|
||||
}
|
||||
}
|
||||
if (rt->rt_flags & RTF_REJECT)
|
||||
if (rt->rt_rmx.rmx_expire == 0 ||
|
||||
time.tv_sec < rt->rt_rmx.rmx_expire)
|
||||
senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
|
||||
}
|
||||
switch (dst->sa_family) {
|
||||
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (!ARPRESOLVE(ac, rt, m, dst, edst, rt0))
|
||||
return (0); /* if not yet resolved */
|
||||
/* 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;
|
||||
break;
|
||||
#endif
|
||||
#ifdef NS
|
||||
case AF_NS:
|
||||
type = 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)))
|
||||
return (looutput(ifp, m, dst, rt));
|
||||
/* 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);
|
||||
break;
|
||||
#endif
|
||||
#ifdef ISO
|
||||
case AF_ISO: {
|
||||
int snpalen;
|
||||
struct llc *l;
|
||||
register struct sockaddr_dl *sdl;
|
||||
|
||||
if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) &&
|
||||
sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
|
||||
bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst));
|
||||
} else if (error =
|
||||
iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
|
||||
(char *)edst, &snpalen))
|
||||
goto bad; /* Not Resolved */
|
||||
/* If broadcasting on a simplex interface, loopback a copy */
|
||||
if (*edst & 1)
|
||||
m->m_flags |= (M_BCAST|M_MCAST);
|
||||
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
|
||||
(mcopy = m_copy(m, 0, (int)M_COPYALL))) {
|
||||
M_PREPEND(mcopy, sizeof (*fh), M_DONTWAIT);
|
||||
if (mcopy) {
|
||||
fh = mtod(mcopy, struct fddi_header *);
|
||||
bcopy((caddr_t)edst,
|
||||
(caddr_t)fh->fddi_dhost, sizeof (edst));
|
||||
bcopy((caddr_t)ac->ac_enaddr,
|
||||
(caddr_t)fh->fddi_shost, sizeof (edst));
|
||||
}
|
||||
}
|
||||
M_PREPEND(m, 3, M_DONTWAIT);
|
||||
if (m == NULL)
|
||||
return (0);
|
||||
type = 0;
|
||||
l = mtod(m, struct llc *);
|
||||
l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
|
||||
l->llc_control = LLC_UI;
|
||||
IFDEBUG(D_ETHER)
|
||||
int i;
|
||||
printf("unoutput: sending pkt to: ");
|
||||
for (i=0; i<6; i++)
|
||||
printf("%x ", edst[i] & 0xff);
|
||||
printf("\n");
|
||||
ENDDEBUG
|
||||
} break;
|
||||
#endif /* ISO */
|
||||
#ifdef LLC
|
||||
/* case AF_NSAP: */
|
||||
case AF_CCITT: {
|
||||
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 ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
|
||||
(mcopy = m_copy(m, 0, (int)M_COPYALL))) {
|
||||
M_PREPEND(mcopy, sizeof (*fh), M_DONTWAIT);
|
||||
if (mcopy) {
|
||||
fh = mtod(mcopy, struct fddi_header *);
|
||||
bcopy((caddr_t)edst,
|
||||
(caddr_t)fh->fddi_dhost, sizeof (edst));
|
||||
bcopy((caddr_t)ac->ac_enaddr,
|
||||
(caddr_t)fh->fddi_shost, sizeof (edst));
|
||||
fh->fddi_fc = FDDIFC_LLC_ASYNC|FDDIFC_LLC_PRIO4;
|
||||
}
|
||||
}
|
||||
type = 0;
|
||||
#ifdef LLC_DEBUG
|
||||
{
|
||||
int i;
|
||||
register struct llc *l = mtod(m, struct llc *);
|
||||
|
||||
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",
|
||||
type & 0xff, l->llc_dsap & 0xff, l->llc_ssap &0xff,
|
||||
l->llc_control & 0xff);
|
||||
|
||||
}
|
||||
#endif /* LLC_DEBUG */
|
||||
} break;
|
||||
#endif /* LLC */
|
||||
|
||||
case AF_UNSPEC:
|
||||
{
|
||||
struct ether_header *eh;
|
||||
eh = (struct ether_header *)dst->sa_data;
|
||||
bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
|
||||
if (*edst & 1)
|
||||
m->m_flags |= (M_BCAST|M_MCAST);
|
||||
type = eh->ether_type;
|
||||
break;
|
||||
}
|
||||
|
||||
#if NBPFILTER > 0
|
||||
case AF_IMPLINK:
|
||||
{
|
||||
fh = mtod(m, struct fddi_header *);
|
||||
error = EPROTONOSUPPORT;
|
||||
switch (fh->fddi_fc & (FDDIFC_C|FDDIFC_L|FDDIFC_F)) {
|
||||
case FDDIFC_LLC_ASYNC: {
|
||||
/* legal priorities are 0 through 7 */
|
||||
if ((fh->fddi_fc & FDDIFC_Z) > 7)
|
||||
goto bad;
|
||||
break;
|
||||
}
|
||||
case FDDIFC_LLC_SYNC: {
|
||||
/* FDDIFC_Z bits reserved, must be zero */
|
||||
if (fh->fddi_fc & FDDIFC_Z)
|
||||
goto bad;
|
||||
break;
|
||||
}
|
||||
case FDDIFC_SMT: {
|
||||
/* FDDIFC_Z bits must be non zero */
|
||||
if ((fh->fddi_fc & FDDIFC_Z) == 0)
|
||||
goto bad;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
/* anything else is too dangerous */
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
error = 0;
|
||||
if (fh->fddi_dhost[0] & 1)
|
||||
m->m_flags |= (M_BCAST|M_MCAST);
|
||||
goto queue_it;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
|
||||
dst->sa_family);
|
||||
senderr(EAFNOSUPPORT);
|
||||
}
|
||||
|
||||
|
||||
if (mcopy)
|
||||
(void) looutput(ifp, mcopy, dst, rt);
|
||||
if (type != 0) {
|
||||
register struct llc *l;
|
||||
M_PREPEND(m, sizeof (struct llc), M_DONTWAIT);
|
||||
if (m == 0)
|
||||
senderr(ENOBUFS);
|
||||
l = mtod(m, struct llc *);
|
||||
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);
|
||||
bcopy((caddr_t) &type, (caddr_t) &l->llc_snap.ether_type,
|
||||
sizeof(u_short));
|
||||
}
|
||||
/*
|
||||
* Add local net header. If no space in first mbuf,
|
||||
* allocate another.
|
||||
*/
|
||||
M_PREPEND(m, sizeof (struct fddi_header), M_DONTWAIT);
|
||||
if (m == 0)
|
||||
senderr(ENOBUFS);
|
||||
fh = mtod(m, struct fddi_header *);
|
||||
fh->fddi_fc = FDDIFC_LLC_ASYNC|FDDIFC_LLC_PRIO4;
|
||||
bcopy((caddr_t)edst, (caddr_t)fh->fddi_dhost, sizeof (edst));
|
||||
queue_it:
|
||||
bcopy((caddr_t)ac->ac_enaddr, (caddr_t)fh->fddi_shost,
|
||||
sizeof(fh->fddi_shost));
|
||||
s = splimp();
|
||||
/*
|
||||
* Queue message on interface, and start output if interface
|
||||
* not yet active.
|
||||
*/
|
||||
if (IF_QFULL(&ifp->if_snd)) {
|
||||
IF_DROP(&ifp->if_snd);
|
||||
splx(s);
|
||||
senderr(ENOBUFS);
|
||||
}
|
||||
ifp->if_obytes += m->m_pkthdr.len;
|
||||
IF_ENQUEUE(&ifp->if_snd, m);
|
||||
if ((ifp->if_flags & IFF_OACTIVE) == 0)
|
||||
(*ifp->if_start)(ifp);
|
||||
splx(s);
|
||||
if (m->m_flags & M_MCAST)
|
||||
ifp->if_omcasts++;
|
||||
return (error);
|
||||
|
||||
bad:
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a received FDDI packet;
|
||||
* the packet is in the mbuf chain m without
|
||||
* the fddi header, which is provided separately.
|
||||
*/
|
||||
void
|
||||
fddi_input(ifp, fh, m)
|
||||
struct ifnet *ifp;
|
||||
register struct fddi_header *fh;
|
||||
struct mbuf *m;
|
||||
{
|
||||
register struct ifqueue *inq;
|
||||
register struct llc *l;
|
||||
int s;
|
||||
|
||||
if ((ifp->if_flags & IFF_UP) == 0) {
|
||||
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))
|
||||
ifp->if_imcasts++;
|
||||
|
||||
l = mtod(m, struct llc *);
|
||||
switch (l->llc_dsap) {
|
||||
#if defined(INET) || defined(NS) || defined(DECNET)
|
||||
case LLC_SNAP_LSAP:
|
||||
{
|
||||
unsigned fddi_type;
|
||||
if (l->llc_control != LLC_UI || l->llc_ssap != LLC_SNAP_LSAP)
|
||||
goto dropanyway;
|
||||
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);
|
||||
m_adj(m, 8);
|
||||
switch (fddi_type) {
|
||||
#ifdef INET
|
||||
case ETHERTYPE_IP:
|
||||
schednetisr(NETISR_IP);
|
||||
inq = &ipintrq;
|
||||
break;
|
||||
|
||||
case ETHERTYPE_ARP:
|
||||
schednetisr(NETISR_ARP);
|
||||
inq = &arpintrq;
|
||||
break;
|
||||
#endif
|
||||
#ifdef NS
|
||||
case ETHERTYPE_NS:
|
||||
schednetisr(NETISR_NS);
|
||||
inq = &nsintrq;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DECNET
|
||||
case ETHERTYPE_DECENT:
|
||||
schednetisr(NETISR_DECNET);
|
||||
inq = &decnetintrq;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("fddi_input: unknown protocol 0x%x\n", fddi_type);
|
||||
ifp->if_noproto++;
|
||||
goto dropanyway;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* INET || NS */
|
||||
#ifdef ISO
|
||||
case LLC_ISO_LSAP:
|
||||
switch (l->llc_control) {
|
||||
case LLC_UI:
|
||||
/* LLC_UI_P forbidden in class 1 service */
|
||||
if ((l->llc_dsap == LLC_ISO_LSAP) &&
|
||||
(l->llc_ssap == LLC_ISO_LSAP)) {
|
||||
/* LSAP for ISO */
|
||||
m->m_data += 3; /* XXX */
|
||||
m->m_len -= 3; /* XXX */
|
||||
m->m_pkthdr.len -= 3; /* XXX */
|
||||
M_PREPEND(m, sizeof *fh, M_DONTWAIT);
|
||||
if (m == 0)
|
||||
return;
|
||||
*mtod(m, struct fddi_header *) = *fh;
|
||||
IFDEBUG(D_ETHER)
|
||||
printf("clnp packet");
|
||||
ENDDEBUG
|
||||
schednetisr(NETISR_ISO);
|
||||
inq = &clnlintrq;
|
||||
break;
|
||||
}
|
||||
goto dropanyway;
|
||||
|
||||
case LLC_XID:
|
||||
case LLC_XID_P:
|
||||
if(m->m_len < 6)
|
||||
goto dropanyway;
|
||||
l->llc_window = 0;
|
||||
l->llc_fid = 9;
|
||||
l->llc_class = 1;
|
||||
l->llc_dsap = l->llc_ssap = 0;
|
||||
/* Fall through to */
|
||||
case LLC_TEST:
|
||||
case LLC_TEST_P:
|
||||
{
|
||||
struct sockaddr sa;
|
||||
register struct ether_header *eh2;
|
||||
int i;
|
||||
u_char c = l->llc_dsap;
|
||||
|
||||
l->llc_dsap = l->llc_ssap;
|
||||
l->llc_ssap = c;
|
||||
if (m->m_flags & (M_BCAST | M_MCAST))
|
||||
bcopy((caddr_t)ac->ac_enaddr,
|
||||
(caddr_t)eh->ether_dhost, 6);
|
||||
sa.sa_family = AF_UNSPEC;
|
||||
sa.sa_len = sizeof(sa);
|
||||
eh2 = (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;
|
||||
}
|
||||
eh2->ether_type = 0;
|
||||
ifp->if_output(ifp, m, &sa, NULL);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
#endif /* ISO */
|
||||
#ifdef LLC
|
||||
case LLC_X25_LSAP:
|
||||
{
|
||||
M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);
|
||||
if (m == 0)
|
||||
return;
|
||||
if ( !sdl_sethdrif(ifp, fh->fddi_shost, LLC_X25_LSAP,
|
||||
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);
|
||||
#ifdef LLC_DEBUG
|
||||
printf("llc packet\n");
|
||||
#endif /* LLC_DEBUG */
|
||||
schednetisr(NETISR_CCITT);
|
||||
inq = &llcintrq;
|
||||
break;
|
||||
}
|
||||
#endif /* LLC */
|
||||
|
||||
default:
|
||||
printf("fddi_input: unknown dsap 0x%x\n", l->llc_dsap);
|
||||
ifp->if_noproto++;
|
||||
dropanyway:
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
s = splimp();
|
||||
if (IF_QFULL(inq)) {
|
||||
IF_DROP(inq);
|
||||
m_freem(m);
|
||||
} else
|
||||
IF_ENQUEUE(inq, m);
|
||||
splx(s);
|
||||
}
|
||||
/*
|
||||
* Perform common duties while attaching to interface list
|
||||
*/
|
||||
void
|
||||
fddi_ifattach(ifp)
|
||||
register struct ifnet *ifp;
|
||||
{
|
||||
register struct ifaddr *ifa;
|
||||
register struct sockaddr_dl *sdl;
|
||||
|
||||
ifp->if_type = IFT_FDDI;
|
||||
ifp->if_addrlen = 6;
|
||||
ifp->if_hdrlen = 21;
|
||||
ifp->if_mtu = FDDIMTU;
|
||||
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
|
||||
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;
|
||||
}
|
||||
}
|
84
sys/netinet/if_fddi.h
Normal file
84
sys/netinet/if_fddi.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* @(#)if_fddi.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id: if_fddi.h,v 1.1 1995/03/10 17:43:45 thomas Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETINET_IF_FDDI_H_
|
||||
#define _NETINET_IF_FDDI_H_
|
||||
|
||||
/*
|
||||
* Structure of an 100Mb/s FDDI header.
|
||||
*/
|
||||
struct fddi_header {
|
||||
u_char fddi_fc;
|
||||
u_char fddi_dhost[6];
|
||||
u_char fddi_shost[6];
|
||||
};
|
||||
|
||||
#define FDDIMTU 4470
|
||||
#define FDDIMIN 3
|
||||
|
||||
#define FDDIFC_C 0x80 /* 0b10000000 */
|
||||
#define FDDIFC_L 0x40 /* 0b01000000 */
|
||||
#define FDDIFC_F 0x30 /* 0b00110000 */
|
||||
#define FDDIFC_Z 0x0F /* 0b00001111 */
|
||||
|
||||
#define FDDIFC_LLC_ASYNC 0x50
|
||||
#define FDDIFC_LLC_PRIO0 0
|
||||
#define FDDIFC_LLC_PRIO1 1
|
||||
#define FDDIFC_LLC_PRIO2 2
|
||||
#define FDDIFC_LLC_PRIO3 3
|
||||
#define FDDIFC_LLC_PRIO4 4
|
||||
#define FDDIFC_LLC_PRIO5 5
|
||||
#define FDDIFC_LLC_PRIO6 6
|
||||
#define FDDIFC_LLC_PRIO7 7
|
||||
#define FDDIFC_LLC_SYNC 0xd0
|
||||
#define FDDIFC_SMT 0x40
|
||||
|
||||
#ifdef 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 *));
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
844
sys/pci/if_pdq.c
Normal file
844
sys/pci/if_pdq.c
Normal file
@ -0,0 +1,844 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $Id: if_pdq.c,v 1.7 1995/03/14 01:52:52 thomas Exp $
|
||||
*
|
||||
* $Log: if_pdq.c,v $
|
||||
* Revision 1.7 1995/03/14 01:52:52 thomas
|
||||
* Update for new FreeBSD PCI Interrupt interface
|
||||
*
|
||||
* Revision 1.6 1995/03/10 17:06:59 thomas
|
||||
* Update for latest version of FreeBSD.
|
||||
* Compensate for the fast that the ifp will not be first thing
|
||||
* in softc on BSDI.
|
||||
*
|
||||
* Revision 1.5 1995/03/07 19:59:42 thomas
|
||||
* First pass at BSDI EISA support
|
||||
*
|
||||
* Revision 1.4 1995/03/06 17:06:03 thomas
|
||||
* Add transmit timeout support.
|
||||
* Add support DEFEA (untested).
|
||||
*
|
||||
* Revision 1.3 1995/03/03 13:48:35 thomas
|
||||
* more fixes
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* DEC PDQ FDDI Controller; code for BSD derived operating systems
|
||||
*
|
||||
* Written by Matt Thomas
|
||||
*
|
||||
* This driver supports the following FDDI controllers:
|
||||
*
|
||||
* Device: Config file entry:
|
||||
* DEC DEFPA (PCI) device fpa0
|
||||
* DEC DEFEA (EISA) device fea0 at isa0 net irq ? vector feaintr
|
||||
*
|
||||
* Eventually, the following adapters will also be supported:
|
||||
*
|
||||
* DEC DEFTA (TC) device fta0 at tc? slot * vector ftaintr
|
||||
* DEC DEFQA (Q-Bus) device fta0 at uba? csr 0?? vector fqaintr
|
||||
* DEC DEFAA (FB+) device faa0 at fbus? slot * vector faaintr
|
||||
*/
|
||||
|
||||
|
||||
#include "fea.h" /* DEFPA EISA FDDI */
|
||||
#ifndef __bsdi__
|
||||
#include "fpa.h" /* DEFPA PCI FDDI */
|
||||
#endif
|
||||
#if NFPA > 0 || NFEA > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include "bpfilter.h"
|
||||
#if NBPFILTER > 0
|
||||
#include <net/bpf.h>
|
||||
#include <net/bpfdesc.h>
|
||||
#endif
|
||||
|
||||
#ifdef INET
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#endif
|
||||
#include <netinet/if_fddi.h>
|
||||
|
||||
#ifdef NS
|
||||
#include <netns/ns.h>
|
||||
#include <netns/ns_if.h>
|
||||
#endif
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_kern.h>
|
||||
#include <vm/vm_param.h>
|
||||
|
||||
#if NFPA > 0
|
||||
#include <pci/pcivar.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#endif
|
||||
|
||||
#if NFEA > 0
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/devconf.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#endif
|
||||
#ifdef __bsdi__
|
||||
#include <sys/device.h>
|
||||
#include <i386/isa/isavar.h>
|
||||
#include <i386/eisa/eisa.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "pdqreg.h"
|
||||
#include "pdq_os.h"
|
||||
|
||||
typedef struct {
|
||||
#ifdef __bsdi__
|
||||
struct device sc_dev; /* base device */
|
||||
struct isadev sc_id; /* ISA device */
|
||||
struct intrhand sc_ih; /* intrrupt vectoring */
|
||||
struct atshutdown sc_ats; /* shutdown routine */
|
||||
#endif
|
||||
struct arpcom sc_ac;
|
||||
pdq_t *sc_pdq;
|
||||
#if NBPFILTER > 0 && !defined(__FreeBSD__) && !defined(__bsdi__)
|
||||
caddr_t sc_bpf;
|
||||
#endif
|
||||
#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_bpf, 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_bpf, 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 ether_multistep step;
|
||||
struct ether_multi *enm;
|
||||
|
||||
ETHER_FIRST_MULTI(step, &sc->sc_ac, enm);
|
||||
while (enm != NULL && num_addrs > 0) {
|
||||
((u_short *) addr->lanaddr_bytes)[0] = ((u_short *) enm->enm_addrlo)[0];
|
||||
((u_short *) addr->lanaddr_bytes)[1] = ((u_short *) enm->enm_addrlo)[1];
|
||||
((u_short *) addr->lanaddr_bytes)[2] = ((u_short *) enm->enm_addrlo)[2];
|
||||
ETHER_NEXT_MULTI(step, enm);
|
||||
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: {
|
||||
((struct arpcom *)ifp)->ac_ipaddr = IA_SIN(ifa)->sin_addr;
|
||||
(*ifp->if_init)(ifp->if_unit);
|
||||
#ifdef __FreeBSD__
|
||||
arp_ifinit((struct arpcom *)ifp, ifa);
|
||||
#else
|
||||
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->pdq_ac.ac_enaddr);
|
||||
} else {
|
||||
ifp->if_flags &= ~IFF_RUNNING;
|
||||
bcopy((caddr_t)ina->x_host.c_host,
|
||||
(caddr_t)sc->pdq_ac.ac_enaddr,
|
||||
sizeof sc->pdq_ac.ac_enaddr);
|
||||
}
|
||||
|
||||
(*ifp->if_init)(ifp->if_unit);
|
||||
break;
|
||||
}
|
||||
#endif /* NS */
|
||||
|
||||
default: {
|
||||
(*ifp->if_init)(ifp->if_unit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SIOCSIFFLAGS: {
|
||||
(*ifp->if_init)(ifp->if_unit);
|
||||
break;
|
||||
}
|
||||
|
||||
case SIOCADDMULTI:
|
||||
case SIOCDELMULTI: {
|
||||
/*
|
||||
* Update multicast listeners
|
||||
*/
|
||||
if (cmd == SIOCADDMULTI)
|
||||
error = ether_addmulti((struct ifreq *)data, &sc->sc_ac);
|
||||
else
|
||||
error = ether_delmulti((struct ifreq *)data, &sc->sc_ac);
|
||||
|
||||
if (error == ENETRESET) {
|
||||
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)(int unit))
|
||||
{
|
||||
struct ifnet *ifp = &sc->sc_if;
|
||||
|
||||
ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;
|
||||
|
||||
ifp->if_init = ifinit;
|
||||
#ifndef __bsdi__
|
||||
ifp->if_reset = ifreset;
|
||||
#endif
|
||||
ifp->if_watchdog = ifwatchdog;
|
||||
|
||||
ifp->if_ioctl = pdq_ifioctl;
|
||||
ifp->if_output = fddi_output;
|
||||
ifp->if_start = pdq_ifstart;
|
||||
|
||||
if_attach(ifp);
|
||||
fddi_ifattach(ifp);
|
||||
#if NBPFILTER > 0
|
||||
bpfattach(&sc->sc_bpf, 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;
|
||||
|
||||
struct pci_device fpadevice = {
|
||||
"fpa",
|
||||
pdq_pci_probe,
|
||||
pdq_pci_attach,
|
||||
&pdq_pci_count,
|
||||
};
|
||||
|
||||
#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(
|
||||
int unit)
|
||||
{
|
||||
pdq_ifwatchdog(PDQ_PCI_UNIT_TO_SOFTC(unit));
|
||||
}
|
||||
|
||||
static int
|
||||
pdq_pci_ifintr(
|
||||
pdq_softc_t *sc)
|
||||
{
|
||||
return 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(
|
||||
int unit)
|
||||
{
|
||||
pdq_ifwatchdog(PDQ_EISA_UNIT_TO_SOFTC(unit));
|
||||
}
|
||||
|
||||
int
|
||||
feaintr(
|
||||
int unit)
|
||||
{
|
||||
pdq_interrupt(PDQ_EISA_UNIT_TO_SOFTC(unit)->sc_pdq);
|
||||
return unit;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 struct kern_devconf kdc_fea[NFEA] = { {
|
||||
0, 0, 0, /* filled in by dev_attach */
|
||||
"fea", 0, { MDDT_ISA, 0, "net" },
|
||||
isa_generic_externalize, 0, 0, ISA_EXTERNALLEN,
|
||||
&kdc_isa0, /* parent */
|
||||
0, /* parentdata */
|
||||
DC_BUSY, /* host adapters are always ``in use'' */
|
||||
"DEC DEFEA EISA FDDI Controller"
|
||||
} };
|
||||
|
||||
static inline void
|
||||
pdq_eisa_registerdev(
|
||||
struct isa_device *id)
|
||||
{
|
||||
if (id->id_unit)
|
||||
kdc_fea[id->id_unit] = kdc_fea[0];
|
||||
kdc_fea[id->id_unit].kdc_unit = id->id_unit;
|
||||
kdc_fea[id->id_unit].kdc_parentdata = id;
|
||||
dev_attach(&kdc_fea[id->id_unit]);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
#if 0
|
||||
id->id_maddr = (char *) NULL + atdevbase + maddr;
|
||||
id->id_msize = msize;
|
||||
#endif
|
||||
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);
|
||||
vm_offset_t va_csrs;
|
||||
pdq_uint32_t maddr, msize;
|
||||
|
||||
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);
|
||||
pdq_eisa_subprobe(sc->sc_iobase, &maddr, &msize, NULL);
|
||||
va_csrs = (vm_offset_t) pmap_mapdev(maddr, msize);
|
||||
if (va_csrs == (vm_offset_t) 0) {
|
||||
printf("fea%s: mapping of device memory failed\n", sc->sc_if.if_unit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sc->sc_pdq = pdq_initialize((void *) va_csrs, "fea", sc->sc_if.if_unit,
|
||||
(void *) sc, PDQ_DEFEA);
|
||||
if (sc->sc_pdq == NULL) {
|
||||
printf("fea%s: 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);
|
||||
pdq_eisa_registerdev(id);
|
||||
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%s: 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 */
|
1558
sys/pci/pdq.c
Normal file
1558
sys/pci/pdq.c
Normal file
File diff suppressed because it is too large
Load Diff
198
sys/pci/pdq_os.h
Normal file
198
sys/pci/pdq_os.h
Normal file
@ -0,0 +1,198 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $Id: pdq_os.h,v 1.6 1995/03/14 01:52:52 thomas Exp $
|
||||
*
|
||||
* $Log: pdq_os.h,v $
|
||||
* Revision 1.6 1995/03/14 01:52:52 thomas
|
||||
* Update for new FreeBSD PCI Interrupt interface
|
||||
* Use inl/inb/... inline macros provided by FreeBSD and BSDI
|
||||
*
|
||||
* Revision 1.5 1995/03/10 17:42:24 thomas
|
||||
* More changes for BSDI
|
||||
*
|
||||
* Revision 1.4 1995/03/06 17:08:56 thomas
|
||||
* Add copyright/disclaimer
|
||||
* Add inx/outx macros
|
||||
*
|
||||
* Revision 1.3 1995/03/03 13:48:35 thomas
|
||||
* more fixes
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* DEC PDQ FDDI Controller; PDQ O/S dependent definitions
|
||||
*
|
||||
* Written by Matt Thomas
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PDQ_OS_H
|
||||
#define _PDQ_OS_H
|
||||
|
||||
#define PDQ_OS_TX_TIMEOUT 5 /* seconds */
|
||||
|
||||
#ifdef PDQTEST
|
||||
#include <pdq_os_test.h>
|
||||
#elif defined(__FreeBSD__) || defined(__bsdi__)
|
||||
|
||||
#include <sys/param.h>
|
||||
#ifndef M_MCAST
|
||||
#include <sys/mbuf.h>
|
||||
#endif
|
||||
#include <sys/malloc.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_kern.h>
|
||||
|
||||
#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 NBPG
|
||||
#define PDQ_OS_USEC_DELAY(n) DELAY(n)
|
||||
#define PDQ_OS_MEMZERO(p, n) bzero((caddr_t)(p), (n))
|
||||
#define PDQ_OS_VA_TO_PA(p) vtophys(p)
|
||||
#define PDQ_OS_MEMALLOC(n) malloc(n, M_DEVBUF, M_NOWAIT)
|
||||
#define PDQ_OS_MEMFREE(p, n) free((void *) p, M_DEVBUF)
|
||||
#ifdef __FreeBSD__
|
||||
#define PDQ_OS_MEMALLOC_CONTIG(n) vm_page_alloc_contig(n, 0, 0xffffffff, PAGE_SIZE)
|
||||
#define PDQ_OS_MEMFREE_CONTIG(p, n) kmem_free(kernel_map, (vm_offset_t) p, n)
|
||||
#else
|
||||
#define PDQ_OS_MEMALLOC_CONTIG PDQ_OS_MEMALLOC
|
||||
#define PDQ_OS_MEMFREE_CONTIG PDQ_OS_MEMFREE
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <machine/cpufunc.h>
|
||||
#elif defined(__bsdi__)
|
||||
#include <machine/inline.h>
|
||||
#endif
|
||||
#define PDQ_OS_IORD_32(port) inl(port)
|
||||
#define PDQ_OS_IOWR_32(port, data) outl(port, data)
|
||||
#define PDQ_OS_IORD_8(port) inb(port)
|
||||
#define PDQ_OS_IOWR_8(port, data) outb(port, data)
|
||||
#endif
|
||||
|
||||
#ifdef PDQ_USE_MBUFS
|
||||
#define PDQ_OS_DATABUF_SIZE (MCLBYTES)
|
||||
#define PDQ_OS_DATABUF_FREE(b) (m_freem(b))
|
||||
#define PDQ_OS_DATABUF_NEXT(b) ((b)->m_next)
|
||||
#define PDQ_OS_DATABUF_NEXT_SET(b, b1) ((b)->m_next = (b1))
|
||||
#define PDQ_OS_DATABUF_NEXTPKT(b) ((b)->m_nextpkt)
|
||||
#define PDQ_OS_DATABUF_NEXTPKT_SET(b, b1) ((b)->m_nextpkt = (b1))
|
||||
#define PDQ_OS_DATABUF_LEN(b) ((b)->m_len)
|
||||
#define PDQ_OS_DATABUF_LEN_SET(b, n) ((b)->m_len = (n))
|
||||
#define PDQ_OS_DATABUF_LEN_ADJ(b, n) ((b)->m_len += (n))
|
||||
#define PDQ_OS_DATABUF_PTR(b) (mtod((b), pdq_uint8_t *))
|
||||
#define PDQ_OS_DATABUF_PTR_ADJ(b, n) ((b)->m_data += (n))
|
||||
typedef struct mbuf PDQ_OS_DATABUF_T;
|
||||
|
||||
#define PDQ_OS_DATABUF_ALLOC(b) do { \
|
||||
PDQ_OS_DATABUF_T *x_m0; \
|
||||
MGETHDR(x_m0, M_DONTWAIT, MT_DATA); \
|
||||
if (x_m0 != NULL) { \
|
||||
MCLGET(x_m0, M_DONTWAIT); \
|
||||
if ((x_m0->m_flags & M_EXT) == 0) { \
|
||||
m_free(x_m0); \
|
||||
(b) = NULL; \
|
||||
} else { \
|
||||
(b) = x_m0; \
|
||||
x_m0->m_len = PDQ_OS_DATABUF_SIZE; \
|
||||
} \
|
||||
} else { \
|
||||
(b) = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
#define PDQ_OS_DATABUF_RESET(b) ((b)->m_data = (b)->m_ext.ext_buf, (b)->m_len = MCLBYTES)
|
||||
#endif /* PDQ_USE_MBUFS */
|
||||
|
||||
#ifdef PDQ_USE_STREAMS
|
||||
#define PDQ_OS_DATABUF_FREE(b) (freemsg(b))
|
||||
#define PDQ_OS_DATABUF_NEXT(b) ((b)->b_cont)
|
||||
#define PDQ_OS_DATABUF_NEXTPKT(b) ((b)->b_next)
|
||||
#define PDQ_OS_DATABUF_NEXTPKT_SET(b, b1) ((b)->b_next = (b1))
|
||||
#define PDQ_OS_DATABUF_LEN(b) ((b)->b_wptr - (b)->b_rptr)
|
||||
#define PDQ_OS_DATABUF_PTR(b) ((pdq_uint8_t *) (b)->b_rptr)
|
||||
typedef mblk_t PDQ_OS_DATABUF_T;
|
||||
#endif /* PDQ_USE_STREAMS */
|
||||
|
||||
#define PDQ_OS_TX_TRANSMIT 5
|
||||
|
||||
#define PDQ_OS_DATABUF_ENQUEUE(q, b) do { \
|
||||
PDQ_OS_DATABUF_NEXTPKT_SET(b, NULL); \
|
||||
if ((q)->q_tail == NULL) \
|
||||
(q)->q_head = (b); \
|
||||
else \
|
||||
PDQ_OS_DATABUF_NEXTPKT_SET(((PDQ_OS_DATABUF_T *)(q)->q_tail), b); \
|
||||
(q)->q_tail = (b); \
|
||||
} while (0)
|
||||
|
||||
#define PDQ_OS_DATABUF_DEQUEUE(q, b) do { \
|
||||
if (((b) = (PDQ_OS_DATABUF_T *) (q)->q_head) != NULL) { \
|
||||
if (((q)->q_head = PDQ_OS_DATABUF_NEXTPKT(b)) == NULL) \
|
||||
(q)->q_tail = NULL; \
|
||||
PDQ_OS_DATABUF_NEXTPKT_SET(b, NULL); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
extern void pdq_os_addr_fill(pdq_t *pdq, pdq_lanaddr_t *addrs, size_t numaddrs);
|
||||
extern void pdq_os_receive_pdu(pdq_t *, PDQ_OS_DATABUF_T *pdu, size_t pdulen);
|
||||
extern void pdq_os_restart_transmitter(pdq_t *pdq);
|
||||
extern void pdq_os_transmit_done(pdq_t *pdq, PDQ_OS_DATABUF_T *pdu);
|
||||
|
||||
extern void pdq_print_fddi_chars(pdq_t *pdq, const pdq_response_status_chars_get_t *rsp);
|
||||
|
||||
extern void pdq_init_csrs(pdq_csrs_t *csrs, void *csrs_va, size_t csr_size);
|
||||
extern void pdq_init_pci_csrs(pdq_pci_csrs_t *csrs, void *csrs_va, size_t csr_size);
|
||||
|
||||
extern void pdq_flush_databuf_queue(pdq_databuf_queue_t *q);
|
||||
|
||||
extern pdq_boolean_t pdq_do_port_control(const pdq_csrs_t * const csrs, pdq_uint32_t cmd);
|
||||
extern void pdq_read_mla(const pdq_csrs_t * const csrs, pdq_lanaddr_t *hwaddr);
|
||||
extern void pdq_read_fwrev(const pdq_csrs_t * const csrs, pdq_fwrev_t *fwrev);
|
||||
extern pdq_boolean_t pdq_read_error_log(pdq_t *pdq, pdq_response_error_log_get_t *log_entry);
|
||||
extern pdq_chip_rev_t pdq_read_chiprev(const pdq_csrs_t * const csrs);
|
||||
|
||||
extern void pdq_queue_commands(pdq_t *pdq);
|
||||
extern void pdq_process_command_responses(pdq_t *pdq);
|
||||
extern void pdq_process_unsolicited_events(pdq_t *pdq);
|
||||
|
||||
extern 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);
|
||||
|
||||
extern pdq_boolean_t pdq_queue_transmit_data(pdq_t *pdq, PDQ_OS_DATABUF_T *pdu);
|
||||
extern void pdq_process_transmitted_data(pdq_t *pdq);
|
||||
extern void pdq_flush_transmitter(pdq_t *pdq);
|
||||
|
||||
|
||||
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 */
|
1081
sys/pci/pdqreg.h
Normal file
1081
sys/pci/pdqreg.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user