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