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