import Chuck Cranor's ATM driver
This commit is contained in:
parent
3cc5346fb1
commit
413fe3928f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/CRANOR/; revision=25603
348
sys/dev/en/if_en_pci.c
Normal file
348
sys/dev/en/if_en_pci.c
Normal file
@ -0,0 +1,348 @@
|
||||
/* $NetBSD: if_en_pci.c,v 1.1 1996/06/22 02:00:31 chuck Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1996 Charles D. Cranor and Washington University.
|
||||
* 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 Charles D. Cranor and
|
||||
* Washington University.
|
||||
* 4. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* i f _ e n _ p c i . c
|
||||
*
|
||||
* author: Chuck Cranor <chuck@ccrc.wustl.edu>
|
||||
* started: spring, 1996.
|
||||
*
|
||||
* FreeBSD PCI glue for the eni155p card.
|
||||
* thanks to Matt Thomas for figuring out FreeBSD vs NetBSD vs etc.. diffs.
|
||||
*/
|
||||
|
||||
#include "en.h"
|
||||
#include "pci.h"
|
||||
#if (NEN > 0) && (NPCI > 0)
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#ifndef SHUTDOWN_PRE_SYNC
|
||||
/*
|
||||
* device shutdown mechanism has been changed since 2.2-ALPHA.
|
||||
* if SHUTDOWN_PRE_SYNC is defined in "sys/systm.h", use new one.
|
||||
* otherwise, use old one.
|
||||
* new: 2.2-ALPHA, 2.2-BETA, 2.2-GAMME, 2.2-RELEASE, 3.0
|
||||
* old: 2.1.5, 2.1.6, 2.2-SNAP
|
||||
* -- kjc
|
||||
*/
|
||||
#include <sys/devconf.h>
|
||||
#endif
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
|
||||
#include <machine/cpufunc.h> /* for rdtsc proto for clock.h below */
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <pci/pcivar.h>
|
||||
#include <pci/pcireg.h>
|
||||
|
||||
#include <dev/en/midwayreg.h>
|
||||
#include <dev/en/midwayvar.h>
|
||||
|
||||
|
||||
/*
|
||||
* prototypes
|
||||
*/
|
||||
|
||||
static void en_pci_attach __P((pcici_t, int));
|
||||
static char *en_pci_probe __P((pcici_t, pcidi_t));
|
||||
#ifdef SHUTDOWN_PRE_SYNC
|
||||
static void en_pci_shutdown __P((int, void *));
|
||||
#else
|
||||
static int en_pci_shutdown __P((struct kern_devconf *, int));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* local structures
|
||||
*/
|
||||
|
||||
struct en_pci_softc {
|
||||
/* bus independent stuff */
|
||||
struct en_softc esc; /* includes "device" structure */
|
||||
|
||||
/* PCI bus glue */
|
||||
void *sc_ih; /* interrupt handle */
|
||||
pci_chipset_tag_t en_pc; /* for PCI calls */
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* pointers to softcs (we alloc)
|
||||
*/
|
||||
|
||||
static struct en_pci_softc *enpcis[NEN] = {0};
|
||||
extern struct cfdriver en_cd;
|
||||
|
||||
/*
|
||||
* autoconfig structures
|
||||
*/
|
||||
|
||||
static u_long en_pci_count;
|
||||
|
||||
static struct pci_device endevice = {
|
||||
"en",
|
||||
en_pci_probe,
|
||||
en_pci_attach,
|
||||
&en_pci_count,
|
||||
#ifdef SHUTDOWN_PRE_SYNC
|
||||
NULL,
|
||||
#else
|
||||
en_pci_shutdown,
|
||||
#endif
|
||||
};
|
||||
|
||||
DATA_SET (pcidevice_set, endevice);
|
||||
|
||||
/*
|
||||
* local defines (PCI specific stuff)
|
||||
*/
|
||||
|
||||
/*
|
||||
* address of config base memory address register in PCI config space
|
||||
* (this is card specific)
|
||||
*/
|
||||
|
||||
#define PCI_CBMA 0x10
|
||||
|
||||
/*
|
||||
* tonga (pci bridge). ENI cards only!
|
||||
*/
|
||||
|
||||
#define EN_TONGA 0x60 /* PCI config addr of tonga reg */
|
||||
|
||||
#define TONGA_SWAP_DMA 0x80 /* endian swap control */
|
||||
#define TONGA_SWAP_BYTE 0x40
|
||||
#define TONGA_SWAP_WORD 0x20
|
||||
|
||||
/*
|
||||
* adaptec pci bridge. ADP cards only!
|
||||
*/
|
||||
|
||||
#define ADP_PCIREG 0x050040 /* PCI control register */
|
||||
|
||||
#define ADP_PCIREG_RESET 0x1 /* reset card */
|
||||
#define ADP_PCIREG_IENABLE 0x2 /* interrupt enable */
|
||||
#define ADP_PCIREG_SWAP_WORD 0x4 /* swap byte on slave access */
|
||||
#define ADP_PCIREG_SWAP_DMA 0x8 /* swap byte on DMA */
|
||||
|
||||
#define PCI_VENDOR_EFFICIENTNETS 0x111a /* Efficent Networks */
|
||||
#define PCI_PRODUCT_EFFICIENTNETS_ENI155PF 0x0000 /* ENI-155P ATM */
|
||||
#define PCI_PRODUCT_EFFICIENTNETS_ENI155PA 0x0002 /* ENI-155P ATM */
|
||||
#define PCI_VENDOR_ADP 0x9004 /* adaptec */
|
||||
#define PCI_PRODUCT_ADP_AIC5900 0x5900
|
||||
#define PCI_PRODUCT_ADP_AIC5905 0x5905
|
||||
#define PCI_VENDOR(x) ((x) & 0xFFFF)
|
||||
#define PCI_CHIPID(x) (((x) >> 16) & 0xFFFF)
|
||||
|
||||
#if !defined(MIDWAY_ENIONLY)
|
||||
|
||||
static void adp_busreset __P((void *));
|
||||
|
||||
/*
|
||||
* bus specific reset function [ADP only!]
|
||||
*/
|
||||
|
||||
static void adp_busreset(v)
|
||||
|
||||
void *v;
|
||||
|
||||
{
|
||||
struct en_softc *sc = (struct en_softc *) v;
|
||||
u_int32_t dummy;
|
||||
|
||||
bus_space_write_4(sc->en_memt, sc->en_base, ADP_PCIREG, ADP_PCIREG_RESET);
|
||||
DELAY(1000); /* let it reset */
|
||||
dummy = bus_space_read_4(sc->en_memt, sc->en_base, ADP_PCIREG);
|
||||
bus_space_write_4(sc->en_memt, sc->en_base, ADP_PCIREG,
|
||||
(ADP_PCIREG_SWAP_WORD|ADP_PCIREG_SWAP_DMA|ADP_PCIREG_IENABLE));
|
||||
dummy = bus_space_read_4(sc->en_memt, sc->en_base, ADP_PCIREG);
|
||||
if ((dummy & (ADP_PCIREG_SWAP_WORD|ADP_PCIREG_SWAP_DMA)) !=
|
||||
(ADP_PCIREG_SWAP_WORD|ADP_PCIREG_SWAP_DMA))
|
||||
printf("adp_busreset: Adaptec ATM did NOT reset!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
/*
|
||||
* autoconfig stuff
|
||||
*/
|
||||
|
||||
static char *en_pci_probe(config_id, device_id)
|
||||
|
||||
pcici_t config_id;
|
||||
pcidi_t device_id;
|
||||
|
||||
{
|
||||
#if !defined(MIDWAY_ADPONLY)
|
||||
if (PCI_VENDOR(device_id) == PCI_VENDOR_EFFICIENTNETS &&
|
||||
(PCI_CHIPID(device_id) == PCI_PRODUCT_EFFICIENTNETS_ENI155PF ||
|
||||
PCI_CHIPID(device_id) == PCI_PRODUCT_EFFICIENTNETS_ENI155PA))
|
||||
return "Efficient Networks ENI-155p";
|
||||
#endif
|
||||
|
||||
#if !defined(MIDWAY_ENIONLY)
|
||||
if (PCI_VENDOR(device_id) == PCI_VENDOR_ADP &&
|
||||
(PCI_CHIPID(device_id) == PCI_PRODUCT_ADP_AIC5900 ||
|
||||
PCI_CHIPID(device_id) == PCI_PRODUCT_ADP_AIC5905))
|
||||
return "Adaptec 155 ATM";
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void en_pci_attach(config_id, unit)
|
||||
|
||||
pcici_t config_id;
|
||||
int unit;
|
||||
|
||||
{
|
||||
struct en_softc *sc;
|
||||
struct en_pci_softc *scp;
|
||||
pcidi_t device_id;
|
||||
int retval;
|
||||
vm_offset_t pa;
|
||||
|
||||
if (unit >= NEN) {
|
||||
printf("en%d: not configured; kernel is built for only %d device%s.\n",
|
||||
unit, NEN, NEN == 1 ? "" : "s");
|
||||
return;
|
||||
}
|
||||
|
||||
scp = (struct en_pci_softc *) malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT);
|
||||
if (scp == NULL)
|
||||
return;
|
||||
bzero(scp, sizeof(*scp)); /* zero */
|
||||
sc = &scp->esc;
|
||||
|
||||
retval = pci_map_mem(config_id, PCI_CBMA, (vm_offset_t *) &sc->en_base, &pa);
|
||||
|
||||
if (!retval) {
|
||||
free((caddr_t) scp, M_DEVBUF);
|
||||
return;
|
||||
}
|
||||
enpcis[unit] = scp; /* lock it in */
|
||||
en_cd.cd_devs[unit] = sc; /* fake a cfdriver structure */
|
||||
en_cd.cd_ndevs = NEN;
|
||||
sprintf(sc->sc_dev.dv_xname, "en%d", unit);
|
||||
sc->enif.if_unit = unit;
|
||||
sc->enif.if_name = "en";
|
||||
|
||||
/*
|
||||
* figure out if we are an adaptec card or not.
|
||||
* XXX: why do we have to re-read PC_ID_REG when en_pci_probe already
|
||||
* had that info?
|
||||
*/
|
||||
|
||||
device_id = pci_conf_read(config_id, PCI_ID_REG);
|
||||
sc->is_adaptec = (PCI_VENDOR(device_id) == PCI_VENDOR_ADP) ? 1 : 0;
|
||||
|
||||
#ifdef SHUTDOWN_PRE_SYNC
|
||||
/*
|
||||
* Add shutdown hook so that DMA is disabled prior to reboot. Not
|
||||
* doing so could allow DMA to corrupt kernel memory during the
|
||||
* reboot before the driver initializes.
|
||||
*/
|
||||
at_shutdown(en_pci_shutdown, scp, SHUTDOWN_POST_SYNC);
|
||||
#endif
|
||||
|
||||
if (!pci_map_int(config_id, en_intr, (void *) sc, &net_imask)) {
|
||||
printf("%s: couldn't establish interrupt\n", sc->sc_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
sc->ipl = 1; /* XXX */
|
||||
|
||||
/*
|
||||
* set up pci bridge
|
||||
*/
|
||||
|
||||
#if !defined(MIDWAY_ENIONLY)
|
||||
if (sc->is_adaptec) {
|
||||
sc->en_busreset = adp_busreset;
|
||||
adp_busreset(sc);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(MIDWAY_ADPONLY)
|
||||
if (!sc->is_adaptec) {
|
||||
sc->en_busreset = NULL;
|
||||
pci_conf_write(config_id, EN_TONGA, (TONGA_SWAP_DMA|TONGA_SWAP_WORD));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* done PCI specific stuff
|
||||
*/
|
||||
|
||||
en_attach(sc);
|
||||
|
||||
}
|
||||
|
||||
#ifdef SHUTDOWN_PRE_SYNC
|
||||
static void
|
||||
en_pci_shutdown(
|
||||
int howto,
|
||||
void *sc)
|
||||
{
|
||||
struct en_pci_softc *psc = (struct en_pci_softc *)sc;
|
||||
|
||||
en_reset(&psc->esc);
|
||||
DELAY(10);
|
||||
}
|
||||
#else /* !SHUTDOWN_PRE_SYNC */
|
||||
static int
|
||||
en_pci_shutdown(kdc, force)
|
||||
|
||||
struct kern_devconf *kdc;
|
||||
int force;
|
||||
|
||||
{
|
||||
if (kdc->kdc_unit < NEN) {
|
||||
struct en_pci_softc *psc = enpcis[kdc->kdc_unit];
|
||||
if (psc) /* can it be null? */
|
||||
en_reset(&psc->esc);
|
||||
DELAY(10);
|
||||
}
|
||||
dev_detach(kdc);
|
||||
return(0);
|
||||
}
|
||||
#endif /* !SHUTDOWN_PRE_SYNC */
|
||||
#endif /* NEN > 0 && NPCI > 0 */
|
3208
sys/dev/en/midway.c
Normal file
3208
sys/dev/en/midway.c
Normal file
File diff suppressed because it is too large
Load Diff
304
sys/dev/en/midwayreg.h
Normal file
304
sys/dev/en/midwayreg.h
Normal file
@ -0,0 +1,304 @@
|
||||
/* $NetBSD: midwayreg.h,v 1.6 1997/03/20 21:34:47 chuck Exp $ */
|
||||
|
||||
/*
|
||||
* m i d w a y r e g . h
|
||||
*
|
||||
* this file contains the description of the ENI ATM midway chip
|
||||
* data structures. see midway.c for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(sparc) || defined(__FreeBSD__)
|
||||
/* XXX: gross. netbsd/sparc doesn't have machine/bus.h yet. */
|
||||
typedef void * bus_space_tag_t;
|
||||
typedef u_int32_t pci_chipset_tag_t;
|
||||
typedef caddr_t bus_space_handle_t;
|
||||
typedef u_int32_t bus_size_t;
|
||||
typedef caddr_t bus_addr_t;
|
||||
|
||||
#define bus_space_read_4(t, h, o) ((void) t, \
|
||||
(*(volatile u_int32_t *)((h) + (o))))
|
||||
#define bus_space_write_4(t, h, o, v) \
|
||||
((void) t, ((void)(*(volatile u_int32_t *)((h) + (o)) = (v))))
|
||||
|
||||
#if defined(sparc)
|
||||
#define vtophys(x) ((u_int32_t)(x)) /* sun4c dvma */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define MID_SZTOB(X) ((X) * 256 * 4) /* size to bytes */
|
||||
#define MID_BTOSZ(X) ((X) / 256 / 4) /* bytes to "size" */
|
||||
|
||||
#define MID_N_VC 1024 /* # of VCs we can use */
|
||||
#define MID_NTX_CH 8 /* 8 transmit channels (shared) */
|
||||
#define MID_ATMDATASZ 48 /* need data in 48 byte blocks */
|
||||
|
||||
/*
|
||||
* card data structures, top down
|
||||
*
|
||||
* in order to have a portable driver, the netbsd guys will not let us
|
||||
* use structs. we have a bus_space_handle_t which is the en_base address.
|
||||
* everything else is an offset from that base. all card data must be
|
||||
* accessed with bus_space_read_4()/bus_space_write_4():
|
||||
*
|
||||
* rv = bus_space_read_4(sc->en_memt, sc->en_base, BYTE_OFFSET);
|
||||
* bus_space_write_4(sc->en_memt, sc->en_base, BYTE_OFFSET, VALUE);
|
||||
*
|
||||
* en_card: the whole card (prom + phy + midway + obmem)
|
||||
* obmem contains: vci tab + dma queues (rx & tx) + service list + bufs
|
||||
*/
|
||||
|
||||
/* byte offsets from en_base of various items */
|
||||
#define MID_PHYOFF 0x030000 /* PHY offset */
|
||||
#define MID_MIDOFF 0x040000 /* midway regs offset */
|
||||
#define MID_RAMOFF 0x200000 /* RAM offset */
|
||||
#define MID_DRQOFF 0x204000 /* DRQ offset */
|
||||
#define MID_DRQEND MID_DTQOFF /* DRQ end */
|
||||
#define MID_DTQOFF 0x205000 /* DTQ offset */
|
||||
#define MID_DTQEND MID_SLOFF /* DTQ end */
|
||||
#define MID_SLOFF 0x206000 /* service list */
|
||||
#define MID_SLEND MID_BUFOFF /* service list end */
|
||||
#define MID_BUFOFF 0x207000 /* buffer area */
|
||||
#define MID_PROBEOFF 0x21fffc /* start probe here */
|
||||
#define MID_PROBSIZE 0x020000 /* 128 KB */
|
||||
#define MID_MAXOFF 0x3ffffc /* max offset */
|
||||
|
||||
/*
|
||||
* prom & phy: not defined here
|
||||
*/
|
||||
|
||||
/*
|
||||
* midway regs (byte offsets from en_base)
|
||||
*/
|
||||
|
||||
#define MID_RESID 0x40000 /* write=reset reg, read=ID reg */
|
||||
|
||||
#define MID_VER(X) (((X) & 0xf0000000) >> 28) /* midway version # */
|
||||
#define MID_MID(X) (((X) & 0x700) >> 8) /* motherboard ID */
|
||||
#define MID_IS_SABRE(X) ((X) & 0x80) /* sabre controller? */
|
||||
#define MID_IS_SUNI(X) ((X) & 0x40) /* SUNI? vs utopia */
|
||||
#define MID_IS_UPIPE(X) ((X) & 0x20) /* utopia pipeline? */
|
||||
#define MID_DID(X) ((X) & 0x1f) /* daughterboard ID */
|
||||
|
||||
#define MID_INTACK 0x40004 /* interrupt ACK */
|
||||
#define MID_INTSTAT 0x40008 /* interrupt status */
|
||||
#define MID_INTENA 0x4000c /* interrupt enable */
|
||||
|
||||
#define MID_TXCHAN(N) (1 << ((N) + 9)) /* ack/status/enable xmit channel bit*/
|
||||
#define MID_INT_TX 0x1fe00 /* mask for any xmit interrupt */
|
||||
#define MID_INT_DMA_OVR 0x00100 /* DMA overflow interrupt */
|
||||
#define MID_INT_IDENT 0x00080 /* ident match error interrupt */
|
||||
#define MID_INT_LERR 0x00040 /* LERR interrupt (sbus?) */
|
||||
#define MID_INT_DMA_ERR 0x00020 /* DMA error interrupt */
|
||||
#define MID_INT_DMA_RX 0x00010 /* DMA recv interrupt */
|
||||
#define MID_INT_DMA_TX 0x00008 /* DMA xmit interrupt */
|
||||
#define MID_INT_SERVICE 0x00004 /* service list interrupt */
|
||||
#define MID_INT_SUNI 0x00002 /* SUNI interrupt */
|
||||
#define MID_INT_STATS 0x00001 /* stats overflow interrupt */
|
||||
|
||||
#define MID_INT_ANY 0x1ffff /* any interrupt? */
|
||||
|
||||
#define MID_INTBITS "\20\21T7\20T6\17T5\16T4\15T3\14T2\13T1\12T0\11DMAOVR\10ID\7LERR\6DMAERR\5RXDMA\4TXDMA\3SERV\2SUNI\1STAT"
|
||||
|
||||
#define MID_MAST_CSR 0x40010 /* master CSR */
|
||||
|
||||
#define MID_IPL(X) (((X) & 0x1c0) >> 6) /* IPL */
|
||||
#define MID_SETIPL(I) ((I) << 6)
|
||||
#define MID_MCSR_TXLOCK 0x20 /* lock on xmit overflow mode */
|
||||
/* NOTE: next 5 bits: write 1 means enable, write 0 means no change */
|
||||
#define MID_MCSR_ENDMA 0x10 /* DMA enable */
|
||||
#define MID_MCSR_ENTX 0x08 /* TX enable */
|
||||
#define MID_MCSR_ENRX 0x04 /* RX enable */
|
||||
#define MID_MCSR_W1MS 0x02 /* wait 1 msec */
|
||||
#define MID_MCSR_W500US 0x01 /* wait 500 usec */
|
||||
|
||||
#define MID_MCSRBITS "\20\6LCK\5DMAON\4TXON\3RXON\2W1MS\1W500US"
|
||||
|
||||
#define MID_STAT 0x40014 /* stat register, clear on read */
|
||||
|
||||
#define MID_VTRASH(X) (((X) >> 16) & 0xffff)
|
||||
/* # cells trashed due to VCI's mode */
|
||||
#define MID_OTRASH(X) ((X) & 0xffff) /* # cells trashed due to overflow */
|
||||
|
||||
#define MID_SERV_WRITE 0x40018 /* 10 bit service write pointer (r/o) */
|
||||
#define MID_DMA_ADDR 0x4001c /* VA of DMA (r/o) */
|
||||
|
||||
/* DMA queue pointers (bits 0 to 8) */
|
||||
#define MID_DMA_WRRX 0x40020 /* write ptr. for DMA recv queue */
|
||||
/* (for adaptor -> host xfers) */
|
||||
#define MID_DMA_RDRX 0x40024 /* read ptr for DMA recv queue (r/o) */
|
||||
/* (i.e. current adaptor->host xfer) */
|
||||
#define MID_DMA_WRTX 0x40028 /* write ptr for DMA xmit queue */
|
||||
/* (for host -> adaptor xfers) */
|
||||
#define MID_DMA_RDTX 0x4002c /* read ptr for DMA xmit queue (r/o) */
|
||||
/* (i.e. current host->adaptor xfer) */
|
||||
|
||||
/* xmit channel regs (1 per channel, MID_NTX_CH max channels) */
|
||||
|
||||
#define MIDX_PLACE(N) (0x40040+((N)*0x10)) /* xmit place */
|
||||
|
||||
#define MIDX_MKPLACE(SZ,LOC) ( ((SZ) << 11) | (LOC) )
|
||||
#define MIDX_LOC(X) ((X) & 0x7ff) /* location in obmem */
|
||||
#define MIDX_SZ(X) ((X) >> 11) /* (size of block / 256) in int32_t's*/
|
||||
#define MIDX_BASE(X) \
|
||||
(((MIDX_LOC(X) << MIDV_LOCTOPSHFT) * sizeof(u_int32_t)) + MID_RAMOFF)
|
||||
|
||||
/* the following two regs are word offsets in the block */
|
||||
#define MIDX_READPTR(N) (0x40044+((N)*0x10)) /* xmit read pointer (r/o) */
|
||||
#define MIDX_DESCSTART(N) (0x40048+((N)*0x10)) /* seg currently in DMA (r/o) */
|
||||
|
||||
|
||||
/*
|
||||
* obmem items
|
||||
*/
|
||||
|
||||
/*
|
||||
* vci table in obmem (offset from MID_VCTOFF)
|
||||
*/
|
||||
|
||||
#define MID_VC(N) (MID_RAMOFF+((N)*0x10))
|
||||
|
||||
#define MIDV_TRASH 0x00000000 /* ignore VC */
|
||||
#define MIDV_AAL5 0x80000000 /* do AAL5 on it */
|
||||
#define MIDV_NOAAL 0x40000000 /* do per-cell stuff on it */
|
||||
#define MIDV_MASK 0xc0000000 /* mode mask */
|
||||
#define MIDV_SETMODE(VC,M) (((VC) & ~(MIDV_MASK)) | (M)) /* new mode */
|
||||
#define MIDV_PTI 0x20000000 /* save PTI cells? */
|
||||
#define MIDV_LOCTOPSHFT 8 /* shift to get top 11 bits of 19 */
|
||||
#define MIDV_LOCSHIFT 18
|
||||
#define MIDV_LOCMASK 0x7ff
|
||||
#define MIDV_LOC(X) (((X) >> MIDV_LOCSHIFT) & MIDV_LOCMASK)
|
||||
/* 11 most sig bits of addr */
|
||||
#define MIDV_SZSHIFT 15
|
||||
#define MIDV_SZ(X) (((X) >> MIDV_SZSHIFT) & 7)
|
||||
/* size encoded the usual way */
|
||||
#define MIDV_INSERVICE 0x1 /* in service list */
|
||||
|
||||
#define MID_DST_RP(N) (MID_VC(N)|0x4)
|
||||
|
||||
#define MIDV_DSTART_SHIFT 16 /* shift */
|
||||
#define MIDV_DSTART(X) (((X) >> MIDV_DSTART_SHIFT) & 0x7fff)
|
||||
#define MIDV_READP_MASK 0x7fff /* valid bits, (shift = 0) */
|
||||
|
||||
#define MID_WP_ST_CNT(N) (MID_VC(N)|0x8) /* write pointer/state/count */
|
||||
|
||||
#define MIDV_WRITEP_MASK 0x7fff0000 /* mask for write ptr. */
|
||||
#define MIDV_WRITEP_SHIFT 16
|
||||
#define MIDV_ST_IDLE 0x0000
|
||||
#define MIDV_ST_TRASH 0xc000
|
||||
#define MIDV_ST_REASS 0x4000
|
||||
#define MIDV_CCOUNT 0x7ff /* cell count */
|
||||
|
||||
#define MID_CRC(N) (MID_VC(N)|0xc) /* CRC */
|
||||
|
||||
/*
|
||||
* dma recv q.
|
||||
*/
|
||||
|
||||
#define MID_DMA_END (1 << 5) /* for both tx and rx */
|
||||
#define MID_DMA_CNT(X) (((X) >> 16) & 0xffff)
|
||||
#define MID_DMA_TXCHAN(X) (((X) >> 6) & 0x7)
|
||||
#define MID_DMA_RXVCI(X) (((X) >> 6) & 0x3ff)
|
||||
#define MID_DMA_TYPE(X) ((X) & 0xf)
|
||||
|
||||
#define MID_DRQ_N 512 /* # of descriptors */
|
||||
#define MID_DRQ_A2REG(N) (((N) - MID_DRQOFF) >> 3)
|
||||
/* convert byte offset to reg value */
|
||||
#define MID_DRQ_REG2A(N) (((N) << 3) + MID_DRQOFF) /* and back */
|
||||
|
||||
/* note: format of word 1 of RXQ is different beween ENI and ADP cards */
|
||||
#define MID_MK_RXQ_ENI(CNT,VC,END,TYPE) \
|
||||
( ((CNT) << 16)|((VC) << 6)|(END)|(TYPE) )
|
||||
|
||||
#define MID_MK_RXQ_ADP(CNT,VC,END,JK) \
|
||||
( ((CNT) << 12)|((VC) << 2)|((END) >> 4)|(((JK) != 0) ? 1 : 0))
|
||||
/*
|
||||
* dma xmit q.
|
||||
*/
|
||||
|
||||
#define MID_DTQ_N 512 /* # of descriptors */
|
||||
#define MID_DTQ_A2REG(N) (((N) - MID_DTQOFF) >> 3)
|
||||
/* convert byte offset to reg value */
|
||||
#define MID_DTQ_REG2A(N) (((N) << 3) + MID_DTQOFF) /* and back */
|
||||
|
||||
|
||||
/* note: format of word 1 of TXQ is different beween ENI and ADP cards */
|
||||
#define MID_MK_TXQ_ENI(CNT,CHN,END,TYPE) \
|
||||
( ((CNT) << 16)|((CHN) << 6)|(END)|(TYPE) )
|
||||
|
||||
#define MID_MK_TXQ_ADP(CNT,CHN,END,JK) \
|
||||
( ((CNT) << 12)|((CHN) << 2)|((END) >> 4)|(((JK) != 0) ? 1 : 0) )
|
||||
|
||||
/*
|
||||
* dma types
|
||||
*/
|
||||
|
||||
#define MIDDMA_JK 0x3 /* just kidding */
|
||||
#define MIDDMA_BYTE 0x1 /* byte */
|
||||
#define MIDDMA_2BYTE 0x2 /* 2 bytes */
|
||||
#define MIDDMA_WORD 0x0 /* word */
|
||||
#define MIDDMA_2WORD 0x7 /* 2 words */
|
||||
#define MIDDMA_4WORD 0x4 /* 4 words */
|
||||
#define MIDDMA_8WORD 0x5 /* 8 words */
|
||||
#define MIDDMA_16WORD 0x6 /* 16 words!!! */
|
||||
#define MIDDMA_2WMAYBE 0xf /* 2 words, maybe */
|
||||
#define MIDDMA_4WMAYBE 0xc /* 4 words, maybe */
|
||||
#define MIDDMA_8WMAYBE 0xd /* 8 words, maybe */
|
||||
#define MIDDMA_16WMAYBE 0xe /* 16 words, maybe */
|
||||
|
||||
#define MIDDMA_MAYBE 0xc /* mask to detect WMAYBE dma code */
|
||||
#define MIDDMA_MAXBURST (16 * sizeof(u_int32_t)) /* largest burst */
|
||||
|
||||
/*
|
||||
* service list
|
||||
*/
|
||||
|
||||
#define MID_SL_N 1024 /* max # entries on slist */
|
||||
#define MID_SL_A2REG(N) (((N) - MID_SLOFF) >> 2)
|
||||
/* convert byte offset to reg value */
|
||||
#define MID_SL_REG2A(N) (((N) << 2) + MID_SLOFF) /* and back */
|
||||
|
||||
/*
|
||||
* data in the buffer area of obmem
|
||||
*/
|
||||
|
||||
/*
|
||||
* recv buffer desc. (1 u_int32_t at start of buffer)
|
||||
*/
|
||||
|
||||
#define MID_RBD_SIZE 4 /* RBD size */
|
||||
#define MID_CHDR_SIZE 4 /* on aal0, cell header size */
|
||||
#define MID_RBD_ID(X) ((X) & 0xfe000000) /* get ID */
|
||||
#define MID_RBD_STDID 0x36000000 /* standard ID */
|
||||
#define MID_RBD_CLP 0x01000000 /* CLP: cell loss priority */
|
||||
#define MID_RBD_CE 0x00010000 /* CE: congestion experienced */
|
||||
#define MID_RBD_T 0x00001000 /* T: trashed due to overflow */
|
||||
#define MID_RBD_CRCERR 0x00000800 /* CRC error */
|
||||
#define MID_RBD_CNT(X) ((X) & 0x7ff) /* cell count */
|
||||
|
||||
/*
|
||||
* xmit buffer desc. (2 u_int32_t's at start of buffer)
|
||||
* (note we treat the PR & RATE as a single u_int8_t)
|
||||
*/
|
||||
|
||||
#define MID_TBD_SIZE 8
|
||||
#define MID_TBD_MK1(AAL,PR_RATE,CNT) \
|
||||
(MID_TBD_STDID|(AAL)|((PR_RATE) << 19)|(CNT))
|
||||
#define MID_TBD_STDID 0xb0000000 /* standard ID */
|
||||
#define MID_TBD_AAL5 0x08000000 /* AAL 5 */
|
||||
#define MID_TBD_NOAAL5 0x00000000 /* not AAL 5 */
|
||||
|
||||
#define MID_TBD_MK2(VCI,PTI,CLP) \
|
||||
(((VCI) << 4)|((PTI) << 1)|(CLP))
|
||||
|
||||
/*
|
||||
* aal5 pdu tail, last 2 words of last cell of AAL5 frame
|
||||
* (word 2 is CRC .. handled by hw)
|
||||
*/
|
||||
|
||||
#define MID_PDU_SIZE 8
|
||||
#define MID_PDU_MK1(UU,CPI,LEN) \
|
||||
(((UU) << 24)|((CPI) << 16)|(LEN))
|
||||
#define MID_PDU_LEN(X) ((X) & 0xffff)
|
205
sys/dev/en/midwayvar.h
Normal file
205
sys/dev/en/midwayvar.h
Normal file
@ -0,0 +1,205 @@
|
||||
/* $NetBSD: midwayvar.h,v 1.10 1997/03/20 21:34:46 chuck Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1996 Charles D. Cranor and Washington University.
|
||||
* 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 Charles D. Cranor and
|
||||
* Washington University.
|
||||
* 4. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* m i d w a y v a r . h
|
||||
*
|
||||
* we define the en_softc here so that bus specific modules can allocate
|
||||
* it as the first item in their softc. note that BSD-required
|
||||
* "struct device" is in the mid_softc!
|
||||
*
|
||||
* author: Chuck Cranor <chuck@ccrc.wustl.edu>
|
||||
*/
|
||||
|
||||
/*
|
||||
* params needed to determine softc size
|
||||
*/
|
||||
|
||||
#ifndef EN_NTX
|
||||
#define EN_NTX 8 /* number of tx bufs to use */
|
||||
#endif
|
||||
#ifndef EN_TXSZ
|
||||
#define EN_TXSZ 32 /* trasmit buf size in KB */
|
||||
#endif
|
||||
#ifndef EN_RXSZ
|
||||
#define EN_RXSZ 32 /* recv buf size in KB */
|
||||
#endif
|
||||
#define EN_MAXNRX ((2048-(EN_NTX*EN_TXSZ))/EN_RXSZ)
|
||||
/* largest possible NRX (depends on RAM size) */
|
||||
|
||||
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)
|
||||
#define EN_INTR_TYPE int
|
||||
#define EN_INTR_RET(X) return(X)
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#define EN_IOCTL_CMDT u_long
|
||||
#elif defined(__bsdi__)
|
||||
#define EN_IOCTL_CMDT int
|
||||
#endif
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
#define EN_INTR_TYPE void
|
||||
#define EN_INTR_RET(X) return
|
||||
#define EN_IOCTL_CMDT int
|
||||
|
||||
struct device {
|
||||
char dv_xname[IFNAMSIZ];
|
||||
};
|
||||
|
||||
#define DV_IFNET 1
|
||||
|
||||
struct cfdriver {
|
||||
int zero;
|
||||
char *name;
|
||||
int one;
|
||||
int cd_ndevs;
|
||||
void *cd_devs[NEN];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* softc
|
||||
*/
|
||||
|
||||
struct en_softc {
|
||||
/* bsd glue */
|
||||
struct device sc_dev; /* system device */
|
||||
struct ifnet enif; /* network ifnet handle */
|
||||
|
||||
/* bus glue */
|
||||
bus_space_tag_t en_memt; /* for EN_READ/EN_WRITE */
|
||||
bus_space_handle_t en_base; /* base of en card */
|
||||
bus_size_t en_obmemsz; /* size of en card (bytes) */
|
||||
void (*en_busreset) __P((void *));
|
||||
/* bus specific reset function */
|
||||
|
||||
/* serv list */
|
||||
u_int32_t hwslistp; /* hw pointer to service list (byte offset) */
|
||||
u_int16_t swslist[MID_SL_N]; /* software service list (see en_service()) */
|
||||
u_int16_t swsl_head, /* ends of swslist (index into swslist) */
|
||||
swsl_tail;
|
||||
u_int32_t swsl_size; /* # of items in swsl */
|
||||
|
||||
|
||||
/* xmit dma */
|
||||
u_int32_t dtq[MID_DTQ_N]; /* sw copy of dma q (see ENIDQ macros) */
|
||||
u_int32_t dtq_free; /* # of dtq's free */
|
||||
u_int32_t dtq_us; /* software copy of our pointer (byte offset) */
|
||||
u_int32_t dtq_chip; /* chip's pointer (byte offset) */
|
||||
u_int32_t need_dtqs; /* true if we ran out of DTQs */
|
||||
|
||||
/* recv dma */
|
||||
u_int32_t drq[MID_DRQ_N]; /* sw copy of dma q (see ENIDQ macros) */
|
||||
u_int32_t drq_free; /* # of drq's free */
|
||||
u_int32_t drq_us; /* software copy of our pointer (byte offset) */
|
||||
u_int32_t drq_chip; /* chip's pointer (byte offset) */
|
||||
u_int32_t need_drqs; /* true if we ran out of DRQs */
|
||||
|
||||
/* xmit buf ctrl. (per channel) */
|
||||
struct {
|
||||
u_int32_t mbsize; /* # mbuf bytes we are using (max=TXHIWAT) */
|
||||
u_int32_t bfree; /* # free bytes in buffer (not dma or xmit) */
|
||||
u_int32_t start, stop; /* ends of buffer area (byte offset) */
|
||||
u_int32_t cur; /* next free area (byte offset) */
|
||||
u_int32_t nref; /* # of VCs using this channel */
|
||||
struct ifqueue indma; /* mbufs being dma'd now */
|
||||
struct ifqueue q; /* mbufs waiting for dma now */
|
||||
} txslot[MID_NTX_CH];
|
||||
|
||||
/* xmit vc ctrl. (per vc) */
|
||||
u_int8_t txspeed[MID_N_VC]; /* speed of tx on a VC */
|
||||
u_int8_t txvc2slot[MID_N_VC]; /* map VC to slot */
|
||||
|
||||
/* recv vc ctrl. (per vc). maps VC number to recv slot */
|
||||
u_int16_t rxvc2slot[MID_N_VC];
|
||||
int en_nrx; /* # of active rx slots */
|
||||
|
||||
/* recv buf ctrl. (per recv slot) */
|
||||
struct {
|
||||
void *rxhand; /* recv. handle if doing direct delivery */
|
||||
u_int32_t mode; /* saved copy of mode info */
|
||||
u_int32_t start, stop; /* ends of my buffer area */
|
||||
u_int32_t cur; /* where I am at */
|
||||
u_int16_t atm_vci; /* backpointer to VCI */
|
||||
u_int8_t atm_flags; /* copy of atm_flags from atm_ph */
|
||||
u_int8_t oth_flags; /* other flags */
|
||||
u_int32_t raw_threshold; /* for raw mode */
|
||||
struct ifqueue indma; /* mbufs being dma'd now */
|
||||
struct ifqueue q; /* mbufs waiting for dma now */
|
||||
} rxslot[EN_MAXNRX]; /* recv info */
|
||||
|
||||
/* stats */
|
||||
u_int32_t vtrash; /* sw copy of counter */
|
||||
u_int32_t otrash; /* sw copy of counter */
|
||||
u_int32_t ttrash; /* # of RBD's with T bit set */
|
||||
u_int32_t mfix; /* # of times we had to call mfix */
|
||||
u_int32_t mfixfail; /* # of times mfix failed */
|
||||
u_int32_t headbyte; /* # of times we used BYTE DMA at front */
|
||||
u_int32_t tailbyte; /* # of times we used BYTE DMA at end */
|
||||
u_int32_t tailflush; /* # of times we had to FLUSH out DMA bytes */
|
||||
u_int32_t txmbovr; /* # of times we dropped due to mbsize */
|
||||
u_int32_t dmaovr; /* tx dma overflow count */
|
||||
u_int32_t txoutspace; /* out of space in xmit buffer */
|
||||
u_int32_t txdtqout; /* out of DTQs */
|
||||
u_int32_t launch; /* total # of launches */
|
||||
u_int32_t lheader; /* # of launches without OB header */
|
||||
u_int32_t ltail; /* # of launches without OB tail */
|
||||
u_int32_t hwpull; /* # of pulls off hardware service list */
|
||||
u_int32_t swadd; /* # of pushes on sw service list */
|
||||
u_int32_t rxqnotus; /* # of times we pull from rx q, but fail */
|
||||
u_int32_t rxqus; /* # of good pulls from rx q */
|
||||
u_int32_t rxoutboth; /* # of times out of mbufs and DRQs */
|
||||
u_int32_t rxdrqout; /* # of times out of DRQs */
|
||||
u_int32_t rxmbufout; /* # of time out of mbufs */
|
||||
|
||||
/* random stuff */
|
||||
u_int32_t ipl; /* sbus interrupt lvl (1 on pci?) */
|
||||
u_int8_t bestburstcode; /* code of best burst we can use */
|
||||
u_int8_t bestburstlen; /* length of best burst (bytes) */
|
||||
u_int8_t bestburstshift; /* (x >> shift) == (x / bestburstlen) */
|
||||
u_int8_t bestburstmask; /* bits to check if not multiple of burst */
|
||||
u_int8_t alburst; /* align dma bursts? */
|
||||
u_int8_t is_adaptec; /* adaptec version of midway? */
|
||||
};
|
||||
|
||||
/*
|
||||
* exported functions
|
||||
*/
|
||||
|
||||
void en_attach __P((struct en_softc *));
|
||||
EN_INTR_TYPE en_intr __P((void *));
|
||||
void en_reset __P((struct en_softc *));
|
111
sys/net/if_atm.h
Normal file
111
sys/net/if_atm.h
Normal file
@ -0,0 +1,111 @@
|
||||
/* $NetBSD: if_atm.h,v 1.7 1996/11/09 23:02:27 chuck Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1996 Charles D. Cranor and Washington University.
|
||||
* 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 Charles D. Cranor and
|
||||
* Washington University.
|
||||
* 4. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* net/if_atm.h
|
||||
*/
|
||||
|
||||
#if (defined(__FreeBSD__) || defined(__bsdi__)) && defined(KERNEL)
|
||||
#ifndef _KERNEL
|
||||
#define _KERNEL
|
||||
#endif
|
||||
#endif /* freebsd doesn't define _KERNEL */
|
||||
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)
|
||||
#define RTALLOC1(A,B) rtalloc1((A),(B))
|
||||
#elif defined(__FreeBSD__)
|
||||
#define RTALLOC1(A,B) rtalloc1((A),(B),0UL)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* pseudo header for packet transmission
|
||||
*/
|
||||
|
||||
struct atm_pseudohdr {
|
||||
u_int8_t atm_ph[4]; /* flags+VPI+VCI1(msb)+VCI2(lsb) */
|
||||
};
|
||||
|
||||
#define ATM_PH_FLAGS(X) ((X)->atm_ph[0])
|
||||
#define ATM_PH_VPI(X) ((X)->atm_ph[1])
|
||||
#define ATM_PH_VCI(X) ((((X)->atm_ph[2]) << 8) | ((X)->atm_ph[3]))
|
||||
#define ATM_PH_SETVCI(X,V) { \
|
||||
(X)->atm_ph[2] = ((V) >> 8) & 0xff; \
|
||||
(X)->atm_ph[3] = ((V) & 0xff); \
|
||||
}
|
||||
|
||||
#define ATM_PH_AAL5 0x01 /* use AAL5? (0 == aal0) */
|
||||
#define ATM_PH_LLCSNAP 0x02 /* use the LLC SNAP encoding (iff aal5) */
|
||||
|
||||
#define ATM_PH_DRIVER7 0x40 /* reserve for driver's use */
|
||||
#define ATM_PH_DRIVER8 0x80 /* reserve for driver's use */
|
||||
|
||||
#define ATMMTU 9180 /* ATM MTU size for IP */
|
||||
/* XXX: could be 9188 with LLC/SNAP according
|
||||
to comer */
|
||||
|
||||
/* user's ioctl hook for raw atm mode */
|
||||
#define SIOCRAWATM _IOWR('a', 122, int) /* set driver's raw mode */
|
||||
|
||||
/* atm_pseudoioctl: turns on and off RX VCIs [for internal use only!] */
|
||||
struct atm_pseudoioctl {
|
||||
struct atm_pseudohdr aph;
|
||||
void *rxhand;
|
||||
};
|
||||
#define SIOCATMENA _IOWR('a', 123, struct atm_pseudoioctl) /* enable */
|
||||
#define SIOCATMDIS _IOWR('a', 124, struct atm_pseudoioctl) /* disable */
|
||||
|
||||
/*
|
||||
* XXX forget all the garbage in if_llc.h and do it the easy way
|
||||
*/
|
||||
|
||||
#define ATMLLC_HDR "\252\252\3\0\0\0"
|
||||
struct atmllc {
|
||||
u_int8_t llchdr[6]; /* aa.aa.03.00.00.00 */
|
||||
u_int8_t type[2]; /* "ethernet" type */
|
||||
};
|
||||
|
||||
/* ATM_LLC macros: note type code in host byte order */
|
||||
#define ATM_LLC_TYPE(X) (((X)->type[0] << 8) | ((X)->type[1]))
|
||||
#define ATM_LLC_SETTYPE(X,V) { \
|
||||
(X)->type[1] = ((V) >> 8) & 0xff; \
|
||||
(X)->type[0] = ((V) & 0xff); \
|
||||
}
|
||||
|
||||
#ifdef _KERNEL
|
||||
void atm_ifattach __P((struct ifnet *));
|
||||
void atm_input __P((struct ifnet *, struct atm_pseudohdr *,
|
||||
struct mbuf *, void *));
|
||||
int atm_output __P((struct ifnet *, struct mbuf *, struct sockaddr *,
|
||||
struct rtentry *));
|
||||
#endif
|
410
sys/net/if_atmsubr.c
Normal file
410
sys/net/if_atmsubr.c
Normal file
@ -0,0 +1,410 @@
|
||||
/* $NetBSD: if_atmsubr.c,v 1.10 1997/03/11 23:19:51 chuck Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1996 Charles D. Cranor and Washington University.
|
||||
* 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 Charles D. Cranor and
|
||||
* Washington University.
|
||||
* 4. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* if_atmsubr.c
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/sockio.h>
|
||||
#else
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#include <sys/errno.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/netisr.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_atm.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/if_atm.h>
|
||||
#include <netinet/if_ether.h> /* XXX: for ETHERTYPE_* */
|
||||
#ifdef INET
|
||||
#include <netinet/in_var.h>
|
||||
#endif
|
||||
#ifdef NATM
|
||||
#include <netnatm/natm.h>
|
||||
#endif
|
||||
|
||||
#include "bpfilter.h"
|
||||
#if NBPFILTER > 0
|
||||
/*
|
||||
* bpf support.
|
||||
* the code is derived from if_loop.c.
|
||||
* bpf support should belong to the driver but it's easier to implement
|
||||
* it here since we can call bpf_mtap before atm_output adds a pseudo
|
||||
* header to the mbuf.
|
||||
* --kjc
|
||||
*/
|
||||
#include <sys/time.h>
|
||||
#include <net/bpf.h>
|
||||
#endif /* NBPFILTER > 0 */
|
||||
|
||||
#define senderr(e) { error = (e); goto bad;}
|
||||
|
||||
/*
|
||||
* atm_output: ATM output routine
|
||||
* inputs:
|
||||
* "ifp" = ATM interface to output to
|
||||
* "m0" = the packet to output
|
||||
* "dst" = the sockaddr to send to (either IP addr, or raw VPI/VCI)
|
||||
* "rt0" = the route to use
|
||||
* returns: error code [0 == ok]
|
||||
*
|
||||
* note: special semantic: if (dst == NULL) then we assume "m" already
|
||||
* has an atm_pseudohdr on it and just send it directly.
|
||||
* [for native mode ATM output] if dst is null, then
|
||||
* rt0 must also be NULL.
|
||||
*/
|
||||
|
||||
int
|
||||
atm_output(ifp, m0, dst, rt0)
|
||||
register struct ifnet *ifp;
|
||||
struct mbuf *m0;
|
||||
struct sockaddr *dst;
|
||||
struct rtentry *rt0;
|
||||
{
|
||||
u_int16_t etype = 0; /* if using LLC/SNAP */
|
||||
int s, error = 0, sz;
|
||||
struct atm_pseudohdr atmdst, *ad;
|
||||
register struct mbuf *m = m0;
|
||||
register struct rtentry *rt;
|
||||
struct atmllc *atmllc;
|
||||
u_int32_t atm_flags;
|
||||
|
||||
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
|
||||
senderr(ENETDOWN);
|
||||
ifp->if_lastchange = time;
|
||||
|
||||
/*
|
||||
* check route
|
||||
*/
|
||||
if ((rt = rt0) != NULL) {
|
||||
|
||||
if ((rt->rt_flags & RTF_UP) == 0) { /* route went down! */
|
||||
if ((rt0 = rt = RTALLOC1(dst, 0)) != NULL)
|
||||
rt->rt_refcnt--;
|
||||
else
|
||||
senderr(EHOSTUNREACH);
|
||||
}
|
||||
|
||||
if (rt->rt_flags & RTF_GATEWAY) {
|
||||
if (rt->rt_gwroute == 0)
|
||||
goto lookup;
|
||||
if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
|
||||
rtfree(rt); rt = rt0;
|
||||
lookup: rt->rt_gwroute = RTALLOC1(rt->rt_gateway, 0);
|
||||
if ((rt = rt->rt_gwroute) == 0)
|
||||
senderr(EHOSTUNREACH);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: put RTF_REJECT code here if doing ATMARP */
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* check for non-native ATM traffic (dst != NULL)
|
||||
*/
|
||||
if (dst) {
|
||||
switch (dst->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (!atmresolve(rt, m, dst, &atmdst)) {
|
||||
m = NULL;
|
||||
/* XXX: atmresolve already free'd it */
|
||||
senderr(EHOSTUNREACH);
|
||||
/* XXX: put ATMARP stuff here */
|
||||
/* XXX: watch who frees m on failure */
|
||||
}
|
||||
etype = htons(ETHERTYPE_IP);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
printf("%s: can't handle af%d\n", ifp->if_xname,
|
||||
dst->sa_family);
|
||||
#elif defined(__FreeBSD__) || defined(__bsdi__)
|
||||
printf("%s%d: can't handle af%d\n", ifp->if_name,
|
||||
ifp->if_unit, dst->sa_family);
|
||||
#endif
|
||||
senderr(EAFNOSUPPORT);
|
||||
}
|
||||
|
||||
#if NBPFILTER > 0
|
||||
/* BPF write needs to be handled specially */
|
||||
if (dst && dst->sa_family == AF_UNSPEC) {
|
||||
dst->sa_family = *(mtod(m, int *));
|
||||
m->m_len -= sizeof(int);
|
||||
m->m_pkthdr.len -= sizeof(int);
|
||||
m->m_data += sizeof(int);
|
||||
}
|
||||
|
||||
if (ifp->if_bpf) {
|
||||
/*
|
||||
* We need to prepend the address family as
|
||||
* a four byte field. Cons up a dummy header
|
||||
* to pacify bpf. This is safe because bpf
|
||||
* will only read from the mbuf (i.e., it won't
|
||||
* try to free it or keep a pointer a to it).
|
||||
*/
|
||||
struct mbuf m1;
|
||||
u_int af = dst->sa_family;
|
||||
|
||||
m1.m_next = m;
|
||||
m1.m_len = 4;
|
||||
m1.m_data = (char *)⁡
|
||||
|
||||
s = splimp();
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
bpf_mtap(&ifp->if_bpf, &m0);
|
||||
#elif defined(__FreeBSD__)
|
||||
bpf_mtap(ifp, &m1);
|
||||
#endif
|
||||
splx(s);
|
||||
}
|
||||
#endif /* NBPFILTER > 0 */
|
||||
|
||||
/*
|
||||
* must add atm_pseudohdr to data
|
||||
*/
|
||||
sz = sizeof(atmdst);
|
||||
atm_flags = ATM_PH_FLAGS(&atmdst);
|
||||
if (atm_flags & ATM_PH_LLCSNAP) sz += 8; /* sizeof snap == 8 */
|
||||
M_PREPEND(m, sz, M_DONTWAIT);
|
||||
if (m == 0)
|
||||
senderr(ENOBUFS);
|
||||
ad = mtod(m, struct atm_pseudohdr *);
|
||||
*ad = atmdst;
|
||||
if (atm_flags & ATM_PH_LLCSNAP) {
|
||||
atmllc = (struct atmllc *)(ad + 1);
|
||||
bcopy(ATMLLC_HDR, atmllc->llchdr,
|
||||
sizeof(atmllc->llchdr));
|
||||
ATM_LLC_SETTYPE(atmllc, etype);
|
||||
/* note: already in network order */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue message on interface, and start output if interface
|
||||
* not yet active.
|
||||
*/
|
||||
|
||||
s = splimp();
|
||||
if (IF_QFULL(&ifp->if_snd)) {
|
||||
IF_DROP(&ifp->if_snd);
|
||||
splx(s);
|
||||
senderr(ENOBUFS);
|
||||
}
|
||||
ifp->if_obytes += m->m_pkthdr.len;
|
||||
IF_ENQUEUE(&ifp->if_snd, m);
|
||||
if ((ifp->if_flags & IFF_OACTIVE) == 0)
|
||||
(*ifp->if_start)(ifp);
|
||||
splx(s);
|
||||
return (error);
|
||||
|
||||
bad:
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a received ATM packet;
|
||||
* the packet is in the mbuf chain m.
|
||||
*/
|
||||
void
|
||||
atm_input(ifp, ah, m, rxhand)
|
||||
struct ifnet *ifp;
|
||||
register struct atm_pseudohdr *ah;
|
||||
struct mbuf *m;
|
||||
void *rxhand;
|
||||
{
|
||||
register struct ifqueue *inq;
|
||||
u_int16_t etype = ETHERTYPE_IP; /* default */
|
||||
int s;
|
||||
|
||||
if ((ifp->if_flags & IFF_UP) == 0) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
ifp->if_lastchange = time;
|
||||
ifp->if_ibytes += m->m_pkthdr.len;
|
||||
|
||||
#if NBPFILTER > 0
|
||||
if (ifp->if_bpf) {
|
||||
/*
|
||||
* We need to prepend the address family as
|
||||
* a four byte field. Cons up a dummy header
|
||||
* to pacify bpf. This is safe because bpf
|
||||
* will only read from the mbuf (i.e., it won't
|
||||
* try to free it or keep a pointer to it).
|
||||
*/
|
||||
struct mbuf m0;
|
||||
u_int af = AF_INET;
|
||||
|
||||
m0.m_next = m;
|
||||
m0.m_len = 4;
|
||||
m0.m_data = (char *)⁡
|
||||
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
bpf_mtap(&ifp->if_bpf, &m0);
|
||||
#elif defined(__FreeBSD__)
|
||||
bpf_mtap(ifp, &m0);
|
||||
#endif
|
||||
}
|
||||
#endif /* NBPFILTER > 0 */
|
||||
|
||||
if (rxhand) {
|
||||
#ifdef NATM
|
||||
struct natmpcb *npcb = rxhand;
|
||||
s = splimp(); /* in case 2 atm cards @ diff lvls */
|
||||
npcb->npcb_inq++; /* count # in queue */
|
||||
splx(s);
|
||||
schednetisr(NETISR_NATM);
|
||||
inq = &natmintrq;
|
||||
m->m_pkthdr.rcvif = rxhand; /* XXX: overload */
|
||||
#else
|
||||
printf("atm_input: NATM detected but not configured in kernel\n");
|
||||
m_freem(m);
|
||||
return;
|
||||
#endif
|
||||
} else {
|
||||
/*
|
||||
* handle LLC/SNAP header, if present
|
||||
*/
|
||||
if (ATM_PH_FLAGS(ah) & ATM_PH_LLCSNAP) {
|
||||
struct atmllc *alc;
|
||||
if (m->m_len < sizeof(*alc) && (m = m_pullup(m, sizeof(*alc))) == 0)
|
||||
return; /* failed */
|
||||
alc = mtod(m, struct atmllc *);
|
||||
if (bcmp(alc, ATMLLC_HDR, 6)) {
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
printf("%s: recv'd invalid LLC/SNAP frame [vp=%d,vc=%d]\n",
|
||||
ifp->if_xname, ATM_PH_VPI(ah), ATM_PH_VCI(ah));
|
||||
#elif defined(__FreeBSD__) || defined(__bsdi__)
|
||||
printf("%s%d: recv'd invalid LLC/SNAP frame [vp=%d,vc=%d]\n",
|
||||
ifp->if_name, ifp->if_unit, ATM_PH_VPI(ah), ATM_PH_VCI(ah));
|
||||
#endif
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
etype = ATM_LLC_TYPE(alc);
|
||||
m_adj(m, sizeof(*alc));
|
||||
}
|
||||
|
||||
switch (etype) {
|
||||
#ifdef INET
|
||||
case ETHERTYPE_IP:
|
||||
schednetisr(NETISR_IP);
|
||||
inq = &ipintrq;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
s = splimp();
|
||||
if (IF_QFULL(inq)) {
|
||||
IF_DROP(inq);
|
||||
m_freem(m);
|
||||
} else
|
||||
IF_ENQUEUE(inq, m);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform common duties while attaching to interface list
|
||||
*/
|
||||
void
|
||||
atm_ifattach(ifp)
|
||||
register struct ifnet *ifp;
|
||||
{
|
||||
register struct ifaddr *ifa;
|
||||
register struct sockaddr_dl *sdl;
|
||||
|
||||
ifp->if_type = IFT_ATM;
|
||||
ifp->if_addrlen = 0;
|
||||
ifp->if_hdrlen = 0;
|
||||
ifp->if_mtu = ATMMTU;
|
||||
ifp->if_output = atm_output;
|
||||
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;
|
||||
ifa = ifa->ifa_list.tqe_next)
|
||||
#elif defined(__FreeBSD__) && ((__FreeBSD__ > 2) || defined(_NET_IF_VAR_H_))
|
||||
/*
|
||||
* for FreeBSD-3.0. 3.0-SNAP-970124 still sets -D__FreeBSD__=2!
|
||||
* XXX -- for now, use newly-introduced "net/if_var.h" as an identifier.
|
||||
* need a better way to identify 3.0. -- kjc
|
||||
*/
|
||||
for (ifa = ifp->if_addrhead.tqh_first; ifa;
|
||||
ifa = ifa->ifa_link.tqe_next)
|
||||
#elif defined(__FreeBSD__) || defined(__bsdi__)
|
||||
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
|
||||
#endif
|
||||
|
||||
if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
|
||||
sdl->sdl_family == AF_LINK) {
|
||||
sdl->sdl_type = IFT_ATM;
|
||||
sdl->sdl_alen = ifp->if_addrlen;
|
||||
#ifdef notyet /* if using ATMARP, store hardware address using the next line */
|
||||
bcopy(ifp->hw_addr, LLADDR(sdl), ifp->if_addrlen);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#if NBPFILTER > 0
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
bpfattach(&ifp->if_bpf, ifp, DLT_NULL, sizeof(u_int));
|
||||
#elif defined(__FreeBSD__)
|
||||
bpfattach(ifp, DLT_NULL, sizeof(u_int));
|
||||
#endif
|
||||
#endif /* NBPFILTER > 0 */
|
||||
}
|
285
sys/netinet/if_atm.c
Normal file
285
sys/netinet/if_atm.c
Normal file
@ -0,0 +1,285 @@
|
||||
/* $NetBSD: if_atm.c,v 1.6 1996/10/13 02:03:01 christos Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1996 Charles D. Cranor and Washington University.
|
||||
* 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 Charles D. Cranor and
|
||||
* Washington University.
|
||||
* 4. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* IP <=> ATM address resolution.
|
||||
*/
|
||||
|
||||
#ifdef INET
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/errno.h>
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/sockio.h>
|
||||
#else
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/proc.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_atm.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/if_atm.h>
|
||||
|
||||
#ifdef NATM
|
||||
#include <netnatm/natm.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define SDL(s) ((struct sockaddr_dl *)s)
|
||||
|
||||
/*
|
||||
* atm_rtrequest: handle ATM rt request (in support of generic code)
|
||||
* inputs: "req" = request code
|
||||
* "rt" = route entry
|
||||
* "sa" = sockaddr
|
||||
*/
|
||||
|
||||
void
|
||||
atm_rtrequest(req, rt, sa)
|
||||
int req;
|
||||
register struct rtentry *rt;
|
||||
struct sockaddr *sa;
|
||||
{
|
||||
register struct sockaddr *gate = rt->rt_gateway;
|
||||
struct atm_pseudoioctl api;
|
||||
#ifdef NATM
|
||||
struct sockaddr_in *sin;
|
||||
struct natmpcb *npcb = NULL;
|
||||
struct atm_pseudohdr *aph;
|
||||
#endif
|
||||
static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
|
||||
|
||||
if (rt->rt_flags & RTF_GATEWAY) /* link level requests only */
|
||||
return;
|
||||
|
||||
switch (req) {
|
||||
|
||||
case RTM_RESOLVE: /* resolve: only happens when cloning */
|
||||
printf("atm_rtrequest: RTM_RESOLVE request detected?\n");
|
||||
break;
|
||||
|
||||
case RTM_ADD:
|
||||
|
||||
/*
|
||||
* route added by a command (e.g. ifconfig, route, arp...).
|
||||
*
|
||||
* first check to see if this is not a host route, in which
|
||||
* case we are being called via "ifconfig" to set the address.
|
||||
*/
|
||||
|
||||
if ((rt->rt_flags & RTF_HOST) == 0) {
|
||||
rt_setgate(rt,rt_key(rt),(struct sockaddr *)&null_sdl);
|
||||
gate = rt->rt_gateway;
|
||||
SDL(gate)->sdl_type = rt->rt_ifp->if_type;
|
||||
SDL(gate)->sdl_index = rt->rt_ifp->if_index;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((rt->rt_flags & RTF_CLONING) != 0) {
|
||||
printf("atm_rtrequest: cloning route detected?\n");
|
||||
break;
|
||||
}
|
||||
if (gate->sa_family != AF_LINK ||
|
||||
gate->sa_len < sizeof(null_sdl)) {
|
||||
log(LOG_DEBUG, "atm_rtrequest: bad gateway value");
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (rt->rt_ifp->if_ioctl == NULL) panic("atm null ioctl");
|
||||
#endif
|
||||
|
||||
#ifdef NATM
|
||||
/*
|
||||
* let native ATM know we are using this VCI/VPI
|
||||
* (i.e. reserve it)
|
||||
*/
|
||||
sin = (struct sockaddr_in *) rt_key(rt);
|
||||
if (sin->sin_family != AF_INET)
|
||||
goto failed;
|
||||
aph = (struct atm_pseudohdr *) LLADDR(SDL(gate));
|
||||
npcb = npcb_add(NULL, rt->rt_ifp, ATM_PH_VCI(aph),
|
||||
ATM_PH_VPI(aph));
|
||||
if (npcb == NULL)
|
||||
goto failed;
|
||||
npcb->npcb_flags |= NPCB_IP;
|
||||
npcb->ipaddr.s_addr = sin->sin_addr.s_addr;
|
||||
/* XXX: move npcb to llinfo when ATM ARP is ready */
|
||||
rt->rt_llinfo = (caddr_t) npcb;
|
||||
rt->rt_flags |= RTF_LLINFO;
|
||||
#endif
|
||||
/*
|
||||
* let the lower level know this circuit is active
|
||||
*/
|
||||
bcopy(LLADDR(SDL(gate)), &api.aph, sizeof(api.aph));
|
||||
api.rxhand = NULL;
|
||||
if (rt->rt_ifp->if_ioctl(rt->rt_ifp, SIOCATMENA,
|
||||
(caddr_t)&api) != 0) {
|
||||
printf("atm: couldn't add VC\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
SDL(gate)->sdl_type = rt->rt_ifp->if_type;
|
||||
SDL(gate)->sdl_index = rt->rt_ifp->if_index;
|
||||
|
||||
break;
|
||||
|
||||
failed:
|
||||
#ifdef NATM
|
||||
if (npcb) {
|
||||
npcb_free(npcb, NPCB_DESTROY);
|
||||
rt->rt_llinfo = NULL;
|
||||
rt->rt_flags &= ~RTF_LLINFO;
|
||||
}
|
||||
#endif
|
||||
rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0,
|
||||
rt_mask(rt), 0, (struct rtentry **) 0);
|
||||
break;
|
||||
|
||||
case RTM_DELETE:
|
||||
|
||||
#ifdef NATM
|
||||
/*
|
||||
* tell native ATM we are done with this VC
|
||||
*/
|
||||
|
||||
if (rt->rt_flags & RTF_LLINFO) {
|
||||
npcb_free((struct natmpcb *)rt->rt_llinfo,
|
||||
NPCB_DESTROY);
|
||||
rt->rt_llinfo = NULL;
|
||||
rt->rt_flags &= ~RTF_LLINFO;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* tell the lower layer to disable this circuit
|
||||
*/
|
||||
|
||||
bcopy(LLADDR(SDL(gate)), &api.aph, sizeof(api.aph));
|
||||
api.rxhand = NULL;
|
||||
(void)rt->rt_ifp->if_ioctl(rt->rt_ifp, SIOCATMDIS,
|
||||
(caddr_t)&api);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* atmresolve:
|
||||
* inputs:
|
||||
* [1] "rt" = the link level route to use (or null if need to look one up)
|
||||
* [2] "m" = mbuf containing the data to be sent
|
||||
* [3] "dst" = sockaddr_in (IP) address of dest.
|
||||
* output:
|
||||
* [4] "desten" = ATM pseudo header which we will fill in VPI/VCI info
|
||||
* return:
|
||||
* 0 == resolve FAILED; note that "m" gets m_freem'd in this case
|
||||
* 1 == resolve OK; desten contains result
|
||||
*
|
||||
* XXX: will need more work if we wish to support ATMARP in the kernel,
|
||||
* but this is enough for PVCs entered via the "route" command.
|
||||
*/
|
||||
|
||||
int
|
||||
atmresolve(rt, m, dst, desten)
|
||||
|
||||
register struct rtentry *rt;
|
||||
struct mbuf *m;
|
||||
register struct sockaddr *dst;
|
||||
register struct atm_pseudohdr *desten; /* OUT */
|
||||
|
||||
{
|
||||
struct sockaddr_dl *sdl;
|
||||
|
||||
if (m->m_flags & (M_BCAST|M_MCAST)) {
|
||||
log(LOG_INFO, "atmresolve: BCAST/MCAST packet detected/dumped");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (rt == NULL) {
|
||||
rt = RTALLOC1(dst, 0);
|
||||
if (rt == NULL) goto bad; /* failed */
|
||||
rt->rt_refcnt--; /* don't keep LL references */
|
||||
if ((rt->rt_flags & RTF_GATEWAY) != 0 ||
|
||||
(rt->rt_flags & RTF_LLINFO) == 0 ||
|
||||
/* XXX: are we using LLINFO? */
|
||||
rt->rt_gateway->sa_family != AF_LINK) {
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* note that rt_gateway is a sockaddr_dl which contains the
|
||||
* atm_pseudohdr data structure for this route. we currently
|
||||
* don't need any rt_llinfo info (but will if we want to support
|
||||
* ATM ARP [c.f. if_ether.c]).
|
||||
*/
|
||||
|
||||
sdl = SDL(rt->rt_gateway);
|
||||
|
||||
/*
|
||||
* Check the address family and length is valid, the address
|
||||
* is resolved; otherwise, try to resolve.
|
||||
*/
|
||||
|
||||
|
||||
if (sdl->sdl_family == AF_LINK && sdl->sdl_alen == sizeof(*desten)) {
|
||||
bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
|
||||
return(1); /* ok, go for it! */
|
||||
}
|
||||
|
||||
/*
|
||||
* we got an entry, but it doesn't have valid link address
|
||||
* info in it (it is prob. the interface route, which has
|
||||
* sdl_alen == 0). dump packet. (fall through to "bad").
|
||||
*/
|
||||
|
||||
bad:
|
||||
m_freem(m);
|
||||
return(0);
|
||||
}
|
||||
#endif /* INET */
|
41
sys/netinet/if_atm.h
Normal file
41
sys/netinet/if_atm.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* $NetBSD: if_atm.h,v 1.2 1996/07/03 17:17:17 chuck Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1996 Charles D. Cranor and Washington University.
|
||||
* 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 Charles D. Cranor and
|
||||
* Washington University.
|
||||
* 4. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* if_atm.h
|
||||
*/
|
||||
|
||||
void atm_rtrequest __P((int, struct rtentry *, struct sockaddr *));
|
||||
int atmresolve __P((struct rtentry *, struct mbuf *, struct sockaddr *,
|
||||
struct atm_pseudohdr *));
|
161
sys/netnatm/natm.h
Normal file
161
sys/netnatm/natm.h
Normal file
@ -0,0 +1,161 @@
|
||||
/* $NetBSD: natm.h,v 1.1 1996/07/04 03:20:12 chuck Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1996 Charles D. Cranor and Washington University.
|
||||
* 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 Charles D. Cranor and
|
||||
* Washington University.
|
||||
* 4. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* natm.h: native mode atm
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* supported protocols
|
||||
*/
|
||||
|
||||
#define PROTO_NATMAAL0 1
|
||||
#define PROTO_NATMAAL5 2
|
||||
|
||||
/*
|
||||
* sockaddr_natm
|
||||
*/
|
||||
|
||||
struct sockaddr_natm {
|
||||
u_int8_t snatm_len; /* length */
|
||||
u_int8_t snatm_family; /* AF_NATM */
|
||||
char snatm_if[IFNAMSIZ]; /* interface name */
|
||||
u_int16_t snatm_vci; /* vci */
|
||||
u_int8_t snatm_vpi; /* vpi */
|
||||
};
|
||||
|
||||
|
||||
#if defined(__FreeBSD__) && defined(KERNEL)
|
||||
|
||||
#ifndef _KERNEL
|
||||
#define _KERNEL
|
||||
#endif
|
||||
|
||||
#define SPLSOFTNET() splnet()
|
||||
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
|
||||
#define SPLSOFTNET() splsoftnet()
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
* natm protocol control block
|
||||
*/
|
||||
|
||||
struct natmpcb {
|
||||
LIST_ENTRY(natmpcb) pcblist; /* list pointers */
|
||||
u_int npcb_inq; /* # of our pkts in proto q */
|
||||
struct socket *npcb_socket; /* backpointer to socket */
|
||||
struct ifnet *npcb_ifp; /* pointer to hardware */
|
||||
struct in_addr ipaddr; /* remote IP address, if APCB_IP */
|
||||
u_int16_t npcb_vci; /* VCI */
|
||||
u_int8_t npcb_vpi; /* VPI */
|
||||
u_int8_t npcb_flags; /* flags */
|
||||
};
|
||||
|
||||
/* flags */
|
||||
#define NPCB_FREE 0x01 /* free (not on any list) */
|
||||
#define NPCB_CONNECTED 0x02 /* connected */
|
||||
#define NPCB_IP 0x04 /* used by IP */
|
||||
#define NPCB_DRAIN 0x08 /* destory as soon as inq == 0 */
|
||||
#define NPCB_RAW 0x10 /* in 'raw' mode? */
|
||||
|
||||
/* flag arg to npcb_free */
|
||||
#define NPCB_REMOVE 0 /* remove from global list */
|
||||
#define NPCB_DESTROY 1 /* destroy and be free */
|
||||
|
||||
/*
|
||||
* NPCB_RAWCC is a hack which applies to connections in 'raw' mode. it
|
||||
* is used to override the sbspace() macro when you *really* don't want
|
||||
* to drop rcv data. the recv socket buffer size is raised to this value.
|
||||
*
|
||||
* XXX: socket buffering needs to be looked at.
|
||||
*/
|
||||
|
||||
#define NPCB_RAWCC (1024*1024) /* 1MB */
|
||||
|
||||
LIST_HEAD(npcblist, natmpcb);
|
||||
|
||||
/* global data structures */
|
||||
|
||||
struct npcblist natm_pcbs; /* global list of pcbs */
|
||||
extern struct ifqueue natmintrq; /* natm packet input queue */
|
||||
#define NATM_STAT
|
||||
#ifdef NATM_STAT
|
||||
extern u_int natm_sodropcnt,
|
||||
natm_sodropbytes; /* account of droppage */
|
||||
extern u_int natm_sookcnt,
|
||||
natm_sookbytes; /* account of ok */
|
||||
#endif
|
||||
|
||||
/* atm_rawioctl: kernel's version of SIOCRAWATM [for internal use only!] */
|
||||
struct atm_rawioctl {
|
||||
struct natmpcb *npcb;
|
||||
int rawvalue;
|
||||
};
|
||||
#define SIOCXRAWATM _IOWR('a', 125, struct atm_rawioctl)
|
||||
|
||||
/* external functions */
|
||||
|
||||
/* natm_pcb.c */
|
||||
struct natmpcb *npcb_alloc __P((int));
|
||||
void npcb_free __P((struct natmpcb *, int));
|
||||
struct natmpcb *npcb_add __P((struct natmpcb *, struct ifnet *, int, int));
|
||||
|
||||
/* natm.c */
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
int natm_usrreq __P((struct socket *, int, struct mbuf *,
|
||||
struct mbuf *, struct mbuf *, struct proc *));
|
||||
#elif defined(__FreeBSD__)
|
||||
#if __FreeBSD__ > 2
|
||||
/*
|
||||
* FreeBSD new usrreqs style appeared since 2.2. compatibility to old style
|
||||
* has gone since 3.0.
|
||||
*/
|
||||
#define FREEBSD_USRREQS
|
||||
extern struct pr_usrreqs natm_usrreqs;
|
||||
#else /* !( __FreeBSD__ > 2) */
|
||||
int natm_usrreq __P((struct socket *, int, struct mbuf *,
|
||||
struct mbuf *, struct mbuf *));
|
||||
#endif /* !( __FreeBSD__ > 2) */
|
||||
#endif
|
||||
int natm0_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
|
||||
int natm5_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
|
||||
void natmintr __P((void));
|
||||
|
||||
#endif
|
194
sys/netnatm/natm_pcb.c
Normal file
194
sys/netnatm/natm_pcb.c
Normal file
@ -0,0 +1,194 @@
|
||||
/* $NetBSD: natm_pcb.c,v 1.4 1996/11/09 03:26:27 chuck Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1996 Charles D. Cranor and Washington University.
|
||||
* 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 Charles D. Cranor and
|
||||
* Washington University.
|
||||
* 4. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* atm_pcb.c: manage atm protocol control blocks and keep IP and NATM
|
||||
* from trying to use each other's VCs.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/radix.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <netnatm/natm.h>
|
||||
|
||||
/*
|
||||
* npcb_alloc: allocate a npcb [in the free state]
|
||||
*/
|
||||
|
||||
struct natmpcb *npcb_alloc(wait)
|
||||
|
||||
int wait;
|
||||
|
||||
{
|
||||
struct natmpcb *npcb;
|
||||
|
||||
MALLOC(npcb, struct natmpcb *, sizeof(*npcb), M_PCB, wait);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (wait == M_WAITOK && npcb == NULL) panic("npcb_alloc: malloc didn't wait");
|
||||
#endif
|
||||
|
||||
if (npcb) {
|
||||
bzero(npcb, sizeof(*npcb));
|
||||
npcb->npcb_flags = NPCB_FREE;
|
||||
}
|
||||
return(npcb);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* npcb_free: free a npcb
|
||||
*/
|
||||
|
||||
void npcb_free(npcb, op)
|
||||
|
||||
struct natmpcb *npcb;
|
||||
int op;
|
||||
|
||||
{
|
||||
int s = splimp();
|
||||
|
||||
if ((npcb->npcb_flags & NPCB_FREE) == 0) {
|
||||
LIST_REMOVE(npcb, pcblist);
|
||||
npcb->npcb_flags = NPCB_FREE;
|
||||
}
|
||||
if (op == NPCB_DESTROY) {
|
||||
if (npcb->npcb_inq) {
|
||||
npcb->npcb_flags = NPCB_DRAIN; /* flag for distruction */
|
||||
} else {
|
||||
FREE(npcb, M_PCB); /* kill it! */
|
||||
}
|
||||
}
|
||||
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* npcb_add: add or remove npcb from main list
|
||||
* returns npcb if ok
|
||||
*/
|
||||
|
||||
struct natmpcb *npcb_add(npcb, ifp, vci, vpi)
|
||||
|
||||
struct natmpcb *npcb;
|
||||
struct ifnet *ifp;
|
||||
u_int16_t vci;
|
||||
u_int8_t vpi;
|
||||
|
||||
{
|
||||
struct natmpcb *cpcb = NULL; /* current pcb */
|
||||
int s = splimp();
|
||||
|
||||
|
||||
/*
|
||||
* lookup required
|
||||
*/
|
||||
|
||||
for (cpcb = natm_pcbs.lh_first ; cpcb != NULL ;
|
||||
cpcb = cpcb->pcblist.le_next) {
|
||||
if (ifp == cpcb->npcb_ifp && vci == cpcb->npcb_vci && vpi == cpcb->npcb_vpi)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* add & something already there?
|
||||
*/
|
||||
|
||||
if (cpcb) {
|
||||
cpcb = NULL;
|
||||
goto done; /* fail */
|
||||
}
|
||||
|
||||
/*
|
||||
* need to allocate a pcb?
|
||||
*/
|
||||
|
||||
if (npcb == NULL) {
|
||||
cpcb = npcb_alloc(M_NOWAIT); /* could be called from lower half */
|
||||
if (cpcb == NULL)
|
||||
goto done; /* fail */
|
||||
} else {
|
||||
cpcb = npcb;
|
||||
}
|
||||
|
||||
cpcb->npcb_ifp = ifp;
|
||||
cpcb->ipaddr.s_addr = 0;
|
||||
cpcb->npcb_vci = vci;
|
||||
cpcb->npcb_vpi = vpi;
|
||||
cpcb->npcb_flags = NPCB_CONNECTED;
|
||||
|
||||
LIST_INSERT_HEAD(&natm_pcbs, cpcb, pcblist);
|
||||
|
||||
done:
|
||||
splx(s);
|
||||
return(cpcb);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef DDB
|
||||
|
||||
int npcb_dump __P((void));
|
||||
|
||||
int npcb_dump()
|
||||
|
||||
{
|
||||
struct natmpcb *cpcb;
|
||||
|
||||
printf("npcb dump:\n");
|
||||
for (cpcb = natm_pcbs.lh_first ; cpcb != NULL ;
|
||||
cpcb = cpcb->pcblist.le_next) {
|
||||
printf("if=%s, vci=%d, vpi=%d, IP=0x%x, sock=%p, flags=0x%x, inq=%d\n",
|
||||
cpcb->npcb_ifp->if_xname, cpcb->npcb_vci, cpcb->npcb_vpi,
|
||||
cpcb->ipaddr.s_addr, cpcb->npcb_socket,
|
||||
cpcb->npcb_flags, cpcb->npcb_inq);
|
||||
}
|
||||
printf("done\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
#endif
|
131
sys/netnatm/natm_proto.c
Normal file
131
sys/netnatm/natm_proto.c
Normal file
@ -0,0 +1,131 @@
|
||||
/* $NetBSD: natm_proto.c,v 1.3 1996/09/18 00:56:41 chuck Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1996 Charles D. Cranor and Washington University.
|
||||
* 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 Charles D. Cranor and
|
||||
* Washington University.
|
||||
* 4. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* protocol layer for access to native mode ATM
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/mbuf.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/radix.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <netnatm/natm.h>
|
||||
|
||||
extern struct domain natmdomain;
|
||||
|
||||
static void natm_init __P((void));
|
||||
|
||||
struct protosw natmsw[] = {
|
||||
{ SOCK_STREAM, &natmdomain, PROTO_NATMAAL5, PR_CONNREQUIRED,
|
||||
0, 0, 0, 0,
|
||||
#ifdef FREEBSD_USRREQS
|
||||
0,
|
||||
#else
|
||||
natm_usrreq,
|
||||
#endif
|
||||
0, 0, 0, 0,
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
natm5_sysctl
|
||||
#elif defined(FREEBSD_USRREQS)
|
||||
&natm_usrreqs
|
||||
#endif
|
||||
},
|
||||
{ SOCK_DGRAM, &natmdomain, PROTO_NATMAAL5, PR_CONNREQUIRED | PR_ATOMIC,
|
||||
0, 0, 0, 0,
|
||||
#ifdef FREEBSD_USRREQS
|
||||
0,
|
||||
#else
|
||||
natm_usrreq,
|
||||
#endif
|
||||
0, 0, 0, 0,
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
natm5_sysctl
|
||||
#elif defined(FREEBSD_USRREQS)
|
||||
&natm_usrreqs
|
||||
#endif
|
||||
},
|
||||
{ SOCK_STREAM, &natmdomain, PROTO_NATMAAL0, PR_CONNREQUIRED,
|
||||
0, 0, 0, 0,
|
||||
#ifdef FREEBSD_USRREQS
|
||||
0,
|
||||
#else
|
||||
natm_usrreq,
|
||||
#endif
|
||||
0, 0, 0, 0,
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
natm0_sysctl
|
||||
#elif defined(FREEBSD_USRREQS)
|
||||
&natm_usrreqs
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
struct domain natmdomain =
|
||||
{ AF_NATM, "natm", natm_init, 0, 0,
|
||||
natmsw, &natmsw[sizeof(natmsw)/sizeof(natmsw[0])], 0,
|
||||
0, 0, 0};
|
||||
|
||||
struct ifqueue natmintrq; /* natm packet input queue */
|
||||
int natmqmaxlen = IFQ_MAXLEN; /* max # of packets on queue */
|
||||
#ifdef NATM_STAT
|
||||
u_int natm_sodropcnt = 0; /* # mbufs dropped due to full sb */
|
||||
u_int natm_sodropbytes = 0; /* # of bytes dropped */
|
||||
u_int natm_sookcnt = 0; /* # mbufs ok */
|
||||
u_int natm_sookbytes = 0; /* # of bytes ok */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void natm_init()
|
||||
|
||||
{
|
||||
LIST_INIT(&natm_pcbs);
|
||||
bzero(&natmintrq, sizeof(natmintrq));
|
||||
natmintrq.ifq_maxlen = natmqmaxlen;
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
DOMAIN_SET(natm);
|
||||
#endif
|
348
sys/pci/if_en_pci.c
Normal file
348
sys/pci/if_en_pci.c
Normal file
@ -0,0 +1,348 @@
|
||||
/* $NetBSD: if_en_pci.c,v 1.1 1996/06/22 02:00:31 chuck Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1996 Charles D. Cranor and Washington University.
|
||||
* 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 Charles D. Cranor and
|
||||
* Washington University.
|
||||
* 4. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* i f _ e n _ p c i . c
|
||||
*
|
||||
* author: Chuck Cranor <chuck@ccrc.wustl.edu>
|
||||
* started: spring, 1996.
|
||||
*
|
||||
* FreeBSD PCI glue for the eni155p card.
|
||||
* thanks to Matt Thomas for figuring out FreeBSD vs NetBSD vs etc.. diffs.
|
||||
*/
|
||||
|
||||
#include "en.h"
|
||||
#include "pci.h"
|
||||
#if (NEN > 0) && (NPCI > 0)
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#ifndef SHUTDOWN_PRE_SYNC
|
||||
/*
|
||||
* device shutdown mechanism has been changed since 2.2-ALPHA.
|
||||
* if SHUTDOWN_PRE_SYNC is defined in "sys/systm.h", use new one.
|
||||
* otherwise, use old one.
|
||||
* new: 2.2-ALPHA, 2.2-BETA, 2.2-GAMME, 2.2-RELEASE, 3.0
|
||||
* old: 2.1.5, 2.1.6, 2.2-SNAP
|
||||
* -- kjc
|
||||
*/
|
||||
#include <sys/devconf.h>
|
||||
#endif
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
|
||||
#include <machine/cpufunc.h> /* for rdtsc proto for clock.h below */
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <pci/pcivar.h>
|
||||
#include <pci/pcireg.h>
|
||||
|
||||
#include <dev/en/midwayreg.h>
|
||||
#include <dev/en/midwayvar.h>
|
||||
|
||||
|
||||
/*
|
||||
* prototypes
|
||||
*/
|
||||
|
||||
static void en_pci_attach __P((pcici_t, int));
|
||||
static char *en_pci_probe __P((pcici_t, pcidi_t));
|
||||
#ifdef SHUTDOWN_PRE_SYNC
|
||||
static void en_pci_shutdown __P((int, void *));
|
||||
#else
|
||||
static int en_pci_shutdown __P((struct kern_devconf *, int));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* local structures
|
||||
*/
|
||||
|
||||
struct en_pci_softc {
|
||||
/* bus independent stuff */
|
||||
struct en_softc esc; /* includes "device" structure */
|
||||
|
||||
/* PCI bus glue */
|
||||
void *sc_ih; /* interrupt handle */
|
||||
pci_chipset_tag_t en_pc; /* for PCI calls */
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* pointers to softcs (we alloc)
|
||||
*/
|
||||
|
||||
static struct en_pci_softc *enpcis[NEN] = {0};
|
||||
extern struct cfdriver en_cd;
|
||||
|
||||
/*
|
||||
* autoconfig structures
|
||||
*/
|
||||
|
||||
static u_long en_pci_count;
|
||||
|
||||
static struct pci_device endevice = {
|
||||
"en",
|
||||
en_pci_probe,
|
||||
en_pci_attach,
|
||||
&en_pci_count,
|
||||
#ifdef SHUTDOWN_PRE_SYNC
|
||||
NULL,
|
||||
#else
|
||||
en_pci_shutdown,
|
||||
#endif
|
||||
};
|
||||
|
||||
DATA_SET (pcidevice_set, endevice);
|
||||
|
||||
/*
|
||||
* local defines (PCI specific stuff)
|
||||
*/
|
||||
|
||||
/*
|
||||
* address of config base memory address register in PCI config space
|
||||
* (this is card specific)
|
||||
*/
|
||||
|
||||
#define PCI_CBMA 0x10
|
||||
|
||||
/*
|
||||
* tonga (pci bridge). ENI cards only!
|
||||
*/
|
||||
|
||||
#define EN_TONGA 0x60 /* PCI config addr of tonga reg */
|
||||
|
||||
#define TONGA_SWAP_DMA 0x80 /* endian swap control */
|
||||
#define TONGA_SWAP_BYTE 0x40
|
||||
#define TONGA_SWAP_WORD 0x20
|
||||
|
||||
/*
|
||||
* adaptec pci bridge. ADP cards only!
|
||||
*/
|
||||
|
||||
#define ADP_PCIREG 0x050040 /* PCI control register */
|
||||
|
||||
#define ADP_PCIREG_RESET 0x1 /* reset card */
|
||||
#define ADP_PCIREG_IENABLE 0x2 /* interrupt enable */
|
||||
#define ADP_PCIREG_SWAP_WORD 0x4 /* swap byte on slave access */
|
||||
#define ADP_PCIREG_SWAP_DMA 0x8 /* swap byte on DMA */
|
||||
|
||||
#define PCI_VENDOR_EFFICIENTNETS 0x111a /* Efficent Networks */
|
||||
#define PCI_PRODUCT_EFFICIENTNETS_ENI155PF 0x0000 /* ENI-155P ATM */
|
||||
#define PCI_PRODUCT_EFFICIENTNETS_ENI155PA 0x0002 /* ENI-155P ATM */
|
||||
#define PCI_VENDOR_ADP 0x9004 /* adaptec */
|
||||
#define PCI_PRODUCT_ADP_AIC5900 0x5900
|
||||
#define PCI_PRODUCT_ADP_AIC5905 0x5905
|
||||
#define PCI_VENDOR(x) ((x) & 0xFFFF)
|
||||
#define PCI_CHIPID(x) (((x) >> 16) & 0xFFFF)
|
||||
|
||||
#if !defined(MIDWAY_ENIONLY)
|
||||
|
||||
static void adp_busreset __P((void *));
|
||||
|
||||
/*
|
||||
* bus specific reset function [ADP only!]
|
||||
*/
|
||||
|
||||
static void adp_busreset(v)
|
||||
|
||||
void *v;
|
||||
|
||||
{
|
||||
struct en_softc *sc = (struct en_softc *) v;
|
||||
u_int32_t dummy;
|
||||
|
||||
bus_space_write_4(sc->en_memt, sc->en_base, ADP_PCIREG, ADP_PCIREG_RESET);
|
||||
DELAY(1000); /* let it reset */
|
||||
dummy = bus_space_read_4(sc->en_memt, sc->en_base, ADP_PCIREG);
|
||||
bus_space_write_4(sc->en_memt, sc->en_base, ADP_PCIREG,
|
||||
(ADP_PCIREG_SWAP_WORD|ADP_PCIREG_SWAP_DMA|ADP_PCIREG_IENABLE));
|
||||
dummy = bus_space_read_4(sc->en_memt, sc->en_base, ADP_PCIREG);
|
||||
if ((dummy & (ADP_PCIREG_SWAP_WORD|ADP_PCIREG_SWAP_DMA)) !=
|
||||
(ADP_PCIREG_SWAP_WORD|ADP_PCIREG_SWAP_DMA))
|
||||
printf("adp_busreset: Adaptec ATM did NOT reset!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
/*
|
||||
* autoconfig stuff
|
||||
*/
|
||||
|
||||
static char *en_pci_probe(config_id, device_id)
|
||||
|
||||
pcici_t config_id;
|
||||
pcidi_t device_id;
|
||||
|
||||
{
|
||||
#if !defined(MIDWAY_ADPONLY)
|
||||
if (PCI_VENDOR(device_id) == PCI_VENDOR_EFFICIENTNETS &&
|
||||
(PCI_CHIPID(device_id) == PCI_PRODUCT_EFFICIENTNETS_ENI155PF ||
|
||||
PCI_CHIPID(device_id) == PCI_PRODUCT_EFFICIENTNETS_ENI155PA))
|
||||
return "Efficient Networks ENI-155p";
|
||||
#endif
|
||||
|
||||
#if !defined(MIDWAY_ENIONLY)
|
||||
if (PCI_VENDOR(device_id) == PCI_VENDOR_ADP &&
|
||||
(PCI_CHIPID(device_id) == PCI_PRODUCT_ADP_AIC5900 ||
|
||||
PCI_CHIPID(device_id) == PCI_PRODUCT_ADP_AIC5905))
|
||||
return "Adaptec 155 ATM";
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void en_pci_attach(config_id, unit)
|
||||
|
||||
pcici_t config_id;
|
||||
int unit;
|
||||
|
||||
{
|
||||
struct en_softc *sc;
|
||||
struct en_pci_softc *scp;
|
||||
pcidi_t device_id;
|
||||
int retval;
|
||||
vm_offset_t pa;
|
||||
|
||||
if (unit >= NEN) {
|
||||
printf("en%d: not configured; kernel is built for only %d device%s.\n",
|
||||
unit, NEN, NEN == 1 ? "" : "s");
|
||||
return;
|
||||
}
|
||||
|
||||
scp = (struct en_pci_softc *) malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT);
|
||||
if (scp == NULL)
|
||||
return;
|
||||
bzero(scp, sizeof(*scp)); /* zero */
|
||||
sc = &scp->esc;
|
||||
|
||||
retval = pci_map_mem(config_id, PCI_CBMA, (vm_offset_t *) &sc->en_base, &pa);
|
||||
|
||||
if (!retval) {
|
||||
free((caddr_t) scp, M_DEVBUF);
|
||||
return;
|
||||
}
|
||||
enpcis[unit] = scp; /* lock it in */
|
||||
en_cd.cd_devs[unit] = sc; /* fake a cfdriver structure */
|
||||
en_cd.cd_ndevs = NEN;
|
||||
sprintf(sc->sc_dev.dv_xname, "en%d", unit);
|
||||
sc->enif.if_unit = unit;
|
||||
sc->enif.if_name = "en";
|
||||
|
||||
/*
|
||||
* figure out if we are an adaptec card or not.
|
||||
* XXX: why do we have to re-read PC_ID_REG when en_pci_probe already
|
||||
* had that info?
|
||||
*/
|
||||
|
||||
device_id = pci_conf_read(config_id, PCI_ID_REG);
|
||||
sc->is_adaptec = (PCI_VENDOR(device_id) == PCI_VENDOR_ADP) ? 1 : 0;
|
||||
|
||||
#ifdef SHUTDOWN_PRE_SYNC
|
||||
/*
|
||||
* Add shutdown hook so that DMA is disabled prior to reboot. Not
|
||||
* doing so could allow DMA to corrupt kernel memory during the
|
||||
* reboot before the driver initializes.
|
||||
*/
|
||||
at_shutdown(en_pci_shutdown, scp, SHUTDOWN_POST_SYNC);
|
||||
#endif
|
||||
|
||||
if (!pci_map_int(config_id, en_intr, (void *) sc, &net_imask)) {
|
||||
printf("%s: couldn't establish interrupt\n", sc->sc_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
sc->ipl = 1; /* XXX */
|
||||
|
||||
/*
|
||||
* set up pci bridge
|
||||
*/
|
||||
|
||||
#if !defined(MIDWAY_ENIONLY)
|
||||
if (sc->is_adaptec) {
|
||||
sc->en_busreset = adp_busreset;
|
||||
adp_busreset(sc);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(MIDWAY_ADPONLY)
|
||||
if (!sc->is_adaptec) {
|
||||
sc->en_busreset = NULL;
|
||||
pci_conf_write(config_id, EN_TONGA, (TONGA_SWAP_DMA|TONGA_SWAP_WORD));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* done PCI specific stuff
|
||||
*/
|
||||
|
||||
en_attach(sc);
|
||||
|
||||
}
|
||||
|
||||
#ifdef SHUTDOWN_PRE_SYNC
|
||||
static void
|
||||
en_pci_shutdown(
|
||||
int howto,
|
||||
void *sc)
|
||||
{
|
||||
struct en_pci_softc *psc = (struct en_pci_softc *)sc;
|
||||
|
||||
en_reset(&psc->esc);
|
||||
DELAY(10);
|
||||
}
|
||||
#else /* !SHUTDOWN_PRE_SYNC */
|
||||
static int
|
||||
en_pci_shutdown(kdc, force)
|
||||
|
||||
struct kern_devconf *kdc;
|
||||
int force;
|
||||
|
||||
{
|
||||
if (kdc->kdc_unit < NEN) {
|
||||
struct en_pci_softc *psc = enpcis[kdc->kdc_unit];
|
||||
if (psc) /* can it be null? */
|
||||
en_reset(&psc->esc);
|
||||
DELAY(10);
|
||||
}
|
||||
dev_detach(kdc);
|
||||
return(0);
|
||||
}
|
||||
#endif /* !SHUTDOWN_PRE_SYNC */
|
||||
#endif /* NEN > 0 && NPCI > 0 */
|
Loading…
Reference in New Issue
Block a user