bf8be94eec1d880732b06ac2fed9b2625c280847
[dragonfly.git] / sys / dev / netif / rdp / if_rdp.c
1 /*
2  * Copyright 1998, Joerg Wunsch
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice unmodified, this list of conditions, and the following
10  *    disclaimer.
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.
14  *
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
25  * SUCH DAMAGE.
26  *
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.4 2003/08/07 21:17:04 dillon Exp $
29  */
30
31 /*
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.
36  *
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)
40  *
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
47  * ethernet adapter.
48  *
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.
56  *
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.
63  */
64
65 #include "use_rdp.h"
66
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/conf.h>
70 #include <sys/sockio.h>
71 #include <sys/malloc.h>
72 #include <sys/mbuf.h>
73 #include <sys/socket.h>
74 #include <sys/syslog.h>
75
76 #include <net/ethernet.h>
77 #include <net/if.h>
78 #include <net/if_arp.h>
79 #include <net/if_dl.h>
80 #include <net/if_mib.h>
81
82 #ifdef INET
83 #include <netinet/in.h>
84 #include <netinet/if_ether.h>
85 #endif
86
87 #ifdef NS
88 #include <netns/ns.h>
89 #include <netns/ns_if.h>
90 #endif
91
92 #include <net/bpf.h>
93
94 #include <machine/clock.h>
95 #include <machine/md_var.h>
96
97 #include <bus/isa/i386/isa_device.h>
98 #include <i386/isa/icu.h>
99 #include "if_rdpreg.h"
100 #include <i386/isa/intr_machdep.h>
101
102 #define IOCTL_CMD_T u_long
103
104 /*
105  * Debug levels (ORed together):
106  *  != 0 - general (bad packets etc.)
107  *  2 - debug EEPROM IO
108  *  4 - debug interrupt status
109  */
110 #undef DEBUG
111 #define DEBUG 0
112
113 /*
114  * rdp_softc: per interface info and status
115  */
116 struct rdp_softc {
117         struct arpcom arpcom;   /*
118                                  * Ethernet common, always goes first so
119                                  * a rdp_softc * can be cast into an
120                                  * arpcom * or into an ifnet *.
121                                  */
122
123         /*
124          * local stuff, somewhat sorted by memory alignment class
125          */
126         u_short baseaddr;       /* IO port address */
127         u_short txsize;         /* tx size for next (buffered) packet,
128                                  * there's only one additional packet
129                                  * we can buffer, thus a single variable
130                                  * ought to be enough */
131         int txbusy;             /* tx is transmitting */
132         int txbuffered;         /* # of packets in tx buffer */
133         int slow;               /* use lpt_control to send data */
134         u_char irqenbit;        /* mirror of current Ctrl_IRQEN */
135         /*
136          * type of parameter EEPROM; device flags 0x1 selects 74S288
137          */
138         enum {
139                 EEPROM_93C46, EEPROM_74S288 /* or 82S123 */
140         } eeprom;
141 };
142
143 static struct rdp_softc rdp_softc[NRDP];
144
145 /*
146  * Since there's no fixed location in the EEPROM about where to find
147  * the ethernet hardware address, we drop a table of valid OUIs here,
148  * and search through the EEPROM until we find a possible valid
149  * Ethernet address.  Only the first 16 bits of all possible OUIs are
150  * recorded in the table (as obtained from
151  * http://standards.ieee.org/regauth/oui/oui.txt).
152  */
153
154 static u_short allowed_ouis[] = {
155         0x0000, 0x0001, 0x0002, 0x0004, 0x0005, 0x0006, 0x0007,
156         0x0008, 0x0010, 0x001C, 0x0020, 0x0040, 0x0050, 0x0060,
157         0x0070, 0x0080, 0x0090, 0x009D, 0x00A0, 0x00AA, 0x00BB,
158         0x00C0, 0x00CF, 0x00DD, 0x00E0, 0x00E6, 0x0207, 0x021C,
159         0x0260, 0x0270, 0x029D, 0x02AA, 0x02BB, 0x02C0, 0x02CF,
160         0x02E6, 0x040A, 0x04E0, 0x0800, 0x08BB, 0x1000, 0x1100,
161         0x8000, 0xAA00
162 };
163
164 /*
165  * ISA bus support.
166  */
167 static int rdp_probe            __P((struct isa_device *));
168 static int rdp_attach           __P((struct isa_device *));
169
170 /*
171  * Required entry points.
172  */
173 static void rdp_init(void *);
174 static int rdp_ioctl(struct ifnet *, IOCTL_CMD_T, caddr_t);
175 static void rdp_start(struct ifnet *);
176 static void rdp_reset(struct ifnet *);
177 static void rdp_watchdog(struct ifnet *);
178 static void rdpintr(int);
179
180 /*
181  * REDP private functions.
182  */
183
184 static void rdp_stop(struct rdp_softc *);
185 static void rdp_rint(struct rdp_softc *);
186 static void rdp_get_packet(struct rdp_softc *, unsigned);
187 static u_short rdp_write_mbufs(struct rdp_softc *, struct mbuf *);
188 static int rdp_gethwaddr_93c46(struct rdp_softc *, u_char *);
189 static void rdp_gethwaddr_74s288(struct rdp_softc *, u_char *);
190 static void rdp_93c46_cmd(struct rdp_softc *, u_short, unsigned);
191 static u_short rdp_93c46_read(struct rdp_softc *);
192
193 struct isa_driver rdpdriver = {
194         rdp_probe,
195         rdp_attach,
196         "rdp",
197         1                       /* we wanna get a chance before lptN */
198 };
199
200 /*
201  * REDP-specific functions.
202  *
203  * They are inlined, thus go first in this file.  Together with gcc's
204  * usual optimization, these functions probably come close to the
205  * packet driver's hand-optimized code. ;-)
206  *
207  * Comments are partially obtained from the packet driver as well.
208  * Some of the function names contain register names which don't make
209  * much sense for us, but i've kept them for easier reference in
210  * comparision to the packet driver.
211  *
212  * Some of the functions are currently not used by the driver; it's
213  * not quite clear whether we ever need them at all.  They are
214  * supposedly even slower than what is currently implemented as `slow'
215  * mode.  Right now, `fast' (default) mode is what the packet driver
216  * calls mode 0, slow mode is mode 3 (writing through lpt_control,
217  * reading twice).
218  *
219  * We should autoprobe the modi, as opposed to making them dependent
220  * on a kernel configuration flag.
221  */
222
223 /*
224  * read a nibble from rreg; end-of-data cmd is not issued;
225  * used for general register read.
226  *
227  * Unlike the packet driver's version, i'm shifting the result
228  * by 3 here (as opposed to within the caller's code) for clarity.
229  *  -- Joerg
230  */
231 static __inline u_char
232 RdNib(struct rdp_softc *sc, u_char rreg)
233 {
234
235         outb(sc->baseaddr + lpt_data, EOC + rreg);
236         outb(sc->baseaddr + lpt_data, RdAddr + rreg); /* write addr */
237         (void)inb(sc->baseaddr + lpt_status);
238         return (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
239 }
240
241 #if 0
242 /*
243  * read a byte from MAR register through lpt_data; the low nibble is
244  * read prior to the high one; end-of-read command is not issued; used
245  * for remote DMA in mode 4 + 5
246  */
247 static __inline u_char
248 RdByte(struct rdp_softc *sc)
249 {
250         u_char hinib, lonib;
251
252         outb(sc->baseaddr + lpt_data, RdAddr + MAR); /* cmd for low nibble */
253         lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
254         outb(sc->baseaddr + lpt_data, RdAddr + MAR + HNib);
255         hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0;
256         return hinib + lonib;
257 }
258
259
260 /*
261  * read a byte from MAR register through lpt_data; the low nibble is
262  * read prior to the high one; end-of-read command is not issued; used
263  * for remote DMA in mode 6 + 7
264  */
265 static __inline u_char
266 RdByte1(struct rdp_softc *sc)
267 {
268         u_char hinib, lonib;
269
270         outb(sc->baseaddr + lpt_data, RdAddr + MAR); /* cmd for low nibble */
271         (void)inb(sc->baseaddr + lpt_status);
272         lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
273         outb(sc->baseaddr + lpt_data, RdAddr + MAR + HNib);
274         (void)inb(sc->baseaddr + lpt_status);
275         hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0;
276         return hinib + lonib;
277 }
278 #endif
279
280
281 /*
282  * read a byte from MAR register through lpt_control; the low nibble is
283  * read prior to the high one; end-of-read command is not issued; used
284  * for remote DMA in mode 0 + 1
285  */
286 static __inline u_char
287 RdByteA1(struct rdp_softc *sc)
288 {
289         u_char hinib, lonib;
290
291         outb(sc->baseaddr + lpt_control, Ctrl_LNibRead);
292         lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
293         outb(sc->baseaddr + lpt_control, Ctrl_HNibRead);
294         hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0;
295         return hinib + lonib;
296 }
297
298
299 /*
300  * read a byte from MAR register through lpt_control; the low nibble is
301  * read prior to the high one; end-of-read command is not issued; used
302  * for remote DMA in mode 2 + 3
303  */
304 static __inline u_char
305 RdByteA2(struct rdp_softc *sc)
306 {
307         u_char hinib, lonib;
308
309         outb(sc->baseaddr + lpt_control, Ctrl_LNibRead);
310         (void)inb(sc->baseaddr + lpt_status);
311         lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
312         outb(sc->baseaddr + lpt_control, Ctrl_HNibRead);
313         (void)inb(sc->baseaddr + lpt_status);
314         hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0;
315         return hinib + lonib;
316 }
317
318 /*
319  * End-of-read cmd
320  */
321 static __inline void
322 RdEnd(struct rdp_softc *sc, u_char rreg)
323 {
324
325         outb(sc->baseaddr + lpt_data, EOC + rreg);
326 }
327
328 /*
329  * Write a nibble to a register; end-of-write is issued.
330  * Used for general register write.
331  */
332 static __inline void
333 WrNib(struct rdp_softc *sc, u_char wreg, u_char wdata)
334 {
335
336         /* prepare and write address */
337         outb(sc->baseaddr + lpt_data, EOC + wreg);
338         outb(sc->baseaddr + lpt_data, WrAddr + wreg);
339         outb(sc->baseaddr + lpt_data, WrAddr + wreg);
340         /* prepare and write data */
341         outb(sc->baseaddr + lpt_data, WrAddr + wdata);
342         outb(sc->baseaddr + lpt_data, wdata);
343         outb(sc->baseaddr + lpt_data, wdata);
344         /* end-of-write */
345         outb(sc->baseaddr + lpt_data, EOC + wdata);
346 }
347
348 /*
349  * Write a byte to a register; end-of-write is issued.
350  * Used for general register write.
351  */
352 static __inline void
353 WrByte(struct rdp_softc *sc, u_char wreg, u_char wdata)
354 {
355
356         /* prepare and write address */
357         outb(sc->baseaddr + lpt_data, EOC + wreg);
358         outb(sc->baseaddr + lpt_data, WrAddr + wreg);
359         outb(sc->baseaddr + lpt_data, WrAddr + wreg);
360         /* prepare and write low nibble */
361         outb(sc->baseaddr + lpt_data, WrAddr + (wdata & 0x0F));
362         outb(sc->baseaddr + lpt_data, (wdata & 0x0F));
363         outb(sc->baseaddr + lpt_data, (wdata & 0x0F));
364         /* prepare and write high nibble */
365         wdata >>= 4;
366         outb(sc->baseaddr + lpt_data, wdata);
367         outb(sc->baseaddr + lpt_data, wdata + HNib);
368         outb(sc->baseaddr + lpt_data, wdata + HNib);
369         /* end-of-write */
370         outb(sc->baseaddr + lpt_data, EOC + wdata + HNib);
371 }
372
373 /*
374  * Write the byte to DRAM via lpt_data;
375  * used for remote DMA write in mode 0 / 2 / 4
376  */
377 static __inline void
378 WrByteALToDRAM(struct rdp_softc *sc, u_char val)
379 {
380
381         outb(sc->baseaddr + lpt_data, val & 0x0F);
382         outb(sc->baseaddr + lpt_data, MkHi(val));
383 }
384
385 /*
386  * Write the byte to DRAM via lpt_control;
387  * used for remote DMA write in mode 1 / 3 / 5
388  */
389 static __inline void
390 WrByteALToDRAMA(struct rdp_softc *sc, u_char val)
391 {
392
393         outb(sc->baseaddr + lpt_data, val & 0x0F);
394         outb(sc->baseaddr + lpt_control, Ctrl_LNibRead | sc->irqenbit);
395         outb(sc->baseaddr + lpt_data, val >> 4);
396         outb(sc->baseaddr + lpt_control, Ctrl_HNibRead | sc->irqenbit);
397 }
398
399 #if 0 /* they could be used for the RAM test */
400 /*
401  * Write the u_short to DRAM via lpt_data;
402  * used for remote DMA write in mode 0 / 2 / 4
403  */
404 static __inline void
405 WrWordbxToDRAM(struct rdp_softc *sc, u_short val)
406 {
407
408         outb(sc->baseaddr + lpt_data, val & 0x0F);
409         val >>= 4;
410         outb(sc->baseaddr + lpt_data, (val & 0x0F) + HNib);
411         val >>= 4;
412         outb(sc->baseaddr + lpt_data, val & 0x0F);
413         val >>= 4;
414         outb(sc->baseaddr + lpt_data, val + HNib);
415 }
416
417
418 /*
419  * Write the u_short to DRAM via lpt_control;
420  * used for remote DMA write in mode 1 / 3 / 5
421  */
422 static __inline void
423 WrWordbxToDRAMA(struct rdp_softc *sc, u_short val)
424 {
425
426         outb(sc->baseaddr + lpt_data, val & 0x0F);
427         outb(sc->baseaddr + lpt_control, Ctrl_LNibRead | sc->irqenbit);
428         val >>= 4;
429         outb(sc->baseaddr + lpt_data, (val & 0x0F) + HNib);
430         outb(sc->baseaddr + lpt_control, Ctrl_HNibRead | sc->irqenbit);
431         val >>= 4;
432         outb(sc->baseaddr + lpt_data, val & 0x0F);
433         outb(sc->baseaddr + lpt_control, Ctrl_LNibRead | sc->irqenbit);
434         val >>= 4;
435         outb(sc->baseaddr + lpt_data, val + HNib);
436         outb(sc->baseaddr + lpt_control, Ctrl_HNibRead | sc->irqenbit);
437 }
438 #endif
439
440
441 /*
442  * Determine if the device is present
443  *
444  *   on entry:
445  *      a pointer to an isa_device struct
446  *   on exit:
447  *      0 if device not found
448  *      or # of i/o addresses used (if found)
449  */
450 static int
451 rdp_probe(struct isa_device *isa_dev)
452 {
453         int unit = isa_dev->id_unit;
454         struct rdp_softc *sc = &rdp_softc[unit];
455         u_char b1, b2;
456         intrmask_t irqmap[3];
457         u_char sval[3];
458
459         if (unit < 0 || unit >= NRDP)
460                 return 0;
461
462         sc->baseaddr = isa_dev->id_iobase;
463         if (isa_dev->id_flags & 1)
464                 sc->eeprom = EEPROM_74S288;
465         /* else defaults to 93C46 */
466         if (isa_dev->id_flags & 2)
467                 sc->slow = 1;
468
469         /* let R/WB = A/DB = CSB = high to be ready for next r/w cycle */
470         outb(sc->baseaddr + lpt_data, 0xFF);
471         /* DIR = 0 for write mode, IRQEN=0, SLCT=INIT=AUTOFEED=STB=high */
472         outb(sc->baseaddr + lpt_control, Ctrl_SelData);
473         /* software reset */
474         WrNib(sc, CMR1 + HNib, MkHi(CMR1_RST));
475         DELAY(2000);
476         /* is EPLC alive? */
477         b1 = RdNib(sc, CMR1);
478         RdEnd(sc, CMR1);
479         b2 = RdNib(sc, CMR2) & 0x0f;
480         b2 |= RdNib(sc, CMR2 + HNib) << 4;
481         RdEnd(sc, CMR2 + HNib);
482         /*
483          * After the reset, we expect CMR1 & 7 to be 1 (rx buffer empty),
484          * and CMR2 & 0xf7 to be 0x20 (receive mode set to physical and
485          * broadcasts).
486          */
487         if (bootverbose)
488                 printf("rdp%d: CMR1 = %#x, CMR2 = %#x\n", unit, b1, b2);
489
490         if ((b1 & (CMR1_BUFE | CMR1_IRQ | CMR1_TRA)) != CMR1_BUFE
491             || (b2 & ~CMR2_IRQINV) != CMR2_AM_PB)
492                 return 0;
493
494         /*
495          * We have found something that could be a RTL 80[01]2, now
496          * see whether we can generate an interrupt.
497          */
498         cpu_disable_intr();
499
500         /*
501          * Test whether our configured IRQ is working.
502          *
503          * Set to no acception mode + IRQout, then enable RxE + TxE,
504          * then cause RBER (by advancing the read pointer although
505          * the read buffer is empty) to generate an interrupt.
506          */
507         WrByte(sc, CMR2, CMR2_IRQOUT);
508         WrNib(sc, CMR1 + HNib, MkHi(CMR1_TE | CMR1_RE));
509         WrNib(sc, CMR1, CMR1_RDPAC);
510         DELAY(1000);
511
512         irqmap[0] = isa_irq_pending();
513         sval[0] = inb(sc->baseaddr + lpt_status);
514
515         /* allow IRQs to pass the parallel interface */
516         outb(sc->baseaddr + lpt_control, Ctrl_IRQEN + Ctrl_SelData);
517         DELAY(1000);
518         /* generate interrupt */
519         WrNib(sc, IMR + HNib, MkHi(ISR_RBER));
520         DELAY(1000);
521
522         irqmap[1] = isa_irq_pending();
523         sval[1] = inb(sc->baseaddr + lpt_status);
524
525         /* de-assert and disable IRQ */
526         WrNib(sc, IMR + HNib, MkHi(0));
527         (void)inb(sc->baseaddr + lpt_status); /* might be necessary to
528                                                  clear IRQ */
529         DELAY(1000);
530         irqmap[2] = isa_irq_pending();
531         sval[2] = inb(sc->baseaddr + lpt_status);
532
533         WrNib(sc, CMR1 + HNib, MkHi(0));
534         outb(sc->baseaddr + lpt_control, Ctrl_SelData);
535         WrNib(sc, CMR2, CMR2_IRQINV);
536
537         cpu_enable_intr();
538
539         if (bootverbose)
540                 printf("rdp%d: irq maps / lpt status "
541                        "%#x/%#x - %#x/%#x - %#x/%#x (id_irq %#x)\n",
542                        unit, irqmap[0], sval[0], irqmap[1], sval[1],
543                        irqmap[2], sval[2], isa_dev->id_irq);
544
545         if ((irqmap[1] & isa_dev->id_irq) == 0) {
546                 printf("rdp%d: configured IRQ (%d) cannot be asserted "
547                        "by device",
548                        unit, ffs(isa_dev->id_irq) - 1);
549                 if (irqmap[1])
550                         printf(" (probable IRQ: %d)", ffs(irqmap[1]) - 1);
551                 printf("\n");
552                 return 0;
553         }
554
555         /*
556          * XXX should do RAMtest here
557          */
558
559         switch (sc->eeprom) {
560         case EEPROM_93C46:
561                 if (rdp_gethwaddr_93c46(sc, sc->arpcom.ac_enaddr) == 0) {
562                         printf("rdp%d: failed to find a valid hardware "
563                                "address in EEPROM\n",
564                                unit);
565                         return 0;
566                 }
567                 break;
568
569         case EEPROM_74S288:
570                 rdp_gethwaddr_74s288(sc, sc->arpcom.ac_enaddr);
571                 break;
572         }
573
574         return lpt_control + 1;
575 }
576
577 /*
578  * Install interface into kernel networking data structures
579  */
580 static int
581 rdp_attach(struct isa_device *isa_dev)
582 {
583         int unit = isa_dev->id_unit;
584         struct rdp_softc *sc = &rdp_softc[unit];
585         struct ifnet *ifp = &sc->arpcom.ac_if;
586
587         isa_dev->id_ointr = rdpintr;
588
589         /*
590          * Reset interface
591          */
592         rdp_stop(sc);
593
594         if (!ifp->if_name) {
595                 /*
596                  * Initialize ifnet structure
597                  */
598                 ifp->if_softc = sc;
599                 ifp->if_unit = unit;
600                 ifp->if_name = "rdp";
601                 ifp->if_output = ether_output;
602                 ifp->if_start = rdp_start;
603                 ifp->if_ioctl = rdp_ioctl;
604                 ifp->if_watchdog = rdp_watchdog;
605                 ifp->if_init = rdp_init;
606                 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
607                 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
608
609                 /*
610                  * Attach the interface
611                  */
612                 ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
613         }
614
615         /*
616          * Print additional info when attached
617          */
618         printf("%s%d: RealTek RTL%s pocket ethernet, EEPROM %s, %s mode\n",
619                ifp->if_name, ifp->if_unit,
620                "8002",          /* hook for 8012 */
621                sc->eeprom == EEPROM_93C46? "93C46": "74S288",
622                sc->slow? "slow": "fast");
623         printf("%s%d: address %6D\n", ifp->if_name, ifp->if_unit,
624                sc->arpcom.ac_enaddr, ":");
625
626         return 1;
627 }
628
629 /*
630  * Reset interface.
631  */
632 static void
633 rdp_reset(struct ifnet *ifp)
634 {
635         struct rdp_softc *sc = ifp->if_softc;
636         int s;
637
638         s = splimp();
639
640         /*
641          * Stop interface and re-initialize.
642          */
643         rdp_stop(sc);
644         rdp_init(sc);
645
646         (void) splx(s);
647 }
648
649 /*
650  * Take interface offline.
651  */
652 static void
653 rdp_stop(struct rdp_softc *sc)
654 {
655
656         sc->txbusy = sc->txbusy = 0;
657
658         /* disable printer interface interrupts */
659         sc->irqenbit = 0;
660         outb(sc->baseaddr + lpt_control, Ctrl_SelData);
661         outb(sc->baseaddr + lpt_data, 0xff);
662
663         /* reset the RTL 8002 */
664         WrNib(sc, CMR1 + HNib, MkHi(CMR1_RST));
665         DELAY(100);
666 }
667
668 /*
669  * Device timeout/watchdog routine. Entered if the device neglects to
670  * generate an interrupt after a transmit has been started on it.
671  */
672 static void
673 rdp_watchdog(struct ifnet *ifp)
674 {
675
676         log(LOG_ERR, "rdp%d: device timeout\n", ifp->if_unit);
677         ifp->if_oerrors++;
678
679         rdp_reset(ifp);
680 }
681
682 /*
683  * Initialize device.
684  */
685 static void
686 rdp_init(void *xsc)
687 {
688         struct rdp_softc *sc = xsc;
689         struct ifnet *ifp = &sc->arpcom.ac_if;
690         int i, s;
691         u_char reg;
692
693         /* address not known */
694         if (TAILQ_EMPTY(&ifp->if_addrhead))
695                 return;
696
697         s = splimp();
698
699         ifp->if_timer = 0;
700
701         /* program ethernet ID into the chip */
702         for (i = 0, reg = IDR0; i < 6; i++, reg++)
703                 WrByte(sc, reg, sc->arpcom.ac_enaddr[i]);
704
705         /* set accept mode */
706         WrNib(sc, CMR2 + HNib,
707               MkHi((ifp->if_flags & IFF_PROMISC)? CMR2_AM_ALL: CMR2_AM_PB));
708
709         /* enable tx and rx */
710         WrNib(sc, CMR1 + HNib, MkHi(CMR1_TE | CMR1_RE));
711
712         /* allow interrupts to happen */
713         WrNib(sc, CMR2, CMR2_IRQOUT | CMR2_IRQINV);
714         WrNib(sc, IMR, ISR_TOK | ISR_TER | ISR_ROK | ISR_RER);
715         WrNib(sc, IMR + HNib, MkHi(ISR_RBER));
716
717         /* allow IRQs to pass the parallel interface */
718         sc->irqenbit = Ctrl_IRQEN;
719         outb(sc->baseaddr + lpt_control, sc->irqenbit + Ctrl_SelData);
720
721         /* clear all flags */
722         sc->txbusy = sc->txbuffered = 0;
723
724         /*
725          * Set 'running' flag, and clear output active flag.
726          */
727         ifp->if_flags |= IFF_RUNNING;
728         ifp->if_flags &= ~IFF_OACTIVE;
729
730         /*
731          * ...and attempt to start output
732          */
733         rdp_start(ifp);
734
735         (void) splx(s);
736 }
737
738 /*
739  * Start output on interface.
740  * We make two assumptions here:
741  *  1) that the current priority is set to splimp _before_ this code
742  *     is called *and* is returned to the appropriate priority after
743  *     return
744  *  2) that the IFF_OACTIVE flag is checked before this code is called
745  *     (i.e. that the output part of the interface is idle)
746  */
747 static void
748 rdp_start(struct ifnet *ifp)
749 {
750         struct rdp_softc *sc = ifp->if_softc;
751         struct mbuf *m;
752         int len;
753
754 outloop:
755
756         /*
757          * See if there is room to put another packet in the buffer.
758          */
759         if (sc->txbuffered) {
760                 /*
761                  * No room. Indicate this to the outside world and exit.
762                  */
763                 ifp->if_flags |= IFF_OACTIVE;
764                 return;
765         }
766         IF_DEQUEUE(&ifp->if_snd, m);
767         if (m == 0) {
768                 /*
769                  * We are using the !OACTIVE flag to indicate to the outside
770                  * world that we can accept an additional packet rather than
771                  * that the transmitter is _actually_ active. Indeed, the
772                  * transmitter may be active, but if we haven't filled all the
773                  * buffers with data then we still want to accept more.
774                  */
775                 ifp->if_flags &= ~IFF_OACTIVE;
776                 return;
777         }
778
779         /*
780          * Copy the mbuf chain into the transmit buffer
781          */
782
783         len = rdp_write_mbufs(sc, m);
784         if (len == 0)
785                 goto outloop;
786
787         /* ensure minimal valid ethernet length */
788         len = max(len, (ETHER_MIN_LEN-ETHER_CRC_LEN));
789
790         /*
791          * Actually start the transceiver.  Set a timeout in case the
792          * Tx interrupt never arrives.
793          */
794         if (!sc->txbusy) {
795                 WrNib(sc, TBCR1, len >> 8);
796                 WrByte(sc, TBCR0, len & 0xff);
797                 WrNib(sc, CMR1, CMR1_TRA);
798                 sc->txbusy = 1;
799                 ifp->if_timer = 2;
800         } else {
801                 sc->txbuffered = 1;
802                 sc->txsize = len;
803         }
804
805         /*
806          * Tap off here if there is a bpf listener.
807          */
808         if (ifp->if_bpf) {
809                 bpf_mtap(ifp, m);
810         }
811
812         m_freem(m);
813
814         /*
815          * Loop back to the top to possibly buffer more packets
816          */
817         goto outloop;
818 }
819
820 /*
821  * Process an ioctl request.
822  */
823 static int
824 rdp_ioctl(struct ifnet *ifp, IOCTL_CMD_T command, caddr_t data)
825 {
826         struct rdp_softc *sc = ifp->if_softc;
827         int s, error = 0;
828
829         s = splimp();
830
831         switch (command) {
832
833         case SIOCSIFADDR:
834         case SIOCGIFADDR:
835         case SIOCSIFMTU:
836                 error = ether_ioctl(ifp, command, data);
837                 break;
838
839         case SIOCSIFFLAGS:
840                 /*
841                  * If the interface is marked up and stopped, then start it.
842                  * If it is marked down and running, then stop it.
843                  */
844                 if (ifp->if_flags & IFF_UP) {
845                         if ((ifp->if_flags & IFF_RUNNING) == 0)
846                                 rdp_init(sc);
847                 } else {
848                         if (ifp->if_flags & IFF_RUNNING) {
849                                 rdp_stop(sc);
850                                 ifp->if_flags &= ~IFF_RUNNING;
851                         }
852                 }
853
854                 /*
855                  * Promiscuous flag may have changed, propagage this
856                  * to the NIC.
857                  */
858                 if (ifp->if_flags & IFF_UP)
859                         WrNib(sc, CMR2 + HNib,
860                               MkHi((ifp->if_flags & IFF_PROMISC)?
861                                    CMR2_AM_ALL: CMR2_AM_PB));
862
863                 break;
864
865         case SIOCADDMULTI:
866         case SIOCDELMULTI:
867                 /*
868                  * Multicast list has changed; we don't support it.
869                  */
870                 error = ENOTTY;
871                 break;
872
873         default:
874                 error = EINVAL;
875         }
876         (void) splx(s);
877         return (error);
878 }
879
880 /*
881  * External interrupt service routine.
882  */
883 void 
884 rdpintr(int unit)
885 {
886         struct rdp_softc *sc = rdp_softc + unit;
887         struct ifnet *ifp = (struct ifnet *)sc;
888         u_char isr, tsr, rsr, colls;
889
890         /* disable interrupts, so SD3 can be routed to the pin */
891         sc->irqenbit = 0;
892         outb(sc->baseaddr + lpt_control, Ctrl_SelData);
893         WrNib(sc, CMR2, CMR2_IRQINV);
894         /*
895          * loop until there are no more new interrupts
896          */
897         for (;;) {
898                 isr = RdNib(sc, ISR);
899                 isr |= RdNib(sc, ISR + HNib) << 4;
900                 RdEnd(sc, ISR + HNib);
901
902                 if (isr == 0)
903                         break;
904 #if DEBUG & 4
905                 printf("rdp%d: ISR = %#x\n", unit, isr);
906 #endif
907
908                 /*
909                  * Clear the pending interrupt bits.
910                  */
911                 WrNib(sc, ISR, isr & 0x0f);
912                 if (isr & 0xf0)
913                         WrNib(sc, ISR + HNib, MkHi(isr));
914
915                 /*
916                  * Handle transmitter interrupts.
917                  */
918                 if (isr & (ISR_TOK | ISR_TER)) {
919                         tsr = RdNib(sc, TSR);
920                         RdEnd(sc, TSR);
921 #if DEBUG & 4
922                         if (isr & ISR_TER)
923                                 printf("rdp%d: tsr %#x\n", unit, tsr);
924 #endif
925                         if (tsr & TSR_TABT)
926                                 ifp->if_oerrors++;
927                         else
928                                 /*
929                                  * Update total number of successfully
930                                  * transmitted packets.
931                                  */
932                                 ifp->if_opackets++;
933
934                         if (tsr & TSR_COL) {
935                                 colls = RdNib(sc, COLR);
936                                 RdEnd(sc, COLR);
937                                 ifp->if_collisions += colls;
938                         }
939
940                         /*
941                          * reset tx busy and output active flags
942                          */
943                         sc->txbusy = 0;
944                         ifp->if_flags &= ~IFF_OACTIVE;
945
946                         /*
947                          * If we had already queued up another packet,
948                          * start sending it now.
949                          */
950                         if (sc->txbuffered) {
951                                 WrNib(sc, TBCR1, sc->txsize >> 8);
952                                 WrByte(sc, TBCR0, sc->txsize & 0xff);
953                                 WrNib(sc, CMR1, CMR1_TRA);
954                                 sc->txbusy = 1;
955                                 sc->txbuffered = 0;
956                                 ifp->if_timer = 2;
957                         } else {
958                                 /*
959                                  * clear watchdog timer
960                                  */
961                                 ifp->if_timer = 0;
962                         }
963                         
964                 }
965
966                 /*
967                  * Handle receiver interrupts
968                  */
969                 if (isr & (ISR_ROK | ISR_RER | ISR_RBER)) {
970                         rsr = RdNib(sc, RSR);
971                         rsr |= RdNib(sc, RSR + HNib) << 4;
972                         RdEnd(sc, RSR + HNib);
973 #if DEBUG & 4
974                         if (isr & (ISR_RER | ISR_RBER))
975                                 printf("rdp%d: rsr %#x\n", unit, rsr);
976 #endif
977
978                         if (rsr & (RSR_PUN | RSR_POV)) {
979                                 printf("rdp%d: rsr %#x, resetting\n",
980                                        unit, rsr);
981                                 rdp_reset(ifp);
982                                 break;
983                         }
984
985                         if (rsr & RSR_BUFO)
986                                 /*
987                                  * CRC and FA errors are recorded in
988                                  * rdp_rint() on a per-packet basis
989                                  */
990                                 ifp->if_ierrors++;
991                         if (isr & (ISR_ROK | ISR_RER))
992                                 rdp_rint(sc);
993                 }
994
995                 /*
996                  * If it looks like the transmitter can take more data,
997                  * attempt to start output on the interface. This is done
998                  * after handling the receiver to give the receiver priority.
999                  */
1000                 if ((ifp->if_flags & IFF_OACTIVE) == 0)
1001                         rdp_start(ifp);
1002
1003         }
1004         /* re-enable interrupts */
1005         WrNib(sc, CMR2, CMR2_IRQOUT | CMR2_IRQINV);
1006         sc->irqenbit = Ctrl_IRQEN;
1007         outb(sc->baseaddr + lpt_control, Ctrl_SelData + sc->irqenbit);
1008 }
1009
1010 /*
1011  * Ethernet interface receiver interrupt.
1012  */
1013 static void
1014 rdp_rint(struct rdp_softc *sc)
1015 {
1016         struct ifnet *ifp = &sc->arpcom.ac_if;
1017         struct rdphdr rh;
1018         u_short len;
1019         size_t i;
1020         u_char *packet_ptr, b, status;
1021         int excessive_bad_pkts = 0;
1022
1023         /*
1024          * Fetch the packets from the NIC's buffer.
1025          */
1026         for (;;) {
1027                 b = RdNib(sc, CMR1);
1028                 RdEnd(sc, CMR1);
1029
1030                 if (b & CMR1_BUFE)
1031                         /* no more packets */
1032                         break;
1033
1034                 /* first, obtain the buffer header */
1035                 
1036                 outb(sc->baseaddr + lpt_data, MAR + EOC); /* prepare addr */
1037                 outb(sc->baseaddr + lpt_control, Ctrl_LNibRead);
1038                 outb(sc->baseaddr + lpt_data, MAR + RdAddr + HNib);
1039
1040                 packet_ptr = (u_char *)&rh;
1041                 if (sc->slow)
1042                         for (i = 0; i < sizeof rh; i++, packet_ptr++)
1043                                 *packet_ptr = RdByteA2(sc);
1044                 else
1045                         for (i = 0; i < sizeof rh; i++, packet_ptr++)
1046                                 *packet_ptr = RdByteA1(sc);
1047
1048                 RdEnd(sc, MAR + HNib);
1049                 outb(sc->baseaddr + lpt_control, Ctrl_SelData);
1050
1051                 len = rh.pktlen - ETHER_CRC_LEN;
1052                 status = rh.status;
1053
1054                 if ((status & (RSR_ROK | RSR_CRC | RSR_FA)) != RSR_ROK ||
1055                     len > (ETHER_MAX_LEN - ETHER_CRC_LEN) ||
1056                     len < (ETHER_MIN_LEN - ETHER_CRC_LEN) ||
1057                     len > MCLBYTES) {
1058 #if DEBUG
1059                         printf("rdp%d: bad packet in buffer, "
1060                                "len %d, status %#x\n",
1061                                ifp->if_unit, (int)len, (int)status);
1062 #endif
1063                         ifp->if_ierrors++;
1064                         /* rx jump packet */
1065                         WrNib(sc, CMR1, CMR1_RDPAC);
1066                         if (++excessive_bad_pkts > 5) {
1067                                 /*
1068                                  * the chip seems to be stuck, we are
1069                                  * probably seeing the same bad packet
1070                                  * over and over again
1071                                  */
1072 #if DEBUG
1073                                 printf("rdp%d: resetting due to an "
1074                                        "excessive number of bad packets\n",
1075                                        ifp->if_unit);
1076 #endif
1077                                 rdp_reset(ifp);
1078                                 return;
1079                         }
1080                         continue;
1081                 }
1082
1083                 /*
1084                  * Go get packet.
1085                  */
1086                 excessive_bad_pkts = 0;
1087                 rdp_get_packet(sc, len);
1088                 ifp->if_ipackets++;
1089         }
1090 }
1091
1092 /*
1093  * Retreive packet from NIC memory and send to the next level up via
1094  * ether_input().
1095  */
1096 static void
1097 rdp_get_packet(struct rdp_softc *sc, unsigned len)
1098 {
1099         struct ether_header *eh;
1100         struct mbuf *m;
1101         u_char *packet_ptr;
1102         size_t s;
1103
1104         /* Allocate a header mbuf */
1105         MGETHDR(m, M_DONTWAIT, MT_DATA);
1106         if (m == NULL)
1107                 return;
1108         m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
1109         m->m_pkthdr.len = m->m_len = len;
1110
1111         /*
1112          * We always put the received packet in a single buffer -
1113          * either with just an mbuf header or in a cluster attached
1114          * to the header. The +2 is to compensate for the alignment
1115          * fixup below.
1116          */
1117         if ((len + 2) > MHLEN) {
1118                 /* Attach an mbuf cluster */
1119                 MCLGET(m, M_DONTWAIT);
1120
1121                 /* Insist on getting a cluster */
1122                 if ((m->m_flags & M_EXT) == 0) {
1123                         m_freem(m);
1124                         return;
1125                 }
1126         }
1127
1128         /*
1129          * The +2 is to longword align the start of the real packet.
1130          * This is important for NFS.
1131          */
1132         m->m_data += 2;
1133         eh = mtod(m, struct ether_header *);
1134
1135         /*
1136          * Get packet, including link layer address, from interface.
1137          */
1138         outb(sc->baseaddr + lpt_control, Ctrl_LNibRead);
1139         outb(sc->baseaddr + lpt_data, RdAddr + MAR);
1140
1141         packet_ptr = (u_char *)eh;
1142         if (sc->slow)
1143                 for (s = 0; s < len; s++, packet_ptr++)
1144                         *packet_ptr = RdByteA2(sc);
1145         else
1146                 for (s = 0; s < len; s++, packet_ptr++)
1147                         *packet_ptr = RdByteA1(sc);
1148
1149         RdEnd(sc, MAR + HNib);
1150         outb(sc->baseaddr + lpt_control, Ctrl_SelData);
1151         WrNib(sc, CMR1, CMR1_RDPAC);
1152
1153         /*
1154          * Remove link layer address.
1155          */
1156         m->m_pkthdr.len = m->m_len = len - sizeof(struct ether_header);
1157         m->m_data += sizeof(struct ether_header);
1158
1159         ether_input(&sc->arpcom.ac_if, eh, m);
1160 }
1161
1162 /*
1163  * Write an mbuf chain to the NIC's tx buffer.
1164  */
1165 static u_short
1166 rdp_write_mbufs(struct rdp_softc *sc, struct mbuf *m)
1167 {
1168         u_short total_len;
1169         struct mbuf *mp;
1170         u_char *dp, b;
1171         int i;
1172
1173         /* First, count up the total number of bytes to copy */
1174         for (total_len = 0, mp = m; mp; mp = mp->m_next)
1175                 total_len += mp->m_len;
1176
1177         if (total_len == 0)
1178                 return 0;
1179
1180         outb(sc->baseaddr + lpt_data, MAR | EOC);
1181
1182         /*
1183          * Transfer the mbuf chain to the NIC memory.
1184          */
1185         if (sc->slow) {
1186                 /* writing the first byte is complicated */
1187                 outb(sc->baseaddr + lpt_control,
1188                      Ctrl_LNibRead | sc->irqenbit);
1189                 outb(sc->baseaddr + lpt_data, MAR | WrAddr);
1190                 b = *(u_char *)m->m_data;
1191                 outb(sc->baseaddr + lpt_data, (b & 0x0f) | 0x40);
1192                 outb(sc->baseaddr + lpt_data, b & 0x0f);
1193                 outb(sc->baseaddr + lpt_data, b >> 4);
1194                 outb(sc->baseaddr + lpt_control,
1195                      Ctrl_HNibRead | sc->irqenbit);
1196                 /* advance the mbuf pointer */
1197                 mp = m;
1198                 m->m_len--;
1199                 m->m_data++;
1200                 /* write the remaining bytes */
1201                 while (m) {
1202                         for (i = 0, dp = (u_char *)m->m_data;
1203                              i < m->m_len;
1204                              i++, dp++)
1205                                 WrByteALToDRAMA(sc, *dp);
1206                         m = m->m_next;
1207                 }
1208                 /*
1209                  * restore old mbuf in case we have to hand it off to
1210                  * BPF again
1211                  */
1212                 m = mp;
1213                 m->m_len++;
1214                 m->m_data--;
1215
1216                 /* the RTL 8002 requires an even byte-count remote DMA */
1217                 if (total_len & 1)
1218                         WrByteALToDRAMA(sc, 0);
1219         } else {
1220                 outb(sc->baseaddr + lpt_data, MAR | WrAddr);
1221                 while (m) {
1222                         for (i = 0, dp = (u_char *)m->m_data;
1223                              i < m->m_len;
1224                              i++, dp++)
1225                                 WrByteALToDRAM(sc, *dp);
1226                         m = m->m_next;
1227                 }
1228
1229                 /* the RTL 8002 requires an even byte-count remote DMA */
1230                 if (total_len & 1)
1231                         WrByteALToDRAM(sc, 0);
1232         }
1233
1234         outb(sc->baseaddr + lpt_data, 0xff);
1235         outb(sc->baseaddr + lpt_control,
1236              Ctrl_HNibRead | Ctrl_SelData | sc->irqenbit);
1237
1238         return total_len;
1239 }
1240
1241 /*
1242  * Read the designated ethernet hardware address out of a 93C46
1243  * (serial) EEPROM.
1244  * Note that the 93C46 uses 16-bit words in big-endian notation.
1245  */
1246 static int
1247 rdp_gethwaddr_93c46(struct rdp_softc *sc, u_char *etheraddr)
1248 {
1249         int i, magic;
1250         size_t j = 0;
1251         u_short w;
1252
1253         WrNib(sc, CMR2, CMR2_PAGE | CMR2_IRQINV); /* select page 1 */
1254
1255         /*
1256          * The original RealTek packet driver had the ethernet address
1257          * starting at EEPROM address 0.  Other vendors seem to have
1258          * gone `creative' here -- while they didn't do anything else
1259          * than changing a few strings in the entire driver, compared
1260          * to the RealTek version, they also moved out the ethernet
1261          * address to a different location in the EEPROM, so the
1262          * original RealTek driver won't work correctly with them, and
1263          * vice versa.  Sounds pretty cool, eh?  $@%&!
1264          *
1265          * Anyway, we walk through the EEPROM, until we find some
1266          * allowable value based upon our table of IEEE OUI assignments.
1267          */
1268         for (i = magic = 0; magic < 3 && i < 32; i++) {
1269                 /* read cmd (+ 6 bit address) */
1270                 rdp_93c46_cmd(sc, 0x180 + i, 10);
1271                 w = rdp_93c46_read(sc);
1272                 switch (magic) {
1273                 case 0:
1274                         for (j = 0;
1275                              j < sizeof allowed_ouis / sizeof(u_short);
1276                              j++)
1277                                 if (w == allowed_ouis[j]) {
1278                                         etheraddr[0] = (w >> 8) & 0xff;
1279                                         etheraddr[1] = w & 0xff;
1280                                         magic++;
1281                                         break;
1282                                 }
1283                         break;
1284
1285                 case 1:
1286                         /*
1287                          * If the first two bytes have been 00:00, we
1288                          * discard the match iff the next two bytes
1289                          * are also 00:00, so we won't get fooled by
1290                          * an EEPROM that has been filled with zeros.
1291                          * This in theory would disallow 64 K of legal
1292                          * addresses assigned to Xerox, but it's
1293                          * almost certain that those addresses haven't
1294                          * been used for RTL80[01]2 chips anyway.
1295                          */
1296                         if ((etheraddr[0] | etheraddr[1]) == 0 && w == 0) {
1297                                 magic--;
1298                                 break;
1299                         }
1300
1301                         etheraddr[2] = (w >> 8) & 0xff;
1302                         etheraddr[3] = w & 0xff;
1303                         magic++;
1304                         break;
1305
1306                 case 2:
1307                         etheraddr[4] = (w >> 8) & 0xff;
1308                         etheraddr[5] = w & 0xff;
1309                         magic++;
1310                         break;
1311                 }
1312         }
1313
1314         WrNib(sc, CMR2, CMR2_IRQINV);   /* back to page 0 */
1315
1316         return magic == 3;
1317 }
1318
1319 /*
1320  * Read the designated ethernet hardware address out of a 74S288
1321  * EEPROM.
1322  *
1323  * This is untested, since i haven't seen any adapter actually using
1324  * a 74S288.  In the RTL 8012, only the serial EEPROM (94C46) is
1325  * supported anymore.
1326  */
1327 static void
1328 rdp_gethwaddr_74s288(struct rdp_softc *sc, u_char *etheraddr)
1329 {
1330         int i;
1331         u_char b;
1332
1333         WrNib(sc, CMR2, CMR2_PAGE | CMR2_IRQINV); /* select page 1 */
1334
1335         for (i = 0; i < 6; i++) {
1336                 WrNib(sc, PCMR, i & 0x0f); /* lower 4 bit of addr */
1337                 WrNib(sc, PCMR + HNib, HNib + 4); /* upper 2 bit addr + /CS */
1338                 WrNib(sc, PCMR + HNib, HNib); /* latch data now */
1339                 b = RdNib(sc, PDR) & 0x0f;
1340                 b |= (RdNib(sc, PDR + HNib) & 0x0f) << 4;
1341                 etheraddr[i] = b;
1342         }
1343
1344         RdEnd(sc, PDR + HNib);
1345         WrNib(sc, CMR2, CMR2_IRQINV);   /* reselect page 0 */
1346 }
1347
1348 /*
1349  * Send nbits of data (starting with MSB) out to the 93c46 as a
1350  * command.  Assumes register page 1 has already been selected.
1351  */
1352 static void
1353 rdp_93c46_cmd(struct rdp_softc *sc, u_short data, unsigned nbits)
1354 {
1355         u_short mask = 1 << (nbits - 1);
1356         unsigned i;
1357         u_char b;
1358
1359 #if DEBUG & 2
1360         printf("rdp_93c46_cmd(): ");
1361 #endif
1362         for (i = 0; i < nbits; i++, mask >>= 1) {
1363                 b = HNib + PCMR_SK + PCMR_CS;
1364                 if (data & mask)
1365                         b += PCMR_DO;
1366 #if DEBUG & 2
1367                 printf("%d", b & 1);
1368 #endif
1369                 WrNib(sc, PCMR + HNib, b);
1370                 DELAY(1);
1371                 WrNib(sc, PCMR + HNib, b & ~PCMR_SK);
1372                 DELAY(1);
1373         }
1374 #if DEBUG & 2
1375         printf("\n");
1376 #endif
1377 }
1378
1379 /*
1380  * Read one word of data from the 93c46.  Actually, we have to read
1381  * 17 bits, and discard the very first bit.  Assumes register page 1
1382  * to be selected as well.
1383  */
1384 static u_short
1385 rdp_93c46_read(struct rdp_softc *sc)
1386 {
1387         u_short data = 0;
1388         u_char b;
1389         int i;
1390
1391 #if DEBUG & 2
1392         printf("rdp_93c46_read(): ");
1393 #endif
1394         for (i = 0; i < 17; i++) {
1395                 WrNib(sc, PCMR + HNib, PCMR_SK + PCMR_CS + HNib);
1396                 DELAY(1);
1397                 WrNib(sc, PCMR + HNib, PCMR_CS + HNib);
1398                 DELAY(1);
1399                 b = RdNib(sc, PDR);
1400                 data <<= 1;
1401                 if (b & 1)
1402                         data |= 1;
1403 #if DEBUG & 2
1404                 printf("%d", b & 1);
1405 #endif
1406                 RdEnd(sc, PDR);
1407                 DELAY(1);
1408         }
1409
1410 #if DEBUG & 2
1411         printf("\n");
1412 #endif
1413         /* end of cycle */
1414         WrNib(sc, PCMR + HNib, PCMR_SK + HNib);
1415         DELAY(1);
1416
1417         return data;
1418 }