23ccd403f79de10cdd379737ccea09c50d4aa6f1
[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.21 2005/11/28 17:13:43 dillon Exp $
29  */
30
31 /*
32  * Device driver for RealTek RTL 8002 (`REDP') based pocket-ethernet
33  * adapters, hooked up to a printer port.  `rdp' is a shorthand for
34  * REDP since some tools like netstat work best if the interface name
35  * has no more than three letters.
36  *
37  * Driver configuration flags so far:
38  *   flags 0x1 -- assume 74S288 EEPROM (default 94C46)
39  *   flags 0x2 -- use `slow' mode (mode 3 of the packet driver, default 0)
40  *
41  * Maybe this driver will some day also work with the successor, RTL
42  * 8012 (`AREDP'), which is unfortunately not fully register-
43  * compatible with the 8002.  The 8012 offers support for faster
44  * transfer modi like bidirectional SPP and EPP, 64 K x 4 buffer
45  * memory as opposed to 16 K x 4 for the 8002, a multicast filter, and
46  * a builtin multiplexer that allows chaining a printer behind the
47  * ethernet adapter.
48  *
49  * About the only documentation i've been able to find about the RTL
50  * 8002 was the packet driver source code at ftp.realtek.com.tw, so
51  * this driver is somewhat based on the way the packet driver handles
52  * the chip.  The exact author of the packet driver is unknown, the
53  * only name that i could find in the source was someone called Chiu,
54  * supposedly an employee of RealTek.  So credits to them for that
55  * piece of code which has proven valuable to me.
56  *
57  * Later on, Leo kuo <leo@realtek.com.tw> has been very helpful to me
58  * by sending me a readable (PDF) file documenting the RTL 8012, which
59  * helped me to also understand the 8002, as well as by providing me
60  * with the source code of the 8012 packet driver that i haven't been
61  * able to find on the FTP site.  A big Thanks! goes here to RealTek
62  * for this kind of service.
63  */
64
65 #include "use_rdp.h"
66
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/conf.h>
70 #include <sys/sockio.h>
71 #include <sys/malloc.h>
72 #include <sys/mbuf.h>
73 #include <sys/socket.h>
74 #include <sys/syslog.h>
75 #include <sys/linker_set.h>
76 #include <sys/module.h>
77 #include <sys/bus.h>
78 #include <sys/serialize.h>
79 #include <sys/thread2.h>
80
81 #include <net/ethernet.h>
82 #include <net/if.h>
83 #include <net/ifq_var.h>
84 #include <net/if_arp.h>
85 #include <net/if_dl.h>
86 #include <net/if_mib.h>
87
88 #ifdef INET
89 #include <netinet/in.h>
90 #include <netinet/if_ether.h>
91 #endif
92
93 #ifdef NS
94 #include <netns/ns.h>
95 #include <netns/ns_if.h>
96 #endif
97
98 #include <net/bpf.h>
99
100 #include <machine/clock.h>
101 #include <machine/md_var.h>
102
103 #include <bus/isa/isavar.h>
104 #include <bus/isa/i386/isa_device.h>
105 #include <i386/icu/icu.h>
106 #include "if_rdpreg.h"
107 #include <i386/isa/intr_machdep.h>
108
109 #define IOCTL_CMD_T u_long
110
111 /*
112  * Debug levels (ORed together):
113  *  != 0 - general (bad packets etc.)
114  *  2 - debug EEPROM IO
115  *  4 - debug interrupt status
116  */
117 #undef DEBUG
118 #define DEBUG 0
119
120 /*
121  * rdp_softc: per interface info and status
122  */
123 struct rdp_softc {
124         struct arpcom arpcom;   /*
125                                  * Ethernet common, always goes first so
126                                  * a rdp_softc * can be cast into an
127                                  * arpcom * or into an ifnet *.
128                                  */
129
130         /*
131          * local stuff, somewhat sorted by memory alignment class
132          */
133         u_short baseaddr;       /* IO port address */
134         u_short txsize;         /* tx size for next (buffered) packet,
135                                  * there's only one additional packet
136                                  * we can buffer, thus a single variable
137                                  * ought to be enough */
138         int txbusy;             /* tx is transmitting */
139         int txbuffered;         /* # of packets in tx buffer */
140         int slow;               /* use lpt_control to send data */
141         u_char irqenbit;        /* mirror of current Ctrl_IRQEN */
142         /*
143          * type of parameter EEPROM; device flags 0x1 selects 74S288
144          */
145         enum {
146                 EEPROM_93C46, EEPROM_74S288 /* or 82S123 */
147         } eeprom;
148 };
149
150 DECLARE_DUMMY_MODULE(if_rdp);
151
152 static struct rdp_softc rdp_softc[NRDP];
153
154 /*
155  * Since there's no fixed location in the EEPROM about where to find
156  * the ethernet hardware address, we drop a table of valid OUIs here,
157  * and search through the EEPROM until we find a possible valid
158  * Ethernet address.  Only the first 16 bits of all possible OUIs are
159  * recorded in the table (as obtained from
160  * http://standards.ieee.org/regauth/oui/oui.txt).
161  */
162
163 static u_short allowed_ouis[] = {
164         0x0000, 0x0001, 0x0002, 0x0004, 0x0005, 0x0006, 0x0007,
165         0x0008, 0x0010, 0x001C, 0x0020, 0x0040, 0x0050, 0x0060,
166         0x0070, 0x0080, 0x0090, 0x009D, 0x00A0, 0x00AA, 0x00BB,
167         0x00C0, 0x00CF, 0x00DD, 0x00E0, 0x00E6, 0x0207, 0x021C,
168         0x0260, 0x0270, 0x029D, 0x02AA, 0x02BB, 0x02C0, 0x02CF,
169         0x02E6, 0x040A, 0x04E0, 0x0800, 0x08BB, 0x1000, 0x1100,
170         0x8000, 0xAA00
171 };
172
173 /*
174  * ISA bus support.
175  */
176 static int rdp_probe            (struct isa_device *);
177 static int rdp_attach           (struct isa_device *);
178
179 /*
180  * Required entry points.
181  */
182 static void rdp_init(void *);
183 static int rdp_ioctl(struct ifnet *, IOCTL_CMD_T, caddr_t, struct ucred *);
184 static void rdp_start(struct ifnet *);
185 static void rdp_reset(struct ifnet *);
186 static void rdp_watchdog(struct ifnet *);
187 static void rdpintr(void *);
188
189 /*
190  * REDP private functions.
191  */
192
193 static void rdp_stop(struct rdp_softc *);
194 static void rdp_rint(struct rdp_softc *);
195 static void rdp_get_packet(struct rdp_softc *, unsigned);
196 static u_short rdp_write_mbufs(struct rdp_softc *, struct mbuf *);
197 static int rdp_gethwaddr_93c46(struct rdp_softc *, u_char *);
198 static void rdp_gethwaddr_74s288(struct rdp_softc *, u_char *);
199 static void rdp_93c46_cmd(struct rdp_softc *, u_short, unsigned);
200 static u_short rdp_93c46_read(struct rdp_softc *);
201
202 struct isa_driver rdpdriver = {
203         rdp_probe,
204         rdp_attach,
205         "rdp",
206         1                       /* we wanna get a chance before lptN */
207 };
208
209 /*
210  * REDP-specific functions.
211  *
212  * They are inlined, thus go first in this file.  Together with gcc's
213  * usual optimization, these functions probably come close to the
214  * packet driver's hand-optimized code. ;-)
215  *
216  * Comments are partially obtained from the packet driver as well.
217  * Some of the function names contain register names which don't make
218  * much sense for us, but i've kept them for easier reference in
219  * comparision to the packet driver.
220  *
221  * Some of the functions are currently not used by the driver; it's
222  * not quite clear whether we ever need them at all.  They are
223  * supposedly even slower than what is currently implemented as `slow'
224  * mode.  Right now, `fast' (default) mode is what the packet driver
225  * calls mode 0, slow mode is mode 3 (writing through lpt_control,
226  * reading twice).
227  *
228  * We should autoprobe the modi, as opposed to making them dependent
229  * on a kernel configuration flag.
230  */
231
232 /*
233  * read a nibble from rreg; end-of-data cmd is not issued;
234  * used for general register read.
235  *
236  * Unlike the packet driver's version, i'm shifting the result
237  * by 3 here (as opposed to within the caller's code) for clarity.
238  *  -- Joerg
239  */
240 static __inline u_char
241 RdNib(struct rdp_softc *sc, u_char rreg)
242 {
243
244         outb(sc->baseaddr + lpt_data, EOC + rreg);
245         outb(sc->baseaddr + lpt_data, RdAddr + rreg); /* write addr */
246         (void)inb(sc->baseaddr + lpt_status);
247         return (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
248 }
249
250 #if 0
251 /*
252  * read a byte from MAR register through lpt_data; the low nibble is
253  * read prior to the high one; end-of-read command is not issued; used
254  * for remote DMA in mode 4 + 5
255  */
256 static __inline u_char
257 RdByte(struct rdp_softc *sc)
258 {
259         u_char hinib, lonib;
260
261         outb(sc->baseaddr + lpt_data, RdAddr + MAR); /* cmd for low nibble */
262         lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
263         outb(sc->baseaddr + lpt_data, RdAddr + MAR + HNib);
264         hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0;
265         return hinib + lonib;
266 }
267
268
269 /*
270  * read a byte from MAR register through lpt_data; the low nibble is
271  * read prior to the high one; end-of-read command is not issued; used
272  * for remote DMA in mode 6 + 7
273  */
274 static __inline u_char
275 RdByte1(struct rdp_softc *sc)
276 {
277         u_char hinib, lonib;
278
279         outb(sc->baseaddr + lpt_data, RdAddr + MAR); /* cmd for low nibble */
280         (void)inb(sc->baseaddr + lpt_status);
281         lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
282         outb(sc->baseaddr + lpt_data, RdAddr + MAR + HNib);
283         (void)inb(sc->baseaddr + lpt_status);
284         hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0;
285         return hinib + lonib;
286 }
287 #endif
288
289
290 /*
291  * read a byte from MAR register through lpt_control; the low nibble is
292  * read prior to the high one; end-of-read command is not issued; used
293  * for remote DMA in mode 0 + 1
294  */
295 static __inline u_char
296 RdByteA1(struct rdp_softc *sc)
297 {
298         u_char hinib, lonib;
299
300         outb(sc->baseaddr + lpt_control, Ctrl_LNibRead);
301         lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
302         outb(sc->baseaddr + lpt_control, Ctrl_HNibRead);
303         hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0;
304         return hinib + lonib;
305 }
306
307
308 /*
309  * read a byte from MAR register through lpt_control; the low nibble is
310  * read prior to the high one; end-of-read command is not issued; used
311  * for remote DMA in mode 2 + 3
312  */
313 static __inline u_char
314 RdByteA2(struct rdp_softc *sc)
315 {
316         u_char hinib, lonib;
317
318         outb(sc->baseaddr + lpt_control, Ctrl_LNibRead);
319         (void)inb(sc->baseaddr + lpt_status);
320         lonib = (inb(sc->baseaddr + lpt_status) >> 3) & 0x0f;
321         outb(sc->baseaddr + lpt_control, Ctrl_HNibRead);
322         (void)inb(sc->baseaddr + lpt_status);
323         hinib = (inb(sc->baseaddr + lpt_status) << 1) & 0xf0;
324         return hinib + lonib;
325 }
326
327 /*
328  * End-of-read cmd
329  */
330 static __inline void
331 RdEnd(struct rdp_softc *sc, u_char rreg)
332 {
333
334         outb(sc->baseaddr + lpt_data, EOC + rreg);
335 }
336
337 /*
338  * Write a nibble to a register; end-of-write is issued.
339  * Used for general register write.
340  */
341 static __inline void
342 WrNib(struct rdp_softc *sc, u_char wreg, u_char wdata)
343 {
344
345         /* prepare and write address */
346         outb(sc->baseaddr + lpt_data, EOC + wreg);
347         outb(sc->baseaddr + lpt_data, WrAddr + wreg);
348         outb(sc->baseaddr + lpt_data, WrAddr + wreg);
349         /* prepare and write data */
350         outb(sc->baseaddr + lpt_data, WrAddr + wdata);
351         outb(sc->baseaddr + lpt_data, wdata);
352         outb(sc->baseaddr + lpt_data, wdata);
353         /* end-of-write */
354         outb(sc->baseaddr + lpt_data, EOC + wdata);
355 }
356
357 /*
358  * Write a byte to a register; end-of-write is issued.
359  * Used for general register write.
360  */
361 static __inline void
362 WrByte(struct rdp_softc *sc, u_char wreg, u_char wdata)
363 {
364
365         /* prepare and write address */
366         outb(sc->baseaddr + lpt_data, EOC + wreg);
367         outb(sc->baseaddr + lpt_data, WrAddr + wreg);
368         outb(sc->baseaddr + lpt_data, WrAddr + wreg);
369         /* prepare and write low nibble */
370         outb(sc->baseaddr + lpt_data, WrAddr + (wdata & 0x0F));
371         outb(sc->baseaddr + lpt_data, (wdata & 0x0F));
372         outb(sc->baseaddr + lpt_data, (wdata & 0x0F));
373         /* prepare and write high nibble */
374         wdata >>= 4;
375         outb(sc->baseaddr + lpt_data, wdata);
376         outb(sc->baseaddr + lpt_data, wdata + HNib);
377         outb(sc->baseaddr + lpt_data, wdata + HNib);
378         /* end-of-write */
379         outb(sc->baseaddr + lpt_data, EOC + wdata + HNib);
380 }
381
382 /*
383  * Write the byte to DRAM via lpt_data;
384  * used for remote DMA write in mode 0 / 2 / 4
385  */
386 static __inline void
387 WrByteALToDRAM(struct rdp_softc *sc, u_char val)
388 {
389
390         outb(sc->baseaddr + lpt_data, val & 0x0F);
391         outb(sc->baseaddr + lpt_data, MkHi(val));
392 }
393
394 /*
395  * Write the byte to DRAM via lpt_control;
396  * used for remote DMA write in mode 1 / 3 / 5
397  */
398 static __inline void
399 WrByteALToDRAMA(struct rdp_softc *sc, u_char val)
400 {
401
402         outb(sc->baseaddr + lpt_data, val & 0x0F);
403         outb(sc->baseaddr + lpt_control, Ctrl_LNibRead | sc->irqenbit);
404         outb(sc->baseaddr + lpt_data, val >> 4);
405         outb(sc->baseaddr + lpt_control, Ctrl_HNibRead | sc->irqenbit);
406 }
407
408 #if 0 /* they could be used for the RAM test */
409 /*
410  * Write the u_short to DRAM via lpt_data;
411  * used for remote DMA write in mode 0 / 2 / 4
412  */
413 static __inline void
414 WrWordbxToDRAM(struct rdp_softc *sc, u_short val)
415 {
416
417         outb(sc->baseaddr + lpt_data, val & 0x0F);
418         val >>= 4;
419         outb(sc->baseaddr + lpt_data, (val & 0x0F) + HNib);
420         val >>= 4;
421         outb(sc->baseaddr + lpt_data, val & 0x0F);
422         val >>= 4;
423         outb(sc->baseaddr + lpt_data, val + HNib);
424 }
425
426
427 /*
428  * Write the u_short to DRAM via lpt_control;
429  * used for remote DMA write in mode 1 / 3 / 5
430  */
431 static __inline void
432 WrWordbxToDRAMA(struct rdp_softc *sc, u_short val)
433 {
434
435         outb(sc->baseaddr + lpt_data, val & 0x0F);
436         outb(sc->baseaddr + lpt_control, Ctrl_LNibRead | sc->irqenbit);
437         val >>= 4;
438         outb(sc->baseaddr + lpt_data, (val & 0x0F) + HNib);
439         outb(sc->baseaddr + lpt_control, Ctrl_HNibRead | sc->irqenbit);
440         val >>= 4;
441         outb(sc->baseaddr + lpt_data, val & 0x0F);
442         outb(sc->baseaddr + lpt_control, Ctrl_LNibRead | sc->irqenbit);
443         val >>= 4;
444         outb(sc->baseaddr + lpt_data, val + HNib);
445         outb(sc->baseaddr + lpt_control, Ctrl_HNibRead | sc->irqenbit);
446 }
447 #endif
448
449
450 /*
451  * Determine if the device is present
452  *
453  *   on entry:
454  *      a pointer to an isa_device struct
455  *   on exit:
456  *      0 if device not found
457  *      or # of i/o addresses used (if found)
458  */
459 static int
460 rdp_probe(struct isa_device *isa_dev)
461 {
462         int unit = isa_dev->id_unit;
463         struct rdp_softc *sc = &rdp_softc[unit];
464         u_char b1, b2;
465         intrmask_t irqmap[3];
466         u_char sval[3];
467
468         if (unit < 0 || unit >= NRDP)
469                 return 0;
470
471         sc->baseaddr = isa_dev->id_iobase;
472         if (isa_dev->id_flags & 1)
473                 sc->eeprom = EEPROM_74S288;
474         /* else defaults to 93C46 */
475         if (isa_dev->id_flags & 2)
476                 sc->slow = 1;
477
478         /* let R/WB = A/DB = CSB = high to be ready for next r/w cycle */
479         outb(sc->baseaddr + lpt_data, 0xFF);
480         /* DIR = 0 for write mode, IRQEN=0, SLCT=INIT=AUTOFEED=STB=high */
481         outb(sc->baseaddr + lpt_control, Ctrl_SelData);
482         /* software reset */
483         WrNib(sc, CMR1 + HNib, MkHi(CMR1_RST));
484         DELAY(2000);
485         /* is EPLC alive? */
486         b1 = RdNib(sc, CMR1);
487         RdEnd(sc, CMR1);
488         b2 = RdNib(sc, CMR2) & 0x0f;
489         b2 |= RdNib(sc, CMR2 + HNib) << 4;
490         RdEnd(sc, CMR2 + HNib);
491         /*
492          * After the reset, we expect CMR1 & 7 to be 1 (rx buffer empty),
493          * and CMR2 & 0xf7 to be 0x20 (receive mode set to physical and
494          * broadcasts).
495          */
496         if (bootverbose)
497                 printf("rdp%d: CMR1 = %#x, CMR2 = %#x\n", unit, b1, b2);
498
499         if ((b1 & (CMR1_BUFE | CMR1_IRQ | CMR1_TRA)) != CMR1_BUFE
500             || (b2 & ~CMR2_IRQINV) != CMR2_AM_PB)
501                 return 0;
502
503         /*
504          * We have found something that could be a RTL 80[01]2, now
505          * see whether we can generate an interrupt.
506          */
507         cpu_disable_intr();
508
509         /*
510          * Test whether our configured IRQ is working.
511          *
512          * Set to no acception mode + IRQout, then enable RxE + TxE,
513          * then cause RBER (by advancing the read pointer although
514          * the read buffer is empty) to generate an interrupt.
515          */
516         WrByte(sc, CMR2, CMR2_IRQOUT);
517         WrNib(sc, CMR1 + HNib, MkHi(CMR1_TE | CMR1_RE));
518         WrNib(sc, CMR1, CMR1_RDPAC);
519         DELAY(1000);
520
521         irqmap[0] = isa_irq_pending();
522         sval[0] = inb(sc->baseaddr + lpt_status);
523
524         /* allow IRQs to pass the parallel interface */
525         outb(sc->baseaddr + lpt_control, Ctrl_IRQEN + Ctrl_SelData);
526         DELAY(1000);
527         /* generate interrupt */
528         WrNib(sc, IMR + HNib, MkHi(ISR_RBER));
529         DELAY(1000);
530
531         irqmap[1] = isa_irq_pending();
532         sval[1] = inb(sc->baseaddr + lpt_status);
533
534         /* de-assert and disable IRQ */
535         WrNib(sc, IMR + HNib, MkHi(0));
536         (void)inb(sc->baseaddr + lpt_status); /* might be necessary to
537                                                  clear IRQ */
538         DELAY(1000);
539         irqmap[2] = isa_irq_pending();
540         sval[2] = inb(sc->baseaddr + lpt_status);
541
542         WrNib(sc, CMR1 + HNib, MkHi(0));
543         outb(sc->baseaddr + lpt_control, Ctrl_SelData);
544         WrNib(sc, CMR2, CMR2_IRQINV);
545
546         cpu_enable_intr();
547
548         if (bootverbose)
549                 printf("rdp%d: irq maps / lpt status "
550                        "%#x/%#x - %#x/%#x - %#x/%#x (id_irq %#x)\n",
551                        unit, irqmap[0], sval[0], irqmap[1], sval[1],
552                        irqmap[2], sval[2], isa_dev->id_irq);
553
554         if ((irqmap[1] & isa_dev->id_irq) == 0) {
555                 printf("rdp%d: configured IRQ (%d) cannot be asserted "
556                        "by device",
557                        unit, ffs(isa_dev->id_irq) - 1);
558                 if (irqmap[1])
559                         printf(" (probable IRQ: %d)", ffs(irqmap[1]) - 1);
560                 printf("\n");
561                 return 0;
562         }
563
564         /*
565          * XXX should do RAMtest here
566          */
567
568         switch (sc->eeprom) {
569         case EEPROM_93C46:
570                 if (rdp_gethwaddr_93c46(sc, sc->arpcom.ac_enaddr) == 0) {
571                         printf("rdp%d: failed to find a valid hardware "
572                                "address in EEPROM\n",
573                                unit);
574                         return 0;
575                 }
576                 break;
577
578         case EEPROM_74S288:
579                 rdp_gethwaddr_74s288(sc, sc->arpcom.ac_enaddr);
580                 break;
581         }
582
583         return lpt_control + 1;
584 }
585
586 /*
587  * Install interface into kernel networking data structures
588  */
589 static int
590 rdp_attach(struct isa_device *isa_dev)
591 {
592         int unit = isa_dev->id_unit;
593         struct rdp_softc *sc = &rdp_softc[unit];
594         struct ifnet *ifp = &sc->arpcom.ac_if;
595
596         isa_dev->id_intr = (inthand2_t *)rdpintr;
597
598         /*
599          * Reset interface
600          */
601         rdp_stop(sc);
602
603         /*
604          * Initialize ifnet structure
605          */
606         ifp->if_softc = sc;
607         if_initname(ifp, "rdp", unit);
608         ifp->if_start = rdp_start;
609         ifp->if_ioctl = rdp_ioctl;
610         ifp->if_watchdog = rdp_watchdog;
611         ifp->if_init = rdp_init;
612         ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
613         ifq_set_ready(&ifp->if_snd);
614         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
615
616         /*
617          * Attach the interface
618          */
619         ether_ifattach(ifp, sc->arpcom.ac_enaddr, NULL);
620
621         /*
622          * Print additional info when attached
623          */
624         printf("%s: RealTek RTL%s pocket ethernet, EEPROM %s, %s mode\n",
625                ifp->if_xname,
626                "8002",          /* hook for 8012 */
627                sc->eeprom == EEPROM_93C46? "93C46": "74S288",
628                sc->slow? "slow": "fast");
629
630         return 1;
631 }
632
633 /*
634  * Reset interface.
635  */
636 static void
637 rdp_reset(struct ifnet *ifp)
638 {
639         struct rdp_softc *sc = ifp->if_softc;
640
641         crit_enter();
642
643         /*
644          * Stop interface and re-initialize.
645          */
646         rdp_stop(sc);
647         rdp_init(sc);
648
649         crit_exit();
650 }
651
652 /*
653  * Take interface offline.
654  */
655 static void
656 rdp_stop(struct rdp_softc *sc)
657 {
658
659         sc->txbusy = sc->txbusy = 0;
660
661         /* disable printer interface interrupts */
662         sc->irqenbit = 0;
663         outb(sc->baseaddr + lpt_control, Ctrl_SelData);
664         outb(sc->baseaddr + lpt_data, 0xff);
665
666         /* reset the RTL 8002 */
667         WrNib(sc, CMR1 + HNib, MkHi(CMR1_RST));
668         DELAY(100);
669 }
670
671 /*
672  * Device timeout/watchdog routine. Entered if the device neglects to
673  * generate an interrupt after a transmit has been started on it.
674  */
675 static void
676 rdp_watchdog(struct ifnet *ifp)
677 {
678
679         log(LOG_ERR, "%s: device timeout\n", ifp->if_xname);
680         ifp->if_oerrors++;
681
682         rdp_reset(ifp);
683 }
684
685 /*
686  * Initialize device.
687  */
688 static void
689 rdp_init(void *xsc)
690 {
691         struct rdp_softc *sc = xsc;
692         struct ifnet *ifp = &sc->arpcom.ac_if;
693         int i;
694         u_char reg;
695
696         crit_enter();
697
698         ifp->if_timer = 0;
699
700         /* program ethernet ID into the chip */
701         for (i = 0, reg = IDR0; i < 6; i++, reg++)
702                 WrByte(sc, reg, sc->arpcom.ac_enaddr[i]);
703
704         /* set accept mode */
705         WrNib(sc, CMR2 + HNib,
706               MkHi((ifp->if_flags & IFF_PROMISC)? CMR2_AM_ALL: CMR2_AM_PB));
707
708         /* enable tx and rx */
709         WrNib(sc, CMR1 + HNib, MkHi(CMR1_TE | CMR1_RE));
710
711         /* allow interrupts to happen */
712         WrNib(sc, CMR2, CMR2_IRQOUT | CMR2_IRQINV);
713         WrNib(sc, IMR, ISR_TOK | ISR_TER | ISR_ROK | ISR_RER);
714         WrNib(sc, IMR + HNib, MkHi(ISR_RBER));
715
716         /* allow IRQs to pass the parallel interface */
717         sc->irqenbit = Ctrl_IRQEN;
718         outb(sc->baseaddr + lpt_control, sc->irqenbit + Ctrl_SelData);
719
720         /* clear all flags */
721         sc->txbusy = sc->txbuffered = 0;
722
723         /*
724          * Set 'running' flag, and clear output active flag.
725          */
726         ifp->if_flags |= IFF_RUNNING;
727         ifp->if_flags &= ~IFF_OACTIVE;
728
729         /*
730          * ...and attempt to start output
731          */
732         rdp_start(ifp);
733
734         crit_exit();
735 }
736
737 /*
738  * Start output on interface.
739  * We make one assumption here:
740  *  - that the IFF_OACTIVE flag is checked before this code is called
741  *    (i.e. that the output part of the interface is idle)
742  */
743 static void
744 rdp_start(struct ifnet *ifp)
745 {
746         struct rdp_softc *sc = ifp->if_softc;
747         struct mbuf *m;
748         int len;
749
750 outloop:
751
752         /*
753          * See if there is room to put another packet in the buffer.
754          */
755         if (sc->txbuffered) {
756                 /*
757                  * No room. Indicate this to the outside world and exit.
758                  */
759                 ifp->if_flags |= IFF_OACTIVE;
760                 return;
761         }
762         m = ifq_dequeue(&ifp->if_snd, NULL);
763         if (m == NULL) {
764                 /*
765                  * We are using the !OACTIVE flag to indicate to the outside
766                  * world that we can accept an additional packet rather than
767                  * that the transmitter is _actually_ active. Indeed, the
768                  * transmitter may be active, but if we haven't filled all the
769                  * buffers with data then we still want to accept more.
770                  */
771                 ifp->if_flags &= ~IFF_OACTIVE;
772                 return;
773         }
774
775         /*
776          * Copy the mbuf chain into the transmit buffer
777          */
778
779         len = rdp_write_mbufs(sc, m);
780         if (len == 0)
781                 goto outloop;
782
783         /* ensure minimal valid ethernet length */
784         len = max(len, (ETHER_MIN_LEN-ETHER_CRC_LEN));
785
786         /*
787          * Actually start the transceiver.  Set a timeout in case the
788          * Tx interrupt never arrives.
789          */
790         if (!sc->txbusy) {
791                 WrNib(sc, TBCR1, len >> 8);
792                 WrByte(sc, TBCR0, len & 0xff);
793                 WrNib(sc, CMR1, CMR1_TRA);
794                 sc->txbusy = 1;
795                 ifp->if_timer = 2;
796         } else {
797                 sc->txbuffered = 1;
798                 sc->txsize = len;
799         }
800
801         BPF_MTAP(ifp, m);
802
803         m_freem(m);
804
805         /*
806          * Loop back to the top to possibly buffer more packets
807          */
808         goto outloop;
809 }
810
811 /*
812  * Process an ioctl request.
813  */
814 static int
815 rdp_ioctl(struct ifnet *ifp, IOCTL_CMD_T command, caddr_t data,
816           struct ucred *ur)
817 {
818         struct rdp_softc *sc = ifp->if_softc;
819         int error = 0;
820
821         crit_enter();
822
823         switch (command) {
824         case SIOCSIFFLAGS:
825                 /*
826                  * If the interface is marked up and stopped, then start it.
827                  * If it is marked down and running, then stop it.
828                  */
829                 if (ifp->if_flags & IFF_UP) {
830                         if ((ifp->if_flags & IFF_RUNNING) == 0)
831                                 rdp_init(sc);
832                 } else {
833                         if (ifp->if_flags & IFF_RUNNING) {
834                                 rdp_stop(sc);
835                                 ifp->if_flags &= ~IFF_RUNNING;
836                         }
837                 }
838
839                 /*
840                  * Promiscuous flag may have changed, propagage this
841                  * to the NIC.
842                  */
843                 if (ifp->if_flags & IFF_UP)
844                         WrNib(sc, CMR2 + HNib,
845                               MkHi((ifp->if_flags & IFF_PROMISC)?
846                                    CMR2_AM_ALL: CMR2_AM_PB));
847
848                 break;
849
850         case SIOCADDMULTI:
851         case SIOCDELMULTI:
852                 /*
853                  * Multicast list has changed; we don't support it.
854                  */
855                 error = ENOTTY;
856                 break;
857
858         default:
859                 error = ether_ioctl(ifp, command, data);
860                 break;
861         }
862
863         crit_exit();
864
865         return (error);
866 }
867
868 /*
869  * External interrupt service routine.
870  */
871 void 
872 rdpintr(void *arg)
873 {
874         int unit = (int)arg;
875         struct rdp_softc *sc = rdp_softc + unit;
876         struct ifnet *ifp = (struct ifnet *)sc;
877         u_char isr, tsr, rsr, colls;
878
879         lwkt_serialize_enter(ifp->if_serializer);
880
881         /* disable interrupts, so SD3 can be routed to the pin */
882         sc->irqenbit = 0;
883         outb(sc->baseaddr + lpt_control, Ctrl_SelData);
884         WrNib(sc, CMR2, CMR2_IRQINV);
885         /*
886          * loop until there are no more new interrupts
887          */
888         for (;;) {
889                 isr = RdNib(sc, ISR);
890                 isr |= RdNib(sc, ISR + HNib) << 4;
891                 RdEnd(sc, ISR + HNib);
892
893                 if (isr == 0)
894                         break;
895 #if DEBUG & 4
896                 printf("rdp%d: ISR = %#x\n", unit, isr);
897 #endif
898
899                 /*
900                  * Clear the pending interrupt bits.
901                  */
902                 WrNib(sc, ISR, isr & 0x0f);
903                 if (isr & 0xf0)
904                         WrNib(sc, ISR + HNib, MkHi(isr));
905
906                 /*
907                  * Handle transmitter interrupts.
908                  */
909                 if (isr & (ISR_TOK | ISR_TER)) {
910                         tsr = RdNib(sc, TSR);
911                         RdEnd(sc, TSR);
912 #if DEBUG & 4
913                         if (isr & ISR_TER)
914                                 printf("rdp%d: tsr %#x\n", unit, tsr);
915 #endif
916                         if (tsr & TSR_TABT)
917                                 ifp->if_oerrors++;
918                         else
919                                 /*
920                                  * Update total number of successfully
921                                  * transmitted packets.
922                                  */
923                                 ifp->if_opackets++;
924
925                         if (tsr & TSR_COL) {
926                                 colls = RdNib(sc, COLR);
927                                 RdEnd(sc, COLR);
928                                 ifp->if_collisions += colls;
929                         }
930
931                         /*
932                          * reset tx busy and output active flags
933                          */
934                         sc->txbusy = 0;
935                         ifp->if_flags &= ~IFF_OACTIVE;
936
937                         /*
938                          * If we had already queued up another packet,
939                          * start sending it now.
940                          */
941                         if (sc->txbuffered) {
942                                 WrNib(sc, TBCR1, sc->txsize >> 8);
943                                 WrByte(sc, TBCR0, sc->txsize & 0xff);
944                                 WrNib(sc, CMR1, CMR1_TRA);
945                                 sc->txbusy = 1;
946                                 sc->txbuffered = 0;
947                                 ifp->if_timer = 2;
948                         } else {
949                                 /*
950                                  * clear watchdog timer
951                                  */
952                                 ifp->if_timer = 0;
953                         }
954                         
955                 }
956
957                 /*
958                  * Handle receiver interrupts
959                  */
960                 if (isr & (ISR_ROK | ISR_RER | ISR_RBER)) {
961                         rsr = RdNib(sc, RSR);
962                         rsr |= RdNib(sc, RSR + HNib) << 4;
963                         RdEnd(sc, RSR + HNib);
964 #if DEBUG & 4
965                         if (isr & (ISR_RER | ISR_RBER))
966                                 printf("rdp%d: rsr %#x\n", unit, rsr);
967 #endif
968
969                         if (rsr & (RSR_PUN | RSR_POV)) {
970                                 printf("rdp%d: rsr %#x, resetting\n",
971                                        unit, rsr);
972                                 rdp_reset(ifp);
973                                 break;
974                         }
975
976                         if (rsr & RSR_BUFO)
977                                 /*
978                                  * CRC and FA errors are recorded in
979                                  * rdp_rint() on a per-packet basis
980                                  */
981                                 ifp->if_ierrors++;
982                         if (isr & (ISR_ROK | ISR_RER))
983                                 rdp_rint(sc);
984                 }
985
986                 /*
987                  * If it looks like the transmitter can take more data,
988                  * attempt to start output on the interface. This is done
989                  * after handling the receiver to give the receiver priority.
990                  */
991                 if ((ifp->if_flags & IFF_OACTIVE) == 0)
992                         rdp_start(ifp);
993
994         }
995         /* re-enable interrupts */
996         WrNib(sc, CMR2, CMR2_IRQOUT | CMR2_IRQINV);
997         sc->irqenbit = Ctrl_IRQEN;
998         outb(sc->baseaddr + lpt_control, Ctrl_SelData + sc->irqenbit);
999         lwkt_serialize_exit(ifp->if_serializer);
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 }