Remove support for the Arcnet protocol.

While Arcnet has some continued deployment in industrial controls, the
lack of drivers for any of the PCI, USB, or PCIe NICs on the market
suggests such users aren't running FreeBSD.

Evidence in the PR database suggests that the cm(4) driver (our sole
Arcnet NIC) was broken in 5.0 and has not worked since.

PR:		182297
Reviewed by:	jhibbits, vangyzen
Relnotes:	yes
Sponsored by:	DARPA, AFRL
Differential Revision:	https://reviews.freebsd.org/D15057
This commit is contained in:
Brooks Davis 2018-04-13 21:18:04 +00:00
parent d86c1f0dc1
commit 3a4fc8a8a1
26 changed files with 10 additions and 2538 deletions

View File

@ -38,6 +38,9 @@
# xargs -n1 | sort | uniq -d;
# done
# 20180413: remove Arcnet support
OLD_FILES+=usr/include/net/if_arc.h
OLD_FILES+=usr/share/man/man4/cm.4
# 20180409: remove FDDI support
OLD_FILES+=usr/include/net/fddi.h
OLD_FILES+=usr/share/man/man4/fpa.4.gz

View File

@ -51,6 +51,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
****************************** SPECIAL WARNING: ******************************
20180413:
Support for Arcnet networks has been removed. If you have device
arcnet or device cm in your kernel config file they must be
removed.
20180411:
Support for FDDI networks has been removed. If you have device
fddi or device fpa in your kernel config file they must be

View File

@ -846,7 +846,6 @@ static void
check_llbcast(struct mibif *ifp)
{
static u_char ether_bcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
static u_char arcnet_bcast = 0;
struct mibrcvaddr *rcv;
if (!(ifp->mib.ifmd_flags & IFF_BROADCAST))
@ -862,12 +861,6 @@ check_llbcast(struct mibif *ifp)
(rcv = mib_rcvaddr_create(ifp, ether_bcast, 6)) != NULL)
rcv->flags |= MIBRCVADDR_BCAST;
break;
case IFT_ARCNET:
if (mib_find_rcvaddr(ifp->index, &arcnet_bcast, 1) == NULL &&
(rcv = mib_rcvaddr_create(ifp, &arcnet_bcast, 1)) != NULL)
rcv->flags |= MIBRCVADDR_BCAST;
break;
}
}

View File

@ -481,7 +481,6 @@ getnameinfo_link(const struct afd *afd,
* IFT_OTHER (netinet/ip_ipip.c)
*/
/* default below is believed correct for all these. */
case IFT_ARCNET:
case IFT_ETHER:
case IFT_FDDI:
case IFT_HIPPI:

View File

@ -120,7 +120,6 @@ MAN= aac.4 \
chromebook_platform.4 \
ciss.4 \
cloudabi.4 \
cm.4 \
cmx.4 \
${_coretemp.4} \
${_cpuctl.4} \

View File

@ -1,179 +0,0 @@
.\"
.\" Copyright (c) 2004 Tom Rhodes
.\" 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.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
.\"
.\" $FreeBSD$
.\"
.Dd March 29, 2018
.Dt CM 4
.Os
.Sh NAME
.Nm cm
.Nd "SMC Arcnet Ethernet device driver"
.Sh SYNOPSIS
To compile this driver into the kernel,
place the following lines in your kernel
configuration file:
.Bd -ragged -offset indent
.Cd "device isa"
.Cd "device cm"
.Ed
.Pp
Alternatively, to load the driver as a
module at boot time, place the following line in
.Xr loader.conf 5 :
.Bd -literal -offset indent
if_cm_load="YES"
.Ed
.Sh DEPRECATION NOTICE
The
.Nm
driver is not present in
.Fx 12.0
and later.
.Sh DESCRIPTION
The
.Nm
driver provides support for the
.Tn Arcnet
.Tn ISA
network adapters.
.Pp
This driver also has quirks preset in the
.Xr device.hints 5
file for card detection.
.Sh HARDWARE
The
.Nm
driver supports the following
card models:
.Pp
.Bl -bullet -compact
.It
SMC90c26
.It
SMC90c56
.It
SMC90c66 in '56 compatibility mode.
.El
.Sh IMPLEMENTATION NOTES
When the
.Va NOARP
flag is set on the
.Nm
interface,
it does not employ the address resolution protocol described in
.Xr arp 4
to dynamically map between Internet and Ethernet addresses on
the local network.
Instead it uses the least significant 8 bits of the
.Tn IP
address as the hardware address
like described in
.Tn RFC
1051
and
.Tn RFC
1201.
.Pp
With the
.Dv IFF_LINK0
flag cleared
.Tn IP/ARP/RARP
encoding is done according to
.Tn RFC
1201
that is, with Packet Header Definition Standard header and packet type
212 / 213.
The
.Tn MTU
is normally 1500.
The
.Dv IFF_LINK0
flag is cleared by default.
.Pp
With the
.Dv IFF_LINK0
flag set,
.Tn IP
and
.Tn ARP
encoding is done according to the deprecated
.Tn RFC
1051 encoding, that is with simple header, packet type 240 / 241,
and the
.Tn MTU
is 507.
.Pp
When switching between the two modes, use
.Dl ifconfig interfacename down up
to switch the
.Tn MTU .
.Sh DIAGNOSTICS
The following driver specific error messages
may be reported:
.Bl -diag
.It "reset: card reset, link addr = 0x%02x (cm%d)"
The card is being reset and a new link address assigned.
.It "srint: restarted rx on buf cm%d"
The rx buffer has been emptied and will be reset.
.El
.Sh SEE ALSO
.Xr netintro 4 ,
.Xr watchdog 4 ,
.Xr device.hints 5 ,
.Xr ifconfig 8 ,
.Xr watchdog 8
.Sh HISTORY
The
.Nm
device was ported from
.Nx
by
.An Max Khon Aq Mt fjoe@FreeBSD.org
and first appeared in
.Fx 4.6 .
This manual page first appeared in
.Fx 5.3 .
.Sh AUTHORS
This manual page was written by
.An Tom Rhodes Aq Mt trhodes@FreeBSD.org .
The
.Sx IMPLEMENTATION NOTES
section was submitted by
.An Max Khon Aq Mt fjoe@FreeBSD.org
and originated from
.Nx .
.Sh BUGS
The
.Nm
driver code could do with a bit of improvement,
it would be nice if some one could come along and take care of this.
.Pp
The
.Sx IMPLEMENTATION NOTES
section is specific to all Arcnet
devices (see
.Pa sys/net/if_arcsubr.c )
and should be moved to a more generic location.

View File

@ -245,7 +245,6 @@ typedef struct {
# define ETHER_TYPE 1
# define EXP_ETHER_TYPE 2
# define IEEE_TYPE 6
# define ARCNET_TYPE 7
uint16_t HwAddrLen; /* Length of hardware address */
MAC_ADDR CurrentNodeAddress; /* Current hardware address */

View File

@ -845,9 +845,6 @@ device wlan_xauth
device wlan_acl
device wlan_amrr
# The `arcnet' device provides generic code to support Arcnet.
device arcnet
# The `sppp' device serves a similar role for certain types
# of synchronous PPP links (like `cx', `ar').
device sppp

View File

@ -1362,7 +1362,6 @@ dev/cfi/cfi_dev.c optional cfi
dev/cfi/cfi_disk.c optional cfid
dev/chromebook_platform/chromebook_platform.c optional chromebook_platform
dev/ciss/ciss.c optional ciss
dev/cm/smc90cx6.c optional cm
dev/cmx/cmx.c optional cmx
dev/cmx/cmx_pccard.c optional cmx pccard
dev/cpufreq/ichss.c optional cpufreq pci
@ -4127,7 +4126,6 @@ net/bridgestp.c optional bridge | if_bridge
net/flowtable.c optional flowtable inet | flowtable inet6
net/ieee8023ad_lacp.c optional lagg
net/if.c standard
net/if_arcsubr.c optional arcnet
net/if_bridge.c optional bridge inet | if_bridge inet
net/if_clone.c standard
net/if_dead.c standard

View File

@ -185,7 +185,6 @@ dev/ce/ceddk.c optional ce
dev/ce/if_ce.c optional ce
dev/ce/tau32-ddk.c optional ce \
compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}"
dev/cm/if_cm_isa.c optional cm isa
dev/coretemp/coretemp.c optional coretemp
dev/cp/cpddk.c optional cp
dev/cp/if_cp.c optional cp

View File

@ -1,166 +0,0 @@
/* $NetBSD: if_bah_zbus.c,v 1.6 2000/01/23 21:06:12 aymeric Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*-
* SPDX-License-Identifier: BSD-2-Clause-NetBSD
*
* Copyright (c) 1994, 1995, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Ignatios Souvatzis.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/socket.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_arc.h>
#include <dev/cm/smc90cx6reg.h>
#include <dev/cm/smc90cx6var.h>
static int cm_isa_probe (device_t);
static int cm_isa_attach (device_t);
static int
cm_isa_probe(dev)
device_t dev;
{
struct cm_softc *sc = device_get_softc(dev);
int rid;
rid = 0;
sc->port_res = bus_alloc_resource_anywhere(
dev, SYS_RES_IOPORT, &rid, CM_IO_PORTS, RF_ACTIVE);
if (sc->port_res == NULL)
return (ENOENT);
if (GETREG(CMSTAT) == 0xff) {
cm_release_resources(dev);
return (ENXIO);
}
rid = 0;
sc->mem_res = bus_alloc_resource_anywhere(
dev, SYS_RES_MEMORY, &rid, CM_MEM_SIZE, RF_ACTIVE);
if (sc->mem_res == NULL) {
cm_release_resources(dev);
return (ENOENT);
}
rid = 0;
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
if (sc->irq_res == NULL) {
cm_release_resources(dev);
return (ENOENT);
}
return (0);
}
static int
cm_isa_attach(dev)
device_t dev;
{
struct cm_softc *sc = device_get_softc(dev);
int error;
/* init mtx and setup interrupt */
mtx_init(&sc->sc_mtx, device_get_nameunit(dev),
MTX_NETWORK_LOCK, MTX_DEF);
error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
NULL, cmintr, sc, &sc->irq_handle);
if (error)
goto err;
/* attach */
error = cm_attach(dev);
if (error)
goto err;
gone_in_dev(dev, 12, "cm(4) driver");
return 0;
err:
mtx_destroy(&sc->sc_mtx);
cm_release_resources(dev);
return (error);
}
static int
cm_isa_detach(device_t dev)
{
struct cm_softc *sc = device_get_softc(dev);
struct ifnet *ifp = sc->sc_ifp;
/* stop and detach */
CM_LOCK(sc);
cm_stop_locked(sc);
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
CM_UNLOCK(sc);
callout_drain(&sc->sc_recon_ch);
arc_ifdetach(ifp);
/* teardown interrupt, destroy mtx and release resources */
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
mtx_destroy(&sc->sc_mtx);
if_free(ifp);
cm_release_resources(dev);
bus_generic_detach(dev);
return (0);
}
static device_method_t cm_isa_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, cm_isa_probe),
DEVMETHOD(device_attach, cm_isa_attach),
DEVMETHOD(device_detach, cm_isa_detach),
{ 0, 0 }
};
static driver_t cm_isa_driver = {
"cm",
cm_isa_methods,
sizeof(struct cm_softc)
};
DRIVER_MODULE(cm, isa, cm_isa_driver, cm_devclass, 0, 0);
MODULE_DEPEND(cm, isa, 1, 1, 1);

