xref: /freebsd/sys/dev/sbni/if_sbni.c (revision d6b92ffa)
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_var.h>
83 #include <net/if_dl.h>
84 #include <net/ethernet.h>
85 #include <net/bpf.h>
86 #include <net/if_types.h>
87 
88 #include <dev/sbni/if_sbnireg.h>
89 #include <dev/sbni/if_sbnivar.h>
90 
91 static void	sbni_init(void *);
92 static void	sbni_init_locked(struct sbni_softc *);
93 static void	sbni_start(struct ifnet *);
94 static void	sbni_start_locked(struct ifnet *);
95 static int	sbni_ioctl(struct ifnet *, u_long, caddr_t);
96 static void	sbni_stop(struct sbni_softc *);
97 static void	handle_channel(struct sbni_softc *);
98 
99 static void	card_start(struct sbni_softc *);
100 static int	recv_frame(struct sbni_softc *);
101 static void	send_frame(struct sbni_softc *);
102 static int	upload_data(struct sbni_softc *, u_int, u_int, u_int, u_int32_t);
103 static int	skip_tail(struct sbni_softc *, u_int, u_int32_t);
104 static void	interpret_ack(struct sbni_softc *, u_int);
105 static void	download_data(struct sbni_softc *, u_int32_t *);
106 static void	prepare_to_send(struct sbni_softc *);
107 static void	drop_xmit_queue(struct sbni_softc *);
108 static int	get_rx_buf(struct sbni_softc *);
109 static void	indicate_pkt(struct sbni_softc *);
110 static void	change_level(struct sbni_softc *);
111 static int	check_fhdr(struct sbni_softc *, u_int *, u_int *,
112 			   u_int *, u_int *, u_int32_t *);
113 static int	append_frame_to_pkt(struct sbni_softc *, u_int, u_int32_t);
114 static void	timeout_change_level(struct sbni_softc *);
115 static void	send_frame_header(struct sbni_softc *, u_int32_t *);
116 static void	set_initial_values(struct sbni_softc *, struct sbni_flags);
117 
118 static u_int32_t	calc_crc32(u_int32_t, caddr_t, u_int);
119 static timeout_t	sbni_timeout;
120 
121 static __inline u_char	sbni_inb(struct sbni_softc *, enum sbni_reg);
122 static __inline void	sbni_outb(struct sbni_softc *, enum sbni_reg, u_char);
123 static __inline void	sbni_insb(struct sbni_softc *, u_char *, u_int);
124 static __inline void	sbni_outsb(struct sbni_softc *, u_char *, u_int);
125 
126 static u_int32_t crc32tab[];
127 
128 #ifdef SBNI_DUAL_COMPOUND
129 static struct mtx headlist_lock;
130 MTX_SYSINIT(headlist_lock, &headlist_lock, "sbni headlist", MTX_DEF);
131 static struct sbni_softc *sbni_headlist;
132 #endif
133 
134 /* -------------------------------------------------------------------------- */
135 
136 static __inline u_char
137 sbni_inb(struct sbni_softc *sc, enum sbni_reg reg)
138 {
139 	return bus_space_read_1(
140 	    rman_get_bustag(sc->io_res),
141 	    rman_get_bushandle(sc->io_res),
142 	    sc->io_off + reg);
143 }
144 
145 static __inline void
146 sbni_outb(struct sbni_softc *sc, enum sbni_reg reg, u_char value)
147 {
148 	bus_space_write_1(
149 	    rman_get_bustag(sc->io_res),
150 	    rman_get_bushandle(sc->io_res),
151 	    sc->io_off + reg, value);
152 }
153 
154 static __inline void
155 sbni_insb(struct sbni_softc *sc, u_char *to, u_int len)
156 {
157 	bus_space_read_multi_1(
158 	    rman_get_bustag(sc->io_res),
159 	    rman_get_bushandle(sc->io_res),
160 	    sc->io_off + DAT, to, len);
161 }
162 
163 static __inline void
164 sbni_outsb(struct sbni_softc *sc, u_char *from, u_int len)
165 {
166 	bus_space_write_multi_1(
167 	    rman_get_bustag(sc->io_res),
168 	    rman_get_bushandle(sc->io_res),
169 	    sc->io_off + DAT, from, len);
170 }
171 
172 
173 /*
174 	Valid combinations in CSR0 (for probing):
175 
176 	VALID_DECODER	0000,0011,1011,1010
177 
178 				    	; 0   ; -
179 				TR_REQ	; 1   ; +
180 			TR_RDY	    	; 2   ; -
181 			TR_RDY	TR_REQ	; 3   ; +
182 		BU_EMP		    	; 4   ; +
183 		BU_EMP	     	TR_REQ	; 5   ; +
184 		BU_EMP	TR_RDY	    	; 6   ; -
185 		BU_EMP	TR_RDY	TR_REQ	; 7   ; +
186 	RC_RDY 		     		; 8   ; +
187 	RC_RDY			TR_REQ	; 9   ; +
188 	RC_RDY		TR_RDY		; 10  ; -
189 	RC_RDY		TR_RDY	TR_REQ	; 11  ; -
190 	RC_RDY	BU_EMP			; 12  ; -
191 	RC_RDY	BU_EMP		TR_REQ	; 13  ; -
192 	RC_RDY	BU_EMP	TR_RDY		; 14  ; -
193 	RC_RDY	BU_EMP	TR_RDY	TR_REQ	; 15  ; -
194 */
195 
196 #define VALID_DECODER	(2 + 8 + 0x10 + 0x20 + 0x80 + 0x100 + 0x200)
197 
198 
199 int
200 sbni_probe(struct sbni_softc *sc)
201 {
202 	u_char csr0;
203 
204 	csr0 = sbni_inb(sc, CSR0);
205 	if (csr0 != 0xff && csr0 != 0x00) {
206 		csr0 &= ~EN_INT;
207 		if (csr0 & BU_EMP)
208 			csr0 |= EN_INT;
209 
210 		if (VALID_DECODER & (1 << (csr0 >> 4)))
211 			return (0);
212 	}
213 
214 	return (ENXIO);
215 }
216 
217 
218 /*
219  * Install interface into kernel networking data structures
220  */
221 int
222 sbni_attach(struct sbni_softc *sc, int unit, struct sbni_flags flags)
223 {
224 	struct ifnet *ifp;
225 	u_char csr0;
226 
227 	ifp = sc->ifp = if_alloc(IFT_ETHER);
228 	if (ifp == NULL)
229 		return (ENOMEM);
230 	sbni_outb(sc, CSR0, 0);
231 	set_initial_values(sc, flags);
232 
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 	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
240 
241 	/* report real baud rate */
242 	csr0 = sbni_inb(sc, CSR0);
243 	ifp->if_baudrate =
244 		(csr0 & 0x01 ? 500000 : 2000000) / (1 << flags.rate);
245 
246 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
247 
248 	mtx_init(&sc->lock, ifp->if_xname, MTX_NETWORK_LOCK, MTX_DEF);
249 	callout_init_mtx(&sc->wch, &sc->lock, 0);
250 	ether_ifattach(ifp, sc->enaddr);
251 	/* device attach does transition from UNCONFIGURED to IDLE state */
252 
253 	if_printf(ifp, "speed %ju, rxl ", (uintmax_t)ifp->if_baudrate);
254 	if (sc->delta_rxl)
255 		printf("auto\n");
256 	else
257 		printf("%d (fixed)\n", sc->cur_rxl_index);
258 	return (0);
259 }
260 
261 void
262 sbni_detach(struct sbni_softc *sc)
263 {
264 
265 	SBNI_LOCK(sc);
266 	sbni_stop(sc);
267 	SBNI_UNLOCK(sc);
268 	callout_drain(&sc->wch);
269 	ether_ifdetach(sc->ifp);
270 	if (sc->irq_handle)
271 		bus_teardown_intr(sc->dev, sc->irq_res, sc->irq_handle);
272 	mtx_destroy(&sc->lock);
273 	if_free(sc->ifp);
274 }
275 
276 void
277 sbni_release_resources(struct sbni_softc *sc)
278 {
279 
280 	if (sc->irq_res)
281 		bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irq_rid,
282 		    sc->irq_res);
283 	if (sc->io_res && sc->io_off == 0)
284 		bus_release_resource(sc->dev, SYS_RES_IOPORT, sc->io_rid,
285 		    sc->io_res);
286 }
287 
288 /* -------------------------------------------------------------------------- */
289 
290 static void
291 sbni_init(void *xsc)
292 {
293 	struct sbni_softc *sc;
294 
295 	sc = (struct sbni_softc *)xsc;
296 	SBNI_LOCK(sc);
297 	sbni_init_locked(sc);
298 	SBNI_UNLOCK(sc);
299 }
300 
301 static void
302 sbni_init_locked(struct sbni_softc *sc)
303 {
304 	struct ifnet *ifp;
305 
306 	ifp = sc->ifp;
307 
308 	/*
309 	 * kludge to avoid multiple initialization when more than once
310 	 * protocols configured
311 	 */
312 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
313 		return;
314 
315 	card_start(sc);
316 	callout_reset(&sc->wch, hz/SBNI_HZ, sbni_timeout, sc);
317 
318 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
319 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
320 
321 	/* attempt to start output */
322 	sbni_start_locked(ifp);
323 }
324 
325 static void
326 sbni_start(struct ifnet *ifp)
327 {
328 	struct sbni_softc *sc = ifp->if_softc;
329 
330 	SBNI_LOCK(sc);
331 	sbni_start_locked(ifp);
332 	SBNI_UNLOCK(sc);
333 }
334 
335 static void
336 sbni_start_locked(struct ifnet *ifp)
337 {
338 	struct sbni_softc *sc = ifp->if_softc;
339 
340 	if (sc->tx_frameno == 0)
341 		prepare_to_send(sc);
342 }
343 
344 
345 static void
346 sbni_stop(struct sbni_softc *sc)
347 {
348 	sbni_outb(sc, CSR0, 0);
349 	drop_xmit_queue(sc);
350 
351 	if (sc->rx_buf_p) {
352 		m_freem(sc->rx_buf_p);
353 		sc->rx_buf_p = NULL;
354 	}
355 
356 	callout_stop(&sc->wch);
357 	sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
358 }
359 
360 /* -------------------------------------------------------------------------- */
361 
362 /* interrupt handler */
363 
364 /*
365  * 	SBNI12D-10, -11/ISA boards within "common interrupt" mode could not
366  * be looked as two independent single-channel devices. Every channel seems
367  * as Ethernet interface but interrupt handler must be common. Really, first
368  * channel ("master") driver only registers the handler. In it's struct softc
369  * it has got pointer to "slave" channel's struct softc and handles that's
370  * interrupts too.
371  *	softc of successfully attached ISA SBNI boards is linked to list.
372  * While next board driver is initialized, it scans this list. If one
373  * has found softc with same irq and ioaddr different by 4 then it assumes
374  * this board to be "master".
375  */
376 
377 void
378 sbni_intr(void *arg)
379 {
380 	struct sbni_softc *sc;
381 	int repeat;
382 
383 	sc = (struct sbni_softc *)arg;
384 
385 	do {
386 		repeat = 0;
387 		SBNI_LOCK(sc);
388 		if (sbni_inb(sc, CSR0) & (RC_RDY | TR_RDY)) {
389 			handle_channel(sc);
390 			repeat = 1;
391 		}
392 		SBNI_UNLOCK(sc);
393 		if (sc->slave_sc) {
394 			/* second channel present */
395 			SBNI_LOCK(sc->slave_sc);
396 			if (sbni_inb(sc->slave_sc, CSR0) & (RC_RDY | TR_RDY)) {
397 				handle_channel(sc->slave_sc);
398 				repeat = 1;
399 			}
400 			SBNI_UNLOCK(sc->slave_sc);
401 		}
402 	} while (repeat);
403 }
404 
405 
406 static void
407 handle_channel(struct sbni_softc *sc)
408 {
409 	int req_ans;
410 	u_char csr0;
411 
412 	sbni_outb(sc, CSR0, (sbni_inb(sc, CSR0) & ~EN_INT) | TR_REQ);
413 
414 	sc->timer_ticks = CHANGE_LEVEL_START_TICKS;
415 	for (;;) {
416 		csr0 = sbni_inb(sc, CSR0);
417 		if ((csr0 & (RC_RDY | TR_RDY)) == 0)
418 			break;
419 
420 		req_ans = !(sc->state & FL_PREV_OK);
421 
422 		if (csr0 & RC_RDY)
423 			req_ans = recv_frame(sc);
424 
425 		/*
426 		 * TR_RDY always equals 1 here because we have owned the marker,
427 		 * and we set TR_REQ when disabled interrupts
428 		 */
429 		csr0 = sbni_inb(sc, CSR0);
430 		if ((csr0 & TR_RDY) == 0 || (csr0 & RC_RDY) != 0)
431 			if_printf(sc->ifp, "internal error!\n");
432 
433 		/* if state & FL_NEED_RESEND != 0 then tx_frameno != 0 */
434 		if (req_ans || sc->tx_frameno != 0)
435 			send_frame(sc);
436 		else {
437 			/* send the marker without any data */
438 			sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) & ~TR_REQ);
439 		}
440 	}
441 
442 	sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) | EN_INT);
443 }
444 
445 
446 /*
447  * Routine returns 1 if it need to acknoweledge received frame.
448  * Empty frame received without errors won't be acknoweledged.
449  */
450 
451 static int
452 recv_frame(struct sbni_softc *sc)
453 {
454 	u_int32_t crc;
455 	u_int framelen, frameno, ack;
456 	u_int is_first, frame_ok;
457 
458 	crc = CRC32_INITIAL;
459 	if (check_fhdr(sc, &framelen, &frameno, &ack, &is_first, &crc)) {
460 		frame_ok = framelen > 4 ?
461 		    upload_data(sc, framelen, frameno, is_first, crc) :
462 		    skip_tail(sc, framelen, crc);
463 		if (frame_ok)
464 			interpret_ack(sc, ack);
465 	} else {
466 		framelen = 0;
467 		frame_ok = 0;
468 	}
469 
470 	sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) ^ CT_ZER);
471 	if (frame_ok) {
472 		sc->state |= FL_PREV_OK;
473 		if (framelen > 4)
474 			sc->in_stats.all_rx_number++;
475 	} else {
476 		sc->state &= ~FL_PREV_OK;
477 		change_level(sc);
478 		sc->in_stats.all_rx_number++;
479 		sc->in_stats.bad_rx_number++;
480 	}
481 
482 	return (!frame_ok || framelen > 4);
483 }
484 
485 
486 static void
487 send_frame(struct sbni_softc *sc)
488 {
489 	u_int32_t crc;
490 	u_char csr0;
491 
492 	crc = CRC32_INITIAL;
493 	if (sc->state & FL_NEED_RESEND) {
494 
495 		/* if frame was sended but not ACK'ed - resend it */
496 		if (sc->trans_errors) {
497 			sc->trans_errors--;
498 			if (sc->framelen != 0)
499 				sc->in_stats.resend_tx_number++;
500 		} else {
501 			/* cannot xmit with many attempts */
502 			drop_xmit_queue(sc);
503 			goto do_send;
504 		}
505 	} else
506 		sc->trans_errors = TR_ERROR_COUNT;
507 
508 	send_frame_header(sc, &crc);
509 	sc->state |= FL_NEED_RESEND;
510 	/*
511 	 * FL_NEED_RESEND will be cleared after ACK, but if empty
512 	 * frame sended then in prepare_to_send next frame
513 	 */
514 
515 
516 	if (sc->framelen) {
517 		download_data(sc, &crc);
518 		sc->in_stats.all_tx_number++;
519 		sc->state |= FL_WAIT_ACK;
520 	}
521 
522 	sbni_outsb(sc, (u_char *)&crc, sizeof crc);
523 
524 do_send:
525 	csr0 = sbni_inb(sc, CSR0);
526 	sbni_outb(sc, CSR0, csr0 & ~TR_REQ);
527 
528 	if (sc->tx_frameno) {
529 		/* next frame exists - request to send */
530 		sbni_outb(sc, CSR0, csr0 | TR_REQ);
531 	}
532 }
533 
534 
535 static void
536 download_data(struct sbni_softc *sc, u_int32_t *crc_p)
537 {
538 	struct mbuf *m;
539 	caddr_t	data_p;
540 	u_int data_len, pos, slice;
541 
542 	data_p = NULL;		/* initialized to avoid warn */
543 	pos = 0;
544 
545 	for (m = sc->tx_buf_p;  m != NULL && pos < sc->pktlen;  m = m->m_next) {
546 		if (pos + m->m_len > sc->outpos) {
547 			data_len = m->m_len - (sc->outpos - pos);
548 			data_p = mtod(m, caddr_t) + (sc->outpos - pos);
549 
550 			goto do_copy;
551 		} else
552 			pos += m->m_len;
553 	}
554 
555 	data_len = 0;
556 
557 do_copy:
558 	pos = 0;
559 	do {
560 		if (data_len) {
561 			slice = min(data_len, sc->framelen - pos);
562 			sbni_outsb(sc, data_p, slice);
563 			*crc_p = calc_crc32(*crc_p, data_p, slice);
564 
565 			pos += slice;
566 			if (data_len -= slice)
567 				data_p += slice;
568 			else {
569 				do {
570 					m = m->m_next;
571 				} while (m != NULL && m->m_len == 0);
572 
573 				if (m) {
574 					data_len = m->m_len;
575 					data_p = mtod(m, caddr_t);
576 				}
577 			}
578 		} else {
579 			/* frame too short - zero padding */
580 
581 			pos = sc->framelen - pos;
582 			while (pos--) {
583 				sbni_outb(sc, DAT, 0);
584 				*crc_p = CRC32(0, *crc_p);
585 			}
586 			return;
587 		}
588 	} while (pos < sc->framelen);
589 }
590 
591 
592 static int
593 upload_data(struct sbni_softc *sc, u_int framelen, u_int frameno,
594 	    u_int is_first, u_int32_t crc)
595 {
596 	int frame_ok;
597 
598 	if (is_first) {
599 		sc->wait_frameno = frameno;
600 		sc->inppos = 0;
601 	}
602 
603 	if (sc->wait_frameno == frameno) {
604 
605 		if (sc->inppos + framelen  <=  ETHER_MAX_LEN) {
606 			frame_ok = append_frame_to_pkt(sc, framelen, crc);
607 
608 		/*
609 		 * if CRC is right but framelen incorrect then transmitter
610 		 * error was occurred... drop entire packet
611 		 */
612 		} else if ((frame_ok = skip_tail(sc, framelen, crc)) != 0) {
613 			sc->wait_frameno = 0;
614 			sc->inppos = 0;
615 			if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
616 			/* now skip all frames until is_first != 0 */
617 		}
618 	} else
619 		frame_ok = skip_tail(sc, framelen, crc);
620 
621 	if (is_first && !frame_ok) {
622 		/*
623 		 * Frame has been violated, but we have stored
624 		 * is_first already... Drop entire packet.
625 		 */
626 		sc->wait_frameno = 0;
627 		if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
628 	}
629 
630 	return (frame_ok);
631 }
632 
633 
634 static __inline void	send_complete(struct sbni_softc *);
635 
636 static __inline void
637 send_complete(struct sbni_softc *sc)
638 {
639 	m_freem(sc->tx_buf_p);
640 	sc->tx_buf_p = NULL;
641 	if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1);
642 }
643 
644 
645 static void
646 interpret_ack(struct sbni_softc *sc, u_int ack)
647 {
648 	if (ack == FRAME_SENT_OK) {
649 		sc->state &= ~FL_NEED_RESEND;
650 
651 		if (sc->state & FL_WAIT_ACK) {
652 			sc->outpos += sc->framelen;
653 
654 			if (--sc->tx_frameno) {
655 				sc->framelen = min(
656 				    sc->maxframe, sc->pktlen - sc->outpos);
657 			} else {
658 				send_complete(sc);
659 				prepare_to_send(sc);
660 			}
661 		}
662 	}
663 
664 	sc->state &= ~FL_WAIT_ACK;
665 }
666 
667 
668 /*
669  * Glue received frame with previous fragments of packet.
670  * Indicate packet when last frame would be accepted.
671  */
672 
673 static int
674 append_frame_to_pkt(struct sbni_softc *sc, u_int framelen, u_int32_t crc)
675 {
676 	caddr_t p;
677 
678 	if (sc->inppos + framelen > ETHER_MAX_LEN)
679 		return (0);
680 
681 	if (!sc->rx_buf_p && !get_rx_buf(sc))
682 		return (0);
683 
684 	p = sc->rx_buf_p->m_data + sc->inppos;
685 	sbni_insb(sc, p, framelen);
686 	if (calc_crc32(crc, p, framelen) != CRC32_REMAINDER)
687 		return (0);
688 
689 	sc->inppos += framelen - 4;
690 	if (--sc->wait_frameno == 0) {		/* last frame received */
691 		indicate_pkt(sc);
692 		if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1);
693 	}
694 
695 	return (1);
696 }
697 
698 
699 /*
700  * Prepare to start output on adapter. Current priority must be set to splimp
701  * before this routine is called.
702  * Transmitter will be actually activated when marker has been accepted.
703  */
704 
705 static void
706 prepare_to_send(struct sbni_softc *sc)
707 {
708 	struct mbuf *m;
709 	u_int len;
710 
711 	/* sc->tx_buf_p == NULL here! */
712 	if (sc->tx_buf_p)
713 		printf("sbni: memory leak!\n");
714 
715 	sc->outpos = 0;
716 	sc->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
717 
718 	for (;;) {
719 		IF_DEQUEUE(&sc->ifp->if_snd, sc->tx_buf_p);
720 		if (!sc->tx_buf_p) {
721 			/* nothing to transmit... */
722 			sc->pktlen     = 0;
723 			sc->tx_frameno = 0;
724 			sc->framelen   = 0;
725 			sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
726 			return;
727 		}
728 
729 		for (len = 0, m = sc->tx_buf_p;  m;  m = m->m_next)
730 			len += m->m_len;
731 
732 		if (len != 0)
733 			break;
734 		m_freem(sc->tx_buf_p);
735 	}
736 
737 	if (len < SBNI_MIN_LEN)
738 		len = SBNI_MIN_LEN;
739 
740 	sc->pktlen	= len;
741 	sc->tx_frameno	= howmany(len, sc->maxframe);
742 	sc->framelen	= min(len, sc->maxframe);
743 
744 	sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) | TR_REQ);
745 	sc->ifp->if_drv_flags |= IFF_DRV_OACTIVE;
746 	BPF_MTAP(sc->ifp, sc->tx_buf_p);
747 }
748 
749 
750 static void
751 drop_xmit_queue(struct sbni_softc *sc)
752 {
753 	struct mbuf *m;
754 
755 	if (sc->tx_buf_p) {
756 		m_freem(sc->tx_buf_p);
757 		sc->tx_buf_p = NULL;
758 		if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
759 	}
760 
761 	for (;;) {
762 		IF_DEQUEUE(&sc->ifp->if_snd, m);
763 		if (m == NULL)
764 			break;
765 		m_freem(m);
766 		if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
767 	}
768 
769 	sc->tx_frameno	= 0;
770 	sc->framelen	= 0;
771 	sc->outpos	= 0;
772 	sc->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
773 	sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
774 }
775 
776 
777 static void
778 send_frame_header(struct sbni_softc *sc, u_int32_t *crc_p)
779 {
780 	u_int32_t crc;
781 	u_int len_field;
782 	u_char value;
783 
784 	crc = *crc_p;
785 	len_field = sc->framelen + 6;	/* CRC + frameno + reserved */
786 
787 	if (sc->state & FL_NEED_RESEND)
788 		len_field |= FRAME_RETRY;	/* non-first attempt... */
789 
790 	if (sc->outpos == 0)
791 		len_field |= FRAME_FIRST;
792 
793 	len_field |= (sc->state & FL_PREV_OK) ? FRAME_SENT_OK : FRAME_SENT_BAD;
794 	sbni_outb(sc, DAT, SBNI_SIG);
795 
796 	value = (u_char)len_field;
797 	sbni_outb(sc, DAT, value);
798 	crc = CRC32(value, crc);
799 	value = (u_char)(len_field >> 8);
800 	sbni_outb(sc, DAT, value);
801 	crc = CRC32(value, crc);
802 
803 	sbni_outb(sc, DAT, sc->tx_frameno);
804 	crc = CRC32(sc->tx_frameno, crc);
805 	sbni_outb(sc, DAT, 0);
806 	crc = CRC32(0, crc);
807 	*crc_p = crc;
808 }
809 
810 
811 /*
812  * if frame tail not needed (incorrect number or received twice),
813  * it won't store, but CRC will be calculated
814  */
815 
816 static int
817 skip_tail(struct sbni_softc *sc, u_int tail_len, u_int32_t crc)
818 {
819 	while (tail_len--)
820 		crc = CRC32(sbni_inb(sc, DAT), crc);
821 
822 	return (crc == CRC32_REMAINDER);
823 }
824 
825 
826 static int
827 check_fhdr(struct sbni_softc *sc, u_int *framelen, u_int *frameno,
828 	   u_int *ack, u_int *is_first, u_int32_t *crc_p)
829 {
830 	u_int32_t crc;
831 	u_char value;
832 
833 	crc = *crc_p;
834 	if (sbni_inb(sc, DAT) != SBNI_SIG)
835 		return (0);
836 
837 	value = sbni_inb(sc, DAT);
838 	*framelen = (u_int)value;
839 	crc = CRC32(value, crc);
840 	value = sbni_inb(sc, DAT);
841 	*framelen |= ((u_int)value) << 8;
842 	crc = CRC32(value, crc);
843 
844 	*ack = *framelen & FRAME_ACK_MASK;
845 	*is_first = (*framelen & FRAME_FIRST) != 0;
846 
847 	if ((*framelen &= FRAME_LEN_MASK) < 6 || *framelen > SBNI_MAX_FRAME - 3)
848 		return (0);
849 
850 	value = sbni_inb(sc, DAT);
851 	*frameno = (u_int)value;
852 	crc = CRC32(value, crc);
853 
854 	crc = CRC32(sbni_inb(sc, DAT), crc);		/* reserved byte */
855 	*framelen -= 2;
856 
857 	*crc_p = crc;
858 	return (1);
859 }
860 
861 
862 static int
863 get_rx_buf(struct sbni_softc *sc)
864 {
865 	struct mbuf *m;
866 
867 	MGETHDR(m, M_NOWAIT, MT_DATA);
868 	if (m == NULL) {
869 		if_printf(sc->ifp, "cannot allocate header mbuf\n");
870 		return (0);
871 	}
872 
873 	/*
874 	 * We always put the received packet in a single buffer -
875 	 * either with just an mbuf header or in a cluster attached
876 	 * to the header. The +2 is to compensate for the alignment
877 	 * fixup below.
878 	 */
879 	if (ETHER_MAX_LEN + 2 > MHLEN) {
880 		/* Attach an mbuf cluster */
881 		if (!(MCLGET(m, M_NOWAIT))) {
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