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