View File

@ -1,926 +0,0 @@
/* $NetBSD: smc90cx6.c,v 1.38 2001/07/07 15:57:53 thorpej Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*-
* SPDX-License-Identifier: BSD-2-Clause-NetBSD
*
* Copyright (c) 1994, 1995, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Ignatios Souvatzis.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Chip core driver for the SMC90c26 / SMC90c56 (and SMC90c66 in '56
* compatibility mode) boards
*/
/* #define CMSOFTCOPY */
#define CMRETRANSMIT /**/
/* #define CM_DEBUG */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/syslog.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/if_arc.h>
#include <dev/cm/smc90cx6reg.h>
#include <dev/cm/smc90cx6var.h>
MODULE_DEPEND(if_cm, arcnet, 1, 1, 1);
/* these should be elsewhere */
#define ARC_MIN_LEN 1
#define ARC_MIN_FORBID_LEN 254
#define ARC_MAX_FORBID_LEN 256
#define ARC_MAX_LEN 508
#define ARC_ADDR_LEN 1
/* for watchdog timer. This should be more than enough. */
#define ARCTIMEOUT (5*IFNET_SLOWHZ)
devclass_t cm_devclass;
/*
* This currently uses 2 bufs for tx, 2 for rx
*
* New rx protocol:
*
* rx has a fillcount variable. If fillcount > (NRXBUF-1),
* rx can be switched off from rx hard int.
* Else rx is restarted on the other receiver.
* rx soft int counts down. if it is == (NRXBUF-1), it restarts
* the receiver.
* To ensure packet ordering (we need that for 1201 later), we have a counter
* which is incremented modulo 256 on each receive and a per buffer
* variable, which is set to the counter on filling. The soft int can
* compare both values to determine the older packet.
*
* Transmit direction:
*
* cm_start checks tx_fillcount
* case 2: return
*
* else fill tx_act ^ 1 && inc tx_fillcount
*
* check tx_fillcount again.
* case 2: set IFF_DRV_OACTIVE to stop arc_output from filling us.
* case 1: start tx
*
* tint clears IFF_OACTIVE, decrements and checks tx_fillcount
* case 1: start tx on tx_act ^ 1, softcall cm_start
* case 0: softcall cm_start
*
* #define fill(i) get mbuf && copy mbuf to chip(i)
*/
void cm_init(void *);
static void cm_init_locked(struct cm_softc *);
static void cm_reset_locked(struct cm_softc *);
void cm_start(struct ifnet *);
void cm_start_locked(struct ifnet *);
int cm_ioctl(struct ifnet *, unsigned long, caddr_t);
void cm_watchdog(void *);
void cm_srint_locked(void *vsc);
static void cm_tint_locked(struct cm_softc *, int);
void cm_reconwatch_locked(void *);
/*
* Release all resources
*/
void
cm_release_resources(dev)
device_t dev;
{
struct cm_softc *sc = device_get_softc(dev);
if (sc->port_res != NULL) {
bus_release_resource(dev, SYS_RES_IOPORT,
0, sc->port_res);
sc->port_res = NULL;
}
if (sc->mem_res != NULL) {
bus_release_resource(dev, SYS_RES_MEMORY,
0, sc->mem_res);
sc->mem_res = NULL;
}
if (sc->irq_res != NULL) {
bus_release_resource(dev, SYS_RES_IRQ,
0, sc->irq_res);
sc->irq_res = NULL;
}
}
int
cm_attach(dev)
device_t dev;
{
struct cm_softc *sc = device_get_softc(dev);
struct ifnet *ifp;
u_int8_t linkaddress;
ifp = sc->sc_ifp = if_alloc(IFT_ARCNET);
if (ifp == NULL)
return (ENOSPC);
/*
* read the arcnet address from the board
*/
GETREG(CMRESET);
do {
DELAY(200);
} while (!(GETREG(CMSTAT) & CM_POR));
linkaddress = GETMEM(CMMACOFF);
/* clear the int mask... */
sc->sc_intmask = 0;
PUTREG(CMSTAT, 0);
PUTREG(CMCMD, CM_CONF(CONF_LONG));
PUTREG(CMCMD, CM_CLR(CLR_POR|CLR_RECONFIG));
sc->sc_recontime = sc->sc_reconcount = 0;
/*
* set interface to stopped condition (reset)
*/
cm_stop_locked(sc);
ifp->if_softc = sc;
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_output = arc_output;
ifp->if_start = cm_start;
ifp->if_ioctl = cm_ioctl;
ifp->if_init = cm_init;
/* XXX IFQ_SET_READY(&ifp->if_snd); */
ifp->if_snd.ifq_maxlen = ifqmaxlen;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
arc_ifattach(ifp, linkaddress);
#ifdef CMSOFTCOPY
sc->sc_rxcookie = softintr_establish(IPL_SOFTNET, cm_srint, sc);
sc->sc_txcookie = softintr_establish(IPL_SOFTNET,
(void (*)(void *))cm_start, ifp);
#endif
callout_init_mtx(&sc->sc_recon_ch, &sc->sc_mtx, 0);
callout_init_mtx(&sc->sc_watchdog_timer, &sc->sc_mtx, 0);
if_printf(ifp, "link addr 0x%02x (%d)\n", linkaddress, linkaddress);
return 0;
}
/*
* Initialize device
*
*/
void
cm_init(xsc)
void *xsc;
{
struct cm_softc *sc = (struct cm_softc *)xsc;
CM_LOCK(sc);
cm_init_locked(sc);
CM_UNLOCK(sc);
}
static void
cm_init_locked(struct cm_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
ifp->if_drv_flags |= IFF_DRV_RUNNING;
cm_reset_locked(sc);
}
}
/*
* Reset the interface...
*
* Assumes that it is called with sc_mtx held
*/
void
cm_reset_locked(sc)
struct cm_softc *sc;
{
struct ifnet *ifp;
int linkaddress;
ifp = sc->sc_ifp;
#ifdef CM_DEBUG
if_printf(ifp, "reset\n");
#endif
/* stop and restart hardware */
GETREG(CMRESET);
do {
DELAY(200);
} while (!(GETREG(CMSTAT) & CM_POR));
linkaddress = GETMEM(CMMACOFF);
#if defined(CM_DEBUG) && (CM_DEBUG > 2)
if_printf(ifp, "reset: card reset, link addr = 0x%02x (%d)\n",
linkaddress, linkaddress);
#endif
/* tell the routing level about the (possibly changed) link address */
arc_storelladdr(ifp, linkaddress);
arc_frag_init(ifp);
/* POR is NMI, but we need it below: */
sc->sc_intmask = CM_RECON|CM_POR;
PUTREG(CMSTAT, sc->sc_intmask);
PUTREG(CMCMD, CM_CONF(CONF_LONG));
#ifdef CM_DEBUG
if_printf(ifp, "reset: chip configured, status=0x%02x\n",
GETREG(CMSTAT));
#endif
PUTREG(CMCMD, CM_CLR(CLR_POR|CLR_RECONFIG));
#ifdef CM_DEBUG
if_printf(ifp, "reset: bits cleared, status=0x%02x\n",
GETREG(CMSTAT));
#endif
sc->sc_reconcount_excessive = ARC_EXCESSIVE_RECONS;
/* start receiver */
sc->sc_intmask |= CM_RI;
sc->sc_rx_fillcount = 0;
sc->sc_rx_act = 2;
PUTREG(CMCMD, CM_RXBC(2));
PUTREG(CMSTAT, sc->sc_intmask);
#ifdef CM_DEBUG
if_printf(ifp, "reset: started receiver, status=0x%02x\n",
GETREG(CMSTAT));
#endif
/* and init transmitter status */
sc->sc_tx_act = 0;
sc->sc_tx_fillcount = 0;
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
callout_reset(&sc->sc_watchdog_timer, hz, cm_watchdog, sc);
cm_start_locked(ifp);
}
/*
* Take interface offline
*/
void
cm_stop_locked(sc)
struct cm_softc *sc;
{
/* Stop the interrupts */
PUTREG(CMSTAT, 0);
/* Stop the interface */
GETREG(CMRESET);
/* Stop watchdog timer */
callout_stop(&sc->sc_watchdog_timer);
sc->sc_timer = 0;
}
void
cm_start(struct ifnet *ifp)
{
struct cm_softc *sc = ifp->if_softc;
CM_LOCK(sc);
cm_start_locked(ifp);
CM_UNLOCK(sc);
}
/*
* Start output on interface. Get another datagram to send
* off the interface queue, and copy it to the
* interface becore starting the output
*
* Assumes that sc_mtx is held
*/
void
cm_start_locked(ifp)
struct ifnet *ifp;
{
struct cm_softc *sc = ifp->if_softc;
struct mbuf *m, *mp;
int cm_ram_ptr;
int len, tlen, offset, buffer;
#ifdef CMTIMINGS
u_long copystart, lencopy, perbyte;
#endif
#if defined(CM_DEBUG) && (CM_DEBUG > 3)
if_printf(ifp, "start(%p)\n", ifp);
#endif
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
return;
if (sc->sc_tx_fillcount >= 2)
return;
m = arc_frag_next(ifp);
buffer = sc->sc_tx_act ^ 1;
if (m == NULL)
return;
#ifdef CM_DEBUG
if (m->m_len < ARC_HDRLEN)
m = m_pullup(m, ARC_HDRLEN);/* gcc does structure padding */
if_printf(ifp, "start: filling %d from %d to %d type %d\n",
buffer, mtod(m, u_char *)[0],
mtod(m, u_char *)[1], mtod(m, u_char *)[2]);
#else
if (m->m_len < 2)
m = m_pullup(m, 2);
#endif
cm_ram_ptr = buffer * 512;
if (m == NULL)
return;
/* write the addresses to RAM and throw them away */
/*
* Hardware does this: Yet Another Microsecond Saved.
* (btw, timing code says usually 2 microseconds)
* PUTMEM(cm_ram_ptr + 0, mtod(m, u_char *)[0]);
*/
PUTMEM(cm_ram_ptr + 1, mtod(m, u_char *)[1]);
m_adj(m, 2);
/* get total length left at this point */
tlen = m->m_pkthdr.len;
if (tlen < ARC_MIN_FORBID_LEN) {
offset = 256 - tlen;
PUTMEM(cm_ram_ptr + 2, offset);
} else {
PUTMEM(cm_ram_ptr + 2, 0);
if (tlen <= ARC_MAX_FORBID_LEN)
offset = 255; /* !!! */
else {
if (tlen > ARC_MAX_LEN)
tlen = ARC_MAX_LEN;
offset = 512 - tlen;
}
PUTMEM(cm_ram_ptr + 3, offset);
}
cm_ram_ptr += offset;
/* lets loop through the mbuf chain */
for (mp = m; mp; mp = mp->m_next) {
if ((len = mp->m_len)) { /* YAMS */
bus_space_write_region_1(
rman_get_bustag(sc->mem_res),
rman_get_bushandle(sc->mem_res),
cm_ram_ptr, mtod(mp, caddr_t), len);
cm_ram_ptr += len;
}
}
sc->sc_broadcast[buffer] = (m->m_flags & M_BCAST) != 0;
sc->sc_retransmits[buffer] = (m->m_flags & M_BCAST) ? 1 : 5;
if (++sc->sc_tx_fillcount > 1) {
/*
* We are filled up to the rim. No more bufs for the moment,
* please.
*/
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
} else {
#ifdef CM_DEBUG
if_printf(ifp, "start: starting transmitter on buffer %d\n",
buffer);
#endif
/* Transmitter was off, start it */
sc->sc_tx_act = buffer;
/*
* We still can accept another buf, so don't:
* ifp->if_drv_flags |= IFF_DRV_OACTIVE;
*/
sc->sc_intmask |= CM_TA;
PUTREG(CMCMD, CM_TX(buffer));
PUTREG(CMSTAT, sc->sc_intmask);
sc->sc_timer = ARCTIMEOUT;
}
m_freem(m);
/*
* After 10 times reading the docs, I realized
* that in the case the receiver NAKs the buffer request,
* the hardware retries till shutdown.
* This is integrated now in the code above.
*/
}
#ifdef CMSOFTCOPY
void
cm_srint(void *vsc)
{
struct cm_softc *sc = (struct cm_softc *)vsc;
CM_LOCK(sc);
cm_srint_locked(vsc);
CM_UNLOCK(sc);
}
#endif
/*
* Arcnet interface receiver soft interrupt:
* get the stuff out of any filled buffer we find.
*/
void
cm_srint_locked(vsc)
void *vsc;
{
struct cm_softc *sc = (struct cm_softc *)vsc;
int buffer, len, offset, type;
int cm_ram_ptr;
struct mbuf *m;
struct arc_header *ah;
struct ifnet *ifp;
ifp = sc->sc_ifp;
buffer = sc->sc_rx_act ^ 1;
/* Allocate header mbuf */
MGETHDR(m, M_NOWAIT, MT_DATA);
if (m == NULL) {
/*
* in case s.th. goes wrong with mem, drop it
* to make sure the receiver can be started again
* count it as input error (we dont have any other
* detectable)
*/
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto cleanup;
}
m->m_pkthdr.rcvif = ifp;
/*
* Align so that IP packet will be longword aligned. Here we
* assume that m_data of new packet is longword aligned.
* When implementing PHDS, we might have to change it to 2,
* (2*sizeof(ulong) - CM_HDRNEWLEN)), packet type dependent.
*/
cm_ram_ptr = buffer * 512;
offset = GETMEM(cm_ram_ptr + 2);
if (offset)
len = 256 - offset;
else {
offset = GETMEM(cm_ram_ptr + 3);
len = 512 - offset;
}
/*
* first +2 bytes for align fixup below
* second +2 bytes are for src/dst addresses
*/
if ((len + 2 + 2) > MHLEN) {
/* attach an mbuf cluster */
if (!(MCLGET(m, M_NOWAIT))) {
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto cleanup;
}
}
if (m == NULL) {
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto cleanup;
}
type = GETMEM(cm_ram_ptr + offset);
m->m_data += 1 + arc_isphds(type);
/* mbuf filled with ARCnet addresses */
m->m_pkthdr.len = m->m_len = len + 2;
ah = mtod(m, struct arc_header *);
ah->arc_shost = GETMEM(cm_ram_ptr + 0);
ah->arc_dhost = GETMEM(cm_ram_ptr + 1);
bus_space_read_region_1(
rman_get_bustag(sc->mem_res), rman_get_bushandle(sc->mem_res),
cm_ram_ptr + offset, mtod(m, u_char *) + 2, len);
CM_UNLOCK(sc);
arc_input(ifp, m);
CM_LOCK(sc);
m = NULL;
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
cleanup:
if (m != NULL)
m_freem(m);
/* mark buffer as invalid by source id 0 */
PUTMEM(buffer << 9, 0);
if (--sc->sc_rx_fillcount == 2 - 1) {
/* was off, restart it on buffer just emptied */
sc->sc_rx_act = buffer;
sc->sc_intmask |= CM_RI;
/* this also clears the RI flag interrupt: */
PUTREG(CMCMD, CM_RXBC(buffer));
PUTREG(CMSTAT, sc->sc_intmask);
#ifdef CM_DEBUG
if_printf(ifp, "srint: restarted rx on buf %d\n", buffer);
#endif
}
}
static inline void
cm_tint_locked(sc, isr)
struct cm_softc *sc;
int isr;
{
struct ifnet *ifp;
int buffer;
#ifdef CMTIMINGS
int clknow;
#endif
ifp = sc->sc_ifp;
buffer = sc->sc_tx_act;
/*
* retransmit code:
* Normal situtations first for fast path:
* If acknowledgement received ok or broadcast, we're ok.
* else if
*/
if (isr & CM_TMA || sc->sc_broadcast[buffer])
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
#ifdef CMRETRANSMIT
else if (ifp->if_flags & IFF_LINK2 && sc->sc_timer > 0
&& --sc->sc_retransmits[buffer] > 0) {
/* retransmit same buffer */
PUTREG(CMCMD, CM_TX(buffer));
return;
}
#endif
else
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
/* We know we can accept another buffer at this point. */
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
if (--sc->sc_tx_fillcount > 0) {
/*
* start tx on other buffer.
* This also clears the int flag
*/
buffer ^= 1;
sc->sc_tx_act = buffer;
/*
* already given:
* sc->sc_intmask |= CM_TA;
* PUTREG(CMSTAT, sc->sc_intmask);
*/
PUTREG(CMCMD, CM_TX(buffer));
/* init watchdog timer */
sc->sc_timer = ARCTIMEOUT;
#if defined(CM_DEBUG) && (CM_DEBUG > 1)
if_printf(ifp,
"tint: starting tx on buffer %d, status 0x%02x\n",
buffer, GETREG(CMSTAT));
#endif
} else {
/* have to disable TX interrupt */
sc->sc_intmask &= ~CM_TA;
PUTREG(CMSTAT, sc->sc_intmask);
/* ... and watchdog timer */
sc->sc_timer = 0;
#ifdef CM_DEBUG
if_printf(ifp, "tint: no more buffers to send, status 0x%02x\n",
GETREG(CMSTAT));
#endif
}
/* XXXX TODO */
#ifdef CMSOFTCOPY
/* schedule soft int to fill a new buffer for us */
softintr_schedule(sc->sc_txcookie);
#else
/* call it directly */
cm_start_locked(ifp);
#endif
}
/*
* Our interrupt routine
*/
void
cmintr(arg)
void *arg;
{
struct cm_softc *sc = arg;
struct ifnet *ifp = sc->sc_ifp;
u_char isr, maskedisr;
int buffer;
u_long newsec;
CM_LOCK(sc);
isr = GETREG(CMSTAT);
maskedisr = isr & sc->sc_intmask;
if (!maskedisr || (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
CM_UNLOCK(sc);
return;
}
do {
#if defined(CM_DEBUG) && (CM_DEBUG > 1)
if_printf(ifp, "intr: status 0x%02x, intmask 0x%02x\n",
isr, sc->sc_intmask);
#endif
if (maskedisr & CM_POR) {
/*
* XXX We should never see this. Don't bother to store
* the address.
* sc->sc_ifp->if_l2com->ac_anaddr = GETMEM(CMMACOFF);
*/
PUTREG(CMCMD, CM_CLR(CLR_POR));
log(LOG_WARNING,
"%s: intr: got spurious power on reset int\n",
ifp->if_xname);
}
if (maskedisr & CM_RECON) {
/*
* we dont need to:
* PUTREG(CMCMD, CM_CONF(CONF_LONG));
*/
PUTREG(CMCMD, CM_CLR(CLR_RECONFIG));
if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 1);
/*
* If less than 2 seconds per reconfig:
* If ARC_EXCESSIVE_RECONFIGS
* since last burst, complain and set treshold for
* warnings to ARC_EXCESSIVE_RECONS_REWARN.
*
* This allows for, e.g., new stations on the cable, or
* cable switching as long as it is over after
* (normally) 16 seconds.
*
* XXX TODO: check timeout bits in status word and
* double time if necessary.
*/
callout_stop(&sc->sc_recon_ch);
newsec = time_second;
if ((newsec - sc->sc_recontime <= 2) &&
(++sc->sc_reconcount == ARC_EXCESSIVE_RECONS)) {
log(LOG_WARNING,
"%s: excessive token losses, "
"cable problem?\n",
ifp->if_xname);
}
sc->sc_recontime = newsec;
callout_reset(&sc->sc_recon_ch, 15 * hz,
cm_reconwatch_locked, (void *)sc);
}
if (maskedisr & CM_RI) {
#if defined(CM_DEBUG) && (CM_DEBUG > 1)
if_printf(ifp, "intr: hard rint, act %d\n",
sc->sc_rx_act);
#endif
buffer = sc->sc_rx_act;
/* look if buffer is marked invalid: */
if (GETMEM(buffer * 512) == 0) {
/*
* invalid marked buffer (or illegally
* configured sender)
*/
log(LOG_WARNING,
"%s: spurious RX interrupt or sender 0 "
" (ignored)\n", ifp->if_xname);
/*
* restart receiver on same buffer.
* XXX maybe better reset interface?
*/
PUTREG(CMCMD, CM_RXBC(buffer));
} else {
if (++sc->sc_rx_fillcount > 1) {
sc->sc_intmask &= ~CM_RI;
PUTREG(CMSTAT, sc->sc_intmask);
} else {
buffer ^= 1;
sc->sc_rx_act = buffer;
/*
* Start receiver on other receive
* buffer. This also clears the RI
* interrupt flag.
*/
PUTREG(CMCMD, CM_RXBC(buffer));
/* in RX intr, so mask is ok for RX */
#ifdef CM_DEBUG
if_printf(ifp, "strt rx for buf %d, "
"stat 0x%02x\n",
sc->sc_rx_act, GETREG(CMSTAT));
#endif
}
#ifdef CMSOFTCOPY
/*
* this one starts a soft int to copy out
* of the hw
*/
softintr_schedule(sc->sc_rxcookie);
#else
/* this one does the copy here */
cm_srint_locked(sc);
#endif
}
}
if (maskedisr & CM_TA) {
cm_tint_locked(sc, isr);
}
isr = GETREG(CMSTAT);
maskedisr = isr & sc->sc_intmask;
} while (maskedisr);
#if defined(CM_DEBUG) && (CM_DEBUG > 1)
if_printf(ifp, "intr (exit): status 0x%02x, intmask 0x%02x\n",
isr, sc->sc_intmask);
#endif
CM_UNLOCK(sc);
}
void
cm_reconwatch_locked(arg)
void *arg;
{
struct cm_softc *sc = arg;
struct ifnet *ifp = sc->sc_ifp;
if (sc->sc_reconcount >= ARC_EXCESSIVE_RECONS) {
sc->sc_reconcount = 0;
log(LOG_WARNING, "%s: token valid again.\n",
ifp->if_xname);
}
sc->sc_reconcount = 0;
}
/*
* Process an ioctl request.
* This code needs some work - it looks pretty ugly.
*/
int
cm_ioctl(ifp, command, data)
struct ifnet *ifp;
u_long command;
caddr_t data;
{
struct cm_softc *sc;
int error;
error = 0;
sc = ifp->if_softc;
#if defined(CM_DEBUG) && (CM_DEBUG > 2)
if_printf(ifp, "ioctl() called, cmd = 0x%lx\n", command);
#endif
switch (command) {
case SIOCSIFADDR:
case SIOCGIFADDR:
case SIOCADDMULTI:
case SIOCDELMULTI:
case SIOCSIFMTU:
error = arc_ioctl(ifp, command, data);
break;
case SIOCSIFFLAGS:
CM_LOCK(sc);
if ((ifp->if_flags & IFF_UP) == 0 &&
(ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
/*
* If interface is marked down and it is running,
* then stop it.
*/
cm_stop_locked(sc);
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
} else if ((ifp->if_flags & IFF_UP) != 0 &&
(ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
/*
* If interface is marked up and it is stopped, then
* start it.
*/
cm_init_locked(sc);
}
CM_UNLOCK(sc);
break;
default:
error = EINVAL;
break;
}
return (error);
}
/*
* watchdog routine for transmitter.
*
* We need this, because else a receiver whose hardware is alive, but whose
* software has not enabled the Receiver, would make our hardware wait forever
* Discovered this after 20 times reading the docs.
*
* Only thing we do is disable transmitter. We'll get a transmit timeout,
* and the int handler will have to decide not to retransmit (in case
* retransmission is implemented).
*/
void
cm_watchdog(void *arg)
{
struct cm_softc *sc;
sc = arg;
callout_reset(&sc->sc_watchdog_timer, hz, cm_watchdog, sc);
if (sc->sc_timer == 0 || --sc->sc_timer > 0)
return;
PUTREG(CMCMD, CM_TXDIS);
}

View File

@ -1,87 +0,0 @@
/* $NetBSD: smc90cx6reg.h,v 1.7 1999/02/16 23:34:13 is Exp $ */
/* $FreeBSD$ */
/*-
* SPDX-License-Identifier: BSD-2-Clause-NetBSD
*
* Copyright (c) 1994, 1995, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Ignatios Souvatzis.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* chip offsets and bits for the SMC Arcnet chipset.
*/
#ifndef _SMC90CXVAR_H_
#define _SMC90CXVAR_H_
#define CM_IO_PORTS 16
#define CM_MEM_SIZE 0x800
/* register offsets */
#define CMSTAT 0
#define CMCMD 1
#define CMRESET 8
/* memory offsets */
#define CMCHECKBYTE 0
#define CMMACOFF 1
#define CM_TXDIS 0x01
#define CM_RXDIS 0x02
#define CM_TX(x) (0x03 | ((x)<<3))
#define CM_RX(x) (0x04 | ((x)<<3))
#define CM_RXBC(x) (0x84 | ((x)<<3))
#define CM_CONF(x) (0x05 | (x))
#define CLR_POR 0x08
#define CLR_RECONFIG 0x10
#define CM_CLR(x) (0x06 | (x))
#define CONF_LONG 0x08
#define CONF_SHORT 0x00
/*
* These are not in the COM90C65 docs. Derived from the arcnet.asm
* packet driver by Philippe Prindeville and Russel Nelson.
*/
#define CM_LDTST(x) (0x07 | (x))
#define TEST_ON 0x08
#define TEST_OFF 0x00
#define CM_TA 1 /* int mask also */
#define CM_TMA 2
#define CM_RECON 4 /* int mask also */
#define CM_TEST 8 /* not in the COM90C65 docs (see above) */
#define CM_POR 0x10 /* non maskable interrupt */
#define CM_ET1 0x20 /* timeout value bits, normally 1 */
#define CM_ET2 0x40 /* timeout value bits, normally 1 */
#define CM_RI 0x80 /* int mask also */
#endif

View File

@ -1,114 +0,0 @@
/* $NetBSD: smc90cx6var.h,v 1.5 2000/03/23 07:01:32 thorpej Exp $ */
/* $FreeBSD$ */
/*-
* SPDX-License-Identifier: BSD-2-Clause-NetBSD
*
* Copyright (c) 1994, 1995, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Ignatios Souvatzis.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* BAH (SMC 8bit ARCnet chipset) k/dpi
*
* The SMC 8bit ARCnet chip family uses a register and a memory window, which
* we get passed via bus_space_tags and bus_space_handles.
*
* As the reset functionality differs between the Amiga boards (using the
* 90c26 chip) and middle-aged ISA boards (using the 90c56 chip), we have
* a sc_reset callback function in the softc, which does a stop function
* (reset and leave dead) or a reset function depending on wether the 2nd
* parameter is 0 or 1.
*/
#ifndef _SMC90CX6VAR_H_
#define _SMC90CX6VAR_H_
#include <sys/callout.h>
struct cm_softc {
struct ifnet *sc_ifp; /* Common arcnet structures */
struct mtx sc_mtx; /* sc mutex */
int port_rid; /* resource id for port range */
struct resource *port_res; /* resource for port range */
int mem_rid; /* resource id for memory range */
struct resource *mem_res; /* resource for memory range */
int irq_rid; /* resource id for irq */
struct resource *irq_res; /* resource for irq */
void * irq_handle; /* handle for irq handler */
void *sc_rxcookie; /* softcallback cookies */
void *sc_txcookie;
struct callout sc_recon_ch;
u_long sc_recontime; /* seconds only, I'm lazy */
u_long sc_reconcount; /* for the above */
u_long sc_reconcount_excessive; /* for the above */
#define ARC_EXCESSIVE_RECONS 20
#define ARC_EXCESSIVE_RECONS_REWARN 400
struct callout sc_watchdog_timer;
int sc_timer;
u_char sc_intmask;
u_char sc_rx_act; /* 2..3 */
u_char sc_tx_act; /* 0..1 */
u_char sc_rx_fillcount;
u_char sc_tx_fillcount;
u_char sc_broadcast[2]; /* is it a broadcast packet? */
u_char sc_retransmits[2]; /* unused at the moment */
};
int cm_attach(device_t dev);
void cmintr(void *);
void cm_stop_locked(struct cm_softc *sc);
void cm_release_resources(device_t dev);
extern devclass_t cm_devclass;
#define CM_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
#define CM_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
/* short notation */
#define GETREG(off) \
bus_space_read_1(rman_get_bustag((sc)->port_res), \
rman_get_bushandle((sc)->port_res), \
(off))
#define PUTREG(off, value) \
bus_space_write_1(rman_get_bustag((sc)->port_res), \
rman_get_bushandle((sc)->port_res), \
(off), (value))
#define GETMEM(off) \
bus_space_read_1(rman_get_bustag((sc)->mem_res), \
rman_get_bushandle((sc)->mem_res), \
(off))
#define PUTMEM(off, value) \
bus_space_write_1(rman_get_bustag((sc)->mem_res), \
rman_get_bushandle((sc)->mem_res), \
(off), (value))
#endif

View File

@ -42,7 +42,6 @@ SUBDIR= \
${_aout} \
${_apm} \
${_arcmsr} \
${_arcnet} \
${_armv8crypto} \
${_asmc} \
ata \
@ -92,7 +91,6 @@ SUBDIR= \
cloudabi \
${_cloudabi32} \
${_cloudabi64} \
${_cm} \
${_cmx} \
${_coff} \
${_coretemp} \
@ -744,7 +742,6 @@ _3dfx= 3dfx
_3dfx_linux= 3dfx_linux
_aic= aic
_apm= apm
_arcnet= arcnet
.if ${MK_SOURCELESS_UCODE} != "no"
_ce= ce
.endif
@ -763,7 +760,6 @@ _pcfclock= pcfclock
_pst= pst
_sbni= sbni
_stg= stg
_cm= cm
.if ${MK_SOURCELESS_UCODE} != "no"
_ctau= ctau
.endif

View File

@ -1,19 +0,0 @@
# $FreeBSD$
.PATH: ${SRCTOP}/sys/net
KMOD= arcnet
SRCS= if_arcsubr.c
SRCS+= opt_inet.h opt_inet6.h opt_ofed.h
EXPORT_SYMS= arc_frag_init \
arc_frag_next \
arc_ifattach \
arc_ifdetach \
arc_input \
arc_ioctl \
arc_isphds \
arc_output \
arc_storelladdr
.include <bsd.kmod.mk>

View File

@ -1,10 +0,0 @@
# $FreeBSD$
.PATH: ${SRCTOP}/sys/dev/cm
KMOD= if_cm
SRCS= smc90cx6.c if_cm_isa.c
SRCS+= bus_if.h device_if.h isa_if.h
.include <bsd.kmod.mk>

View File

@ -3695,7 +3695,6 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
case IFT_XETHER:
case IFT_L2VLAN:
case IFT_BRIDGE:
case IFT_ARCNET:
case IFT_IEEE8023ADLAG:
bcopy(lladdr, LLADDR(sdl), len);
ifa_free(ifa);

View File

@ -1,145 +0,0 @@
/* $NetBSD: if_arc.h,v 1.13 1999/11/19 20:41:19 thorpej Exp $ */
/* $FreeBSD$ */
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* 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. 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: NetBSD: if_ether.h,v 1.10 1994/06/29 06:37:55 cgd Exp
* @(#)if_ether.h 8.1 (Berkeley) 6/10/93
*/
#ifndef _NET_IF_ARC_H_
#define _NET_IF_ARC_H_
/*
* Arcnet address - 1 octets
* don't know who uses this.
*/
struct arc_addr {
u_int8_t arc_addr_octet[1];
} __packed;
/*
* Structure of a 2.5MB/s Arcnet header.
* as given to interface code.
*/
struct arc_header {
u_int8_t arc_shost;
u_int8_t arc_dhost;
u_int8_t arc_type;
/*
* only present for newstyle encoding with LL fragmentation.
* Don't use sizeof(anything), use ARC_HDR{,NEW}LEN instead.
*/
u_int8_t arc_flag;
u_int16_t arc_seqid;
/*
* only present in exception packets (arc_flag == 0xff)
*/
u_int8_t arc_type2; /* same as arc_type */
u_int8_t arc_flag2; /* real flag value */
u_int16_t arc_seqid2; /* real seqid value */
} __packed;
#define ARC_ADDR_LEN 1
#define ARC_HDRLEN 3
#define ARC_HDRNEWLEN 6
#define ARC_HDRNEWLEN_EXC 10
/* these lengths are data link layer length - 2 * ARC_ADDR_LEN */
#define ARC_MIN_LEN 1
#define ARC_MIN_FORBID_LEN 254
#define ARC_MAX_FORBID_LEN 256
#define ARC_MAX_LEN 508
#define ARC_MAX_DATA 504
/* RFC 1051 */
#define ARCTYPE_IP_OLD 240 /* IP protocol */
#define ARCTYPE_ARP_OLD 241 /* address resolution protocol */
/* RFC 1201 */
#define ARCTYPE_IP 212 /* IP protocol */
#define ARCTYPE_ARP 213 /* address resolution protocol */
#define ARCTYPE_REVARP 214 /* reverse addr resolution protocol */
#define ARCTYPE_ATALK 221 /* Appletalk */
#define ARCTYPE_BANIAN 247 /* Banyan Vines */
#define ARCTYPE_IPX 250 /* Novell IPX */
#define ARCTYPE_INET6 0xc4 /* IPng */
#define ARCTYPE_DIAGNOSE 0x80 /* as per ANSI/ATA 878.1 */
#define ARCMTU 507
#define ARCMIN 0
#define ARC_PHDS_MAXMTU 60480
struct arccom {
struct ifnet *ac_ifp; /* network-visible interface */
u_int16_t ac_seqid; /* seq. id used by PHDS encap. */
u_int8_t arc_shost;
u_int8_t arc_dhost;
u_int8_t arc_type;
u_int8_t dummy0;
u_int16_t dummy1;
int sflag, fsflag, rsflag;
struct mbuf *curr_frag;
struct ac_frag {
u_int8_t af_maxflag; /* from first packet */
u_int8_t af_lastseen; /* last split flag seen */
u_int16_t af_seqid;
struct mbuf *af_packet;
} ac_fragtab[256]; /* indexed by sender ll address */
};
#ifdef _KERNEL
extern u_int8_t arcbroadcastaddr;
extern int arc_ipmtu; /* XXX new ip only, no RFC 1051! */
void arc_ifattach(struct ifnet *, u_int8_t);
void arc_ifdetach(struct ifnet *);
void arc_storelladdr(struct ifnet *, u_int8_t);
int arc_isphds(u_int8_t);
void arc_input(struct ifnet *, struct mbuf *);
int arc_output(struct ifnet *, struct mbuf *,
const struct sockaddr *, struct route *);
int arc_ioctl(struct ifnet *, u_long, caddr_t);
void arc_frag_init(struct ifnet *);
struct mbuf * arc_frag_next(struct ifnet *);
#endif
#endif /* _NET_IF_ARC_H_ */

View File

@ -1,831 +0,0 @@
/* $NetBSD: if_arcsubr.c,v 1.36 2001/06/14 05:44:23 itojun Exp $ */
/* $FreeBSD$ */
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 1994, 1995 Ignatios Souvatzis
* 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: NetBSD: if_ethersubr.c,v 1.9 1994/06/29 06:36:11 cgd Exp
* @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93
*
*/
#include "opt_inet.h"
#include "opt_inet6.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/errno.h>
#include <sys/syslog.h>
#include <machine/cpu.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/netisr.h>
#include <net/route.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/if_arc.h>
#include <net/if_arp.h>
#include <net/bpf.h>
#include <net/if_llatbl.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
#define ARCNET_ALLOW_BROKEN_ARP
static struct mbuf *arc_defrag(struct ifnet *, struct mbuf *);
static int arc_resolvemulti(struct ifnet *, struct sockaddr **,
struct sockaddr *);
u_int8_t arcbroadcastaddr = 0;
#define ARC_LLADDR(ifp) (*(u_int8_t *)IF_LLADDR(ifp))
#define senderr(e) { error = (e); goto bad;}
#define SIN(s) ((const struct sockaddr_in *)(s))
/*
* ARCnet output routine.
* Encapsulate a packet of type family for the local net.
* Assumes that ifp is actually pointer to arccom structure.
*/
int
arc_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
struct route *ro)
{
struct arc_header *ah;
int error;
u_int8_t atype, adst;
int loop_copy = 0;
int isphds;
#if defined(INET) || defined(INET6)
int is_gw = 0;
#endif
if (!((ifp->if_flags & IFF_UP) &&
(ifp->if_drv_flags & IFF_DRV_RUNNING)))
return(ENETDOWN); /* m, m1 aren't initialized yet */
error = 0;
#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:
/*
* For now, use the simple IP addr -> ARCnet addr mapping
*/
if (m->m_flags & (M_BCAST|M_MCAST))
adst = arcbroadcastaddr; /* ARCnet broadcast address */
else if (ifp->if_flags & IFF_NOARP)
adst = ntohl(SIN(dst)->sin_addr.s_addr) & 0xFF;
else {
error = arpresolve(ifp, is_gw, m, dst, &adst, NULL,
NULL);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
}
atype = (ifp->if_flags & IFF_LINK0) ?
ARCTYPE_IP_OLD : ARCTYPE_IP;
break;
case AF_ARP:
{
struct arphdr *ah;
ah = mtod(m, struct arphdr *);
ah->ar_hrd = htons(ARPHRD_ARCNET);
loop_copy = -1; /* if this is for us, don't do it */
switch(ntohs(ah->ar_op)) {
case ARPOP_REVREQUEST:
case ARPOP_REVREPLY:
atype = ARCTYPE_REVARP;
break;
case ARPOP_REQUEST:
case ARPOP_REPLY:
default:
atype = ARCTYPE_ARP;
break;
}
if (m->m_flags & M_BCAST)
bcopy(ifp->if_broadcastaddr, &adst, ARC_ADDR_LEN);
else
bcopy(ar_tha(ah), &adst, ARC_ADDR_LEN);
}
break;
#endif
#ifdef INET6
case AF_INET6:
if ((m->m_flags & M_MCAST) != 0)
adst = arcbroadcastaddr; /* ARCnet broadcast address */
else {
error = nd6_resolve(ifp, is_gw, m, dst, &adst, NULL,
NULL);
if (error != 0)
return (error == EWOULDBLOCK ? 0 : error);
}
atype = ARCTYPE_INET6;
break;
#endif
case AF_UNSPEC:
{
const struct arc_header *ah;
loop_copy = -1;
ah = (const struct arc_header *)dst->sa_data;
adst = ah->arc_dhost;
atype = ah->arc_type;
if (atype == ARCTYPE_ARP) {
atype = (ifp->if_flags & IFF_LINK0) ?
ARCTYPE_ARP_OLD: ARCTYPE_ARP;
#ifdef ARCNET_ALLOW_BROKEN_ARP
/*
* XXX It's not clear per RFC826 if this is needed, but
* "assigned numbers" say this is wrong.
* However, e.g., AmiTCP 3.0Beta used it... we make this
* switchable for emergency cases. Not perfect, but...
*/
if (ifp->if_flags & IFF_LINK2)
mtod(m, struct arphdr *)->ar_pro = atype - 1;
#endif
}
break;
}
default:
if_printf(ifp, "can't handle af%d\n", dst->sa_family);
senderr(EAFNOSUPPORT);
}
isphds = arc_isphds(atype);
M_PREPEND(m, isphds ? ARC_HDRNEWLEN : ARC_HDRLEN, M_NOWAIT);
if (m == NULL)
senderr(ENOBUFS);
ah = mtod(m, struct arc_header *);
ah->arc_type = atype;
ah->arc_dhost = adst;
ah->arc_shost = ARC_LLADDR(ifp);
if (isphds) {
ah->arc_flag = 0;
ah->arc_seqid = 0;
}
if ((ifp->if_flags & IFF_SIMPLEX) && (loop_copy != -1)) {
if ((m->m_flags & M_BCAST) || (loop_copy > 0)) {
struct mbuf *n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
(void) if_simloop(ifp, n, dst->sa_family, ARC_HDRLEN);
} else if (ah->arc_dhost == ah->arc_shost) {
(void) if_simloop(ifp, m, dst->sa_family, ARC_HDRLEN);
return (0); /* XXX */
}
}
BPF_MTAP(ifp, m);
error = ifp->if_transmit(ifp, m);
return (error);
bad:
if (m)
m_freem(m);
return (error);
}
void
arc_frag_init(struct ifnet *ifp)
{
struct arccom *ac;
ac = (struct arccom *)ifp->if_l2com;
ac->curr_frag = 0;
}
struct mbuf *
arc_frag_next(struct ifnet *ifp)
{
struct arccom *ac;
struct mbuf *m;
struct arc_header *ah;
ac = (struct arccom *)ifp->if_l2com;
if ((m = ac->curr_frag) == NULL) {
int tfrags;
/* dequeue new packet */
IF_DEQUEUE(&ifp->if_snd, m);
if (m == NULL)
return 0;
ah = mtod(m, struct arc_header *);
if (!arc_isphds(ah->arc_type))
return m;
++ac->ac_seqid; /* make the seqid unique */
tfrags = howmany(m->m_pkthdr.len, ARC_MAX_DATA);
ac->fsflag = 2 * tfrags - 3;
ac->sflag = 0;
ac->rsflag = ac->fsflag;
ac->arc_dhost = ah->arc_dhost;
ac->arc_shost = ah->arc_shost;
ac->arc_type = ah->arc_type;
m_adj(m, ARC_HDRNEWLEN);
ac->curr_frag = m;
}
/* split out next fragment and return it */
if (ac->sflag < ac->fsflag) {
/* we CAN'T have short packets here */
ac->curr_frag = m_split(m, ARC_MAX_DATA, M_NOWAIT);
if (ac->curr_frag == 0) {
m_freem(m);
return 0;
}
M_PREPEND(m, ARC_HDRNEWLEN, M_NOWAIT);
if (m == NULL) {
m_freem(ac->curr_frag);
ac->curr_frag = 0;
return 0;
}
ah = mtod(m, struct arc_header *);
ah->arc_flag = ac->rsflag;
ah->arc_seqid = ac->ac_seqid;
ac->sflag += 2;
ac->rsflag = ac->sflag;
} else if ((m->m_pkthdr.len >=
ARC_MIN_FORBID_LEN - ARC_HDRNEWLEN + 2) &&
(m->m_pkthdr.len <=
ARC_MAX_FORBID_LEN - ARC_HDRNEWLEN + 2)) {
ac->curr_frag = 0;
M_PREPEND(m, ARC_HDRNEWLEN_EXC, M_NOWAIT);
if (m == NULL)
return 0;
ah = mtod(m, struct arc_header *);
ah->arc_flag = 0xFF;
ah->arc_seqid = 0xFFFF;
ah->arc_type2 = ac->arc_type;
ah->arc_flag2 = ac->sflag;
ah->arc_seqid2 = ac->ac_seqid;
} else {
ac->curr_frag = 0;
M_PREPEND(m, ARC_HDRNEWLEN, M_NOWAIT);
if (m == NULL)
return 0;
ah = mtod(m, struct arc_header *);
ah->arc_flag = ac->sflag;
ah->arc_seqid = ac->ac_seqid;
}
ah->arc_dhost = ac->arc_dhost;
ah->arc_shost = ac->arc_shost;
ah->arc_type = ac->arc_type;
return m;
}
/*
* Defragmenter. Returns mbuf if last packet found, else
* NULL. frees incoming mbuf as necessary.
*/
static __inline struct mbuf *
arc_defrag(struct ifnet *ifp, struct mbuf *m)
{
struct arc_header *ah, *ah1;
struct arccom *ac;
struct ac_frag *af;
struct mbuf *m1;
char *s;
int newflen;
u_char src,dst,typ;
ac = (struct arccom *)ifp->if_l2com;
if (m->m_len < ARC_HDRNEWLEN) {
m = m_pullup(m, ARC_HDRNEWLEN);
if (m == NULL) {
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
return NULL;
}
}
ah = mtod(m, struct arc_header *);
typ = ah->arc_type;
if (!arc_isphds(typ))
return m;
src = ah->arc_shost;
dst = ah->arc_dhost;
if (ah->arc_flag == 0xff) {
m_adj(m, 4);
if (m->m_len < ARC_HDRNEWLEN) {
m = m_pullup(m, ARC_HDRNEWLEN);
if (m == NULL) {
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
return NULL;
}
}
ah = mtod(m, struct arc_header *);
}
af = &ac->ac_fragtab[src];
m1 = af->af_packet;
s = "debug code error";
if (ah->arc_flag & 1) {
/*
* first fragment. We always initialize, which is
* about the right thing to do, as we only want to
* accept one fragmented packet per src at a time.
*/
if (m1 != NULL)
m_freem(m1);
af->af_packet = m;
m1 = m;
af->af_maxflag = ah->arc_flag;
af->af_lastseen = 0;
af->af_seqid = ah->arc_seqid;
return NULL;
/* notreached */
} else {
/* check for unfragmented packet */
if (ah->arc_flag == 0)
return m;
/* do we have a first packet from that src? */
if (m1 == NULL) {
s = "no first frag";
goto outofseq;
}
ah1 = mtod(m1, struct arc_header *);
if (ah->arc_seqid != ah1->arc_seqid) {
s = "seqid differs";
goto outofseq;
}
if (typ != ah1->arc_type) {
s = "type differs";
goto outofseq;
}
if (dst != ah1->arc_dhost) {
s = "dest host differs";
goto outofseq;
}
/* typ, seqid and dst are ok here. */
if (ah->arc_flag == af->af_lastseen) {
m_freem(m);
return NULL;
}
if (ah->arc_flag == af->af_lastseen + 2) {
/* ok, this is next fragment */
af->af_lastseen = ah->arc_flag;
m_adj(m,ARC_HDRNEWLEN);
/*
* m_cat might free the first mbuf (with pkthdr)
* in 2nd chain; therefore:
*/
newflen = m->m_pkthdr.len;
m_cat(m1,m);
m1->m_pkthdr.len += newflen;
/* is it the last one? */
if (af->af_lastseen > af->af_maxflag) {
af->af_packet = NULL;
return(m1);
} else
return NULL;
}
s = "other reason";
/* if all else fails, it is out of sequence, too */
}
outofseq:
if (m1) {
m_freem(m1);
af->af_packet = NULL;
}
if (m)
m_freem(m);
log(LOG_INFO,"%s: got out of seq. packet: %s\n",
ifp->if_xname, s);
return NULL;
}
/*
* return 1 if Packet Header Definition Standard, else 0.
* For now: old IP, old ARP aren't obviously. Lacking correct information,
* we guess that besides new IP and new ARP also IPX and APPLETALK are PHDS.
* (Apple and Novell corporations were involved, among others, in PHDS work).
* Easiest is to assume that everybody else uses that, too.
*/
int
arc_isphds(u_int8_t type)
{
return (type != ARCTYPE_IP_OLD &&
type != ARCTYPE_ARP_OLD &&
type != ARCTYPE_DIAGNOSE);
}
/*
* Process a received Arcnet packet;
* the packet is in the mbuf chain m with
* the ARCnet header.
*/
void
arc_input(struct ifnet *ifp, struct mbuf *m)
{
struct arc_header *ah;
int isr;
u_int8_t atype;
if ((ifp->if_flags & IFF_UP) == 0) {
m_freem(m);
return;
}
/* possibly defragment: */
m = arc_defrag(ifp, m);
if (m == NULL)
return;
BPF_MTAP(ifp, m);
ah = mtod(m, struct arc_header *);
/* does this belong to us? */
if ((ifp->if_flags & IFF_PROMISC) == 0
&& ah->arc_dhost != arcbroadcastaddr
&& ah->arc_dhost != ARC_LLADDR(ifp)) {
m_freem(m);
return;
}
if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
if (ah->arc_dhost == arcbroadcastaddr) {
m->m_flags |= M_BCAST|M_MCAST;
if_inc_counter(ifp, IFCOUNTER_IMCASTS, 1);
}
atype = ah->arc_type;
switch (atype) {
#ifdef INET
case ARCTYPE_IP:
m_adj(m, ARC_HDRNEWLEN);
isr = NETISR_IP;
break;
case ARCTYPE_IP_OLD:
m_adj(m, ARC_HDRLEN);
isr = NETISR_IP;
break;
case ARCTYPE_ARP:
if (ifp->if_flags & IFF_NOARP) {
/* Discard packet if ARP is disabled on interface */
m_freem(m);
return;
}
m_adj(m, ARC_HDRNEWLEN);
isr = NETISR_ARP;
#ifdef ARCNET_ALLOW_BROKEN_ARP
mtod(m, struct arphdr *)->ar_pro = htons(ETHERTYPE_IP);
#endif
break;
case ARCTYPE_ARP_OLD:
if (ifp->if_flags & IFF_NOARP) {
/* Discard packet if ARP is disabled on interface */
m_freem(m);
return;
}
m_adj(m, ARC_HDRLEN);
isr = NETISR_ARP;
#ifdef ARCNET_ALLOW_BROKEN_ARP
mtod(m, struct arphdr *)->ar_pro = htons(ETHERTYPE_IP);
#endif
break;
#endif
#ifdef INET6
case ARCTYPE_INET6:
m_adj(m, ARC_HDRNEWLEN);
isr = NETISR_IPV6;
break;
#endif
default:
m_freem(m);
return;
}
M_SETFIB(m, ifp->if_fib);
netisr_dispatch(isr, m);
}
/*
* Register (new) link level address.
*/
void
arc_storelladdr(struct ifnet *ifp, u_int8_t lla)
{
ARC_LLADDR(ifp) = lla;
}
/*
* Perform common duties while attaching to interface list
*/
void
arc_ifattach(struct ifnet *ifp, u_int8_t lla)
{
struct ifaddr *ifa;
struct sockaddr_dl *sdl;
struct arccom *ac;
if_attach(ifp);
ifp->if_addrlen = 1;
ifp->if_hdrlen = ARC_HDRLEN;
ifp->if_mtu = 1500;
ifp->if_resolvemulti = arc_resolvemulti;
if (ifp->if_baudrate == 0)
ifp->if_baudrate = 2500000;
ifa = ifp->if_addr;
KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__));
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
sdl->sdl_type = IFT_ARCNET;
sdl->sdl_alen = ifp->if_addrlen;
if (ifp->if_flags & IFF_BROADCAST)
ifp->if_flags |= IFF_MULTICAST|IFF_ALLMULTI;
ac = (struct arccom *)ifp->if_l2com;
ac->ac_seqid = (time_second) & 0xFFFF; /* try to make seqid unique */
if (lla == 0) {
/* XXX this message isn't entirely clear, to me -- cgd */
log(LOG_ERR,"%s: link address 0 reserved for broadcasts. Please change it and ifconfig %s down up\n",
ifp->if_xname, ifp->if_xname);
}
arc_storelladdr(ifp, lla);
ifp->if_broadcastaddr = &arcbroadcastaddr;
bpfattach(ifp, DLT_ARCNET, ARC_HDRLEN);
}
void
arc_ifdetach(struct ifnet *ifp)
{
bpfdetach(ifp);
if_detach(ifp);
}
int
arc_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
{
struct ifaddr *ifa = (struct ifaddr *) data;
struct ifreq *ifr = (struct ifreq *) data;
int error = 0;
switch (command) {
case SIOCSIFADDR:
ifp->if_flags |= IFF_UP;
switch (ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET:
ifp->if_init(ifp->if_softc); /* before arpwhohas */
arp_ifinit(ifp, ifa);
break;
#endif
default:
ifp->if_init(ifp->if_softc);
break;
}
break;
case SIOCGIFADDR:
ifr->ifr_addr.sa_data[0] = ARC_LLADDR(ifp);
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
if (ifr == NULL)
error = EAFNOSUPPORT;
else {
switch (ifr->ifr_addr.sa_family) {
case AF_INET:
case AF_INET6:
error = 0;
break;
default:
error = EAFNOSUPPORT;
break;
}
}
break;
case SIOCSIFMTU:
/*
* Set the interface MTU.
* mtu can't be larger than ARCMTU for RFC1051
* and can't be larger than ARC_PHDS_MTU
*/
if (((ifp->if_flags & IFF_LINK0) && ifr->ifr_mtu > ARCMTU) ||
ifr->ifr_mtu > ARC_PHDS_MAXMTU)
error = EINVAL;
else
ifp->if_mtu = ifr->ifr_mtu;
break;
}
return (error);
}
/* based on ether_resolvemulti() */
int
arc_resolvemulti(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
switch(sa->sa_family) {
case AF_LINK:
/*
* No mapping needed. Just check that it's a valid MC address.
*/
sdl = (struct sockaddr_dl *)sa;
if (*LLADDR(sdl) != arcbroadcastaddr)
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_ETHER);
sdl->sdl_alen = ARC_ADDR_LEN;
*LLADDR(sdl) = 0;
*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_ETHER);
sdl->sdl_alen = ARC_ADDR_LEN;
*LLADDR(sdl) = 0;
*llsa = (struct sockaddr *)sdl;
return 0;
#endif
default:
/*
* Well, the text isn't quite right, but it's the name
* that counts...
*/
return EAFNOSUPPORT;
}
}
static MALLOC_DEFINE(M_ARCCOM, "arccom", "ARCNET interface internals");
static void*
arc_alloc(u_char type, struct ifnet *ifp)
{
struct arccom *ac;
ac = malloc(sizeof(struct arccom), M_ARCCOM, M_WAITOK | M_ZERO);
ac->ac_ifp = ifp;
return (ac);
}
static void
arc_free(void *com, u_char type)
{
free(com, M_ARCCOM);
}
static int
arc_modevent(module_t mod, int type, void *data)
{
switch (type) {
case MOD_LOAD:
if_register_com_alloc(IFT_ARCNET, arc_alloc, arc_free);
break;
case MOD_UNLOAD:
if_deregister_com_alloc(IFT_ARCNET);
break;
default:
return EOPNOTSUPP;
}
return (0);
}
static moduledata_t arc_mod = {
"arcnet",
arc_modevent,
0
};
DECLARE_MODULE(arcnet, arc_mod, SI_SUB_INIT_IF, SI_ORDER_ANY);
MODULE_VERSION(arcnet, 1);

