|
|
1.1 ! root 1: /* ac3200.c: A driver for the Ansel Communications EISA ethernet adaptor. */ ! 2: /* ! 3: Written 1993, 1994 by Donald Becker. ! 4: Copyright 1993 United States Government as represented by the Director, ! 5: National Security Agency. This software may only be used and distributed ! 6: according to the terms of the GNU Public License as modified by SRC, ! 7: incorporated herein by reference. ! 8: ! 9: The author may be reached as [email protected], or ! 10: C/O Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 ! 11: ! 12: This is driver for the Ansel Communications Model 3200 EISA Ethernet LAN ! 13: Adapter. The programming information is from the users manual, as related ! 14: by [email protected]. ! 15: */ ! 16: ! 17: static const char *version = ! 18: "ac3200.c:v1.01 7/1/94 Donald Becker ([email protected])\n"; ! 19: ! 20: #include <linux/module.h> ! 21: ! 22: #include <linux/kernel.h> ! 23: #include <linux/sched.h> ! 24: #include <linux/errno.h> ! 25: #include <linux/string.h> ! 26: #include <linux/netdevice.h> ! 27: #include <linux/etherdevice.h> ! 28: ! 29: #include <asm/system.h> ! 30: #include <asm/io.h> ! 31: ! 32: #include "8390.h" ! 33: ! 34: /* Offsets from the base address. */ ! 35: #define AC_NIC_BASE 0x00 ! 36: #define AC_SA_PROM 0x16 /* The station address PROM. */ ! 37: #define AC_ADDR0 0x00 /* Prefix station address values. */ ! 38: #define AC_ADDR1 0x40 /* !!!!These are just guesses!!!! */ ! 39: #define AC_ADDR2 0x90 ! 40: #define AC_ID_PORT 0xC80 ! 41: #define AC_EISA_ID 0x0110d305 ! 42: #define AC_RESET_PORT 0xC84 ! 43: #define AC_RESET 0x00 ! 44: #define AC_ENABLE 0x01 ! 45: #define AC_CONFIG 0xC90 /* The configuration port. */ ! 46: ! 47: #define AC_IO_EXTENT 0x10 /* IS THIS REALLY TRUE ??? */ ! 48: /* Actually accessed is: ! 49: * AC_NIC_BASE (0-15) ! 50: * AC_SA_PROM (0-5) ! 51: * AC_ID_PORT (0-3) ! 52: * AC_RESET_PORT ! 53: * AC_CONFIG ! 54: */ ! 55: ! 56: /* Decoding of the configuration register. */ ! 57: static unsigned char config2irqmap[8] = {15, 12, 11, 10, 9, 7, 5, 3}; ! 58: static int addrmap[8] = ! 59: {0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000, 0xD0000, 0 }; ! 60: static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"}; ! 61: ! 62: #define config2irq(configval) config2irqmap[((configval) >> 3) & 7] ! 63: #define config2mem(configval) addrmap[(configval) & 7] ! 64: #define config2name(configval) port_name[((configval) >> 6) & 3] ! 65: ! 66: /* First and last 8390 pages. */ ! 67: #define AC_START_PG 0x00 /* First page of 8390 TX buffer */ ! 68: #define AC_STOP_PG 0x80 /* Last page +1 of the 8390 RX ring */ ! 69: ! 70: int ac3200_probe(struct device *dev); ! 71: static int ac_probe1(int ioaddr, struct device *dev); ! 72: ! 73: static int ac_open(struct device *dev); ! 74: static void ac_reset_8390(struct device *dev); ! 75: static void ac_block_input(struct device *dev, int count, ! 76: struct sk_buff *skb, int ring_offset); ! 77: static void ac_block_output(struct device *dev, const int count, ! 78: const unsigned char *buf, const int start_page); ! 79: static void ac_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, ! 80: int ring_page); ! 81: ! 82: static int ac_close_card(struct device *dev); ! 83: ! 84: ! 85: /* Probe for the AC3200. ! 86: ! 87: The AC3200 can be identified by either the EISA configuration registers, ! 88: or the unique value in the station address PROM. ! 89: */ ! 90: ! 91: int ac3200_probe(struct device *dev) ! 92: { ! 93: unsigned short ioaddr = dev->base_addr; ! 94: ! 95: if (ioaddr > 0x1ff) /* Check a single specified location. */ ! 96: return ac_probe1(ioaddr, dev); ! 97: else if (ioaddr > 0) /* Don't probe at all. */ ! 98: return ENXIO; ! 99: ! 100: /* If you have a pre 0.99pl15 machine you should delete this line. */ ! 101: if ( ! EISA_bus) ! 102: return ENXIO; ! 103: ! 104: for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) { ! 105: if (check_region(ioaddr, AC_IO_EXTENT)) ! 106: continue; ! 107: if (ac_probe1(ioaddr, dev) == 0) ! 108: return 0; ! 109: } ! 110: ! 111: return ENODEV; ! 112: } ! 113: ! 114: static int ac_probe1(int ioaddr, struct device *dev) ! 115: { ! 116: int i; ! 117: ! 118: #ifndef final_version ! 119: printk("AC3200 ethercard probe at %#3x:", ioaddr); ! 120: ! 121: for(i = 0; i < 6; i++) ! 122: printk(" %02x", inb(ioaddr + AC_SA_PROM + i)); ! 123: #endif ! 124: ! 125: /* !!!!The values of AC_ADDRn (see above) should be corrected when we ! 126: find out the correct station address prefix!!!! */ ! 127: if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0 ! 128: || inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1 ! 129: || inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) { ! 130: #ifndef final_version ! 131: printk(" not found (invalid prefix).\n"); ! 132: #endif ! 133: return ENODEV; ! 134: } ! 135: ! 136: /* The correct probe method is to check the EISA ID. */ ! 137: for (i = 0; i < 4; i++) ! 138: if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) { ! 139: printk("EISA ID mismatch, %8x vs %8x.\n", ! 140: inl(ioaddr + AC_ID_PORT), AC_EISA_ID); ! 141: return ENODEV; ! 142: } ! 143: ! 144: ! 145: /* We should have a "dev" from Space.c or the static module table. */ ! 146: if (dev == NULL) { ! 147: printk("ac3200.c: Passed a NULL device.\n"); ! 148: dev = init_etherdev(0, 0); ! 149: } ! 150: ! 151: for(i = 0; i < ETHER_ADDR_LEN; i++) ! 152: dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i); ! 153: ! 154: #ifndef final_version ! 155: printk("\nAC3200 ethercard configuration register is %#02x," ! 156: " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG), ! 157: inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1), ! 158: inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3)); ! 159: #endif ! 160: ! 161: /* Assign and allocate the interrupt now. */ ! 162: if (dev->irq == 0) ! 163: dev->irq = config2irq(inb(ioaddr + AC_CONFIG)); ! 164: else if (dev->irq == 2) ! 165: dev->irq = 9; ! 166: ! 167: if (request_irq(dev->irq, ei_interrupt, 0, "ac3200", NULL)) { ! 168: printk (" unable to get IRQ %d.\n", dev->irq); ! 169: return EAGAIN; ! 170: } ! 171: ! 172: /* Allocate dev->priv and fill in 8390 specific dev fields. */ ! 173: if (ethdev_init(dev)) { ! 174: printk (" unable to allocate memory for dev->priv.\n"); ! 175: free_irq(dev->irq, NULL); ! 176: return -ENOMEM; ! 177: } ! 178: ! 179: request_region(ioaddr, AC_IO_EXTENT, "ac3200"); ! 180: ! 181: dev->base_addr = ioaddr; ! 182: ! 183: #ifdef notyet ! 184: if (dev->mem_start) { /* Override the value from the board. */ ! 185: for (i = 0; i < 7; i++) ! 186: if (addrmap[i] == dev->mem_start) ! 187: break; ! 188: if (i >= 7) ! 189: i = 0; ! 190: outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG); ! 191: } ! 192: #endif ! 193: ! 194: dev->if_port = inb(ioaddr + AC_CONFIG) >> 6; ! 195: dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG)); ! 196: dev->rmem_start = dev->mem_start + TX_PAGES*256; ! 197: dev->mem_end = dev->rmem_end = dev->mem_start ! 198: + (AC_STOP_PG - AC_START_PG)*256; ! 199: ! 200: ei_status.name = "AC3200"; ! 201: ei_status.tx_start_page = AC_START_PG; ! 202: ei_status.rx_start_page = AC_START_PG + TX_PAGES; ! 203: ei_status.stop_page = AC_STOP_PG; ! 204: ei_status.word16 = 1; ! 205: ! 206: printk("\n%s: AC3200 at %#x, IRQ %d, %s port, shared memory %#lx-%#lx.\n", ! 207: dev->name, ioaddr, dev->irq, port_name[dev->if_port], ! 208: dev->mem_start, dev->mem_end-1); ! 209: ! 210: if (ei_debug > 0) ! 211: printk(version); ! 212: ! 213: ei_status.reset_8390 = &ac_reset_8390; ! 214: ei_status.block_input = &ac_block_input; ! 215: ei_status.block_output = &ac_block_output; ! 216: ei_status.get_8390_hdr = &ac_get_8390_hdr; ! 217: ! 218: dev->open = &ac_open; ! 219: dev->stop = &ac_close_card; ! 220: NS8390_init(dev, 0); ! 221: return 0; ! 222: } ! 223: ! 224: static int ac_open(struct device *dev) ! 225: { ! 226: #ifdef notyet ! 227: /* Someday we may enable the IRQ and shared memory here. */ ! 228: int ioaddr = dev->base_addr; ! 229: ! 230: if (request_irq(dev->irq, ei_interrupt, 0, "ac3200", NULL)) ! 231: return -EAGAIN; ! 232: #endif ! 233: ! 234: ei_open(dev); ! 235: ! 236: MOD_INC_USE_COUNT; ! 237: ! 238: return 0; ! 239: } ! 240: ! 241: static void ac_reset_8390(struct device *dev) ! 242: { ! 243: ushort ioaddr = dev->base_addr; ! 244: ! 245: outb(AC_RESET, ioaddr + AC_RESET_PORT); ! 246: if (ei_debug > 1) printk("resetting AC3200, t=%ld...", jiffies); ! 247: ! 248: ei_status.txing = 0; ! 249: outb(AC_ENABLE, ioaddr + AC_RESET_PORT); ! 250: if (ei_debug > 1) printk("reset done\n"); ! 251: ! 252: return; ! 253: } ! 254: ! 255: /* Grab the 8390 specific header. Similar to the block_input routine, but ! 256: we don't need to be concerned with ring wrap as the header will be at ! 257: the start of a page, so we optimize accordingly. */ ! 258: ! 259: static void ! 260: ac_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) ! 261: { ! 262: unsigned long hdr_start = dev->mem_start + ((ring_page - AC_START_PG)<<8); ! 263: memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); ! 264: } ! 265: ! 266: /* Block input and output are easy on shared memory ethercards, the only ! 267: complication is when the ring buffer wraps. */ ! 268: ! 269: static void ac_block_input(struct device *dev, int count, struct sk_buff *skb, ! 270: int ring_offset) ! 271: { ! 272: unsigned long xfer_start = dev->mem_start + ring_offset - (AC_START_PG<<8); ! 273: ! 274: if (xfer_start + count > dev->rmem_end) { ! 275: /* We must wrap the input move. */ ! 276: int semi_count = dev->rmem_end - xfer_start; ! 277: memcpy_fromio(skb->data, xfer_start, semi_count); ! 278: count -= semi_count; ! 279: memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); ! 280: } else { ! 281: /* Packet is in one chunk -- we can copy + cksum. */ ! 282: eth_io_copy_and_sum(skb, xfer_start, count, 0); ! 283: } ! 284: } ! 285: ! 286: static void ac_block_output(struct device *dev, int count, ! 287: const unsigned char *buf, int start_page) ! 288: { ! 289: unsigned long shmem = dev->mem_start + ((start_page - AC_START_PG)<<8); ! 290: ! 291: memcpy_toio(shmem, buf, count); ! 292: } ! 293: ! 294: static int ac_close_card(struct device *dev) ! 295: { ! 296: dev->start = 0; ! 297: dev->tbusy = 1; ! 298: ! 299: if (ei_debug > 1) ! 300: printk("%s: Shutting down ethercard.\n", dev->name); ! 301: ! 302: #ifdef notyet ! 303: /* We should someday disable shared memory and interrupts. */ ! 304: outb(0x00, ioaddr + 6); /* Disable interrupts. */ ! 305: free_irq(dev->irq, NULL); ! 306: irq2dev_map[dev->irq] = 0; ! 307: #endif ! 308: ! 309: ei_close(dev); ! 310: ! 311: MOD_DEC_USE_COUNT; ! 312: ! 313: return 0; ! 314: } ! 315: ! 316: #ifdef MODULE ! 317: #define MAX_AC32_CARDS 4 /* Max number of AC32 cards per module */ ! 318: #define NAMELEN 8 /* # of chars for storing dev->name */ ! 319: static char namelist[NAMELEN * MAX_AC32_CARDS] = { 0, }; ! 320: static struct device dev_ac32[MAX_AC32_CARDS] = { ! 321: { ! 322: NULL, /* assign a chunk of namelist[] below */ ! 323: 0, 0, 0, 0, ! 324: 0, 0, ! 325: 0, 0, 0, NULL, NULL ! 326: }, ! 327: }; ! 328: ! 329: static int io[MAX_AC32_CARDS] = { 0, }; ! 330: static int irq[MAX_AC32_CARDS] = { 0, }; ! 331: static int mem[MAX_AC32_CARDS] = { 0, }; ! 332: ! 333: int ! 334: init_module(void) ! 335: { ! 336: int this_dev, found = 0; ! 337: ! 338: for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) { ! 339: struct device *dev = &dev_ac32[this_dev]; ! 340: dev->name = namelist+(NAMELEN*this_dev); ! 341: dev->irq = irq[this_dev]; ! 342: dev->base_addr = io[this_dev]; ! 343: dev->mem_start = mem[this_dev]; /* Currently ignored by driver */ ! 344: dev->init = ac3200_probe; ! 345: /* Default is to only install one card. */ ! 346: if (io[this_dev] == 0 && this_dev != 0) break; ! 347: if (register_netdev(dev) != 0) { ! 348: printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]); ! 349: if (found != 0) return 0; /* Got at least one. */ ! 350: return -ENXIO; ! 351: } ! 352: found++; ! 353: } ! 354: ! 355: return 0; ! 356: } ! 357: ! 358: void ! 359: cleanup_module(void) ! 360: { ! 361: int this_dev; ! 362: ! 363: for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) { ! 364: struct device *dev = &dev_ac32[this_dev]; ! 365: if (dev->priv != NULL) { ! 366: kfree(dev->priv); ! 367: dev->priv = NULL; ! 368: /* Someday free_irq + irq2dev may be in ac_close_card() */ ! 369: free_irq(dev->irq, NULL); ! 370: irq2dev_map[dev->irq] = NULL; ! 371: release_region(dev->base_addr, AC_IO_EXTENT); ! 372: unregister_netdev(dev); ! 373: } ! 374: } ! 375: } ! 376: #endif /* MODULE */ ! 377: ! 378: /* ! 379: * Local variables: ! 380: * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c ac3200.c" ! 381: * version-control: t ! 382: * kept-new-versions: 5 ! 383: * tab-width: 4 ! 384: * End: ! 385: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.