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