View File

@ -49,7 +49,6 @@ struct arphdr {
u_short ar_hrd; /* format of hardware address */
#define ARPHRD_ETHER 1 /* ethernet hardware format */
#define ARPHRD_IEEE802 6 /* token-ring hardware format */
#define ARPHRD_ARCNET 7 /* arcnet hardware format */
#define ARPHRD_FRELAY 15 /* frame relay hardware format */
#define ARPHRD_IEEE1394 24 /* firewire hardware format */
#define ARPHRD_INFINIBAND 32 /* infiniband hardware format */

View File

@ -694,10 +694,6 @@ arpintr(struct mbuf *m)
hlen = ETHER_ADDR_LEN; /* RFC 826 */
layer = "ethernet";
break;
case ARPHRD_ARCNET:
hlen = 1; /* RFC 1201, ARC_ADDR_LEN */
layer = "arcnet";
break;
case ARPHRD_INFINIBAND:
hlen = 20; /* RFC 4391, INFINIBAND_ALEN */
layer = "infiniband";

View File

@ -1974,8 +1974,6 @@ in6_if2idlen(struct ifnet *ifp)
return (64);
case IFT_PPP: /* RFC2472 */
return (64);
case IFT_ARCNET: /* RFC2497 */
return (64);
case IFT_FRELAY: /* RFC2590 */
return (64);
case IFT_IEEE1394: /* RFC3146 */

View File

@ -316,26 +316,6 @@ in6_get_hw_ifid(struct ifnet *ifp, struct in6_addr *in6)
}
break;
case IFT_ARCNET:
if (addrlen != 1) {
IF_ADDR_RUNLOCK(ifp);
return -1;
}
if (!addr[0]) {
IF_ADDR_RUNLOCK(ifp);
return -1;
}
bzero(&in6->s6_addr[8], 8);
in6->s6_addr[15] = addr[0];
/*
* due to insufficient bitwidth, we mark it local.
*/
in6->s6_addr[8] &= ~EUI64_GBIT; /* g bit to "individual" */
in6->s6_addr[8] |= EUI64_UBIT; /* u bit to "local" */
break;
case IFT_GIF:
case IFT_STF:
/*

View File

@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_arc.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/route.h>
@ -334,15 +333,7 @@ nd6_setmtu0(struct ifnet *ifp, struct nd_ifinfo *ndi)
u_int32_t omaxmtu;
omaxmtu = ndi->maxmtu;
switch (ifp->if_type) {
case IFT_ARCNET:
ndi->maxmtu = MIN(ARC_PHDS_MAXMTU, ifp->if_mtu); /* RFC2497 */
break;
default:
ndi->maxmtu = ifp->if_mtu;
break;
}
ndi->maxmtu = ifp->if_mtu;
/*
* Decreasing the interface MTU under IPV6 minimum MTU may cause
@ -2519,13 +2510,12 @@ nd6_need_cache(struct ifnet *ifp)
{
/*
* XXX: we currently do not make neighbor cache on any interface
* other than ARCnet, Ethernet and GIF.
* other than Ethernet and GIF.
*
* RFC2893 says:
* - unidirectional tunnels needs no ND
*/
switch (ifp->if_type) {
case IFT_ARCNET:
case IFT_ETHER:
case IFT_IEEE1394:
case IFT_L2VLAN:

View File

@ -1090,7 +1090,6 @@ caddr_t
nd6_ifptomac(struct ifnet *ifp)
{
switch (ifp->if_type) {
case IFT_ARCNET:
case IFT_ETHER:
case IFT_IEEE1394:
case IFT_L2VLAN: