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