1 /* $NetBSD: if_qn.c,v 1.20 2000/11/15 01:02:12 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1995 Mika Kortelainen 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Mika Kortelainen 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 * Thanks for Aspecs Oy (Finland) for the data book for the NIC used 33 * in this card and also many thanks for the Resource Management Force 34 * (QuickNet card manufacturer) and especially Daniel Koch for providing 35 * me with the necessary 'inside' information to write the driver. 36 * 37 * This is partly based on other code: 38 * - if_ed.c: basic function structure for Ethernet driver and now also 39 * qn_put() is done similarly, i.e. no extra packet buffers. 40 * 41 * Device driver for National Semiconductor DS8390/WD83C690 based ethernet 42 * adapters. 43 * 44 * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. 45 * 46 * Copyright (C) 1993, David Greenman. This software may be used, 47 * modified, copied, distributed, and sold, in both source and binary 48 * form provided that the above copyright and these terms are retained. 49 * Under no circumstances is the author responsible for the proper 50 * functioning of this software, nor does the author assume any 51 * responsibility for damages incurred with its use. 52 * 53 * - if_es.c: used as an example of -current driver 54 * 55 * Copyright (c) 1995 Michael L. Hitch 56 * All rights reserved. 57 * 58 * - if_fe.c: some ideas for error handling for qn_rint() which might 59 * have fixed those random lock ups, too. 60 * 61 * All Rights Reserved, Copyright (C) Fujitsu Limited 1995 62 * 63 * 64 * TODO: 65 * - add multicast support 66 */ 67 68 #include "qn.h" 69 #if NQN > 0 70 71 #define QN_DEBUG 72 #define QN_DEBUG1_no /* hides some old tests */ 73 #define QN_CHECKS_no /* adds some checks (not needed in normal situations) */ 74 75 #include "bpfilter.h" 76 77 /* 78 * Fujitsu MB86950 Ethernet Controller (as used in the QuickNet QN2000 79 * Ethernet card) 80 */ 81 82 #include "opt_inet.h" 83 #include "opt_ns.h" 84 85 #include <sys/param.h> 86 #include <sys/systm.h> 87 #include <sys/mbuf.h> 88 #include <sys/buf.h> 89 #include <sys/device.h> 90 #include <sys/protosw.h> 91 #include <sys/socket.h> 92 #include <sys/syslog.h> 93 #include <sys/ioctl.h> 94 #include <sys/errno.h> 95 96 #include <net/if.h> 97 #include <net/if_dl.h> 98 #include <net/if_ether.h> 99 100 #ifdef INET 101 #include <netinet/in.h> 102 #include <netinet/in_systm.h> 103 #include <netinet/in_var.h> 104 #include <netinet/ip.h> 105 #include <netinet/if_inarp.h> 106 #endif 107 108 #ifdef NS 109 #include <netns/ns.h> 110 #include <netns/ns_if.h> 111 #endif 112 113 #include <machine/cpu.h> 114 #include <machine/mtpr.h> 115 #include <amiga/amiga/device.h> 116 #include <amiga/amiga/isr.h> 117 #include <amiga/dev/zbusvar.h> 118 #include <amiga/dev/if_qnreg.h> 119 120 121 #define NIC_R_MASK (R_INT_PKT_RDY | R_INT_ALG_ERR |\ 122 R_INT_CRC_ERR | R_INT_OVR_FLO) 123 #define MAX_PACKETS 30 /* max number of packets read per interrupt */ 124 125 /* 126 * Ethernet software status per interface 127 * 128 * Each interface is referenced by a network interface structure, 129 * qn_if, which the routing code uses to locate the interface. 130 * This structure contains the output queue for the interface, its address, ... 131 */ 132 struct qn_softc { 133 struct device sc_dev; 134 struct isr sc_isr; 135 struct ethercom sc_ethercom; /* Common ethernet structures */ 136 u_char volatile *sc_base; 137 u_char volatile *sc_nic_base; 138 u_short volatile *nic_fifo; 139 u_short volatile *nic_r_status; 140 u_short volatile *nic_t_status; 141 u_short volatile *nic_r_mask; 142 u_short volatile *nic_t_mask; 143 u_short volatile *nic_r_mode; 144 u_short volatile *nic_t_mode; 145 u_short volatile *nic_reset; 146 u_short volatile *nic_len; 147 u_char transmit_pending; 148 #if NBPFILTER > 0 149 caddr_t sc_bpf; 150 #endif 151 } qn_softc[NQN]; 152 153 #if NBPFILTER > 0 154 #include <net/bpf.h> 155 #include <net/bpfdesc.h> 156 #endif 157 158 159 int qnmatch __P((struct device *, struct cfdata *, void *)); 160 void qnattach __P((struct device *, struct device *, void *)); 161 int qnintr __P((void *)); 162 int qnioctl __P((struct ifnet *, u_long, caddr_t)); 163 void qnstart __P((struct ifnet *)); 164 void qnwatchdog __P((struct ifnet *)); 165 void qnreset __P((struct qn_softc *)); 166 void qninit __P((struct qn_softc *)); 167 void qnstop __P((struct qn_softc *)); 168 static u_short qn_put __P((u_short volatile *, struct mbuf *)); 169 static void qn_rint __P((struct qn_softc *, u_short)); 170 static void qn_flush __P((struct qn_softc *)); 171 static void inline word_copy_from_card __P((u_short volatile *, u_short *, u_short)); 172 static void inline word_copy_to_card __P((u_short *, u_short volatile *, register u_short)); 173 static void qn_get_packet __P((struct qn_softc *, u_short)); 174 #ifdef QN_DEBUG1 175 static void qn_dump __P((struct qn_softc *)); 176 #endif 177 178 struct cfattach qn_ca = { 179 sizeof(struct qn_softc), qnmatch, qnattach 180 }; 181 182 int 183 qnmatch(parent, cfp, aux) 184 struct device *parent; 185 struct cfdata *cfp; 186 void *aux; 187 { 188 struct zbus_args *zap; 189 190 zap = (struct zbus_args *)aux; 191 192 /* RMF QuickNet QN2000 EtherNet card */ 193 if (zap->manid == 2011 && zap->prodid == 2) 194 return (1); 195 196 return (0); 197 } 198 199 /* 200 * Interface exists: make available by filling in network interface 201 * record. System will initialize the interface when it is ready 202 * to accept packets. 203 */ 204 void 205 qnattach(parent, self, aux) 206 struct device *parent, *self; 207 void *aux; 208 { 209 struct zbus_args *zap; 210 struct qn_softc *sc = (struct qn_softc *)self; 211 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 212 u_int8_t myaddr[ETHER_ADDR_LEN]; 213 214 zap = (struct zbus_args *)aux; 215 216 sc->sc_base = zap->va; 217 sc->sc_nic_base = sc->sc_base + QUICKNET_NIC_BASE; 218 sc->nic_fifo = (u_short volatile *)(sc->sc_nic_base + NIC_BMPR0); 219 sc->nic_len = (u_short volatile *)(sc->sc_nic_base + NIC_BMPR2); 220 sc->nic_t_status = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR0); 221 sc->nic_r_status = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR2); 222 sc->nic_t_mask = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR1); 223 sc->nic_r_mask = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR3); 224 sc->nic_t_mode = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR4); 225 sc->nic_r_mode = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR5); 226 sc->nic_reset = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR6); 227 sc->transmit_pending = 0; 228 229 /* 230 * The ethernet address of the board (1st three bytes are the vendor 231 * address, the rest is the serial number of the board). 232 */ 233 myaddr[0] = 0x5c; 234 myaddr[1] = 0x5c; 235 myaddr[2] = 0x00; 236 myaddr[3] = (zap->serno >> 16) & 0xff; 237 myaddr[4] = (zap->serno >> 8) & 0xff; 238 myaddr[5] = zap->serno & 0xff; 239 240 /* set interface to stopped condition (reset) */ 241 qnstop(sc); 242 243 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 244 ifp->if_softc = sc; 245 ifp->if_ioctl = qnioctl; 246 ifp->if_watchdog = qnwatchdog; 247 ifp->if_start = qnstart; 248 /* XXX IFF_MULTICAST */ 249 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; 250 ifp->if_mtu = ETHERMTU; 251 252 /* Attach the interface. */ 253 if_attach(ifp); 254 ether_ifattach(ifp, myaddr); 255 256 #ifdef QN_DEBUG 257 printf(": hardware address %s\n", ether_sprintf(myaddr)); 258 #endif 259 260 sc->sc_isr.isr_intr = qnintr; 261 sc->sc_isr.isr_arg = sc; 262 sc->sc_isr.isr_ipl = 2; 263 add_isr(&sc->sc_isr); 264 } 265 266 /* 267 * Initialize device 268 * 269 */ 270 void 271 qninit(sc) 272 struct qn_softc *sc; 273 { 274 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 275 u_short i; 276 static int retry = 0; 277 278 *sc->nic_r_mask = NIC_R_MASK; 279 *sc->nic_t_mode = NO_LOOPBACK; 280 281 if (sc->sc_ethercom.ec_if.if_flags & IFF_PROMISC) { 282 *sc->nic_r_mode = PROMISCUOUS_MODE; 283 log(LOG_INFO, "qn: Promiscuous mode (not tested)\n"); 284 } else 285 *sc->nic_r_mode = NORMAL_MODE; 286 287 /* Set physical ethernet address. */ 288 for (i = 0; i < ETHER_ADDR_LEN; i++) 289 *((u_short volatile *)(sc->sc_nic_base+ 290 QNET_HARDWARE_ADDRESS+2*i)) = 291 ((((u_short)LLADDR(ifp->if_sadl)[i]) << 8) | 292 LLADDR(ifp->if_sadl)[i]); 293 294 ifp->if_flags |= IFF_RUNNING; 295 ifp->if_flags &= ~IFF_OACTIVE; 296 sc->transmit_pending = 0; 297 298 qn_flush(sc); 299 300 /* QuickNet magic. Done ONLY once, otherwise a lockup occurs. */ 301 if (retry == 0) { 302 *((u_short volatile *)(sc->sc_nic_base + QNET_MAGIC)) = 0; 303 retry = 1; 304 } 305 306 /* Enable data link controller. */ 307 *sc->nic_reset = ENABLE_DLC; 308 309 /* Attempt to start output, if any. */ 310 qnstart(ifp); 311 } 312 313 /* 314 * Device timeout/watchdog routine. Entered if the device neglects to 315 * generate an interrupt after a transmit has been started on it. 316 */ 317 void 318 qnwatchdog(ifp) 319 struct ifnet *ifp; 320 { 321 struct qn_softc *sc = ifp->if_softc; 322 323 log(LOG_INFO, "qn: device timeout (watchdog)\n"); 324 ++sc->sc_ethercom.ec_if.if_oerrors; 325 326 qnreset(sc); 327 } 328 329 /* 330 * Flush card's buffer RAM. 331 */ 332 static void 333 qn_flush(sc) 334 struct qn_softc *sc; 335 { 336 #if 1 337 /* Read data until bus read error (i.e. buffer empty). */ 338 while (!(*sc->nic_r_status & R_BUS_RD_ERR)) 339 (void)(*sc->nic_fifo); 340 #else 341 /* Read data twice to clear some internal pipelines. */ 342 (void)(*sc->nic_fifo); 343 (void)(*sc->nic_fifo); 344 #endif 345 346 /* Clear bus read error. */ 347 *sc->nic_r_status = R_BUS_RD_ERR; 348 } 349 350 /* 351 * Reset the interface. 352 * 353 */ 354 void 355 qnreset(sc) 356 struct qn_softc *sc; 357 { 358 int s; 359 360 s = splnet(); 361 qnstop(sc); 362 qninit(sc); 363 splx(s); 364 } 365 366 /* 367 * Take interface offline. 368 */ 369 void 370 qnstop(sc) 371 struct qn_softc *sc; 372 { 373 374 /* Stop the interface. */ 375 *sc->nic_reset = DISABLE_DLC; 376 delay(200); 377 *sc->nic_t_status = CLEAR_T_ERR; 378 *sc->nic_t_mask = CLEAR_T_MASK; 379 *sc->nic_r_status = CLEAR_R_ERR; 380 *sc->nic_r_mask = CLEAR_R_MASK; 381 382 /* Turn DMA off */ 383 *((u_short volatile *)(sc->sc_nic_base + NIC_BMPR4)) = 0; 384 385 /* Accept no packets. */ 386 *sc->nic_r_mode = 0; 387 *sc->nic_t_mode = 0; 388 389 qn_flush(sc); 390 } 391 392 /* 393 * Start output on interface. Get another datagram to send 394 * off the interface queue, and copy it to the 395 * interface before starting the output. 396 * 397 * This assumes that it is called inside a critical section... 398 * 399 */ 400 void 401 qnstart(ifp) 402 struct ifnet *ifp; 403 { 404 struct qn_softc *sc = ifp->if_softc; 405 struct mbuf *m; 406 u_short len; 407 int timout = 60000; 408 409 410 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 411 return; 412 413 IF_DEQUEUE(&ifp->if_snd, m); 414 if (m == 0) 415 return; 416 417 #if NBPFILTER > 0 418 /* 419 * If bpf is listening on this interface, let it 420 * see the packet before we commit it to the wire 421 * 422 * (can't give the copy in QuickNet card RAM to bpf, because 423 * that RAM is not visible to the host but is read from FIFO) 424 * 425 */ 426 if (sc->sc_bpf) 427 bpf_mtap(sc->sc_bpf, m); 428 #endif 429 len = qn_put(sc->nic_fifo, m); 430 m_freem(m); 431 432 /* 433 * Really transmit the packet. 434 */ 435 436 /* Set packet length (byte-swapped). */ 437 len = ((len >> 8) & 0x0007) | TRANSMIT_START | ((len & 0x00ff) << 8); 438 *sc->nic_len = len; 439 440 /* Wait for the packet to really leave. */ 441 while (!(*sc->nic_t_status & T_TMT_OK) && --timout) { 442 if ((timout % 10000) == 0) 443 log(LOG_INFO, "qn: timout...\n"); 444 } 445 446 if (timout == 0) 447 /* Maybe we should try to recover from this one? */ 448 /* But now, let's just fall thru and hope the best... */ 449 log(LOG_INFO, "qn: transmit timout (fatal?)\n"); 450 451 sc->transmit_pending = 1; 452 *sc->nic_t_mask = INT_TMT_OK | INT_SIXTEEN_COL; 453 454 ifp->if_flags |= IFF_OACTIVE; 455 ifp->if_timer = 2; 456 } 457 458 /* 459 * Memory copy, copies word at a time 460 */ 461 static void inline 462 word_copy_from_card(card, b, len) 463 u_short volatile *card; 464 u_short *b, len; 465 { 466 register u_short l = len/2; 467 468 while (l--) 469 *b++ = *card; 470 } 471 472 static void inline 473 word_copy_to_card(a, card, len) 474 u_short *a; 475 u_short volatile *card; 476 register u_short len; 477 { 478 /*register u_short l = len/2;*/ 479 480 while (len--) 481 *card = *a++; 482 } 483 484 /* 485 * Copy packet from mbuf to the board memory 486 * 487 */ 488 static u_short 489 qn_put(addr, m) 490 u_short volatile *addr; 491 struct mbuf *m; 492 { 493 u_short *data; 494 u_char savebyte[2]; 495 int len, len1, wantbyte; 496 u_short totlen; 497 498 totlen = wantbyte = 0; 499 500 for (; m != NULL; m = m->m_next) { 501 data = mtod(m, u_short *); 502 len = m->m_len; 503 if (len > 0) { 504 totlen += len; 505 506 /* Finish the last word. */ 507 if (wantbyte) { 508 savebyte[1] = *((u_char *)data); 509 *addr = *((u_short *)savebyte); 510 ((u_char *)data)++; 511 len--; 512 wantbyte = 0; 513 } 514 /* Output contiguous words. */ 515 if (len > 1) { 516 len1 = len/2; 517 word_copy_to_card(data, addr, len1); 518 data += len1; 519 len &= 1; 520 } 521 /* Save last byte, if necessary. */ 522 if (len == 1) { 523 savebyte[0] = *((u_char *)data); 524 wantbyte = 1; 525 } 526 } 527 } 528 529 if (wantbyte) { 530 savebyte[1] = 0; 531 *addr = *((u_short *)savebyte); 532 } 533 534 if(totlen < (ETHER_MIN_LEN - ETHER_CRC_LEN)) { 535 /* 536 * Fill the rest of the packet with zeros. 537 * N.B.: This is required! Otherwise MB86950 fails. 538 */ 539 for(len = totlen + 1; len < (ETHER_MIN_LEN - ETHER_CRC_LEN); 540 len += 2) 541 *addr = (u_short)0x0000; 542 totlen = (ETHER_MIN_LEN - ETHER_CRC_LEN); 543 } 544 545 return (totlen); 546 } 547 548 /* 549 * Copy packet from board RAM. 550 * 551 * Trailers not supported. 552 * 553 */ 554 static void 555 qn_get_packet(sc, len) 556 struct qn_softc *sc; 557 u_short len; 558 { 559 register u_short volatile *nic_fifo_ptr = sc->nic_fifo; 560 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 561 struct mbuf *m, *dst, *head = NULL; 562 register u_short len1; 563 u_short amount; 564 565 /* Allocate header mbuf. */ 566 MGETHDR(m, M_DONTWAIT, MT_DATA); 567 if (m == NULL) 568 goto bad; 569 570 /* 571 * Round len to even value. 572 */ 573 if (len & 1) 574 len++; 575 576 m->m_pkthdr.rcvif = &sc->sc_ethercom.ec_if; 577 m->m_pkthdr.len = len; 578 m->m_len = 0; 579 head = m; 580 581 word_copy_from_card(nic_fifo_ptr, 582 mtod(head, u_short *), 583 sizeof(struct ether_header)); 584 585 head->m_len += sizeof(struct ether_header); 586 len -= sizeof(struct ether_header); 587 588 while (len > 0) { 589 len1 = len; 590 591 amount = M_TRAILINGSPACE(m); 592 if (amount == 0) { 593 /* Allocate another mbuf. */ 594 dst = m; 595 MGET(m, M_DONTWAIT, MT_DATA); 596 if (m == NULL) 597 goto bad; 598 599 if (len1 >= MINCLSIZE) 600 MCLGET(m, M_DONTWAIT); 601 602 m->m_len = 0; 603 dst->m_next = m; 604 605 amount = M_TRAILINGSPACE(m); 606 } 607 608 if (amount < len1) 609 len1 = amount; 610 611 word_copy_from_card(nic_fifo_ptr, 612 (u_short *)(mtod(m, caddr_t) + m->m_len), 613 len1); 614 m->m_len += len1; 615 len -= len1; 616 } 617 618 #if NBPFILTER > 0 619 if (sc->sc_bpf) 620 bpf_mtap(sc->sc_bpf, head); 621 #endif 622 623 (*ifp->if_input)(ifp, head); 624 return; 625 626 bad: 627 if (head) { 628 m_freem(head); 629 log(LOG_INFO, "qn_get_packet: mbuf alloc failed\n"); 630 } 631 } 632 633 /* 634 * Ethernet interface receiver interrupt. 635 */ 636 static void 637 qn_rint(sc, rstat) 638 struct qn_softc *sc; 639 u_short rstat; 640 { 641 int i; 642 u_short len, status; 643 644 /* Clear the status register. */ 645 *sc->nic_r_status = CLEAR_R_ERR; 646 647 /* 648 * Was there some error? 649 * Some of them are senseless because they are masked off. 650 * XXX 651 */ 652 if (rstat & R_INT_OVR_FLO) { 653 #ifdef QN_DEBUG 654 log(LOG_INFO, "Overflow\n"); 655 #endif 656 ++sc->sc_ethercom.ec_if.if_ierrors; 657 } 658 if (rstat & R_INT_CRC_ERR) { 659 #ifdef QN_DEBUG 660 log(LOG_INFO, "CRC Error\n"); 661 #endif 662 ++sc->sc_ethercom.ec_if.if_ierrors; 663 } 664 if (rstat & R_INT_ALG_ERR) { 665 #ifdef QN_DEBUG 666 log(LOG_INFO, "Alignment error\n"); 667 #endif 668 ++sc->sc_ethercom.ec_if.if_ierrors; 669 } 670 if (rstat & R_INT_SRT_PKT) { 671 /* Short packet (these may occur and are 672 * no reason to worry about - or maybe 673 * they are?). 674 */ 675 #ifdef QN_DEBUG 676 log(LOG_INFO, "Short packet\n"); 677 #endif 678 ++sc->sc_ethercom.ec_if.if_ierrors; 679 } 680 if (rstat & 0x4040) { 681 #ifdef QN_DEBUG 682 log(LOG_INFO, "Bus read error\n"); 683 #endif 684 ++sc->sc_ethercom.ec_if.if_ierrors; 685 qnreset(sc); 686 } 687 688 /* 689 * Read at most MAX_PACKETS packets per interrupt 690 */ 691 for (i = 0; i < MAX_PACKETS; i++) { 692 if (*sc->nic_r_mode & RM_BUF_EMP) 693 /* Buffer empty. */ 694 break; 695 696 /* 697 * Read the first word: upper byte contains useful 698 * information. 699 */ 700 status = *sc->nic_fifo; 701 if ((status & 0x7000) != 0x2000) { 702 log(LOG_INFO, "qn: ERROR: status=%04x\n", status); 703 continue; 704 } 705 706 /* 707 * Read packet length (byte-swapped). 708 * CRC is stripped off by the NIC. 709 */ 710 len = *sc->nic_fifo; 711 len = ((len << 8) & 0xff00) | ((len >> 8) & 0x00ff); 712 713 #ifdef QN_CHECKS 714 if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN) || 715 len < ETHER_HDR_LEN) { 716 log(LOG_WARNING, 717 "%s: received a %s packet? (%u bytes)\n", 718 sc->sc_dev.dv_xname, 719 len < ETHER_HDR_LEN ? "partial" : "big", len); 720 ++sc->sc_ethercom.ec_if.if_ierrors; 721 continue; 722 } 723 #endif 724 #ifdef QN_CHECKS 725 if (len < (ETHER_MIN_LEN - ETHER_CRC_LEN)) 726 log(LOG_WARNING, 727 "%s: received a short packet? (%u bytes)\n", 728 sc->sc_dev.dv_xname, len); 729 #endif 730 731 /* Read the packet. */ 732 qn_get_packet(sc, len); 733 734 ++sc->sc_ethercom.ec_if.if_ipackets; 735 } 736 737 #ifdef QN_DEBUG 738 /* This print just to see whether MAX_PACKETS is large enough. */ 739 if (i == MAX_PACKETS) 740 log(LOG_INFO, "used all the %d loops\n", MAX_PACKETS); 741 #endif 742 } 743 744 /* 745 * Our interrupt routine 746 */ 747 int 748 qnintr(arg) 749 void *arg; 750 { 751 struct qn_softc *sc = arg; 752 u_short tint, rint, tintmask; 753 char return_tintmask = 0; 754 755 /* 756 * If the driver has not been initialized, just return immediately. 757 * This also happens if there is no QuickNet board present. 758 */ 759 if (sc->sc_base == NULL) 760 return (0); 761 762 /* Get interrupt statuses and masks. */ 763 rint = (*sc->nic_r_status) & NIC_R_MASK; 764 tintmask = *sc->nic_t_mask; 765 tint = (*sc->nic_t_status) & tintmask; 766 if (tint == 0 && rint == 0) 767 return (0); 768 769 /* Disable interrupts so that we won't miss anything. */ 770 *sc->nic_r_mask = CLEAR_R_MASK; 771 *sc->nic_t_mask = CLEAR_T_MASK; 772 773 /* 774 * Handle transmitter interrupts. Some of them are not asked for 775 * but do happen, anyway. 776 */ 777 778 if (tint != 0) { 779 /* Clear transmit interrupt status. */ 780 *sc->nic_t_status = CLEAR_T_ERR; 781 782 if (sc->transmit_pending && (tint & T_TMT_OK)) { 783 sc->transmit_pending = 0; 784 /* 785 * Update total number of successfully 786 * transmitted packets. 787 */ 788 sc->sc_ethercom.ec_if.if_opackets++; 789 } 790 791 if (tint & T_SIXTEEN_COL) { 792 /* 793 * 16 collision (i.e., packet lost). 794 */ 795 log(LOG_INFO, "qn: 16 collision - packet lost\n"); 796 #ifdef QN_DEBUG1 797 qn_dump(sc); 798 #endif 799 sc->sc_ethercom.ec_if.if_oerrors++; 800 sc->sc_ethercom.ec_if.if_collisions += 16; 801 sc->transmit_pending = 0; 802 } 803 804 if (sc->transmit_pending) { 805 log(LOG_INFO, "qn:still pending...\n"); 806 807 /* Must return transmission interrupt mask. */ 808 return_tintmask = 1; 809 } else { 810 sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE; 811 812 /* Clear watchdog timer. */ 813 sc->sc_ethercom.ec_if.if_timer = 0; 814 } 815 } else 816 return_tintmask = 1; 817 818 /* 819 * Handle receiver interrupts. 820 */ 821 if (rint != 0) 822 qn_rint(sc, rint); 823 824 if ((sc->sc_ethercom.ec_if.if_flags & IFF_OACTIVE) == 0) 825 qnstart(&sc->sc_ethercom.ec_if); 826 else if (return_tintmask == 1) 827 *sc->nic_t_mask = tintmask; 828 829 /* Set receive interrupt mask back. */ 830 *sc->nic_r_mask = NIC_R_MASK; 831 832 return (1); 833 } 834 835 /* 836 * Process an ioctl request. This code needs some work - it looks pretty ugly. 837 * I somehow think that this is quite a common excuse... ;-) 838 */ 839 int 840 qnioctl(ifp, command, data) 841 register struct ifnet *ifp; 842 u_long command; 843 caddr_t data; 844 { 845 struct qn_softc *sc = ifp->if_softc; 846 register struct ifaddr *ifa = (struct ifaddr *)data; 847 #if 0 848 struct ifreg *ifr = (struct ifreg *)data; 849 #endif 850 int s, error = 0; 851 852 s = splnet(); 853 854 switch (command) { 855 856 case SIOCSIFADDR: 857 ifp->if_flags |= IFF_UP; 858 859 switch (ifa->ifa_addr->sa_family) { 860 #ifdef INET 861 case AF_INET: 862 qnstop(sc); 863 qninit(sc); 864 arp_ifinit(ifp, ifa); 865 break; 866 #endif 867 #ifdef NS 868 case AF_NS: 869 { 870 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 871 872 if (ns_nullhost(*ina)) 873 ina->x_host = 874 *(union ns_host *)LLADDR(ifp->if_sadl); 875 else 876 bcopy(ina->x_host.c_host, 877 LLADDR(ifp->if_sadl), ETHER_ADDR_LEN); 878 qnstop(sc); 879 qninit(sc); 880 break; 881 } 882 #endif 883 default: 884 log(LOG_INFO, "qn:sa_family:default (not tested)\n"); 885 qnstop(sc); 886 qninit(sc); 887 break; 888 } 889 break; 890 891 case SIOCSIFFLAGS: 892 if ((ifp->if_flags & IFF_UP) == 0 && 893 (ifp->if_flags & IFF_RUNNING) != 0) { 894 /* 895 * If interface is marked down and it is running, then 896 * stop it. 897 */ 898 #ifdef QN_DEBUG1 899 qn_dump(sc); 900 #endif 901 qnstop(sc); 902 ifp->if_flags &= ~IFF_RUNNING; 903 } else if ((ifp->if_flags & IFF_UP) != 0 && 904 (ifp->if_flags & IFF_RUNNING) == 0) { 905 /* 906 * If interface is marked up and it is stopped, then 907 * start it. 908 */ 909 qninit(sc); 910 } else { 911 /* 912 * Something else... we won't do anything so we won't 913 * break anything (hope so). 914 */ 915 #ifdef QN_DEBUG1 916 log(LOG_INFO, "Else branch...\n"); 917 #endif 918 } 919 break; 920 921 case SIOCADDMULTI: 922 case SIOCDELMULTI: 923 log(LOG_INFO, "qnioctl: multicast not done yet\n"); 924 #if 0 925 error = (command == SIOCADDMULTI) ? 926 ether_addmulti(ifr, &sc->sc_ethercom) : 927 ether_delmulti(ifr, &sc->sc_ethercom); 928 929 if (error == ENETRESET) { 930 /* 931 * Multicast list has changed; set the hardware filter 932 * accordingly. 933 */ 934 log(LOG_INFO, "qnioctl: multicast not done yet\n"); 935 error = 0; 936 } 937 #else 938 error = EINVAL; 939 #endif 940 break; 941 942 default: 943 log(LOG_INFO, "qnioctl: default\n"); 944 error = EINVAL; 945 } 946 947 splx(s); 948 return (error); 949 } 950 951 /* 952 * Dump some register information. 953 */ 954 #ifdef QN_DEBUG1 955 static void 956 qn_dump(sc) 957 struct qn_softc *sc; 958 { 959 960 log(LOG_INFO, "t_status : %04x\n", *sc->nic_t_status); 961 log(LOG_INFO, "t_mask : %04x\n", *sc->nic_t_mask); 962 log(LOG_INFO, "t_mode : %04x\n", *sc->nic_t_mode); 963 log(LOG_INFO, "r_status : %04x\n", *sc->nic_r_status); 964 log(LOG_INFO, "r_mask : %04x\n", *sc->nic_r_mask); 965 log(LOG_INFO, "r_mode : %04x\n", *sc->nic_r_mode); 966 log(LOG_INFO, "pending : %02x\n", sc->transmit_pending); 967 log(LOG_INFO, "if_flags : %04x\n", sc->sc_ethercom.ec_if.if_flags); 968 } 969 #endif 970 971 #endif /* NQN > 0 */ 972