From 721745e356873f865540e4d539aee00ab7ef7d87 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 14 Mar 2004 22:35:29 +0000 Subject: [PATCH] The rdp driver uses the COMPAT_OLD api. This is being retired, so this driver is being retired. Remove it from the tree. If someone wants to update it to the latest APIs and can test the hardware, it can return to the tree. --- sys/conf/files.i386 | 1 - sys/i386/conf/NOTES | 6 - sys/i386/isa/if_rdp.c | 1396 -------------------------------------- sys/i386/isa/if_rdpreg.h | 187 ----- 4 files changed, 1590 deletions(-) delete mode 100644 sys/i386/isa/if_rdp.c delete mode 100644 sys/i386/isa/if_rdpreg.h diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index aa24a0c1df6f..79aac9419e69 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -266,7 +266,6 @@ i386/isa/elink.c optional ep i386/isa/elink.c optional ie i386/isa/gsc.c count gsc i386/isa/if_el.c count el -i386/isa/if_rdp.c count rdp i386/isa/isa.c optional isa i386/isa/isa_compat.c optional isa compat_oldisa \ warning "Old ISA driver compatibility shims present." diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index a876312532fa..744bd4b650a1 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -511,7 +511,6 @@ hint.mse.0.irq="5" # oltr: Olicom ISA token-ring adapters OC-3115, OC-3117, OC-3118 and OC-3133. # Olicom PCI token-ring adapters OC-3136, OC-3137, OC-3139, OC-3140, # OC-3141, OC-3540 and OC-3250. -# rdp: RealTek RTL 8002-based pocket ethernet adapters # sbni: Granch SBNI12-xx ISA and PCI adapters # sr: RISCom/N2 hdlc sync 1/2 port V.35/X.21 serial driver (requires sppp) # wl: Lucent Wavelan (ISA card only). @@ -554,11 +553,6 @@ hint.lnc.0.at="isa" hint.lnc.0.port="0x280" hint.lnc.0.irq="10" hint.lnc.0.drq="0" -device rdp 1 -hint.rdp.0.at="isa" -hint.rdp.0.port="0x378" -hint.rdp.0.irq="7" -hint.rdp.0.flags="2" device sbni hint.sbni.0.at="isa" hint.sbni.0.port="0x210" diff --git a/sys/i386/isa/if_rdp.c b/sys/i386/isa/if_rdp.c deleted file mode 100644 index a396bdd69eea..000000000000 --- a/sys/i386/isa/if_rdp.c +++ /dev/null @@ -1,1396 +0,0 @@ -/* - * Copyright 1998, Joerg Wunsch - * 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 unmodified, this list of conditions, and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * Device driver for RealTek RTL 8002 (`REDP') based pocket-ethernet - * adapters, hooked up to a printer port. `rdp' is a shorthand for - * REDP since some tools like netstat work best if the interface name - * has no more than three letters. - * - * Driver configuration flags so far: - * flags 0x1 -- assume 74S288 EEPROM (default 94C46) - * flags 0x2 -- use `slow' mode (mode 3 of the packet driver, default 0) - * - * Maybe this driver will some day also work with the successor, RTL - * 8012 (`AREDP'), which is unfortunately not fully register- - * compatible with the 8002. The 8012 offers support for faster - * transfer modi like bidirectional SPP and EPP, 64 K x 4 buffer - * memory as opposed to 16 K x 4 for the 8002, a multicast filter, and - * a builtin multiplexer that allows chaining a printer behind the - * ethernet adapter. - * - * About the only documentation i've been able to find about the RTL - * 8002 was the packet driver source code at ftp.realtek.com.tw, so - * this driver is somewhat based on the way the packet driver handles - * the chip. The exact author of the packet driver is unknown, the - * only name that i could find in the source was someone called Chiu, - * supposedly an employee of RealTek. So credits to them for that - * piece of code which has proven valuable to me. - * - * Later on, Leo kuo has been very helpful to me - * by sending me a readable (PDF) file documenting the RTL 8012, which - * helped me to also understand the 8002, as well as by providing me - * with the source code of the 8012 packet driver that i haven't been - * able to find on the FTP site. A big Thanks! goes here to RealTek - * for this kind of service. - */ - -#include "rdp.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef INET -#include -#include -#endif - -#include - -#include -#include - -#include -#include -#include - -#ifndef COMPAT_OLDISA -#error "The rdp device requires the old isa compatibility shims" -#endif - -#define IOCTL_CMD_T u_long - -/* - * Debug levels (ORed together): - * != 0 - general (bad packets etc.) - * 2 - debug EEPROM IO - * 4 - debug interrupt status - */ -#undef DEBUG -#define DEBUG 0 - -/* - * rdp_softc: per interface info and status - */ -struct rdp_softc { - struct arpcom arpcom; /* - * Ethernet common, always goes first so - * a rdp_softc * can be cast into an - * arpcom * or into an ifnet *. - */ - - /* - * local stuff, somewhat sorted by memory alignment class - */ - u_int baseaddr; /* IO port address */ - u_short txsize; /* tx size for next (buffered) packet, - * there's only one additional packet - * we can buffer, thus a single variable - * ought to be enough */ - int txbusy; /* tx is transmitting */ - int txbuffered; /* # of packets in tx buffer */ - int slow; /* use lpt_control to send data */ - u_char irqenbit; /* mirror of current Ctrl_IRQEN */ - /* - * type of parameter EEPROM; device flags 0x1 selects 74S288 - */ - enum { - EEPROM_93C46, EEPROM_74S288 /* or 82S123 */ - } eeprom; -}; - -static struct rdp_softc rdp_softc[NRDP]; - -/* - * Since there's no fixed location in the EEPROM about where to find - * the ethernet hardware address, we drop a table of valid OUIs here, - * and search through the EEPROM until we find a possible valid - * Ethernet address. Only the first 16 bits of all possible OUIs are - * recorded in the table (as obtained from - * http://standards.ieee.org/regauth/oui/oui.txt). - */ - -static u_short allowed_ouis[] = { - 0x0000, 0x0001, 0x0002, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x0010, 0x001C, 0x0020, 0x0040, 0x0050, 0x0060, - 0x0070, 0x0080, 0x0090, 0x009D, 0x00A0, 0x00AA, 0x00BB, - 0x00C0, 0x00CF, 0x00DD, 0x00E0, 0x00E6, 0x0207, 0x021C, - 0x0260, 0x0270, 0x029D, 0x02AA, 0x02BB, 0x02C0, 0x02CF, - 0x02E6, 0x040A, 0x04E0, 0x0800, 0x08BB, 0x1000, 0x1100, - 0x8000, 0xAA00 -}; - -/* - * ISA bus support. - */ -static int rdp_probe(struct isa_device *); -static int rdp_attach(struct isa_device *); - -/* - * Required entry points. - */ -static void rdp_init(void *); -static int rdp_ioctl(struct ifnet *, IOCTL_CMD_T, caddr_t); -static void rdp_start(struct ifnet *); -static void rdp_reset(struct ifnet *); -static void rdp_watchdog(struct ifnet *); -static void rdpintr(int); - -/* - * REDP private functions. - */ - -static void rdp_stop(struct rdp_softc *); -static void rdp_rint(struct rdp_softc *); -static void rdp_get_packet(struct rdp_softc *, unsigned); -static u_short rdp_write_mbufs(struct rdp_softc *, struct mbuf *); -static int rdp_gethwaddr_93c46(struct rdp_softc *, u_char *); -static void rdp_gethwaddr_74s288(struct rdp_softc *, u_char *); -static void rdp_93c46_cmd(struct rdp_softc *, u_short, unsigned); -static u_short rdp_93c46_read(struct rdp_softc *); - -struct isa_driver rdpdriver = { - INTR_TYPE_NET, - rdp_probe, - rdp_attach, - "rdp", - 1 /* we wanna get a chance before lptN */ -}; -COMPAT_ISA_DRIVER(rdp, rdpdriver); - -/* - * REDP-specific functions. - * - * They are inlined, thus go first in this file. Together with gcc's - * usual optimization, these functions probably come close to the - * packet driver's hand-optimized code. ;-) - * - * Comments are partially obtained from the packet driver as well. - * Some of the function names contain register names which don't make - * much sense for us, but i've kept them for easier reference in - * comparision to the packet driver. - * - * Some of the functions are currently not used by the driver; it's - * not quite clear whether we ever need them at all. They are - * supposedly even slower than what is currently implemented as `slow' - * mode. Right now, `fast' (default) mode is what the packet driver - * calls mode 0, slow mode is mode 3 (writing through lpt_control, - * reading twice). - * - * We should autoprobe the modi, as opposed to making them dependent - * on a kernel configuration flag. - */ - -/* - * read a nibble from rreg; end-of-data cmd is not issued; - * used for general register read. - * - * Unlike the packet driver's version, i'm shifting the result - * by 3 here (as opposed to within the caller's code) for clarity. - * -- Joerg - */ -static __inline u_char -RdNib(struct rdp_softc *sc, u_char rreg) -{ - - outb(sc->baseaddr + lpt_data, EOC + rreg); - outb(sc->baseaddr + lpt_data, RdAddr + rreg); /* write addr */ - (void)inb(sc->baseaddr + lpt_status); - return (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f; -} - -#if 0 -/* - * read a byte from MAR register through lpt_data; the low nibble is - * read prior to the high one; end-of-read command is not issued; used - * for remote DMA in mode 4 + 5 - */ -static __inline u_char -RdByte(struct rdp_softc *sc) -{ - u_char hinib, lonib; - - outb(sc->baseaddr + lpt_data, RdAddr + MAR); /* cmd for low nibble */ - lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f; - outb(sc->baseaddr + lpt_data, RdAddr + MAR + HNib); - hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0; - return hinib + lonib; -} - - -/* - * read a byte from MAR register through lpt_data; the low nibble is - * read prior to the high one; end-of-read command is not issued; used - * for remote DMA in mode 6 + 7 - */ -static __inline u_char -RdByte1(struct rdp_softc *sc) -{ - u_char hinib, lonib; - - outb(sc->baseaddr + lpt_data, RdAddr + MAR); /* cmd for low nibble */ - (void)inb(sc->baseaddr + lpt_status); - lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f; - outb(sc->baseaddr + lpt_data, RdAddr + MAR + HNib); - (void)inb(sc->baseaddr + lpt_status); - hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0; - return hinib + lonib; -} -#endif - - -/* - * read a byte from MAR register through lpt_control; the low nibble is - * read prior to the high one; end-of-read command is not issued; used - * for remote DMA in mode 0 + 1 - */ -static __inline u_char -RdByteA1(struct rdp_softc *sc) -{ - u_char hinib, lonib; - - outb(sc->baseaddr + lpt_control, Ctrl_LNibRead); - lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f; - outb(sc->baseaddr + lpt_control, Ctrl_HNibRead); - hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0; - return hinib + lonib; -} - - -/* - * read a byte from MAR register through lpt_control; the low nibble is - * read prior to the high one; end-of-read command is not issued; used - * for remote DMA in mode 2 + 3 - */ -static __inline u_char -RdByteA2(struct rdp_softc *sc) -{ - u_char hinib, lonib; - - outb(sc->baseaddr + lpt_control, Ctrl_LNibRead); - (void)inb(sc->baseaddr + lpt_status); - lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f; - outb(sc->baseaddr + lpt_control, Ctrl_HNibRead); - (void)inb(sc->baseaddr + lpt_status); - hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0; - return hinib + lonib; -} - -/* - * End-of-read cmd - */ -static __inline void -RdEnd(struct rdp_softc *sc, u_char rreg) -{ - - outb(sc->baseaddr + lpt_data, EOC + rreg); -} - -/* - * Write a nibble to a register; end-of-write is issued. - * Used for general register write. - */ -static __inline void -WrNib(struct rdp_softc *sc, u_char wreg, u_char wdata) -{ - - /* prepare and write address */ - outb(sc->baseaddr + lpt_data, EOC + wreg); - outb(sc->baseaddr + lpt_data, WrAddr + wreg); - outb(sc->baseaddr + lpt_data, WrAddr + wreg); - /* prepare and write data */ - outb(sc->baseaddr + lpt_data, WrAddr + wdata); - outb(sc->baseaddr + lpt_data, wdata); - outb(sc->baseaddr + lpt_data, wdata); - /* end-of-write */ - outb(sc->baseaddr + lpt_data, EOC + wdata); -} - -/* - * Write a byte to a register; end-of-write is issued. - * Used for general register write. - */ -static __inline void -WrByte(struct rdp_softc *sc, u_char wreg, u_char wdata) -{ - - /* prepare and write address */ - outb(sc->baseaddr + lpt_data, EOC + wreg); - outb(sc->baseaddr + lpt_data, WrAddr + wreg); - outb(sc->baseaddr + lpt_data, WrAddr + wreg); - /* prepare and write low nibble */ - outb(sc->baseaddr + lpt_data, WrAddr + (wdata & 0x0F)); - outb(sc->baseaddr + lpt_data, (wdata & 0x0F)); - outb(sc->baseaddr + lpt_data, (wdata & 0x0F)); - /* prepare and write high nibble */ - wdata >>= 4; - outb(sc->baseaddr + lpt_data, wdata); - outb(sc->baseaddr + lpt_data, wdata + HNib); - outb(sc->baseaddr + lpt_data, wdata + HNib); - /* end-of-write */ - outb(sc->baseaddr + lpt_data, EOC + wdata + HNib); -} - -/* - * Write the byte to DRAM via lpt_data; - * used for remote DMA write in mode 0 / 2 / 4 - */ -static __inline void -WrByteALToDRAM(struct rdp_softc *sc, u_char val) -{ - - outb(sc->baseaddr + lpt_data, val & 0x0F); - outb(sc->baseaddr + lpt_data, MkHi(val)); -} - -/* - * Write the byte to DRAM via lpt_control; - * used for remote DMA write in mode 1 / 3 / 5 - */ -static __inline void -WrByteALToDRAMA(struct rdp_softc *sc, u_char val) -{ - - outb(sc->baseaddr + lpt_data, val & 0x0F); - outb(sc->baseaddr + lpt_control, Ctrl_LNibRead | sc->irqenbit); - outb(sc->baseaddr + lpt_data, val >> 4); - outb(sc->baseaddr + lpt_control, Ctrl_HNibRead | sc->irqenbit); -} - -#if 0 /* they could be used for the RAM test */ -/* - * Write the u_short to DRAM via lpt_data; - * used for remote DMA write in mode 0 / 2 / 4 - */ -static __inline void -WrWordbxToDRAM(struct rdp_softc *sc, u_short val) -{ - - outb(sc->baseaddr + lpt_data, val & 0x0F); - val >>= 4; - outb(sc->baseaddr + lpt_data, (val & 0x0F) + HNib); - val >>= 4; - outb(sc->baseaddr + lpt_data, val & 0x0F); - val >>= 4; - outb(sc->baseaddr + lpt_data, val + HNib); -} - - -/* - * Write the u_short to DRAM via lpt_control; - * used for remote DMA write in mode 1 / 3 / 5 - */ -static __inline void -WrWordbxToDRAMA(struct rdp_softc *sc, u_short val) -{ - - outb(sc->baseaddr + lpt_data, val & 0x0F); - outb(sc->baseaddr + lpt_control, Ctrl_LNibRead | sc->irqenbit); - val >>= 4; - outb(sc->baseaddr + lpt_data, (val & 0x0F) + HNib); - outb(sc->baseaddr + lpt_control, Ctrl_HNibRead | sc->irqenbit); - val >>= 4; - outb(sc->baseaddr + lpt_data, val & 0x0F); - outb(sc->baseaddr + lpt_control, Ctrl_LNibRead | sc->irqenbit); - val >>= 4; - outb(sc->baseaddr + lpt_data, val + HNib); - outb(sc->baseaddr + lpt_control, Ctrl_HNibRead | sc->irqenbit); -} -#endif - - -/* - * Determine if the device is present - * - * on entry: - * a pointer to an isa_device struct - * on exit: - * 0 if device not found - * or # of i/o addresses used (if found) - */ -static int -rdp_probe(struct isa_device *isa_dev) -{ - int unit = isa_dev->id_unit; - struct rdp_softc *sc = &rdp_softc[unit]; - u_char b1, b2; - intrmask_t irqmap[3]; - u_char sval[3]; - - if (unit < 0 || unit >= NRDP) - return 0; - - sc->baseaddr = isa_dev->id_iobase; - if (isa_dev->id_flags & 1) - sc->eeprom = EEPROM_74S288; - /* else defaults to 93C46 */ - if (isa_dev->id_flags & 2) - sc->slow = 1; - - /* let R/WB = A/DB = CSB = high to be ready for next r/w cycle */ - outb(sc->baseaddr + lpt_data, 0xFF); - /* DIR = 0 for write mode, IRQEN=0, SLCT=INIT=AUTOFEED=STB=high */ - outb(sc->baseaddr + lpt_control, Ctrl_SelData); - /* software reset */ - WrNib(sc, CMR1 + HNib, MkHi(CMR1_RST)); - DELAY(2000); - /* is EPLC alive? */ - b1 = RdNib(sc, CMR1); - RdEnd(sc, CMR1); - b2 = RdNib(sc, CMR2) & 0x0f; - b2 |= RdNib(sc, CMR2 + HNib) << 4; - RdEnd(sc, CMR2 + HNib); - /* - * After the reset, we expect CMR1 & 7 to be 1 (rx buffer empty), - * and CMR2 & 0xf7 to be 0x20 (receive mode set to physical and - * broadcasts). - */ - if (bootverbose) - printf("rdp%d: CMR1 = %#x, CMR2 = %#x\n", unit, b1, b2); - - if ((b1 & (CMR1_BUFE | CMR1_IRQ | CMR1_TRA)) != CMR1_BUFE - || (b2 & ~CMR2_IRQINV) != CMR2_AM_PB) - return 0; - - /* - * We have found something that could be a RTL 80[01]2, now - * see whether we can generate an interrupt. - */ - disable_intr(); - - /* - * Test whether our configured IRQ is working. - * - * Set to no acception mode + IRQout, then enable RxE + TxE, - * then cause RBER (by advancing the read pointer although - * the read buffer is empty) to generate an interrupt. - */ - WrByte(sc, CMR2, CMR2_IRQOUT); - WrNib(sc, CMR1 + HNib, MkHi(CMR1_TE | CMR1_RE)); - WrNib(sc, CMR1, CMR1_RDPAC); - DELAY(1000); - - irqmap[0] = isa_irq_pending(); - sval[0] = inb(sc->baseaddr + lpt_status); - - /* allow IRQs to pass the parallel interface */ - outb(sc->baseaddr + lpt_control, Ctrl_IRQEN + Ctrl_SelData); - DELAY(1000); - /* generate interrupt */ - WrNib(sc, IMR + HNib, MkHi(ISR_RBER)); - DELAY(1000); - - irqmap[1] = isa_irq_pending(); - sval[1] = inb(sc->baseaddr + lpt_status); - - /* de-assert and disable IRQ */ - WrNib(sc, IMR + HNib, MkHi(0)); - (void)inb(sc->baseaddr + lpt_status); /* might be necessary to - clear IRQ */ - DELAY(1000); - irqmap[2] = isa_irq_pending(); - sval[2] = inb(sc->baseaddr + lpt_status); - - WrNib(sc, CMR1 + HNib, MkHi(0)); - outb(sc->baseaddr + lpt_control, Ctrl_SelData); - WrNib(sc, CMR2, CMR2_IRQINV); - - enable_intr(); - - if (bootverbose) - printf("rdp%d: irq maps / lpt status " - "%#x/%#x - %#x/%#x - %#x/%#x (id_irq %#x)\n", - unit, irqmap[0], sval[0], irqmap[1], sval[1], - irqmap[2], sval[2], isa_dev->id_irq); - - if ((irqmap[1] & isa_dev->id_irq) == 0) { - printf("rdp%d: configured IRQ (%d) cannot be asserted " - "by device", - unit, ffs(isa_dev->id_irq) - 1); - if (irqmap[1]) - printf(" (probable IRQ: %d)", ffs(irqmap[1]) - 1); - printf("\n"); - return 0; - } - - /* - * XXX should do RAMtest here - */ - - switch (sc->eeprom) { - case EEPROM_93C46: - if (rdp_gethwaddr_93c46(sc, sc->arpcom.ac_enaddr) == 0) { - printf("rdp%d: failed to find a valid hardware " - "address in EEPROM\n", - unit); - return 0; - } - break; - - case EEPROM_74S288: - rdp_gethwaddr_74s288(sc, sc->arpcom.ac_enaddr); - break; - } - - return lpt_control + 1; -} - -/* - * Install interface into kernel networking data structures - */ -static int -rdp_attach(struct isa_device *isa_dev) -{ - int unit = isa_dev->id_unit; - struct rdp_softc *sc = &rdp_softc[unit]; - struct ifnet *ifp = &sc->arpcom.ac_if; - - isa_dev->id_ointr = rdpintr; - - /* - * Reset interface - */ - rdp_stop(sc); - - /* - * Initialize ifnet structure - */ - ifp->if_softc = sc; - if_initname(ifp, "rdp", unit); - ifp->if_start = rdp_start; - ifp->if_ioctl = rdp_ioctl; - ifp->if_watchdog = rdp_watchdog; - ifp->if_init = rdp_init; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; - - /* - * Attach the interface - */ - ether_ifattach(ifp, sc->arpcom.ac_enaddr); - - /* - * Print additional info when attached - */ - if_printf(ifp, "RealTek RTL%s pocket ethernet, EEPROM %s, %s mode\n", - "8002", /* hook for 8012 */ - sc->eeprom == EEPROM_93C46? "93C46": "74S288", - sc->slow? "slow": "fast"); - - return 1; -} - -/* - * Reset interface. - */ -static void -rdp_reset(struct ifnet *ifp) -{ - struct rdp_softc *sc = ifp->if_softc; - int s; - - s = splimp(); - - /* - * Stop interface and re-initialize. - */ - rdp_stop(sc); - rdp_init(sc); - - (void) splx(s); -} - -/* - * Take interface offline. - */ -static void -rdp_stop(struct rdp_softc *sc) -{ - - sc->txbusy = sc->txbusy = 0; - - /* disable printer interface interrupts */ - sc->irqenbit = 0; - outb(sc->baseaddr + lpt_control, Ctrl_SelData); - outb(sc->baseaddr + lpt_data, 0xff); - - /* reset the RTL 8002 */ - WrNib(sc, CMR1 + HNib, MkHi(CMR1_RST)); - DELAY(100); -} - -/* - * Device timeout/watchdog routine. Entered if the device neglects to - * generate an interrupt after a transmit has been started on it. - */ -static void -rdp_watchdog(struct ifnet *ifp) -{ - - log(LOG_ERR, "%s: device timeout\n", ifp->if_xname); - ifp->if_oerrors++; - - rdp_reset(ifp); -} - -/* - * Initialize device. - */ -static void -rdp_init(void *xsc) -{ - struct rdp_softc *sc = xsc; - struct ifnet *ifp = &sc->arpcom.ac_if; - int i, s; - u_char reg; - - /* address not known */ - if (TAILQ_EMPTY(&ifp->if_addrhead)) - return; - - s = splimp(); - - ifp->if_timer = 0; - - /* program ethernet ID into the chip */ - for (i = 0, reg = IDR0; i < 6; i++, reg++) - WrByte(sc, reg, sc->arpcom.ac_enaddr[i]); - - /* set accept mode */ - WrNib(sc, CMR2 + HNib, - MkHi((ifp->if_flags & IFF_PROMISC)? CMR2_AM_ALL: CMR2_AM_PB)); - - /* enable tx and rx */ - WrNib(sc, CMR1 + HNib, MkHi(CMR1_TE | CMR1_RE)); - - /* allow interrupts to happen */ - WrNib(sc, CMR2, CMR2_IRQOUT | CMR2_IRQINV); - WrNib(sc, IMR, ISR_TOK | ISR_TER | ISR_ROK | ISR_RER); - WrNib(sc, IMR + HNib, MkHi(ISR_RBER)); - - /* allow IRQs to pass the parallel interface */ - sc->irqenbit = Ctrl_IRQEN; - outb(sc->baseaddr + lpt_control, sc->irqenbit + Ctrl_SelData); - - /* clear all flags */ - sc->txbusy = sc->txbuffered = 0; - - /* - * Set 'running' flag, and clear output active flag. - */ - ifp->if_flags |= IFF_RUNNING; - ifp->if_flags &= ~IFF_OACTIVE; - - /* - * ...and attempt to start output - */ - rdp_start(ifp); - - (void) splx(s); -} - -/* - * Start output on interface. - * We make two assumptions here: - * 1) that the current priority is set to splimp _before_ this code - * is called *and* is returned to the appropriate priority after - * return - * 2) that the IFF_OACTIVE flag is checked before this code is called - * (i.e. that the output part of the interface is idle) - */ -static void -rdp_start(struct ifnet *ifp) -{ - struct rdp_softc *sc = ifp->if_softc; - struct mbuf *m; - int len; - -outloop: - - /* - * See if there is room to put another packet in the buffer. - */ - if (sc->txbuffered) { - /* - * No room. Indicate this to the outside world and exit. - */ - ifp->if_flags |= IFF_OACTIVE; - return; - } - IF_DEQUEUE(&ifp->if_snd, m); - if (m == 0) { - /* - * We are using the !OACTIVE flag to indicate to the outside - * world that we can accept an additional packet rather than - * that the transmitter is _actually_ active. Indeed, the - * transmitter may be active, but if we haven't filled all the - * buffers with data then we still want to accept more. - */ - ifp->if_flags &= ~IFF_OACTIVE; - return; - } - - /* - * Copy the mbuf chain into the transmit buffer - */ - - len = rdp_write_mbufs(sc, m); - if (len == 0) - goto outloop; - - /* ensure minimal valid ethernet length */ - len = max(len, (ETHER_MIN_LEN-ETHER_CRC_LEN)); - - /* - * Actually start the transceiver. Set a timeout in case the - * Tx interrupt never arrives. - */ - if (!sc->txbusy) { - WrNib(sc, TBCR1, len >> 8); - WrByte(sc, TBCR0, len & 0xff); - WrNib(sc, CMR1, CMR1_TRA); - sc->txbusy = 1; - ifp->if_timer = 2; - } else { - sc->txbuffered = 1; - sc->txsize = len; - } - - /* - * Tap off here if there is a bpf listener. - */ - BPF_MTAP(ifp, m); - - m_freem(m); - - /* - * Loop back to the top to possibly buffer more packets - */ - goto outloop; -} - -/* - * Process an ioctl request. - */ -static int -rdp_ioctl(struct ifnet *ifp, IOCTL_CMD_T command, caddr_t data) -{ - struct rdp_softc *sc = ifp->if_softc; - int s, error = 0; - - s = splimp(); - - switch (command) { - - case SIOCSIFFLAGS: - /* - * If the interface is marked up and stopped, then start it. - * If it is marked down and running, then stop it. - */ - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_flags & IFF_RUNNING) == 0) - rdp_init(sc); - } else { - if (ifp->if_flags & IFF_RUNNING) { - rdp_stop(sc); - ifp->if_flags &= ~IFF_RUNNING; - } - } - - /* - * Promiscuous flag may have changed, propagage this - * to the NIC. - */ - if (ifp->if_flags & IFF_UP) - WrNib(sc, CMR2 + HNib, - MkHi((ifp->if_flags & IFF_PROMISC)? - CMR2_AM_ALL: CMR2_AM_PB)); - - break; - - case SIOCADDMULTI: - case SIOCDELMULTI: - /* - * Multicast list has changed; we don't support it. - */ - error = ENOTTY; - break; - - default: - error = ether_ioctl(ifp, command, data); - break; - } - (void) splx(s); - return (error); -} - -/* - * External interrupt service routine. - */ -static void -rdpintr(int unit) -{ - struct rdp_softc *sc = rdp_softc + unit; - struct ifnet *ifp = (struct ifnet *)sc; - u_char isr, tsr, rsr, colls; - - /* disable interrupts, so SD3 can be routed to the pin */ - sc->irqenbit = 0; - outb(sc->baseaddr + lpt_control, Ctrl_SelData); - WrNib(sc, CMR2, CMR2_IRQINV); - /* - * loop until there are no more new interrupts - */ - for (;;) { - isr = RdNib(sc, ISR); - isr |= RdNib(sc, ISR + HNib) << 4; - RdEnd(sc, ISR + HNib); - - if (isr == 0) - break; -#if DEBUG & 4 - printf("rdp%d: ISR = %#x\n", unit, isr); -#endif - - /* - * Clear the pending interrupt bits. - */ - WrNib(sc, ISR, isr & 0x0f); - if (isr & 0xf0) - WrNib(sc, ISR + HNib, MkHi(isr)); - - /* - * Handle transmitter interrupts. - */ - if (isr & (ISR_TOK | ISR_TER)) { - tsr = RdNib(sc, TSR); - RdEnd(sc, TSR); -#if DEBUG & 4 - if (isr & ISR_TER) - printf("rdp%d: tsr %#x\n", unit, tsr); -#endif - if (tsr & TSR_TABT) - ifp->if_oerrors++; - else - /* - * Update total number of successfully - * transmitted packets. - */ - ifp->if_opackets++; - - if (tsr & TSR_COL) { - colls = RdNib(sc, COLR); - RdEnd(sc, COLR); - ifp->if_collisions += colls; - } - - /* - * reset tx busy and output active flags - */ - sc->txbusy = 0; - ifp->if_flags &= ~IFF_OACTIVE; - - /* - * If we had already queued up another packet, - * start sending it now. - */ - if (sc->txbuffered) { - WrNib(sc, TBCR1, sc->txsize >> 8); - WrByte(sc, TBCR0, sc->txsize & 0xff); - WrNib(sc, CMR1, CMR1_TRA); - sc->txbusy = 1; - sc->txbuffered = 0; - ifp->if_timer = 2; - } else { - /* - * clear watchdog timer - */ - ifp->if_timer = 0; - } - - } - - /* - * Handle receiver interrupts - */ - if (isr & (ISR_ROK | ISR_RER | ISR_RBER)) { - rsr = RdNib(sc, RSR); - rsr |= RdNib(sc, RSR + HNib) << 4; - RdEnd(sc, RSR + HNib); -#if DEBUG & 4 - if (isr & (ISR_RER | ISR_RBER)) - printf("rdp%d: rsr %#x\n", unit, rsr); -#endif - - if (rsr & (RSR_PUN | RSR_POV)) { - printf("rdp%d: rsr %#x, resetting\n", - unit, rsr); - rdp_reset(ifp); - break; - } - - if (rsr & RSR_BUFO) - /* - * CRC and FA errors are recorded in - * rdp_rint() on a per-packet basis - */ - ifp->if_ierrors++; - if (isr & (ISR_ROK | ISR_RER)) - rdp_rint(sc); - } - - /* - * If it looks like the transmitter can take more data, - * attempt to start output on the interface. This is done - * after handling the receiver to give the receiver priority. - */ - if ((ifp->if_flags & IFF_OACTIVE) == 0) - rdp_start(ifp); - - } - /* re-enable interrupts */ - WrNib(sc, CMR2, CMR2_IRQOUT | CMR2_IRQINV); - sc->irqenbit = Ctrl_IRQEN; - outb(sc->baseaddr + lpt_control, Ctrl_SelData + sc->irqenbit); -} - -/* - * Ethernet interface receiver interrupt. - */ -static void -rdp_rint(struct rdp_softc *sc) -{ - struct ifnet *ifp = &sc->arpcom.ac_if; - struct rdphdr rh; - u_short len; - size_t i; - u_char *packet_ptr, b, status; - int excessive_bad_pkts = 0; - - /* - * Fetch the packets from the NIC's buffer. - */ - for (;;) { - b = RdNib(sc, CMR1); - RdEnd(sc, CMR1); - - if (b & CMR1_BUFE) - /* no more packets */ - break; - - /* first, obtain the buffer header */ - - outb(sc->baseaddr + lpt_data, MAR + EOC); /* prepare addr */ - outb(sc->baseaddr + lpt_control, Ctrl_LNibRead); - outb(sc->baseaddr + lpt_data, MAR + RdAddr + HNib); - - packet_ptr = (u_char *)&rh; - if (sc->slow) - for (i = 0; i < sizeof rh; i++, packet_ptr++) - *packet_ptr = RdByteA2(sc); - else - for (i = 0; i < sizeof rh; i++, packet_ptr++) - *packet_ptr = RdByteA1(sc); - - RdEnd(sc, MAR + HNib); - outb(sc->baseaddr + lpt_control, Ctrl_SelData); - - len = rh.pktlen - ETHER_CRC_LEN; - status = rh.status; - - if ((status & (RSR_ROK | RSR_CRC | RSR_FA)) != RSR_ROK || - len > (ETHER_MAX_LEN - ETHER_CRC_LEN) || - len < (ETHER_MIN_LEN - ETHER_CRC_LEN) || - len > MCLBYTES) { -#if DEBUG - if_printf(ifp, "bad packet in buffer, " - "len %d, status %#x\n", - (int)len, (int)status); -#endif - ifp->if_ierrors++; - /* rx jump packet */ - WrNib(sc, CMR1, CMR1_RDPAC); - if (++excessive_bad_pkts > 5) { - /* - * the chip seems to be stuck, we are - * probably seeing the same bad packet - * over and over again - */ -#if DEBUG - if_printf(ifp, "resetting due to an " - "excessive number of bad packets\n"); -#endif - rdp_reset(ifp); - return; - } - continue; - } - - /* - * Go get packet. - */ - excessive_bad_pkts = 0; - rdp_get_packet(sc, len); - ifp->if_ipackets++; - } -} - -/* - * Retreive packet from NIC memory and send to the next level up via - * ether_input(). - */ -static void -rdp_get_packet(struct rdp_softc *sc, unsigned len) -{ - struct ifnet *ifp = &sc->arpcom.ac_if; - struct mbuf *m; - u_char *packet_ptr; - size_t s; - - /* Allocate a header mbuf */ - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) - return; - m->m_pkthdr.rcvif = ifp; - m->m_pkthdr.len = m->m_len = len; - - /* - * We always put the received packet in a single buffer - - * either with just an mbuf header or in a cluster attached - * to the header. The +2 is to compensate for the alignment - * fixup below. - */ - if ((len + ETHER_ALIGN) > MHLEN) { - /* Attach an mbuf cluster */ - MCLGET(m, M_DONTWAIT); - - /* Insist on getting a cluster */ - if ((m->m_flags & M_EXT) == 0) { - m_freem(m); - return; - } - } - - /* - * The +2 is to longword align the start of the real packet. - * This is important for NFS. - */ - m->m_data += ETHER_ALIGN; - - /* - * Get packet, including link layer address, from interface. - */ - outb(sc->baseaddr + lpt_control, Ctrl_LNibRead); - outb(sc->baseaddr + lpt_data, RdAddr + MAR); - - packet_ptr = mtod(m, u_char *); - if (sc->slow) - for (s = 0; s < len; s++, packet_ptr++) - *packet_ptr = RdByteA2(sc); - else - for (s = 0; s < len; s++, packet_ptr++) - *packet_ptr = RdByteA1(sc); - - RdEnd(sc, MAR + HNib); - outb(sc->baseaddr + lpt_control, Ctrl_SelData); - WrNib(sc, CMR1, CMR1_RDPAC); - - (*ifp->if_input)(ifp, m); -} - -/* - * Write an mbuf chain to the NIC's tx buffer. - */ -static u_short -rdp_write_mbufs(struct rdp_softc *sc, struct mbuf *m) -{ - u_short total_len; - struct mbuf *mp; - u_char *dp, b; - int i; - - /* First, count up the total number of bytes to copy */ - for (total_len = 0, mp = m; mp; mp = mp->m_next) - total_len += mp->m_len; - - if (total_len == 0) - return 0; - - outb(sc->baseaddr + lpt_data, MAR | EOC); - - /* - * Transfer the mbuf chain to the NIC memory. - */ - if (sc->slow) { - /* writing the first byte is complicated */ - outb(sc->baseaddr + lpt_control, - Ctrl_LNibRead | sc->irqenbit); - outb(sc->baseaddr + lpt_data, MAR | WrAddr); - b = *(u_char *)m->m_data; - outb(sc->baseaddr + lpt_data, (b & 0x0f) | 0x40); - outb(sc->baseaddr + lpt_data, b & 0x0f); - outb(sc->baseaddr + lpt_data, b >> 4); - outb(sc->baseaddr + lpt_control, - Ctrl_HNibRead | sc->irqenbit); - /* advance the mbuf pointer */ - mp = m; - m->m_len--; - m->m_data++; - /* write the remaining bytes */ - while (m) { - for (i = 0, dp = (u_char *)m->m_data; - i < m->m_len; - i++, dp++) - WrByteALToDRAMA(sc, *dp); - m = m->m_next; - } - /* - * restore old mbuf in case we have to hand it off to - * BPF again - */ - m = mp; - m->m_len++; - m->m_data--; - - /* the RTL 8002 requires an even byte-count remote DMA */ - if (total_len & 1) - WrByteALToDRAMA(sc, 0); - } else { - outb(sc->baseaddr + lpt_data, MAR | WrAddr); - while (m) { - for (i = 0, dp = (u_char *)m->m_data; - i < m->m_len; - i++, dp++) - WrByteALToDRAM(sc, *dp); - m = m->m_next; - } - - /* the RTL 8002 requires an even byte-count remote DMA */ - if (total_len & 1) - WrByteALToDRAM(sc, 0); - } - - outb(sc->baseaddr + lpt_data, 0xff); - outb(sc->baseaddr + lpt_control, - Ctrl_HNibRead | Ctrl_SelData | sc->irqenbit); - - return total_len; -} - -/* - * Read the designated ethernet hardware address out of a 93C46 - * (serial) EEPROM. - * Note that the 93C46 uses 16-bit words in big-endian notation. - */ -static int -rdp_gethwaddr_93c46(struct rdp_softc *sc, u_char *etheraddr) -{ - int i, magic; - size_t j = 0; - u_short w; - - WrNib(sc, CMR2, CMR2_PAGE | CMR2_IRQINV); /* select page 1 */ - - /* - * The original RealTek packet driver had the ethernet address - * starting at EEPROM address 0. Other vendors seem to have - * gone `creative' here -- while they didn't do anything else - * than changing a few strings in the entire driver, compared - * to the RealTek version, they also moved out the ethernet - * address to a different location in the EEPROM, so the - * original RealTek driver won't work correctly with them, and - * vice versa. Sounds pretty cool, eh? $@%&! - * - * Anyway, we walk through the EEPROM, until we find some - * allowable value based upon our table of IEEE OUI assignments. - */ - for (i = magic = 0; magic < 3 && i < 32; i++) { - /* read cmd (+ 6 bit address) */ - rdp_93c46_cmd(sc, 0x180 + i, 10); - w = rdp_93c46_read(sc); - switch (magic) { - case 0: - for (j = 0; - j < sizeof allowed_ouis / sizeof(u_short); - j++) - if (w == allowed_ouis[j]) { - etheraddr[0] = (w >> 8) & 0xff; - etheraddr[1] = w & 0xff; - magic++; - break; - } - break; - - case 1: - /* - * If the first two bytes have been 00:00, we - * discard the match iff the next two bytes - * are also 00:00, so we won't get fooled by - * an EEPROM that has been filled with zeros. - * This in theory would disallow 64 K of legal - * addresses assigned to Xerox, but it's - * almost certain that those addresses haven't - * been used for RTL80[01]2 chips anyway. - */ - if ((etheraddr[0] | etheraddr[1]) == 0 && w == 0) { - magic--; - break; - } - - etheraddr[2] = (w >> 8) & 0xff; - etheraddr[3] = w & 0xff; - magic++; - break; - - case 2: - etheraddr[4] = (w >> 8) & 0xff; - etheraddr[5] = w & 0xff; - magic++; - break; - } - } - - WrNib(sc, CMR2, CMR2_IRQINV); /* back to page 0 */ - - return magic == 3; -} - -/* - * Read the designated ethernet hardware address out of a 74S288 - * EEPROM. - * - * This is untested, since i haven't seen any adapter actually using - * a 74S288. In the RTL 8012, only the serial EEPROM (94C46) is - * supported anymore. - */ -static void -rdp_gethwaddr_74s288(struct rdp_softc *sc, u_char *etheraddr) -{ - int i; - u_char b; - - WrNib(sc, CMR2, CMR2_PAGE | CMR2_IRQINV); /* select page 1 */ - - for (i = 0; i < 6; i++) { - WrNib(sc, PCMR, i & 0x0f); /* lower 4 bit of addr */ - WrNib(sc, PCMR + HNib, HNib + 4); /* upper 2 bit addr + /CS */ - WrNib(sc, PCMR + HNib, HNib); /* latch data now */ - b = RdNib(sc, PDR) & 0x0f; - b |= (RdNib(sc, PDR + HNib) & 0x0f) << 4; - etheraddr[i] = b; - } - - RdEnd(sc, PDR + HNib); - WrNib(sc, CMR2, CMR2_IRQINV); /* reselect page 0 */ -} - -/* - * Send nbits of data (starting with MSB) out to the 93c46 as a - * command. Assumes register page 1 has already been selected. - */ -static void -rdp_93c46_cmd(struct rdp_softc *sc, u_short data, unsigned nbits) -{ - u_short mask = 1 << (nbits - 1); - unsigned i; - u_char b; - -#if DEBUG & 2 - printf("rdp_93c46_cmd(): "); -#endif - for (i = 0; i < nbits; i++, mask >>= 1) { - b = HNib + PCMR_SK + PCMR_CS; - if (data & mask) - b += PCMR_DO; -#if DEBUG & 2 - printf("%d", b & 1); -#endif - WrNib(sc, PCMR + HNib, b); - DELAY(1); - WrNib(sc, PCMR + HNib, b & ~PCMR_SK); - DELAY(1); - } -#if DEBUG & 2 - printf("\n"); -#endif -} - -/* - * Read one word of data from the 93c46. Actually, we have to read - * 17 bits, and discard the very first bit. Assumes register page 1 - * to be selected as well. - */ -static u_short -rdp_93c46_read(struct rdp_softc *sc) -{ - u_short data = 0; - u_char b; - int i; - -#if DEBUG & 2 - printf("rdp_93c46_read(): "); -#endif - for (i = 0; i < 17; i++) { - WrNib(sc, PCMR + HNib, PCMR_SK + PCMR_CS + HNib); - DELAY(1); - WrNib(sc, PCMR + HNib, PCMR_CS + HNib); - DELAY(1); - b = RdNib(sc, PDR); - data <<= 1; - if (b & 1) - data |= 1; -#if DEBUG & 2 - printf("%d", b & 1); -#endif - RdEnd(sc, PDR); - DELAY(1); - } - -#if DEBUG & 2 - printf("\n"); -#endif - /* end of cycle */ - WrNib(sc, PCMR + HNib, PCMR_SK + HNib); - DELAY(1); - - return data; -} diff --git a/sys/i386/isa/if_rdpreg.h b/sys/i386/isa/if_rdpreg.h deleted file mode 100644 index ee56e82e4963..000000000000 --- a/sys/i386/isa/if_rdpreg.h +++ /dev/null @@ -1,187 +0,0 @@ -#ifndef IF_RDPREG_H -#define IF_RDPREG_H 1 -/* - * Copyright (c) 1998 Joerg Wunsch - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * Part of the definitions here has been copied over from the REDP - * packet driver's REDPPD.INC file. This provides us with the same - * set of acronyms as the packet driver is using. - * - * The packet driver had no copyright, and is believed to be in the - * public domain. The author seems to be someone who calls himself - * "Chiu", so that's the only acknowledgment i can give here. - * Supposedly the author was someone from RealTek. - */ - -/* - * We're hanging upon an LPT port, thus suck in the lpt defs as well. - */ -#include - -struct rdphdr { - /* RTL8002 header that is prepended to the actual packet */ - u_char unused2[2]; - u_short pktlen; - u_char status; /* copy of RSR for this packet */ - u_char unused3[3]; -}; - -/* - * - * 8 Data Modes are provided: - * - * +--------+---------------+-------------+ - * | Mode | Read | Write | - * +--------+---------------+-------------+ - * | 0 | LptCtrl | LptData | - * +--------+---------------+-------------+ - * | 1 | LptCtrl | LptCtrl | - * +--------+---------------+-------------+ - * | 2 | LptCtrl*2 | LptData | - * +--------+---------------+-------------+ - * | 3 | LptCtrl*2 | LptCtrl | - * +--------+---------------+-------------+ - * | 4 | LptData | LptData | - * +--------+---------------+-------------+ - * | 5 | LptData | LptCtrl | - * +--------+---------------+-------------+ - * | 6 | LptData*2 | LptData | - * +--------+---------------+-------------+ - * | 7 | LptData*2 | LptCtrl | - * +--------+---------------+-------------+ - * - * Right now, this driver only implements mode 0 (which ought to work - * on any standard parallel interface). - * - */ - -/* - * Page 0 of EPLC registers - */ -#define IDR0 0x00 /* Ethernet ID register (R/W) */ -#define IDR1 0x01 -#define IDR2 0x02 -#define IDR3 0x03 -#define IDR4 0x04 -#define IDR5 0x05 -#define TBCR0 0x06 /* transmit byte count (W), 11 bits valid */ -#define TBCR1 0x07 -#define TSR 0x08 /* transmit status (R), cleared upon next tx */ -# define TSR_TOK 1 /* transmit OK */ -# define TSR_TABT 2 /* transmit aborted (excessive collisions) */ -# define TSR_COL 4 /* collision detected */ -# define TSR_CDH 8 /* CD heartbeat detected */ -#define RSR 0x09 /* - * receiver status (R), cleared upon next - * received packet (but stored in rx buffer - * header anyway) - */ -# define RSR_ROK 1 /* receive OK */ -# define RSR_CRC 2 /* CRC error */ -# define RSR_FA 4 /* frame alignment error (not multiple of 8) */ -# define RSR_BUFO 0x10 /* rx buffer overflow, packet discarded */ -# define RSR_PUN 0x20 /* packet count underflow (jump command issued - * but rx buffer was empty) */ -# define RSR_POV 0x40 /* packet count overflow (more than 254 (?) - * packets still in buffer) */ -#define ISR 0x0A /* interrupt status register (R), writing - * clears the written bits */ -# define ISR_TOK 1 /* transmission OK (~ TSR_TOK) */ -# define ISR_TER 2 /* transmitter error (~ TSR_TABT) */ -# define ISR_ROK 4 /* receive OK (~ RSR_ROK) */ -# define ISR_RER 8 /* receiver error (~ RSR_CRC|RSR_FA) */ -# define ISR_RBER 0x10 /* rx buffer overflow (POV|PUN|BUFO) */ -#define IMR 0x0B /* interrupt mask register (R/W), bit as ISR */ -#define CMR1 0x0C /* command register 1 (R/W) */ -# define CMR1_BUFE 1 /* (R) rx buffer empty */ -# define CMR1_IRQ 2 /* (R) interrupt request */ -# define CMR1_TRA 4 /* (R) transmission in progress */ - /* (W) transmit start */ -# define CMR1_TE 0x10 /* (R/W) transmitter enable */ -# define CMR1_RE 0x20 /* (R/W) receiver enable */ -# define CMR1_RST 0x40 /* (R/W) reset; sticks until reset completed */ -# define CMR1_RDPAC 1 /* (W) `rx jump packet', prepare for reading - * next packet from ring buffer */ -# define CMR1_WRPAC 2 /* (W) `tx jump packet', packet in tx buffer - * is complete and can be sent */ -# define CMR1_RETX 8 /* (W) retransmit (must be accomp'ed by TRA) */ -# define CMR1_MUX 0x80 /* (W) RTL8012: tell the printer MUX to - * connect the output pins to the host */ -#define CMR2 0x0D /* command register 2 (R/W) */ -# define CMR2_IRQOUT 1 /* interrupt signal output enabled */ -# define CMR2_RAMTST 2 /* enable RAM test */ -# define CMR2_PAGE 4 /* select register page #1 */ -# define CMR2_IRQINV 8 /* make active IRQ `low' */ -# define CMR2_AMbits 0x30 /* address mode bits: */ -# define CMR2_AM_NONE 0x00 /* 0: accept nothing */ -# define CMR2_AM_PHYS 0x10 /* 1: only physical addr */ -# define CMR2_AM_PB 0x20 /* 2: phys + broadcast */ -# define CMR2_AM_ALL 0x30 /* 3: promiscuous */ -# define CMR2_LBK 0x40 /* enable loopback */ -# define CMR2_SER 0x80 /* save error packet */ -#define MAR 0x0E /* memory access register (?), used for - * remote DMA to the 8002's buffer */ -#define PNR TBCR0 /* received packet number (R) */ -#define COLR TBCR1 /* collision count (R) (4 bit valid) */ - -/* - * Page 1 of EPLC registers -- EEPROM control - */ -#define PCMR TBCR0 /* port command register */ -/* bits for 93C46 control -- add HNib */ -#define PCMR_SK 0x04 /* serial clock for EEPROM */ -#define PCMR_CS 0x02 /* chip select for EEPROM */ -#define PCMR_DO 0x01 /* DI to EEPROM */ - -/* EEPROM data, nibbles for 74S288, bits for 93C46 */ -#define PDR TBCR1 /* DO from EEPROM, only bit 0 valid for - * serial EEPROM */ - -/* - * The following definitionss define remote DMA command through LptCtrl - */ -#define ATFD 3 /* ATFD bit in Lpt's Control register */ - /* -> ATFD bit is added for Xircom's MUX */ -#define Ctrl_LNibRead (0x08+ATFD) /* specify low nibble */ -#define Ctrl_HNibRead (0+ATFD) /* specify high nibble */ -#define Ctrl_SelData (0x04+ATFD) /* not through LptCtrl but through */ - /* LptData */ -#define Ctrl_IRQEN 0x10 /* set IRQEN of lpt control register */ - -/* Here define constants to construct the required read/write commands */ -#define WrAddr 0x40 /* set address of EPLC write register */ -#define RdAddr 0x0C0 /* set address of EPLC read register */ -#define EOR 0x20 /* ORed to make 'end of read',set CSB=1 */ -#define EOW 0x0E0 /* end of write, R/WB=A/DB=CSB=1 */ -#define EOC 0x0E0 /* End Of r/w Command, R/WB=A/DB=CSB=1 */ -#define HNib 0x10 - -#define MkHi(value) (((value) >> 4) | HNib) - -#endif /* IF_RDPREG_H */