10fe49d72c
#if NBPFILTER is no longer required in the client. This change doesn't yet add support for loading bpf as a module, since drivers can register before bpf is attached. However, callers of bpf can now be modularized. Dynamically loadable bpf could probably be done fairly easily with coordination from the stub driver and the real driver by registering attachments in the stub before the real driver is loaded and doing a handoff. ... and I'm not going to ponder the depths of unload here. Tested with i386/MONOLITHIC, modified MONOLITHIC without bpf and rump.
196 lines
5.5 KiB
C
196 lines
5.5 KiB
C
/* $NetBSD: if_le_lebuffer.c,v 1.28 2010/01/19 22:07:43 pooka Exp $ */
|
|
|
|
/*-
|
|
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This code is derived from software contributed to The NetBSD Foundation
|
|
* by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace
|
|
* Simulation Facility, NASA Ames Research Center; Paul Kranenburg.
|
|
*
|
|
* 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/cdefs.h>
|
|
__KERNEL_RCSID(0, "$NetBSD: if_le_lebuffer.c,v 1.28 2010/01/19 22:07:43 pooka Exp $");
|
|
|
|
#include "opt_inet.h"
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/systm.h>
|
|
#include <sys/mbuf.h>
|
|
#include <sys/syslog.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/device.h>
|
|
#include <sys/malloc.h>
|
|
|
|
#include <net/if.h>
|
|
#include <net/if_ether.h>
|
|
#include <net/if_media.h>
|
|
|
|
#ifdef INET
|
|
#include <netinet/in.h>
|
|
#include <netinet/if_inarp.h>
|
|
#endif
|
|
|
|
#include <sys/bus.h>
|
|
#include <sys/intr.h>
|
|
#include <machine/autoconf.h>
|
|
|
|
#include <dev/sbus/sbusvar.h>
|
|
#include <dev/sbus/lebuffervar.h>
|
|
|
|
#include <dev/ic/lancereg.h>
|
|
#include <dev/ic/lancevar.h>
|
|
#include <dev/ic/am7990reg.h>
|
|
#include <dev/ic/am7990var.h>
|
|
|
|
#include "ioconf.h"
|
|
|
|
/*
|
|
* LANCE registers.
|
|
*/
|
|
#define LEREG1_RDP 0 /* Register Data port */
|
|
#define LEREG1_RAP 2 /* Register Address port */
|
|
|
|
struct le_softc {
|
|
struct am7990_softc sc_am7990; /* glue to MI code */
|
|
bus_space_tag_t sc_bustag;
|
|
bus_dma_tag_t sc_dmatag;
|
|
bus_space_handle_t sc_reg; /* LANCE registers */
|
|
};
|
|
|
|
|
|
int lematch_lebuffer(device_t, cfdata_t, void *);
|
|
void leattach_lebuffer(device_t, device_t, void *);
|
|
|
|
/*
|
|
* Media types supported.
|
|
*/
|
|
static int lemedia[] = {
|
|
IFM_ETHER|IFM_10_T,
|
|
};
|
|
#define NLEMEDIA __arraycount(lemedia)
|
|
|
|
CFATTACH_DECL_NEW(le_lebuffer, sizeof(struct le_softc),
|
|
lematch_lebuffer, leattach_lebuffer, NULL, NULL);
|
|
|
|
#if defined(_KERNEL_OPT)
|
|
#include "opt_ddb.h"
|
|
#endif
|
|
|
|
static void lewrcsr(struct lance_softc *, uint16_t, uint16_t);
|
|
static uint16_t lerdcsr(struct lance_softc *, uint16_t);
|
|
|
|
static void
|
|
lewrcsr(struct lance_softc *sc, uint16_t port, uint16_t val)
|
|
{
|
|
struct le_softc *lesc = (struct le_softc *)sc;
|
|
bus_space_tag_t t = lesc->sc_bustag;
|
|
bus_space_handle_t h = lesc->sc_reg;
|
|
|
|
bus_space_write_2(t, h, LEREG1_RAP, port);
|
|
bus_space_write_2(t, h, LEREG1_RDP, val);
|
|
|
|
#if defined(SUN4M)
|
|
/*
|
|
* We need to flush the Sbus->Mbus write buffers. This can most
|
|
* easily be accomplished by reading back the register that we
|
|
* just wrote (thanks to Chris Torek for this solution).
|
|
*/
|
|
(void)bus_space_read_2(t, h, LEREG1_RDP);
|
|
#endif
|
|
}
|
|
|
|
static uint16_t
|
|
lerdcsr(struct lance_softc *sc, uint16_t port)
|
|
{
|
|
struct le_softc *lesc = (struct le_softc *)sc;
|
|
bus_space_tag_t t = lesc->sc_bustag;
|
|
bus_space_handle_t h = lesc->sc_reg;
|
|
|
|
bus_space_write_2(t, h, LEREG1_RAP, port);
|
|
return (bus_space_read_2(t, h, LEREG1_RDP));
|
|
}
|
|
|
|
int
|
|
lematch_lebuffer(device_t parent, cfdata_t cf, void *aux)
|
|
{
|
|
struct sbus_attach_args *sa = aux;
|
|
|
|
return (strcmp(cf->cf_name, sa->sa_name) == 0);
|
|
}
|
|
|
|
|
|
void
|
|
leattach_lebuffer(device_t parent, device_t self, void *aux)
|
|
{
|
|
struct le_softc *lesc = device_private(self);
|
|
struct lance_softc *sc = &lesc->sc_am7990.lsc;
|
|
struct lebuf_softc *lebuf = device_private(parent);
|
|
struct sbus_attach_args *sa = aux;
|
|
|
|
sc->sc_dev = self;
|
|
lesc->sc_bustag = sa->sa_bustag;
|
|
lesc->sc_dmatag = sa->sa_dmatag;
|
|
|
|
if (sbus_bus_map(sa->sa_bustag,
|
|
sa->sa_slot,
|
|
sa->sa_offset,
|
|
sa->sa_size,
|
|
0, &lesc->sc_reg)) {
|
|
aprint_error(": cannot map registers\n");
|
|
return;
|
|
}
|
|
|
|
sc->sc_mem = lebuf->sc_buffer;
|
|
sc->sc_memsize = lebuf->sc_bufsiz;
|
|
sc->sc_addr = 0; /* Lance view is offset by buffer location */
|
|
lebuf->attached = 1;
|
|
|
|
/* That old black magic... */
|
|
sc->sc_conf3 = prom_getpropint(sa->sa_node, "busmaster-regval",
|
|
LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON);
|
|
|
|
sc->sc_supmedia = lemedia;
|
|
sc->sc_nsupmedia = NLEMEDIA;
|
|
sc->sc_defaultmedia = lemedia[0];
|
|
|
|
prom_getether(sa->sa_node, sc->sc_enaddr);
|
|
|
|
sc->sc_copytodesc = lance_copytobuf_contig;
|
|
sc->sc_copyfromdesc = lance_copyfrombuf_contig;
|
|
sc->sc_copytobuf = lance_copytobuf_contig;
|
|
sc->sc_copyfrombuf = lance_copyfrombuf_contig;
|
|
sc->sc_zerobuf = lance_zerobuf_contig;
|
|
|
|
sc->sc_rdcsr = lerdcsr;
|
|
sc->sc_wrcsr = lewrcsr;
|
|
|
|
am7990_config(&lesc->sc_am7990);
|
|
|
|
/* Establish interrupt handler */
|
|
if (sa->sa_nintr != 0)
|
|
(void)bus_intr_establish(lesc->sc_bustag, sa->sa_pri,
|
|
IPL_NET, am7990_intr, sc);
|
|
}
|