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