2 * Copyright 1998, Joerg Wunsch
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * $FreeBSD: src/sys/i386/isa/if_rdp.c,v 1.6.2.2 2000/07/17 21:24:32 archie Exp $
28 * $DragonFly: src/sys/dev/netif/rdp/if_rdp.c,v 1.21 2005/11/28 17:13:43 dillon Exp $
32 * Device driver for RealTek RTL 8002 (`REDP') based pocket-ethernet
33 * adapters, hooked up to a printer port. `rdp' is a shorthand for
34 * REDP since some tools like netstat work best if the interface name
35 * has no more than three letters.
37 * Driver configuration flags so far:
38 * flags 0x1 -- assume 74S288 EEPROM (default 94C46)
39 * flags 0x2 -- use `slow' mode (mode 3 of the packet driver, default 0)
41 * Maybe this driver will some day also work with the successor, RTL
42 * 8012 (`AREDP'), which is unfortunately not fully register-
43 * compatible with the 8002. The 8012 offers support for faster
44 * transfer modi like bidirectional SPP and EPP, 64 K x 4 buffer
45 * memory as opposed to 16 K x 4 for the 8002, a multicast filter, and
46 * a builtin multiplexer that allows chaining a printer behind the
49 * About the only documentation i've been able to find about the RTL
50 * 8002 was the packet driver source code at ftp.realtek.com.tw, so
51 * this driver is somewhat based on the way the packet driver handles
52 * the chip. The exact author of the packet driver is unknown, the
53 * only name that i could find in the source was someone called Chiu,
54 * supposedly an employee of RealTek. So credits to them for that
55 * piece of code which has proven valuable to me.
57 * Later on, Leo kuo <leo@realtek.com.tw> has been very helpful to me
58 * by sending me a readable (PDF) file documenting the RTL 8012, which
59 * helped me to also understand the 8002, as well as by providing me
60 * with the source code of the 8012 packet driver that i haven't been
61 * able to find on the FTP site. A big Thanks! goes here to RealTek
62 * for this kind of service.
67 #include <sys/param.h>
68 #include <sys/systm.h>
70 #include <sys/sockio.h>
71 #include <sys/malloc.h>
73 #include <sys/socket.h>
74 #include <sys/syslog.h>
75 #include <sys/linker_set.h>
76 #include <sys/module.h>
78 #include <sys/serialize.h>
79 #include <sys/thread2.h>
81 #include <net/ethernet.h>
83 #include <net/ifq_var.h>
84 #include <net/if_arp.h>
85 #include <net/if_dl.h>
86 #include <net/if_mib.h>
89 #include <netinet/in.h>
90 #include <netinet/if_ether.h>
95 #include <netns/ns_if.h>
100 #include <machine/clock.h>
101 #include <machine/md_var.h>
103 #include <bus/isa/isavar.h>
104 #include <bus/isa/i386/isa_device.h>
105 #include <i386/icu/icu.h>
106 #include "if_rdpreg.h"
107 #include <i386/isa/intr_machdep.h>
109 #define IOCTL_CMD_T u_long
112 * Debug levels (ORed together):
113 * != 0 - general (bad packets etc.)
114 * 2 - debug EEPROM IO
115 * 4 - debug interrupt status
121 * rdp_softc: per interface info and status
124 struct arpcom arpcom; /*
125 * Ethernet common, always goes first so
126 * a rdp_softc * can be cast into an
127 * arpcom * or into an ifnet *.
131 * local stuff, somewhat sorted by memory alignment class
133 u_short baseaddr; /* IO port address */
134 u_short txsize; /* tx size for next (buffered) packet,
135 * there's only one additional packet
136 * we can buffer, thus a single variable
137 * ought to be enough */
138 int txbusy; /* tx is transmitting */
139 int txbuffered; /* # of packets in tx buffer */
140 int slow; /* use lpt_control to send data */
141 u_char irqenbit; /* mirror of current Ctrl_IRQEN */
143 * type of parameter EEPROM; device flags 0x1 selects 74S288
146 EEPROM_93C46, EEPROM_74S288 /* or 82S123 */
150 DECLARE_DUMMY_MODULE(if_rdp);
152 static struct rdp_softc rdp_softc[NRDP];
155 * Since there's no fixed location in the EEPROM about where to find
156 * the ethernet hardware address, we drop a table of valid OUIs here,
157 * and search through the EEPROM until we find a possible valid
158 * Ethernet address. Only the first 16 bits of all possible OUIs are
159 * recorded in the table (as obtained from
160 * http://standards.ieee.org/regauth/oui/oui.txt).
163 static u_short allowed_ouis[] = {
164 0x0000, 0x0001, 0x0002, 0x0004, 0x0005, 0x0006, 0x0007,
165 0x0008, 0x0010, 0x001C, 0x0020, 0x0040, 0x0050, 0x0060,
166 0x0070, 0x0080, 0x0090, 0x009D, 0x00A0, 0x00AA, 0x00BB,
167 0x00C0, 0x00CF, 0x00DD, 0x00E0, 0x00E6, 0x0207, 0x021C,
168 0x0260, 0x0270, 0x029D, 0x02AA, 0x02BB, 0x02C0, 0x02CF,
169 0x02E6, 0x040A, 0x04E0, 0x0800, 0x08BB, 0x1000, 0x1100,
176 static int rdp_probe (struct isa_device *);
177 static int rdp_attach (struct isa_device *);
180 * Required entry points.
182 static void rdp_init(void *);
183 static int rdp_ioctl(struct ifnet *, IOCTL_CMD_T, caddr_t, struct ucred *);
184 static void rdp_start(struct ifnet *);
185 static void rdp_reset(struct ifnet *);
186 static void rdp_watchdog(struct ifnet *);
187 static void rdpintr(void *);
190 * REDP private functions.
193 static void rdp_stop(struct rdp_softc *);
194 static void rdp_rint(struct rdp_softc *);
195 static void rdp_get_packet(struct rdp_softc *, unsigned);
196 static u_short rdp_write_mbufs(struct rdp_softc *, struct mbuf *);
197 static int rdp_gethwaddr_93c46(struct rdp_softc *, u_char *);
198 static void rdp_gethwaddr_74s288(struct rdp_softc *, u_char *);
199 static void rdp_93c46_cmd(struct rdp_softc *, u_short, unsigned);
200 static u_short rdp_93c46_read(struct rdp_softc *);
202 struct isa_driver rdpdriver = {
206 1 /* we wanna get a chance before lptN */
210 * REDP-specific functions.
212 * They are inlined, thus go first in this file. Together with gcc's
213 * usual optimization, these functions probably come close to the
214 * packet driver's hand-optimized code. ;-)
216 * Comments are partially obtained from the packet driver as well.
217 * Some of the function names contain register names which don't make
218 * much sense for us, but i've kept them for easier reference in
219 * comparision to the packet driver.
221 * Some of the functions are currently not used by the driver; it's
222 * not quite clear whether we ever need them at all. They are
223 * supposedly even slower than what is currently implemented as `slow'
224 * mode. Right now, `fast' (default) mode is what the packet driver
225 * calls mode 0, slow mode is mode 3 (writing through lpt_control,
228 * We should autoprobe the modi, as opposed to making them dependent
229 * on a kernel configuration flag.
233 * read a nibble from rreg; end-of-data cmd is not issued;
234 * used for general register read.
236 * Unlike the packet driver's version, i'm shifting the result
237 * by 3 here (as opposed to within the caller's code) for clarity.
240 static __inline u_char
241 RdNib(struct rdp_softc *sc, u_char rreg)
244 outb(sc->baseaddr + lpt_data, EOC + rreg);
245 outb(sc->baseaddr + lpt_data, RdAddr + rreg); /* write addr */
246 (void)inb(sc->baseaddr + lpt_status);
247 return (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
252 * read a byte from MAR register through lpt_data; the low nibble is
253 * read prior to the high one; end-of-read command is not issued; used
254 * for remote DMA in mode 4 + 5
256 static __inline u_char
257 RdByte(struct rdp_softc *sc)
261 outb(sc->baseaddr + lpt_data, RdAddr + MAR); /* cmd for low nibble */
262 lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
263 outb(sc->baseaddr + lpt_data, RdAddr + MAR + HNib);
264 hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0;
265 return hinib + lonib;
270 * read a byte from MAR register through lpt_data; the low nibble is
271 * read prior to the high one; end-of-read command is not issued; used
272 * for remote DMA in mode 6 + 7
274 static __inline u_char
275 RdByte1(struct rdp_softc *sc)
279 outb(sc->baseaddr + lpt_data, RdAddr + MAR); /* cmd for low nibble */
280 (void)inb(sc->baseaddr + lpt_status);
281 lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
282 outb(sc->baseaddr + lpt_data, RdAddr + MAR + HNib);
283 (void)inb(sc->baseaddr + lpt_status);
284 hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0;
285 return hinib + lonib;
291 * read a byte from MAR register through lpt_control; the low nibble is
292 * read prior to the high one; end-of-read command is not issued; used
293 * for remote DMA in mode 0 + 1
295 static __inline u_char
296 RdByteA1(struct rdp_softc *sc)
300 outb(sc->baseaddr + lpt_control, Ctrl_LNibRead);
301 lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
302 outb(sc->baseaddr + lpt_control, Ctrl_HNibRead);
303 hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0;
304 return hinib + lonib;
309 * read a byte from MAR register through lpt_control; the low nibble is
310 * read prior to the high one; end-of-read command is not issued; used
311 * for remote DMA in mode 2 + 3
313 static __inline u_char
314 RdByteA2(struct rdp_softc *sc)
318 outb(sc->baseaddr + lpt_control, Ctrl_LNibRead);
319 (void)inb(sc->baseaddr + lpt_status);
320 lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
321 outb(sc->baseaddr + lpt_control, Ctrl_HNibRead);
322 (void)inb(sc->baseaddr + lpt_status);
323 hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0;
324 return hinib + lonib;
331 RdEnd(struct rdp_softc *sc, u_char rreg)
334 outb(sc->baseaddr + lpt_data, EOC + rreg);
338 * Write a nibble to a register; end-of-write is issued.
339 * Used for general register write.
342 WrNib(struct rdp_softc *sc, u_char wreg, u_char wdata)
345 /* prepare and write address */
346 outb(sc->baseaddr + lpt_data, EOC + wreg);
347 outb(sc->baseaddr + lpt_data, WrAddr + wreg);
348 outb(sc->baseaddr + lpt_data, WrAddr + wreg);
349 /* prepare and write data */
350 outb(sc->baseaddr + lpt_data, WrAddr + wdata);
351 outb(sc->baseaddr + lpt_data, wdata);
352 outb(sc->baseaddr + lpt_data, wdata);
354 outb(sc->baseaddr + lpt_data, EOC + wdata);
358 * Write a byte to a register; end-of-write is issued.
359 * Used for general register write.
362 WrByte(struct rdp_softc *sc, u_char wreg, u_char wdata)
365 /* prepare and write address */
366 outb(sc->baseaddr + lpt_data, EOC + wreg);
367 outb(sc->baseaddr + lpt_data, WrAddr + wreg);
368 outb(sc->baseaddr + lpt_data, WrAddr + wreg);
369 /* prepare and write low nibble */
370 outb(sc->baseaddr + lpt_data, WrAddr + (wdata & 0x0F));
371 outb(sc->baseaddr + lpt_data, (wdata & 0x0F));
372 outb(sc->baseaddr + lpt_data, (wdata & 0x0F));
373 /* prepare and write high nibble */
375 outb(sc->baseaddr + lpt_data, wdata);
376 outb(sc->baseaddr + lpt_data, wdata + HNib);
377 outb(sc->baseaddr + lpt_data, wdata + HNib);
379 outb(sc->baseaddr + lpt_data, EOC + wdata + HNib);
383 * Write the byte to DRAM via lpt_data;
384 * used for remote DMA write in mode 0 / 2 / 4
387 WrByteALToDRAM(struct rdp_softc *sc, u_char val)
390 outb(sc->baseaddr + lpt_data, val & 0x0F);
391 outb(sc->baseaddr + lpt_data, MkHi(val));
395 * Write the byte to DRAM via lpt_control;
396 * used for remote DMA write in mode 1 / 3 / 5
399 WrByteALToDRAMA(struct rdp_softc *sc, u_char val)
402 outb(sc->baseaddr + lpt_data, val & 0x0F);
403 outb(sc->baseaddr + lpt_control, Ctrl_LNibRead | sc->irqenbit);
404 outb(sc->baseaddr + lpt_data, val >> 4);
405 outb(sc->baseaddr + lpt_control, Ctrl_HNibRead | sc->irqenbit);
408 #if 0 /* they could be used for the RAM test */
410 * Write the u_short to DRAM via lpt_data;
411 * used for remote DMA write in mode 0 / 2 / 4
414 WrWordbxToDRAM(struct rdp_softc *sc, u_short val)
417 outb(sc->baseaddr + lpt_data, val & 0x0F);
419 outb(sc->baseaddr + lpt_data, (val & 0x0F) + HNib);
421 outb(sc->baseaddr + lpt_data, val & 0x0F);
423 outb(sc->baseaddr + lpt_data, val + HNib);
428 * Write the u_short to DRAM via lpt_control;
429 * used for remote DMA write in mode 1 / 3 / 5
432 WrWordbxToDRAMA(struct rdp_softc *sc, u_short val)
435 outb(sc->baseaddr + lpt_data, val & 0x0F);
436 outb(sc->baseaddr + lpt_control, Ctrl_LNibRead | sc->irqenbit);
438 outb(sc->baseaddr + lpt_data, (val & 0x0F) + HNib);
439 outb(sc->baseaddr + lpt_control, Ctrl_HNibRead | sc->irqenbit);
441 outb(sc->baseaddr + lpt_data, val & 0x0F);
442 outb(sc->baseaddr + lpt_control, Ctrl_LNibRead | sc->irqenbit);
444 outb(sc->baseaddr + lpt_data, val + HNib);
445 outb(sc->baseaddr + lpt_control, Ctrl_HNibRead | sc->irqenbit);
451 * Determine if the device is present
454 * a pointer to an isa_device struct
456 * 0 if device not found
457 * or # of i/o addresses used (if found)
460 rdp_probe(struct isa_device *isa_dev)
462 int unit = isa_dev->id_unit;
463 struct rdp_softc *sc = &rdp_softc[unit];
465 intrmask_t irqmap[3];
468 if (unit < 0 || unit >= NRDP)
471 sc->baseaddr = isa_dev->id_iobase;
472 if (isa_dev->id_flags & 1)
473 sc->eeprom = EEPROM_74S288;
474 /* else defaults to 93C46 */
475 if (isa_dev->id_flags & 2)
478 /* let R/WB = A/DB = CSB = high to be ready for next r/w cycle */
479 outb(sc->baseaddr + lpt_data, 0xFF);
480 /* DIR = 0 for write mode, IRQEN=0, SLCT=INIT=AUTOFEED=STB=high */
481 outb(sc->baseaddr + lpt_control, Ctrl_SelData);
483 WrNib(sc, CMR1 + HNib, MkHi(CMR1_RST));
486 b1 = RdNib(sc, CMR1);
488 b2 = RdNib(sc, CMR2) & 0x0f;
489 b2 |= RdNib(sc, CMR2 + HNib) << 4;
490 RdEnd(sc, CMR2 + HNib);
492 * After the reset, we expect CMR1 & 7 to be 1 (rx buffer empty),
493 * and CMR2 & 0xf7 to be 0x20 (receive mode set to physical and
497 printf("rdp%d: CMR1 = %#x, CMR2 = %#x\n", unit, b1, b2);
499 if ((b1 & (CMR1_BUFE | CMR1_IRQ | CMR1_TRA)) != CMR1_BUFE
500 || (b2 & ~CMR2_IRQINV) != CMR2_AM_PB)
504 * We have found something that could be a RTL 80[01]2, now
505 * see whether we can generate an interrupt.
510 * Test whether our configured IRQ is working.
512 * Set to no acception mode + IRQout, then enable RxE + TxE,
513 * then cause RBER (by advancing the read pointer although
514 * the read buffer is empty) to generate an interrupt.
516 WrByte(sc, CMR2, CMR2_IRQOUT);
517 WrNib(sc, CMR1 + HNib, MkHi(CMR1_TE | CMR1_RE));
518 WrNib(sc, CMR1, CMR1_RDPAC);
521 irqmap[0] = isa_irq_pending();
522 sval[0] = inb(sc->baseaddr + lpt_status);
524 /* allow IRQs to pass the parallel interface */
525 outb(sc->baseaddr + lpt_control, Ctrl_IRQEN + Ctrl_SelData);
527 /* generate interrupt */
528 WrNib(sc, IMR + HNib, MkHi(ISR_RBER));
531 irqmap[1] = isa_irq_pending();
532 sval[1] = inb(sc->baseaddr + lpt_status);
534 /* de-assert and disable IRQ */
535 WrNib(sc, IMR + HNib, MkHi(0));
536 (void)inb(sc->baseaddr + lpt_status); /* might be necessary to
539 irqmap[2] = isa_irq_pending();
540 sval[2] = inb(sc->baseaddr + lpt_status);
542 WrNib(sc, CMR1 + HNib, MkHi(0));
543 outb(sc->baseaddr + lpt_control, Ctrl_SelData);
544 WrNib(sc, CMR2, CMR2_IRQINV);
549 printf("rdp%d: irq maps / lpt status "
550 "%#x/%#x - %#x/%#x - %#x/%#x (id_irq %#x)\n",
551 unit, irqmap[0], sval[0], irqmap[1], sval[1],
552 irqmap[2], sval[2], isa_dev->id_irq);
554 if ((irqmap[1] & isa_dev->id_irq) == 0) {
555 printf("rdp%d: configured IRQ (%d) cannot be asserted "
557 unit, ffs(isa_dev->id_irq) - 1);
559 printf(" (probable IRQ: %d)", ffs(irqmap[1]) - 1);
565 * XXX should do RAMtest here
568 switch (sc->eeprom) {
570 if (rdp_gethwaddr_93c46(sc, sc->arpcom.ac_enaddr) == 0) {
571 printf("rdp%d: failed to find a valid hardware "
572 "address in EEPROM\n",
579 rdp_gethwaddr_74s288(sc, sc->arpcom.ac_enaddr);
583 return lpt_control + 1;
587 * Install interface into kernel networking data structures
590 rdp_attach(struct isa_device *isa_dev)
592 int unit = isa_dev->id_unit;
593 struct rdp_softc *sc = &rdp_softc[unit];
594 struct ifnet *ifp = &sc->arpcom.ac_if;
596 isa_dev->id_intr = (inthand2_t *)rdpintr;
604 * Initialize ifnet structure
607 if_initname(ifp, "rdp", unit);
608 ifp->if_start = rdp_start;
609 ifp->if_ioctl = rdp_ioctl;
610 ifp->if_watchdog = rdp_watchdog;
611 ifp->if_init = rdp_init;
612 ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
613 ifq_set_ready(&ifp->if_snd);
614 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
617 * Attach the interface
619 ether_ifattach(ifp, sc->arpcom.ac_enaddr, NULL);
622 * Print additional info when attached
624 printf("%s: RealTek RTL%s pocket ethernet, EEPROM %s, %s mode\n",
626 "8002", /* hook for 8012 */
627 sc->eeprom == EEPROM_93C46? "93C46": "74S288",
628 sc->slow? "slow": "fast");
637 rdp_reset(struct ifnet *ifp)
639 struct rdp_softc *sc = ifp->if_softc;
644 * Stop interface and re-initialize.
653 * Take interface offline.
656 rdp_stop(struct rdp_softc *sc)
659 sc->txbusy = sc->txbusy = 0;
661 /* disable printer interface interrupts */
663 outb(sc->baseaddr + lpt_control, Ctrl_SelData);
664 outb(sc->baseaddr + lpt_data, 0xff);
666 /* reset the RTL 8002 */
667 WrNib(sc, CMR1 + HNib, MkHi(CMR1_RST));
672 * Device timeout/watchdog routine. Entered if the device neglects to
673 * generate an interrupt after a transmit has been started on it.
676 rdp_watchdog(struct ifnet *ifp)
679 log(LOG_ERR, "%s: device timeout\n", ifp->if_xname);
691 struct rdp_softc *sc = xsc;
692 struct ifnet *ifp = &sc->arpcom.ac_if;
700 /* program ethernet ID into the chip */
701 for (i = 0, reg = IDR0; i < 6; i++, reg++)
702 WrByte(sc, reg, sc->arpcom.ac_enaddr[i]);
704 /* set accept mode */
705 WrNib(sc, CMR2 + HNib,
706 MkHi((ifp->if_flags & IFF_PROMISC)? CMR2_AM_ALL: CMR2_AM_PB));
708 /* enable tx and rx */
709 WrNib(sc, CMR1 + HNib, MkHi(CMR1_TE | CMR1_RE));
711 /* allow interrupts to happen */
712 WrNib(sc, CMR2, CMR2_IRQOUT | CMR2_IRQINV);
713 WrNib(sc, IMR, ISR_TOK | ISR_TER | ISR_ROK | ISR_RER);
714 WrNib(sc, IMR + HNib, MkHi(ISR_RBER));
716 /* allow IRQs to pass the parallel interface */
717 sc->irqenbit = Ctrl_IRQEN;
718 outb(sc->baseaddr + lpt_control, sc->irqenbit + Ctrl_SelData);
720 /* clear all flags */
721 sc->txbusy = sc->txbuffered = 0;
724 * Set 'running' flag, and clear output active flag.
726 ifp->if_flags |= IFF_RUNNING;
727 ifp->if_flags &= ~IFF_OACTIVE;
730 * ...and attempt to start output
738 * Start output on interface.
739 * We make one assumption here:
740 * - that the IFF_OACTIVE flag is checked before this code is called
741 * (i.e. that the output part of the interface is idle)
744 rdp_start(struct ifnet *ifp)
746 struct rdp_softc *sc = ifp->if_softc;
753 * See if there is room to put another packet in the buffer.
755 if (sc->txbuffered) {
757 * No room. Indicate this to the outside world and exit.
759 ifp->if_flags |= IFF_OACTIVE;
762 m = ifq_dequeue(&ifp->if_snd, NULL);
765 * We are using the !OACTIVE flag to indicate to the outside
766 * world that we can accept an additional packet rather than
767 * that the transmitter is _actually_ active. Indeed, the
768 * transmitter may be active, but if we haven't filled all the
769 * buffers with data then we still want to accept more.
771 ifp->if_flags &= ~IFF_OACTIVE;
776 * Copy the mbuf chain into the transmit buffer
779 len = rdp_write_mbufs(sc, m);
783 /* ensure minimal valid ethernet length */
784 len = max(len, (ETHER_MIN_LEN-ETHER_CRC_LEN));
787 * Actually start the transceiver. Set a timeout in case the
788 * Tx interrupt never arrives.
791 WrNib(sc, TBCR1, len >> 8);
792 WrByte(sc, TBCR0, len & 0xff);
793 WrNib(sc, CMR1, CMR1_TRA);
806 * Loop back to the top to possibly buffer more packets
812 * Process an ioctl request.
815 rdp_ioctl(struct ifnet *ifp, IOCTL_CMD_T command, caddr_t data,
818 struct rdp_softc *sc = ifp->if_softc;
826 * If the interface is marked up and stopped, then start it.
827 * If it is marked down and running, then stop it.
829 if (ifp->if_flags & IFF_UP) {
830 if ((ifp->if_flags & IFF_RUNNING) == 0)
833 if (ifp->if_flags & IFF_RUNNING) {
835 ifp->if_flags &= ~IFF_RUNNING;
840 * Promiscuous flag may have changed, propagage this
843 if (ifp->if_flags & IFF_UP)
844 WrNib(sc, CMR2 + HNib,
845 MkHi((ifp->if_flags & IFF_PROMISC)?
846 CMR2_AM_ALL: CMR2_AM_PB));
853 * Multicast list has changed; we don't support it.
859 error = ether_ioctl(ifp, command, data);
869 * External interrupt service routine.
875 struct rdp_softc *sc = rdp_softc + unit;
876 struct ifnet *ifp = (struct ifnet *)sc;
877 u_char isr, tsr, rsr, colls;
879 lwkt_serialize_enter(ifp->if_serializer);
881 /* disable interrupts, so SD3 can be routed to the pin */
883 outb(sc->baseaddr + lpt_control, Ctrl_SelData);
884 WrNib(sc, CMR2, CMR2_IRQINV);
886 * loop until there are no more new interrupts
889 isr = RdNib(sc, ISR);
890 isr |= RdNib(sc, ISR + HNib) << 4;
891 RdEnd(sc, ISR + HNib);
896 printf("rdp%d: ISR = %#x\n", unit, isr);
900 * Clear the pending interrupt bits.
902 WrNib(sc, ISR, isr & 0x0f);
904 WrNib(sc, ISR + HNib, MkHi(isr));
907 * Handle transmitter interrupts.
909 if (isr & (ISR_TOK | ISR_TER)) {
910 tsr = RdNib(sc, TSR);
914 printf("rdp%d: tsr %#x\n", unit, tsr);
920 * Update total number of successfully
921 * transmitted packets.
926 colls = RdNib(sc, COLR);
928 ifp->if_collisions += colls;
932 * reset tx busy and output active flags
935 ifp->if_flags &= ~IFF_OACTIVE;
938 * If we had already queued up another packet,
939 * start sending it now.
941 if (sc->txbuffered) {
942 WrNib(sc, TBCR1, sc->txsize >> 8);
943 WrByte(sc, TBCR0, sc->txsize & 0xff);
944 WrNib(sc, CMR1, CMR1_TRA);
950 * clear watchdog timer
958 * Handle receiver interrupts
960 if (isr & (ISR_ROK | ISR_RER | ISR_RBER)) {
961 rsr = RdNib(sc, RSR);
962 rsr |= RdNib(sc, RSR + HNib) << 4;
963 RdEnd(sc, RSR + HNib);
965 if (isr & (ISR_RER | ISR_RBER))
966 printf("rdp%d: rsr %#x\n", unit, rsr);
969 if (rsr & (RSR_PUN | RSR_POV)) {
970 printf("rdp%d: rsr %#x, resetting\n",
978 * CRC and FA errors are recorded in
979 * rdp_rint() on a per-packet basis
982 if (isr & (ISR_ROK | ISR_RER))
987 * If it looks like the transmitter can take more data,
988 * attempt to start output on the interface. This is done
989 * after handling the receiver to give the receiver priority.
991 if ((ifp->if_flags & IFF_OACTIVE) == 0)
995 /* re-enable interrupts */
996 WrNib(sc, CMR2, CMR2_IRQOUT | CMR2_IRQINV);
997 sc->irqenbit = Ctrl_IRQEN;
998 outb(sc->baseaddr + lpt_control, Ctrl_SelData + sc->irqenbit);
999 lwkt_serialize_exit(ifp->if_serializer);
1003 * Ethernet interface receiver interrupt.
1006 rdp_rint(struct rdp_softc *sc)
1008 struct ifnet *ifp = &sc->arpcom.ac_if;
1012 u_char *packet_ptr, b, status;
1013 int excessive_bad_pkts = 0;
1016 * Fetch the packets from the NIC's buffer.
1019 b = RdNib(sc, CMR1);
1023 /* no more packets */
1026 /* first, obtain the buffer header */
1028 outb(sc->baseaddr + lpt_data, MAR + EOC); /* prepare addr */
1029 outb(sc->baseaddr + lpt_control, Ctrl_LNibRead);
1030 outb(sc->baseaddr + lpt_data, MAR + RdAddr + HNib);
1032 packet_ptr = (u_char *)&rh;
1034 for (i = 0; i < sizeof rh; i++, packet_ptr++)
1035 *packet_ptr = RdByteA2(sc);
1037 for (i = 0; i < sizeof rh; i++, packet_ptr++)
1038 *packet_ptr = RdByteA1(sc);
1040 RdEnd(sc, MAR + HNib);
1041 outb(sc->baseaddr + lpt_control, Ctrl_SelData);
1043 len = rh.pktlen - ETHER_CRC_LEN;
1046 if ((status & (RSR_ROK | RSR_CRC | RSR_FA)) != RSR_ROK ||
1047 len > (ETHER_MAX_LEN - ETHER_CRC_LEN) ||
1048 len < (ETHER_MIN_LEN - ETHER_CRC_LEN) ||
1051 printf("%s: bad packet in buffer, "
1052 "len %d, status %#x\n",
1053 ifp->if_xname, (int)len, (int)status);
1056 /* rx jump packet */
1057 WrNib(sc, CMR1, CMR1_RDPAC);
1058 if (++excessive_bad_pkts > 5) {
1060 * the chip seems to be stuck, we are
1061 * probably seeing the same bad packet
1062 * over and over again
1065 printf("%s: resetting due to an "
1066 "excessive number of bad packets\n",
1078 excessive_bad_pkts = 0;
1079 rdp_get_packet(sc, len);
1085 * Retreive packet from NIC memory and send to the next level up via
1089 rdp_get_packet(struct rdp_softc *sc, unsigned len)
1091 struct ifnet *ifp = &sc->arpcom.ac_if;
1096 /* Allocate a header mbuf */
1097 MGETHDR(m, MB_DONTWAIT, MT_DATA);
1100 m->m_pkthdr.rcvif = ifp;
1101 m->m_pkthdr.len = m->m_len = len;
1104 * We always put the received packet in a single buffer -
1105 * either with just an mbuf header or in a cluster attached
1106 * to the header. The +2 is to compensate for the alignment
1109 if ((len + 2) > MHLEN) {
1110 /* Attach an mbuf cluster */
1111 MCLGET(m, MB_DONTWAIT);
1113 /* Insist on getting a cluster */
1114 if ((m->m_flags & M_EXT) == 0) {
1121 * The +2 is to longword align the start of the real packet.
1122 * This is important for NFS.
1127 * Get packet, including link layer address, from interface.
1129 outb(sc->baseaddr + lpt_control, Ctrl_LNibRead);
1130 outb(sc->baseaddr + lpt_data, RdAddr + MAR);
1132 packet_ptr = mtod(m, u_char *);
1134 for (s = 0; s < len; s++, packet_ptr++)
1135 *packet_ptr = RdByteA2(sc);
1137 for (s = 0; s < len; s++, packet_ptr++)
1138 *packet_ptr = RdByteA1(sc);
1140 RdEnd(sc, MAR + HNib);
1141 outb(sc->baseaddr + lpt_control, Ctrl_SelData);
1142 WrNib(sc, CMR1, CMR1_RDPAC);
1144 ifp->if_input(ifp, m);
1148 * Write an mbuf chain to the NIC's tx buffer.
1151 rdp_write_mbufs(struct rdp_softc *sc, struct mbuf *m)
1158 /* First, count up the total number of bytes to copy */
1159 for (total_len = 0, mp = m; mp; mp = mp->m_next)
1160 total_len += mp->m_len;
1165 outb(sc->baseaddr + lpt_data, MAR | EOC);
1168 * Transfer the mbuf chain to the NIC memory.
1171 /* writing the first byte is complicated */
1172 outb(sc->baseaddr + lpt_control,
1173 Ctrl_LNibRead | sc->irqenbit);
1174 outb(sc->baseaddr + lpt_data, MAR | WrAddr);
1175 b = *(u_char *)m->m_data;
1176 outb(sc->baseaddr + lpt_data, (b & 0x0f) | 0x40);
1177 outb(sc->baseaddr + lpt_data, b & 0x0f);
1178 outb(sc->baseaddr + lpt_data, b >> 4);
1179 outb(sc->baseaddr + lpt_control,
1180 Ctrl_HNibRead | sc->irqenbit);
1181 /* advance the mbuf pointer */
1185 /* write the remaining bytes */
1187 for (i = 0, dp = (u_char *)m->m_data;
1190 WrByteALToDRAMA(sc, *dp);
1194 * restore old mbuf in case we have to hand it off to
1201 /* the RTL 8002 requires an even byte-count remote DMA */
1203 WrByteALToDRAMA(sc, 0);
1205 outb(sc->baseaddr + lpt_data, MAR | WrAddr);
1207 for (i = 0, dp = (u_char *)m->m_data;
1210 WrByteALToDRAM(sc, *dp);
1214 /* the RTL 8002 requires an even byte-count remote DMA */
1216 WrByteALToDRAM(sc, 0);
1219 outb(sc->baseaddr + lpt_data, 0xff);
1220 outb(sc->baseaddr + lpt_control,
1221 Ctrl_HNibRead | Ctrl_SelData | sc->irqenbit);
1227 * Read the designated ethernet hardware address out of a 93C46
1229 * Note that the 93C46 uses 16-bit words in big-endian notation.
1232 rdp_gethwaddr_93c46(struct rdp_softc *sc, u_char *etheraddr)
1238 WrNib(sc, CMR2, CMR2_PAGE | CMR2_IRQINV); /* select page 1 */
1241 * The original RealTek packet driver had the ethernet address
1242 * starting at EEPROM address 0. Other vendors seem to have
1243 * gone `creative' here -- while they didn't do anything else
1244 * than changing a few strings in the entire driver, compared
1245 * to the RealTek version, they also moved out the ethernet
1246 * address to a different location in the EEPROM, so the
1247 * original RealTek driver won't work correctly with them, and
1248 * vice versa. Sounds pretty cool, eh? $@%&!
1250 * Anyway, we walk through the EEPROM, until we find some
1251 * allowable value based upon our table of IEEE OUI assignments.
1253 for (i = magic = 0; magic < 3 && i < 32; i++) {
1254 /* read cmd (+ 6 bit address) */
1255 rdp_93c46_cmd(sc, 0x180 + i, 10);
1256 w = rdp_93c46_read(sc);
1260 j < sizeof allowed_ouis / sizeof(u_short);
1262 if (w == allowed_ouis[j]) {
1263 etheraddr[0] = (w >> 8) & 0xff;
1264 etheraddr[1] = w & 0xff;
1272 * If the first two bytes have been 00:00, we
1273 * discard the match iff the next two bytes
1274 * are also 00:00, so we won't get fooled by
1275 * an EEPROM that has been filled with zeros.
1276 * This in theory would disallow 64 K of legal
1277 * addresses assigned to Xerox, but it's
1278 * almost certain that those addresses haven't
1279 * been used for RTL80[01]2 chips anyway.
1281 if ((etheraddr[0] | etheraddr[1]) == 0 && w == 0) {
1286 etheraddr[2] = (w >> 8) & 0xff;
1287 etheraddr[3] = w & 0xff;
1292 etheraddr[4] = (w >> 8) & 0xff;
1293 etheraddr[5] = w & 0xff;
1299 WrNib(sc, CMR2, CMR2_IRQINV); /* back to page 0 */
1305 * Read the designated ethernet hardware address out of a 74S288
1308 * This is untested, since i haven't seen any adapter actually using
1309 * a 74S288. In the RTL 8012, only the serial EEPROM (94C46) is
1310 * supported anymore.
1313 rdp_gethwaddr_74s288(struct rdp_softc *sc, u_char *etheraddr)
1318 WrNib(sc, CMR2, CMR2_PAGE | CMR2_IRQINV); /* select page 1 */
1320 for (i = 0; i < 6; i++) {
1321 WrNib(sc, PCMR, i & 0x0f); /* lower 4 bit of addr */
1322 WrNib(sc, PCMR + HNib, HNib + 4); /* upper 2 bit addr + /CS */
1323 WrNib(sc, PCMR + HNib, HNib); /* latch data now */
1324 b = RdNib(sc, PDR) & 0x0f;
1325 b |= (RdNib(sc, PDR + HNib) & 0x0f) << 4;
1329 RdEnd(sc, PDR + HNib);
1330 WrNib(sc, CMR2, CMR2_IRQINV); /* reselect page 0 */
1334 * Send nbits of data (starting with MSB) out to the 93c46 as a
1335 * command. Assumes register page 1 has already been selected.
1338 rdp_93c46_cmd(struct rdp_softc *sc, u_short data, unsigned nbits)
1340 u_short mask = 1 << (nbits - 1);
1345 printf("rdp_93c46_cmd(): ");
1347 for (i = 0; i < nbits; i++, mask >>= 1) {
1348 b = HNib + PCMR_SK + PCMR_CS;
1352 printf("%d", b & 1);
1354 WrNib(sc, PCMR + HNib, b);
1356 WrNib(sc, PCMR + HNib, b & ~PCMR_SK);
1365 * Read one word of data from the 93c46. Actually, we have to read
1366 * 17 bits, and discard the very first bit. Assumes register page 1
1367 * to be selected as well.
1370 rdp_93c46_read(struct rdp_softc *sc)
1377 printf("rdp_93c46_read(): ");
1379 for (i = 0; i < 17; i++) {
1380 WrNib(sc, PCMR + HNib, PCMR_SK + PCMR_CS + HNib);
1382 WrNib(sc, PCMR + HNib, PCMR_CS + HNib);
1389 printf("%d", b & 1);
1399 WrNib(sc, PCMR + HNib, PCMR_SK + HNib);