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