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