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