xref: /freebsd/sys/dev/sbni/if_sbni.c (revision c98323078dede7579020518ec84cdcb478e5c142)
1 /*
2  * Copyright (c) 1997-2001 Granch, Ltd. All rights reserved.
3  * Author: Denis I.Timofeev <timofeev@granch.ru>
4  *
5  * Redistributon 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 NEIGENCE 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  */
28 
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31 
32 /*
33  * Device driver for Granch SBNI12 leased line adapters
34  *
35  * Revision 2.0.0  1997/08/06
36  * Initial revision by Alexey Zverev
37  *
38  * Revision 2.0.1 1997/08/11
39  * Additional internal statistics support (tx statistics)
40  *
41  * Revision 2.0.2 1997/11/05
42  * if_bpf bug has been fixed
43  *
44  * Revision 2.0.3 1998/12/20
45  * Memory leakage has been eliminated in
46  * the sbni_st and sbni_timeout routines.
47  *
48  * Revision 3.0 2000/08/10 by Yaroslav Polyakov
49  * Support for PCI cards. 4.1 modification.
50  *
51  * Revision 3.1 2000/09/12
52  * Removed extra #defines around bpf functions
53  *
54  * Revision 4.0 2000/11/23 by Denis Timofeev
55  * Completely redesigned the buffer management
56  *
57  * Revision 4.1 2001/01/21
58  * Support for PCI Dual cards and new SBNI12D-10, -11 Dual/ISA cards
59  *
60  * Written with reference to NE2000 driver developed by David Greenman.
61  */
62 
63 
64 #include <sys/param.h>
65 #include <sys/systm.h>
66 #include <sys/socket.h>
67 #include <sys/sockio.h>
68 #include <sys/mbuf.h>
69 #include <sys/kernel.h>
70 #include <sys/proc.h>
71 #include <sys/callout.h>
72 #include <sys/syslog.h>
73 #include <sys/random.h>
74 
75 #include <machine/bus.h>
76 #include <sys/rman.h>
77 #include <machine/resource.h>
78 
79 #include <net/if.h>
80 #include <net/ethernet.h>
81 #include <net/if_arp.h>
82 #include <net/bpf.h>
83 
84 #include <dev/sbni/if_sbnireg.h>
85 #include <dev/sbni/if_sbnivar.h>
86 
87 #define ASM_CRC 1
88 
89 static void	sbni_init(void *);
90 static void	sbni_start(struct ifnet *);
91 static int	sbni_ioctl(struct ifnet *, u_long, caddr_t);
92 static void	sbni_watchdog(struct ifnet *);
93 static void	sbni_stop(struct sbni_softc *);
94 static void	handle_channel(struct sbni_softc *);
95 
96 static void	card_start(struct sbni_softc *);
97 static int	recv_frame(struct sbni_softc *);
98 static void	send_frame(struct sbni_softc *);
99 static int	upload_data(struct sbni_softc *, u_int, u_int, u_int, u_int32_t);
100 static int	skip_tail(struct sbni_softc *, u_int, u_int32_t);
101 static void	interpret_ack(struct sbni_softc *, u_int);
102 static void	download_data(struct sbni_softc *, u_int32_t *);
103 static void	prepare_to_send(struct sbni_softc *);
104 static void	drop_xmit_queue(struct sbni_softc *);
105 static int	get_rx_buf(struct sbni_softc *);
106 static void	indicate_pkt(struct sbni_softc *);
107 static void	change_level(struct sbni_softc *);
108 static int	check_fhdr(struct sbni_softc *, u_int *, u_int *,
109 			   u_int *, u_int *, u_int32_t *);
110 static int	append_frame_to_pkt(struct sbni_softc *, u_int, u_int32_t);
111 static void	timeout_change_level(struct sbni_softc *);
112 static void	send_frame_header(struct sbni_softc *, u_int32_t *);
113 static void	set_initial_values(struct sbni_softc *, struct sbni_flags);
114 
115 static u_int32_t	calc_crc32(u_int32_t, caddr_t, u_int);
116 static timeout_t	sbni_timeout;
117 
118 static __inline u_char	sbni_inb(struct sbni_softc *, enum sbni_reg);
119 static __inline void	sbni_outb(struct sbni_softc *, enum sbni_reg, u_char);
120 static __inline void	sbni_insb(struct sbni_softc *, u_char *, u_int);
121 static __inline void	sbni_outsb(struct sbni_softc *, u_char *, u_int);
122 
123 static u_int32_t crc32tab[];
124 
125 #ifdef SBNI_DUAL_COMPOUND
126 struct sbni_softc *sbni_headlist;
127 #endif
128 
129 u_int32_t next_sbni_unit;
130 
131 /* -------------------------------------------------------------------------- */
132 
133 static __inline u_char
134 sbni_inb(struct sbni_softc *sc, enum sbni_reg reg)
135 {
136 	return bus_space_read_1(
137 	    rman_get_bustag(sc->io_res),
138 	    rman_get_bushandle(sc->io_res),
139 	    sc->io_off + reg);
140 }
141 
142 static __inline void
143 sbni_outb(struct sbni_softc *sc, enum sbni_reg reg, u_char value)
144 {
145 	bus_space_write_1(
146 	    rman_get_bustag(sc->io_res),
147 	    rman_get_bushandle(sc->io_res),
148 	    sc->io_off + reg, value);
149 }
150 
151 static __inline void
152 sbni_insb(struct sbni_softc *sc, u_char *to, u_int len)
153 {
154 	bus_space_read_multi_1(
155 	    rman_get_bustag(sc->io_res),
156 	    rman_get_bushandle(sc->io_res),
157 	    sc->io_off + DAT, to, len);
158 }
159 
160 static __inline void
161 sbni_outsb(struct sbni_softc *sc, u_char *from, u_int len)
162 {
163 	bus_space_write_multi_1(
164 	    rman_get_bustag(sc->io_res),
165 	    rman_get_bushandle(sc->io_res),
166 	    sc->io_off + DAT, from, len);
167 }
168 
169 
170 /*
171 	Valid combinations in CSR0 (for probing):
172 
173 	VALID_DECODER	0000,0011,1011,1010
174 
175 				    	; 0   ; -
176 				TR_REQ	; 1   ; +
177 			TR_RDY	    	; 2   ; -
178 			TR_RDY	TR_REQ	; 3   ; +
179 		BU_EMP		    	; 4   ; +
180 		BU_EMP	     	TR_REQ	; 5   ; +
181 		BU_EMP	TR_RDY	    	; 6   ; -
182 		BU_EMP	TR_RDY	TR_REQ	; 7   ; +
183 	RC_RDY 		     		; 8   ; +
184 	RC_RDY			TR_REQ	; 9   ; +
185 	RC_RDY		TR_RDY		; 10  ; -
186 	RC_RDY		TR_RDY	TR_REQ	; 11  ; -
187 	RC_RDY	BU_EMP			; 12  ; -
188 	RC_RDY	BU_EMP		TR_REQ	; 13  ; -
189 	RC_RDY	BU_EMP	TR_RDY		; 14  ; -
190 	RC_RDY	BU_EMP	TR_RDY	TR_REQ	; 15  ; -
191 */
192 
193 #define VALID_DECODER	(2 + 8 + 0x10 + 0x20 + 0x80 + 0x100 + 0x200)
194 
195 
196 int
197 sbni_probe(struct sbni_softc *sc)
198 {
199 	u_char csr0;
200 
201 	csr0 = sbni_inb(sc, CSR0);
202 	if (csr0 != 0xff && csr0 != 0x00) {
203 		csr0 &= ~EN_INT;
204 		if (csr0 & BU_EMP)
205 			csr0 |= EN_INT;
206 
207 		if (VALID_DECODER & (1 << (csr0 >> 4)))
208 			return (0);
209 	}
210 
211 	return (ENXIO);
212 }
213 
214 
215 /*
216  * Install interface into kernel networking data structures
217  */
218 void
219 sbni_attach(struct sbni_softc *sc, int unit, struct sbni_flags flags)
220 {
221 	struct ifnet *ifp;
222 	u_char csr0;
223 
224 	ifp = &sc->arpcom.ac_if;
225 	sbni_outb(sc, CSR0, 0);
226 	set_initial_values(sc, flags);
227 
228 	callout_handle_init(&sc->wch);
229 	/* Initialize ifnet structure */
230 	ifp->if_softc	= sc;
231 	if_initname(ifp, "sbni", unit);
232 	ifp->if_init	= sbni_init;
233 	ifp->if_start	= sbni_start;
234 	ifp->if_ioctl	= sbni_ioctl;
235 	ifp->if_watchdog	= sbni_watchdog;
236 	ifp->if_snd.ifq_maxlen	= IFQ_MAXLEN;
237 
238 	/* report real baud rate */
239 	csr0 = sbni_inb(sc, CSR0);
240 	ifp->if_baudrate =
241 		(csr0 & 0x01 ? 500000 : 2000000) / (1 << flags.rate);
242 
243 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
244 	ether_ifattach(ifp, sc->arpcom.ac_enaddr);
245 	/* device attach does transition from UNCONFIGURED to IDLE state */
246 
247 	if_printf(ifp, "speed %ld, rxl ", ifp->if_baudrate);
248 	if (sc->delta_rxl)
249 		printf("auto\n");
250 	else
251 		printf("%d (fixed)\n", sc->cur_rxl_index);
252 }
253 
254 /* -------------------------------------------------------------------------- */
255 
256 static void
257 sbni_init(void *xsc)
258 {
259 	struct sbni_softc *sc;
260 	struct ifnet *ifp;
261 	int  s;
262 
263 	sc = (struct sbni_softc *)xsc;
264 	ifp = &sc->arpcom.ac_if;
265 
266 	/*
267 	 * kludge to avoid multiple initialization when more than once
268 	 * protocols configured
269 	 */
270 	if (ifp->if_flags & IFF_RUNNING)
271 		return;
272 
273 	s = splimp();
274 	ifp->if_timer = 0;
275 	card_start(sc);
276 	sc->wch = timeout(sbni_timeout, sc, hz/SBNI_HZ);
277 
278 	ifp->if_flags |= IFF_RUNNING;
279 	ifp->if_flags &= ~IFF_OACTIVE;
280 
281 	/* attempt to start output */
282 	sbni_start(ifp);
283 	splx(s);
284 }
285 
286 
287 static void
288 sbni_start(struct ifnet *ifp)
289 {
290 	struct sbni_softc *sc = ifp->if_softc;
291 	if (sc->tx_frameno == 0)
292 		prepare_to_send(sc);
293 }
294 
295 
296 static void
297 sbni_stop(struct sbni_softc *sc)
298 {
299 	sbni_outb(sc, CSR0, 0);
300 	drop_xmit_queue(sc);
301 
302 	if (sc->rx_buf_p) {
303 		m_freem(sc->rx_buf_p);
304 		sc->rx_buf_p = NULL;
305 	}
306 
307 	untimeout(sbni_timeout, sc, sc->wch);
308 	sc->wch.callout = NULL;
309 }
310 
311 /* -------------------------------------------------------------------------- */
312 
313 /* interrupt handler */
314 
315 /*
316  * 	SBNI12D-10, -11/ISA boards within "common interrupt" mode could not
317  * be looked as two independent single-channel devices. Every channel seems
318  * as Ethernet interface but interrupt handler must be common. Really, first
319  * channel ("master") driver only registers the handler. In it's struct softc
320  * it has got pointer to "slave" channel's struct softc and handles that's
321  * interrupts too.
322  *	softc of successfully attached ISA SBNI boards is linked to list.
323  * While next board driver is initialized, it scans this list. If one
324  * has found softc with same irq and ioaddr different by 4 then it assumes
325  * this board to be "master".
326  */
327 
328 void
329 sbni_intr(void *arg)
330 {
331 	struct sbni_softc *sc;
332 	int repeat;
333 
334 	sc = (struct sbni_softc *)arg;
335 
336 	do {
337 		repeat = 0;
338 		if (sbni_inb(sc, CSR0) & (RC_RDY | TR_RDY)) {
339 			handle_channel(sc);
340 			repeat = 1;
341 		}
342 		if (sc->slave_sc && 	/* second channel present */
343 		    (sbni_inb(sc->slave_sc, CSR0) & (RC_RDY | TR_RDY))) {
344 			handle_channel(sc->slave_sc);
345 			repeat = 1;
346 		}
347 	} while (repeat);
348 }
349 
350 
351 static void
352 handle_channel(struct sbni_softc *sc)
353 {
354 	int req_ans;
355 	u_char csr0;
356 
357 	sbni_outb(sc, CSR0, (sbni_inb(sc, CSR0) & ~EN_INT) | TR_REQ);
358 
359 	sc->timer_ticks = CHANGE_LEVEL_START_TICKS;
360 	for (;;) {
361 		csr0 = sbni_inb(sc, CSR0);
362 		if ((csr0 & (RC_RDY | TR_RDY)) == 0)
363 			break;
364 
365 		req_ans = !(sc->state & FL_PREV_OK);
366 
367 		if (csr0 & RC_RDY)
368 			req_ans = recv_frame(sc);
369 
370 		/*
371 		 * TR_RDY always equals 1 here because we have owned the marker,
372 		 * and we set TR_REQ when disabled interrupts
373 		 */
374 		csr0 = sbni_inb(sc, CSR0);
375 		if ((csr0 & TR_RDY) == 0 || (csr0 & RC_RDY) != 0)
376 			printf("sbni: internal error!\n");
377 
378 		/* if state & FL_NEED_RESEND != 0 then tx_frameno != 0 */
379 		if (req_ans || sc->tx_frameno != 0)
380 			send_frame(sc);
381 		else {
382 			/* send the marker without any data */
383 			sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) & ~TR_REQ);
384 		}
385 	}
386 
387 	sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) | EN_INT);
388 }
389 
390 
391 /*
392  * Routine returns 1 if it need to acknoweledge received frame.
393  * Empty frame received without errors won't be acknoweledged.
394  */
395 
396 static int
397 recv_frame(struct sbni_softc *sc)
398 {
399 	u_int32_t crc;
400 	u_int framelen, frameno, ack;
401 	u_int is_first, frame_ok;
402 
403 	crc = CRC32_INITIAL;
404 	if (check_fhdr(sc, &framelen, &frameno, &ack, &is_first, &crc)) {
405 		frame_ok = framelen > 4 ?
406 		    upload_data(sc, framelen, frameno, is_first, crc) :
407 		    skip_tail(sc, framelen, crc);
408 		if (frame_ok)
409 			interpret_ack(sc, ack);
410 	} else
411 		frame_ok = 0;
412 
413 	sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) ^ CT_ZER);
414 	if (frame_ok) {
415 		sc->state |= FL_PREV_OK;
416 		if (framelen > 4)
417 			sc->in_stats.all_rx_number++;
418 	} else {
419 		sc->state &= ~FL_PREV_OK;
420 		change_level(sc);
421 		sc->in_stats.all_rx_number++;
422 		sc->in_stats.bad_rx_number++;
423 	}
424 
425 	return (!frame_ok || framelen > 4);
426 }
427 
428 
429 static void
430 send_frame(struct sbni_softc *sc)
431 {
432 	u_int32_t crc;
433 	u_char csr0;
434 
435 	crc = CRC32_INITIAL;
436 	if (sc->state & FL_NEED_RESEND) {
437 
438 		/* if frame was sended but not ACK'ed - resend it */
439 		if (sc->trans_errors) {
440 			sc->trans_errors--;
441 			if (sc->framelen != 0)
442 				sc->in_stats.resend_tx_number++;
443 		} else {
444 			/* cannot xmit with many attempts */
445 			drop_xmit_queue(sc);
446 			goto do_send;
447 		}
448 	} else
449 		sc->trans_errors = TR_ERROR_COUNT;
450 
451 	send_frame_header(sc, &crc);
452 	sc->state |= FL_NEED_RESEND;
453 	/*
454 	 * FL_NEED_RESEND will be cleared after ACK, but if empty
455 	 * frame sended then in prepare_to_send next frame
456 	 */
457 
458 
459 	if (sc->framelen) {
460 		download_data(sc, &crc);
461 		sc->in_stats.all_tx_number++;
462 		sc->state |= FL_WAIT_ACK;
463 	}
464 
465 	sbni_outsb(sc, (u_char *)&crc, sizeof crc);
466 
467 do_send:
468 	csr0 = sbni_inb(sc, CSR0);
469 	sbni_outb(sc, CSR0, csr0 & ~TR_REQ);
470 
471 	if (sc->tx_frameno) {
472 		/* next frame exists - request to send */
473 		sbni_outb(sc, CSR0, csr0 | TR_REQ);
474 	}
475 }
476 
477 
478 static void
479 download_data(struct sbni_softc *sc, u_int32_t *crc_p)
480 {
481 	struct mbuf *m;
482 	caddr_t	data_p;
483 	u_int data_len, pos, slice;
484 
485 	data_p = NULL;		/* initialized to avoid warn */
486 	pos = 0;
487 
488 	for (m = sc->tx_buf_p;  m != NULL && pos < sc->pktlen;  m = m->m_next) {
489 		if (pos + m->m_len > sc->outpos) {
490 			data_len = m->m_len - (sc->outpos - pos);
491 			data_p = mtod(m, caddr_t) + (sc->outpos - pos);
492 
493 			goto do_copy;
494 		} else
495 			pos += m->m_len;
496 	}
497 
498 	data_len = 0;
499 
500 do_copy:
501 	pos = 0;
502 	do {
503 		if (data_len) {
504 			slice = min(data_len, sc->framelen - pos);
505 			sbni_outsb(sc, data_p, slice);
506 			*crc_p = calc_crc32(*crc_p, data_p, slice);
507 
508 			pos += slice;
509 			if (data_len -= slice)
510 				data_p += slice;
511 			else {
512 				do {
513 					m = m->m_next;
514 				} while (m != NULL && m->m_len == 0);
515 
516 				if (m) {
517 					data_len = m->m_len;
518 					data_p = mtod(m, caddr_t);
519 				}
520 			}
521 		} else {
522 			/* frame too short - zero padding */
523 
524 			pos = sc->framelen - pos;
525 			while (pos--) {
526 				sbni_outb(sc, DAT, 0);
527 				*crc_p = CRC32(0, *crc_p);
528 			}
529 			return;
530 		}
531 	} while (pos < sc->framelen);
532 }
533 
534 
535 static int
536 upload_data(struct sbni_softc *sc, u_int framelen, u_int frameno,
537 	    u_int is_first, u_int32_t crc)
538 {
539 	int frame_ok;
540 
541 	if (is_first) {
542 		sc->wait_frameno = frameno;
543 		sc->inppos = 0;
544 	}
545 
546 	if (sc->wait_frameno == frameno) {
547 
548 		if (sc->inppos + framelen  <=  ETHER_MAX_LEN) {
549 			frame_ok = append_frame_to_pkt(sc, framelen, crc);
550 
551 		/*
552 		 * if CRC is right but framelen incorrect then transmitter
553 		 * error was occured... drop entire packet
554 		 */
555 		} else if ((frame_ok = skip_tail(sc, framelen, crc)) != 0) {
556 			sc->wait_frameno = 0;
557 			sc->inppos = 0;
558 			sc->arpcom.ac_if.if_ierrors++;
559 			/* now skip all frames until is_first != 0 */
560 		}
561 	} else
562 		frame_ok = skip_tail(sc, framelen, crc);
563 
564 	if (is_first && !frame_ok) {
565 		/*
566 		 * Frame has been violated, but we have stored
567 		 * is_first already... Drop entire packet.
568 		 */
569 		sc->wait_frameno = 0;
570 		sc->arpcom.ac_if.if_ierrors++;
571 	}
572 
573 	return (frame_ok);
574 }
575 
576 
577 static __inline void	send_complete(struct sbni_softc *);
578 
579 static __inline void
580 send_complete(struct sbni_softc *sc)
581 {
582 	m_freem(sc->tx_buf_p);
583 	sc->tx_buf_p = NULL;
584 	sc->arpcom.ac_if.if_opackets++;
585 }
586 
587 
588 static void
589 interpret_ack(struct sbni_softc *sc, u_int ack)
590 {
591 	if (ack == FRAME_SENT_OK) {
592 		sc->state &= ~FL_NEED_RESEND;
593 
594 		if (sc->state & FL_WAIT_ACK) {
595 			sc->outpos += sc->framelen;
596 
597 			if (--sc->tx_frameno) {
598 				sc->framelen = min(
599 				    sc->maxframe, sc->pktlen - sc->outpos);
600 			} else {
601 				send_complete(sc);
602 				prepare_to_send(sc);
603 			}
604 		}
605 	}
606 
607 	sc->state &= ~FL_WAIT_ACK;
608 }
609 
610 
611 /*
612  * Glue received frame with previous fragments of packet.
613  * Indicate packet when last frame would be accepted.
614  */
615 
616 static int
617 append_frame_to_pkt(struct sbni_softc *sc, u_int framelen, u_int32_t crc)
618 {
619 	caddr_t p;
620 
621 	if (sc->inppos + framelen > ETHER_MAX_LEN)
622 		return (0);
623 
624 	if (!sc->rx_buf_p && !get_rx_buf(sc))
625 		return (0);
626 
627 	p = sc->rx_buf_p->m_data + sc->inppos;
628 	sbni_insb(sc, p, framelen);
629 	if (calc_crc32(crc, p, framelen) != CRC32_REMAINDER)
630 		return (0);
631 
632 	sc->inppos += framelen - 4;
633 	if (--sc->wait_frameno == 0) {		/* last frame received */
634 		indicate_pkt(sc);
635 		sc->arpcom.ac_if.if_ipackets++;
636 	}
637 
638 	return (1);
639 }
640 
641 
642 /*
643  * Prepare to start output on adapter. Current priority must be set to splimp
644  * before this routine is called.
645  * Transmitter will be actually activated when marker has been accepted.
646  */
647 
648 static void
649 prepare_to_send(struct sbni_softc *sc)
650 {
651 	struct mbuf *m;
652 	u_int len;
653 
654 	/* sc->tx_buf_p == NULL here! */
655 	if (sc->tx_buf_p)
656 		printf("sbni: memory leak!\n");
657 
658 	sc->outpos = 0;
659 	sc->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
660 
661 	for (;;) {
662 		IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, sc->tx_buf_p);
663 		if (!sc->tx_buf_p) {
664 			/* nothing to transmit... */
665 			sc->pktlen     = 0;
666 			sc->tx_frameno = 0;
667 			sc->framelen   = 0;
668 			sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
669 			return;
670 		}
671 
672 		for (len = 0, m = sc->tx_buf_p;  m;  m = m->m_next)
673 			len += m->m_len;
674 
675 		if (len != 0)
676 			break;
677 		m_freem(sc->tx_buf_p);
678 	}
679 
680 	if (len < SBNI_MIN_LEN)
681 		len = SBNI_MIN_LEN;
682 
683 	sc->pktlen	= len;
684 	sc->tx_frameno	= (len + sc->maxframe - 1) / sc->maxframe;
685 	sc->framelen	= min(len, sc->maxframe);
686 
687 	sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) | TR_REQ);
688 	sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
689 	BPF_MTAP(&sc->arpcom.ac_if, sc->tx_buf_p);
690 }
691 
692 
693 static void
694 drop_xmit_queue(struct sbni_softc *sc)
695 {
696 	struct mbuf *m;
697 
698 	if (sc->tx_buf_p) {
699 		m_freem(sc->tx_buf_p);
700 		sc->tx_buf_p = NULL;
701 		sc->arpcom.ac_if.if_oerrors++;
702 	}
703 
704 	for (;;) {
705 		IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
706 		if (m == NULL)
707 			break;
708 		m_freem(m);
709 		sc->arpcom.ac_if.if_oerrors++;
710 	}
711 
712 	sc->tx_frameno	= 0;
713 	sc->framelen	= 0;
714 	sc->outpos	= 0;
715 	sc->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
716 	sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
717 }
718 
719 
720 static void
721 send_frame_header(struct sbni_softc *sc, u_int32_t *crc_p)
722 {
723 	u_int32_t crc;
724 	u_int len_field;
725 	u_char value;
726 
727 	crc = *crc_p;
728 	len_field = sc->framelen + 6;	/* CRC + frameno + reserved */
729 
730 	if (sc->state & FL_NEED_RESEND)
731 		len_field |= FRAME_RETRY;	/* non-first attempt... */
732 
733 	if (sc->outpos == 0)
734 		len_field |= FRAME_FIRST;
735 
736 	len_field |= (sc->state & FL_PREV_OK) ? FRAME_SENT_OK : FRAME_SENT_BAD;
737 	sbni_outb(sc, DAT, SBNI_SIG);
738 
739 	value = (u_char)len_field;
740 	sbni_outb(sc, DAT, value);
741 	crc = CRC32(value, crc);
742 	value = (u_char)(len_field >> 8);
743 	sbni_outb(sc, DAT, value);
744 	crc = CRC32(value, crc);
745 
746 	sbni_outb(sc, DAT, sc->tx_frameno);
747 	crc = CRC32(sc->tx_frameno, crc);
748 	sbni_outb(sc, DAT, 0);
749 	crc = CRC32(0, crc);
750 	*crc_p = crc;
751 }
752 
753 
754 /*
755  * if frame tail not needed (incorrect number or received twice),
756  * it won't store, but CRC will be calculated
757  */
758 
759 static int
760 skip_tail(struct sbni_softc *sc, u_int tail_len, u_int32_t crc)
761 {
762 	while (tail_len--)
763 		crc = CRC32(sbni_inb(sc, DAT), crc);
764 
765 	return (crc == CRC32_REMAINDER);
766 }
767 
768 
769 static int
770 check_fhdr(struct sbni_softc *sc, u_int *framelen, u_int *frameno,
771 	   u_int *ack, u_int *is_first, u_int32_t *crc_p)
772 {
773 	u_int32_t crc;
774 	u_char value;
775 
776 	crc = *crc_p;
777 	if (sbni_inb(sc, DAT) != SBNI_SIG)
778 		return (0);
779 
780 	value = sbni_inb(sc, DAT);
781 	*framelen = (u_int)value;
782 	crc = CRC32(value, crc);
783 	value = sbni_inb(sc, DAT);
784 	*framelen |= ((u_int)value) << 8;
785 	crc = CRC32(value, crc);
786 
787 	*ack = *framelen & FRAME_ACK_MASK;
788 	*is_first = (*framelen & FRAME_FIRST) != 0;
789 
790 	if ((*framelen &= FRAME_LEN_MASK) < 6 || *framelen > SBNI_MAX_FRAME - 3)
791 		return (0);
792 
793 	value = sbni_inb(sc, DAT);
794 	*frameno = (u_int)value;
795 	crc = CRC32(value, crc);
796 
797 	crc = CRC32(sbni_inb(sc, DAT), crc);		/* reserved byte */
798 	*framelen -= 2;
799 
800 	*crc_p = crc;
801 	return (1);
802 }
803 
804 
805 static int
806 get_rx_buf(struct sbni_softc *sc)
807 {
808 	struct mbuf *m;
809 
810 	MGETHDR(m, M_DONTWAIT, MT_DATA);
811 	if (m == NULL) {
812 		if_printf(&sc->arpcom.ac_if, "cannot allocate header mbuf\n");
813 		return (0);
814 	}
815 
816 	/*
817 	 * We always put the received packet in a single buffer -
818 	 * either with just an mbuf header or in a cluster attached
819 	 * to the header. The +2 is to compensate for the alignment
820 	 * fixup below.
821 	 */
822 	if (ETHER_MAX_LEN + 2 > MHLEN) {
823 		/* Attach an mbuf cluster */
824 		MCLGET(m, M_DONTWAIT);
825 		if ((m->m_flags & M_EXT) == 0) {
826 			m_freem(m);
827 			return (0);
828 		}
829 	}
830 	m->m_pkthdr.len = m->m_len = ETHER_MAX_LEN + 2;
831 
832 	/*
833 	 * The +2 is to longword align the start of the real packet.
834 	 * (sizeof ether_header == 14)
835 	 * This is important for NFS.
836 	 */
837 	m_adj(m, 2);
838 	sc->rx_buf_p = m;
839 	return (1);
840 }
841 
842 
843 static void
844 indicate_pkt(struct sbni_softc *sc)
845 {
846 	struct ifnet *ifp = &sc->arpcom.ac_if;
847 	struct mbuf *m;
848 
849 	m = sc->rx_buf_p;
850 	m->m_pkthdr.rcvif = ifp;
851 	m->m_pkthdr.len   = m->m_len = sc->inppos;
852 
853 	(*ifp->if_input)(ifp, m);
854 	sc->rx_buf_p = NULL;
855 }
856 
857 /* -------------------------------------------------------------------------- */
858 
859 /*
860  * Routine checks periodically wire activity and regenerates marker if
861  * connect was inactive for a long time.
862  */
863 
864 static void
865 sbni_timeout(void *xsc)
866 {
867 	struct sbni_softc *sc;
868 	int s;
869 	u_char csr0;
870 
871 	sc = (struct sbni_softc *)xsc;
872 	s = splimp();
873 
874 	csr0 = sbni_inb(sc, CSR0);
875 	if (csr0 & RC_CHK) {
876 
877 		if (sc->timer_ticks) {
878 			if (csr0 & (RC_RDY | BU_EMP))
879 				/* receiving not active */
880 				sc->timer_ticks--;
881 		} else {
882 			sc->in_stats.timeout_number++;
883 			if (sc->delta_rxl)
884 				timeout_change_level(sc);
885 
886 			sbni_outb(sc, CSR1, *(u_char *)&sc->csr1 | PR_RES);
887 			csr0 = sbni_inb(sc, CSR0);
888 		}
889 	}
890 
891 	sbni_outb(sc, CSR0, csr0 | RC_CHK);
892 	sc->wch = timeout(sbni_timeout, sc, hz/SBNI_HZ);
893 	splx(s);
894 }
895 
896 /* -------------------------------------------------------------------------- */
897 
898 static void
899 card_start(struct sbni_softc *sc)
900 {
901 	sc->timer_ticks = CHANGE_LEVEL_START_TICKS;
902 	sc->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
903 	sc->state |= FL_PREV_OK;
904 
905 	sc->inppos = 0;
906 	sc->wait_frameno = 0;
907 
908 	sbni_outb(sc, CSR1, *(u_char *)&sc->csr1 | PR_RES);
909 	sbni_outb(sc, CSR0, EN_INT);
910 }
911 
912 /* -------------------------------------------------------------------------- */
913 
914 /*
915  * Device timeout/watchdog routine. Entered if the device neglects to
916  *	generate an interrupt after a transmit has been started on it.
917  */
918 
919 static void
920 sbni_watchdog(struct ifnet *ifp)
921 {
922 	log(LOG_ERR, "%s: device timeout\n", ifp->if_xname);
923 	ifp->if_oerrors++;
924 }
925 
926 
927 static u_char rxl_tab[] = {
928 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
929 	0x0a, 0x0c, 0x0f, 0x16, 0x18, 0x1a, 0x1c, 0x1f
930 };
931 
932 #define SIZE_OF_TIMEOUT_RXL_TAB 4
933 static u_char timeout_rxl_tab[] = {
934 	0x03, 0x05, 0x08, 0x0b
935 };
936 
937 static void
938 set_initial_values(struct sbni_softc *sc, struct sbni_flags flags)
939 {
940 	if (flags.fixed_rxl) {
941 		sc->delta_rxl = 0; /* disable receive level autodetection */
942 		sc->cur_rxl_index = flags.rxl;
943 	} else {
944 		sc->delta_rxl = DEF_RXL_DELTA;
945 		sc->cur_rxl_index = DEF_RXL;
946 	}
947 
948 	sc->csr1.rate = flags.fixed_rate ? flags.rate : DEFAULT_RATE;
949 	sc->csr1.rxl  = rxl_tab[sc->cur_rxl_index];
950 	sc->maxframe  = DEFAULT_FRAME_LEN;
951 
952 	/*
953 	 * generate Ethernet address (0x00ff01xxxxxx)
954 	 */
955 	*(u_int16_t *) sc->arpcom.ac_enaddr = htons(0x00ff);
956 	if (flags.mac_addr) {
957 		*(u_int32_t *) (sc->arpcom.ac_enaddr + 2) =
958 		    htonl(flags.mac_addr | 0x01000000);
959 	} else {
960 		*(u_char *) (sc->arpcom.ac_enaddr + 2) = 0x01;
961 		read_random(sc->arpcom.ac_enaddr + 3, 3);
962 	}
963 }
964 
965 
966 #ifdef SBNI_DUAL_COMPOUND
967 
968 struct sbni_softc *
969 connect_to_master(struct sbni_softc *sc)
970 {
971 	struct sbni_softc *p, *p_prev;
972 
973 	for (p = sbni_headlist, p_prev = NULL; p; p_prev = p, p = p->link) {
974 		if (rman_get_start(p->io_res) == rman_get_start(sc->io_res) + 4 ||
975 		    rman_get_start(p->io_res) == rman_get_start(sc->io_res) - 4) {
976 			p->slave_sc = sc;
977 			if (p_prev)
978 				p_prev->link = p->link;
979 			else
980 				sbni_headlist = p->link;
981 			return p;
982 		}
983 	}
984 
985 	return (NULL);
986 }
987 
988 #endif	/* SBNI_DUAL_COMPOUND */
989 
990 
991 /* Receive level auto-selection */
992 
993 static void
994 change_level(struct sbni_softc *sc)
995 {
996 	if (sc->delta_rxl == 0)		/* do not auto-negotiate RxL */
997 		return;
998 
999 	if (sc->cur_rxl_index == 0)
1000 		sc->delta_rxl = 1;
1001 	else if (sc->cur_rxl_index == 15)
1002 		sc->delta_rxl = -1;
1003 	else if (sc->cur_rxl_rcvd < sc->prev_rxl_rcvd)
1004 		sc->delta_rxl = -sc->delta_rxl;
1005 
1006 	sc->csr1.rxl = rxl_tab[sc->cur_rxl_index += sc->delta_rxl];
1007 	sbni_inb(sc, CSR0);	/* it needed for PCI cards */
1008 	sbni_outb(sc, CSR1, *(u_char *)&sc->csr1);
1009 
1010 	sc->prev_rxl_rcvd = sc->cur_rxl_rcvd;
1011 	sc->cur_rxl_rcvd  = 0;
1012 }
1013 
1014 
1015 static void
1016 timeout_change_level(struct sbni_softc *sc)
1017 {
1018 	sc->cur_rxl_index = timeout_rxl_tab[sc->timeout_rxl];
1019 	if (++sc->timeout_rxl >= 4)
1020 		sc->timeout_rxl = 0;
1021 
1022 	sc->csr1.rxl = rxl_tab[sc->cur_rxl_index];
1023 	sbni_inb(sc, CSR0);
1024 	sbni_outb(sc, CSR1, *(u_char *)&sc->csr1);
1025 
1026 	sc->prev_rxl_rcvd = sc->cur_rxl_rcvd;
1027 	sc->cur_rxl_rcvd  = 0;
1028 }
1029 
1030 /* -------------------------------------------------------------------------- */
1031 
1032 /*
1033  * Process an ioctl request. This code needs some work - it looks
1034  *	pretty ugly.
1035  */
1036 
1037 static int
1038 sbni_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
1039 {
1040 	struct sbni_softc *sc;
1041 	struct ifreq *ifr;
1042 	struct thread *td;
1043 	struct sbni_in_stats *in_stats;
1044 	struct sbni_flags flags;
1045 	int error, s;
1046 
1047 	sc = ifp->if_softc;
1048 	ifr = (struct ifreq *)data;
1049 	td = curthread;
1050 	error = 0;
1051 
1052 	s = splimp();
1053 
1054 	switch (command) {
1055 	case SIOCSIFFLAGS:
1056 		/*
1057 		 * If the interface is marked up and stopped, then start it.
1058 		 * If it is marked down and running, then stop it.
1059 		 */
1060 		if (ifp->if_flags & IFF_UP) {
1061 			if (!(ifp->if_flags & IFF_RUNNING))
1062 				sbni_init(sc);
1063 		} else {
1064 			if (ifp->if_flags & IFF_RUNNING) {
1065 				sbni_stop(sc);
1066 				ifp->if_flags &= ~IFF_RUNNING;
1067 			}
1068 		}
1069 		break;
1070 
1071 	case SIOCADDMULTI:
1072 	case SIOCDELMULTI:
1073 		/*
1074 		 * Multicast list has changed; set the hardware filter
1075 		 * accordingly.
1076 		 */
1077 		error = 0;
1078 		/* if (ifr == NULL)
1079 			error = EAFNOSUPPORT; */
1080 		break;
1081 
1082 	case SIOCSIFMTU:
1083 		if (ifr->ifr_mtu > ETHERMTU)
1084 			error = EINVAL;
1085 		else
1086 			ifp->if_mtu = ifr->ifr_mtu;
1087 		break;
1088 
1089 		/*
1090 		 * SBNI specific ioctl
1091 		 */
1092 	case SIOCGHWFLAGS:	/* get flags */
1093 		bcopy((caddr_t) sc->arpcom.ac_enaddr+3, (caddr_t) &flags, 3);
1094 		flags.rxl = sc->cur_rxl_index;
1095 		flags.rate = sc->csr1.rate;
1096 		flags.fixed_rxl = (sc->delta_rxl == 0);
1097 		flags.fixed_rate = 1;
1098 		ifr->ifr_data = *(caddr_t*) &flags;
1099 		break;
1100 
1101 	case SIOCGINSTATS:
1102 		in_stats = (struct sbni_in_stats *)ifr->ifr_data;
1103 		bcopy((void *)(&(sc->in_stats)), (void *)in_stats,
1104 		      sizeof(struct sbni_in_stats));
1105 		break;
1106 
1107 	case SIOCSHWFLAGS:	/* set flags */
1108 		/* root only */
1109 		error = suser(td);
1110 		if (error)
1111 			break;
1112 		flags = *(struct sbni_flags*)&ifr->ifr_data;
1113 		if (flags.fixed_rxl) {
1114 			sc->delta_rxl = 0;
1115 			sc->cur_rxl_index = flags.rxl;
1116 		} else {
1117 			sc->delta_rxl = DEF_RXL_DELTA;
1118 			sc->cur_rxl_index = DEF_RXL;
1119 		}
1120 		sc->csr1.rxl = rxl_tab[sc->cur_rxl_index];
1121 		sc->csr1.rate = flags.fixed_rate ? flags.rate : DEFAULT_RATE;
1122 		if (flags.mac_addr)
1123 			bcopy((caddr_t) &flags,
1124 			      (caddr_t) sc->arpcom.ac_enaddr+3, 3);
1125 
1126 		/* Don't be afraid... */
1127 		sbni_outb(sc, CSR1, *(char*)(&sc->csr1) | PR_RES);
1128 		break;
1129 
1130 	case SIOCRINSTATS:
1131 		if (!(error = suser(td)))	/* root only */
1132 			bzero(&sc->in_stats, sizeof(struct sbni_in_stats));
1133 		break;
1134 
1135 	default:
1136 		error = ether_ioctl(ifp, command, data);
1137 		break;
1138 	}
1139 
1140 	splx(s);
1141 	return (error);
1142 }
1143 
1144 /* -------------------------------------------------------------------------- */
1145 
1146 #ifdef ASM_CRC
1147 
1148 static u_int32_t
1149 calc_crc32(u_int32_t crc, caddr_t p, u_int len)
1150 {
1151 	register u_int32_t  _crc __asm ("ax");
1152 	_crc = crc;
1153 
1154 	__asm __volatile (
1155 		"xorl	%%ebx, %%ebx\n"
1156 		"movl	%1, %%esi\n"
1157 		"movl	%2, %%ecx\n"
1158 		"movl	$crc32tab, %%edi\n"
1159 		"shrl	$2, %%ecx\n"
1160 		"jz	1f\n"
1161 
1162 		".align 4\n"
1163 	"0:\n"
1164 		"movb	%%al, %%bl\n"
1165 		"movl	(%%esi), %%edx\n"
1166 		"shrl	$8, %%eax\n"
1167 		"xorb	%%dl, %%bl\n"
1168 		"shrl	$8, %%edx\n"
1169 		"xorl	(%%edi,%%ebx,4), %%eax\n"
1170 
1171 		"movb	%%al, %%bl\n"
1172 		"shrl	$8, %%eax\n"
1173 		"xorb	%%dl, %%bl\n"
1174 		"shrl	$8, %%edx\n"
1175 		"xorl	(%%edi,%%ebx,4), %%eax\n"
1176 
1177 		"movb	%%al, %%bl\n"
1178 		"shrl	$8, %%eax\n"
1179 		"xorb	%%dl, %%bl\n"
1180 		"movb	%%dh, %%dl\n"
1181 		"xorl	(%%edi,%%ebx,4), %%eax\n"
1182 
1183 		"movb	%%al, %%bl\n"
1184 		"shrl	$8, %%eax\n"
1185 		"xorb	%%dl, %%bl\n"
1186 		"addl	$4, %%esi\n"
1187 		"xorl	(%%edi,%%ebx,4), %%eax\n"
1188 
1189 		"decl	%%ecx\n"
1190 		"jnz	0b\n"
1191 
1192 	"1:\n"
1193 		"movl	%2, %%ecx\n"
1194 		"andl	$3, %%ecx\n"
1195 		"jz	2f\n"
1196 
1197 		"movb	%%al, %%bl\n"
1198 		"shrl	$8, %%eax\n"
1199 		"xorb	(%%esi), %%bl\n"
1200 		"xorl	(%%edi,%%ebx,4), %%eax\n"
1201 
1202 		"decl	%%ecx\n"
1203 		"jz	2f\n"
1204 
1205 		"movb	%%al, %%bl\n"
1206 		"shrl	$8, %%eax\n"
1207 		"xorb	1(%%esi), %%bl\n"
1208 		"xorl	(%%edi,%%ebx,4), %%eax\n"
1209 
1210 		"decl	%%ecx\n"
1211 		"jz	2f\n"
1212 
1213 		"movb	%%al, %%bl\n"
1214 		"shrl	$8, %%eax\n"
1215 		"xorb	2(%%esi), %%bl\n"
1216 		"xorl	(%%edi,%%ebx,4), %%eax\n"
1217 	"2:\n"
1218 		: "=a" (_crc)
1219 		: "g" (p), "g" (len)
1220 		: "bx", "cx", "dx", "si", "di"
1221 	);
1222 
1223 	return (_crc);
1224 }
1225 
1226 #else	/* ASM_CRC */
1227 
1228 static u_int32_t
1229 calc_crc32(u_int32_t crc, caddr_t p, u_int len)
1230 {
1231 	while (len--)
1232 		crc = CRC32(*p++, crc);
1233 
1234 	return (crc);
1235 }
1236 
1237 #endif	/* ASM_CRC */
1238 
1239 
1240 static u_int32_t crc32tab[] __aligned(8) = {
1241 	0xD202EF8D,  0xA505DF1B,  0x3C0C8EA1,  0x4B0BBE37,
1242 	0xD56F2B94,  0xA2681B02,  0x3B614AB8,  0x4C667A2E,
1243 	0xDCD967BF,  0xABDE5729,  0x32D70693,  0x45D03605,
1244 	0xDBB4A3A6,  0xACB39330,  0x35BAC28A,  0x42BDF21C,
1245 	0xCFB5FFE9,  0xB8B2CF7F,  0x21BB9EC5,  0x56BCAE53,
1246 	0xC8D83BF0,  0xBFDF0B66,  0x26D65ADC,  0x51D16A4A,
1247 	0xC16E77DB,  0xB669474D,  0x2F6016F7,  0x58672661,
1248 	0xC603B3C2,  0xB1048354,  0x280DD2EE,  0x5F0AE278,
1249 	0xE96CCF45,  0x9E6BFFD3,  0x0762AE69,  0x70659EFF,
1250 	0xEE010B5C,  0x99063BCA,  0x000F6A70,  0x77085AE6,
1251 	0xE7B74777,  0x90B077E1,  0x09B9265B,  0x7EBE16CD,
1252 	0xE0DA836E,  0x97DDB3F8,  0x0ED4E242,  0x79D3D2D4,
1253 	0xF4DBDF21,  0x83DCEFB7,  0x1AD5BE0D,  0x6DD28E9B,
1254 	0xF3B61B38,  0x84B12BAE,  0x1DB87A14,  0x6ABF4A82,
1255 	0xFA005713,  0x8D076785,  0x140E363F,  0x630906A9,
1256 	0xFD6D930A,  0x8A6AA39C,  0x1363F226,  0x6464C2B0,
1257 	0xA4DEAE1D,  0xD3D99E8B,  0x4AD0CF31,  0x3DD7FFA7,
1258 	0xA3B36A04,  0xD4B45A92,  0x4DBD0B28,  0x3ABA3BBE,
1259 	0xAA05262F,  0xDD0216B9,  0x440B4703,  0x330C7795,
1260 	0xAD68E236,  0xDA6FD2A0,  0x4366831A,  0x3461B38C,
1261 	0xB969BE79,  0xCE6E8EEF,  0x5767DF55,  0x2060EFC3,
1262 	0xBE047A60,  0xC9034AF6,  0x500A1B4C,  0x270D2BDA,
1263 	0xB7B2364B,  0xC0B506DD,  0x59BC5767,  0x2EBB67F1,
1264 	0xB0DFF252,  0xC7D8C2C4,  0x5ED1937E,  0x29D6A3E8,
1265 	0x9FB08ED5,  0xE8B7BE43,  0x71BEEFF9,  0x06B9DF6F,
1266 	0x98DD4ACC,  0xEFDA7A5A,  0x76D32BE0,  0x01D41B76,
1267 	0x916B06E7,  0xE66C3671,  0x7F6567CB,  0x0862575D,
1268 	0x9606C2FE,  0xE101F268,  0x7808A3D2,  0x0F0F9344,
1269 	0x82079EB1,  0xF500AE27,  0x6C09FF9D,  0x1B0ECF0B,
1270 	0x856A5AA8,  0xF26D6A3E,  0x6B643B84,  0x1C630B12,
1271 	0x8CDC1683,  0xFBDB2615,  0x62D277AF,  0x15D54739,
1272 	0x8BB1D29A,  0xFCB6E20C,  0x65BFB3B6,  0x12B88320,
1273 	0x3FBA6CAD,  0x48BD5C3B,  0xD1B40D81,  0xA6B33D17,
1274 	0x38D7A8B4,  0x4FD09822,  0xD6D9C998,  0xA1DEF90E,
1275 	0x3161E49F,  0x4666D409,  0xDF6F85B3,  0xA868B525,
1276 	0x360C2086,  0x410B1010,  0xD80241AA,  0xAF05713C,
1277 	0x220D7CC9,  0x550A4C5F,  0xCC031DE5,  0xBB042D73,
1278 	0x2560B8D0,  0x52678846,  0xCB6ED9FC,  0xBC69E96A,
1279 	0x2CD6F4FB,  0x5BD1C46D,  0xC2D895D7,  0xB5DFA541,
1280 	0x2BBB30E2,  0x5CBC0074,  0xC5B551CE,  0xB2B26158,
1281 	0x04D44C65,  0x73D37CF3,  0xEADA2D49,  0x9DDD1DDF,
1282 	0x03B9887C,  0x74BEB8EA,  0xEDB7E950,  0x9AB0D9C6,
1283 	0x0A0FC457,  0x7D08F4C1,  0xE401A57B,  0x930695ED,
1284 	0x0D62004E,  0x7A6530D8,  0xE36C6162,  0x946B51F4,
1285 	0x19635C01,  0x6E646C97,  0xF76D3D2D,  0x806A0DBB,
1286 	0x1E0E9818,  0x6909A88E,  0xF000F934,  0x8707C9A2,
1287 	0x17B8D433,  0x60BFE4A5,  0xF9B6B51F,  0x8EB18589,
1288 	0x10D5102A,  0x67D220BC,  0xFEDB7106,  0x89DC4190,
1289 	0x49662D3D,  0x3E611DAB,  0xA7684C11,  0xD06F7C87,
1290 	0x4E0BE924,  0x390CD9B2,  0xA0058808,  0xD702B89E,
1291 	0x47BDA50F,  0x30BA9599,  0xA9B3C423,  0xDEB4F4B5,
1292 	0x40D06116,  0x37D75180,  0xAEDE003A,  0xD9D930AC,
1293 	0x54D13D59,  0x23D60DCF,  0xBADF5C75,  0xCDD86CE3,
1294 	0x53BCF940,  0x24BBC9D6,  0xBDB2986C,  0xCAB5A8FA,
1295 	0x5A0AB56B,  0x2D0D85FD,  0xB404D447,  0xC303E4D1,
1296 	0x5D677172,  0x2A6041E4,  0xB369105E,  0xC46E20C8,
1297 	0x72080DF5,  0x050F3D63,  0x9C066CD9,  0xEB015C4F,
1298 	0x7565C9EC,  0x0262F97A,  0x9B6BA8C0,  0xEC6C9856,
1299 	0x7CD385C7,  0x0BD4B551,  0x92DDE4EB,  0xE5DAD47D,
1300 	0x7BBE41DE,  0x0CB97148,  0x95B020F2,  0xE2B71064,
1301 	0x6FBF1D91,  0x18B82D07,  0x81B17CBD,  0xF6B64C2B,
1302 	0x68D2D988,  0x1FD5E91E,  0x86DCB8A4,  0xF1DB8832,
1303 	0x616495A3,  0x1663A535,  0x8F6AF48F,  0xF86DC419,
1304 	0x660951BA,  0x110E612C,  0x88073096,  0xFF000000
1305 };
1306