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