|
|
1.1 ! root 1: /* 3c501.c: A 3Com 3c501 ethernet driver for linux. */ ! 2: /* ! 3: Written 1992,1993,1994 Donald Becker ! 4: ! 5: Copyright 1993 United States Government as represented by the ! 6: Director, National Security Agency. This software may be used and ! 7: distributed according to the terms of the GNU Public License, ! 8: incorporated herein by reference. ! 9: ! 10: This is a device driver for the 3Com Etherlink 3c501. ! 11: Do not purchase this card, even as a joke. It's performance is horrible, ! 12: and it breaks in many ways. ! 13: ! 14: The author may be reached as [email protected], or C/O ! 15: Center of Excellence in Space Data and Information Sciences ! 16: Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 ! 17: ! 18: Fixed (again!) the missing interrupt locking on TX/RX shifting. ! 19: Alan Cox <[email protected]> ! 20: ! 21: Removed calls to init_etherdev since they are no longer needed, and ! 22: cleaned up modularization just a bit. The driver still allows only ! 23: the default address for cards when loaded as a module, but that's ! 24: really less braindead than anyone using a 3c501 board. :) ! 25: 19950208 ([email protected]) ! 26: ! 27: Added traps for interrupts hitting the window as we clear and TX load ! 28: the board. Now getting 150K/second FTP with a 3c501 card. Still playing ! 29: with a TX-TX optimisation to see if we can touch 180-200K/second as seems ! 30: theoretically maximum. ! 31: 19950402 Alan Cox <[email protected]> ! 32: ! 33: Some notes on this thing if you have to hack it. [Alan] ! 34: ! 35: 1] Some documentation is available from 3Com. Due to the boards age ! 36: standard responses when you ask for this will range from 'be serious' ! 37: to 'give it to a museum'. The documentation is incomplete and mostly ! 38: of historical interest anyway. ! 39: ! 40: 2] The basic system is a single buffer which can be used to receive or ! 41: transmit a packet. A third command mode exists when you are setting ! 42: things up. ! 43: ! 44: 3] If it's transmitting it's not receiving and vice versa. In fact the ! 45: time to get the board back into useful state after an operation is ! 46: quite large. ! 47: ! 48: 4] The driver works by keeping the board in receive mode waiting for a ! 49: packet to arrive. When one arrives it is copied out of the buffer ! 50: and delivered to the kernel. The card is reloaded and off we go. ! 51: ! 52: 5] When transmitting dev->tbusy is set and the card is reset (from ! 53: receive mode) [possibly losing a packet just received] to command ! 54: mode. A packet is loaded and transmit mode triggered. The interrupt ! 55: handler runs different code for transmit interrupts and can handle ! 56: returning to receive mode or retransmissions (yes you have to help ! 57: out with those too). ! 58: ! 59: Problems: ! 60: There are a wide variety of undocumented error returns from the card ! 61: and you basically have to kick the board and pray if they turn up. Most ! 62: only occur under extreme load or if you do something the board doesn't ! 63: like (eg touching a register at the wrong time). ! 64: ! 65: The driver is less efficient than it could be. It switches through ! 66: receive mode even if more transmits are queued. If this worries you buy ! 67: a real ethernet card. ! 68: ! 69: The combination of slow receive restart and no real multicast ! 70: filter makes the board unusable with a kernel compiled for IP ! 71: multicasting in a real multicast environment. Thats down to the board, ! 72: but even with no multicast programs running a multicast IP kernel is ! 73: in group 224.0.0.1 and you will therefore be listening to all multicasts. ! 74: One nv conference running over that ethernet and you can give up. ! 75: ! 76: */ ! 77: ! 78: static const char *version = ! 79: "3c501.c: 9/23/94 Donald Becker ([email protected]).\n"; ! 80: ! 81: /* ! 82: * Braindamage remaining: ! 83: * The 3c501 board. ! 84: */ ! 85: ! 86: #include <linux/module.h> ! 87: ! 88: #include <linux/kernel.h> ! 89: #include <linux/sched.h> ! 90: #include <linux/ptrace.h> ! 91: #include <linux/fcntl.h> ! 92: #include <linux/ioport.h> ! 93: #include <linux/interrupt.h> ! 94: #include <linux/malloc.h> ! 95: #include <linux/string.h> ! 96: #include <linux/ioport.h> ! 97: #include <linux/errno.h> ! 98: #include <linux/config.h> /* for CONFIG_IP_MULTICAST */ ! 99: ! 100: #include <asm/bitops.h> ! 101: #include <asm/io.h> ! 102: ! 103: #include <linux/netdevice.h> ! 104: #include <linux/etherdevice.h> ! 105: #include <linux/skbuff.h> ! 106: ! 107: #define BLOCKOUT_2 ! 108: ! 109: /* A zero-terminated list of I/O addresses to be probed. ! 110: The 3c501 can be at many locations, but here are the popular ones. */ ! 111: static unsigned int netcard_portlist[] = ! 112: { 0x280, 0x300, 0}; ! 113: ! 114: ! 115: /* ! 116: * Index to functions. ! 117: */ ! 118: ! 119: int el1_probe(struct device *dev); ! 120: static int el1_probe1(struct device *dev, int ioaddr); ! 121: static int el_open(struct device *dev); ! 122: static int el_start_xmit(struct sk_buff *skb, struct device *dev); ! 123: static void el_interrupt(int irq, struct pt_regs *regs); ! 124: static void el_receive(struct device *dev); ! 125: static void el_reset(struct device *dev); ! 126: static int el1_close(struct device *dev); ! 127: static struct enet_statistics *el1_get_stats(struct device *dev); ! 128: static void set_multicast_list(struct device *dev); ! 129: ! 130: #define EL1_IO_EXTENT 16 ! 131: ! 132: #ifndef EL_DEBUG ! 133: #define EL_DEBUG 0 /* use 0 for production, 1 for devel., >2 for debug */ ! 134: #endif /* Anything above 5 is wordy death! */ ! 135: static int el_debug = EL_DEBUG; ! 136: ! 137: /* ! 138: * Board-specific info in dev->priv. ! 139: */ ! 140: ! 141: struct net_local ! 142: { ! 143: struct enet_statistics stats; ! 144: int tx_pkt_start; /* The length of the current Tx packet. */ ! 145: int collisions; /* Tx collisions this packet */ ! 146: int loading; /* Spot buffer load collisions */ ! 147: }; ! 148: ! 149: ! 150: #define RX_STATUS (ioaddr + 0x06) ! 151: #define RX_CMD RX_STATUS ! 152: #define TX_STATUS (ioaddr + 0x07) ! 153: #define TX_CMD TX_STATUS ! 154: #define GP_LOW (ioaddr + 0x08) ! 155: #define GP_HIGH (ioaddr + 0x09) ! 156: #define RX_BUF_CLR (ioaddr + 0x0A) ! 157: #define RX_LOW (ioaddr + 0x0A) ! 158: #define RX_HIGH (ioaddr + 0x0B) ! 159: #define SAPROM (ioaddr + 0x0C) ! 160: #define AX_STATUS (ioaddr + 0x0E) ! 161: #define AX_CMD AX_STATUS ! 162: #define DATAPORT (ioaddr + 0x0F) ! 163: #define TX_RDY 0x08 /* In TX_STATUS */ ! 164: ! 165: #define EL1_DATAPTR 0x08 ! 166: #define EL1_RXPTR 0x0A ! 167: #define EL1_SAPROM 0x0C ! 168: #define EL1_DATAPORT 0x0f ! 169: ! 170: /* ! 171: * Writes to the ax command register. ! 172: */ ! 173: ! 174: #define AX_OFF 0x00 /* Irq off, buffer access on */ ! 175: #define AX_SYS 0x40 /* Load the buffer */ ! 176: #define AX_XMIT 0x44 /* Transmit a packet */ ! 177: #define AX_RX 0x48 /* Receive a packet */ ! 178: #define AX_LOOP 0x0C /* Loopback mode */ ! 179: #define AX_RESET 0x80 ! 180: ! 181: /* ! 182: * Normal receive mode written to RX_STATUS. We must intr on short packets ! 183: * to avoid bogus rx lockups. ! 184: */ ! 185: ! 186: #define RX_NORM 0xA8 /* 0x68 == all addrs, 0xA8 only to me. */ ! 187: #define RX_PROM 0x68 /* Senior Prom, uhmm promiscuous mode. */ ! 188: #define RX_MULT 0xE8 /* Accept multicast packets. */ ! 189: #define TX_NORM 0x0A /* Interrupt on everything that might hang the chip */ ! 190: ! 191: /* ! 192: * TX_STATUS register. ! 193: */ ! 194: ! 195: #define TX_COLLISION 0x02 ! 196: #define TX_16COLLISIONS 0x04 ! 197: #define TX_READY 0x08 ! 198: ! 199: #define RX_RUNT 0x08 ! 200: #define RX_MISSED 0x01 /* Missed a packet due to 3c501 braindamage. */ ! 201: #define RX_GOOD 0x30 /* Good packet 0x20, or simple overflow 0x10. */ ! 202: ! 203: ! 204: /* ! 205: * The boilerplate probe code. ! 206: */ ! 207: ! 208: #ifdef HAVE_DEVLIST ! 209: struct netdev_entry el1_drv = {"3c501", el1_probe1, EL1_IO_EXTENT, netcard_portlist}; ! 210: #else ! 211: ! 212: int el1_probe(struct device *dev) ! 213: { ! 214: int i; ! 215: int base_addr = dev ? dev->base_addr : 0; ! 216: ! 217: if (base_addr > 0x1ff) /* Check a single specified location. */ ! 218: return el1_probe1(dev, base_addr); ! 219: else if (base_addr != 0) /* Don't probe at all. */ ! 220: return ENXIO; ! 221: ! 222: for (i = 0; netcard_portlist[i]; i++) ! 223: { ! 224: int ioaddr = netcard_portlist[i]; ! 225: if (check_region(ioaddr, EL1_IO_EXTENT)) ! 226: continue; ! 227: if (el1_probe1(dev, ioaddr) == 0) ! 228: return 0; ! 229: } ! 230: ! 231: return ENODEV; ! 232: } ! 233: #endif ! 234: ! 235: /* ! 236: * The actual probe. ! 237: */ ! 238: ! 239: static int el1_probe1(struct device *dev, int ioaddr) ! 240: { ! 241: #ifndef MODULE ! 242: ! 243: const char *mname; /* Vendor name */ ! 244: unsigned char station_addr[6]; ! 245: int autoirq = 0; ! 246: int i; ! 247: ! 248: /* ! 249: * Read the station address PROM data from the special port. ! 250: */ ! 251: ! 252: for (i = 0; i < 6; i++) ! 253: { ! 254: outw(i, ioaddr + EL1_DATAPTR); ! 255: station_addr[i] = inb(ioaddr + EL1_SAPROM); ! 256: } ! 257: /* ! 258: * Check the first three octets of the S.A. for 3Com's prefix, or ! 259: * for the Sager NP943 prefix. ! 260: */ ! 261: ! 262: if (station_addr[0] == 0x02 && station_addr[1] == 0x60 ! 263: && station_addr[2] == 0x8c) ! 264: { ! 265: mname = "3c501"; ! 266: } else if (station_addr[0] == 0x00 && station_addr[1] == 0x80 ! 267: && station_addr[2] == 0xC8) ! 268: { ! 269: mname = "NP943"; ! 270: } ! 271: else ! 272: return ENODEV; ! 273: ! 274: /* ! 275: * Grab the region so we can find the another board if autoIRQ fails. ! 276: */ ! 277: ! 278: request_region(ioaddr, EL1_IO_EXTENT,"3c501"); ! 279: ! 280: /* ! 281: * We auto-IRQ by shutting off the interrupt line and letting it float ! 282: * high. ! 283: */ ! 284: ! 285: if (dev->irq < 2) ! 286: { ! 287: autoirq_setup(2); ! 288: inb(RX_STATUS); /* Clear pending interrupts. */ ! 289: inb(TX_STATUS); ! 290: outb(AX_LOOP + 1, AX_CMD); ! 291: ! 292: outb(0x00, AX_CMD); ! 293: ! 294: autoirq = autoirq_report(1); ! 295: ! 296: if (autoirq == 0) ! 297: { ! 298: printk("%s probe at %#x failed to detect IRQ line.\n", ! 299: mname, ioaddr); ! 300: return EAGAIN; ! 301: } ! 302: } ! 303: ! 304: outb(AX_RESET+AX_LOOP, AX_CMD); /* Loopback mode. */ ! 305: dev->base_addr = ioaddr; ! 306: memcpy(dev->dev_addr, station_addr, ETH_ALEN); ! 307: ! 308: if (dev->mem_start & 0xf) ! 309: el_debug = dev->mem_start & 0x7; ! 310: if (autoirq) ! 311: dev->irq = autoirq; ! 312: ! 313: printk("%s: %s EtherLink at %#lx, using %sIRQ %d.\n", dev->name, mname, dev->base_addr, ! 314: autoirq ? "auto":"assigned ", dev->irq); ! 315: ! 316: #ifdef CONFIG_IP_MULTICAST ! 317: printk("WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n"); ! 318: #endif ! 319: ! 320: if (el_debug) ! 321: printk("%s", version); ! 322: ! 323: /* ! 324: * Initialize the device structure. ! 325: */ ! 326: ! 327: dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); ! 328: if (dev->priv == NULL) ! 329: return -ENOMEM; ! 330: memset(dev->priv, 0, sizeof(struct net_local)); ! 331: ! 332: /* ! 333: * The EL1-specific entries in the device structure. ! 334: */ ! 335: ! 336: dev->open = &el_open; ! 337: dev->hard_start_xmit = &el_start_xmit; ! 338: dev->stop = &el1_close; ! 339: dev->get_stats = &el1_get_stats; ! 340: dev->set_multicast_list = &set_multicast_list; ! 341: ! 342: /* ! 343: * Setup the generic properties ! 344: */ ! 345: ! 346: ether_setup(dev); ! 347: ! 348: #endif /* !MODULE */ ! 349: ! 350: return 0; ! 351: } ! 352: ! 353: /* ! 354: * Open/initialize the board. ! 355: */ ! 356: ! 357: static int el_open(struct device *dev) ! 358: { ! 359: int ioaddr = dev->base_addr; ! 360: ! 361: if (el_debug > 2) ! 362: printk("%s: Doing el_open()...", dev->name); ! 363: ! 364: if (request_irq(dev->irq, &el_interrupt, 0, "3c501")) ! 365: return -EAGAIN; ! 366: ! 367: irq2dev_map[dev->irq] = dev; ! 368: el_reset(dev); ! 369: ! 370: dev->start = 1; ! 371: ! 372: outb(AX_RX, AX_CMD); /* Aux control, irq and receive enabled */ ! 373: MOD_INC_USE_COUNT; ! 374: return 0; ! 375: } ! 376: ! 377: static int el_start_xmit(struct sk_buff *skb, struct device *dev) ! 378: { ! 379: struct net_local *lp = (struct net_local *)dev->priv; ! 380: int ioaddr = dev->base_addr; ! 381: unsigned long flags; ! 382: ! 383: if(dev->interrupt) /* May be unloading, don't stamp on */ ! 384: return 1; /* the packet buffer this time */ ! 385: ! 386: if (dev->tbusy) ! 387: { ! 388: if (jiffies - dev->trans_start < 20) ! 389: { ! 390: if (el_debug > 2) ! 391: printk(" transmitter busy, deferred.\n"); ! 392: return 1; ! 393: } ! 394: if (el_debug) ! 395: printk ("%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n", ! 396: dev->name, inb(TX_STATUS), inb(AX_STATUS), inb(RX_STATUS)); ! 397: lp->stats.tx_errors++; ! 398: outb(TX_NORM, TX_CMD); ! 399: outb(RX_NORM, RX_CMD); ! 400: outb(AX_OFF, AX_CMD); /* Just trigger a false interrupt. */ ! 401: outb(AX_RX, AX_CMD); /* Aux control, irq and receive enabled */ ! 402: dev->tbusy = 0; ! 403: dev->trans_start = jiffies; ! 404: } ! 405: ! 406: if (skb == NULL) ! 407: { ! 408: dev_tint(dev); ! 409: return 0; ! 410: } ! 411: ! 412: save_flags(flags); ! 413: ! 414: /* ! 415: * Avoid incoming interrupts between us flipping tbusy and flipping ! 416: * mode as the driver assumes tbusy is a faithful indicator of card ! 417: * state ! 418: */ ! 419: ! 420: cli(); ! 421: ! 422: /* ! 423: * Avoid timer-based retransmission conflicts. ! 424: */ ! 425: ! 426: if (set_bit(0, (void*)&dev->tbusy) != 0) ! 427: { ! 428: restore_flags(flags); ! 429: printk("%s: Transmitter access conflict.\n", dev->name); ! 430: } ! 431: else ! 432: { ! 433: int gp_start = 0x800 - (ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN); ! 434: unsigned char *buf = skb->data; ! 435: ! 436: load_it_again_sam: ! 437: lp->tx_pkt_start = gp_start; ! 438: lp->collisions = 0; ! 439: ! 440: /* ! 441: * Command mode with status cleared should [in theory] ! 442: * mean no more interrupts can be pending on the card. ! 443: */ ! 444: ! 445: #ifdef BLOCKOUT_1 ! 446: disable_irq(dev->irq); ! 447: #endif ! 448: outb_p(AX_SYS, AX_CMD); ! 449: inb_p(RX_STATUS); ! 450: inb_p(TX_STATUS); ! 451: ! 452: lp->loading=1; ! 453: ! 454: /* ! 455: * Turn interrupts back on while we spend a pleasant afternoon ! 456: * loading bytes into the board ! 457: */ ! 458: ! 459: restore_flags(flags); ! 460: outw(0x00, RX_BUF_CLR); /* Set rx packet area to 0. */ ! 461: outw(gp_start, GP_LOW); /* aim - packet will be loaded into buffer start */ ! 462: outsb(DATAPORT,buf,skb->len); /* load buffer (usual thing each byte increments the pointer) */ ! 463: outw(gp_start, GP_LOW); /* the board reuses the same register */ ! 464: #ifndef BLOCKOUT_1 ! 465: if(lp->loading==2) /* A receive upset our load, despite our best efforts */ ! 466: { ! 467: if(el_debug>2) ! 468: printk("%s: burped during tx load.\n", dev->name); ! 469: goto load_it_again_sam; /* Sigh... */ ! 470: } ! 471: #endif ! 472: outb(AX_XMIT, AX_CMD); /* fire ... Trigger xmit. */ ! 473: lp->loading=0; ! 474: #ifdef BLOCKOUT_1 ! 475: enable_irq(dev->irq); ! 476: #endif ! 477: dev->trans_start = jiffies; ! 478: } ! 479: ! 480: if (el_debug > 2) ! 481: printk(" queued xmit.\n"); ! 482: dev_kfree_skb (skb, FREE_WRITE); ! 483: return 0; ! 484: } ! 485: ! 486: ! 487: /* ! 488: * The typical workload of the driver: ! 489: * Handle the ether interface interrupts. ! 490: */ ! 491: ! 492: static void el_interrupt(int irq, struct pt_regs *regs) ! 493: { ! 494: struct device *dev = (struct device *)(irq2dev_map[irq]); ! 495: struct net_local *lp; ! 496: int ioaddr; ! 497: int axsr; /* Aux. status reg. */ ! 498: ! 499: if (dev == NULL || dev->irq != irq) ! 500: { ! 501: printk ("3c501 driver: irq %d for unknown device.\n", irq); ! 502: return; ! 503: } ! 504: ! 505: ioaddr = dev->base_addr; ! 506: lp = (struct net_local *)dev->priv; ! 507: ! 508: /* ! 509: * What happened ? ! 510: */ ! 511: ! 512: axsr = inb(AX_STATUS); ! 513: ! 514: /* ! 515: * Log it ! 516: */ ! 517: ! 518: if (el_debug > 3) ! 519: printk("%s: el_interrupt() aux=%#02x", dev->name, axsr); ! 520: if (dev->interrupt) ! 521: printk("%s: Reentering the interrupt driver!\n", dev->name); ! 522: dev->interrupt = 1; ! 523: #ifndef BLOCKOUT_1 ! 524: if(lp->loading==1 && !dev->tbusy) ! 525: printk("%s: Inconsistent state loading while not in tx\n", ! 526: dev->name); ! 527: #endif ! 528: #ifdef BLOCKOUT_3 ! 529: lp->loading=2; /* So we can spot loading interruptions */ ! 530: #endif ! 531: ! 532: if (dev->tbusy) ! 533: { ! 534: ! 535: /* ! 536: * Board in transmit mode. May be loading. If we are ! 537: * loading we shouldn't have got this. ! 538: */ ! 539: ! 540: int txsr = inb(TX_STATUS); ! 541: #ifdef BLOCKOUT_2 ! 542: if(lp->loading==1) ! 543: { ! 544: if(el_debug > 2) ! 545: { ! 546: printk("%s: Interrupt while loading [", dev->name); ! 547: printk(" txsr=%02x gp=%04x rp=%04x]\n", txsr, inw(GP_LOW),inw(RX_LOW)); ! 548: } ! 549: lp->loading=2; /* Force a reload */ ! 550: dev->interrupt = 0; ! 551: return; ! 552: } ! 553: #endif ! 554: if (el_debug > 6) ! 555: printk(" txsr=%02x gp=%04x rp=%04x", txsr, inw(GP_LOW),inw(RX_LOW)); ! 556: ! 557: if ((axsr & 0x80) && (txsr & TX_READY) == 0) ! 558: { ! 559: /* ! 560: * FIXME: is there a logic to whether to keep on trying or ! 561: * reset immediately ? ! 562: */ ! 563: printk("%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x" ! 564: " gp=%03x rp=%03x.\n", dev->name, txsr, axsr, ! 565: inw(ioaddr + EL1_DATAPTR), inw(ioaddr + EL1_RXPTR)); ! 566: dev->tbusy = 0; ! 567: mark_bh(NET_BH); ! 568: } ! 569: else if (txsr & TX_16COLLISIONS) ! 570: { ! 571: /* ! 572: * Timed out ! 573: */ ! 574: if (el_debug) ! 575: printk("%s: Transmit failed 16 times, ethernet jammed?\n",dev->name); ! 576: outb(AX_SYS, AX_CMD); ! 577: lp->stats.tx_aborted_errors++; ! 578: } ! 579: else if (txsr & TX_COLLISION) ! 580: { ! 581: /* ! 582: * Retrigger xmit. ! 583: */ ! 584: ! 585: if (el_debug > 6) ! 586: printk(" retransmitting after a collision.\n"); ! 587: /* ! 588: * Poor little chip can't reset its own start pointer ! 589: */ ! 590: ! 591: outb(AX_SYS, AX_CMD); ! 592: outw(lp->tx_pkt_start, GP_LOW); ! 593: outb(AX_XMIT, AX_CMD); ! 594: lp->stats.collisions++; ! 595: dev->interrupt = 0; ! 596: return; ! 597: } ! 598: else ! 599: { ! 600: /* ! 601: * It worked.. we will now fall through and receive ! 602: */ ! 603: lp->stats.tx_packets++; ! 604: if (el_debug > 6) ! 605: printk(" Tx succeeded %s\n", ! 606: (txsr & TX_RDY) ? "." : "but tx is busy!"); ! 607: /* ! 608: * This is safe the interrupt is atomic WRT itself. ! 609: */ ! 610: ! 611: dev->tbusy = 0; ! 612: mark_bh(NET_BH); /* In case more to transmit */ ! 613: } ! 614: } ! 615: else ! 616: { ! 617: /* ! 618: * In receive mode. ! 619: */ ! 620: ! 621: int rxsr = inb(RX_STATUS); ! 622: if (el_debug > 5) ! 623: printk(" rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS),inw(RX_LOW)); ! 624: /* ! 625: * Just reading rx_status fixes most errors. ! 626: */ ! 627: if (rxsr & RX_MISSED) ! 628: lp->stats.rx_missed_errors++; ! 629: else if (rxsr & RX_RUNT) ! 630: { /* Handled to avoid board lock-up. */ ! 631: lp->stats.rx_length_errors++; ! 632: if (el_debug > 5) ! 633: printk(" runt.\n"); ! 634: } ! 635: else if (rxsr & RX_GOOD) ! 636: { ! 637: /* ! 638: * Receive worked. ! 639: */ ! 640: el_receive(dev); ! 641: } ! 642: else ! 643: { ! 644: /* ! 645: * Nothing? Something is broken! ! 646: */ ! 647: if (el_debug > 2) ! 648: printk("%s: No packet seen, rxsr=%02x **resetting 3c501***\n", ! 649: dev->name, rxsr); ! 650: el_reset(dev); ! 651: } ! 652: if (el_debug > 3) ! 653: printk(".\n"); ! 654: } ! 655: ! 656: /* ! 657: * Move into receive mode ! 658: */ ! 659: ! 660: outb(AX_RX, AX_CMD); ! 661: outw(0x00, RX_BUF_CLR); ! 662: inb(RX_STATUS); /* Be certain that interrupts are cleared. */ ! 663: inb(TX_STATUS); ! 664: dev->interrupt = 0; ! 665: return; ! 666: } ! 667: ! 668: ! 669: /* ! 670: * We have a good packet. Well, not really "good", just mostly not broken. ! 671: * We must check everything to see if it is good. ! 672: */ ! 673: ! 674: static void el_receive(struct device *dev) ! 675: { ! 676: struct net_local *lp = (struct net_local *)dev->priv; ! 677: int ioaddr = dev->base_addr; ! 678: int pkt_len; ! 679: struct sk_buff *skb; ! 680: ! 681: pkt_len = inw(RX_LOW); ! 682: ! 683: if (el_debug > 4) ! 684: printk(" el_receive %d.\n", pkt_len); ! 685: ! 686: if ((pkt_len < 60) || (pkt_len > 1536)) ! 687: { ! 688: if (el_debug) ! 689: printk("%s: bogus packet, length=%d\n", dev->name, pkt_len); ! 690: lp->stats.rx_over_errors++; ! 691: return; ! 692: } ! 693: ! 694: /* ! 695: * Command mode so we can empty the buffer ! 696: */ ! 697: ! 698: outb(AX_SYS, AX_CMD); ! 699: skb = dev_alloc_skb(pkt_len+2); ! 700: ! 701: /* ! 702: * Start of frame ! 703: */ ! 704: ! 705: outw(0x00, GP_LOW); ! 706: if (skb == NULL) ! 707: { ! 708: printk("%s: Memory squeeze, dropping packet.\n", dev->name); ! 709: lp->stats.rx_dropped++; ! 710: return; ! 711: } ! 712: else ! 713: { ! 714: skb_reserve(skb,2); /* Force 16 byte alignment */ ! 715: skb->dev = dev; ! 716: /* ! 717: * The read increments through the bytes. The interrupt ! 718: * handler will fix the pointer when it returns to ! 719: * receive mode. ! 720: */ ! 721: insb(DATAPORT, skb_put(skb,pkt_len), pkt_len); ! 722: skb->protocol=eth_type_trans(skb,dev); ! 723: netif_rx(skb); ! 724: lp->stats.rx_packets++; ! 725: } ! 726: return; ! 727: } ! 728: ! 729: static void el_reset(struct device *dev) ! 730: { ! 731: int ioaddr = dev->base_addr; ! 732: ! 733: if (el_debug> 2) ! 734: printk("3c501 reset..."); ! 735: outb(AX_RESET, AX_CMD); /* Reset the chip */ ! 736: outb(AX_LOOP, AX_CMD); /* Aux control, irq and loopback enabled */ ! 737: { ! 738: int i; ! 739: for (i = 0; i < 6; i++) /* Set the station address. */ ! 740: outb(dev->dev_addr[i], ioaddr + i); ! 741: } ! 742: ! 743: outw(0, RX_BUF_CLR); /* Set rx packet area to 0. */ ! 744: cli(); /* Avoid glitch on writes to CMD regs */ ! 745: outb(TX_NORM, TX_CMD); /* tx irq on done, collision */ ! 746: outb(RX_NORM, RX_CMD); /* Set Rx commands. */ ! 747: inb(RX_STATUS); /* Clear status. */ ! 748: inb(TX_STATUS); ! 749: dev->interrupt = 0; ! 750: dev->tbusy = 0; ! 751: sti(); ! 752: } ! 753: ! 754: static int el1_close(struct device *dev) ! 755: { ! 756: int ioaddr = dev->base_addr; ! 757: ! 758: if (el_debug > 2) ! 759: printk("%s: Shutting down ethercard at %#x.\n", dev->name, ioaddr); ! 760: ! 761: dev->tbusy = 1; ! 762: dev->start = 0; ! 763: ! 764: /* ! 765: * Free and disable the IRQ. ! 766: */ ! 767: ! 768: free_irq(dev->irq); ! 769: outb(AX_RESET, AX_CMD); /* Reset the chip */ ! 770: irq2dev_map[dev->irq] = 0; ! 771: ! 772: MOD_DEC_USE_COUNT; ! 773: return 0; ! 774: } ! 775: ! 776: static struct enet_statistics *el1_get_stats(struct device *dev) ! 777: { ! 778: struct net_local *lp = (struct net_local *)dev->priv; ! 779: return &lp->stats; ! 780: } ! 781: ! 782: /* ! 783: * Set or clear the multicast filter for this adaptor. ! 784: * best-effort filtering. ! 785: */ ! 786: ! 787: static void set_multicast_list(struct device *dev) ! 788: { ! 789: int ioaddr = dev->base_addr; ! 790: ! 791: if(dev->flags&IFF_PROMISC) ! 792: { ! 793: outb(RX_PROM, RX_CMD); ! 794: inb(RX_STATUS); ! 795: } ! 796: else if (dev->mc_list || dev->flags&IFF_ALLMULTI) ! 797: { ! 798: outb(RX_MULT, RX_CMD); /* Multicast or all multicast is the same */ ! 799: inb(RX_STATUS); /* Clear status. */ ! 800: } ! 801: else ! 802: { ! 803: outb(RX_NORM, RX_CMD); ! 804: inb(RX_STATUS); ! 805: } ! 806: } ! 807: ! 808: #ifdef MODULE ! 809: ! 810: static char devicename[9] = { 0, }; ! 811: ! 812: static struct device dev_3c501 = ! 813: { ! 814: devicename, /* device name is inserted by linux/drivers/net/net_init.c */ ! 815: 0, 0, 0, 0, ! 816: 0x280, 5, ! 817: 0, 0, 0, NULL, el1_probe ! 818: }; ! 819: ! 820: static int io=0x280; ! 821: static int irq=5; ! 822: ! 823: int init_module(void) ! 824: { ! 825: dev_3c501.irq=irq; ! 826: dev_3c501.base_addr=io; ! 827: if (register_netdev(&dev_3c501) != 0) ! 828: return -EIO; ! 829: return 0; ! 830: } ! 831: ! 832: void cleanup_module(void) ! 833: { ! 834: /* ! 835: * No need to check MOD_IN_USE, as sys_delete_module() checks. ! 836: */ ! 837: ! 838: unregister_netdev(&dev_3c501); ! 839: ! 840: /* ! 841: * Free up the private structure, or leak memory :-) ! 842: */ ! 843: ! 844: kfree(dev_3c501.priv); ! 845: dev_3c501.priv = NULL; /* gets re-allocated by el1_probe1 */ ! 846: ! 847: /* ! 848: * If we don't do this, we can't re-insmod it later. ! 849: */ ! 850: release_region(dev_3c501.base_addr, EL1_IO_EXTENT); ! 851: } ! 852: ! 853: #endif /* MODULE */ ! 854: ! 855: /* ! 856: * Local variables: ! 857: * compile-command: "gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -m486 -c -o 3c501.o 3c501.c" ! 858: * kept-new-versions: 5 ! 859: * End: ! 860: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.