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