|
|
1.1 ! root 1: /* smc-ultra.c: A SMC Ultra ethernet driver for linux. */ ! 2: /* ! 3: This is a driver for the SMC Ultra and SMC EtherEZ ISA ethercards. ! 4: ! 5: Written 1993-1998 by Donald Becker. ! 6: ! 7: Copyright 1993 United States Government as represented by the ! 8: Director, National Security Agency. ! 9: ! 10: This software may be used and distributed according to the terms ! 11: of the GNU Public License, incorporated herein by reference. ! 12: ! 13: The author may be reached as [email protected], or C/O ! 14: Center of Excellence in Space Data and Information Sciences ! 15: Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 ! 16: ! 17: This driver uses the cards in the 8390-compatible mode. ! 18: Most of the run-time complexity is handled by the generic code in ! 19: 8390.c. The code in this file is responsible for ! 20: ! 21: ultra_probe() Detecting and initializing the card. ! 22: ultra_probe1() ! 23: ! 24: ultra_open() The card-specific details of starting, stopping ! 25: ultra_reset_8390() and resetting the 8390 NIC core. ! 26: ultra_close() ! 27: ! 28: ultra_block_input() Routines for reading and writing blocks of ! 29: ultra_block_output() packet buffer memory. ! 30: ultra_pio_input() ! 31: ultra_pio_output() ! 32: ! 33: This driver enables the shared memory only when doing the actual data ! 34: transfers to avoid a bug in early version of the card that corrupted ! 35: data transferred by a AHA1542. ! 36: ! 37: This driver now supports the programmed-I/O (PIO) data transfer mode of ! 38: the EtherEZ. It does not use the non-8390-compatible "Altego" mode. ! 39: That support (if available) is in smc-ez.c. ! 40: ! 41: Changelog: ! 42: ! 43: Paul Gortmaker : multiple card support for module users. ! 44: Donald Becker : 4/17/96 PIO support, minor potential problems avoided. ! 45: Donald Becker : 6/6/96 correctly set auto-wrap bit. ! 46: */ ! 47: ! 48: static const char *version = ! 49: "smc-ultra.c:v2.02 2/3/98 Donald Becker ([email protected])\n"; ! 50: ! 51: #include <linux/module.h> ! 52: ! 53: #include <linux/kernel.h> ! 54: #include <linux/sched.h> ! 55: #include <linux/errno.h> ! 56: #include <linux/string.h> ! 57: #include <asm/io.h> ! 58: #include <asm/system.h> ! 59: ! 60: #include <linux/netdevice.h> ! 61: #include <linux/etherdevice.h> ! 62: #include "8390.h" ! 63: ! 64: /* A zero-terminated list of I/O addresses to be probed. */ ! 65: static unsigned int ultra_portlist[] = ! 66: {0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0}; ! 67: ! 68: int ultra_probe(struct device *dev); ! 69: int ultra_probe1(struct device *dev, int ioaddr); ! 70: ! 71: static int ultra_open(struct device *dev); ! 72: static void ultra_reset_8390(struct device *dev); ! 73: static void ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, ! 74: int ring_page); ! 75: static void ultra_block_input(struct device *dev, int count, ! 76: struct sk_buff *skb, int ring_offset); ! 77: static void ultra_block_output(struct device *dev, int count, ! 78: const unsigned char *buf, const int start_page); ! 79: static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, ! 80: int ring_page); ! 81: static void ultra_pio_input(struct device *dev, int count, ! 82: struct sk_buff *skb, int ring_offset); ! 83: static void ultra_pio_output(struct device *dev, int count, ! 84: const unsigned char *buf, const int start_page); ! 85: static int ultra_close_card(struct device *dev); ! 86: ! 87: ! 88: #define START_PG 0x00 /* First page of TX buffer */ ! 89: ! 90: #define ULTRA_CMDREG 0 /* Offset to ASIC command register. */ ! 91: #define ULTRA_RESET 0x80 /* Board reset, in ULTRA_CMDREG. */ ! 92: #define ULTRA_MEMENB 0x40 /* Enable the shared memory. */ ! 93: #define IOPD 0x02 /* I/O Pipe Data (16 bits), PIO operation. */ ! 94: #define IOPA 0x07 /* I/O Pipe Address for PIO operation. */ ! 95: #define ULTRA_NIC_OFFSET 16 /* NIC register offset from the base_addr. */ ! 96: #define ULTRA_IO_EXTENT 32 ! 97: #define EN0_ERWCNT 0x08 /* Early receive warning count. */ ! 98: ! 99: /* Probe for the Ultra. This looks like a 8013 with the station ! 100: address PROM at I/O ports <base>+8 to <base>+13, with a checksum ! 101: following. ! 102: */ ! 103: #ifdef HAVE_DEVLIST ! 104: struct netdev_entry ultra_drv = ! 105: {"ultra", ultra_probe1, NETCARD_IO_EXTENT, netcard_portlist}; ! 106: #else ! 107: ! 108: int ultra_probe(struct device *dev) ! 109: { ! 110: int i; ! 111: int base_addr = dev ? dev->base_addr : 0; ! 112: ! 113: if (base_addr > 0x1ff) /* Check a single specified location. */ ! 114: return ultra_probe1(dev, base_addr); ! 115: else if (base_addr != 0) /* Don't probe at all. */ ! 116: return ENXIO; ! 117: ! 118: for (i = 0; ultra_portlist[i]; i++) { ! 119: int ioaddr = ultra_portlist[i]; ! 120: if (check_region(ioaddr, ULTRA_IO_EXTENT)) ! 121: continue; ! 122: if (ultra_probe1(dev, ioaddr) == 0) ! 123: return 0; ! 124: } ! 125: ! 126: return ENODEV; ! 127: } ! 128: #endif ! 129: ! 130: int ultra_probe1(struct device *dev, int ioaddr) ! 131: { ! 132: int i; ! 133: int checksum = 0; ! 134: const char *model_name; ! 135: unsigned char eeprom_irq = 0; ! 136: static unsigned version_printed = 0; ! 137: /* Values from various config regs. */ ! 138: unsigned char num_pages, irqreg, addr, piomode; ! 139: unsigned char idreg = inb(ioaddr + 7); ! 140: unsigned char reg4 = inb(ioaddr + 4) & 0x7f; ! 141: ! 142: /* Check the ID nibble. */ ! 143: if ((idreg & 0xF0) != 0x20 /* SMC Ultra */ ! 144: && (idreg & 0xF0) != 0x40) /* SMC EtherEZ */ ! 145: return ENODEV; ! 146: ! 147: /* Select the station address register set. */ ! 148: outb(reg4, ioaddr + 4); ! 149: ! 150: for (i = 0; i < 8; i++) ! 151: checksum += inb(ioaddr + 8 + i); ! 152: if ((checksum & 0xff) != 0xFF) ! 153: return ENODEV; ! 154: ! 155: if (dev == NULL) ! 156: dev = init_etherdev(0, 0); ! 157: ! 158: if (ei_debug && version_printed++ == 0) ! 159: printk(version); ! 160: ! 161: model_name = (idreg & 0xF0) == 0x20 ? "SMC Ultra" : "SMC EtherEZ"; ! 162: ! 163: printk("%s: %s at %#3x,", dev->name, model_name, ioaddr); ! 164: ! 165: for (i = 0; i < 6; i++) ! 166: printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i)); ! 167: ! 168: /* Switch from the station address to the alternate register set and ! 169: read the useful registers there. */ ! 170: outb(0x80 | reg4, ioaddr + 4); ! 171: ! 172: /* Enabled FINE16 mode to avoid BIOS ROM width mismatches @ reboot. */ ! 173: outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c); ! 174: piomode = inb(ioaddr + 0x8); ! 175: addr = inb(ioaddr + 0xb); ! 176: irqreg = inb(ioaddr + 0xd); ! 177: ! 178: /* Switch back to the station address register set so that the MS-DOS driver ! 179: can find the card after a warm boot. */ ! 180: outb(reg4, ioaddr + 4); ! 181: ! 182: if (dev->irq < 2) { ! 183: unsigned char irqmap[] = {0, 9, 3, 5, 7, 10, 11, 15}; ! 184: int irq; ! 185: ! 186: /* The IRQ bits are split. */ ! 187: irq = irqmap[((irqreg & 0x40) >> 4) + ((irqreg & 0x0c) >> 2)]; ! 188: ! 189: if (irq == 0) { ! 190: printk(", failed to detect IRQ line.\n"); ! 191: return -EAGAIN; ! 192: } ! 193: dev->irq = irq; ! 194: eeprom_irq = 1; ! 195: } ! 196: ! 197: /* Allocate dev->priv and fill in 8390 specific dev fields. */ ! 198: if (ethdev_init(dev)) { ! 199: printk (", no memory for dev->priv.\n"); ! 200: return -ENOMEM; ! 201: } ! 202: ! 203: /* OK, we are certain this is going to work. Setup the device. */ ! 204: request_region(ioaddr, ULTRA_IO_EXTENT, model_name); ! 205: ! 206: /* The 8390 isn't at the base address, so fake the offset */ ! 207: dev->base_addr = ioaddr+ULTRA_NIC_OFFSET; ! 208: ! 209: { ! 210: int addr_tbl[4] = {0x0C0000, 0x0E0000, 0xFC0000, 0xFE0000}; ! 211: short num_pages_tbl[4] = {0x20, 0x40, 0x80, 0xff}; ! 212: ! 213: dev->mem_start = ((addr & 0x0f) << 13) + addr_tbl[(addr >> 6) & 3] ; ! 214: num_pages = num_pages_tbl[(addr >> 4) & 3]; ! 215: } ! 216: ! 217: ei_status.name = model_name; ! 218: ei_status.word16 = 1; ! 219: ei_status.tx_start_page = START_PG; ! 220: ei_status.rx_start_page = START_PG + TX_PAGES; ! 221: ei_status.stop_page = num_pages; ! 222: ! 223: dev->rmem_start = dev->mem_start + TX_PAGES*256; ! 224: dev->mem_end = dev->rmem_end ! 225: = dev->mem_start + (ei_status.stop_page - START_PG)*256; ! 226: ! 227: if (piomode) { ! 228: printk(",%s IRQ %d programmed-I/O mode.\n", ! 229: eeprom_irq ? "EEPROM" : "assigned ", dev->irq); ! 230: ei_status.block_input = &ultra_pio_input; ! 231: ei_status.block_output = &ultra_pio_output; ! 232: ei_status.get_8390_hdr = &ultra_pio_get_hdr; ! 233: } else { ! 234: printk(",%s IRQ %d memory %#lx-%#lx.\n", eeprom_irq ? "" : "assigned ", ! 235: dev->irq, dev->mem_start, dev->mem_end-1); ! 236: ei_status.block_input = &ultra_block_input; ! 237: ei_status.block_output = &ultra_block_output; ! 238: ei_status.get_8390_hdr = &ultra_get_8390_hdr; ! 239: } ! 240: ei_status.reset_8390 = &ultra_reset_8390; ! 241: dev->open = &ultra_open; ! 242: dev->stop = &ultra_close_card; ! 243: NS8390_init(dev, 0); ! 244: ! 245: return 0; ! 246: } ! 247: ! 248: static int ! 249: ultra_open(struct device *dev) ! 250: { ! 251: int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ ! 252: unsigned char irq2reg[] = {0, 0, 0x04, 0x08, 0, 0x0C, 0, 0x40, ! 253: 0, 0x04, 0x44, 0x48, 0, 0, 0, 0x4C, }; ! 254: ! 255: if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name, dev)) ! 256: return -EAGAIN; ! 257: ! 258: outb(0x00, ioaddr); /* Disable shared memory for safety. */ ! 259: outb(0x80, ioaddr + 5); ! 260: /* Set the IRQ line. */ ! 261: outb(inb(ioaddr + 4) | 0x80, ioaddr + 4); ! 262: outb((inb(ioaddr + 13) & ~0x4C) | irq2reg[dev->irq], ioaddr + 13); ! 263: outb(inb(ioaddr + 4) & 0x7f, ioaddr + 4); ! 264: ! 265: if (ei_status.block_input == &ultra_pio_input) { ! 266: outb(0x11, ioaddr + 6); /* Enable interrupts and PIO. */ ! 267: outb(0x01, ioaddr + 0x19); /* Enable ring read auto-wrap. */ ! 268: } else ! 269: outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */ ! 270: /* Set the early receive warning level in window 0 high enough not ! 271: to receive ERW interrupts. */ ! 272: outb_p(E8390_NODMA+E8390_PAGE0, dev->base_addr); ! 273: outb(0xff, dev->base_addr + EN0_ERWCNT); ! 274: ei_open(dev); ! 275: MOD_INC_USE_COUNT; ! 276: return 0; ! 277: } ! 278: ! 279: static void ! 280: ultra_reset_8390(struct device *dev) ! 281: { ! 282: int cmd_port = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC base addr */ ! 283: ! 284: outb(ULTRA_RESET, cmd_port); ! 285: if (ei_debug > 1) printk("resetting Ultra, t=%ld...", jiffies); ! 286: ei_status.txing = 0; ! 287: ! 288: outb(0x00, cmd_port); /* Disable shared memory for safety. */ ! 289: outb(0x80, cmd_port + 5); ! 290: if (ei_status.block_input == &ultra_pio_input) ! 291: outb(0x11, cmd_port + 6); /* Enable interrupts and PIO. */ ! 292: else ! 293: outb(0x01, cmd_port + 6); /* Enable interrupts and memory. */ ! 294: ! 295: if (ei_debug > 1) printk("reset done\n"); ! 296: return; ! 297: } ! 298: ! 299: /* Grab the 8390 specific header. Similar to the block_input routine, but ! 300: we don't need to be concerned with ring wrap as the header will be at ! 301: the start of a page, so we optimize accordingly. */ ! 302: ! 303: static void ! 304: ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) ! 305: { ! 306: unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG)<<8); ! 307: ! 308: outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem on */ ! 309: #ifdef notdef ! 310: /* Officially this is what we are doing, but the readl() is faster */ ! 311: memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); ! 312: #else ! 313: ((unsigned int*)hdr)[0] = readl(hdr_start); ! 314: #endif ! 315: outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem off */ ! 316: } ! 317: ! 318: /* Block input and output are easy on shared memory ethercards, the only ! 319: complication is when the ring buffer wraps. */ ! 320: ! 321: static void ! 322: ultra_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) ! 323: { ! 324: unsigned long xfer_start = dev->mem_start + ring_offset - (START_PG<<8); ! 325: ! 326: /* Enable shared memory. */ ! 327: outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); ! 328: ! 329: if (xfer_start + count > dev->rmem_end) { ! 330: /* We must wrap the input move. */ ! 331: int semi_count = dev->rmem_end - xfer_start; ! 332: memcpy_fromio(skb->data, xfer_start, semi_count); ! 333: count -= semi_count; ! 334: memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); ! 335: } else { ! 336: /* Packet is in one chunk -- we can copy + cksum. */ ! 337: eth_io_copy_and_sum(skb, xfer_start, count, 0); ! 338: } ! 339: ! 340: outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */ ! 341: } ! 342: ! 343: static void ! 344: ultra_block_output(struct device *dev, int count, const unsigned char *buf, ! 345: int start_page) ! 346: { ! 347: unsigned long shmem = dev->mem_start + ((start_page - START_PG)<<8); ! 348: ! 349: /* Enable shared memory. */ ! 350: outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); ! 351: ! 352: memcpy_toio(shmem, buf, count); ! 353: ! 354: outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */ ! 355: } ! 356: ! 357: /* The identical operations for programmed I/O cards. ! 358: The PIO model is trivial to use: the 16 bit start address is written ! 359: byte-sequentially to IOPA, with no intervening I/O operations, and the ! 360: data is read or written to the IOPD data port. ! 361: The only potential complication is that the address register is shared ! 362: and must be always be rewritten between each read/write direction change. ! 363: This is no problem for us, as the 8390 code ensures that we are single ! 364: threaded. */ ! 365: static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, ! 366: int ring_page) ! 367: { ! 368: int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ ! 369: outb(0x00, ioaddr + IOPA); /* Set the address, LSB first. */ ! 370: outb(ring_page, ioaddr + IOPA); ! 371: insw(ioaddr + IOPD, hdr, sizeof(struct e8390_pkt_hdr)>>1); ! 372: } ! 373: ! 374: static void ultra_pio_input(struct device *dev, int count, ! 375: struct sk_buff *skb, int ring_offset) ! 376: { ! 377: int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ ! 378: char *buf = skb->data; ! 379: ! 380: /* For now set the address again, although it should already be correct. */ ! 381: outb(ring_offset, ioaddr + IOPA); /* Set the address, LSB first. */ ! 382: outb(ring_offset >> 8, ioaddr + IOPA); ! 383: /* We know skbuffs are padded to at least word alignment. */ ! 384: insw(ioaddr + IOPD, buf, (count+1)>>1); ! 385: } ! 386: ! 387: static void ultra_pio_output(struct device *dev, int count, ! 388: const unsigned char *buf, const int start_page) ! 389: { ! 390: int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ ! 391: outb(0x00, ioaddr + IOPA); /* Set the address, LSB first. */ ! 392: outb(start_page, ioaddr + IOPA); ! 393: /* An extra odd byte is OK here as well. */ ! 394: outsw(ioaddr + IOPD, buf, (count+1)>>1); ! 395: } ! 396: ! 397: static int ! 398: ultra_close_card(struct device *dev) ! 399: { ! 400: int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* CMDREG */ ! 401: ! 402: dev->start = 0; ! 403: dev->tbusy = 1; ! 404: ! 405: if (ei_debug > 1) ! 406: printk("%s: Shutting down ethercard.\n", dev->name); ! 407: ! 408: outb(0x00, ioaddr + 6); /* Disable interrupts. */ ! 409: free_irq(dev->irq, dev); ! 410: irq2dev_map[dev->irq] = 0; ! 411: ! 412: NS8390_init(dev, 0); ! 413: ! 414: /* We should someday disable shared memory and change to 8-bit mode ! 415: "just in case"... */ ! 416: ! 417: MOD_DEC_USE_COUNT; ! 418: ! 419: return 0; ! 420: } ! 421: ! 422: ! 423: #ifdef MODULE ! 424: #define MAX_ULTRA_CARDS 4 /* Max number of Ultra cards per module */ ! 425: #define NAMELEN 8 /* # of chars for storing dev->name */ ! 426: static char namelist[NAMELEN * MAX_ULTRA_CARDS] = { 0, }; ! 427: static struct device dev_ultra[MAX_ULTRA_CARDS] = { ! 428: { ! 429: NULL, /* assign a chunk of namelist[] below */ ! 430: 0, 0, 0, 0, ! 431: 0, 0, ! 432: 0, 0, 0, NULL, NULL ! 433: }, ! 434: }; ! 435: ! 436: static int io[MAX_ULTRA_CARDS] = { 0, }; ! 437: static int irq[MAX_ULTRA_CARDS] = { 0, }; ! 438: ! 439: /* This is set up so that only a single autoprobe takes place per call. ! 440: ISA device autoprobes on a running machine are not recommended. */ ! 441: int ! 442: init_module(void) ! 443: { ! 444: int this_dev, found = 0; ! 445: ! 446: for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) { ! 447: struct device *dev = &dev_ultra[this_dev]; ! 448: dev->name = namelist+(NAMELEN*this_dev); ! 449: dev->irq = irq[this_dev]; ! 450: dev->base_addr = io[this_dev]; ! 451: dev->init = ultra_probe; ! 452: if (io[this_dev] == 0) { ! 453: if (this_dev != 0) break; /* only autoprobe 1st one */ ! 454: printk(KERN_NOTICE "smc-ultra.c: Presently autoprobing (not recommended) for a single card.\n"); ! 455: } ! 456: if (register_netdev(dev) != 0) { ! 457: printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]); ! 458: if (found != 0) return 0; /* Got at least one. */ ! 459: return -ENXIO; ! 460: } ! 461: found++; ! 462: } ! 463: ! 464: return 0; ! 465: } ! 466: ! 467: void ! 468: cleanup_module(void) ! 469: { ! 470: int this_dev; ! 471: ! 472: for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) { ! 473: struct device *dev = &dev_ultra[this_dev]; ! 474: if (dev->priv != NULL) { ! 475: /* NB: ultra_close_card() does free_irq + irq2dev */ ! 476: int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; ! 477: kfree(dev->priv); ! 478: dev->priv = NULL; ! 479: release_region(ioaddr, ULTRA_IO_EXTENT); ! 480: unregister_netdev(dev); ! 481: } ! 482: } ! 483: } ! 484: #endif /* MODULE */ ! 485: ! 486: ! 487: /* ! 488: * Local variables: ! 489: * compile-command: "gcc -D__KERNEL__ -Wall -O6 -I/usr/src/linux/net/inet -c smc-ultra.c" ! 490: * version-control: t ! 491: * kept-new-versions: 5 ! 492: * c-indent-level: 4 ! 493: * c-basic-offset: 4 ! 494: * tab-width: 4 ! 495: * End: ! 496: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.