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