1 /* $NetBSD: if_qn.c,v 1.12 1997/03/17 18:04:40 is 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 <sys/param.h> 83 #include <sys/systm.h> 84 #include <sys/mbuf.h> 85 #include <sys/buf.h> 86 #include <sys/device.h> 87 #include <sys/protosw.h> 88 #include <sys/socket.h> 89 #include <sys/syslog.h> 90 #include <sys/ioctl.h> 91 #include <sys/errno.h> 92 93 #include <net/if.h> 94 #include <net/if_dl.h> 95 #include <net/if_ether.h> 96 97 #ifdef INET 98 #include <netinet/in.h> 99 #include <netinet/in_systm.h> 100 #include <netinet/in_var.h> 101 #include <netinet/ip.h> 102 #include <netinet/if_inarp.h> 103 #endif 104 105 #ifdef NS 106 #include <netns/ns.h> 107 #include <netns/ns_if.h> 108 #endif 109 110 #include <machine/cpu.h> 111 #include <machine/mtpr.h> 112 #include <amiga/amiga/device.h> 113 #include <amiga/amiga/isr.h> 114 #include <amiga/dev/zbusvar.h> 115 #include <amiga/dev/if_qnreg.h> 116 117 118 #define ETHER_MIN_LEN 60 119 #define ETHER_MAX_LEN 1514 120 #define ETHER_HDR_SIZE 14 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 struct cfdriver qn_cd = { 183 NULL, "qn", DV_IFNET 184 }; 185 186 187 int 188 qnmatch(parent, cfp, aux) 189 struct device *parent; 190 struct cfdata *cfp; 191 void *aux; 192 { 193 struct zbus_args *zap; 194 195 zap = (struct zbus_args *)aux; 196 197 /* RMF QuickNet QN2000 EtherNet card */ 198 if (zap->manid == 2011 && zap->prodid == 2) 199 return (1); 200 201 return (0); 202 } 203 204 /* 205 * Interface exists: make available by filling in network interface 206 * record. System will initialize the interface when it is ready 207 * to accept packets. 208 */ 209 void 210 qnattach(parent, self, aux) 211 struct device *parent, *self; 212 void *aux; 213 { 214 struct zbus_args *zap; 215 struct qn_softc *sc = (struct qn_softc *)self; 216 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 217 u_int8_t myaddr[ETHER_ADDR_LEN]; 218 219 zap = (struct zbus_args *)aux; 220 221 sc->sc_base = zap->va; 222 sc->sc_nic_base = sc->sc_base + QUICKNET_NIC_BASE; 223 sc->nic_fifo = (u_short volatile *)(sc->sc_nic_base + NIC_BMPR0); 224 sc->nic_len = (u_short volatile *)(sc->sc_nic_base + NIC_BMPR2); 225 sc->nic_t_status = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR0); 226 sc->nic_r_status = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR2); 227 sc->nic_t_mask = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR1); 228 sc->nic_r_mask = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR3); 229 sc->nic_t_mode = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR4); 230 sc->nic_r_mode = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR5); 231 sc->nic_reset = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR6); 232 sc->transmit_pending = 0; 233 234 /* 235 * The ethernet address of the board (1st three bytes are the vendor 236 * address, the rest is the serial number of the board). 237 */ 238 myaddr[0] = 0x5c; 239 myaddr[1] = 0x5c; 240 myaddr[2] = 0x00; 241 myaddr[3] = (zap->serno >> 16) & 0xff; 242 myaddr[4] = (zap->serno >> 8) & 0xff; 243 myaddr[5] = zap->serno & 0xff; 244 245 /* set interface to stopped condition (reset) */ 246 qnstop(sc); 247 248 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 249 ifp->if_softc = sc; 250 ifp->if_ioctl = qnioctl; 251 ifp->if_watchdog = qnwatchdog; 252 ifp->if_output = ether_output; 253 ifp->if_start = qnstart; 254 /* XXX IFF_MULTICAST */ 255 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; 256 ifp->if_mtu = ETHERMTU; 257 258 /* Attach the interface. */ 259 if_attach(ifp); 260 ether_ifattach(ifp, myaddr); 261 262 #ifdef QN_DEBUG 263 printf(": hardware address %s\n", ether_sprintf(myaddr)); 264 #endif 265 266 #if NBPFILTER > 0 267 bpfattach(&sc->sc_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 268 #endif 269 270 sc->sc_isr.isr_intr = qnintr; 271 sc->sc_isr.isr_arg = sc; 272 sc->sc_isr.isr_ipl = 2; 273 add_isr(&sc->sc_isr); 274 } 275 276 /* 277 * Initialize device 278 * 279 */ 280 void 281 qninit(sc) 282 struct qn_softc *sc; 283 { 284 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 285 u_short i; 286 static retry = 0; 287 288 *sc->nic_r_mask = NIC_R_MASK; 289 *sc->nic_t_mode = NO_LOOPBACK; 290 291 if (sc->sc_ethercom.ec_if.if_flags & IFF_PROMISC) { 292 *sc->nic_r_mode = PROMISCUOUS_MODE; 293 log(LOG_INFO, "qn: Promiscuous mode (not tested)\n"); 294 } else 295 *sc->nic_r_mode = NORMAL_MODE; 296 297 /* Set physical ethernet address. */ 298 for (i = 0; i < ETHER_ADDR_LEN; i++) 299 *((u_short volatile *)(sc->sc_nic_base+ 300 QNET_HARDWARE_ADDRESS+2*i)) = 301 ((((u_short)LLADDR(ifp->if_sadl)[i]) << 8) | 302 LLADDR(ifp->if_sadl)[i]); 303 304 ifp->if_flags |= IFF_RUNNING; 305 ifp->if_flags &= ~IFF_OACTIVE; 306 sc->transmit_pending = 0; 307 308 qn_flush(sc); 309 310 /* QuickNet magic. Done ONLY once, otherwise a lockup occurs. */ 311 if (retry == 0) { 312 *((u_short volatile *)(sc->sc_nic_base + QNET_MAGIC)) = 0; 313 retry = 1; 314 } 315 316 /* Enable data link controller. */ 317 *sc->nic_reset = ENABLE_DLC; 318 319 /* Attempt to start output, if any. */ 320 qnstart(ifp); 321 } 322 323 /* 324 * Device timeout/watchdog routine. Entered if the device neglects to 325 * generate an interrupt after a transmit has been started on it. 326 */ 327 void 328 qnwatchdog(ifp) 329 struct ifnet *ifp; 330 { 331 struct qn_softc *sc = ifp->if_softc; 332 333 log(LOG_INFO, "qn: device timeout (watchdog)\n"); 334 ++sc->sc_ethercom.ec_if.if_oerrors; 335 336 qnreset(sc); 337 } 338 339 /* 340 * Flush card's buffer RAM. 341 */ 342 static void 343 qn_flush(sc) 344 struct qn_softc *sc; 345 { 346 #if 1 347 /* Read data until bus read error (i.e. buffer empty). */ 348 while (!(*sc->nic_r_status & R_BUS_RD_ERR)) 349 (void)(*sc->nic_fifo); 350 #else 351 /* Read data twice to clear some internal pipelines. */ 352 (void)(*sc->nic_fifo); 353 (void)(*sc->nic_fifo); 354 #endif 355 356 /* Clear bus read error. */ 357 *sc->nic_r_status = R_BUS_RD_ERR; 358 } 359 360 /* 361 * Reset the interface. 362 * 363 */ 364 void 365 qnreset(sc) 366 struct qn_softc *sc; 367 { 368 int s; 369 370 s = splnet(); 371 qnstop(sc); 372 qninit(sc); 373 splx(s); 374 } 375 376 /* 377 * Take interface offline. 378 */ 379 void 380 qnstop(sc) 381 struct qn_softc *sc; 382 { 383 384 /* Stop the interface. */ 385 *sc->nic_reset = DISABLE_DLC; 386 delay(200); 387 *sc->nic_t_status = CLEAR_T_ERR; 388 *sc->nic_t_mask = CLEAR_T_MASK; 389 *sc->nic_r_status = CLEAR_R_ERR; 390 *sc->nic_r_mask = CLEAR_R_MASK; 391 392 /* Turn DMA off */ 393 *((u_short volatile *)(sc->sc_nic_base + NIC_BMPR4)) = 0; 394 395 /* Accept no packets. */ 396 *sc->nic_r_mode = 0; 397 *sc->nic_t_mode = 0; 398 399 qn_flush(sc); 400 } 401 402 /* 403 * Start output on interface. Get another datagram to send 404 * off the interface queue, and copy it to the 405 * interface before starting the output. 406 * 407 * This assumes that it is called inside a critical section... 408 * 409 */ 410 void 411 qnstart(ifp) 412 struct ifnet *ifp; 413 { 414 struct qn_softc *sc = ifp->if_softc; 415 struct mbuf *m; 416 u_short len; 417 int timout = 60000; 418 419 420 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 421 return; 422 423 IF_DEQUEUE(&ifp->if_snd, m); 424 if (m == 0) 425 return; 426 427 #if NBPFILTER > 0 428 /* 429 * If bpf is listening on this interface, let it 430 * see the packet before we commit it to the wire 431 * 432 * (can't give the copy in QuickNet card RAM to bpf, because 433 * that RAM is not visible to the host but is read from FIFO) 434 * 435 */ 436 if (sc->sc_bpf) 437 bpf_mtap(sc->sc_bpf, m); 438 #endif 439 len = qn_put(sc->nic_fifo, m); 440 m_freem(m); 441 442 /* 443 * Really transmit the packet. 444 */ 445 446 /* Set packet length (byte-swapped). */ 447 len = ((len >> 8) & 0x0007) | TRANSMIT_START | ((len & 0x00ff) << 8); 448 *sc->nic_len = len; 449 450 /* Wait for the packet to really leave. */ 451 while (!(*sc->nic_t_status & T_TMT_OK) && --timout) { 452 if ((timout % 10000) == 0) 453 log(LOG_INFO, "qn: timout...\n"); 454 } 455 456 if (timout == 0) 457 /* Maybe we should try to recover from this one? */ 458 /* But now, let's just fall thru and hope the best... */ 459 log(LOG_INFO, "qn: transmit timout (fatal?)\n"); 460 461 sc->transmit_pending = 1; 462 *sc->nic_t_mask = INT_TMT_OK | INT_SIXTEEN_COL; 463 464 ifp->if_flags |= IFF_OACTIVE; 465 ifp->if_timer = 2; 466 } 467 468 /* 469 * Memory copy, copies word at a time 470 */ 471 static void inline 472 word_copy_from_card(card, b, len) 473 u_short volatile *card; 474 u_short *b, len; 475 { 476 register u_short l = len/2; 477 478 while (l--) 479 *b++ = *card; 480 } 481 482 static void inline 483 word_copy_to_card(a, card, len) 484 u_short *a; 485 u_short volatile *card; 486 register u_short len; 487 { 488 /*register u_short l = len/2;*/ 489 490 while (len--) 491 *card = *a++; 492 } 493 494 /* 495 * Copy packet from mbuf to the board memory 496 * 497 */ 498 static u_short 499 qn_put(addr, m) 500 u_short volatile *addr; 501 struct mbuf *m; 502 { 503 u_short *data; 504 u_char savebyte[2]; 505 int len, len1, wantbyte; 506 u_short totlen; 507 508 totlen = wantbyte = 0; 509 510 for (; m != NULL; m = m->m_next) { 511 data = mtod(m, u_short *); 512 len = m->m_len; 513 if (len > 0) { 514 totlen += len; 515 516 /* Finish the last word. */ 517 if (wantbyte) { 518 savebyte[1] = *((u_char *)data); 519 *addr = *((u_short *)savebyte); 520 ((u_char *)data)++; 521 len--; 522 wantbyte = 0; 523 } 524 /* Output contiguous words. */ 525 if (len > 1) { 526 len1 = len/2; 527 word_copy_to_card(data, addr, len1); 528 data += len1; 529 len &= 1; 530 } 531 /* Save last byte, if necessary. */ 532 if (len == 1) { 533 savebyte[0] = *((u_char *)data); 534 wantbyte = 1; 535 } 536 } 537 } 538 539 if (wantbyte) { 540 savebyte[1] = 0; 541 *addr = *((u_short *)savebyte); 542 } 543 544 if(totlen < ETHER_MIN_LEN) { 545 /* 546 * Fill the rest of the packet with zeros. 547 * N.B.: This is required! Otherwise MB86950 fails. 548 */ 549 for(len = totlen + 1; len < ETHER_MIN_LEN; len += 2) 550 *addr = (u_short)0x0000; 551 totlen = ETHER_MIN_LEN; 552 } 553 554 return (totlen); 555 } 556 557 /* 558 * Copy packet from board RAM. 559 * 560 * Trailers not supported. 561 * 562 */ 563 static void 564 qn_get_packet(sc, len) 565 struct qn_softc *sc; 566 u_short len; 567 { 568 register u_short volatile *nic_fifo_ptr = sc->nic_fifo; 569 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 570 struct ether_header *eh; 571 struct mbuf *m, *dst, *head = NULL; 572 register u_short len1; 573 u_short amount; 574 575 /* Allocate header mbuf. */ 576 MGETHDR(m, M_DONTWAIT, MT_DATA); 577 if (m == NULL) 578 goto bad; 579 580 /* 581 * Round len to even value. 582 */ 583 if (len & 1) 584 len++; 585 586 m->m_pkthdr.rcvif = &sc->sc_ethercom.ec_if; 587 m->m_pkthdr.len = len; 588 m->m_len = 0; 589 head = m; 590 591 eh = mtod(head, struct ether_header *); 592 593 word_copy_from_card(nic_fifo_ptr, 594 mtod(head, u_short *), 595 sizeof(struct ether_header)); 596 597 head->m_len += sizeof(struct ether_header); 598 len -= sizeof(struct ether_header); 599 600 while (len > 0) { 601 len1 = len; 602 603 amount = M_TRAILINGSPACE(m); 604 if (amount == 0) { 605 /* Allocate another mbuf. */ 606 dst = m; 607 MGET(m, M_DONTWAIT, MT_DATA); 608 if (m == NULL) 609 goto bad; 610 611 if (len1 >= MINCLSIZE) 612 MCLGET(m, M_DONTWAIT); 613 614 m->m_len = 0; 615 dst->m_next = m; 616 617 amount = M_TRAILINGSPACE(m); 618 } 619 620 if (amount < len1) 621 len1 = amount; 622 623 word_copy_from_card(nic_fifo_ptr, 624 (u_short *)(mtod(m, caddr_t) + m->m_len), 625 len1); 626 m->m_len += len1; 627 len -= len1; 628 } 629 630 #if NBPFILTER > 0 631 if (sc->sc_bpf) { 632 bpf_mtap(sc->sc_bpf, head); 633 634 /* 635 * The interface cannot be in promiscuous mode if there are 636 * no BPF listeners. And in prom. mode we have to check 637 * if the packet is really ours... 638 */ 639 if ((ifp->if_flags & IFF_PROMISC) && 640 (eh->ether_dhost[0] & 1) == 0 && /* not bcast or mcast */ 641 bcmp(eh->ether_dhost, 642 LLADDR(ifp->if_sadl), 643 ETHER_ADDR_LEN) != 0) { 644 m_freem(head); 645 return; 646 } 647 } 648 #endif 649 650 m_adj(head, sizeof(struct ether_header)); 651 ether_input(ifp, eh, head); 652 return; 653 654 bad: 655 if (head) { 656 m_freem(head); 657 log(LOG_INFO, "qn_get_packet: mbuf alloc failed\n"); 658 } 659 } 660 661 /* 662 * Ethernet interface receiver interrupt. 663 */ 664 static void 665 qn_rint(sc, rstat) 666 struct qn_softc *sc; 667 u_short rstat; 668 { 669 int i; 670 u_short len, status; 671 672 /* Clear the status register. */ 673 *sc->nic_r_status = CLEAR_R_ERR; 674 675 /* 676 * Was there some error? 677 * Some of them are senseless because they are masked off. 678 * XXX 679 */ 680 if (rstat & R_INT_OVR_FLO) { 681 #ifdef QN_DEBUG 682 log(LOG_INFO, "Overflow\n"); 683 #endif 684 ++sc->sc_ethercom.ec_if.if_ierrors; 685 } 686 if (rstat & R_INT_CRC_ERR) { 687 #ifdef QN_DEBUG 688 log(LOG_INFO, "CRC Error\n"); 689 #endif 690 ++sc->sc_ethercom.ec_if.if_ierrors; 691 } 692 if (rstat & R_INT_ALG_ERR) { 693 #ifdef QN_DEBUG 694 log(LOG_INFO, "Alignment error\n"); 695 #endif 696 ++sc->sc_ethercom.ec_if.if_ierrors; 697 } 698 if (rstat & R_INT_SRT_PKT) { 699 /* Short packet (these may occur and are 700 * no reason to worry about - or maybe 701 * they are?). 702 */ 703 #ifdef QN_DEBUG 704 log(LOG_INFO, "Short packet\n"); 705 #endif 706 ++sc->sc_ethercom.ec_if.if_ierrors; 707 } 708 if (rstat & 0x4040) { 709 #ifdef QN_DEBUG 710 log(LOG_INFO, "Bus read error\n"); 711 #endif 712 ++sc->sc_ethercom.ec_if.if_ierrors; 713 qnreset(sc); 714 } 715 716 /* 717 * Read at most MAX_PACKETS packets per interrupt 718 */ 719 for (i = 0; i < MAX_PACKETS; i++) { 720 if (*sc->nic_r_mode & RM_BUF_EMP) 721 /* Buffer empty. */ 722 break; 723 724 /* 725 * Read the first word: upper byte contains useful 726 * information. 727 */ 728 status = *sc->nic_fifo; 729 if ((status & 0x7000) != 0x2000) { 730 log(LOG_INFO, "qn: ERROR: status=%04x\n", status); 731 continue; 732 } 733 734 /* 735 * Read packet length (byte-swapped). 736 * CRC is stripped off by the NIC. 737 */ 738 len = *sc->nic_fifo; 739 len = ((len << 8) & 0xff00) | ((len >> 8) & 0x00ff); 740 741 #ifdef QN_CHECKS 742 if (len > ETHER_MAX_LEN || len < ETHER_HDR_SIZE) { 743 log(LOG_WARNING, 744 "%s: received a %s packet? (%u bytes)\n", 745 sc->sc_dev.dv_xname, 746 len < ETHER_HDR_SIZE ? "partial" : "big", len); 747 ++sc->sc_ethercom.ec_if.if_ierrors; 748 continue; 749 } 750 #endif 751 #ifdef QN_CHECKS 752 if (len < ETHER_MIN_LEN) 753 log(LOG_WARNING, 754 "%s: received a short packet? (%u bytes)\n", 755 sc->sc_dev.dv_xname, len); 756 #endif 757 758 /* Read the packet. */ 759 qn_get_packet(sc, len); 760 761 ++sc->sc_ethercom.ec_if.if_ipackets; 762 } 763 764 #ifdef QN_DEBUG 765 /* This print just to see whether MAX_PACKETS is large enough. */ 766 if (i == MAX_PACKETS) 767 log(LOG_INFO, "used all the %d loops\n", MAX_PACKETS); 768 #endif 769 } 770 771 /* 772 * Our interrupt routine 773 */ 774 int 775 qnintr(arg) 776 void *arg; 777 { 778 struct qn_softc *sc = arg; 779 u_short tint, rint, tintmask; 780 char return_tintmask = 0; 781 782 /* 783 * If the driver has not been initialized, just return immediately. 784 * This also happens if there is no QuickNet board present. 785 */ 786 if (sc->sc_base == NULL) 787 return (0); 788 789 /* Get interrupt statuses and masks. */ 790 rint = (*sc->nic_r_status) & NIC_R_MASK; 791 tintmask = *sc->nic_t_mask; 792 tint = (*sc->nic_t_status) & tintmask; 793 if (tint == 0 && rint == 0) 794 return (0); 795 796 /* Disable interrupts so that we won't miss anything. */ 797 *sc->nic_r_mask = CLEAR_R_MASK; 798 *sc->nic_t_mask = CLEAR_T_MASK; 799 800 /* 801 * Handle transmitter interrupts. Some of them are not asked for 802 * but do happen, anyway. 803 */ 804 805 if (tint != 0) { 806 /* Clear transmit interrupt status. */ 807 *sc->nic_t_status = CLEAR_T_ERR; 808 809 if (sc->transmit_pending && (tint & T_TMT_OK)) { 810 sc->transmit_pending = 0; 811 /* 812 * Update total number of successfully 813 * transmitted packets. 814 */ 815 sc->sc_ethercom.ec_if.if_opackets++; 816 } 817 818 if (tint & T_SIXTEEN_COL) { 819 /* 820 * 16 collision (i.e., packet lost). 821 */ 822 log(LOG_INFO, "qn: 16 collision - packet lost\n"); 823 #ifdef QN_DEBUG1 824 qn_dump(sc); 825 #endif 826 sc->sc_ethercom.ec_if.if_oerrors++; 827 sc->sc_ethercom.ec_if.if_collisions += 16; 828 sc->transmit_pending = 0; 829 } 830 831 if (sc->transmit_pending) { 832 log(LOG_INFO, "qn:still pending...\n"); 833 834 /* Must return transmission interrupt mask. */ 835 return_tintmask = 1; 836 } else { 837 sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE; 838 839 /* Clear watchdog timer. */ 840 sc->sc_ethercom.ec_if.if_timer = 0; 841 } 842 } else 843 return_tintmask = 1; 844 845 /* 846 * Handle receiver interrupts. 847 */ 848 if (rint != 0) 849 qn_rint(sc, rint); 850 851 if ((sc->sc_ethercom.ec_if.if_flags & IFF_OACTIVE) == 0) 852 qnstart(&sc->sc_ethercom.ec_if); 853 else if (return_tintmask == 1) 854 *sc->nic_t_mask = tintmask; 855 856 /* Set receive interrupt mask back. */ 857 *sc->nic_r_mask = NIC_R_MASK; 858 859 return (1); 860 } 861 862 /* 863 * Process an ioctl request. This code needs some work - it looks pretty ugly. 864 * I somehow think that this is quite a common excuse... ;-) 865 */ 866 int 867 qnioctl(ifp, command, data) 868 register struct ifnet *ifp; 869 u_long command; 870 caddr_t data; 871 { 872 struct qn_softc *sc = ifp->if_softc; 873 register struct ifaddr *ifa = (struct ifaddr *)data; 874 #if 0 875 struct ifreg *ifr = (struct ifreg *)data; 876 #endif 877 int s, error = 0; 878 879 s = splnet(); 880 881 switch (command) { 882 883 case SIOCSIFADDR: 884 ifp->if_flags |= IFF_UP; 885 886 switch (ifa->ifa_addr->sa_family) { 887 #ifdef INET 888 case AF_INET: 889 qnstop(sc); 890 qninit(sc); 891 arp_ifinit(ifp, ifa); 892 break; 893 #endif 894 #ifdef NS 895 case AF_NS: 896 { 897 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 898 899 if (ns_nullhost(*ina)) 900 ina->x_host = 901 *(union ns_host *)LLADDR(ifp->if_sadl); 902 else 903 bcopy(ina->x_host.c_host, 904 LLADDR(ifp->if_sadl), ETHER_ADDR_LEN); 905 qnstop(sc); 906 qninit(sc); 907 break; 908 } 909 #endif 910 default: 911 log(LOG_INFO, "qn:sa_family:default (not tested)\n"); 912 qnstop(sc); 913 qninit(sc); 914 break; 915 } 916 break; 917 918 case SIOCSIFFLAGS: 919 if ((ifp->if_flags & IFF_UP) == 0 && 920 (ifp->if_flags & IFF_RUNNING) != 0) { 921 /* 922 * If interface is marked down and it is running, then 923 * stop it. 924 */ 925 #ifdef QN_DEBUG1 926 qn_dump(sc); 927 #endif 928 qnstop(sc); 929 ifp->if_flags &= ~IFF_RUNNING; 930 } else if ((ifp->if_flags & IFF_UP) != 0 && 931 (ifp->if_flags & IFF_RUNNING) == 0) { 932 /* 933 * If interface is marked up and it is stopped, then 934 * start it. 935 */ 936 qninit(sc); 937 } else { 938 /* 939 * Something else... we won't do anything so we won't 940 * break anything (hope so). 941 */ 942 #ifdef QN_DEBUG1 943 log(LOG_INFO, "Else branch...\n"); 944 #endif 945 } 946 break; 947 948 case SIOCADDMULTI: 949 case SIOCDELMULTI: 950 log(LOG_INFO, "qnioctl: multicast not done yet\n"); 951 #if 0 952 error = (command == SIOCADDMULTI) ? 953 ether_addmulti(ifr, &sc->sc_ethercom) : 954 ether_delmulti(ifr, &sc->sc_ethercom); 955 956 if (error == ENETRESET) { 957 /* 958 * Multicast list has changed; set the hardware filter 959 * accordingly. 960 */ 961 log(LOG_INFO, "qnioctl: multicast not done yet\n"); 962 error = 0; 963 } 964 #else 965 error = EINVAL; 966 #endif 967 break; 968 969 default: 970 log(LOG_INFO, "qnioctl: default\n"); 971 error = EINVAL; 972 } 973 974 splx(s); 975 return (error); 976 } 977 978 /* 979 * Dump some register information. 980 */ 981 #ifdef QN_DEBUG1 982 static void 983 qn_dump(sc) 984 struct qn_softc *sc; 985 { 986 987 log(LOG_INFO, "t_status : %04x\n", *sc->nic_t_status); 988 log(LOG_INFO, "t_mask : %04x\n", *sc->nic_t_mask); 989 log(LOG_INFO, "t_mode : %04x\n", *sc->nic_t_mode); 990 log(LOG_INFO, "r_status : %04x\n", *sc->nic_r_status); 991 log(LOG_INFO, "r_mask : %04x\n", *sc->nic_r_mask); 992 log(LOG_INFO, "r_mode : %04x\n", *sc->nic_r_mode); 993 log(LOG_INFO, "pending : %02x\n", sc->transmit_pending); 994 log(LOG_INFO, "if_flags : %04x\n", sc->sc_ethercom.ec_if.if_flags); 995 } 996 #endif 997 998 #endif /* NQN > 0 */ 999