summaryrefslogtreecommitdiff
path: root/chips/lance.c
diff options
context:
space:
mode:
authorThomas Schwinge <tschwinge@gnu.org>2006-02-20 20:44:33 +0000
committerThomas Schwinge <tschwinge@gnu.org>2009-06-18 00:26:34 +0200
commit2486c56afd5ac4392aa95f0e478978331d1c15d6 (patch)
treee3c5e8c5252d5e110208d7fc6dbfad1c3b1e802f /chips/lance.c
parent2a50c925882fe2d6535f130401eb6d4a4feb3e93 (diff)
2006-02-20 Thomas Schwinge <tschwinge@gnu.org>
Remove unused and unsupported code. Consult the file `DEVELOPMENT' for details. Partly based on suggestions by Gianluca Guida <glguida@gmail.com>. * chips/atm.c: Remove file. * chips/atmreg.h: Likewise. * chips/audio.c: Likewise. * chips/audio_config.h: Likewise. * chips/audio_defs.h: Likewise. * chips/bt431.c: Likewise. * chips/bt431.h: Likewise. * chips/bt455.c: Likewise. * chips/bt455.h: Likewise. * chips/bt459.c: Likewise. * chips/bt459.h: Likewise. * chips/bt478.c: Likewise. * chips/bt478.h: Likewise. * chips/build_font.c: Likewise. * chips/cfb_hdw.c: Likewise. * chips/cfb_misc.c: Likewise. * chips/dc503.c: Likewise. * chips/dc503.h: Likewise. * chips/dtop.h: Likewise. * chips/dtop_handlers.c: Likewise. * chips/dtop_hdw.c: Likewise. * chips/dz_7085.h: Likewise. * chips/dz_defs.h: Likewise. * chips/dz_hdw.c: Likewise. * chips/eccreg.h: Likewise. * chips/fb_hdw.c: Likewise. * chips/fb_misc.c: Likewise. * chips/fdc_82077.h: Likewise. * chips/fdc_82077_hdw.c: Likewise. * chips/frc.c: Likewise. * chips/ims332.c: Likewise. * chips/ims332.h: Likewise. * chips/isdn_79c30.h: Likewise. * chips/isdn_79c30_hdw.c: Likewise. * chips/kernel_font.c: Likewise. * chips/kernel_font.data: Likewise. * chips/lance.c: Likewise. * chips/lance.h: Likewise. * chips/lance_mapped.c: Likewise. * chips/lk201.c: Likewise. * chips/lk201.h: Likewise. * chips/mc_clock.c: Likewise. * chips/mc_clock.h: Likewise. * chips/mouse.c: Likewise. * chips/nc.c: Likewise. * chips/nc.h: Likewise. * chips/nw.h: Likewise. * chips/nw_mk.c: Likewise. * chips/nw_mk.h: Likewise. * chips/pm_defs.h: Likewise. * chips/pm_hdw.c: Likewise. * chips/pm_misc.c: Likewise. * chips/scc_8530.h: Likewise. * chips/scc_8530_hdw.c: Likewise. * chips/screen.c: Likewise. * chips/screen.h: Likewise. * chips/screen_defs.h: Likewise. * chips/screen_switch.c: Likewise. * chips/screen_switch.h: Likewise. * chips/serial_console.c: Likewise. * chips/serial_defs.h: Likewise. * chips/sfb_hdw.c: Likewise. * chips/sfb_misc.c: Likewise. * chips/spans.c: Likewise. * chips/spans.h: Likewise. * chips/tca100.c: Likewise. * chips/tca100.h: Likewise. * chips/tca100_if.c: Likewise. * chips/tca100_if.h: Likewise. * chips/vs42x_rb.h: Likewise. * chips/xcfb_hdw.c: Likewise. * chips/xcfb_misc.c: Likewise. * chips/xcfb_monitor.h: Likewise. * Makefile.in (chips-files): Only contain `busses.c' and `busses.h'. * kern/syscall_sw.c: Don't include <chips/nw_mk.h> anymore.
Diffstat (limited to 'chips/lance.c')
-rw-r--r--chips/lance.c1570
1 files changed, 0 insertions, 1570 deletions
diff --git a/chips/lance.c b/chips/lance.c
deleted file mode 100644
index 750d4c5..0000000
--- a/chips/lance.c
+++ /dev/null
@@ -1,1570 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: lance.c
- * Author: Robert V. Baron & Alessandro Forin
- * Date: 5/90
- *
- * Driver for the DEC LANCE Ethernet Controller.
- */
-
-/*
-
- Byte ordering issues.
-
- The lance sees data naturally as half word (16 bit) quantitites.
- Bit 2 (BSWP) in control register 3 (CSR3) controls byte swapping.
- To quote the spec:
-
- 02 BSWP BYTE SWAP allows the chip to
- operate in systems that consdier bits (15:08) of data pointers
- by an even addressa and bits (7:0) to be pointed by an
- odd address.
-
- When BSWP=1, the chip will swap the high and low bytes on DMA
- data transfers between the silo and bus memory. Only data from
- silo transfers is swapped; the Initialization Block data and
- the Descriptor Ring entries are NOT swapped. (emphasis theirs)
-
-
- So on systems with BYTE_MSF=1, the BSWP bit should be set. Note,
- however, that all shorts in the descriptor ring and initialization
- block need to be swapped. The BITFIELD macros in lance.h handle this
- magic.
-
-*/
-
-#include <ln.h>
-#if NLN > 0
-#include <platforms.h>
-
-/*
- * AMD Am7990 LANCE (Ethernet Interface)
- */
-#include <sys/ioctl.h>
-#include <vm/vm_kern.h>
-
-#include <machine/machspl.h> /* spl definitions */
-#include <kern/time_out.h>
-#include <sys/syslog.h>
-#include <ipc/ipc_port.h>
-#include <ipc/ipc_kmsg.h>
-
-#include <device/device_types.h>
-#include <device/errno.h>
-#include <device/io_req.h>
-#include <device/if_hdr.h>
-#include <device/if_ether.h>
-#include <device/net_status.h>
-#include <device/net_io.h>
-
-#ifdef FLAMINGO
-#define se_reg_type unsigned int
-#endif
-
-#include <chips/lance.h>
-#include <chips/busses.h>
-
-#define private static
-#define public
-
-typedef struct se_softc *se_softc_t; /* move above prototypes */
-
-void se_write_reg(); /* forwards */
-void se_read();
-void se_rint();
-void se_tint();
-
-private vm_offset_t se_Hmem_nogap(), se_Hmem_gap16();
-private vm_offset_t se_malloc();
-
-
-/* This config section should go into a separate file */
-
-#ifdef LUNA88K
-# include <luna88k/board.h>
-# define MAPPED 1
- #undef bcopy
- extern void bcopy(), bzero();
-
-#define wbflush()
-#define Hmem(lna) (vm_offset_t)((lna) + sc->lnbuf)
-#define Lmem(lna) (vm_offset_t)((lna) + sc->lnoffset)
-
-#define SPACE (TRI_PORT_RAM_SPACE>>1)
-private struct se_switch se_switch[] = {
- { LANCE_ADDR - TRI_PORT_RAM, /* pointer */
- SPACE /* host side */,
- SPACE /* lance side */,
- - TRI_PORT_RAM,
- 0, /* romstride */
- 0, /* ramstride */
- SPACE,
- /* desc_copyin */ bcopy,
- /* desc_copyout */ bcopy,
- /* data_copyin */ bcopy,
- /* data_copyout */ bcopy,
- /* bzero */ bzero,
- /* mapaddr */ se_Hmem_nogap,
- /* mapoffs */ se_Hmem_nogap
- },
-};
-
-#endif
-
-#ifdef DECSTATION
-#include <mips/mips_cpu.h>
-#include <mips/PMAX/pmad_aa.h>
-
-#define MAPPED 1
-
-/*
- * The LANCE buffer memory as seen from the Pmax cpu is funny.
- * It is viewed as short words (16bits), spaced at word (32bits)
- * intervals. The same applies to the registers. From the LANCE
- * point of view memory is instead contiguous.
- * The ROM that contains the station address is in the space belonging
- * to the clock/battery backup memory. This space is again 16 bits
- * in a 32bit envelope. And the ether address is stored in the "high"
- * byte of 6 consecutive quantities.
- *
- * But Pmaxen and 3maxen (and..) map lance space differently.
- * This requires dynamic adaptation of the driver, which
- * is done via the following switches.
- * For convenience, the switch holds information about
- * the location of the lance control registers as well.
- * This could be either absolute (pmax) or relative to
- * some register base (3max, turbochannel)
- */
-void copyin_gap16(), copyout_gap16(), bzero_gap16();
-extern void bcopy(), bzero();
-void copyin_gap32(), copyout_gap32();
-
-private struct se_switch se_switch[] = {
-/* pmax */
- { 0x00000000, 0x01000000, 0x0, 0x05000000, 8, 16, 64*1024,
- copyin_gap16, copyout_gap16, copyin_gap16, copyout_gap16,
- bzero_gap16, se_Hmem_gap16, se_Hmem_gap16},
-/* 3max */
- { PMAD_OFFSET_LANCE, PMAD_OFFSET_RAM, PMAD_OFFSET_RAM, PMAD_OFFSET_ROM,
- 16, 0, PMAD_RAM_SIZE,
- bcopy, bcopy, bcopy, bcopy, bzero, se_Hmem_nogap, se_Hmem_nogap},
-/* 3min */
-/* XXX re-use other 64k */
- { 0/*later*/, 0/*later*/, 0x0, 0/*later*/, 0, 128, 64*1024,
- copyin_gap16, copyout_gap16, copyin_gap32, copyout_gap32,
- bzero_gap16, se_Hmem_gap16, se_Hmem_nogap},
-};
-
-/*
- * "lna" is what se_malloc hands back. They are offsets using
- * the sizing that the Lance would use. The Lance space is
- * mapped somewhere in the I/O space, as indicated by the softc.
- * Hence we have these two macros:
- */
-/* H & L are not hi and lo but
- H = HOST == addresses for host to reference board memory
- L = LOCAL == addresses on board
- */
-#define Hmem(lna) (vm_offset_t)((se_sw->mapaddr)(lna) + sc->lnbuf)
-#define Lmem(lna) (vm_offset_t)((vm_offset_t)lna + sc->lnoffset)
-#endif /*DECSTATION*/
-
-
-#ifdef VAXSTATION
-#include <vax/ka3100.h>
-
-#define wbflush()
-
-void xzero(x, l) vm_offset_t x; int l; { blkclr(x, l); }
-void xcopy(f, t, l) vm_offset_t f, t; int l; { bcopy(f, t, l); }
-
-private struct se_switch se_switch[] = {
- /* pvax sees contiguous bits in lower 16Meg of memory */
- { 0, 0, 0, 0, 0, 0, 64*1024,
- xcopy, xcopy, xcopy, xcopy, xzero, se_Hmem_nogap, se_Hmem_nogap},
-};
-
-/*
- * "lna" is what se_malloc hands back. They are offsets using
- * the sizing that the Lance would use. The Lance space is
- * mapped somewhere in the I/O space, as indicated by the softc.
- * Hence we have these two macros:
- */
-/* H & L are not hi and lo but
- H = HOST == addresses for host to reference board memory
- L = LOCAL == addresses on board
- */
- /*
- * This does not deal with > 16 Meg physical memory, where
- * Hmem != Lmem
- */
-#define Hmem(lna) (vm_offset_t)((lna) + sc->lnbuf)
-#define Lmem(lna) (vm_offset_t)((lna) + sc->lnoffset)
-
-#endif /*VAXSTATION*/
-
-
-#ifdef FLAMINGO
-#include <alpha/alpha_cpu.h>
-
-/* XXX might be wrong, mostly stolen from kmin */
-extern void copyin_gap16(), copyout_gap16(), bzero_gap16();
-extern void copyin_gap32(), copyout_gap32();
-extern void bcopy(), bzero();
-
-private struct se_switch se_switch[] = {
-/* XXX re-use other 64k */
- { 0/*later*/, 0/*later*/, 0x0, 0/*later*/, 0, 128, 64*1024,
- copyin_gap16, copyout_gap16, copyin_gap32, copyout_gap32,
- bzero_gap16, se_Hmem_gap16, se_Hmem_nogap},
-};
-
-/*
- * "lna" is what se_malloc hands back. They are offsets using
- * the sizing that the Lance would use. The Lance space is
- * mapped somewhere in the I/O space, as indicated by the softc.
- * Hence we have these two macros:
- */
-/* H & L are not hi and lo but
- H = HOST == addresses for host to reference board memory
- L = LOCAL == addresses on board
- */
-#define Hmem(lna) (vm_offset_t)((se_sw->mapaddr)(lna) + sc->lnbuf)
-#define Lmem(lna) (vm_offset_t)((vm_offset_t)lna + sc->lnoffset)
-#endif /*FLAMINGO*/
-
-
-/*
- * Map a lance-space offset into an host-space one
- */
-private vm_offset_t se_Hmem_nogap( vm_offset_t lna) { return lna;}
-private vm_offset_t se_Hmem_gap16( vm_offset_t lna) { return lna << 1;}
-
-/*
- * Memory addresses for LANCE are 24 bits wide.
- */
-#define Addr_lo(y) ((unsigned short)((vm_offset_t)(y) & 0xffff))
-#define Addr_hi(y) ((unsigned short)(((vm_offset_t)(y)>>16) & 0xff))
-
-#define LN_MEMORY_SIZE (se_sw->ramsize)
-
-/* XXX to accomodate heterogeneity this should be made per-drive */
-/* XXX and then some more */
-
-struct se_switch *se_sw = se_switch;
-
-void set_se_switch(n)
-int n;
-{
- se_sw = &se_switch[n];
-}
-
-#ifndef LUNA88K
-void setse_switch(n, r, b, l, o)
- vm_offset_t r, b, l, o;
- int n;
-{
- se_switch[n].regspace = r;
- se_switch[n].bufspace = b;
- se_switch[n].ln_bufspace = l;
- se_switch[n].romspace = o;
-
- /* make sure longword aligned */
- if (se_switch[n].bufspace & 0x7) {
- se_switch[n].bufspace = (se_switch[n].bufspace+0x7) & ~0x7;
- }
-
- set_se_switch(n);
-}
-#endif
-
-/*
- * Autoconf info
- */
-
-private vm_offset_t se_std[NLN] = { 0 };
-private struct bus_device *se_info[NLN];
-private int se_probe();
-private void se_attach();
-
-struct bus_driver se_driver =
- { se_probe, 0, se_attach, 0, se_std, "se", se_info, };
-
-/*
- * Externally visible functions
- */
-char *se_unprobed_addr = 0;
-void se_intr(); /* kernel */
-
-int se_open(), se_output(), se_get_status(), /* user */
- se_set_status(), se_setinput(), se_restart();
-
-/*
- *
- * Internal functions & definitions
- *
- */
-
-private int se_probe();
-private void se_init();
-private void init_lance_space();
-private void se_desc_set_status();
-private volatile long *se_desc_alloc(); /* must be aligned! */
-void se_start();
-private void copy_from_lance();
-private int copy_to_lance();
-
-int se_verbose = 0; /* debug flag */
-
-#define RLOG 4 /* 2**4 = 16 receive descriptors */
-#define TLOG 4 /* 2**4 = 16 transmit descriptors */
-#define NRCV (1<<RLOG) /* Receive descriptors */
-#define NXMT (1<<TLOG) /* Transmit descriptors */
-
-#define LN_BUFFER_SIZE (0x800-0x80)
-
-/*
- * Ethernet software status per interface.
- *
- * Each interface is referenced by a network interface structure,
- * is_if, which contains the output queue for the interface, its address, ...
- */
-int se_loopback_hack = 1;
-
-struct se_softc {
- struct ifnet is_if; /* generic interface header */
- unsigned char is_addr[6]; /* ethernet hardware address */
- unsigned short pad;
- se_reg_t lnregs; /* Lance registers */
- vm_offset_t lnbuf; /* Lance memory, Host offset */
- vm_offset_t lnoffset; /* Lance memory, Lance offset */
- vm_offset_t lnrom;
- vm_offset_t lnsbrk; /* Lance memory allocator */
- vm_offset_t lninit_block; /* Init block address */
- se_desc_t lnrring[NRCV]; /* Receive ring desc. */
- volatile long *lnrbuf[NRCV]; /* Receive buffers */
- se_desc_t lntring[NXMT]; /* Transmit ring desc. */
- volatile long *lntbuf[NXMT]; /* Transmit buffers */
-
- int rcv_last; /* Rcv buffer last read */
-
- io_req_t tpkt[NXMT+1]; /* Xmt pkt queue */
- int xmt_count; /* Xmt queue size */
- int xmt_last; /* Xmt queue head (insert) */
- int xmt_complete; /* Xmt queue tail (remove) */
-
- int se_flags; /* Flags for SIOCSIFFLAGS */
- int counters[4]; /* error counters */
-#define bablcnt counters[0]
-#define misscnt counters[1]
-#define merrcnt counters[2]
-#define rstrtcnt counters[3]
-} se_softc_data[NLN];
-
-se_softc_t se_softc[NLN]; /* quick access */
-
-/*
- * Probe the Lance to see if it's there
- */
-private int se_open_state = 0;
-
-private int se_probe(
- vm_offset_t reg,
- register struct bus_device *ui)
-{
- register se_softc_t sc;
- se_reg_t rdp, rap;
- int unit = ui->unit;
-
- /*
- * See if the interface is there by reading the lance CSR. On pmaxen
- * and 3maxen this is superfluous, but..
- */
- rdp = (se_reg_t) (reg + se_sw->regspace);
-#ifdef DECSTATION
- if (check_memory(rdp, 0))
- return 0;
-#endif /*DECSTATION*/
-#ifdef MAPPED
- SE_probe(reg,ui);
-#endif /*MAPPED*/
- rap = rdp + 2; /* XXX might not be true in the future XXX */
- /* rdp and rap are "shorts" on consecutive
- "long" word boundaries */
-
- /*
- * Bind this interface to the softc.
- */
- sc = &se_softc_data[unit];
- se_softc[unit] = sc;
- sc->lnregs = (se_reg_t) (reg + se_sw->regspace);
- sc->lnbuf = (vm_offset_t) (reg + se_sw->bufspace);
- sc->lnoffset = (vm_offset_t) (se_sw->ln_bufspace);
- sc->lnrom = (vm_offset_t) (reg + se_sw->romspace);
-
- /*
- * Reset the interface, and make sure we really do it! (the 3max
- * seems quite stubborn about these registers)
- */
- se_write_reg(rap, CSR0_SELECT, CSR0_SELECT, "RAP");
- se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0");
-
- /*
- * Allocate lance RAM buffer memory
- */
- init_lance_space(sc);
-
- /*
- * Initialize the chip
- *
- * NOTE: From now on we will only touch csr0
- */
- if (se_ship_init_block(sc, unit))
- return 0;
-
- /*
- * Tell the world we are alive and well
- */
- se_open_state++;
- return 1;
-}
-
-int se_ship_init_block(
- register se_softc_t sc,
- int unit)
-{
- se_reg_t rdp = sc->lnregs;
- se_reg_t rap;
- register int i = 0;
-
- rap = rdp + 2; /* XXX might not be true in the future XXX */
-
- /*
- * Load LANCE control block.
- */
-
-#ifdef LUNA88K
- /* turn on byte swap bit in csr3, set bcon bit - as in 2.5 */
- se_write_reg(rap, CSR3_SELECT, CSR3_SELECT, "RAP");
- se_write_reg(rdp, LN_CSR3_BSWP|LN_CSR3_BCON,
- LN_CSR3_BSWP|LN_CSR3_BCON, "csr3");
-#endif
-
- se_write_reg(rap, CSR1_SELECT, CSR1_SELECT, "RAP");
- se_write_reg(rdp, Addr_lo(Lmem(sc->lninit_block)),
- Addr_lo(Lmem(sc->lninit_block)), "csr1");
-
- se_write_reg(rap, CSR2_SELECT, CSR2_SELECT, "RAP");
- se_write_reg(rdp, Addr_hi(Lmem(sc->lninit_block)),
- Addr_hi(Lmem(sc->lninit_block)), "csr2");
-
- /*
- * Start the INIT sequence now
- */
- se_write_reg(rap, CSR0_SELECT, CSR0_SELECT, "RAP");
- *rdp = (LN_CSR0_IDON | LN_CSR0_INIT);
- wbflush();
-
- /* give it plenty of time to settle */
- while (i++ < 10000) {
- delay(100);
- if ((*rdp & LN_CSR0_IDON) != 0)
- break;
- }
- /* make sure got out okay */
- if ((*rdp & LN_CSR0_IDON) == 0) {
- printf("se%d: cannot initialize\n", unit);
- if (*rdp & LN_CSR0_ERR)
- printf("se%d: initialization error, csr = %04x\n",
- unit, (*rdp & 0xffff));
- return 1;
- }
- /*
- * Do not enable interrupts just yet.
- */
- /* se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0"); */
-
- return 0;
-}
-
-void
-se_write_reg(
- register se_reg_t regptr,
- register int val,
- register int result,
- char *regname)
-{
- register int i = 0;
-
- while ((unsigned short)(*regptr) != (unsigned short)result) {
- *regptr = (se_reg_type)val;
- wbflush();
- if (++i > 10000) {
- printf("se: %s did not settle (to x%x): x%x\n",
- regname, result, (unsigned short)(*regptr));
- return;
- }
- delay(100);
- }
-}
-
-unsigned short
-se_read_reg(
- register se_reg_t regptr)
-{
- return (unsigned short) (*regptr);
-}
-
-private void
-init_lance_space(
- register se_softc_t sc)
-{
- register int lptr; /* Generic lance pointer */
- se_desc_t ringaddr;
- long *rom_eaddress = (long *) sc->lnrom;
- int i;
- struct se_init_block init_block;
-
- /*
- * Allocate local RAM buffer memory for the init block,
- * fill in our local copy then copyout.
- */
-
- sc->lninit_block = se_malloc(sc, sizeof (struct se_init_block));
-
- /*
- * Set values on stack, then copyout en-masse
- */
- bzero(&init_block, sizeof(init_block));
- init_block.mode = 0;
-
- /* byte swapping between host and lance */
-
- init_block.phys_addr_low = ((rom_eaddress[0]>>se_sw->romstride)&0xff) |
- (((rom_eaddress[1]>>se_sw->romstride)&0xff) << 8);
- init_block.phys_addr_med = ((rom_eaddress[2]>>se_sw->romstride)&0xff) |
- (((rom_eaddress[3]>>se_sw->romstride)&0xff) << 8);
- init_block.phys_addr_high = ((rom_eaddress[4]>>se_sw->romstride)&0xff) |
- (((rom_eaddress[5]>>se_sw->romstride)&0xff) << 8);
-
- /*
- * Allocate both descriptor rings at once.
- * Note that the quadword alignment requirement is
- * inherent in the way we perform allocation,
- * but it does depend on the size of the init block.
- */
- lptr = se_malloc(sc, sizeof (struct se_desc) * (NXMT + NRCV));
-
- /*
- * Initialize the buffer descriptors
- */
- init_block.recv_ring_pointer_lo = Addr_lo(Lmem(lptr));
- init_block.recv_ring_pointer_hi = Addr_hi(Lmem(lptr));
- init_block.recv_ring_len = RLOG;
-
- for ( i = 0; i < NRCV ; i++, lptr += sizeof(struct se_desc)) {
- ringaddr = (se_desc_t)Hmem(lptr);
- sc->lnrring[i] = ringaddr;
- sc->lnrbuf[i] = se_desc_alloc (sc, ringaddr);
- }
-
- init_block.xmit_ring_pointer_lo = Addr_lo(Lmem(lptr));
- init_block.xmit_ring_pointer_hi = Addr_hi(Lmem(lptr));
- init_block.xmit_ring_len = TLOG;
-
- for ( i = 0 ; i < NXMT ; i++, lptr += sizeof(struct se_desc)) {
- ringaddr = (se_desc_t)Hmem(lptr);
- sc->lntring[i] = ringaddr;
- sc->lntbuf[i] = se_desc_alloc (sc, ringaddr);
- }
-
- /*
- * No logical address filtering
- */
- init_block.logical_addr_filter0 = 0;
- init_block.logical_addr_filter1 = 0;
- init_block.logical_addr_filter2 = 0;
- init_block.logical_addr_filter3 = 0;
-
- /*
- * Move init block into lance space
- */
- (se_sw->desc_copyout)((vm_offset_t)&init_block, Hmem(sc->lninit_block), sizeof(init_block));
- wbflush();
-}
-
-/*
- * Interface exists: make available by filling in network interface
- * record. System will initialize the interface when it is ready
- * to accept packets.
- */
-private void
-se_attach(
- register struct bus_device *ui)
-{
- unsigned char *enaddr;
- struct ifnet *ifp;
- long *rom_eaddress;
- int unit = ui->unit;
- se_softc_t sc = se_softc[unit];
-
- rom_eaddress = (long *) sc->lnrom;
-
- /*
- * Read the address from the prom and save it.
- */
- enaddr = sc->is_addr;
- enaddr[0] = (unsigned char) ((rom_eaddress[0] >> se_sw->romstride) & 0xff);
- enaddr[1] = (unsigned char) ((rom_eaddress[1] >> se_sw->romstride) & 0xff);
- enaddr[2] = (unsigned char) ((rom_eaddress[2] >> se_sw->romstride) & 0xff);
- enaddr[3] = (unsigned char) ((rom_eaddress[3] >> se_sw->romstride) & 0xff);
- enaddr[4] = (unsigned char) ((rom_eaddress[4] >> se_sw->romstride) & 0xff);
- enaddr[5] = (unsigned char) ((rom_eaddress[5] >> se_sw->romstride) & 0xff);
-
- printf(": %x-%x-%x-%x-%x-%x",
- (rom_eaddress[0] >> se_sw->romstride) & 0xff,
- (rom_eaddress[1] >> se_sw->romstride) & 0xff,
- (rom_eaddress[2] >> se_sw->romstride) & 0xff,
- (rom_eaddress[3] >> se_sw->romstride) & 0xff,
- (rom_eaddress[4] >> se_sw->romstride) & 0xff,
- (rom_eaddress[5] >> se_sw->romstride) & 0xff);
-
- /*
- * Initialize the standard interface descriptor
- */
- ifp = &sc->is_if;
- ifp->if_unit = unit;
- ifp->if_header_size = sizeof(struct ether_header);
- ifp->if_header_format = HDR_ETHERNET;
- ifp->if_address_size = 6;
- ifp->if_mtu = ETHERMTU;
- ifp->if_flags |= IFF_BROADCAST;
-
- ifp->if_address = (char *) enaddr;
-
- if_init_queues(ifp);
-#ifdef MAPPED
- SE_attach(ui);
-#endif /*MAPPED*/
-
-}
-
-/*
- * Use a different hardware address for interface
- */
-void
-se_setaddr(
- unsigned char eaddr[6],
- int unit)
-{
- register se_softc_t sc = se_softc[unit];
- struct se_init_block init_block;
-
- /*
- * Modify initialization block accordingly
- */
- (se_sw->desc_copyin) (Hmem(sc->lninit_block), (vm_offset_t)&init_block, sizeof(init_block));
- bcopy(eaddr, &init_block.phys_addr_low, sizeof(*eaddr));
- (se_sw->desc_copyout)((vm_offset_t)&init_block, Hmem(sc->lninit_block), sizeof(init_block));
- /*
- * Make a note of it
- */
- bcopy(eaddr, sc->is_addr, sizeof(*eaddr));
-
- /*
- * Restart the interface
- */
- se_restart(&sc->is_if);
- se_init(unit);
-}
-
-/*
- * Restart interface
- *
- * We use this internally on those errors that hang the chip,
- * not sure yet what use the MI code will make of it.
- *
- * After stopping the chip and effectively turning off the interface
- * we release all pending buffers and cause the chip to init
- * itself. We do not enable interrupts here.
- */
-int
-se_restart( register struct ifnet *ifp )
-{
- register se_softc_t sc = se_softc[ifp->if_unit];
- se_reg_t rdp;
- register int i;
-
- rdp = sc->lnregs;
-
- /*
- * stop the chip
- */
- se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0");
-
- /*
- * stop network activity
- */
- if (ifp->if_flags & IFF_RUNNING) {
- ifp->if_flags &= ~(IFF_UP | IFF_RUNNING);
- sc->se_flags &= ~(IFF_UP | IFF_RUNNING);
- }
- sc->rstrtcnt++;
-
- if (se_verbose)
- printf("se%d: %d restarts\n", ifp->if_unit, sc->rstrtcnt);
-
- /*
- * free up any buffers currently in use
- */
- for (i = 0; i < NXMT; i++)
- if (sc->tpkt[i]) {
- iodone(sc->tpkt[i]);
- sc->tpkt[i] = (io_req_t) 0;
- }
- /*
- * INIT the chip again, no need to reload init block address.
- */
- se_ship_init_block(sc, ifp->if_unit);
-
- return (0);
-}
-
-/*
- * Initialize the interface.
- */
-private void
-se_init( int unit )
-{
- register se_softc_t sc = se_softc[unit];
- register se_desc_t *rp;
- register struct ifnet *ifp = &sc->is_if;
- se_reg_t rdp;
- short mode;
- spl_t s;
- int i;
-
- if (ifp->if_flags & IFF_RUNNING)
- return;
-
- rdp = sc->lnregs;
-
- /*
- * Init the buffer descriptors and indexes for each of the rings.
- */
- for (i = 0, rp = sc->lnrring; i < NRCV; i++, rp++)
- se_desc_set_status(*rp, LN_RSTATE_OWN);
-
- for (i = 0, rp = sc->lntring; i < NXMT; i++, rp++)
- se_desc_set_status(*rp, 0);
-
- sc->xmt_count = sc->xmt_complete = sc->xmt_last = sc->rcv_last = 0;
-
- /*
- * Deal with loopback mode operation
- */
- s = splimp();
-
- (se_sw->desc_copyin) (Hmem(sc->lninit_block), (vm_offset_t)&mode, sizeof(mode));
-
- if (ifp->if_flags & IFF_LOOPBACK
- && ((mode & LN_MODE_LOOP) == 0)) {
- /* if not already in loopback mode, do external loopback */
- mode &= ~LN_MODE_INTL;
- mode |= LN_MODE_LOOP;
- (se_sw->desc_copyout) ((vm_offset_t)&mode, Hmem(sc->lninit_block), sizeof(mode));
- se_restart(ifp);
- se_init(ifp->if_unit);
- splx(s);
- return;
- }
-
- ifp->if_flags |= (IFF_UP | IFF_RUNNING);
- sc->se_flags |= (IFF_UP | IFF_RUNNING);
-
- /*
- * Start the Lance and enable interrupts
- */
- *rdp = (LN_CSR0_STRT | LN_CSR0_INEA);
- wbflush();
-
- /*
- * See if anything is already queued
- */
- se_start(unit);
- splx(s);
-}
-
-
-/*
- * Shut off the lance
- */
-void
-se_stop(int unit)
-{
- se_reg_t rdp = se_softc[unit]->lnregs;
-
- se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0");
-}
-
-
-/*
- * Open the device, declaring the interface up
- * and enabling lance interrupts.
- */
-/*ARGSUSED*/
-int
-se_open(
- int unit,
- int flag)
-{
- register se_softc_t sc = se_softc[unit];
-
- if (unit >= NLN)
- return EINVAL;
- if (!se_open_state)
- return ENXIO;
-
- sc->is_if.if_flags |= IFF_UP;
- se_open_state++;
- se_init(unit);
- return (0);
-}
-
-#ifdef MAPPED
-int se_use_mapped_interface[NLN];
-#endif /*MAPPED*/
-
-void
-se_normal(int unit)
-{
-#ifdef MAPPED
- se_use_mapped_interface[unit] = 0;
-#endif /*MAPPED*/
- if (se_softc[unit]) {
- se_restart((struct ifnet *)se_softc[unit]);
- se_init(unit);
- }
-}
-
-/*
- * Ethernet interface interrupt routine
- */
-void
-se_intr(
- int unit,
- spl_t spllevel)
-{
- register se_softc_t sc = se_softc[unit];
- se_reg_t rdp;
- register struct ifnet *ifp = &sc->is_if;
- register unsigned short csr;
-
-#ifdef MAPPED
- if (se_use_mapped_interface[unit])
- {
- SE_intr(unit,spllevel);
- return;
- }
-#endif /*MAPPED*/
-
- if (se_open_state < 2) { /* Stray, or not open for business */
- rdp = (sc ? sc->lnregs : (se_reg_t)se_unprobed_addr);
- *rdp |= LN_CSR0_STOP;
- wbflush();
- return;
- }
- rdp = sc->lnregs;
-
- /*
- * Read the CSR and process any error condition.
- * Later on, restart the lance by writing back
- * the CSR (for set-to-clear bits).
- */
- csr = *rdp; /* pick up the csr */
-
- /* drop spurious interrupts */
- if ((csr & LN_CSR0_INTR) == 0)
- return;
-
-#ifdef DECSTATION
- splx(spllevel); /* drop priority now */
-#endif /*DECSTATION*/
-again:
- /*
- * Check for errors first
- */
- if ( csr & LN_CSR0_ERR ) {
- if (csr & LN_CSR0_MISS) {
- /*
- * Stop the chip to prevent a corrupt packet from
- * being transmitted. There is a known problem with
- * missed packet errors causing corrupted data to
- * be transmitted to the same host as was just
- * transmitted, with a valid crc appended to the
- * packet. The only solution is to stop the chip,
- * which will clear the Lance silo, thus preventing
- * the corrupt data from being sent.
- */
- se_write_reg(rdp, LN_CSR0_STOP, LN_CSR0_STOP, "csr0");
-
- sc->misscnt++;
- if (se_verbose) {
- int me = 0, lance = 0, index;
- struct se_desc r;
- for (index = 0; index < NRCV; index++) {
- (se_sw->desc_copyin)(
- (vm_offset_t)sc->lnrring[index],
- (vm_offset_t)&r,
- sizeof(r));
- if (r.status & LN_RSTATE_OWN)
- lance++;
- else
- me++;
- }
- printf("se%d: missed packet (%d) csr = %x, Lance %x, me %x\n",
- unit, sc->misscnt, csr, lance, me);
- }
- se_restart(ifp);
- se_init(unit);
- return;
- }
- if (csr & LN_CSR0_BABL) {
- sc->bablcnt++;
- if (se_verbose)
- printf("se%d: xmt timeout (%d)\n",
- unit, sc->bablcnt);
- }
- if (csr & LN_CSR0_MERR) {
- sc->merrcnt++;
- printf("se%d: memory error (%d)\n",
- unit, sc->merrcnt);
-
- if (((csr & LN_CSR0_RXON) == 0)
- || ((csr & LN_CSR0_TXON) == 0)) {
- se_restart(ifp);
- se_init(unit);
- return;
- }
- }
- }
-
- *rdp = LN_CSR0_INEA | (csr & LN_CSR0_WTC);
- wbflush();
-
- if ( csr & LN_CSR0_RINT )
- se_rint( unit );
-
- if ( csr & LN_CSR0_TINT )
- se_tint( unit );
-
- if ((csr = *rdp) & (LN_CSR0_RINT | LN_CSR0_TINT))
- goto again;
-}
-
-/*
- * Handle a transmitter complete interrupt.
- */
-void
-se_tint(int unit)
-{
- register se_softc_t sc = se_softc[unit];
- register index;
- register status;
- io_req_t request;
- struct se_desc r;
-
- /*
- * Free up descriptors for all packets in queue for which
- * transmission is complete. Start from queue tail, stop at first
- * descriptor we do not OWN, or which is in an inconsistent state
- * (lance still working).
- */
-
- while ((sc->xmt_complete != sc->xmt_last) && (sc->xmt_count > 0)) {
-
- index = sc->xmt_complete;
- (se_sw->desc_copyin) ((vm_offset_t)sc->lntring[index],
- (vm_offset_t)&r, sizeof(r));
- status = r.status;
-
- /*
- * Does lance still own it ?
- */
- if (status & LN_TSTATE_OWN)
- break;
-
- /*
- * Packet sent allright, release queue slot.
- */
- request = sc->tpkt[index];
- sc->tpkt[index] = (io_req_t) 0;
- sc->xmt_complete = ++index & (NXMT - 1);
- --sc->xmt_count;
-
- sc->is_if.if_opackets++;
- if (status & (LN_TSTATE_DEF|LN_TSTATE_ONE|LN_TSTATE_MORE))
- sc->is_if.if_collisions++;
-
- /*
- * Check for transmission errors.
- */
- if (!se_loopback_hack && status & LN_TSTATE_ERR) {
- sc->is_if.if_oerrors++;
- if (se_verbose)
- printf("se%d: xmt error (x%x)\n", unit, r.status2);
-
- if (r.status2 & (LN_TSTATE2_RTRY|LN_TSTATE2_LCOL))
- sc->is_if.if_collisions++;
-
- /*
- * Restart chip on errors that disable the
- * transmitter.
- */
- iodone(request);
- if (r.status2 & LN_TSTATE2_DISABLE) {
- register struct ifnet *ifp = &sc->is_if;
- se_restart(ifp);
- se_init(ifp->if_unit);
- return;
- }
- } else if (request) {
- /*
- * If this was a broadcast packet loop it back.
- * Signal successful transmission of the packet.
- */
- register struct ether_header *eh;
- register int i;
-
- eh = (struct ether_header *) request->io_data;
- /* ether broadcast address is in the spec */
- for (i = 0; (i < 6) && (eh->ether_dhost[i] == 0xff); i++)
- ; /* nop */
- /* sending to ourselves makes sense sometimes */
- if (i != 6 && se_loopback_hack)
- for (i = 0;
- (i < 6) && (eh->ether_dhost[i] == sc->is_addr[i]);
- i++)
- ; /* nop */
- if (i == 6)
- se_read(sc, 0, request->io_count, request);
- iodone(request);
- }
- }
- /*
- * Dequeue next transmit request, if any.
- */
- if (sc->xmt_count <= 0)
- se_start(unit);
-}
-
-/*
- * Handle a receiver complete interrupt.
- */
-void
-se_rint(int unit)
-{
- register se_softc_t sc = se_softc[unit];
- register index, first, len;
- unsigned char status, status1;
- int ring_cnt;
- struct se_desc r;
-
- /*
- * Starting from where we left off, look around the receive ring and
- * pass on all complete packets.
- */
-
- for (;; sc->rcv_last = ++index & (NRCV - 1)) {
-
- /*
- * Read in current descriptor
- */
-read_descriptor:
- (se_sw->desc_copyin) ((vm_offset_t)sc->lnrring[sc->rcv_last],
- (vm_offset_t)&r, sizeof(r));
- status = r.status;
- if (status & LN_RSTATE_OWN)
- break;
- first = index = sc->rcv_last;
-
- /*
- * If not the start of a packet, error
- */
- if (!(status & LN_RSTATE_STP)) {
- if (se_verbose)
- printf("se%d: Rring #%d, status=%x !STP\n",
- unit, index, status);
- break;
- }
- /*
- * See if packet is chained (should not) by looking at
- * the last descriptor (OWN clear and ENP set).
- * Remember the status info in this last descriptor.
- */
- ring_cnt = 1, status1 = status;
- while (((status1 & (LN_RSTATE_ERR | LN_RSTATE_OWN | LN_RSTATE_ENP)) == 0) &&
- (ring_cnt++ <= NRCV)) {
- struct se_desc r1;
- index = (index + 1) & (NRCV - 1);
- (se_sw->desc_copyin) ((vm_offset_t)sc->lnrring[index],
- (vm_offset_t)&r1, sizeof(r1));
- status1 = r1.status;
- }
-
- /*
- * Chained packet (--> illegally sized!); re-init the
- * descriptors involved and ignore this bogus packet. I
- * donno how, but it really happens that we get these
- * monsters.
- */
- if (ring_cnt > 1) {
- /*
- * Return all descriptors to lance
- */
- se_desc_set_status(sc->lnrring[first], LN_RSTATE_OWN);
- while (first != index) {
- first = (first + 1) & (NRCV - 1);
- se_desc_set_status(sc->lnrring[first], LN_RSTATE_OWN);
- }
- if ((status1 & LN_RSTATE_ERR) && se_verbose)
- printf("se%d: rcv error %x (chained)\n", unit, status1);
- continue;
- }
-
- /*
- * Good packets must be owned by us and have the end of
- * packet flag. And nothing else.
- */
- if ((status & ~LN_RSTATE_STP) == LN_RSTATE_ENP) {
- sc->is_if.if_ipackets++;
-
- if ((len = r.message_size) == 0)
- /* race seen on pmaxen: the lance
- * has not updated the size yet ??
- */
- goto read_descriptor;
- /*
- * Drop trailing CRC bytes from len and ship packet
- * up
- */
- se_read(sc, (volatile char*)sc->lnrbuf[first], len-4,0);
-
- /*
- * Return descriptor to lance, and move on to next
- * packet
- */
- r.status = LN_RSTATE_OWN;
- (se_sw->desc_copyout)((vm_offset_t)&r,
- (vm_offset_t)sc->lnrring[first],
- sizeof(r));
- continue;
- }
- /*
- * Not a good packet, see what is wrong
- */
- if (status & LN_RSTATE_ERR) {
- sc->is_if.if_ierrors++;
-
- if (se_verbose)
- printf("se%d: rcv error (x%x)\n", unit, status);
-
- /*
- * Return descriptor to lance
- */
- se_desc_set_status(sc->lnrring[first], LN_RSTATE_OWN);
- } else {
- /*
- * Race condition viz lance, Wait for the next
- * interrupt.
- */
- return;
- }
- }
-}
-
-/*
- * Output routine.
- * Call common function for wiring memory,
- * come back later (to se_start) to get
- * things going.
- */
-io_return_t
-se_output(
- int dev,
- io_req_t ior)
-{
- return net_write(&se_softc[dev]->is_if, (int(*)())se_start, ior);
-}
-
-/*
- * Start output on interface.
- *
- */
-void
-se_start(int unit)
-{
- register se_softc_t sc = se_softc[unit];
- io_req_t request;
- struct se_desc r;
- int tlen;
- spl_t s;
- register int index;
-
- s = splimp();
-
- for (index = sc->xmt_last;
- sc->xmt_count < (NXMT - 1);
- sc->xmt_last = index = (index + 1) & (NXMT - 1)) {
- /*
- * Dequeue the next transmit request, if any.
- */
- IF_DEQUEUE(&sc->is_if.if_snd, request);
- if (request == 0) {
- /*
- * Tell the lance to send the packet now
- * instead of waiting until the next 1.6 ms
- * poll interval expires.
- */
- *sc->lnregs = LN_CSR0_TDMD | LN_CSR0_INEA;
- splx(s);
- return; /* Nothing on the queue */
- }
-
- /*
- * Keep request around until transmission complete
- */
- sc->tpkt[index] = request;
- tlen = copy_to_lance(request, sc->lntbuf[index]);
-
- /*
- * Give away buffer. Must copyin/out, set len,
- * and set the OWN flag. We do not do chaining.
- */
- (se_sw->desc_copyin)((vm_offset_t)sc->lntring[index],
- (vm_offset_t)&r, sizeof(r));
- r.buffer_size = -(tlen) | 0xf000;
- r.status = (LN_TSTATE_OWN | LN_TSTATE_STP | LN_TSTATE_ENP);
- (se_sw->desc_copyout)((vm_offset_t)&r,
- (vm_offset_t)sc->lntring[index],
- sizeof(r));
- wbflush();
-
- sc->xmt_count++;
- }
- /*
- * Since we actually have queued new packets, tell
- * the chip to rescan the descriptors _now_.
- * It is quite unlikely that the ring be filled,
- * but if it is .. the more reason to do it!
- */
- *sc->lnregs = LN_CSR0_TDMD | LN_CSR0_INEA;
- splx(s);
-}
-
-
-/*
- * Pull a packet off the interface and
- * hand it up to the higher levels.
- *
- * Simulate broadcast packets in software.
- */
-void
-se_read(
- register se_softc_t sc,
- volatile char *lnrbuf,
- int len,
- io_req_t loop_back)
-{
- register struct ifnet *ifp = &sc->is_if;
- register ipc_kmsg_t new_kmsg;
- char *hdr, *pkt;
-
- if (len <= sizeof(struct ether_header))
- return; /* sanity */
-
- /*
- * Get a new kmsg to put data into.
- */
- new_kmsg = net_kmsg_get();
- if (new_kmsg == IKM_NULL) {
- /*
- * No room, drop the packet
- */
- ifp->if_rcvdrops++;
- return;
- }
-
- hdr = net_kmsg(new_kmsg)->header;
- pkt = net_kmsg(new_kmsg)->packet;
-
-#define OFF0 (sizeof(struct ether_header) - sizeof(struct packet_header))
-#define OFF1 (OFF0 & ~3)
- if (loop_back) {
- bcopy(loop_back->io_data, hdr, sizeof(struct ether_header));
- bcopy(loop_back->io_data + OFF0,
- pkt, len - OFF0);
- } else
- copy_from_lance(lnrbuf, len, (struct ether_header*)hdr,
- (struct packet_header*)pkt);
-
- /*
- * Set up the 'fake' header with length. Type has been left
- * in the correct place.
- */
- len = len - OFF0;
- ((struct packet_header *)pkt)->length = len;
-
- /*
- * Hand the packet to the network module.
- */
- net_packet(ifp, new_kmsg, len, ethernet_priority(new_kmsg));
-}
-
-
-/*
- * Get a packet out of Lance memory and into main memory.
- */
-private void
-copy_from_lance(
- register volatile unsigned char *rbuf,
- register unsigned int nbytes,
- struct ether_header *hdr,
- struct packet_header *pkt)
-{
- /*
- * Read in ethernet header
- */
- (se_sw->data_copyin) ((vm_offset_t)rbuf, (vm_offset_t)hdr, sizeof(struct ether_header));
-
- nbytes -= sizeof(struct ether_header);
- rbuf += (se_sw->mapoffs) (sizeof(struct ether_header));
-
- pkt->type = (unsigned short) hdr->ether_type;
-
- (se_sw->data_copyin) ((vm_offset_t)rbuf, (vm_offset_t)(pkt + 1), nbytes);
-}
-
-
-/*
- * Move a packet into Lance space
- */
-private int
-copy_to_lance(
- register io_req_t request,
- volatile char *sbuf)
-{
- register unsigned short *dp;
- register int len;
-
- dp = (unsigned short *) request->io_data;
- len = request->io_count;
-
- if (len > (int)(ETHERMTU + sizeof(struct ether_header))) {
- printf("se: truncating HUGE packet\n");
- len = ETHERMTU + sizeof(struct ether_header);
- }
-
- (se_sw->data_copyout) ((vm_offset_t)dp, (vm_offset_t)sbuf, len);
-
- if (len < LN_MINBUF_NOCH)
- /*
- * The lance needs at least this much data in a packet. Who
- * cares if I send some garbage that was left in the lance
- * buffer ? If one can spoof packets then one can spoof
- * packets!
- */
- len = LN_MINBUF_NOCH;
- return len;
-}
-
-/*
- * Reset a descriptor's flags.
- * Optionally give the descriptor to the lance
- */
-private void
-se_desc_set_status (
- register se_desc_t lndesc,
- int val)
-{
- struct se_desc desc;
-
- (se_sw->desc_copyin) ((vm_offset_t)lndesc, (vm_offset_t)&desc, sizeof(desc));
- desc.desc4.bits = 0;
- desc.status = val;
- (se_sw->desc_copyout) ((vm_offset_t)&desc, (vm_offset_t)lndesc, sizeof(desc));
- wbflush();
-}
-
-/*
- * Set/Get status functions
- */
-int
-se_get_status(
- int dev,
- dev_flavor_t flavor,
- dev_status_t status, /* pointer to OUT array */
- natural_t *status_count) /* out */
-{
- return (net_getstat(&se_softc[dev]->is_if,
- flavor, status, status_count));
-}
-
-int
-se_set_status(
- int unit,
- dev_flavor_t flavor,
- dev_status_t status,
- natural_t status_count)
-{
- register se_softc_t sc;
-
- sc = se_softc[unit];
-
-
- switch (flavor) {
-
- case NET_STATUS:
- break;
-
- case NET_ADDRESS: {
-
- register union ether_cvt {
- unsigned char addr[6];
- int lwd[2];
- } *ec = (union ether_cvt *) status;
-
- if (status_count < sizeof(*ec) / sizeof(int))
- return (D_INVALID_SIZE);
-
- ec->lwd[0] = ntohl(ec->lwd[0]);
- ec->lwd[1] = ntohl(ec->lwd[1]);
-
- se_setaddr(ec->addr, unit);
-
- break;
- }
-
- default:
- return (D_INVALID_OPERATION);
- }
-
- return (D_SUCCESS);
-}
-
-
-/*
- * Install new filter.
- * Nothing special needs to be done here.
- */
-io_return_t
-se_setinput(
- int dev,
- ipc_port_t receive_port,
- int priority,
- filter_t *filter,
- natural_t filter_count)
-{
- return (net_set_filter(&se_softc[dev]->is_if,
- receive_port, priority,
- filter, filter_count));
-}
-
-/*
- * Allocate and initialize a ring descriptor.
- * Allocates a buffer from the lance memory and writes a descriptor
- * for that buffer to the host virtual address LNDESC.
- */
-private volatile long
-*se_desc_alloc (
- register se_softc_t sc,
- register se_desc_t lndesc)
-{
- register vm_offset_t dp; /* data pointer */
- struct se_desc desc;
-
- /*
- * Allocate buffer in lance space
- */
- dp = se_malloc(sc, LN_BUFFER_SIZE);
-
- /*
- * Build a descriptor pointing to it
- */
- desc.addr_low = Addr_lo(Lmem(dp));
- desc.addr_hi = Addr_hi(Lmem(dp));
- desc.status = 0;
- desc.buffer_size = -LN_BUFFER_SIZE;
- desc.desc4.bits = 0;
-
- /*
- * Copy the descriptor to lance space
- */
- (se_sw->desc_copyout) ((vm_offset_t)&desc, (vm_offset_t)lndesc, sizeof(desc));
- wbflush();
-
- return (volatile long *) Hmem(dp);
-}
-
-/*
- * Allocate a chunk of lance RAM buffer. Since we never
- * give lance RAM buffer memory back, we'll just step up the
- * byte-count on a per-unit basis.
- *
- * The return value is an index into the lance memory, which can be
- * passed with Hmem() and Lmem() to get the host and chip virtual addresses.
- */
-private vm_offset_t
-se_malloc(
- se_softc_t sc,
- int size)
-{
- register vm_offset_t ret;
-
- /*
- * On first call, zero lance memory
- */
- if (sc->lnsbrk == 0)
- (se_sw->bzero) (Hmem(0), LN_MEMORY_SIZE);
-
- /*
- * Start out on the first double longword boundary
- * (this accomodates some machines, with minimal loss)
- */
- if (sc->lnsbrk & 0xf)
- sc->lnsbrk = (sc->lnsbrk + 0x10) & ~0xf;
-
- ret = sc->lnsbrk;
- sc->lnsbrk += size;
-
- if (sc->lnsbrk > LN_MEMORY_SIZE)
- panic("se_malloc");
-
- return ret;
-}
-
-#endif NLN > 0