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