Remove support for FDDI networks.
Defines in net/if_media.h remain in case code copied from ifconfig is in use elsewere (supporting non-existant media type is harmless). Reviewed by: kib, jhb Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D15017
This commit is contained in:
parent
7feb881918
commit
0437c8e3b1
@ -38,6 +38,8 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20180409: remove FDDI support
|
||||
OLD_FILES+=usr/include/net/fddi.h
|
||||
# 20180319: remove /boot/overlays, replaced by /boot/dtb/overlays
|
||||
OLD_DIRS+=boot/overlays
|
||||
# 20180311: remove sys/sys/i386/include/pcaudioio.h
|
||||
|
5
UPDATING
5
UPDATING
@ -51,6 +51,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
|
||||
|
||||
****************************** SPECIAL WARNING: ******************************
|
||||
|
||||
20180411:
|
||||
Support for FDDI networks has been removed. If you have device
|
||||
fddi or device fpa in your kernel config file they must be
|
||||
removed.
|
||||
|
||||
20180406:
|
||||
In addition to supporting RFC 3164 formatted messages, the
|
||||
syslogd(8) service is now capable of parsing RFC 5424 formatted
|
||||
|
@ -86,15 +86,6 @@ static struct ifmedia_description ifm_subtype_tokenring_aliases[] =
|
||||
static struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] =
|
||||
IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS;
|
||||
|
||||
static struct ifmedia_description ifm_subtype_fddi_descriptions[] =
|
||||
IFM_SUBTYPE_FDDI_DESCRIPTIONS;
|
||||
|
||||
static struct ifmedia_description ifm_subtype_fddi_aliases[] =
|
||||
IFM_SUBTYPE_FDDI_ALIASES;
|
||||
|
||||
static struct ifmedia_description ifm_subtype_fddi_option_descriptions[] =
|
||||
IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS;
|
||||
|
||||
static struct ifmedia_description ifm_subtype_ieee80211_descriptions[] =
|
||||
IFM_SUBTYPE_IEEE80211_DESCRIPTIONS;
|
||||
|
||||
@ -188,24 +179,6 @@ static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] =
|
||||
{ NULL, 0 },
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
{ &ifm_subtype_shared_descriptions[0], 0 },
|
||||
{ &ifm_subtype_shared_aliases[0], 1 },
|
||||
{ &ifm_subtype_fddi_descriptions[0], 0 },
|
||||
{ &ifm_subtype_fddi_aliases[0], 1 },
|
||||
{ NULL, 0 },
|
||||
},
|
||||
{
|
||||
{ &ifm_shared_option_descriptions[0], 0 },
|
||||
{ &ifm_shared_option_aliases[0], 1 },
|
||||
{ &ifm_subtype_fddi_option_descriptions[0], 0 },
|
||||
{ NULL, 0 },
|
||||
},
|
||||
{
|
||||
{ NULL, 0 },
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
{ &ifm_subtype_shared_descriptions[0], 0 },
|
||||
|
@ -380,15 +380,6 @@ static struct ifmedia_description ifm_subtype_tokenring_aliases[] =
|
||||
static struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] =
|
||||
IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS;
|
||||
|
||||
static struct ifmedia_description ifm_subtype_fddi_descriptions[] =
|
||||
IFM_SUBTYPE_FDDI_DESCRIPTIONS;
|
||||
|
||||
static struct ifmedia_description ifm_subtype_fddi_aliases[] =
|
||||
IFM_SUBTYPE_FDDI_ALIASES;
|
||||
|
||||
static struct ifmedia_description ifm_subtype_fddi_option_descriptions[] =
|
||||
IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS;
|
||||
|
||||
static struct ifmedia_description ifm_subtype_ieee80211_descriptions[] =
|
||||
IFM_SUBTYPE_IEEE80211_DESCRIPTIONS;
|
||||
|
||||
@ -478,24 +469,6 @@ static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = {
|
||||
{ NULL, 0 },
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
{ &ifm_subtype_shared_descriptions[0], 0 },
|
||||
{ &ifm_subtype_shared_aliases[0], 1 },
|
||||
{ &ifm_subtype_fddi_descriptions[0], 0 },
|
||||
{ &ifm_subtype_fddi_aliases[0], 1 },
|
||||
{ NULL, 0 },
|
||||
},
|
||||
{
|
||||
{ &ifm_shared_option_descriptions[0], 0 },
|
||||
{ &ifm_shared_option_aliases[0], 1 },
|
||||
{ &ifm_subtype_fddi_option_descriptions[0], 0 },
|
||||
{ NULL, 0 },
|
||||
},
|
||||
{
|
||||
{ NULL, 0 },
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
{ &ifm_subtype_shared_descriptions[0], 0 },
|
||||
|
@ -397,15 +397,6 @@ static struct ifmedia_description ifm_subtype_tokenring_aliases[] =
|
||||
static struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] =
|
||||
IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS;
|
||||
|
||||
static struct ifmedia_description ifm_subtype_fddi_descriptions[] =
|
||||
IFM_SUBTYPE_FDDI_DESCRIPTIONS;
|
||||
|
||||
static struct ifmedia_description ifm_subtype_fddi_aliases[] =
|
||||
IFM_SUBTYPE_FDDI_ALIASES;
|
||||
|
||||
static struct ifmedia_description ifm_subtype_fddi_option_descriptions[] =
|
||||
IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS;
|
||||
|
||||
static struct ifmedia_description ifm_subtype_ieee80211_descriptions[] =
|
||||
IFM_SUBTYPE_IEEE80211_DESCRIPTIONS;
|
||||
|
||||
@ -495,24 +486,6 @@ static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = {
|
||||
{ NULL, 0 },
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
{ &ifm_subtype_shared_descriptions[0], 0 },
|
||||
{ &ifm_subtype_shared_aliases[0], 1 },
|
||||
{ &ifm_subtype_fddi_descriptions[0], 0 },
|
||||
{ &ifm_subtype_fddi_aliases[0], 1 },
|
||||
{ NULL, 0 },
|
||||
},
|
||||
{
|
||||
{ &ifm_shared_option_descriptions[0], 0 },
|
||||
{ &ifm_shared_option_aliases[0], 1 },
|
||||
{ &ifm_subtype_fddi_option_descriptions[0], 0 },
|
||||
{ NULL, 0 },
|
||||
},
|
||||
{
|
||||
{ NULL, 0 },
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
{ &ifm_subtype_shared_descriptions[0], 0 },
|
||||
|
@ -170,7 +170,6 @@ MAN= aac.4 \
|
||||
ffclock.4 \
|
||||
filemon.4 \
|
||||
firewire.4 \
|
||||
fpa.4 \
|
||||
full.4 \
|
||||
fwe.4 \
|
||||
fwip.4 \
|
||||
|
@ -1,44 +0,0 @@
|
||||
.\"
|
||||
.\" Copyright (c) 1995, Matt Thomas
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd March 29, 2018
|
||||
.Dt FPA 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm fpa
|
||||
.Nd device drivers for DEC FDDI controllers
|
||||
.Sh SYNOPSIS
|
||||
.Cd "device fpa"
|
||||
.Pp
|
||||
.Fx
|
||||
only:
|
||||
.Cd "device fddi"
|
||||
.Sh DEPRECATION NOTICE
|
||||
The
|
||||
.Nm
|
||||
driver is not present in
|
||||
.Fx 12.0
|
||||
and later.
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
device driver provide support for the DEC DEFPA PCI FDDI Controller.
|
||||
All variants of the
|
||||
controller are supported including the DAS and SAS configurations.
|
||||
.Sh SEE ALSO
|
||||
.Xr arp 4 ,
|
||||
.Xr netintro 4 ,
|
||||
.Xr ifconfig 8
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
device driver and this manual page were written by
|
||||
.An Matt Thomas .
|
||||
.Sh CAVEATS
|
||||
Normally, the device driver will not enable the reception of SMT frames.
|
||||
However if the IFF_LINK1 flag is set, the device driver will enable the
|
||||
reception of SMT frames and pass them up to the Berkeley Packet Filter for
|
||||
processing.
|
@ -845,9 +845,6 @@ device wlan_xauth
|
||||
device wlan_acl
|
||||
device wlan_amrr
|
||||
|
||||
# The `fddi' device provides generic code to support FDDI.
|
||||
device fddi
|
||||
|
||||
# The `arcnet' device provides generic code to support Arcnet.
|
||||
device arcnet
|
||||
|
||||
@ -1972,7 +1969,6 @@ device xmphy # XaQti XMAC II
|
||||
# ex: Intel EtherExpress Pro/10 and other i82595-based adapters,
|
||||
# Olicom Ethernet PC Card devices.
|
||||
# fe: Fujitsu MB86960A/MB86965A Ethernet
|
||||
# fpa: Support for the Digital DEFPA PCI FDDI. `device fddi' is also needed.
|
||||
# fxp: Intel EtherExpress Pro/100B
|
||||
# (hint of prefer_iomap can be done to prefer I/O instead of Mem mapping)
|
||||
# gem: Apple GMAC/Sun ERI/Sun GEM
|
||||
@ -2150,9 +2146,6 @@ device txp # 3Com 3cR990 (``Typhoon'')
|
||||
device vx # 3Com 3c590, 3c595 (``Vortex'')
|
||||
device vxge # Exar/Neterion XFrame 3100 10GbE
|
||||
|
||||
# PCI FDDI NICs.
|
||||
device fpa
|
||||
|
||||
# PCI WAN adapters.
|
||||
device lmc
|
||||
|
||||
|
@ -2642,9 +2642,6 @@ dev/pci/pcib_if.m standard
|
||||
dev/pci/pcib_support.c standard
|
||||
dev/pci/vga_pci.c optional pci
|
||||
dev/pcn/if_pcn.c optional pcn pci
|
||||
dev/pdq/if_fpa.c optional fpa pci
|
||||
dev/pdq/pdq.c optional nowerror fpa pci
|
||||
dev/pdq/pdq_ifsubr.c optional nowerror fpa pci
|
||||
dev/pms/freebsd/driver/ini/src/agtiapi.c optional pmspcv \
|
||||
compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w"
|
||||
dev/pms/RefTisa/sallsdk/spc/sadisc.c optional pmspcv \
|
||||
@ -4130,7 +4127,6 @@ net/if_edsc.c optional edsc
|
||||
net/if_enc.c optional enc inet | enc inet6
|
||||
net/if_epair.c optional epair
|
||||
net/if_ethersubr.c optional ether
|
||||
net/if_fddisubr.c optional fddi
|
||||
net/if_fwsubr.c optional fwip
|
||||
net/if_gif.c optional gif inet | gif inet6 | \
|
||||
netgraph_gif inet | netgraph_gif inet6
|
||||
|
@ -1,211 +0,0 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-NetBSD
|
||||
*
|
||||
* Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* DEC PDQ FDDI Controller; code for BSD derived operating systems
|
||||
*
|
||||
* This module supports the DEC DEFPA PCI FDDI Controller
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/fddi.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#include <dev/pdq/pdq_freebsd.h>
|
||||
#include <dev/pdq/pdqreg.h>
|
||||
|
||||
#define DEC_VENDORID 0x1011
|
||||
#define DEFPA_CHIPID 0x000F
|
||||
|
||||
#define DEFPA_LATENCY 0x88
|
||||
|
||||
#define PCI_CFLT 0x0C /* Configuration Latency */
|
||||
#define PCI_CBMA 0x10 /* Configuration Base Memory Address */
|
||||
#define PCI_CBIO 0x14 /* Configuration Base I/O Address */
|
||||
|
||||
static int pdq_pci_probe (device_t);
|
||||
static int pdq_pci_attach (device_t);
|
||||
static int pdq_pci_detach (device_t);
|
||||
static int pdq_pci_shutdown (device_t);
|
||||
static void pdq_pci_ifintr (void *);
|
||||
|
||||
static void
|
||||
pdq_pci_ifintr(void *arg)
|
||||
{
|
||||
pdq_softc_t *sc;
|
||||
|
||||
sc = arg;
|
||||
|
||||
PDQ_LOCK(sc);
|
||||
(void) pdq_interrupt(sc->sc_pdq);
|
||||
PDQ_UNLOCK(sc);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the PCI configuration support.
|
||||
*/
|
||||
static int
|
||||
pdq_pci_probe(device_t dev)
|
||||
{
|
||||
if (pci_get_vendor(dev) == DEC_VENDORID &&
|
||||
pci_get_device(dev) == DEFPA_CHIPID) {
|
||||
device_set_desc(dev, "Digital DEFPA PCI FDDI Controller");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
pdq_pci_attach(device_t dev)
|
||||
{
|
||||
pdq_softc_t *sc;
|
||||
u_int32_t command;
|
||||
int error;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
sc->dev = dev;
|
||||
|
||||
/*
|
||||
* Map control/status registers.
|
||||
*/
|
||||
pci_enable_busmaster(dev);
|
||||
|
||||
command = pci_read_config(dev, PCIR_LATTIMER, 1);
|
||||
if (command < DEFPA_LATENCY) {
|
||||
command = DEFPA_LATENCY;
|
||||
pci_write_config(dev, PCIR_LATTIMER, command, 1);
|
||||
}
|
||||
|
||||
sc->mem_rid = PCI_CBMA;
|
||||
sc->mem_type = SYS_RES_MEMORY;
|
||||
sc->mem = bus_alloc_resource_any(dev, sc->mem_type, &sc->mem_rid,
|
||||
RF_ACTIVE);
|
||||
if (!sc->mem) {
|
||||
device_printf(dev, "Unable to allocate I/O space resource.\n");
|
||||
error = ENXIO;
|
||||
goto bad;
|
||||
}
|
||||
sc->mem_bsh = rman_get_bushandle(sc->mem);
|
||||
sc->mem_bst = rman_get_bustag(sc->mem);
|
||||
|
||||
sc->irq_rid = 0;
|
||||
sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
if (!sc->irq) {
|
||||
device_printf(dev, "Unable to allocate interrupt resource.\n");
|
||||
error = ENXIO;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
error = pdq_ifattach(sc, sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, PDQ_DEFPA);
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, NULL,
|
||||
pdq_pci_ifintr, sc, &sc->irq_ih);
|
||||
if (error) {
|
||||
device_printf(dev, "Failed to setup interrupt handler.\n");
|
||||
pdq_ifdetach(sc);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
gone_in_dev(dev, 12, "fpa(4) driver");
|
||||
return (0);
|
||||
bad:
|
||||
pdq_free(dev);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
pdq_pci_detach (dev)
|
||||
device_t dev;
|
||||
{
|
||||
pdq_softc_t *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
pdq_ifdetach(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pdq_pci_shutdown(device_t dev)
|
||||
{
|
||||
pdq_softc_t *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
PDQ_LOCK(sc);
|
||||
pdq_hwreset(sc->sc_pdq);
|
||||
PDQ_UNLOCK(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t pdq_pci_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, pdq_pci_probe),
|
||||
DEVMETHOD(device_attach, pdq_pci_attach),
|
||||
DEVMETHOD(device_detach, pdq_pci_detach),
|
||||
DEVMETHOD(device_shutdown, pdq_pci_shutdown),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t pdq_pci_driver = {
|
||||
"fpa",
|
||||
pdq_pci_methods,
|
||||
sizeof(pdq_softc_t),
|
||||
};
|
||||
|
||||
DRIVER_MODULE(fpa, pci, pdq_pci_driver, pdq_devclass, 0, 0);
|
||||
MODULE_DEPEND(fpa, pci, 1, 1, 1);
|
||||
MODULE_DEPEND(fpa, fddi, 1, 1, 1);
|
1789
sys/dev/pdq/pdq.c
1789
sys/dev/pdq/pdq.c
File diff suppressed because it is too large
Load Diff
@ -1,271 +0,0 @@
|
||||
/* $NetBSD: pdqvar.h,v 1.27 2000/05/03 19:17:54 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-NetBSD
|
||||
*
|
||||
* Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.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.
|
||||
*
|
||||
* Id: pdqvar.h,v 1.21 1997/03/21 21:16:04 thomas Exp
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* DEC PDQ FDDI Controller; PDQ O/S dependent definitions
|
||||
*
|
||||
* Written by Matt Thomas
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(PDQ_HWSUPPORT)
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/fddi.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <vm/vm.h> /* for vtophys */
|
||||
#include <vm/pmap.h> /* for vtophys */
|
||||
|
||||
#endif /* PDQ_HWSUPPORT */
|
||||
|
||||
typedef struct _pdq_t pdq_t;
|
||||
typedef struct _pdq_csrs_t pdq_csrs_t;
|
||||
typedef struct _pdq_pci_csrs_t pdq_pci_csrs_t;
|
||||
typedef struct _pdq_lanaddr_t pdq_lanaddr_t;
|
||||
typedef unsigned int pdq_uint32_t;
|
||||
typedef unsigned short pdq_uint16_t;
|
||||
typedef unsigned char pdq_uint8_t;
|
||||
typedef enum _pdq_boolean_t pdq_boolean_t;
|
||||
typedef enum _pdq_type_t pdq_type_t;
|
||||
typedef enum _pdq_state_t pdq_state_t;
|
||||
typedef struct mbuf PDQ_OS_DATABUF_T;
|
||||
|
||||
typedef bus_space_tag_t pdq_bus_t;
|
||||
typedef bus_space_handle_t pdq_bus_memaddr_t;
|
||||
typedef pdq_bus_memaddr_t pdq_bus_memoffset_t;
|
||||
|
||||
extern devclass_t pdq_devclass;
|
||||
|
||||
enum _pdq_type_t {
|
||||
PDQ_DEFPA, /* PCI-bus */
|
||||
};
|
||||
|
||||
#define sc_ifmedia ifmedia
|
||||
#if 0 /* ALTQ */
|
||||
#define IFQ_DEQUEUE IF_DEQUEUE
|
||||
#define IFQ_IS_EMPTY(q) ((q)->ifq_len == 0)
|
||||
#endif
|
||||
|
||||
typedef struct _pdq_os_ctx_t {
|
||||
struct ifnet *ifp;
|
||||
struct ifmedia ifmedia;
|
||||
device_t dev;
|
||||
int debug;
|
||||
|
||||
pdq_t * sc_pdq;
|
||||
int sc_flags;
|
||||
#define PDQIF_DOWNCALL 0x0001 /* active calling from if to pdq */
|
||||
|
||||
struct resource * io;
|
||||
int io_rid;
|
||||
int io_type;
|
||||
bus_space_handle_t io_bsh;
|
||||
bus_space_tag_t io_bst;
|
||||
|
||||
struct resource * mem;
|
||||
int mem_rid;
|
||||
int mem_type;
|
||||
bus_space_handle_t mem_bsh;
|
||||
bus_space_tag_t mem_bst;
|
||||
|
||||
struct resource * irq;
|
||||
int irq_rid;
|
||||
void * irq_ih;
|
||||
|
||||
struct mtx mtx;
|
||||
struct callout watchdog;
|
||||
int timer;
|
||||
} pdq_softc_t;
|
||||
|
||||
#define PDQ_LOCK(_sc) mtx_lock(&(_sc)->mtx)
|
||||
#define PDQ_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx)
|
||||
#define PDQ_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED)
|
||||
|
||||
#define PDQ_OS_HDR_OFFSET PDQ_RX_FC_OFFSET
|
||||
|
||||
#define PDQ_OS_PAGESIZE PAGE_SIZE
|
||||
#define PDQ_OS_TX_TRANSMIT 5
|
||||
|
||||
#define PDQ_OS_IORD_32(bt, bh, off) bus_space_read_4(bt, bh, off)
|
||||
#define PDQ_OS_IOWR_32(bt, bh, off, data) bus_space_write_4(bt, bh, off, data)
|
||||
#define PDQ_OS_IORD_8(bt, bh, off) bus_space_read_1(bt, bh, off)
|
||||
#define PDQ_OS_IOWR_8(bt, bh, off, data) bus_space_write_1(bt, bh, off, data)
|
||||
|
||||
#define PDQ_CSR_OFFSET(base, offset) (0 + (offset)*sizeof(pdq_uint32_t))
|
||||
#define PDQ_CSR_WRITE(csr, name, data) PDQ_OS_IOWR_32((csr)->csr_bus, (csr)->csr_base, (csr)->name, data)
|
||||
#define PDQ_CSR_READ(csr, name) PDQ_OS_IORD_32((csr)->csr_bus, (csr)->csr_base, (csr)->name)
|
||||
|
||||
#define PDQ_OS_DATABUF_FREE(pdq, b) (m_freem(b))
|
||||
|
||||
#if defined(PDQ_OSSUPPORT)
|
||||
#define PDQ_OS_TX_TIMEOUT 5 /* seconds */
|
||||
|
||||
#define PDQ_OS_IFP_TO_SOFTC(ifp) ((pdq_softc_t *) (ifp)->if_softc)
|
||||
#define PDQ_BPF_MTAP(sc, m) BPF_MTAP((sc)->ifp, m)
|
||||
#define PDQ_IFNET(sc) ((sc)->ifp)
|
||||
|
||||
#endif /* PDQ_OSSUPPORT */
|
||||
|
||||
#if defined(PDQ_HWSUPPORT)
|
||||
|
||||
#define PDQ_OS_PREFIX "%s: "
|
||||
#define PDQ_OS_PREFIX_ARGS pdq->pdq_os_name
|
||||
|
||||
#define PDQ_OS_PTR_FMT "%p"
|
||||
#define PDQ_OS_CSR_FMT "0x%x"
|
||||
|
||||
#define PDQ_OS_USEC_DELAY(n) DELAY(n)
|
||||
#define PDQ_OS_VA_TO_BUSPA(pdq, 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)
|
||||
#define PDQ_OS_MEMZERO(p, n) bzero((caddr_t)(p), (n))
|
||||
#define PDQ_OS_MEMALLOC_CONTIG(n) contigmalloc(n, M_DEVBUF, M_NOWAIT, 0x800000, ~0, PAGE_SIZE, 0)
|
||||
#define PDQ_OS_MEMFREE_CONTIG(p, n) contigfree(p, n, M_DEVBUF)
|
||||
|
||||
#define PDQ_OS_DATABUF_SIZE (MCLBYTES)
|
||||
#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_ADJ(b, n) ((b)->m_data += (n), (b)->m_len -= (n))
|
||||
|
||||
#define PDQ_OS_DATABUF_ALLOC(pdq, b) do { \
|
||||
PDQ_OS_DATABUF_T *x_m0; \
|
||||
MGETHDR(x_m0, M_NOWAIT, MT_DATA); \
|
||||
if (x_m0 != NULL) { \
|
||||
if (!(MCLGET(x_m0, M_NOWAIT))) { \
|
||||
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)
|
||||
|
||||
#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)
|
||||
|
||||
#define PDQ_OS_DATABUF_BUSPA(pdq, b) PDQ_OS_VA_TO_BUSPA(pdq, PDQ_OS_DATABUF_PTR(b))
|
||||
|
||||
#define PDQ_OS_CONSUMER_PRESYNC(pdq) do { } while(0)
|
||||
#define PDQ_OS_CONSUMER_POSTSYNC(pdq) do { } while(0)
|
||||
#define PDQ_OS_DESC_PRESYNC(pdq, d, s) do { } while(0)
|
||||
#define PDQ_OS_DESC_POSTSYNC(pdq, d, s) do { } while(0)
|
||||
#define PDQ_OS_CMDRQST_PRESYNC(pdq, s) do { } while(0)
|
||||
#define PDQ_OS_CMDRQST_POSTSYNC(pdq, s) do { } while(0)
|
||||
#define PDQ_OS_CMDRSP_PRESYNC(pdq, s) do { } while(0)
|
||||
#define PDQ_OS_CMDRSP_POSTSYNC(pdq, s) do { } while(0)
|
||||
#define PDQ_OS_RXPDU_PRESYNC(pdq, b, o, l) do { } while(0)
|
||||
#define PDQ_OS_RXPDU_POSTSYNC(pdq, b, o, l) do { } while(0)
|
||||
#define PDQ_OS_UNSOL_EVENT_PRESYNC(pdq, e) do { } while(0)
|
||||
#define PDQ_OS_UNSOL_EVENT_POSTSYNC(pdq, e) do { } while(0)
|
||||
|
||||
#endif /* PDQ_HWSUPPORT */
|
||||
|
||||
/*
|
||||
* OS dependent functions provided by pdq_ifsubr.c to pdq.c
|
||||
*/
|
||||
void pdq_os_addr_fill (pdq_t *pdq, pdq_lanaddr_t *addrs, size_t numaddrs);
|
||||
void pdq_os_receive_pdu (pdq_t *, PDQ_OS_DATABUF_T *, size_t, int);
|
||||
void pdq_os_restart_transmitter (pdq_t *pdq);
|
||||
void pdq_os_transmit_done (pdq_t *, PDQ_OS_DATABUF_T *);
|
||||
void pdq_os_update_status (pdq_t *, const void *);
|
||||
|
||||
/*
|
||||
* Driver interfaces functions provided by pdq.c to pdq_ifsubr.c
|
||||
*/
|
||||
pdq_boolean_t pdq_queue_transmit_data (pdq_t *pdq, PDQ_OS_DATABUF_T *pdu);
|
||||
void pdq_run (pdq_t *pdq);
|
||||
pdq_state_t pdq_stop (pdq_t *pdq);
|
||||
|
||||
/*
|
||||
* OS dependent functions provided by
|
||||
* pdq_ifsubr.c or pdq.c to the bus front ends
|
||||
*/
|
||||
int pdq_ifattach (pdq_softc_t *, const pdq_uint8_t *,
|
||||
pdq_type_t type);
|
||||
void pdq_ifdetach (pdq_softc_t *);
|
||||
void pdq_free (device_t);
|
||||
int pdq_interrupt (pdq_t *pdq);
|
||||
void pdq_hwreset (pdq_t *pdq);
|
||||
pdq_t * pdq_initialize (pdq_bus_t bus, pdq_bus_memaddr_t csr_va,
|
||||
const char *name, int unit,
|
||||
void *ctx, pdq_type_t type);
|
||||
/*
|
||||
* Misc prototypes.
|
||||
*/
|
||||
void pdq_flush_transmitter(pdq_t *pdq);
|
@ -1,779 +0,0 @@
|
||||
/* $NetBSD: pdq_ifsubr.c,v 1.38 2001/12/21 23:21:47 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-NetBSD
|
||||
*
|
||||
* Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.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.
|
||||
*
|
||||
* $NetBSD: pdq_ifsubr.c,v 1.12 1997/06/05 01:56:35 thomas Exp$
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* DEC PDQ FDDI Controller; code for BSD derived operating systems
|
||||
*
|
||||
* This module provide bus independent BSD specific O/S functions.
|
||||
* (ie. it provides an ifnet interface to the rest of the system)
|
||||
*/
|
||||
|
||||
|
||||
#define PDQ_OSSUPPORT
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/fddi.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
|
||||
#include <dev/pdq/pdq_freebsd.h>
|
||||
#include <dev/pdq/pdqreg.h>
|
||||
|
||||
devclass_t pdq_devclass;
|
||||
|
||||
static void pdq_watchdog(void *);
|
||||
|
||||
static void
|
||||
pdq_ifstop(pdq_softc_t *sc)
|
||||
{
|
||||
|
||||
PDQ_IFNET(sc)->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
||||
sc->sc_pdq->pdq_flags &= ~PDQ_RUNNING;
|
||||
pdq_stop(sc->sc_pdq);
|
||||
callout_stop(&sc->watchdog);
|
||||
}
|
||||
|
||||
static void
|
||||
pdq_ifinit_locked(pdq_softc_t *sc)
|
||||
{
|
||||
|
||||
PDQ_LOCK_ASSERT(sc);
|
||||
if (PDQ_IFNET(sc)->if_flags & IFF_UP) {
|
||||
PDQ_IFNET(sc)->if_drv_flags |= IFF_DRV_RUNNING;
|
||||
if (PDQ_IFNET(sc)->if_flags & IFF_PROMISC) {
|
||||
sc->sc_pdq->pdq_flags |= PDQ_PROMISC;
|
||||
} else {
|
||||
sc->sc_pdq->pdq_flags &= ~PDQ_PROMISC;
|
||||
}
|
||||
if (PDQ_IFNET(sc)->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);
|
||||
callout_reset(&sc->watchdog, hz, pdq_watchdog, sc);
|
||||
} else
|
||||
pdq_ifstop(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
pdq_ifinit(void *arg)
|
||||
{
|
||||
pdq_softc_t *sc;
|
||||
|
||||
sc = arg;
|
||||
PDQ_LOCK(sc);
|
||||
pdq_ifinit_locked(sc);
|
||||
PDQ_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
pdq_watchdog(void *arg)
|
||||
{
|
||||
pdq_softc_t *sc;
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = arg;
|
||||
PDQ_LOCK_ASSERT(sc);
|
||||
callout_reset(&sc->watchdog, hz, pdq_watchdog, sc);
|
||||
if (sc->timer == 0 || --sc->timer > 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* No progress was made on the transmit queue for PDQ_OS_TX_TRANSMIT
|
||||
* seconds. Remove all queued packets.
|
||||
*/
|
||||
ifp = PDQ_IFNET(sc);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
for (;;) {
|
||||
struct mbuf *m;
|
||||
IFQ_DEQUEUE(&ifp->if_snd, m);
|
||||
if (m == NULL)
|
||||
return;
|
||||
PDQ_OS_DATABUF_FREE(PDQ_OS_IFP_TO_SOFTC(ifp)->sc_pdq, m);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pdq_ifstart_locked(struct ifnet *ifp)
|
||||
{
|
||||
pdq_softc_t * const sc = PDQ_OS_IFP_TO_SOFTC(ifp);
|
||||
struct mbuf *m;
|
||||
int tx = 0;
|
||||
|
||||
PDQ_LOCK_ASSERT(sc);
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
return;
|
||||
|
||||
if (sc->timer == 0)
|
||||
sc->timer = PDQ_OS_TX_TIMEOUT;
|
||||
|
||||
if ((sc->sc_pdq->pdq_flags & PDQ_TXOK) == 0) {
|
||||
PDQ_IFNET(sc)->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||
return;
|
||||
}
|
||||
sc->sc_flags |= PDQIF_DOWNCALL;
|
||||
for (;; tx = 1) {
|
||||
IF_DEQUEUE(&ifp->if_snd, m);
|
||||
if (m == NULL)
|
||||
break;
|
||||
#if defined(PDQ_BUS_DMA) && !defined(PDQ_BUS_DMA_NOTX)
|
||||
if ((m->m_flags & M_HASTXDMAMAP) == 0) {
|
||||
bus_dmamap_t map;
|
||||
if (PDQ_OS_HDR_OFFSET != PDQ_RX_FC_OFFSET) {
|
||||
m->m_data[0] = PDQ_FDDI_PH0;
|
||||
m->m_data[1] = PDQ_FDDI_PH1;
|
||||
m->m_data[2] = PDQ_FDDI_PH2;
|
||||
}
|
||||
if (!bus_dmamap_create(sc->sc_dmatag, m->m_pkthdr.len, 255,
|
||||
m->m_pkthdr.len, 0, BUS_DMA_NOWAIT, &map)) {
|
||||
if (!bus_dmamap_load_mbuf(sc->sc_dmatag, map, m,
|
||||
BUS_DMA_WRITE|BUS_DMA_NOWAIT)) {
|
||||
bus_dmamap_sync(sc->sc_dmatag, map, 0, m->m_pkthdr.len,
|
||||
BUS_DMASYNC_PREWRITE);
|
||||
M_SETCTX(m, map);
|
||||
m->m_flags |= M_HASTXDMAMAP;
|
||||
}
|
||||
}
|
||||
if ((m->m_flags & M_HASTXDMAMAP) == 0)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (PDQ_OS_HDR_OFFSET != PDQ_RX_FC_OFFSET) {
|
||||
m->m_data[0] = PDQ_FDDI_PH0;
|
||||
m->m_data[1] = PDQ_FDDI_PH1;
|
||||
m->m_data[2] = PDQ_FDDI_PH2;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pdq_queue_transmit_data(sc->sc_pdq, m) == PDQ_FALSE)
|
||||
break;
|
||||
}
|
||||
if (m != NULL) {
|
||||
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||
IF_PREPEND(&ifp->if_snd, m);
|
||||
}
|
||||
if (tx)
|
||||
PDQ_DO_TYPE2_PRODUCER(sc->sc_pdq);
|
||||
sc->sc_flags &= ~PDQIF_DOWNCALL;
|
||||
}
|
||||
|
||||
static void
|
||||
pdq_ifstart(struct ifnet *ifp)
|
||||
{
|
||||
pdq_softc_t * const sc = PDQ_OS_IFP_TO_SOFTC(ifp);
|
||||
|
||||
PDQ_LOCK(sc);
|
||||
pdq_ifstart_locked(ifp);
|
||||
PDQ_UNLOCK(sc);
|
||||
}
|
||||
|
||||
void
|
||||
pdq_os_receive_pdu(
|
||||
pdq_t *pdq,
|
||||
struct mbuf *m,
|
||||
size_t pktlen,
|
||||
int drop)
|
||||
{
|
||||
pdq_softc_t *sc = pdq->pdq_os_ctx;
|
||||
struct ifnet *ifp = PDQ_IFNET(sc);
|
||||
struct fddi_header *fh;
|
||||
|
||||
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
|
||||
#if defined(PDQ_BUS_DMA)
|
||||
{
|
||||
/*
|
||||
* Even though the first mbuf start at the first fddi header octet,
|
||||
* the dmamap starts PDQ_OS_HDR_OFFSET octets earlier. Any additional
|
||||
* mbufs will start normally.
|
||||
*/
|
||||
int offset = PDQ_OS_HDR_OFFSET;
|
||||
struct mbuf *m0;
|
||||
for (m0 = m; m0 != NULL; m0 = m0->m_next, offset = 0) {
|
||||
pdq_os_databuf_sync(sc, m0, offset, m0->m_len, BUS_DMASYNC_POSTREAD);
|
||||
bus_dmamap_unload(sc->sc_dmatag, M_GETCTX(m0, bus_dmamap_t));
|
||||
bus_dmamap_destroy(sc->sc_dmatag, M_GETCTX(m0, bus_dmamap_t));
|
||||
m0->m_flags &= ~M_HASRXDMAMAP;
|
||||
M_SETCTX(m0, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
m->m_pkthdr.len = pktlen;
|
||||
fh = mtod(m, struct fddi_header *);
|
||||
if (drop || (fh->fddi_fc & (FDDIFC_L|FDDIFC_F)) != FDDIFC_LLC_ASYNC) {
|
||||
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
|
||||
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
|
||||
PDQ_OS_DATABUF_FREE(pdq, m);
|
||||
return;
|
||||
}
|
||||
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
PDQ_UNLOCK(sc);
|
||||
(*ifp->if_input)(ifp, m);
|
||||
PDQ_LOCK(sc);
|
||||
}
|
||||
|
||||
void
|
||||
pdq_os_restart_transmitter(
|
||||
pdq_t *pdq)
|
||||
{
|
||||
pdq_softc_t *sc = pdq->pdq_os_ctx;
|
||||
PDQ_IFNET(sc)->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
if (IFQ_IS_EMPTY(&PDQ_IFNET(sc)->if_snd) == 0) {
|
||||
sc->timer = PDQ_OS_TX_TIMEOUT;
|
||||
if ((sc->sc_flags & PDQIF_DOWNCALL) == 0)
|
||||
pdq_ifstart_locked(PDQ_IFNET(sc));
|
||||
} else {
|
||||
sc->timer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pdq_os_transmit_done(
|
||||
pdq_t *pdq,
|
||||
struct mbuf *m)
|
||||
{
|
||||
pdq_softc_t *sc = pdq->pdq_os_ctx;
|
||||
#if defined(NBPFILTER) && NBPFILTER > 0
|
||||
if (PQD_IFNET(sc)->if_bpf != NULL)
|
||||
PDQ_BPF_MTAP(sc, m);
|
||||
#endif
|
||||
PDQ_OS_DATABUF_FREE(pdq, m);
|
||||
if_inc_counter(PDQ_IFNET(sc), IFCOUNTER_OPACKETS, 1);
|
||||
}
|
||||
|
||||
void
|
||||
pdq_os_addr_fill(
|
||||
pdq_t *pdq,
|
||||
pdq_lanaddr_t *addr,
|
||||
size_t num_addrs)
|
||||
{
|
||||
pdq_softc_t *sc = pdq->pdq_os_ctx;
|
||||
struct ifnet *ifp;
|
||||
struct ifmultiaddr *ifma;
|
||||
|
||||
ifp = sc->ifp;
|
||||
|
||||
/*
|
||||
* ADDR_FILTER_SET is always issued before FILTER_SET so
|
||||
* we can play with PDQ_ALLMULTI and not worry about
|
||||
* queueing a FILTER_SET ourselves.
|
||||
*/
|
||||
|
||||
pdq->pdq_flags &= ~PDQ_ALLMULTI;
|
||||
#if defined(IFF_ALLMULTI)
|
||||
PDQ_IFNET(sc)->if_flags &= ~IFF_ALLMULTI;
|
||||
#endif
|
||||
|
||||
if_maddr_rlock(PDQ_IFNET(sc));
|
||||
for (ifma = TAILQ_FIRST(&PDQ_IFNET(sc)->if_multiaddrs); ifma && num_addrs > 0;
|
||||
ifma = TAILQ_NEXT(ifma, ifma_link)) {
|
||||
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--;
|
||||
}
|
||||
if_maddr_runlock(PDQ_IFNET(sc));
|
||||
/*
|
||||
* If not all the address fit into the CAM, turn on all-multicast mode.
|
||||
*/
|
||||
if (ifma != NULL) {
|
||||
pdq->pdq_flags |= PDQ_ALLMULTI;
|
||||
#if defined(IFF_ALLMULTI)
|
||||
PDQ_IFNET(sc)->if_flags |= IFF_ALLMULTI;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(IFM_FDDI)
|
||||
static int
|
||||
pdq_ifmedia_change(
|
||||
struct ifnet *ifp)
|
||||
{
|
||||
pdq_softc_t * const sc = PDQ_OS_IFP_TO_SOFTC(ifp);
|
||||
|
||||
PDQ_LOCK(sc);
|
||||
if (sc->sc_ifmedia.ifm_media & IFM_FDX) {
|
||||
if ((sc->sc_pdq->pdq_flags & PDQ_WANT_FDX) == 0) {
|
||||
sc->sc_pdq->pdq_flags |= PDQ_WANT_FDX;
|
||||
if (sc->sc_pdq->pdq_flags & PDQ_RUNNING)
|
||||
pdq_run(sc->sc_pdq);
|
||||
}
|
||||
} else if (sc->sc_pdq->pdq_flags & PDQ_WANT_FDX) {
|
||||
sc->sc_pdq->pdq_flags &= ~PDQ_WANT_FDX;
|
||||
if (sc->sc_pdq->pdq_flags & PDQ_RUNNING)
|
||||
pdq_run(sc->sc_pdq);
|
||||
}
|
||||
PDQ_UNLOCK(sc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pdq_ifmedia_status(
|
||||
struct ifnet *ifp,
|
||||
struct ifmediareq *ifmr)
|
||||
{
|
||||
pdq_softc_t * const sc = PDQ_OS_IFP_TO_SOFTC(ifp);
|
||||
|
||||
PDQ_LOCK(sc);
|
||||
ifmr->ifm_status = IFM_AVALID;
|
||||
if (sc->sc_pdq->pdq_flags & PDQ_IS_ONRING)
|
||||
ifmr->ifm_status |= IFM_ACTIVE;
|
||||
|
||||
ifmr->ifm_active = (ifmr->ifm_current & ~IFM_FDX);
|
||||
if (sc->sc_pdq->pdq_flags & PDQ_IS_FDX)
|
||||
ifmr->ifm_active |= IFM_FDX;
|
||||
PDQ_UNLOCK(sc);
|
||||
}
|
||||
|
||||
void
|
||||
pdq_os_update_status(
|
||||
pdq_t *pdq,
|
||||
const void *arg)
|
||||
{
|
||||
pdq_softc_t * const sc = pdq->pdq_os_ctx;
|
||||
const pdq_response_status_chars_get_t *rsp = arg;
|
||||
int media = 0;
|
||||
|
||||
switch (rsp->status_chars_get.pmd_type[0]) {
|
||||
case PDQ_PMD_TYPE_ANSI_MUTLI_MODE: media = IFM_FDDI_MMF; break;
|
||||
case PDQ_PMD_TYPE_ANSI_SINGLE_MODE_TYPE_1: media = IFM_FDDI_SMF; break;
|
||||
case PDQ_PMD_TYPE_ANSI_SIGNLE_MODE_TYPE_2: media = IFM_FDDI_SMF; break;
|
||||
case PDQ_PMD_TYPE_UNSHIELDED_TWISTED_PAIR: media = IFM_FDDI_UTP; break;
|
||||
default: media |= IFM_MANUAL;
|
||||
}
|
||||
|
||||
if (rsp->status_chars_get.station_type == PDQ_STATION_TYPE_DAS)
|
||||
media |= IFM_FDDI_DA;
|
||||
|
||||
sc->sc_ifmedia.ifm_media = media | IFM_FDDI;
|
||||
}
|
||||
#endif /* defined(IFM_FDDI) */
|
||||
|
||||
static int
|
||||
pdq_ifioctl(
|
||||
struct ifnet *ifp,
|
||||
u_long cmd,
|
||||
caddr_t data)
|
||||
{
|
||||
pdq_softc_t *sc = PDQ_OS_IFP_TO_SOFTC(ifp);
|
||||
int error = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS: {
|
||||
pdq_ifinit(sc);
|
||||
break;
|
||||
}
|
||||
|
||||
case SIOCADDMULTI:
|
||||
case SIOCDELMULTI: {
|
||||
PDQ_LOCK(sc);
|
||||
if (PDQ_IFNET(sc)->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
pdq_run(sc->sc_pdq);
|
||||
error = 0;
|
||||
}
|
||||
PDQ_UNLOCK(sc);
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(IFM_FDDI) && defined(SIOCSIFMEDIA)
|
||||
case SIOCSIFMEDIA:
|
||||
case SIOCGIFMEDIA: {
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default: {
|
||||
error = fddi_ioctl(ifp, cmd, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
#ifndef IFF_NOTRAILERS
|
||||
#define IFF_NOTRAILERS 0
|
||||
#endif
|
||||
|
||||
int
|
||||
pdq_ifattach(pdq_softc_t *sc, const pdq_uint8_t *llc, pdq_type_t type)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
|
||||
KASSERT(type == PDQ_DEFPA, ("We only support PCI attachment."));
|
||||
|
||||
ifp = PDQ_IFNET(sc) = if_alloc(IFT_FDDI);
|
||||
if (ifp == NULL) {
|
||||
device_printf(sc->dev, "can not if_alloc()\n");
|
||||
return (ENOSPC);
|
||||
}
|
||||
|
||||
mtx_init(&sc->mtx, device_get_nameunit(sc->dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF);
|
||||
callout_init_mtx(&sc->watchdog, &sc->mtx, 0);
|
||||
|
||||
if_initname(ifp, device_get_name(sc->dev), device_get_unit(sc->dev));
|
||||
ifp->if_softc = sc;
|
||||
ifp->if_init = pdq_ifinit;
|
||||
ifp->if_snd.ifq_maxlen = ifqmaxlen;
|
||||
ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;
|
||||
|
||||
ifp->if_ioctl = pdq_ifioctl;
|
||||
ifp->if_start = pdq_ifstart;
|
||||
|
||||
#if defined(IFM_FDDI)
|
||||
{
|
||||
const int media = sc->sc_ifmedia.ifm_media;
|
||||
ifmedia_init(&sc->sc_ifmedia, IFM_FDX,
|
||||
pdq_ifmedia_change, pdq_ifmedia_status);
|
||||
ifmedia_add(&sc->sc_ifmedia, media, 0, 0);
|
||||
ifmedia_set(&sc->sc_ifmedia, media);
|
||||
}
|
||||
#endif
|
||||
|
||||
sc->sc_pdq = pdq_initialize(sc->mem_bst, sc->mem_bsh, ifp->if_xname, -1,
|
||||
sc, type);
|
||||
if (sc->sc_pdq == NULL) {
|
||||
device_printf(sc->dev, "Initialization failed.\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
fddi_ifattach(ifp, llc, FDDI_BPF_SUPPORTED);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
pdq_ifdetach (pdq_softc_t *sc)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
|
||||
ifp = sc->ifp;
|
||||
|
||||
fddi_ifdetach(ifp, FDDI_BPF_SUPPORTED);
|
||||
PDQ_LOCK(sc);
|
||||
pdq_ifstop(sc);
|
||||
PDQ_UNLOCK(sc);
|
||||
callout_drain(&sc->watchdog);
|
||||
pdq_free(sc->dev);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
pdq_free (device_t dev)
|
||||
{
|
||||
pdq_softc_t *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
if (sc->io)
|
||||
bus_release_resource(dev, sc->io_type, sc->io_rid, sc->io);
|
||||
if (sc->mem)
|
||||
bus_release_resource(dev, sc->mem_type, sc->mem_rid, sc->mem);
|
||||
if (sc->irq_ih)
|
||||
bus_teardown_intr(dev, sc->irq, sc->irq_ih);
|
||||
if (sc->irq)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
|
||||
if (sc->ifp)
|
||||
if_free(sc->ifp);
|
||||
|
||||
/*
|
||||
* Destroy the mutex.
|
||||
*/
|
||||
if (mtx_initialized(&sc->mtx) != 0) {
|
||||
mtx_destroy(&sc->mtx);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(PDQ_BUS_DMA)
|
||||
int
|
||||
pdq_os_memalloc_contig(
|
||||
pdq_t *pdq)
|
||||
{
|
||||
pdq_softc_t * const sc = pdq->pdq_os_ctx;
|
||||
bus_dma_segment_t db_segs[1], ui_segs[1], cb_segs[1];
|
||||
int db_nsegs = 0, ui_nsegs = 0;
|
||||
int steps = 0;
|
||||
int not_ok;
|
||||
|
||||
not_ok = bus_dmamem_alloc(sc->sc_dmatag,
|
||||
sizeof(*pdq->pdq_dbp), sizeof(*pdq->pdq_dbp),
|
||||
sizeof(*pdq->pdq_dbp), db_segs, 1, &db_nsegs,
|
||||
BUS_DMA_NOWAIT);
|
||||
if (!not_ok) {
|
||||
steps = 1;
|
||||
not_ok = bus_dmamem_map(sc->sc_dmatag, db_segs, db_nsegs,
|
||||
sizeof(*pdq->pdq_dbp), (caddr_t *) &pdq->pdq_dbp,
|
||||
BUS_DMA_NOWAIT);
|
||||
}
|
||||
if (!not_ok) {
|
||||
steps = 2;
|
||||
not_ok = bus_dmamap_create(sc->sc_dmatag, db_segs[0].ds_len, 1,
|
||||
0x2000, 0, BUS_DMA_NOWAIT, &sc->sc_dbmap);
|
||||
}
|
||||
if (!not_ok) {
|
||||
steps = 3;
|
||||
not_ok = bus_dmamap_load(sc->sc_dmatag, sc->sc_dbmap,
|
||||
pdq->pdq_dbp, sizeof(*pdq->pdq_dbp),
|
||||
NULL, BUS_DMA_NOWAIT);
|
||||
}
|
||||
if (!not_ok) {
|
||||
steps = 4;
|
||||
pdq->pdq_pa_descriptor_block = sc->sc_dbmap->dm_segs[0].ds_addr;
|
||||
not_ok = bus_dmamem_alloc(sc->sc_dmatag,
|
||||
PDQ_OS_PAGESIZE, PDQ_OS_PAGESIZE, PDQ_OS_PAGESIZE,
|
||||
ui_segs, 1, &ui_nsegs, BUS_DMA_NOWAIT);
|
||||
}
|
||||
if (!not_ok) {
|
||||
steps = 5;
|
||||
not_ok = bus_dmamem_map(sc->sc_dmatag, ui_segs, ui_nsegs,
|
||||
PDQ_OS_PAGESIZE,
|
||||
(caddr_t *) &pdq->pdq_unsolicited_info.ui_events,
|
||||
BUS_DMA_NOWAIT);
|
||||
}
|
||||
if (!not_ok) {
|
||||
steps = 6;
|
||||
not_ok = bus_dmamap_create(sc->sc_dmatag, ui_segs[0].ds_len, 1,
|
||||
PDQ_OS_PAGESIZE, 0, BUS_DMA_NOWAIT,
|
||||
&sc->sc_uimap);
|
||||
}
|
||||
if (!not_ok) {
|
||||
steps = 7;
|
||||
not_ok = bus_dmamap_load(sc->sc_dmatag, sc->sc_uimap,
|
||||
pdq->pdq_unsolicited_info.ui_events,
|
||||
PDQ_OS_PAGESIZE, NULL, BUS_DMA_NOWAIT);
|
||||
}
|
||||
if (!not_ok) {
|
||||
steps = 8;
|
||||
pdq->pdq_unsolicited_info.ui_pa_bufstart = sc->sc_uimap->dm_segs[0].ds_addr;
|
||||
cb_segs[0] = db_segs[0];
|
||||
cb_segs[0].ds_addr += offsetof(pdq_descriptor_block_t, pdqdb_consumer);
|
||||
cb_segs[0].ds_len = sizeof(pdq_consumer_block_t);
|
||||
not_ok = bus_dmamem_map(sc->sc_dmatag, cb_segs, 1,
|
||||
sizeof(*pdq->pdq_cbp), (caddr_t *) &pdq->pdq_cbp,
|
||||
BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
|
||||
}
|
||||
if (!not_ok) {
|
||||
steps = 9;
|
||||
not_ok = bus_dmamap_create(sc->sc_dmatag, cb_segs[0].ds_len, 1,
|
||||
0x2000, 0, BUS_DMA_NOWAIT, &sc->sc_cbmap);
|
||||
}
|
||||
if (!not_ok) {
|
||||
steps = 10;
|
||||
not_ok = bus_dmamap_load(sc->sc_dmatag, sc->sc_cbmap,
|
||||
(caddr_t) pdq->pdq_cbp, sizeof(*pdq->pdq_cbp),
|
||||
NULL, BUS_DMA_NOWAIT);
|
||||
}
|
||||
if (!not_ok) {
|
||||
pdq->pdq_pa_consumer_block = sc->sc_cbmap->dm_segs[0].ds_addr;
|
||||
return not_ok;
|
||||
}
|
||||
|
||||
switch (steps) {
|
||||
case 11: {
|
||||
bus_dmamap_unload(sc->sc_dmatag, sc->sc_cbmap);
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
case 10: {
|
||||
bus_dmamap_destroy(sc->sc_dmatag, sc->sc_cbmap);
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
case 9: {
|
||||
bus_dmamem_unmap(sc->sc_dmatag,
|
||||
(caddr_t) pdq->pdq_cbp, sizeof(*pdq->pdq_cbp));
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
case 8: {
|
||||
bus_dmamap_unload(sc->sc_dmatag, sc->sc_uimap);
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
case 7: {
|
||||
bus_dmamap_destroy(sc->sc_dmatag, sc->sc_uimap);
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
case 6: {
|
||||
bus_dmamem_unmap(sc->sc_dmatag,
|
||||
(caddr_t) pdq->pdq_unsolicited_info.ui_events,
|
||||
PDQ_OS_PAGESIZE);
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
case 5: {
|
||||
bus_dmamem_free(sc->sc_dmatag, ui_segs, ui_nsegs);
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
case 4: {
|
||||
bus_dmamap_unload(sc->sc_dmatag, sc->sc_dbmap);
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
case 3: {
|
||||
bus_dmamap_destroy(sc->sc_dmatag, sc->sc_dbmap);
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
case 2: {
|
||||
bus_dmamem_unmap(sc->sc_dmatag,
|
||||
(caddr_t) pdq->pdq_dbp,
|
||||
sizeof(*pdq->pdq_dbp));
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
case 1: {
|
||||
bus_dmamem_free(sc->sc_dmatag, db_segs, db_nsegs);
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
}
|
||||
|
||||
return not_ok;
|
||||
}
|
||||
|
||||
extern void
|
||||
pdq_os_descriptor_block_sync(
|
||||
pdq_os_ctx_t *sc,
|
||||
size_t offset,
|
||||
size_t length,
|
||||
int ops)
|
||||
{
|
||||
bus_dmamap_sync(sc->sc_dmatag, sc->sc_dbmap, offset, length, ops);
|
||||
}
|
||||
|
||||
extern void
|
||||
pdq_os_consumer_block_sync(
|
||||
pdq_os_ctx_t *sc,
|
||||
int ops)
|
||||
{
|
||||
bus_dmamap_sync(sc->sc_dmatag, sc->sc_cbmap, 0, sizeof(pdq_consumer_block_t), ops);
|
||||
}
|
||||
|
||||
extern void
|
||||
pdq_os_unsolicited_event_sync(
|
||||
pdq_os_ctx_t *sc,
|
||||
size_t offset,
|
||||
size_t length,
|
||||
int ops)
|
||||
{
|
||||
bus_dmamap_sync(sc->sc_dmatag, sc->sc_uimap, offset, length, ops);
|
||||
}
|
||||
|
||||
extern void
|
||||
pdq_os_databuf_sync(
|
||||
pdq_os_ctx_t *sc,
|
||||
struct mbuf *m,
|
||||
size_t offset,
|
||||
size_t length,
|
||||
int ops)
|
||||
{
|
||||
bus_dmamap_sync(sc->sc_dmatag, M_GETCTX(m, bus_dmamap_t), offset, length, ops);
|
||||
}
|
||||
|
||||
extern void
|
||||
pdq_os_databuf_free(
|
||||
pdq_os_ctx_t *sc,
|
||||
struct mbuf *m)
|
||||
{
|
||||
if (m->m_flags & (M_HASRXDMAMAP|M_HASTXDMAMAP)) {
|
||||
bus_dmamap_t map = M_GETCTX(m, bus_dmamap_t);
|
||||
bus_dmamap_unload(sc->sc_dmatag, map);
|
||||
bus_dmamap_destroy(sc->sc_dmatag, map);
|
||||
m->m_flags &= ~(M_HASRXDMAMAP|M_HASTXDMAMAP);
|
||||
}
|
||||
m_freem(m);
|
||||
}
|
||||
|
||||
extern struct mbuf *
|
||||
pdq_os_databuf_alloc(
|
||||
pdq_os_ctx_t *sc)
|
||||
{
|
||||
struct mbuf *m;
|
||||
bus_dmamap_t map;
|
||||
|
||||
MGETHDR(m, M_NOWAIT, MT_DATA);
|
||||
if (m == NULL) {
|
||||
printf("%s: can't alloc small buf\n", sc->sc_dev.dv_xname);
|
||||
return NULL;
|
||||
}
|
||||
if (!(MCLGET(m, M_NOWAIT))) {
|
||||
printf("%s: can't alloc cluster\n", sc->sc_dev.dv_xname);
|
||||
m_free(m);
|
||||
return NULL;
|
||||
}
|
||||
m->m_pkthdr.len = m->m_len = PDQ_OS_DATABUF_SIZE;
|
||||
|
||||
if (bus_dmamap_create(sc->sc_dmatag, PDQ_OS_DATABUF_SIZE,
|
||||
1, PDQ_OS_DATABUF_SIZE, 0, BUS_DMA_NOWAIT, &map)) {
|
||||
printf("%s: can't create dmamap\n", sc->sc_dev.dv_xname);
|
||||
m_free(m);
|
||||
return NULL;
|
||||
}
|
||||
if (bus_dmamap_load_mbuf(sc->sc_dmatag, map, m,
|
||||
BUS_DMA_READ|BUS_DMA_NOWAIT)) {
|
||||
printf("%s: can't load dmamap\n", sc->sc_dev.dv_xname);
|
||||
bus_dmamap_destroy(sc->sc_dmatag, map);
|
||||
m_free(m);
|
||||
return NULL;
|
||||
}
|
||||
m->m_flags |= M_HASRXDMAMAP;
|
||||
M_SETCTX(m, map);
|
||||
return m;
|
||||
}
|
||||
#endif
|
1092
sys/dev/pdq/pdqreg.h
1092
sys/dev/pdq/pdqreg.h
File diff suppressed because it is too large
Load Diff
@ -1,294 +0,0 @@
|
||||
/* $NetBSD: pdqvar.h,v 1.27 2000/05/03 19:17:54 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-NetBSD
|
||||
*
|
||||
* Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.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.
|
||||
*
|
||||
* Id: pdqvar.h,v 1.21 1997/03/21 21:16:04 thomas Exp
|
||||
* $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 */
|
||||
|
||||
typedef struct _pdq_t pdq_t;
|
||||
typedef struct _pdq_csrs_t pdq_csrs_t;
|
||||
typedef struct _pdq_pci_csrs_t pdq_pci_csrs_t;
|
||||
typedef struct _pdq_lanaddr_t pdq_lanaddr_t;
|
||||
typedef unsigned int pdq_uint32_t;
|
||||
typedef unsigned short pdq_uint16_t;
|
||||
typedef unsigned char pdq_uint8_t;
|
||||
typedef enum _pdq_boolean_t pdq_boolean_t;
|
||||
typedef enum _pdq_type_t pdq_type_t;
|
||||
typedef enum _pdq_state_t pdq_state_t;
|
||||
|
||||
enum _pdq_type_t {
|
||||
PDQ_DEFPA, /* PCI-bus */
|
||||
};
|
||||
|
||||
#if defined(PDQTEST)
|
||||
#include <pdq_os_test.h>
|
||||
#else
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#ifndef M_MCAST
|
||||
#include <sys/mbuf.h>
|
||||
#endif /* M_CAST */
|
||||
#include <sys/malloc.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_kern.h>
|
||||
|
||||
#define PDQ_OS_PREFIX "%s: "
|
||||
#define PDQ_OS_PREFIX_ARGS pdq->pdq_os_name
|
||||
#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))
|
||||
#if !defined(PDQ_BUS_DMA)
|
||||
#define PDQ_OS_VA_TO_BUSPA(pdq, p) vtophys(p)
|
||||
#endif
|
||||
#define PDQ_OS_MEMALLOC(n) malloc(n, M_DEVBUF, M_NOWAIT)
|
||||
#define PDQ_OS_MEMFREE(p, n) free((void *) p, M_DEVBUF)
|
||||
#define PDQ_OS_MEMALLOC_CONTIG(n) contigmalloc(n, M_DEVBUF, M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0)
|
||||
#define PDQ_OS_MEMFREE_CONTIG(p, n) contigfree((void *) p, n, M_DEVBUF)
|
||||
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_extern.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#define ifnet_ret_t void
|
||||
typedef int ioctl_cmd_t;
|
||||
typedef enum { PDQ_BUS_EISA, PDQ_BUS_PCI } pdq_bus_t;
|
||||
typedef u_int16_t pdq_bus_ioport_t;
|
||||
typedef volatile pdq_uint32_t *pdq_bus_memaddr_t;
|
||||
typedef pdq_bus_memaddr_t pdq_bus_memoffset_t;
|
||||
#define pdq_os_update_status(a, b) ((void) 0)
|
||||
|
||||
|
||||
#if !defined(PDQ_OS_SPL_RAISE)
|
||||
#define PDQ_OS_SPL_RAISE() splimp()
|
||||
#endif
|
||||
|
||||
#if !defined(PDQ_OS_SPL_LOWER)
|
||||
#define PDQ_OS_SPL_LOWER(s) splx(s)
|
||||
#endif
|
||||
|
||||
#if !defined(PDQ_FDDICOM)
|
||||
#define PDQ_FDDICOM(sc) (&(sc)->sc_ac)
|
||||
#endif
|
||||
|
||||
#if !defined(PDQ_IFNET)
|
||||
#define PDQ_IFNET(sc) (PDQ_FDDICOM((sc))->ac_ifp)
|
||||
#endif
|
||||
|
||||
#define PDQ_BPF_MTAP(sc, m) bpf_mtap(PDQ_IFNET(sc), m)
|
||||
#define PDQ_BPFATTACH(sc, t, s) bpfattach(PDQ_IFNET(sc), t, s)
|
||||
|
||||
#if !defined(PDQ_ARP_IFINIT)
|
||||
#define PDQ_ARP_IFINIT(sc, ifa) arp_ifinit(&(sc)->sc_ac, (ifa))
|
||||
#endif
|
||||
|
||||
#if !defined(PDQ_OS_PTR_FMT)
|
||||
#define PDQ_OS_PTR_FMT "0x%x"
|
||||
#endif
|
||||
|
||||
#if !defined(PDQ_OS_CSR_FMT)
|
||||
#define PDQ_OS_CSR_FMT "0x%x"
|
||||
#endif
|
||||
|
||||
#if !defined(PDQ_LANADDR)
|
||||
#define PDQ_LANADDR(sc) ((sc)->sc_ac.ac_enaddr)
|
||||
#define PDQ_LANADDR_SIZE(sc) (sizeof((sc)->sc_ac.ac_enaddr))
|
||||
#endif
|
||||
|
||||
#if !defined(PDQ_OS_IOMEM)
|
||||
#define PDQ_OS_IORD_32(t, base, offset) inl((base) + (offset))
|
||||
#define PDQ_OS_IOWR_32(t, base, offset, data) outl((base) + (offset), data)
|
||||
#define PDQ_OS_IORD_8(t, base, offset) inb((base) + (offset))
|
||||
#define PDQ_OS_IOWR_8(t, base, offset, data) outb((base) + (offset), data)
|
||||
#define PDQ_OS_MEMRD_32(t, base, offset) (0 + *((base) + (offset)))
|
||||
#define PDQ_OS_MEMWR_32(t, base, offset, data) do *((base) + (offset)) = (data); while (0)
|
||||
#endif
|
||||
#ifndef PDQ_CSR_OFFSET
|
||||
#define PDQ_CSR_OFFSET(base, offset) (0 + (base) + (offset))
|
||||
#endif
|
||||
|
||||
#ifndef PDQ_CSR_WRITE
|
||||
#define PDQ_CSR_WRITE(csr, name, data) PDQ_OS_MEMWR_32((csr)->csr_bus, (csr)->name, 0, data)
|
||||
#define PDQ_CSR_READ(csr, name) PDQ_OS_MEMRD_32((csr)->csr_bus, (csr)->name, 0)
|
||||
#endif
|
||||
|
||||
#ifndef PDQ_OS_IFP_TO_SOFTC
|
||||
#define PDQ_OS_IFP_TO_SOFTC(ifp) ((pdq_softc_t *) ((caddr_t) ifp - offsetof(pdq_softc_t, sc_ac.ac_if)))
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(PDQ_HWSUPPORT)
|
||||
|
||||
typedef struct _pdq_os_ctx_t {
|
||||
struct kern_devconf *sc_kdc; /* freebsd cruft */
|
||||
struct arpcom sc_ac;
|
||||
#if defined(IFM_FDDI)
|
||||
struct ifmedia sc_ifmedia;
|
||||
#endif
|
||||
pdq_t *sc_pdq;
|
||||
#if defined(__i386__)
|
||||
pdq_bus_ioport_t sc_iobase;
|
||||
#endif
|
||||
#if defined(PDQ_IOMAPPED)
|
||||
#define sc_membase sc_iobase
|
||||
#else
|
||||
pdq_bus_memaddr_t sc_membase;
|
||||
#endif
|
||||
pdq_bus_t sc_iotag;
|
||||
pdq_bus_t sc_csrtag;
|
||||
caddr_t sc_bpf;
|
||||
#if defined(PDQ_BUS_DMA)
|
||||
bus_dma_tag_t sc_dmatag;
|
||||
bus_dmamap_t sc_dbmap; /* DMA map for descriptor block */
|
||||
bus_dmamap_t sc_uimap; /* DMA map for unsolicited events */
|
||||
bus_dmamap_t sc_cbmap; /* DMA map for consumer block */
|
||||
#endif
|
||||
} pdq_softc_t;
|
||||
|
||||
|
||||
extern void pdq_ifreset(pdq_softc_t *sc);
|
||||
extern void pdq_ifinit(pdq_softc_t *sc);
|
||||
extern void pdq_ifwatchdog(struct ifnet *ifp);
|
||||
extern ifnet_ret_t pdq_ifstart(struct ifnet *ifp);
|
||||
extern int pdq_ifioctl(struct ifnet *ifp, ioctl_cmd_t cmd, caddr_t data);
|
||||
extern void pdq_ifattach(pdq_softc_t *sc, ifnet_ret_t (*ifwatchdog)(int unit));
|
||||
#endif /* !PDQ_HWSUPPORT */
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define PDQ_OS_DATABUF_SIZE (MCLBYTES)
|
||||
#ifndef PDQ_OS_DATABUF_FREE
|
||||
#define PDQ_OS_DATABUF_FREE(pdq, b) (m_freem(b))
|
||||
#endif
|
||||
#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_ADJ(b, n) ((b)->m_data += (n), (b)->m_len -= (n))
|
||||
typedef struct mbuf PDQ_OS_DATABUF_T;
|
||||
|
||||
#ifndef PDQ_OS_DATABUF_ALLOC
|
||||
#define PDQ_OS_DATABUF_ALLOC(pdq, b) do { \
|
||||
PDQ_OS_DATABUF_T *x_m0; \
|
||||
MGETHDR(x_m0, M_NOWAIT, MT_DATA); \
|
||||
if (x_m0 != NULL) { \
|
||||
if (!(MCLGET(x_m0, M_NOWAIT))) { \
|
||||
m_free(x_m0); \
|
||||
(b) = NULL; \
|
||||
} else { \
|
||||
(b) = x_m0; \
|
||||
x_m0->m_len = PDQ_OS_DATABUF_SIZE; \
|
||||
} \
|
||||
} else { \
|
||||
(b) = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
#define PDQ_OS_DATABUF_RESET(b) ((b)->m_data = (b)->m_ext.ext_buf, (b)->m_len = MCLBYTES)
|
||||
|
||||
#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)
|
||||
|
||||
#if !defined(PDQ_OS_CONSUMER_PRESYNC)
|
||||
#define PDQ_OS_CONSUMER_PRESYNC(pdq) do { } while(0)
|
||||
#define PDQ_OS_CONSUMER_POSTSYNC(pdq) do { } while(0)
|
||||
#define PDQ_OS_DESC_PRESYNC(pdq, d, s) do { } while(0)
|
||||
#define PDQ_OS_DESC_POSTSYNC(pdq, d, s) do { } while(0)
|
||||
#define PDQ_OS_CMDRQST_PRESYNC(pdq, s) do { } while(0)
|
||||
#define PDQ_OS_CMDRQST_POSTSYNC(pdq, s) do { } while(0)
|
||||
#define PDQ_OS_CMDRSP_PRESYNC(pdq, s) do { } while(0)
|
||||
#define PDQ_OS_CMDRSP_POSTSYNC(pdq, s) do { } while(0)
|
||||
#define PDQ_OS_RXPDU_PRESYNC(pdq, b, o, l) do { } while(0)
|
||||
#define PDQ_OS_RXPDU_POSTSYNC(pdq, b, o, l) do { } while(0)
|
||||
#define PDQ_OS_UNSOL_EVENT_PRESYNC(pdq, e) do { } while(0)
|
||||
#define PDQ_OS_UNSOL_EVENT_POSTSYNC(pdq, e) do { } while(0)
|
||||
#endif
|
||||
|
||||
#ifndef PDQ_OS_DATABUF_BUSPA
|
||||
#define PDQ_OS_DATABUF_BUSPA(pdq, b) PDQ_OS_VA_TO_BUSPA(pdq, PDQ_OS_DATABUF_PTR(b))
|
||||
#endif
|
||||
|
||||
#ifndef PDQ_OS_HDR_OFFSET
|
||||
#define PDQ_OS_HDR_OFFSET PDQ_RX_FC_OFFSET
|
||||
#endif
|
||||
|
||||
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, int drop);
|
||||
extern void pdq_os_restart_transmitter(pdq_t *pdq);
|
||||
extern void pdq_os_transmit_done(pdq_t *pdq, PDQ_OS_DATABUF_T *pdu);
|
||||
#if !defined(pdq_os_update_status)
|
||||
extern void pdq_os_update_status(pdq_t *pdq, const void *rsp);
|
||||
#endif
|
||||
#if !defined(PDQ_OS_MEMALLOC_CONTIG)
|
||||
extern int pdq_os_memalloc_contig(pdq_t *pdq);
|
||||
#endif
|
||||
extern pdq_boolean_t pdq_queue_transmit_data(pdq_t *pdq, PDQ_OS_DATABUF_T *pdu);
|
||||
extern void pdq_flush_transmitter(pdq_t *pdq);
|
||||
|
||||
extern void pdq_run(pdq_t *pdq);
|
||||
extern pdq_state_t pdq_stop(pdq_t *pdq);
|
||||
extern void pdq_hwreset(pdq_t *pdq);
|
||||
|
||||
extern int pdq_interrupt(pdq_t *pdq);
|
||||
extern pdq_t *pdq_initialize(pdq_bus_t bus, pdq_bus_memaddr_t csr_va,
|
||||
const char *name, int unit,
|
||||
void *ctx, pdq_type_t type);
|
||||
#endif /* _PDQ_OS_H */
|
107
sys/net/fddi.h
107
sys/net/fddi.h
@ -1,107 +0,0 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-4-Clause
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETINET_IF_FDDI_H_
|
||||
#define _NETINET_IF_FDDI_H_
|
||||
|
||||
#define FDDIIPMTU 4352
|
||||
#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_CLFF 0xF0 /* Class/Length/Format bits */
|
||||
#define FDDIFC_ZZZZ 0x0F /* Control bits */
|
||||
|
||||
/*
|
||||
* FDDI Frame Control values. (48-bit addressing only).
|
||||
*/
|
||||
#define FDDIFC_VOID 0x40 /* Void frame */
|
||||
#define FDDIFC_NRT 0x80 /* Nonrestricted token */
|
||||
#define FDDIFC_RT 0xc0 /* Restricted token */
|
||||
#define FDDIFC_MAC_BEACON 0xc2 /* MAC Beacon frame */
|
||||
#define FDDIFC_MAC_CLAIM 0xc3 /* MAC Claim frame */
|
||||
#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_IMP_ASYNC 0x60 /* Implementor Async. */
|
||||
#define FDDIFC_IMP_SYNC 0xe0 /* Implementor Synch. */
|
||||
#define FDDIFC_SMT 0x40
|
||||
#define FDDIFC_SMT_INFO 0x41 /* SMT Info */
|
||||
#define FDDIFC_SMT_NSA 0x4F /* SMT Next station adrs */
|
||||
#define FDDIFC_MAC 0xc0 /* MAC frame */
|
||||
|
||||
#define FDDI_ADDR_LEN 6
|
||||
#define FDDI_HDR_LEN (sizeof(struct fddi_header))
|
||||
|
||||
/*
|
||||
* Structure of an 100Mb/s FDDI header.
|
||||
*/
|
||||
struct fddi_header {
|
||||
u_char fddi_fc;
|
||||
u_char fddi_dhost[FDDI_ADDR_LEN];
|
||||
u_char fddi_shost[FDDI_ADDR_LEN];
|
||||
};
|
||||
|
||||
#if defined(_KERNEL)
|
||||
#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
|
||||
|
||||
#define FDDI_BPF_UNSUPPORTED 0
|
||||
#define FDDI_BPF_SUPPORTED 1
|
||||
|
||||
void fddi_ifattach(struct ifnet *, const u_int8_t *, int);
|
||||
void fddi_ifdetach(struct ifnet *, int);
|
||||
int fddi_ioctl(struct ifnet *, u_long, caddr_t);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _NET_FDDI_H_ */
|
@ -3692,7 +3692,6 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
|
||||
}
|
||||
switch (ifp->if_type) {
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
case IFT_XETHER:
|
||||
case IFT_L2VLAN:
|
||||
case IFT_BRIDGE:
|
||||
|
@ -72,8 +72,8 @@
|
||||
*
|
||||
* - Currently only supports Ethernet-like interfaces (Ethernet,
|
||||
* 802.11, VLANs on Ethernet, etc.) Figure out a nice way
|
||||
* to bridge other types of interfaces (FDDI-FDDI, and maybe
|
||||
* consider heterogeneous bridges).
|
||||
* to bridge other types of interfaces (maybe consider
|
||||
* heterogeneous bridges).
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
@ -1,667 +0,0 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-4-Clause
|
||||
*
|
||||
* Copyright (c) 1995, 1996
|
||||
* Matt Thomas <matt@3am-software.com>. All rights reserved.
|
||||
* Copyright (c) 1982, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* from: if_ethersubr.c,v 1.5 1994/12/13 22:31:45 wollman Exp
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_llc.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_llatbl.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/netisr.h>
|
||||
#include <net/route.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/fddi.h>
|
||||
|
||||
#if defined(INET) || defined(INET6)
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#endif
|
||||
#ifdef INET6
|
||||
#include <netinet6/nd6.h>
|
||||
#endif
|
||||
|
||||
#ifdef DECNET
|
||||
#include <netdnet/dn.h>
|
||||
#endif
|
||||
|
||||
#include <security/mac/mac_framework.h>
|
||||
|
||||
static const u_char fddibroadcastaddr[FDDI_ADDR_LEN] =
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
static int fddi_resolvemulti(struct ifnet *, struct sockaddr **,
|
||||
struct sockaddr *);
|
||||
static int fddi_output(struct ifnet *, struct mbuf *, const struct sockaddr *,
|
||||
struct route *);
|
||||
static void fddi_input(struct ifnet *ifp, struct mbuf *m);
|
||||
|
||||
#define senderr(e) do { error = (e); goto bad; } while (0)
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
static int
|
||||
fddi_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
||||
struct route *ro)
|
||||
{
|
||||
u_int16_t type;
|
||||
int loop_copy = 0, error = 0, hdrcmplt = 0;
|
||||
u_char esrc[FDDI_ADDR_LEN], edst[FDDI_ADDR_LEN];
|
||||
struct fddi_header *fh;
|
||||
#if defined(INET) || defined(INET6)
|
||||
int is_gw = 0;
|
||||
#endif
|
||||
|
||||
#ifdef MAC
|
||||
error = mac_ifnet_check_transmit(ifp, m);
|
||||
if (error)
|
||||
senderr(error);
|
||||
#endif
|
||||
|
||||
if (ifp->if_flags & IFF_MONITOR)
|
||||
senderr(ENETDOWN);
|
||||
if (!((ifp->if_flags & IFF_UP) &&
|
||||
(ifp->if_drv_flags & IFF_DRV_RUNNING)))
|
||||
senderr(ENETDOWN);
|
||||
getmicrotime(&ifp->if_lastchange);
|
||||
|
||||
#if defined(INET) || defined(INET6)
|
||||
if (ro != NULL)
|
||||
is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
|
||||
#endif
|
||||
|
||||
switch (dst->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET: {
|
||||
error = arpresolve(ifp, is_gw, m, dst, edst, NULL, NULL);
|
||||
if (error)
|
||||
return (error == EWOULDBLOCK ? 0 : error);
|
||||
type = htons(ETHERTYPE_IP);
|
||||
break;
|
||||
}
|
||||
case AF_ARP:
|
||||
{
|
||||
struct arphdr *ah;
|
||||
ah = mtod(m, struct arphdr *);
|
||||
ah->ar_hrd = htons(ARPHRD_ETHER);
|
||||
|
||||
loop_copy = -1; /* if this is for us, don't do it */
|
||||
|
||||
switch (ntohs(ah->ar_op)) {
|
||||
case ARPOP_REVREQUEST:
|
||||
case ARPOP_REVREPLY:
|
||||
type = htons(ETHERTYPE_REVARP);
|
||||
break;
|
||||
case ARPOP_REQUEST:
|
||||
case ARPOP_REPLY:
|
||||
default:
|
||||
type = htons(ETHERTYPE_ARP);
|
||||
break;
|
||||
}
|
||||
|
||||
if (m->m_flags & M_BCAST)
|
||||
bcopy(ifp->if_broadcastaddr, edst, FDDI_ADDR_LEN);
|
||||
else
|
||||
bcopy(ar_tha(ah), edst, FDDI_ADDR_LEN);
|
||||
|
||||
}
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
error = nd6_resolve(ifp, is_gw, m, dst, edst, NULL, NULL);
|
||||
if (error)
|
||||
return (error == EWOULDBLOCK ? 0 : error);
|
||||
type = htons(ETHERTYPE_IPV6);
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
case pseudo_AF_HDRCMPLT:
|
||||
{
|
||||
const struct ether_header *eh;
|
||||
|
||||
hdrcmplt = 1;
|
||||
eh = (const struct ether_header *)dst->sa_data;
|
||||
bcopy(eh->ether_shost, esrc, FDDI_ADDR_LEN);
|
||||
/* FALLTHROUGH */
|
||||
}
|
||||
|
||||
case AF_UNSPEC:
|
||||
{
|
||||
const struct ether_header *eh;
|
||||
|
||||
loop_copy = -1;
|
||||
eh = (const struct ether_header *)dst->sa_data;
|
||||
bcopy(eh->ether_dhost, edst, FDDI_ADDR_LEN);
|
||||
if (*edst & 1)
|
||||
m->m_flags |= (M_BCAST|M_MCAST);
|
||||
type = eh->ether_type;
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
default:
|
||||
if_printf(ifp, "can't handle af%d\n", dst->sa_family);
|
||||
senderr(EAFNOSUPPORT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add LLC header.
|
||||
*/
|
||||
if (type != 0) {
|
||||
struct llc *l;
|
||||
M_PREPEND(m, LLC_SNAPFRAMELEN, M_NOWAIT);
|
||||
if (m == NULL)
|
||||
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;
|
||||
l->llc_snap.ether_type = htons(type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add local net header. If no space in first mbuf,
|
||||
* allocate another.
|
||||
*/
|
||||
M_PREPEND(m, FDDI_HDR_LEN, M_NOWAIT);
|
||||
if (m == NULL)
|
||||
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, FDDI_ADDR_LEN);
|
||||
queue_it:
|
||||
if (hdrcmplt)
|
||||
bcopy((caddr_t)esrc, (caddr_t)fh->fddi_shost, FDDI_ADDR_LEN);
|
||||
else
|
||||
bcopy(IF_LLADDR(ifp), (caddr_t)fh->fddi_shost,
|
||||
FDDI_ADDR_LEN);
|
||||
|
||||
/*
|
||||
* If a simplex interface, and the packet is being sent to our
|
||||
* Ethernet address or a broadcast address, loopback a copy.
|
||||
* XXX To make a simplex device behave exactly like a duplex
|
||||
* device, we should copy in the case of sending to our own
|
||||
* ethernet address (thus letting the original actually appear
|
||||
* on the wire). However, we don't do that here for security
|
||||
* reasons and compatibility with the original behavior.
|
||||
*/
|
||||
if ((ifp->if_flags & IFF_SIMPLEX) && (loop_copy != -1)) {
|
||||
if ((m->m_flags & M_BCAST) || (loop_copy > 0)) {
|
||||
struct mbuf *n;
|
||||
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
|
||||
(void) if_simloop(ifp, n, dst->sa_family,
|
||||
FDDI_HDR_LEN);
|
||||
} else if (bcmp(fh->fddi_dhost, fh->fddi_shost,
|
||||
FDDI_ADDR_LEN) == 0) {
|
||||
(void) if_simloop(ifp, m, dst->sa_family,
|
||||
FDDI_HDR_LEN);
|
||||
return (0); /* XXX */
|
||||
}
|
||||
}
|
||||
|
||||
error = (ifp->if_transmit)(ifp, m);
|
||||
if (error)
|
||||
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
|
||||
|
||||
return (error);
|
||||
|
||||
bad:
|
||||
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a received FDDI packet.
|
||||
*/
|
||||
static void
|
||||
fddi_input(ifp, m)
|
||||
struct ifnet *ifp;
|
||||
struct mbuf *m;
|
||||
{
|
||||
int isr;
|
||||
struct llc *l;
|
||||
struct fddi_header *fh;
|
||||
|
||||
/*
|
||||
* Do consistency checks to verify assumptions
|
||||
* made by code past this point.
|
||||
*/
|
||||
if ((m->m_flags & M_PKTHDR) == 0) {
|
||||
if_printf(ifp, "discard frame w/o packet header\n");
|
||||
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
if (m->m_pkthdr.rcvif == NULL) {
|
||||
if_printf(ifp, "discard frame w/o interface pointer\n");
|
||||
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
m = m_pullup(m, FDDI_HDR_LEN);
|
||||
if (m == NULL) {
|
||||
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
|
||||
goto dropanyway;
|
||||
}
|
||||
fh = mtod(m, struct fddi_header *);
|
||||
|
||||
/*
|
||||
* Discard packet if interface is not up.
|
||||
*/
|
||||
if (!((ifp->if_flags & IFF_UP) &&
|
||||
(ifp->if_drv_flags & IFF_DRV_RUNNING)))
|
||||
goto dropanyway;
|
||||
|
||||
/*
|
||||
* Give bpf a chance at the packet.
|
||||
*/
|
||||
BPF_MTAP(ifp, m);
|
||||
|
||||
/*
|
||||
* Interface marked for monitoring; discard packet.
|
||||
*/
|
||||
if (ifp->if_flags & IFF_MONITOR) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MAC
|
||||
mac_ifnet_create_mbuf(ifp, m);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Update interface statistics.
|
||||
*/
|
||||
if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
|
||||
getmicrotime(&ifp->if_lastchange);
|
||||
|
||||
/*
|
||||
* Discard non local unicast packets when interface
|
||||
* is in promiscuous mode.
|
||||
*/
|
||||
if ((ifp->if_flags & IFF_PROMISC) && ((fh->fddi_dhost[0] & 1) == 0) &&
|
||||
(bcmp(IF_LLADDR(ifp), (caddr_t)fh->fddi_dhost,
|
||||
FDDI_ADDR_LEN) != 0))
|
||||
goto dropanyway;
|
||||
|
||||
/*
|
||||
* Set mbuf flags for bcast/mcast.
|
||||
*/
|
||||
if (fh->fddi_dhost[0] & 1) {
|
||||
if (bcmp(ifp->if_broadcastaddr, fh->fddi_dhost,
|
||||
FDDI_ADDR_LEN) == 0)
|
||||
m->m_flags |= M_BCAST;
|
||||
else
|
||||
m->m_flags |= M_MCAST;
|
||||
if_inc_counter(ifp, IFCOUNTER_IMCASTS, 1);
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
/* Strip off FDDI header. */
|
||||
m_adj(m, FDDI_HDR_LEN);
|
||||
|
||||
m = m_pullup(m, LLC_SNAPFRAMELEN);
|
||||
if (m == NULL) {
|
||||
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
|
||||
goto dropanyway;
|
||||
}
|
||||
l = mtod(m, struct llc *);
|
||||
|
||||
switch (l->llc_dsap) {
|
||||
case LLC_SNAP_LSAP:
|
||||
{
|
||||
u_int16_t type;
|
||||
if ((l->llc_control != LLC_UI) ||
|
||||
(l->llc_ssap != LLC_SNAP_LSAP)) {
|
||||
if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
|
||||
goto dropanyway;
|
||||
}
|
||||
if (l->llc_snap.org_code[0] != 0 ||
|
||||
l->llc_snap.org_code[1] != 0 ||
|
||||
l->llc_snap.org_code[2] != 0) {
|
||||
if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
|
||||
goto dropanyway;
|
||||
}
|
||||
|
||||
type = ntohs(l->llc_snap.ether_type);
|
||||
m_adj(m, LLC_SNAPFRAMELEN);
|
||||
|
||||
switch (type) {
|
||||
#ifdef INET
|
||||
case ETHERTYPE_IP:
|
||||
isr = NETISR_IP;
|
||||
break;
|
||||
|
||||
case ETHERTYPE_ARP:
|
||||
if (ifp->if_flags & IFF_NOARP)
|
||||
goto dropanyway;
|
||||
isr = NETISR_ARP;
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case ETHERTYPE_IPV6:
|
||||
isr = NETISR_IPV6;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DECNET
|
||||
case ETHERTYPE_DECNET:
|
||||
isr = NETISR_DECNET;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* printf("fddi_input: unknown protocol 0x%x\n", type); */
|
||||
if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
|
||||
goto dropanyway;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
/* printf("fddi_input: unknown dsap 0x%x\n", l->llc_dsap); */
|
||||
if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
|
||||
goto dropanyway;
|
||||
}
|
||||
M_SETFIB(m, ifp->if_fib);
|
||||
netisr_dispatch(isr, m);
|
||||
return;
|
||||
|
||||
dropanyway:
|
||||
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform common duties while attaching to interface list
|
||||
*/
|
||||
void
|
||||
fddi_ifattach(ifp, lla, bpf)
|
||||
struct ifnet *ifp;
|
||||
const u_int8_t *lla;
|
||||
int bpf;
|
||||
{
|
||||
struct ifaddr *ifa;
|
||||
struct sockaddr_dl *sdl;
|
||||
|
||||
ifp->if_type = IFT_FDDI;
|
||||
ifp->if_addrlen = FDDI_ADDR_LEN;
|
||||
ifp->if_hdrlen = 21;
|
||||
|
||||
if_attach(ifp); /* Must be called before additional assignments */
|
||||
|
||||
ifp->if_mtu = FDDIMTU;
|
||||
ifp->if_output = fddi_output;
|
||||
ifp->if_input = fddi_input;
|
||||
ifp->if_resolvemulti = fddi_resolvemulti;
|
||||
ifp->if_broadcastaddr = fddibroadcastaddr;
|
||||
ifp->if_baudrate = 100000000;
|
||||
#ifdef IFF_NOTRAILERS
|
||||
ifp->if_flags |= IFF_NOTRAILERS;
|
||||
#endif
|
||||
ifa = ifp->if_addr;
|
||||
KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__));
|
||||
|
||||
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
|
||||
sdl->sdl_type = IFT_FDDI;
|
||||
sdl->sdl_alen = ifp->if_addrlen;
|
||||
bcopy(lla, LLADDR(sdl), ifp->if_addrlen);
|
||||
|
||||
if (bpf)
|
||||
bpfattach(ifp, DLT_FDDI, FDDI_HDR_LEN);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
fddi_ifdetach(ifp, bpf)
|
||||
struct ifnet *ifp;
|
||||
int bpf;
|
||||
{
|
||||
|
||||
if (bpf)
|
||||
bpfdetach(ifp);
|
||||
|
||||
if_detach(ifp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
fddi_ioctl (ifp, command, data)
|
||||
struct ifnet *ifp;
|
||||
u_long command;
|
||||
caddr_t data;
|
||||
{
|
||||
struct ifaddr *ifa;
|
||||
struct ifreq *ifr;
|
||||
int error;
|
||||
|
||||
ifa = (struct ifaddr *) data;
|
||||
ifr = (struct ifreq *) data;
|
||||
error = 0;
|
||||
|
||||
switch (command) {
|
||||
case SIOCSIFADDR:
|
||||
ifp->if_flags |= IFF_UP;
|
||||
|
||||
switch (ifa->ifa_addr->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET: /* before arpwhohas */
|
||||
ifp->if_init(ifp->if_softc);
|
||||
arp_ifinit(ifp, ifa);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ifp->if_init(ifp->if_softc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SIOCGIFADDR:
|
||||
bcopy(IF_LLADDR(ifp), &ifr->ifr_addr.sa_data[0],
|
||||
FDDI_ADDR_LEN);
|
||||
break;
|
||||
case SIOCSIFMTU:
|
||||
/*
|
||||
* Set the interface MTU.
|
||||
*/
|
||||
if (ifr->ifr_mtu > FDDIMTU) {
|
||||
error = EINVAL;
|
||||
} else {
|
||||
ifp->if_mtu = ifr->ifr_mtu;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
fddi_resolvemulti(ifp, llsa, sa)
|
||||
struct ifnet *ifp;
|
||||
struct sockaddr **llsa;
|
||||
struct sockaddr *sa;
|
||||
{
|
||||
struct sockaddr_dl *sdl;
|
||||
#ifdef INET
|
||||
struct sockaddr_in *sin;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
u_char *e_addr;
|
||||
|
||||
switch(sa->sa_family) {
|
||||
case AF_LINK:
|
||||
/*
|
||||
* No mapping needed. Just check that it's a valid MC address.
|
||||
*/
|
||||
sdl = (struct sockaddr_dl *)sa;
|
||||
e_addr = LLADDR(sdl);
|
||||
if ((e_addr[0] & 1) != 1)
|
||||
return (EADDRNOTAVAIL);
|
||||
*llsa = NULL;
|
||||
return (0);
|
||||
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *)sa;
|
||||
if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
|
||||
return (EADDRNOTAVAIL);
|
||||
sdl = link_init_sdl(ifp, *llsa, IFT_FDDI);
|
||||
sdl->sdl_nlen = 0;
|
||||
sdl->sdl_alen = FDDI_ADDR_LEN;
|
||||
sdl->sdl_slen = 0;
|
||||
e_addr = LLADDR(sdl);
|
||||
ETHER_MAP_IP_MULTICAST(&sin->sin_addr, e_addr);
|
||||
*llsa = (struct sockaddr *)sdl;
|
||||
return (0);
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *)sa;
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||
/*
|
||||
* An IP6 address of 0 means listen to all
|
||||
* of the Ethernet multicast address used for IP6.
|
||||
* (This is used for multicast routers.)
|
||||
*/
|
||||
ifp->if_flags |= IFF_ALLMULTI;
|
||||
*llsa = NULL;
|
||||
return (0);
|
||||
}
|
||||
if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
|
||||
return (EADDRNOTAVAIL);
|
||||
sdl = link_init_sdl(ifp, *llsa, IFT_FDDI);
|
||||
sdl->sdl_nlen = 0;
|
||||
sdl->sdl_alen = FDDI_ADDR_LEN;
|
||||
sdl->sdl_slen = 0;
|
||||
e_addr = LLADDR(sdl);
|
||||
ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, e_addr);
|
||||
*llsa = (struct sockaddr *)sdl;
|
||||
return (0);
|
||||
#endif
|
||||
|
||||
default:
|
||||
/*
|
||||
* Well, the text isn't quite right, but it's the name
|
||||
* that counts...
|
||||
*/
|
||||
return (EAFNOSUPPORT);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static moduledata_t fddi_mod = {
|
||||
"fddi", /* module name */
|
||||
NULL, /* event handler */
|
||||
0 /* extra data */
|
||||
};
|
||||
|
||||
DECLARE_MODULE(fddi, fddi_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
|
||||
MODULE_VERSION(fddi, 1);
|
@ -405,12 +405,6 @@ struct ifmedia_description ifm_subtype_tokenring_descriptions[] =
|
||||
struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] =
|
||||
IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS;
|
||||
|
||||
struct ifmedia_description ifm_subtype_fddi_descriptions[] =
|
||||
IFM_SUBTYPE_FDDI_DESCRIPTIONS;
|
||||
|
||||
struct ifmedia_description ifm_subtype_fddi_option_descriptions[] =
|
||||
IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS;
|
||||
|
||||
struct ifmedia_description ifm_subtype_ieee80211_descriptions[] =
|
||||
IFM_SUBTYPE_IEEE80211_DESCRIPTIONS;
|
||||
|
||||
@ -450,11 +444,6 @@ struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = {
|
||||
&ifm_subtype_tokenring_option_descriptions[0],
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
&ifm_subtype_fddi_descriptions[0],
|
||||
&ifm_subtype_fddi_option_descriptions[0],
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
&ifm_subtype_ieee80211_descriptions[0],
|
||||
&ifm_subtype_ieee80211_option_descriptions[0],
|
||||
|
@ -694,10 +694,6 @@ arpintr(struct mbuf *m)
|
||||
hlen = ETHER_ADDR_LEN; /* RFC 826 */
|
||||
layer = "ethernet";
|
||||
break;
|
||||
case ARPHRD_IEEE802:
|
||||
hlen = 6; /* RFC 1390, FDDI_ADDR_LEN */
|
||||
layer = "fddi";
|
||||
break;
|
||||
case ARPHRD_ARCNET:
|
||||
hlen = 1; /* RFC 1201, ARC_ADDR_LEN */
|
||||
layer = "arcnet";
|
||||
|
@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/counter.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/fddi.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_dl.h>
|
||||
@ -1526,18 +1525,6 @@ carp_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *sa)
|
||||
eh->ether_shost[5] = sc->sc_vhid;
|
||||
}
|
||||
break;
|
||||
case IFT_FDDI: {
|
||||
struct fddi_header *fh;
|
||||
|
||||
fh = mtod(m, struct fddi_header *);
|
||||
fh->fddi_shost[0] = 0;
|
||||
fh->fddi_shost[1] = 0;
|
||||
fh->fddi_shost[2] = 0x5e;
|
||||
fh->fddi_shost[3] = 0;
|
||||
fh->fddi_shost[4] = 1;
|
||||
fh->fddi_shost[5] = sc->sc_vhid;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("%s: carp is not supported for the %d interface type\n",
|
||||
ifp->if_xname, ifp->if_type);
|
||||
@ -1719,7 +1706,6 @@ carp_ioctl(struct ifreq *ifr, u_long cmd, struct thread *td)
|
||||
case IFT_ETHER:
|
||||
case IFT_L2VLAN:
|
||||
case IFT_BRIDGE:
|
||||
case IFT_FDDI:
|
||||
break;
|
||||
default:
|
||||
error = EOPNOTSUPP;
|
||||
|
@ -1972,8 +1972,6 @@ in6_if2idlen(struct ifnet *ifp)
|
||||
case IFT_BRIDGE: /* bridge(4) only does Ethernet-like links */
|
||||
case IFT_INFINIBAND:
|
||||
return (64);
|
||||
case IFT_FDDI: /* RFC2467 */
|
||||
return (64);
|
||||
case IFT_PPP: /* RFC2472 */
|
||||
return (64);
|
||||
case IFT_ARCNET: /* RFC2497 */
|
||||
|
@ -274,7 +274,6 @@ in6_get_hw_ifid(struct ifnet *ifp, struct in6_addr *in6)
|
||||
case IFT_BRIDGE:
|
||||
case IFT_ETHER:
|
||||
case IFT_L2VLAN:
|
||||
case IFT_FDDI:
|
||||
case IFT_ATM:
|
||||
case IFT_IEEE1394:
|
||||
/* IEEE802/EUI64 cases - what others? */
|
||||
|
@ -61,7 +61,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <net/if_arc.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/fddi.h>
|
||||
#include <net/route.h>
|
||||
#include <net/vnet.h>
|
||||
|
||||
@ -340,9 +339,6 @@ nd6_setmtu0(struct ifnet *ifp, struct nd_ifinfo *ndi)
|
||||
case IFT_ARCNET:
|
||||
ndi->maxmtu = MIN(ARC_PHDS_MAXMTU, ifp->if_mtu); /* RFC2497 */
|
||||
break;
|
||||
case IFT_FDDI:
|
||||
ndi->maxmtu = MIN(FDDIIPMTU, ifp->if_mtu); /* RFC2467 */
|
||||
break;
|
||||
default:
|
||||
ndi->maxmtu = ifp->if_mtu;
|
||||
break;
|
||||
@ -2272,7 +2268,6 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
|
||||
if (m != NULL && m->m_flags & M_MCAST) {
|
||||
switch (ifp->if_type) {
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
case IFT_L2VLAN:
|
||||
case IFT_BRIDGE:
|
||||
ETHER_MAP_IPV6_MULTICAST(&dst6->sin6_addr,
|
||||
@ -2524,7 +2519,7 @@ nd6_need_cache(struct ifnet *ifp)
|
||||
{
|
||||
/*
|
||||
* XXX: we currently do not make neighbor cache on any interface
|
||||
* other than ARCnet, Ethernet, FDDI and GIF.
|
||||
* other than ARCnet, Ethernet and GIF.
|
||||
*
|
||||
* RFC2893 says:
|
||||
* - unidirectional tunnels needs no ND
|
||||
@ -2532,7 +2527,6 @@ nd6_need_cache(struct ifnet *ifp)
|
||||
switch (ifp->if_type) {
|
||||
case IFT_ARCNET:
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
case IFT_IEEE1394:
|
||||
case IFT_L2VLAN:
|
||||
case IFT_INFINIBAND:
|
||||
|
@ -1092,7 +1092,6 @@ nd6_ifptomac(struct ifnet *ifp)
|
||||
switch (ifp->if_type) {
|
||||
case IFT_ARCNET:
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
case IFT_IEEE1394:
|
||||
case IFT_L2VLAN:
|
||||
case IFT_INFINIBAND:
|
||||
@ -1466,7 +1465,6 @@ nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp)
|
||||
*/
|
||||
switch (ifp->if_type) {
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
case IFT_ATM:
|
||||
case IFT_IEEE1394:
|
||||
case IFT_INFINIBAND:
|
||||
|
@ -1645,7 +1645,6 @@ bootpc_init(void)
|
||||
continue;
|
||||
switch (ifp->if_alloctype) {
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
@ -1675,7 +1674,6 @@ bootpc_init(void)
|
||||
continue;
|
||||
switch (ifp->if_alloctype) {
|
||||
case IFT_ETHER:
|
||||
case IFT_FDDI:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user