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