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