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