summaryrefslogtreecommitdiff
path: root/i386/i386at/gpl/if_ul.c
diff options
context:
space:
mode:
Diffstat (limited to 'i386/i386at/gpl/if_ul.c')
-rw-r--r--i386/i386at/gpl/if_ul.c489
1 files changed, 0 insertions, 489 deletions
diff --git a/i386/i386at/gpl/if_ul.c b/i386/i386at/gpl/if_ul.c
deleted file mode 100644
index 59e74f5..0000000
--- a/i386/i386at/gpl/if_ul.c
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * Copyright (c) 1994 Shantanu Goel
- * 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.
- *
- * THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. THE AUTHOR DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- */
-
-/*
- * Written 1993 by Donald Becker.
- *
- * Copyright 1993 United States Government as represented by the
- * Director, National Security Agency. This software may be used and
- * distributed according to the terms of the GNU Public License,
- * incorporated herein by reference.
- *
- * The Author may be reached as becker@super.org or
- * C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
- */
-
-#include <wd.h>
-#include <ul.h>
-#if NUL > 0
-/*
- * Driver for SMC Ultra ethernet adaptor.
- * Derived from the Linux driver by Donald Becker.
- *
- * Shantanu Goel (goel@cs.columbia.edu)
- */
-#include <mach/sa/sys/types.h>
-#include "vm_param.h"
-#include <kern/time_out.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>
-#include <chips/busses.h>
-#include <i386/machspl.h>
-#include <i386/pio.h>
-#include <i386at/gpl/if_nsreg.h>
-
-#define START_PG 0x00 /* first page of TX buffer */
-#define ULTRA_CMDREG 0 /* offset of ASIC command register */
-#define ULTRA_RESET 0x80 /* board reset in ULTRA_CMDREG */
-#define ULTRA_MEMEN 0x40 /* enable shared memory */
-#define ULTRA_NIC_OFF 16 /* NIC register offset */
-
-#define ulunit(dev) minor(dev)
-
-/*
- * Autoconfiguration stuff.
- */
-int ulprobe();
-void ulattach();
-int ulstd[] = { 0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0 };
-struct bus_device *ulinfo[NUL];
-struct bus_driver uldriver = {
- ulprobe, 0, ulattach, 0, ulstd, "ul", ulinfo, 0, 0, 0
-};
-
-/*
- * NS8390 state.
- */
-struct nssoftc ulnssoftc[NUL];
-
-/*
- * Ultra state.
- */
-struct ulsoftc {
- int sc_mstart; /* start of board's RAM */
- int sc_mend; /* end of board's RAM */
- int sc_rmstart; /* start of receive RAM */
- int sc_rmend; /* end of receive RAM */
-} ulsoftc[NUL];
-
-void ulstart(int);
-void ul_reset(struct nssoftc *sc);
-void ul_input(struct nssoftc *sc, int, char *, int);
-int ul_output(struct nssoftc *sc, int, char *, int);
-
-/*
- * Watchdog.
- */
-int ulwstart = 0;
-void ulwatch(void);
-
-#define ULDEBUG
-#ifdef ULDEBUG
-int uldebug = 0;
-#define DEBUGF(stmt) { if (uldebug) stmt; }
-#else
-#define DEBUGF(stmt)
-#endif
-
-/*
- * Probe for the Ultra.
- * This looks like an 8013 with the station address PROM
- * at I/O ports <base>+8 to <base>+13, with a checksum following.
- */
-int
-ulprobe(xxx, ui)
- int xxx;
- struct bus_device *ui;
-{
- int *port;
-
- if (ui->unit >= NUL) {
- printf("ul%d: not configured\n", ui->unit);
- return (0);
- }
- for (port = ulstd; *port; port++) {
- if (*port < 0)
- continue;
- /*
- * Check chip ID nibble.
- */
- if ((inb(*port + 7) & 0xf0) != 0x20)
- continue;
- if (ulprobe1(*port, ui)) {
- ui->address = *port;
- *port = -1;
-#if NWD > 0
- /*
- * XXX: The Western Digital/SMC driver can sometimes
- * probe the Ultra incorrectly. Remove the Ultra's
- * port from it's list to avoid the problem.
- */
- {
- int i;
- extern int wdstd[];
-
- for (i = 0; wdstd[i]; i++) {
- if (wdstd[i] == ui->address) {
- wdstd[i] = -1;
- break;
- }
- }
- }
-#endif
- return (1);
- }
- }
- return (0);
-}
-
-int
-ulprobe1(port, ui)
- int port;
- struct bus_device *ui;
-{
- u_char num_pages, irqreg, addr, reg4;
- u_char irqmap[] = { 0, 9, 3, 5, 7, 10, 11, 15 };
- short num_pages_tbl[4] = { 0x20, 0x40, 0x80, 0xff };
- int i, irq, checksum = 0;
- int addr_tbl[4] = { 0x0c0000, 0x0e0000, 0xfc0000, 0xfe0000 };
- struct ulsoftc *ul = &ulsoftc[ui->unit];
- struct nssoftc *ns = &ulnssoftc[ui->unit];
- struct ifnet *ifp = &ns->sc_if;
-
- /*
- * Select the station address register set.
- */
- reg4 = inb(port + 4) & 0x7f;
- outb(port + 4, reg4);
-
- for (i = 0; i < 8; i++)
- checksum += inb(port + 8 + i);
- if ((checksum & 0xff) != 0xff)
- return (0);
-
- /*
- * Use 2 transmit buffers.
- */
- ns->sc_pingpong = 1;
-
- printf("ul%d: SMC Ultra at 0x%03x, ", ui->unit, port);
- for (i = 0; i < ETHER_ADDR_LEN; i++) {
- if (i == 0)
- printf("%02x", ns->sc_addr[i] = inb(port + 8 + i));
- else
- printf(":%02x", ns->sc_addr[i] = inb(port + 8 + i));
- }
- /*
- * Switch from station address to alternate register set
- * and read useful registers there.
- */
- outb(port + 4, 0x80 | reg4);
-
- /*
- * Enable FINE16 mode to avoid BIOS ROM width mismatches
- * during reboot.
- */
- outb(port + 0x0c, 0x80 | inb(port + 0x0c));
- irqreg = inb(port + 0x0d);
- addr = inb(port + 0x0b);
-
- /*
- * Switch back to station address register set so the MSDOG
- * driver can find the card after a warm boot.
- */
- outb(port + 4, reg4);
-
- /*
- * Determine IRQ. The IRQ bits are split.
- */
- irq = irqmap[((irqreg & 0x40) >> 4) + ((irqreg & 0x0c) >> 2)];
- if (irq == 0) {
- printf(", failed to detect IRQ line.\n");
- return (0);
- }
- ui->sysdep1 = irq;
- take_dev_irq(ui);
- printf(", irq %d", irq);
-
- /*
- * Determine board's RAM location.
- */
- ul->sc_mstart = ((addr & 0x0f) << 13) + addr_tbl[(addr >> 6) & 3];
- num_pages = num_pages_tbl[(addr >> 4) & 3];
- ul->sc_rmstart = ul->sc_mstart + TX_PAGES(ns) * 256;
- ul->sc_mend = ul->sc_rmend
- = ul->sc_mstart + (num_pages - START_PG) * 256;
- printf(", memory 0x%05x-0x%05x\n", ul->sc_mstart, ul->sc_mend);
-
- /*
- * Initialize 8390 state.
- */
- ns->sc_name = ui->name;
- ns->sc_unit = ui->unit;
- ns->sc_port = port + ULTRA_NIC_OFF;
- ns->sc_word16 = 1;
- ns->sc_txstrtpg = START_PG;
- ns->sc_rxstrtpg = START_PG + TX_PAGES(ns);
- ns->sc_stoppg = num_pages;
- ns->sc_reset = ul_reset;
- ns->sc_input = ul_input;
- ns->sc_output = ul_output;
-
- DEBUGF(printf("ul%d: txstrtpg %d rxstrtpg %d num_pages %d\n",
- ui->unit, ns->sc_txstrtpg, ns->sc_rxstrtpg, num_pages));
-
- /*
- * Initialize interface header.
- */
- ifp->if_unit = ui->unit;
- ifp->if_mtu = ETHERMTU;
- ifp->if_flags = IFF_BROADCAST;
- ifp->if_header_size = sizeof(struct ether_header);
- ifp->if_header_format = HDR_ETHERNET;
- ifp->if_address_size = ETHER_ADDR_LEN;
- ifp->if_address = ns->sc_addr;
- if_init_queues(ifp);
-
- return (1);
-}
-
-void
-ulattach(ui)
- struct bus_device *ui;
-{
- /*
- * void
- */
-}
-
-int
-ulopen(dev, flag)
- dev_t dev;
- int flag;
-{
- int unit = ulunit(dev), s;
- struct bus_device *ui;
-
- if (unit >= NUL || (ui = ulinfo[unit]) == 0 || ui->alive == 0)
- return (ENXIO);
-
- /*
- * Start watchdog.
- */
- if (!ulwstart) {
- ulwstart++;
- timeout(ulwatch, 0, hz);
- }
- ulnssoftc[unit].sc_if.if_flags |= IFF_UP;
- s = splimp();
- outb(ui->address, ULTRA_MEMEN); /* enable memory, 16 bit mode */
- outb(ui->address + 5, 0x80);
- outb(ui->address + 6, 0x01); /* enable interrupts and memory */
- nsinit(&ulnssoftc[unit]);
- splx(s);
- return (0);
-}
-
-int
-uloutput(dev, ior)
- dev_t dev;
- io_req_t ior;
-{
- int unit = ulunit(dev);
- struct bus_device *ui;
-
- if (unit >= NUL || (ui = ulinfo[unit]) == 0 || ui->alive == 0)
- return (ENXIO);
-
- return (net_write(&ulnssoftc[unit].sc_if, ulstart, ior));
-}
-
-int
-ulsetinput(dev, receive_port, priority, filter, filter_count)
- dev_t dev;
- mach_port_t receive_port;
- int priority;
- filter_t *filter;
- unsigned filter_count;
-{
- int unit = ulunit(dev);
- struct bus_device *ui;
-
- if (unit >= NUL || (ui = ulinfo[unit]) == 0 || ui->alive == 0)
- return (ENXIO);
-
- return (net_set_filter(&ulnssoftc[unit].sc_if, receive_port,
- priority, filter, filter_count));
-}
-
-int
-ulgetstat(dev, flavor, status, count)
- dev_t dev;
- int flavor;
- dev_status_t status;
- unsigned *count;
-{
- int unit = ulunit(dev);
- struct bus_device *ui;
-
- if (unit >= NUL || (ui = ulinfo[unit]) == 0 || ui->alive == 0)
- return (ENXIO);
-
- return (net_getstat(&ulnssoftc[unit].sc_if, flavor, status, count));
-}
-
-int
-ulsetstat(dev, flavor, status, count)
- dev_t dev;
- int flavor;
- dev_status_t status;
- unsigned count;
-{
- int unit = ulunit(dev), oflags, s;
- struct bus_device *ui;
- struct ifnet *ifp;
- struct net_status *ns;
-
- if (unit >= NUL || (ui = ulinfo[unit]) == 0 || ui->alive == 0)
- return (ENXIO);
-
- ifp = &ulnssoftc[unit].sc_if;
-
- switch (flavor) {
-
- case NET_STATUS:
- if (count < NET_STATUS_COUNT)
- return (D_INVALID_SIZE);
- ns = (struct net_status *)status;
- oflags = ifp->if_flags & (IFF_ALLMULTI|IFF_PROMISC);
- ifp->if_flags &= ~(IFF_ALLMULTI|IFF_PROMISC);
- ifp->if_flags |= ns->flags & (IFF_ALLMULTI|IFF_PROMISC);
- if ((ifp->if_flags & (IFF_ALLMULTI|IFF_PROMISC)) != oflags) {
- s = splimp();
- nsinit(&ulnssoftc[unit]);
- splx(s);
- }
- break;
-
- default:
- return (D_INVALID_OPERATION);
- }
- return (D_SUCCESS);
-}
-
-void
-ulintr(unit)
- int unit;
-{
- nsintr(&ulnssoftc[unit]);
-}
-
-void
-ulstart(unit)
- int unit;
-{
- nsstart(&ulnssoftc[unit]);
-}
-
-void
-ul_reset(ns)
- struct nssoftc *ns;
-{
- int port = ns->sc_port - ULTRA_NIC_OFF; /* ASIC base address */
-
- outb(port, ULTRA_RESET);
- outb(0x80, 0); /* I/O delay */
- outb(port, ULTRA_MEMEN);
-}
-
-void
-ul_input(ns, count, buf, ring_offset)
- struct nssoftc *ns;
- int count;
- char *buf;
- int ring_offset;
-{
- int xfer_start;
- struct ulsoftc *ul = &ulsoftc[ns->sc_unit];
-
- DEBUGF(printf("ul%d: ring_offset = %d\n", ns->sc_unit, ring_offset));
-
- xfer_start = ul->sc_mstart + ring_offset - (START_PG << 8);
- if (xfer_start + count > ul->sc_rmend) {
- int semi_count = ul->sc_rmend - xfer_start;
-
- /*
- * Input move must be wrapped.
- */
- bcopy((char *)phystokv(xfer_start), buf, semi_count);
- count -= semi_count;
- bcopy((char *)phystokv(ul->sc_rmstart), buf+semi_count, count);
- } else
- bcopy((char *)phystokv(xfer_start), buf, count);
-}
-
-int
-ul_output(ns, count, buf, start_page)
- struct nssoftc *ns;
- int count;
- char *buf;
- int start_page;
-{
- char *shmem;
- int i;
- struct ulsoftc *ul = &ulsoftc[ns->sc_unit];
-
- DEBUGF(printf("ul%d: start_page = %d\n", ns->sc_unit, start_page));
-
- shmem = (char *)phystokv(ul->sc_mstart + ((start_page-START_PG) << 8));
- bcopy(buf, shmem, count);
- while (count < ETHERMIN + sizeof(struct ether_header)) {
- *(shmem + count) = 0;
- count++;
- }
- return (count);
-}
-
-/*
- * Watchdog.
- * Check for hung transmissions.
- */
-void
-ulwatch()
-{
- int unit, s;
- struct nssoftc *ns;
-
- timeout(ulwatch, 0, hz);
-
- s = splimp();
- for (unit = 0; unit < NUL; unit++) {
- if (ulinfo[unit] == 0 || ulinfo[unit]->alive == 0)
- continue;
- ns = &ulnssoftc[unit];
- if (ns->sc_timer && --ns->sc_timer == 0) {
- printf("ul%d: transmission timeout\n", unit);
- nsinit(ns);
- }
- }
- splx(s);
-}
-
-#endif /* NUL > 0 */