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