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