|
|
1.1 ! root 1: /* 8390.c: A general NS8390 ethernet driver core for linux. */ ! 2: /* ! 3: Written 1992-94 by Donald Becker. ! 4: ! 5: Copyright 1993 United States Government as represented by the ! 6: Director, National Security Agency. ! 7: ! 8: This software may be used and distributed according to the terms ! 9: of the GNU Public License, incorporated herein by reference. ! 10: ! 11: The author may be reached as [email protected], or C/O ! 12: Center of Excellence in Space Data and Information Sciences ! 13: Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 ! 14: ! 15: This is the chip-specific code for many 8390-based ethernet adaptors. ! 16: This is not a complete driver, it must be combined with board-specific ! 17: code such as ne.c, wd.c, 3c503.c, etc. ! 18: ! 19: Seeing how at least eight drivers use this code, (not counting the ! 20: PCMCIA ones either) it is easy to break some card by what seems like ! 21: a simple innocent change. Please contact me or Donald if you think ! 22: you have found something that needs changing. -- PG ! 23: ! 24: ! 25: Changelog: ! 26: ! 27: Paul Gortmaker : remove set_bit lock, other cleanups. ! 28: Paul Gortmaker : add ei_get_8390_hdr() so we can pass skb's to ! 29: ei_block_input() for eth_io_copy_and_sum(). ! 30: Paul Gortmaker : exchange static int ei_pingpong for a #define, ! 31: also add better Tx error handling. ! 32: Paul Gortmaker : rewrite Rx overrun handling as per NS specs. ! 33: ! 34: ! 35: Sources: ! 36: The National Semiconductor LAN Databook, and the 3Com 3c503 databook. ! 37: ! 38: */ ! 39: ! 40: static const char *version = ! 41: "8390.c:v1.10 9/23/94 Donald Becker ([email protected])\n"; ! 42: ! 43: #include <linux/module.h> ! 44: #include <linux/kernel.h> ! 45: #include <linux/sched.h> ! 46: #include <linux/fs.h> ! 47: #include <linux/types.h> ! 48: #include <linux/ptrace.h> ! 49: #include <linux/string.h> ! 50: #include <asm/system.h> ! 51: #include <asm/segment.h> ! 52: #include <asm/bitops.h> ! 53: #include <asm/io.h> ! 54: #include <linux/errno.h> ! 55: #include <linux/fcntl.h> ! 56: #include <linux/in.h> ! 57: #include <linux/interrupt.h> ! 58: ! 59: #include <linux/netdevice.h> ! 60: #include <linux/etherdevice.h> ! 61: ! 62: #include "8390.h" ! 63: ! 64: /* These are the operational function interfaces to board-specific ! 65: routines. ! 66: void reset_8390(struct device *dev) ! 67: Resets the board associated with DEV, including a hardware reset of ! 68: the 8390. This is only called when there is a transmit timeout, and ! 69: it is always followed by 8390_init(). ! 70: void block_output(struct device *dev, int count, const unsigned char *buf, ! 71: int start_page) ! 72: Write the COUNT bytes of BUF to the packet buffer at START_PAGE. The ! 73: "page" value uses the 8390's 256-byte pages. ! 74: void get_8390_hdr(struct device *dev, struct e8390_hdr *hdr, int ring_page) ! 75: Read the 4 byte, page aligned 8390 header. *If* there is a ! 76: subsequent read, it will be of the rest of the packet. ! 77: void block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) ! 78: Read COUNT bytes from the packet buffer into the skb data area. Start ! 79: reading from RING_OFFSET, the address as the 8390 sees it. This will always ! 80: follow the read of the 8390 header. ! 81: */ ! 82: #define ei_reset_8390 (ei_local->reset_8390) ! 83: #define ei_block_output (ei_local->block_output) ! 84: #define ei_block_input (ei_local->block_input) ! 85: #define ei_get_8390_hdr (ei_local->get_8390_hdr) ! 86: ! 87: /* use 0 for production, 1 for verification, >2 for debug */ ! 88: #ifdef EI_DEBUG ! 89: int ei_debug = EI_DEBUG; ! 90: #else ! 91: int ei_debug = 1; ! 92: #endif ! 93: ! 94: /* Index to functions. */ ! 95: static void ei_tx_intr(struct device *dev); ! 96: static void ei_tx_err(struct device *dev); ! 97: static void ei_receive(struct device *dev); ! 98: static void ei_rx_overrun(struct device *dev); ! 99: ! 100: /* Routines generic to NS8390-based boards. */ ! 101: static void NS8390_trigger_send(struct device *dev, unsigned int length, ! 102: int start_page); ! 103: static void set_multicast_list(struct device *dev); ! 104: ! 105: ! 106: /* Open/initialize the board. This routine goes all-out, setting everything ! 107: up anew at each open, even though many of these registers should only ! 108: need to be set once at boot. ! 109: */ ! 110: int ei_open(struct device *dev) ! 111: { ! 112: struct ei_device *ei_local = (struct ei_device *) dev->priv; ! 113: ! 114: /* This can't happen unless somebody forgot to call ethdev_init(). */ ! 115: if (ei_local == NULL) { ! 116: printk(KERN_EMERG "%s: ei_open passed a non-existent device!\n", dev->name); ! 117: return -ENXIO; ! 118: } ! 119: ! 120: irq2dev_map[dev->irq] = dev; ! 121: NS8390_init(dev, 1); ! 122: dev->start = 1; ! 123: ei_local->irqlock = 0; ! 124: return 0; ! 125: } ! 126: ! 127: /* Opposite of above. Only used when "ifconfig <devname> down" is done. */ ! 128: int ei_close(struct device *dev) ! 129: { ! 130: NS8390_init(dev, 0); ! 131: dev->start = 0; ! 132: return 0; ! 133: } ! 134: ! 135: static int ei_start_xmit(struct sk_buff *skb, struct device *dev) ! 136: { ! 137: int e8390_base = dev->base_addr; ! 138: struct ei_device *ei_local = (struct ei_device *) dev->priv; ! 139: int length, send_length, output_page; ! 140: ! 141: /* ! 142: * We normally shouldn't be called if dev->tbusy is set, but the ! 143: * existing code does anyway. If it has been too long since the ! 144: * last Tx, we assume the board has died and kick it. ! 145: */ ! 146: ! 147: if (dev->tbusy) { /* Do timeouts, just like the 8003 driver. */ ! 148: int txsr = inb(e8390_base+EN0_TSR), isr; ! 149: int tickssofar = jiffies - dev->trans_start; ! 150: if (tickssofar < TX_TIMEOUT || (tickssofar < (TX_TIMEOUT+5) && ! (txsr & ENTSR_PTX))) { ! 151: return 1; ! 152: } ! 153: isr = inb(e8390_base+EN0_ISR); ! 154: if (dev->start == 0) { ! 155: printk("%s: xmit on stopped card\n", dev->name); ! 156: return 1; ! 157: } ! 158: ! 159: /* ! 160: * Note that if the Tx posted a TX_ERR interrupt, then the ! 161: * error will have been handled from the interrupt handler. ! 162: * and not here. ! 163: */ ! 164: ! 165: printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n", ! 166: dev->name, (txsr & ENTSR_ABT) ? "excess collisions." : ! 167: (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar); ! 168: ! 169: if (!isr && !ei_local->stat.tx_packets) { ! 170: /* The 8390 probably hasn't gotten on the cable yet. */ ! 171: ei_local->interface_num ^= 1; /* Try a different xcvr. */ ! 172: } ! 173: ! 174: /* Try to restart the card. Perhaps the user has fixed something. */ ! 175: ei_reset_8390(dev); ! 176: NS8390_init(dev, 1); ! 177: dev->trans_start = jiffies; ! 178: } ! 179: ! 180: /* Sending a NULL skb means some higher layer thinks we've missed an ! 181: tx-done interrupt. Caution: dev_tint() handles the cli()/sti() ! 182: itself. */ ! 183: if (skb == NULL) { ! 184: dev_tint(dev); ! 185: return 0; ! 186: } ! 187: ! 188: length = skb->len; ! 189: if (skb->len <= 0) ! 190: return 0; ! 191: ! 192: /* Mask interrupts from the ethercard. */ ! 193: outb_p(0x00, e8390_base + EN0_IMR); ! 194: if (dev->interrupt) { ! 195: printk("%s: Tx request while isr active.\n",dev->name); ! 196: outb_p(ENISR_ALL, e8390_base + EN0_IMR); ! 197: return 1; ! 198: } ! 199: ei_local->irqlock = 1; ! 200: ! 201: send_length = ETH_ZLEN < length ? length : ETH_ZLEN; ! 202: ! 203: #ifdef EI_PINGPONG ! 204: ! 205: /* ! 206: * We have two Tx slots available for use. Find the first free ! 207: * slot, and then perform some sanity checks. With two Tx bufs, ! 208: * you get very close to transmitting back-to-back packets. With ! 209: * only one Tx buf, the transmitter sits idle while you reload the ! 210: * card, leaving a substantial gap between each transmitted packet. ! 211: */ ! 212: ! 213: if (ei_local->tx1 == 0) { ! 214: output_page = ei_local->tx_start_page; ! 215: ei_local->tx1 = send_length; ! 216: if (ei_debug && ei_local->tx2 > 0) ! 217: printk("%s: idle transmitter tx2=%d, lasttx=%d, txing=%d.\n", ! 218: dev->name, ei_local->tx2, ei_local->lasttx, ei_local->txing); ! 219: } else if (ei_local->tx2 == 0) { ! 220: output_page = ei_local->tx_start_page + TX_1X_PAGES; ! 221: ei_local->tx2 = send_length; ! 222: if (ei_debug && ei_local->tx1 > 0) ! 223: printk("%s: idle transmitter, tx1=%d, lasttx=%d, txing=%d.\n", ! 224: dev->name, ei_local->tx1, ei_local->lasttx, ei_local->txing); ! 225: } else { /* We should never get here. */ ! 226: if (ei_debug) ! 227: printk("%s: No Tx buffers free! irq=%d tx1=%d tx2=%d last=%d\n", ! 228: dev->name, dev->interrupt, ei_local->tx1, ei_local->tx2, ei_local->lasttx); ! 229: ei_local->irqlock = 0; ! 230: dev->tbusy = 1; ! 231: outb_p(ENISR_ALL, e8390_base + EN0_IMR); ! 232: return 1; ! 233: } ! 234: ! 235: /* ! 236: * Okay, now upload the packet and trigger a send if the transmitter ! 237: * isn't already sending. If it is busy, the interrupt handler will ! 238: * trigger the send later, upon receiving a Tx done interrupt. ! 239: */ ! 240: ! 241: ei_block_output(dev, length, skb->data, output_page); ! 242: if (! ei_local->txing) { ! 243: ei_local->txing = 1; ! 244: NS8390_trigger_send(dev, send_length, output_page); ! 245: dev->trans_start = jiffies; ! 246: if (output_page == ei_local->tx_start_page) { ! 247: ei_local->tx1 = -1; ! 248: ei_local->lasttx = -1; ! 249: } else { ! 250: ei_local->tx2 = -1; ! 251: ei_local->lasttx = -2; ! 252: } ! 253: } else ! 254: ei_local->txqueue++; ! 255: ! 256: dev->tbusy = (ei_local->tx1 && ei_local->tx2); ! 257: ! 258: #else /* EI_PINGPONG */ ! 259: ! 260: /* ! 261: * Only one Tx buffer in use. You need two Tx bufs to come close to ! 262: * back-to-back transmits. Expect a 20 -> 25% performance hit on ! 263: * reasonable hardware if you only use one Tx buffer. ! 264: */ ! 265: ! 266: ei_block_output(dev, length, skb->data, ei_local->tx_start_page); ! 267: ei_local->txing = 1; ! 268: NS8390_trigger_send(dev, send_length, ei_local->tx_start_page); ! 269: dev->trans_start = jiffies; ! 270: dev->tbusy = 1; ! 271: ! 272: #endif /* EI_PINGPONG */ ! 273: ! 274: /* Turn 8390 interrupts back on. */ ! 275: ei_local->irqlock = 0; ! 276: outb_p(ENISR_ALL, e8390_base + EN0_IMR); ! 277: ! 278: dev_kfree_skb (skb, FREE_WRITE); ! 279: ! 280: return 0; ! 281: } ! 282: ! 283: /* The typical workload of the driver: ! 284: Handle the ether interface interrupts. */ ! 285: void ei_interrupt(int irq, void *dev_id, struct pt_regs * regs) ! 286: { ! 287: struct device *dev = (struct device *)(irq2dev_map[irq]); ! 288: int e8390_base; ! 289: int interrupts, nr_serviced = 0; ! 290: struct ei_device *ei_local; ! 291: ! 292: if (dev == NULL) { ! 293: printk ("net_interrupt(): irq %d for unknown device.\n", irq); ! 294: return; ! 295: } ! 296: e8390_base = dev->base_addr; ! 297: ei_local = (struct ei_device *) dev->priv; ! 298: if (dev->interrupt || ei_local->irqlock) { ! 299: /* The "irqlock" check is only for testing. */ ! 300: printk(ei_local->irqlock ! 301: ? "%s: Interrupted while interrupts are masked! isr=%#2x imr=%#2x.\n" ! 302: : "%s: Reentering the interrupt handler! isr=%#2x imr=%#2x.\n", ! 303: dev->name, inb_p(e8390_base + EN0_ISR), ! 304: inb_p(e8390_base + EN0_IMR)); ! 305: return; ! 306: } ! 307: ! 308: dev->interrupt = 1; ! 309: ! 310: /* Change to page 0 and read the intr status reg. */ ! 311: outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD); ! 312: if (ei_debug > 3) ! 313: printk("%s: interrupt(isr=%#2.2x).\n", dev->name, ! 314: inb_p(e8390_base + EN0_ISR)); ! 315: ! 316: /* !!Assumption!! -- we stay in page 0. Don't break this. */ ! 317: while ((interrupts = inb_p(e8390_base + EN0_ISR)) != 0 ! 318: && ++nr_serviced < MAX_SERVICE) { ! 319: if (dev->start == 0) { ! 320: printk("%s: interrupt from stopped card\n", dev->name); ! 321: interrupts = 0; ! 322: break; ! 323: } ! 324: if (interrupts & ENISR_OVER) { ! 325: ei_rx_overrun(dev); ! 326: } else if (interrupts & (ENISR_RX+ENISR_RX_ERR)) { ! 327: /* Got a good (?) packet. */ ! 328: ei_receive(dev); ! 329: } ! 330: /* Push the next to-transmit packet through. */ ! 331: if (interrupts & ENISR_TX) { ! 332: ei_tx_intr(dev); ! 333: } else if (interrupts & ENISR_TX_ERR) { ! 334: ei_tx_err(dev); ! 335: } ! 336: ! 337: if (interrupts & ENISR_COUNTERS) { ! 338: ei_local->stat.rx_frame_errors += inb_p(e8390_base + EN0_COUNTER0); ! 339: ei_local->stat.rx_crc_errors += inb_p(e8390_base + EN0_COUNTER1); ! 340: ei_local->stat.rx_missed_errors+= inb_p(e8390_base + EN0_COUNTER2); ! 341: outb_p(ENISR_COUNTERS, e8390_base + EN0_ISR); /* Ack intr. */ ! 342: } ! 343: ! 344: /* Ignore any RDC interrupts that make it back to here. */ ! 345: if (interrupts & ENISR_RDC) { ! 346: outb_p(ENISR_RDC, e8390_base + EN0_ISR); ! 347: } ! 348: ! 349: outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD); ! 350: } ! 351: ! 352: if (interrupts && ei_debug) { ! 353: outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD); ! 354: if (nr_serviced >= MAX_SERVICE) { ! 355: printk("%s: Too much work at interrupt, status %#2.2x\n", ! 356: dev->name, interrupts); ! 357: outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */ ! 358: } else { ! 359: printk("%s: unknown interrupt %#2x\n", dev->name, interrupts); ! 360: outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */ ! 361: } ! 362: } ! 363: dev->interrupt = 0; ! 364: return; ! 365: } ! 366: ! 367: /* ! 368: * A transmitter error has happened. Most likely excess collisions (which ! 369: * is a fairly normal condition). If the error is one where the Tx will ! 370: * have been aborted, we try and send another one right away, instead of ! 371: * letting the failed packet sit and collect dust in the Tx buffer. This ! 372: * is a much better solution as it avoids kernel based Tx timeouts, and ! 373: * an unnecessary card reset. ! 374: */ ! 375: ! 376: static void ei_tx_err(struct device *dev) ! 377: { ! 378: int e8390_base = dev->base_addr; ! 379: unsigned char txsr = inb_p(e8390_base+EN0_TSR); ! 380: unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU); ! 381: struct ei_device *ei_local = (struct ei_device *) dev->priv; ! 382: ! 383: #ifdef VERBOSE_ERROR_DUMP ! 384: printk(KERN_DEBUG "%s: transmitter error (%#2x): ", dev->name, txsr); ! 385: if (txsr & ENTSR_ABT) ! 386: printk("excess-collisions "); ! 387: if (txsr & ENTSR_ND) ! 388: printk("non-deferral "); ! 389: if (txsr & ENTSR_CRS) ! 390: printk("lost-carrier "); ! 391: if (txsr & ENTSR_FU) ! 392: printk("FIFO-underrun "); ! 393: if (txsr & ENTSR_CDH) ! 394: printk("lost-heartbeat "); ! 395: printk("\n"); ! 396: #endif ! 397: ! 398: outb_p(ENISR_TX_ERR, e8390_base + EN0_ISR); /* Ack intr. */ ! 399: ! 400: if (tx_was_aborted) ! 401: ei_tx_intr(dev); ! 402: ! 403: /* ! 404: * Note: NCR reads zero on 16 collisions so we add them ! 405: * in by hand. Somebody might care... ! 406: */ ! 407: if (txsr & ENTSR_ABT) ! 408: ei_local->stat.collisions += 16; ! 409: ! 410: } ! 411: ! 412: /* We have finished a transmit: check for errors and then trigger the next ! 413: packet to be sent. */ ! 414: static void ei_tx_intr(struct device *dev) ! 415: { ! 416: int e8390_base = dev->base_addr; ! 417: int status = inb(e8390_base + EN0_TSR); ! 418: struct ei_device *ei_local = (struct ei_device *) dev->priv; ! 419: ! 420: outb_p(ENISR_TX, e8390_base + EN0_ISR); /* Ack intr. */ ! 421: ! 422: #ifdef EI_PINGPONG ! 423: ! 424: /* ! 425: * There are two Tx buffers, see which one finished, and trigger ! 426: * the send of another one if it exists. ! 427: */ ! 428: ei_local->txqueue--; ! 429: if (ei_local->tx1 < 0) { ! 430: if (ei_local->lasttx != 1 && ei_local->lasttx != -1) ! 431: printk("%s: bogus last_tx_buffer %d, tx1=%d.\n", ! 432: ei_local->name, ei_local->lasttx, ei_local->tx1); ! 433: ei_local->tx1 = 0; ! 434: dev->tbusy = 0; ! 435: if (ei_local->tx2 > 0) { ! 436: ei_local->txing = 1; ! 437: NS8390_trigger_send(dev, ei_local->tx2, ei_local->tx_start_page + 6); ! 438: dev->trans_start = jiffies; ! 439: ei_local->tx2 = -1, ! 440: ei_local->lasttx = 2; ! 441: } else ! 442: ei_local->lasttx = 20, ei_local->txing = 0; ! 443: } else if (ei_local->tx2 < 0) { ! 444: if (ei_local->lasttx != 2 && ei_local->lasttx != -2) ! 445: printk("%s: bogus last_tx_buffer %d, tx2=%d.\n", ! 446: ei_local->name, ei_local->lasttx, ei_local->tx2); ! 447: ei_local->tx2 = 0; ! 448: dev->tbusy = 0; ! 449: if (ei_local->tx1 > 0) { ! 450: ei_local->txing = 1; ! 451: NS8390_trigger_send(dev, ei_local->tx1, ei_local->tx_start_page); ! 452: dev->trans_start = jiffies; ! 453: ei_local->tx1 = -1; ! 454: ei_local->lasttx = 1; ! 455: } else ! 456: ei_local->lasttx = 10, ei_local->txing = 0; ! 457: } else ! 458: printk("%s: unexpected TX-done interrupt, lasttx=%d.\n", ! 459: dev->name, ei_local->lasttx); ! 460: ! 461: #else /* EI_PINGPONG */ ! 462: /* ! 463: * Single Tx buffer: mark it free so another packet can be loaded. ! 464: */ ! 465: ei_local->txing = 0; ! 466: dev->tbusy = 0; ! 467: #endif ! 468: ! 469: /* Minimize Tx latency: update the statistics after we restart TXing. */ ! 470: if (status & ENTSR_COL) ! 471: ei_local->stat.collisions++; ! 472: if (status & ENTSR_PTX) ! 473: ei_local->stat.tx_packets++; ! 474: else { ! 475: ei_local->stat.tx_errors++; ! 476: if (status & ENTSR_ABT) ei_local->stat.tx_aborted_errors++; ! 477: if (status & ENTSR_CRS) ei_local->stat.tx_carrier_errors++; ! 478: if (status & ENTSR_FU) ei_local->stat.tx_fifo_errors++; ! 479: if (status & ENTSR_CDH) ei_local->stat.tx_heartbeat_errors++; ! 480: if (status & ENTSR_OWC) ei_local->stat.tx_window_errors++; ! 481: } ! 482: ! 483: mark_bh (NET_BH); ! 484: } ! 485: ! 486: /* We have a good packet(s), get it/them out of the buffers. */ ! 487: ! 488: static void ei_receive(struct device *dev) ! 489: { ! 490: int e8390_base = dev->base_addr; ! 491: struct ei_device *ei_local = (struct ei_device *) dev->priv; ! 492: unsigned char rxing_page, this_frame, next_frame; ! 493: unsigned short current_offset; ! 494: int rx_pkt_count = 0; ! 495: struct e8390_pkt_hdr rx_frame; ! 496: int num_rx_pages = ei_local->stop_page-ei_local->rx_start_page; ! 497: ! 498: while (++rx_pkt_count < 10) { ! 499: int pkt_len; ! 500: ! 501: /* Get the rx page (incoming packet pointer). */ ! 502: outb_p(E8390_NODMA+E8390_PAGE1, e8390_base + E8390_CMD); ! 503: rxing_page = inb_p(e8390_base + EN1_CURPAG); ! 504: outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD); ! 505: ! 506: /* Remove one frame from the ring. Boundary is always a page behind. */ ! 507: this_frame = inb_p(e8390_base + EN0_BOUNDARY) + 1; ! 508: if (this_frame >= ei_local->stop_page) ! 509: this_frame = ei_local->rx_start_page; ! 510: ! 511: /* Someday we'll omit the previous, iff we never get this message. ! 512: (There is at least one clone claimed to have a problem.) */ ! 513: if (ei_debug > 0 && this_frame != ei_local->current_page) ! 514: printk("%s: mismatched read page pointers %2x vs %2x.\n", ! 515: dev->name, this_frame, ei_local->current_page); ! 516: ! 517: if (this_frame == rxing_page) /* Read all the frames? */ ! 518: break; /* Done for now */ ! 519: ! 520: current_offset = this_frame << 8; ! 521: ei_get_8390_hdr(dev, &rx_frame, this_frame); ! 522: ! 523: pkt_len = rx_frame.count - sizeof(struct e8390_pkt_hdr); ! 524: ! 525: next_frame = this_frame + 1 + ((pkt_len+4)>>8); ! 526: ! 527: /* Check for bogosity warned by 3c503 book: the status byte is never ! 528: written. This happened a lot during testing! This code should be ! 529: cleaned up someday. */ ! 530: if (rx_frame.next != next_frame ! 531: && rx_frame.next != next_frame + 1 ! 532: && rx_frame.next != next_frame - num_rx_pages ! 533: && rx_frame.next != next_frame + 1 - num_rx_pages) { ! 534: ei_local->current_page = rxing_page; ! 535: outb(ei_local->current_page-1, e8390_base+EN0_BOUNDARY); ! 536: ei_local->stat.rx_errors++; ! 537: continue; ! 538: } ! 539: ! 540: if (pkt_len < 60 || pkt_len > 1518) { ! 541: if (ei_debug) ! 542: printk("%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n", ! 543: dev->name, rx_frame.count, rx_frame.status, ! 544: rx_frame.next); ! 545: ei_local->stat.rx_errors++; ! 546: } else if ((rx_frame.status & 0x0F) == ENRSR_RXOK) { ! 547: struct sk_buff *skb; ! 548: ! 549: skb = dev_alloc_skb(pkt_len+2); ! 550: if (skb == NULL) { ! 551: if (ei_debug > 1) ! 552: printk("%s: Couldn't allocate a sk_buff of size %d.\n", ! 553: dev->name, pkt_len); ! 554: ei_local->stat.rx_dropped++; ! 555: break; ! 556: } else { ! 557: skb_reserve(skb,2); /* IP headers on 16 byte boundaries */ ! 558: skb->dev = dev; ! 559: skb_put(skb, pkt_len); /* Make room */ ! 560: ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame)); ! 561: skb->protocol=eth_type_trans(skb,dev); ! 562: netif_rx(skb); ! 563: ei_local->stat.rx_packets++; ! 564: } ! 565: } else { ! 566: int errs = rx_frame.status; ! 567: if (ei_debug) ! 568: printk("%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n", ! 569: dev->name, rx_frame.status, rx_frame.next, ! 570: rx_frame.count); ! 571: if (errs & ENRSR_FO) ! 572: ei_local->stat.rx_fifo_errors++; ! 573: } ! 574: next_frame = rx_frame.next; ! 575: ! 576: /* This _should_ never happen: it's here for avoiding bad clones. */ ! 577: if (next_frame >= ei_local->stop_page) { ! 578: printk("%s: next frame inconsistency, %#2x\n", dev->name, ! 579: next_frame); ! 580: next_frame = ei_local->rx_start_page; ! 581: } ! 582: ei_local->current_page = next_frame; ! 583: outb_p(next_frame-1, e8390_base+EN0_BOUNDARY); ! 584: } ! 585: ! 586: /* We used to also ack ENISR_OVER here, but that would sometimes mask ! 587: a real overrun, leaving the 8390 in a stopped state with rec'vr off. */ ! 588: outb_p(ENISR_RX+ENISR_RX_ERR, e8390_base+EN0_ISR); ! 589: return; ! 590: } ! 591: ! 592: /* ! 593: * We have a receiver overrun: we have to kick the 8390 to get it started ! 594: * again. Problem is that you have to kick it exactly as NS prescribes in ! 595: * the updated datasheets, or "the NIC may act in an unpredictable manner." ! 596: * This includes causing "the NIC to defer indefinitely when it is stopped ! 597: * on a busy network." Ugh. ! 598: */ ! 599: static void ei_rx_overrun(struct device *dev) ! 600: { ! 601: int e8390_base = dev->base_addr; ! 602: unsigned long wait_start_time; ! 603: unsigned char was_txing, must_resend = 0; ! 604: struct ei_device *ei_local = (struct ei_device *) dev->priv; ! 605: ! 606: /* ! 607: * Record whether a Tx was in progress and then issue the ! 608: * stop command. ! 609: */ ! 610: was_txing = inb_p(e8390_base+E8390_CMD) & E8390_TRANS; ! 611: outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); ! 612: ! 613: if (ei_debug > 1) ! 614: printk("%s: Receiver overrun.\n", dev->name); ! 615: ei_local->stat.rx_over_errors++; ! 616: ! 617: /* ! 618: * Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total. ! 619: * Early datasheets said to poll the reset bit, but now they say that ! 620: * it "is not a reliable indicator and subsequently should be ignored." ! 621: * We wait at least 10ms. ! 622: */ ! 623: wait_start_time = jiffies; ! 624: while (jiffies - wait_start_time <= 1*HZ/100) ! 625: barrier(); ! 626: ! 627: /* ! 628: * Reset RBCR[01] back to zero as per magic incantation. ! 629: */ ! 630: outb_p(0x00, e8390_base+EN0_RCNTLO); ! 631: outb_p(0x00, e8390_base+EN0_RCNTHI); ! 632: ! 633: /* ! 634: * See if any Tx was interrupted or not. According to NS, this ! 635: * step is vital, and skipping it will cause no end of havoc. ! 636: */ ! 637: if (was_txing) { ! 638: unsigned char tx_completed = inb_p(e8390_base+EN0_ISR) & (ENISR_TX+ENISR_TX_ERR); ! 639: if (!tx_completed) must_resend = 1; ! 640: } ! 641: ! 642: /* ! 643: * Have to enter loopback mode and then restart the NIC before ! 644: * you are allowed to slurp packets up off the ring. ! 645: */ ! 646: outb_p(E8390_TXOFF, e8390_base + EN0_TXCR); ! 647: outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, e8390_base + E8390_CMD); ! 648: ! 649: /* ! 650: * Clear the Rx ring of all the debris, and ack the interrupt. ! 651: */ ! 652: ei_receive(dev); ! 653: outb_p(ENISR_OVER, e8390_base+EN0_ISR); ! 654: ! 655: /* ! 656: * Leave loopback mode, and resend any packet that got stopped. ! 657: */ ! 658: outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); ! 659: if (must_resend) ! 660: outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, e8390_base + E8390_CMD); ! 661: ! 662: } ! 663: ! 664: static struct enet_statistics *get_stats(struct device *dev) ! 665: { ! 666: short ioaddr = dev->base_addr; ! 667: struct ei_device *ei_local = (struct ei_device *) dev->priv; ! 668: ! 669: /* If the card is stopped, just return the present stats. */ ! 670: if (dev->start == 0) return &ei_local->stat; ! 671: ! 672: /* Read the counter registers, assuming we are in page 0. */ ! 673: ei_local->stat.rx_frame_errors += inb_p(ioaddr + EN0_COUNTER0); ! 674: ei_local->stat.rx_crc_errors += inb_p(ioaddr + EN0_COUNTER1); ! 675: ei_local->stat.rx_missed_errors+= inb_p(ioaddr + EN0_COUNTER2); ! 676: ! 677: return &ei_local->stat; ! 678: } ! 679: ! 680: /* ! 681: * Set or clear the multicast filter for this adaptor. ! 682: */ ! 683: ! 684: static void set_multicast_list(struct device *dev) ! 685: { ! 686: short ioaddr = dev->base_addr; ! 687: ! 688: if(dev->flags&IFF_PROMISC) ! 689: { ! 690: outb_p(E8390_RXCONFIG | 0x18, ioaddr + EN0_RXCR); ! 691: } ! 692: else if((dev->flags&IFF_ALLMULTI)||dev->mc_list) ! 693: { ! 694: /* The multicast-accept list is initialized to accept-all, and we ! 695: rely on higher-level filtering for now. */ ! 696: outb_p(E8390_RXCONFIG | 0x08, ioaddr + EN0_RXCR); ! 697: } ! 698: else ! 699: outb_p(E8390_RXCONFIG, ioaddr + EN0_RXCR); ! 700: } ! 701: ! 702: /* Initialize the rest of the 8390 device structure. */ ! 703: int ethdev_init(struct device *dev) ! 704: { ! 705: if (ei_debug > 1) ! 706: printk(version); ! 707: ! 708: if (dev->priv == NULL) { ! 709: struct ei_device *ei_local; ! 710: ! 711: dev->priv = kmalloc(sizeof(struct ei_device), GFP_KERNEL); ! 712: if (dev->priv == NULL) ! 713: return -ENOMEM; ! 714: memset(dev->priv, 0, sizeof(struct ei_device)); ! 715: ei_local = (struct ei_device *)dev->priv; ! 716: } ! 717: ! 718: dev->hard_start_xmit = &ei_start_xmit; ! 719: dev->get_stats = get_stats; ! 720: dev->set_multicast_list = &set_multicast_list; ! 721: ! 722: ether_setup(dev); ! 723: ! 724: return 0; ! 725: } ! 726: ! 727: ! 728: /* This page of functions should be 8390 generic */ ! 729: /* Follow National Semi's recommendations for initializing the "NIC". */ ! 730: void NS8390_init(struct device *dev, int startp) ! 731: { ! 732: int e8390_base = dev->base_addr; ! 733: struct ei_device *ei_local = (struct ei_device *) dev->priv; ! 734: int i; ! 735: int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48; ! 736: unsigned long flags; ! 737: ! 738: /* Follow National Semi's recommendations for initing the DP83902. */ ! 739: outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base); /* 0x21 */ ! 740: outb_p(endcfg, e8390_base + EN0_DCFG); /* 0x48 or 0x49 */ ! 741: /* Clear the remote byte count registers. */ ! 742: outb_p(0x00, e8390_base + EN0_RCNTLO); ! 743: outb_p(0x00, e8390_base + EN0_RCNTHI); ! 744: /* Set to monitor and loopback mode -- this is vital!. */ ! 745: outb_p(E8390_RXOFF, e8390_base + EN0_RXCR); /* 0x20 */ ! 746: outb_p(E8390_TXOFF, e8390_base + EN0_TXCR); /* 0x02 */ ! 747: /* Set the transmit page and receive ring. */ ! 748: outb_p(ei_local->tx_start_page, e8390_base + EN0_TPSR); ! 749: ei_local->tx1 = ei_local->tx2 = 0; ! 750: outb_p(ei_local->rx_start_page, e8390_base + EN0_STARTPG); ! 751: outb_p(ei_local->stop_page-1, e8390_base + EN0_BOUNDARY); /* 3c503 says 0x3f,NS0x26*/ ! 752: ei_local->current_page = ei_local->rx_start_page; /* assert boundary+1 */ ! 753: outb_p(ei_local->stop_page, e8390_base + EN0_STOPPG); ! 754: /* Clear the pending interrupts and mask. */ ! 755: outb_p(0xFF, e8390_base + EN0_ISR); ! 756: outb_p(0x00, e8390_base + EN0_IMR); ! 757: ! 758: /* Copy the station address into the DS8390 registers, ! 759: and set the multicast hash bitmap to receive all multicasts. */ ! 760: save_flags(flags); ! 761: cli(); ! 762: outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, e8390_base); /* 0x61 */ ! 763: for(i = 0; i < 6; i++) { ! 764: outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS + i); ! 765: } ! 766: /* Initialize the multicast list to accept-all. If we enable multicast ! 767: the higher levels can do the filtering. */ ! 768: for(i = 0; i < 8; i++) ! 769: outb_p(0xff, e8390_base + EN1_MULT + i); ! 770: ! 771: outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG); ! 772: outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base); ! 773: restore_flags(flags); ! 774: dev->tbusy = 0; ! 775: dev->interrupt = 0; ! 776: ei_local->tx1 = ei_local->tx2 = 0; ! 777: ei_local->txing = 0; ! 778: if (startp) { ! 779: outb_p(0xff, e8390_base + EN0_ISR); ! 780: outb_p(ENISR_ALL, e8390_base + EN0_IMR); ! 781: outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base); ! 782: outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); /* xmit on. */ ! 783: /* 3c503 TechMan says rxconfig only after the NIC is started. */ ! 784: outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); /* rx on, */ ! 785: dev->set_multicast_list(dev); /* Get the multicast status right if this ! 786: was a reset. */ ! 787: } ! 788: return; ! 789: } ! 790: ! 791: /* Trigger a transmit start, assuming the length is valid. */ ! 792: static void NS8390_trigger_send(struct device *dev, unsigned int length, ! 793: int start_page) ! 794: { ! 795: int e8390_base = dev->base_addr; ! 796: ! 797: outb_p(E8390_NODMA+E8390_PAGE0, e8390_base); ! 798: ! 799: if (inb_p(e8390_base) & E8390_TRANS) { ! 800: printk("%s: trigger_send() called with the transmitter busy.\n", ! 801: dev->name); ! 802: return; ! 803: } ! 804: outb_p(length & 0xff, e8390_base + EN0_TCNTLO); ! 805: outb_p(length >> 8, e8390_base + EN0_TCNTHI); ! 806: outb_p(start_page, e8390_base + EN0_TPSR); ! 807: outb_p(E8390_NODMA+E8390_TRANS+E8390_START, e8390_base); ! 808: return; ! 809: } ! 810: ! 811: #ifdef MODULE ! 812: ! 813: int init_module(void) ! 814: { ! 815: return 0; ! 816: } ! 817: ! 818: void ! 819: cleanup_module(void) ! 820: { ! 821: } ! 822: #endif /* MODULE */ ! 823: ! 824: /* ! 825: * Local variables: ! 826: * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c 8390.c" ! 827: * version-control: t ! 828: * kept-new-versions: 5 ! 829: * c-indent-level: 4 ! 830: * tab-width: 4 ! 831: * End: ! 832: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.