static int pcnet_resume(struct pcmcia_device *link) { struct net_device *dev = link->priv; if (link->open) { pcnet_reset_8390(dev); NS8390_init(dev, 1); netif_device_attach(dev); } return 0; }
static int hpp_close(struct device *dev) { int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg = inw(ioaddr + HPP_OPTION); free_irq(dev->irq); irq2dev_map[dev->irq] = NULL; NS8390_init(dev, 0); outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset, ioaddr + HPP_OPTION); return 0; }
static int set_config(struct net_device *dev, struct ifmap *map) { pcnet_dev_t *info = PRIV(dev); if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { if (!(info->flags & HAS_MISC_REG)) return -EOPNOTSUPP; else if ((map->port < 1) || (map->port > 2)) return -EINVAL; dev->if_port = map->port; netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]); NS8390_init(dev, 1); } return 0; }
static int ultra32_close(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; netif_stop_queue(dev); if (ei_debug > 1) printk("%s: Shutting down ethercard.\n", dev->name); outb(0x00, ioaddr + ULTRA32_CFG6); outb(0x00, ioaddr + 6); free_irq(dev->irq, dev); NS8390_init(dev, 0); return 0; }
static int ultramca_close_card(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ netif_stop_queue(dev); if (ei_debug > 1) printk("%s: Shutting down ethercard.\n", dev->name); outb(0x00, ioaddr + 6); /* Disable interrupts. */ free_irq(dev->irq, dev); NS8390_init(dev, 0); /* We should someday disable shared memory and change to 8-bit mode * "just in case"... */ return 0; }
static int __init ultra32_probe1(struct net_device *dev, int ioaddr) { int i, edge, media, retval; int checksum = 0; const char *model_name; static unsigned version_printed; unsigned char idreg; unsigned char reg4; const char *ifmap[] = {"UTP No Link", "", "UTP/AUI", "UTP/BNC"}; if (!request_region(ioaddr, ULTRA32_IO_EXTENT, DRV_NAME)) return -EBUSY; if (inb(ioaddr + ULTRA32_IDPORT) == 0xff || inl(ioaddr + ULTRA32_IDPORT) != ULTRA32_ID) { retval = -ENODEV; goto out; } media = inb(ioaddr + ULTRA32_CFG7) & 0x03; edge = inb(ioaddr + ULTRA32_CFG5) & 0x08; printk("SMC Ultra32 in EISA Slot %d, Media: %s, %s IRQs.\n", ioaddr >> 12, ifmap[media], (edge ? "Edge Triggered" : "Level Sensitive")); idreg = inb(ioaddr + 7); reg4 = inb(ioaddr + 4) & 0x7f; if ((idreg & 0xf0) != 0x20) { retval = -ENODEV; goto out; } outb(reg4, ioaddr + 4); for (i = 0; i < 8; i++) checksum += inb(ioaddr + 8 + i); if ((checksum & 0xff) != 0xff) { retval = -ENODEV; goto out; } if (ei_debug && version_printed++ == 0) printk(version); model_name = "SMC Ultra32"; for (i = 0; i < 6; i++) dev->dev_addr[i] = inb(ioaddr + 8 + i); printk("%s: %s at 0x%X, %pM", dev->name, model_name, ioaddr, dev->dev_addr); outb(0x80 | reg4, ioaddr + 4); outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c); outb(0x00, ioaddr + 0x0b); outb(reg4, ioaddr + 4); if ((inb(ioaddr + ULTRA32_CFG5) & 0x40) == 0) { printk("\nsmc-ultra32: Card RAM is disabled! " "Run EISA config utility.\n"); retval = -ENODEV; goto out; } if ((inb(ioaddr + ULTRA32_CFG2) & 0x04) == 0) printk("\nsmc-ultra32: Ignoring Bus-Master enable bit. " "Run EISA config utility.\n"); if (dev->irq < 2) { unsigned char irqmap[] = {0, 9, 3, 5, 7, 10, 11, 15}; int irq = irqmap[inb(ioaddr + ULTRA32_CFG5) & 0x07]; if (irq == 0) { printk(", failed to detect IRQ line.\n"); retval = -EAGAIN; goto out; } dev->irq = irq; } dev->base_addr = ioaddr + ULTRA32_NIC_OFFSET; ei_status.reg0 = inb(ioaddr + ULTRA32_CFG3) & 0xfc; dev->mem_start = 0xc0000 + ((ei_status.reg0 & 0x7c) << 11); ei_status.name = model_name; ei_status.word16 = 1; ei_status.tx_start_page = 0; ei_status.rx_start_page = TX_PAGES; ei_status.stop_page = 128; ei_status.mem = ioremap(dev->mem_start, 0x2000); if (!ei_status.mem) { printk(", failed to ioremap.\n"); retval = -ENOMEM; goto out; } dev->mem_end = dev->mem_start + 0x1fff; printk(", IRQ %d, 32KB memory, 8KB window at 0x%lx-0x%lx.\n", dev->irq, dev->mem_start, dev->mem_end); ei_status.block_input = &ultra32_block_input; ei_status.block_output = &ultra32_block_output; ei_status.get_8390_hdr = &ultra32_get_8390_hdr; ei_status.reset_8390 = &ultra32_reset_8390; dev->netdev_ops = &ultra32_netdev_ops; NS8390_init(dev, 0); return 0; out: release_region(ioaddr, ULTRA32_IO_EXTENT); return retval; }
static int neprobe1(int ioaddr, struct device *dev, int verbose) { int i; unsigned char SA_prom[32]; int wordlength = 2; char *name; int start_page, stop_page; int neX000, ctron, dlink, dfi; int reg0 = inb(ioaddr); if ( reg0 == 0xFF) return 0; /* Do a quick preliminary check that we have a 8390. */ { int regd; outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); regd = inb_p(ioaddr + 0x0d); outb_p(0xff, ioaddr + 0x0d); outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD); inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ if (inb_p(ioaddr + EN0_COUNTER0) != 0) { outb_p(reg0, ioaddr); outb(regd, ioaddr + 0x0d); /* Restore the old values. */ return 0; } } printk("NE*000 ethercard probe at %#3x:", ioaddr); /* Read the 16 bytes of station address prom, returning 1 for an eight-bit interface and 2 for a 16-bit interface. We must first initialize registers, similar to NS8390_init(eifdev, 0). We can't reliably read the SAPROM address without this. (I learned the hard way!). */ { struct {unsigned char value, offset; } program_seq[] = { {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ {0x00, EN0_RCNTLO}, /* Clear the count regs. */ {0x00, EN0_RCNTHI}, {0x00, EN0_IMR}, /* Mask completion irq. */ {0xFF, EN0_ISR}, {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ {32, EN0_RCNTLO}, {0x00, EN0_RCNTHI}, {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ {0x00, EN0_RSARHI}, {E8390_RREAD+E8390_START, E8390_CMD}, }; for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); } for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) { SA_prom[i] = inb(ioaddr + NE_DATAPORT); SA_prom[i+1] = inb(ioaddr + NE_DATAPORT); if (SA_prom[i] != SA_prom[i+1]) wordlength = 1; } if (wordlength == 2) { /* We must set the 8390 for word mode. */ outb_p(0x49, ioaddr + EN0_DCFG); /* We used to reset the ethercard here, but it doesn't seem to be necessary. */ /* Un-double the SA_prom values. */ for (i = 0; i < 16; i++) SA_prom[i] = SA_prom[i+i]; } #if defined(show_all_SAPROM) /* If your ethercard isn't detected define this to see the SA_PROM. */ for(i = 0; i < sizeof(SA_prom); i++) printk(" %2.2x", SA_prom[i]); #else for(i = 0; i < ETHER_ADDR_LEN; i++) { dev->dev_addr[i] = SA_prom[i]; printk(" %2.2x", SA_prom[i]); } #endif neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57); ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d); dlink = (SA_prom[0] == 0x00 && SA_prom[1] == 0xDE && SA_prom[2] == 0x01); dfi = (SA_prom[0] == 'D' && SA_prom[1] == 'F' && SA_prom[2] == 'I'); /* Set up the rest of the parameters. */ if (neX000 || dlink || dfi) { if (wordlength == 2) { name = dlink ? "DE200" : "NE2000"; start_page = NESM_START_PG; stop_page = NESM_STOP_PG; } else { name = dlink ? "DE100" : "NE1000"; start_page = NE1SM_START_PG; stop_page = NE1SM_STOP_PG; } } else if (ctron) { name = "Cabletron"; start_page = 0x01; stop_page = (wordlength == 2) ? 0x40 : 0x20; } else { printk(" not found.\n"); return 0; } if (dev->irq < 2) { autoirq_setup(0); outb_p(0x50, ioaddr + EN0_IMR); /* Enable one interrupt. */ outb_p(0x00, ioaddr + EN0_RCNTLO); outb_p(0x00, ioaddr + EN0_RCNTHI); outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */ outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */ dev->irq = autoirq_report(0); if (ei_debug > 2) printk(" autoirq is %d", dev->irq); } else if (dev->irq == 2) /* Fixup for users that don't know that IRQ 2 is really IRQ 9, or don't know which one to set. */ dev->irq = 9; /* Snarf the interrupt now. There's no point in waiting since we cannot share and the board will usually be enabled. */ { int irqval = irqaction (dev->irq, &ei_sigaction); if (irqval) { printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval); return 0; } } dev->base_addr = ioaddr; #ifdef HAVE_PORTRESERVE snarf_region(ioaddr, 32); #endif ethdev_init(dev); printk("\n%s: %s found at %#x, using IRQ %d.\n", dev->name, name, ioaddr, dev->irq); if (ei_debug > 0) printk(version); ei_status.name = name; ei_status.tx_start_page = start_page; ei_status.stop_page = stop_page; ei_status.word16 = (wordlength == 2); ei_status.rx_start_page = start_page + TX_PAGES; #ifdef PACKETBUF_MEMSIZE /* Allow the packet buffer size to be overridden by know-it-alls. */ ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; #endif ei_status.reset_8390 = &ne_reset_8390; ei_status.block_input = &ne_block_input; ei_status.block_output = &ne_block_output; NS8390_init(dev, 0); return dev->base_addr; }
static int __init ultra32_probe1(struct net_device *dev, int ioaddr) { int i, edge, media, retval; int checksum = 0; const char *model_name; static unsigned version_printed; /* Values from various config regs. */ unsigned char idreg; unsigned char reg4; const char *ifmap[] = {"UTP No Link", "", "UTP/AUI", "UTP/BNC"}; if (!request_region(ioaddr, ULTRA32_IO_EXTENT, DRV_NAME)) return -EBUSY; if (inb(ioaddr + ULTRA32_IDPORT) == 0xff || inl(ioaddr + ULTRA32_IDPORT) != ULTRA32_ID) { retval = -ENODEV; goto out; } media = inb(ioaddr + ULTRA32_CFG7) & 0x03; edge = inb(ioaddr + ULTRA32_CFG5) & 0x08; printk("SMC Ultra32 in EISA Slot %d, Media: %s, %s IRQs.\n", ioaddr >> 12, ifmap[media], (edge ? "Edge Triggered" : "Level Sensitive")); idreg = inb(ioaddr + 7); reg4 = inb(ioaddr + 4) & 0x7f; /* Check the ID nibble. */ if ((idreg & 0xf0) != 0x20) { /* SMC Ultra */ retval = -ENODEV; goto out; } /* Select the station address register set. */ outb(reg4, ioaddr + 4); for (i = 0; i < 8; i++) checksum += inb(ioaddr + 8 + i); if ((checksum & 0xff) != 0xff) { retval = -ENODEV; goto out; } if (ei_debug && version_printed++ == 0) printk(version); model_name = "SMC Ultra32"; for (i = 0; i < 6; i++) dev->dev_addr[i] = inb(ioaddr + 8 + i); printk("%s: %s at 0x%X, %pM", dev->name, model_name, ioaddr, dev->dev_addr); /* Switch from the station address to the alternate register set and read the useful registers there. */ outb(0x80 | reg4, ioaddr + 4); /* Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot. */ outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c); /* Reset RAM addr. */ outb(0x00, ioaddr + 0x0b); /* Switch back to the station address register set so that the MS-DOS driver can find the card after a warm boot. */ outb(reg4, ioaddr + 4); if ((inb(ioaddr + ULTRA32_CFG5) & 0x40) == 0) { printk("\nsmc-ultra32: Card RAM is disabled! " "Run EISA config utility.\n"); retval = -ENODEV; goto out; } if ((inb(ioaddr + ULTRA32_CFG2) & 0x04) == 0) printk("\nsmc-ultra32: Ignoring Bus-Master enable bit. " "Run EISA config utility.\n"); if (dev->irq < 2) { unsigned char irqmap[] = {0, 9, 3, 5, 7, 10, 11, 15}; int irq = irqmap[inb(ioaddr + ULTRA32_CFG5) & 0x07]; if (irq == 0) { printk(", failed to detect IRQ line.\n"); retval = -EAGAIN; goto out; } dev->irq = irq; } /* The 8390 isn't at the base address, so fake the offset */ dev->base_addr = ioaddr + ULTRA32_NIC_OFFSET; /* Save RAM address in the unused reg0 to avoid excess inb's. */ ei_status.reg0 = inb(ioaddr + ULTRA32_CFG3) & 0xfc; dev->mem_start = 0xc0000 + ((ei_status.reg0 & 0x7c) << 11); ei_status.name = model_name; ei_status.word16 = 1; ei_status.tx_start_page = 0; ei_status.rx_start_page = TX_PAGES; /* All Ultra32 cards have 32KB memory with an 8KB window. */ ei_status.stop_page = 128; ei_status.mem = ioremap(dev->mem_start, 0x2000); if (!ei_status.mem) { printk(", failed to ioremap.\n"); retval = -ENOMEM; goto out; } dev->mem_end = dev->mem_start + 0x1fff; printk(", IRQ %d, 32KB memory, 8KB window at 0x%lx-0x%lx.\n", dev->irq, dev->mem_start, dev->mem_end); ei_status.block_input = &ultra32_block_input; ei_status.block_output = &ultra32_block_output; ei_status.get_8390_hdr = &ultra32_get_8390_hdr; ei_status.reset_8390 = &ultra32_reset_8390; dev->netdev_ops = &ultra32_netdev_ops; NS8390_init(dev, 0); return 0; out: release_region(ioaddr, ULTRA32_IO_EXTENT); return retval; }
static int __init es_probe1(struct net_device *dev, int ioaddr) { int i, retval; unsigned long eisa_id; if (!request_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT, "es3210")) return -ENODEV; #if ES_DEBUG & ES_D_PROBE printk("es3210.c: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + ES_ID_PORT)); printk("es3210.c: config regs: %#x %#x %#x %#x %#x %#x\n", inb(ioaddr + ES_CFG1), inb(ioaddr + ES_CFG2), inb(ioaddr + ES_CFG3), inb(ioaddr + ES_CFG4), inb(ioaddr + ES_CFG5), inb(ioaddr + ES_CFG6)); #endif /* Check the EISA ID of the card. */ eisa_id = inl(ioaddr + ES_ID_PORT); if ((eisa_id != ES_EISA_ID1) && (eisa_id != ES_EISA_ID2)) { retval = -ENODEV; goto out; } /* Check the Racal vendor ID as well. */ if (inb(ioaddr + ES_SA_PROM + 0) != ES_ADDR0 || inb(ioaddr + ES_SA_PROM + 1) != ES_ADDR1 || inb(ioaddr + ES_SA_PROM + 2) != ES_ADDR2 ) { printk("es3210.c: card not found"); for(i = 0; i < ETHER_ADDR_LEN; i++) printk(" %02x", inb(ioaddr + ES_SA_PROM + i)); printk(" (invalid prefix).\n"); retval = -ENODEV; goto out; } printk("es3210.c: ES3210 rev. %ld at %#x, node", eisa_id>>24, ioaddr); for(i = 0; i < ETHER_ADDR_LEN; i++) printk(" %02x", (dev->dev_addr[i] = inb(ioaddr + ES_SA_PROM + i))); /* Snarf the interrupt now. */ if (dev->irq == 0) { unsigned char hi_irq = inb(ioaddr + ES_CFG2) & 0x07; unsigned char lo_irq = inb(ioaddr + ES_CFG1) & 0xfe; if (hi_irq != 0) { dev->irq = hi_irq_map[hi_irq - 1]; } else { int i = 0; while (lo_irq > (1<<i)) i++; dev->irq = lo_irq_map[i]; } printk(" using IRQ %d", dev->irq); #if ES_DEBUG & ES_D_PROBE printk("es3210.c: hi_irq %#x, lo_irq %#x, dev->irq = %d\n", hi_irq, lo_irq, dev->irq); #endif } else { if (dev->irq == 2) dev->irq = 9; /* Doh! */ printk(" assigning IRQ %d", dev->irq); } if (request_irq(dev->irq, ei_interrupt, 0, "es3210", dev)) { printk (" unable to get IRQ %d.\n", dev->irq); retval = -EAGAIN; goto out; } if (dev->mem_start == 0) { unsigned char mem_enabled = inb(ioaddr + ES_CFG2) & 0xc0; unsigned char mem_bits = inb(ioaddr + ES_CFG3) & 0x07; if (mem_enabled != 0x80) { printk(" shared mem disabled - giving up\n"); retval = -ENXIO; goto out1; } dev->mem_start = 0xC0000 + mem_bits*0x4000; printk(" using "); } else { printk(" assigning "); } dev->mem_end = ei_status.rmem_end = dev->mem_start + (ES_STOP_PG - ES_START_PG)*256; ei_status.rmem_start = dev->mem_start + TX_PAGES*256; printk("mem %#lx-%#lx\n", dev->mem_start, dev->mem_end-1); #if ES_DEBUG & ES_D_PROBE if (inb(ioaddr + ES_CFG5)) printk("es3210: Warning - DMA channel enabled, but not used here.\n"); #endif /* Note, point at the 8390, and not the card... */ dev->base_addr = ioaddr + ES_NIC_OFFSET; ei_status.name = "ES3210"; ei_status.tx_start_page = ES_START_PG; ei_status.rx_start_page = ES_START_PG + TX_PAGES; ei_status.stop_page = ES_STOP_PG; ei_status.word16 = 1; if (ei_debug > 0) printk(version); ei_status.reset_8390 = &es_reset_8390; ei_status.block_input = &es_block_input; ei_status.block_output = &es_block_output; ei_status.get_8390_hdr = &es_get_8390_hdr; dev->open = &es_open; dev->stop = &es_close; #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = ei_poll; #endif NS8390_init(dev, 0); return 0; out1: free_irq(dev->irq, dev); out: release_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT); return retval; }
int __init hydra_init(unsigned long board) { struct net_device *dev; unsigned long ioaddr = board+HYDRA_NIC_BASE; const char *name = NULL; int start_page, stop_page; int j; static u32 hydra_offsets[16] = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, }; dev = init_etherdev(0, 0); if (!dev) return -ENOMEM; for(j = 0; j < ETHER_ADDR_LEN; j++) dev->dev_addr[j] = *((u8 *)(board + HYDRA_ADDRPROM + 2*j)); /* We must set the 8390 for word mode. */ writeb(0x4b, ioaddr + NE_EN0_DCFG); start_page = NESM_START_PG; stop_page = NESM_STOP_PG; dev->base_addr = ioaddr; dev->irq = IRQ_AMIGA_PORTS; /* Install the Interrupt handler */ if (request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, "Hydra Ethernet", dev)) return -EAGAIN; /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk("Unable to get memory for dev->priv.\n"); return -ENOMEM; } name = "NE2000"; printk("%s: hydra at 0x%08lx, address %02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n", dev->name, ZTWO_PADDR(board), dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); ei_status.name = name; ei_status.tx_start_page = start_page; ei_status.stop_page = stop_page; ei_status.word16 = 1; ei_status.bigendian = 1; ei_status.rx_start_page = start_page + TX_PAGES; ei_status.reset_8390 = &hydra_reset_8390; ei_status.block_input = &hydra_block_input; ei_status.block_output = &hydra_block_output; ei_status.get_8390_hdr = &hydra_get_8390_hdr; ei_status.reg_offset = hydra_offsets; dev->open = &hydra_open; dev->stop = &hydra_close; #ifdef MODULE ei_status.priv = (unsigned long)root_hydra_dev; root_hydra_dev = dev; #endif NS8390_init(dev, 0); return 0; }
static int __init ac_probe1(int ioaddr, struct net_device *dev) { int i, retval; if (!request_region(ioaddr, AC_IO_EXTENT, DRV_NAME)) return -EBUSY; if (inb_p(ioaddr + AC_ID_PORT) == 0xff) { retval = -ENODEV; goto out; } if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) { retval = -ENODEV; goto out; } #ifndef final_version printk(KERN_DEBUG "AC3200 ethercard configuration register is %#02x," " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG), inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1), inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3)); #endif for (i = 0; i < 6; i++) dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i); printk(KERN_DEBUG "AC3200 in EISA slot %d, node %pM", ioaddr/0x1000, dev->dev_addr); #if 0 /* Check the vendor ID/prefix. Redundant after checking the EISA ID */ if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0 || inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1 || inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) { printk(", not found (invalid prefix).\n"); retval = -ENODEV; goto out; } #endif /* Assign and allocate the interrupt now. */ if (dev->irq == 0) { dev->irq = config2irq(inb(ioaddr + AC_CONFIG)); printk(", using"); } else { dev->irq = irq_canonicalize(dev->irq); printk(", assigning"); } retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev); if (retval) { printk (" nothing! Unable to get IRQ %d.\n", dev->irq); goto out1; } printk(" IRQ %d, %s port\n", dev->irq, port_name[dev->if_port]); dev->base_addr = ioaddr; #ifdef notyet if (dev->mem_start) { /* Override the value from the board. */ for (i = 0; i < 7; i++) if (addrmap[i] == dev->mem_start) break; if (i >= 7) i = 0; outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG); } #endif dev->if_port = inb(ioaddr + AC_CONFIG) >> 6; dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG)); printk("%s: AC3200 at %#3x with %dkB memory at physical address %#lx.\n", dev->name, ioaddr, AC_STOP_PG/4, dev->mem_start); /* * BEWARE!! Some dain-bramaged EISA SCUs will allow you to put * the card mem within the region covered by `normal' RAM !!! * * ioremap() will fail in that case. */ ei_status.mem = ioremap(dev->mem_start, AC_STOP_PG*0x100); if (!ei_status.mem) { printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n"); printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n"); printk(KERN_ERR "ac3200.c: Driver NOT installed.\n"); retval = -EINVAL; goto out1; } printk("ac3200.c: remapped %dkB card memory to virtual address %p\n", AC_STOP_PG/4, ei_status.mem); dev->mem_start = (unsigned long)ei_status.mem; dev->mem_end = dev->mem_start + (AC_STOP_PG - AC_START_PG)*256; ei_status.name = "AC3200"; ei_status.tx_start_page = AC_START_PG; ei_status.rx_start_page = AC_START_PG + TX_PAGES; ei_status.stop_page = AC_STOP_PG; ei_status.word16 = 1; if (ei_debug > 0) printk(version); ei_status.reset_8390 = &ac_reset_8390; ei_status.block_input = &ac_block_input; ei_status.block_output = &ac_block_output; ei_status.get_8390_hdr = &ac_get_8390_hdr; dev->netdev_ops = &ac_netdev_ops; NS8390_init(dev, 0); retval = register_netdev(dev); if (retval) goto out2; return 0; out2: if (ei_status.reg0) iounmap(ei_status.mem); out1: free_irq(dev->irq, dev); out: release_region(ioaddr, AC_IO_EXTENT); return retval; }
static void dma_block_output(struct net_device *dev, int count, const u_char *buf, const int start_page) { unsigned int nic_base = dev->base_addr; pcnet_dev_t *info = PRIV(dev); #ifdef PCMCIA_DEBUG int retries = 0; #endif u_long dma_start; #ifdef PCMCIA_DEBUG if (ei_debug > 4) netdev_dbg(dev, "[bo=%d]\n", count); #endif /* Round the count up for word writes. Do we need to do this? What effect will an odd byte count have on the 8390? I should check someday. */ if (count & 0x01) count++; if (ei_status.dmaing) { netdev_notice(dev, "DMAing conflict in dma_block_output." "[DMAstat:%1x][irqlock:%1x]\n", ei_status.dmaing, ei_status.irqlock); return; } ei_status.dmaing |= 0x01; /* We should already be in page 0, but to be safe... */ outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base+PCNET_CMD); #ifdef PCMCIA_DEBUG retry: #endif outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Now the normal output. */ outb_p(count & 0xff, nic_base + EN0_RCNTLO); outb_p(count >> 8, nic_base + EN0_RCNTHI); outb_p(0x00, nic_base + EN0_RSARLO); outb_p(start_page, nic_base + EN0_RSARHI); outb_p(E8390_RWRITE+E8390_START, nic_base + PCNET_CMD); outsw(nic_base + PCNET_DATAPORT, buf, count>>1); dma_start = jiffies; #ifdef PCMCIA_DEBUG /* This was for the ALPHA version only, but enough people have been encountering problems that it is still here. */ if (ei_debug > 4) { /* DMA termination address check... */ int addr, tries = 20; do { int high = inb_p(nic_base + EN0_RSARHI); int low = inb_p(nic_base + EN0_RSARLO); addr = (high << 8) + low; if ((start_page << 8) + count == addr) break; } while (--tries > 0); if (tries <= 0) { netdev_notice(dev, "Tx packet transfer address mismatch," "%#4.4x (expected) vs. %#4.4x (actual).\n", (start_page << 8) + count, addr); if (retries++ == 0) goto retry; } } #endif while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) if (time_after(jiffies, dma_start + PCNET_RDC_TIMEOUT)) { netdev_notice(dev, "timeout waiting for Tx RDC.\n"); pcnet_reset_8390(dev); NS8390_init(dev, 1); break; } outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ if (info->flags & DELAY_OUTPUT) udelay((long)delay_time); ei_status.dmaing &= ~0x01; }
static void ei_watchdog(u_long arg) { struct net_device *dev = (struct net_device *)arg; pcnet_dev_t *info = PRIV(dev); unsigned int nic_base = dev->base_addr; unsigned int mii_addr = nic_base + DLINK_GPIO; u_short link; if (!netif_device_present(dev)) goto reschedule; /* Check for pending interrupt with expired latency timer: with this, we can limp along even if the interrupt is blocked */ if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) { if (!info->fast_poll) netdev_info(dev, "interrupt(s) dropped!\n"); ei_irq_wrapper(dev->irq, dev); info->fast_poll = HZ; } if (info->fast_poll) { info->fast_poll--; info->watchdog.expires = jiffies + 1; add_timer(&info->watchdog); return; } if (!(info->flags & HAS_MII)) goto reschedule; mdio_read(mii_addr, info->phy_id, 1); link = mdio_read(mii_addr, info->phy_id, 1); if (!link || (link == 0xffff)) { if (info->eth_phy) { info->phy_id = info->eth_phy = 0; } else { netdev_info(dev, "MII is missing!\n"); info->flags &= ~HAS_MII; } goto reschedule; } link &= 0x0004; if (link != info->link_status) { u_short p = mdio_read(mii_addr, info->phy_id, 5); netdev_info(dev, "%s link beat\n", link ? "found" : "lost"); if (link && (info->flags & IS_DL10022)) { /* Disable collision detection on full duplex links */ outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG); } else if (link && (info->flags & IS_DL10019)) { /* Disable collision detection on full duplex links */ write_asic(dev->base_addr, 4, (p & 0x140) ? DL19FDUPLX : 0); } if (link) { if (info->phy_id == info->eth_phy) { if (p) netdev_info(dev, "autonegotiation complete: " "%sbaseT-%cD selected\n", ((p & 0x0180) ? "100" : "10"), ((p & 0x0140) ? 'F' : 'H')); else netdev_info(dev, "link partner did not autonegotiate\n"); } NS8390_init(dev, 1); } info->link_status = link; } if (info->pna_phy && time_after(jiffies, info->mii_reset + 6*HZ)) { link = mdio_read(mii_addr, info->eth_phy, 1) & 0x0004; if (((info->phy_id == info->pna_phy) && link) || ((info->phy_id != info->pna_phy) && !link)) { /* isolate this MII and try flipping to the other one */ mdio_write(mii_addr, info->phy_id, 0, 0x0400); info->phy_id ^= info->pna_phy ^ info->eth_phy; netdev_info(dev, "switched to %s transceiver\n", (info->phy_id == info->eth_phy) ? "ethernet" : "PNA"); mdio_write(mii_addr, info->phy_id, 0, (info->phy_id == info->eth_phy) ? 0x1000 : 0); info->link_status = 0; info->mii_reset = jiffies; } } reschedule: info->watchdog.expires = jiffies + HZ; add_timer(&info->watchdog); }
/* Do the interesting part of the probe at a single address. */ static int __init hpp_probe1(struct net_device *dev, int ioaddr) { int i, retval; unsigned char checksum = 0; const char name[] = "HP-PC-LAN+"; int mem_start; static unsigned version_printed; if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME)) return -EBUSY; /* Check for the HP+ signature, 50 48 0x 53. */ if (inw(ioaddr + HP_ID) != 0x4850 || (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300) { retval = -ENODEV; goto out; } if (ei_debug && version_printed++ == 0) printk(version); printk("%s: %s at %#3x,", dev->name, name, ioaddr); /* Retrieve and checksum the station address. */ outw(MAC_Page, ioaddr + HP_PAGING); for(i = 0; i < ETHER_ADDR_LEN; i++) { unsigned char inval = inb(ioaddr + 8 + i); dev->dev_addr[i] = inval; checksum += inval; printk(" %2.2x", inval); } checksum += inb(ioaddr + 14); if (checksum != 0xff) { printk(" bad checksum %2.2x.\n", checksum); retval = -ENODEV; goto out; } else { /* Point at the Software Configuration Flags. */ outw(ID_Page, ioaddr + HP_PAGING); printk(" ID %4.4x", inw(ioaddr + 12)); } /* Read the IRQ line. */ outw(HW_Page, ioaddr + HP_PAGING); { int irq = inb(ioaddr + 13) & 0x0f; int option = inw(ioaddr + HPP_OPTION); dev->irq = irq; if (option & MemEnable) { mem_start = inw(ioaddr + 9) << 8; printk(", IRQ %d, memory address %#x.\n", irq, mem_start); } else { mem_start = 0; printk(", IRQ %d, programmed-I/O mode.\n", irq); } } /* Set the wrap registers for string I/O reads. */ outw((HP_START_PG + TX_PAGES/2) | ((HP_STOP_PG - 1) << 8), ioaddr + 14); /* Set the base address to point to the NIC, not the "real" base! */ dev->base_addr = ioaddr + NIC_OFFSET; dev->open = &hpp_open; dev->stop = &hpp_close; #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = ei_poll; #endif ei_status.name = name; ei_status.word16 = 0; /* Agggghhhhh! Debug time: 2 days! */ ei_status.tx_start_page = HP_START_PG; ei_status.rx_start_page = HP_START_PG + TX_PAGES/2; ei_status.stop_page = HP_STOP_PG; ei_status.reset_8390 = &hpp_reset_8390; ei_status.block_input = &hpp_io_block_input; ei_status.block_output = &hpp_io_block_output; ei_status.get_8390_hdr = &hpp_io_get_8390_hdr; /* Check if the memory_enable flag is set in the option register. */ if (mem_start) { ei_status.block_input = &hpp_mem_block_input; ei_status.block_output = &hpp_mem_block_output; ei_status.get_8390_hdr = &hpp_mem_get_8390_hdr; dev->mem_start = mem_start; ei_status.mem = ioremap(mem_start, (HP_STOP_PG - HP_START_PG)*256); if (!ei_status.mem) { retval = -ENOMEM; goto out; } ei_status.rmem_start = dev->mem_start + TX_PAGES/2*256; dev->mem_end = ei_status.rmem_end = dev->mem_start + (HP_STOP_PG - HP_START_PG)*256; } outw(Perf_Page, ioaddr + HP_PAGING); NS8390_init(dev, 0); /* Leave the 8390 and HP chip reset. */ outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION); retval = register_netdev(dev); if (retval) goto out1; return 0; out1: iounmap(ei_status.mem); out: release_region(ioaddr, HP_IO_EXTENT); return retval; }
/* Do the interesting part of the probe at a single address. */ int hpp_probe1(struct device *dev, int ioaddr) { int i; unsigned char checksum = 0; char *name = "HP-PC-LAN+"; int mem_start; /* Check for the HP+ signature, 50 48 0x 53. */ if (inw(ioaddr + HP_ID) != 0x4850 || (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300) return ENODEV; if (dev == NULL) dev = init_etherdev(0, sizeof(struct ei_device), 0); printk("%s: %s at %#3x,", dev->name, name, ioaddr); /* Retrieve and checksum the station address. */ outw(MAC_Page, ioaddr + HP_PAGING); for(i = 0; i < ETHER_ADDR_LEN; i++) { unsigned char inval = inb(ioaddr + 8 + i); dev->dev_addr[i] = inval; checksum += inval; printk(" %2.2x", inval); } checksum += inb(ioaddr + 14); if (checksum != 0xff) { printk(" bad checksum %2.2x.\n", checksum); return ENODEV; } else { /* Point at the Software Configuration Flags. */ outw(ID_Page, ioaddr + HP_PAGING); printk(" ID %4.4x", inw(ioaddr + 12)); } /* Grab the region so we can find another board if something fails. */ request_region(ioaddr, HP_IO_EXTENT,"hp-plus"); /* Read the IRQ line. */ outw(HW_Page, ioaddr + HP_PAGING); { int irq = inb(ioaddr + 13) & 0x0f; int option = inw(ioaddr + HPP_OPTION); dev->irq = irq; if (option & MemEnable) { mem_start = inw(ioaddr + 9) << 8; printk(", IRQ %d, memory address %#x.\n", irq, mem_start); } else { mem_start = 0; printk(", IRQ %d, programmed-I/O mode.\n", irq); } } printk( "%s%s", KERN_INFO, version); /* Set the wrap registers for string I/O reads. */ outw((HP_START_PG + TX_2X_PAGES) | ((HP_STOP_PG - 1) << 8), ioaddr + 14); /* Set the base address to point to the NIC, not the "real" base! */ dev->base_addr = ioaddr + NIC_OFFSET; ethdev_init(dev); dev->open = &hpp_open; dev->stop = &hpp_close; ei_status.name = name; ei_status.word16 = 0; /* Agggghhhhh! Debug time: 2 days! */ ei_status.tx_start_page = HP_START_PG; ei_status.rx_start_page = HP_START_PG + TX_2X_PAGES; ei_status.stop_page = HP_STOP_PG; ei_status.reset_8390 = &hpp_reset_8390; ei_status.block_input = &hpp_io_block_input; ei_status.block_output = &hpp_io_block_output; /* Check if the memory_enable flag is set in the option register. */ if (mem_start) { ei_status.block_input = &hpp_mem_block_input; ei_status.block_output = &hpp_mem_block_output; dev->mem_start = mem_start; dev->rmem_start = dev->mem_start + TX_2X_PAGES*256; dev->mem_end = dev->rmem_end = dev->mem_start + (HP_STOP_PG - HP_START_PG)*256; } outw(Perf_Page, ioaddr + HP_PAGING); NS8390_init(dev, 0); /* Leave the 8390 and HP chip reset. */ outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION); return 0; }
static int __init e21_probe1(struct net_device *dev, int ioaddr) { int i, status, retval; unsigned char *station_addr = dev->dev_addr; static unsigned version_printed; if (!request_region(ioaddr, E21_IO_EXTENT, DRV_NAME)) return -EBUSY; /* First check the station address for the Ctron prefix. */ if (inb(ioaddr + E21_SAPROM + 0) != 0x00 || inb(ioaddr + E21_SAPROM + 1) != 0x00 || inb(ioaddr + E21_SAPROM + 2) != 0x1d) { retval = -ENODEV; goto out; } /* Verify by making certain that there is a 8390 at there. */ outb(E8390_NODMA + E8390_STOP, ioaddr); udelay(1); /* we want to delay one I/O cycle - which is 2MHz */ status = inb(ioaddr); if (status != 0x21 && status != 0x23) { retval = -ENODEV; goto out; } /* Read the station address PROM. */ for (i = 0; i < 6; i++) station_addr[i] = inb(ioaddr + E21_SAPROM + i); inb(ioaddr + E21_MEDIA); /* Point to media selection. */ outb(0, ioaddr + E21_ASIC); /* and disable the secondary interface. */ if (ei_debug && version_printed++ == 0) printk(version); for (i = 0; i < 6; i++) printk(" %02X", station_addr[i]); if (dev->irq < 2) { int irqlist[] = {15, 11, 10, 12, 5, 9, 3, 4}; for (i = 0; i < ARRAY_SIZE(irqlist); i++) if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) { dev->irq = irqlist[i]; break; } if (i >= ARRAY_SIZE(irqlist)) { printk(" unable to get IRQ %d.\n", dev->irq); retval = -EAGAIN; goto out; } } else if (dev->irq == 2) /* Fixup luser bogosity: IRQ2 is really IRQ9 */ dev->irq = 9; /* The 8390 is at the base address. */ dev->base_addr = ioaddr; ei_status.name = "E2100"; ei_status.word16 = 1; ei_status.tx_start_page = E21_TX_START_PG; ei_status.rx_start_page = E21_RX_START_PG; ei_status.stop_page = E21_RX_STOP_PG; ei_status.saved_irq = dev->irq; /* Check the media port used. The port can be passed in on the low mem_end bits. */ if (dev->mem_end & 15) dev->if_port = dev->mem_end & 7; else { dev->if_port = 0; inb(ioaddr + E21_MEDIA); /* Turn automatic media detection on. */ for(i = 0; i < 6; i++) if (station_addr[i] != inb(ioaddr + E21_SAPROM + 8 + i)) { dev->if_port = 1; break; } } /* Never map in the E21 shared memory unless you are actively using it. Also, the shared memory has effective only one setting -- spread all over the 128K region! */ if (dev->mem_start == 0) dev->mem_start = 0xd0000; ei_status.mem = ioremap(dev->mem_start, 2*1024); if (!ei_status.mem) { printk("unable to remap memory\n"); retval = -EAGAIN; goto out; } #ifdef notdef /* These values are unused. The E2100 has a 2K window into the packet buffer. The window can be set to start on any page boundary. */ ei_status.rmem_start = dev->mem_start + TX_PAGES*256; dev->mem_end = ei_status.rmem_end = dev->mem_start + 2*1024; #endif printk(", IRQ %d, %s media, memory @ %#lx.\n", dev->irq, dev->if_port ? "secondary" : "primary", dev->mem_start); ei_status.reset_8390 = &e21_reset_8390; ei_status.block_input = &e21_block_input; ei_status.block_output = &e21_block_output; ei_status.get_8390_hdr = &e21_get_8390_hdr; dev->netdev_ops = &e21_netdev_ops; NS8390_init(dev, 0); retval = register_netdev(dev); if (retval) goto out; return 0; out: release_region(ioaddr, E21_IO_EXTENT); return retval; }
int __init ultramca_probe(struct device *gen_dev) { unsigned short ioaddr; struct net_device *dev; unsigned char reg4, num_pages; struct mca_device *mca_dev = to_mca_device(gen_dev); char slot = mca_dev->slot; unsigned char pos2 = 0xff, pos3 = 0xff, pos4 = 0xff, pos5 = 0xff; int i, rc; int adapter = mca_dev->index; int tbase = 0; int tirq = 0; int base_addr = ultra_io[ultra_found]; int irq = ultra_irq[ultra_found]; if (base_addr || irq) { printk(KERN_INFO "Probing for SMC MCA adapter"); if (base_addr) { printk(KERN_INFO " at I/O address 0x%04x%c", base_addr, irq ? ' ' : '\n'); } if (irq) { printk(KERN_INFO "using irq %d\n", irq); } } tirq = 0; tbase = 0; /* If we're trying to match a specificied irq or io address, * we'll reject the adapter found unless it's the one we're * looking for */ pos2 = mca_device_read_stored_pos(mca_dev, 2); /* io_addr */ pos3 = mca_device_read_stored_pos(mca_dev, 3); /* shared mem */ pos4 = mca_device_read_stored_pos(mca_dev, 4); /* ROM bios addr range */ pos5 = mca_device_read_stored_pos(mca_dev, 5); /* irq, media and RIPL */ /* Test the following conditions: * - If an irq parameter is supplied, compare it * with the irq of the adapter we found * - If a base_addr paramater is given, compare it * with the base_addr of the adapter we found * - Check that the irq and the base_addr of the * adapter we found is not already in use by * this driver */ switch (mca_dev->index) { case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A: case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A: case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A: case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A: { tbase = addr_table[(pos2 & 0xf0) >> 4].base_addr; tirq = irq_table[(pos5 & 0xc) >> 2].new_irq; break; } case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A: case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A: case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A: case _efe5_IBM_PS2_Adapter_A_for_Ethernet: { tbase = ((pos2 & 0x0fe) * 0x10); tirq = irq_table[(pos5 & 3)].old_irq; break; } } if(!tirq || !tbase || (irq && irq != tirq) || (base_addr && tbase != base_addr)) /* FIXME: we're trying to force the ordering of the * devices here, there should be a way of getting this * to happen */ return -ENXIO; /* Adapter found. */ dev = alloc_ei_netdev(); if(!dev) return -ENODEV; SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, gen_dev); mca_device_set_name(mca_dev, smc_mca_adapter_names[adapter]); mca_device_set_claim(mca_dev, 1); printk(KERN_INFO "smc_mca: %s found in slot %d\n", smc_mca_adapter_names[adapter], slot + 1); ultra_found++; dev->base_addr = ioaddr = mca_device_transform_ioport(mca_dev, tbase); dev->irq = mca_device_transform_irq(mca_dev, tirq); dev->mem_start = 0; num_pages = 40; switch (adapter) { /* card-# in const array above [hs] */ case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A: case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A: { for (i = 0; i < 16; i++) { /* taking 16 counts * up to 15 [hs] */ if (mem_table[i].mem_index == (pos3 & ~MEM_MASK)) { dev->mem_start = (unsigned long) mca_device_transform_memory(mca_dev, (void *)mem_table[i].mem_start); num_pages = mem_table[i].num_pages; } } break; } case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A: case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A: case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A: case _efe5_IBM_PS2_Adapter_A_for_Ethernet: { dev->mem_start = (unsigned long) mca_device_transform_memory(mca_dev, (void *)((pos3 & 0xfc) * 0x1000)); num_pages = 0x40; break; } case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A: case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A: { /* courtesy of [email protected], pos3 indicates * the index of the 0x2000 step. * beware different number of pages [hs] */ dev->mem_start = (unsigned long) mca_device_transform_memory(mca_dev, (void *)(0xc0000 + (0x2000 * (pos3 & 0xf)))); num_pages = 0x20 + (2 * (pos3 & 0x10)); break; } } /* sanity check, shouldn't happen */ if (dev->mem_start == 0) { rc = -ENODEV; goto err_unclaim; } if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) { rc = -ENODEV; goto err_unclaim; } reg4 = inb(ioaddr + 4) & 0x7f; outb(reg4, ioaddr + 4); printk(KERN_INFO "smc_mca[%d]: Parameters: %#3x,", slot + 1, ioaddr); for (i = 0; i < 6; i++) printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i)); /* Switch from the station address to the alternate register set * and read the useful registers there. */ outb(0x80 | reg4, ioaddr + 4); /* Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot. */ outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c); /* Switch back to the station address register set so that * the MS-DOS driver can find the card after a warm boot. */ outb(reg4, ioaddr + 4); gen_dev->driver_data = dev; /* The 8390 isn't at the base address, so fake the offset */ dev->base_addr = ioaddr + ULTRA_NIC_OFFSET; ei_status.name = "SMC Ultra MCA"; ei_status.word16 = 1; ei_status.tx_start_page = START_PG; ei_status.rx_start_page = START_PG + TX_PAGES; ei_status.stop_page = num_pages; ei_status.rmem_start = dev->mem_start + TX_PAGES * 256; dev->mem_end = ei_status.rmem_end = dev->mem_start + (ei_status.stop_page - START_PG) * 256; printk(", IRQ %d memory %#lx-%#lx.\n", dev->irq, dev->mem_start, dev->mem_end - 1); ei_status.reset_8390 = &ultramca_reset_8390; ei_status.block_input = &ultramca_block_input; ei_status.block_output = &ultramca_block_output; ei_status.get_8390_hdr = &ultramca_get_8390_hdr; ei_status.priv = slot; dev->open = &ultramca_open; dev->stop = &ultramca_close_card; #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = ei_poll; #endif NS8390_init(dev, 0); rc = register_netdev(dev); if (rc) goto err_release_region; return 0; err_release_region: release_region(ioaddr, ULTRA_IO_EXTENT); err_unclaim: mca_device_set_claim(mca_dev, 0); free_netdev(dev); return rc; }
int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev, enum mac8390_type type) { static u32 fwrd4_offsets[16]={ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60 }; static u32 back4_offsets[16]={ 60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4, 0 }; static u32 fwrd2_offsets[16]={ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 }; int access_bitmode; /* 8390 specific init for dev - allocates dev->priv */ if (ethdev_init(dev)) { printk(KERN_ERR "%s: Unable to allocate memory for dev->priv!\n", dev->name); return -ENOMEM; } /* Now fill in our stuff */ dev->open = &mac8390_open; dev->stop = &mac8390_close; /* GAR, ei_status is actually a macro even though it looks global */ ei_status.name = cardname[type]; ei_status.word16 = word16[type]; /* Cabletron's TX/RX buffers are backwards */ if (type == MAC8390_CABLETRON) { ei_status.tx_start_page = CABLETRON_TX_START_PG; ei_status.rx_start_page = CABLETRON_RX_START_PG; ei_status.stop_page = CABLETRON_RX_STOP_PG; ei_status.rmem_start = dev->mem_start; ei_status.rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256; } else { ei_status.tx_start_page = WD_START_PG; ei_status.rx_start_page = WD_START_PG + TX_PAGES; ei_status.stop_page = (dev->mem_end - dev->mem_start)/256; ei_status.rmem_start = dev->mem_start + TX_PAGES*256; ei_status.rmem_end = dev->mem_end; } /* Fill in model-specific information and functions */ switch(type) { case MAC8390_SONICSYS: /* 16 bit card, register map is reversed */ ei_status.reset_8390 = &mac8390_no_reset; ei_status.block_input = &slow_sane_block_input; ei_status.block_output = &slow_sane_block_output; ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; ei_status.reg_offset = back4_offsets; access_bitmode = 0; break; case MAC8390_FARALLON: case MAC8390_APPLE: case MAC8390_ASANTE: case MAC8390_DAYNA2: case MAC8390_DAYNA3: /* 32 bit card, register map is reversed */ /* sane */ ei_status.reset_8390 = &mac8390_no_reset; ei_status.block_input = &sane_block_input; ei_status.block_output = &sane_block_output; ei_status.get_8390_hdr = &sane_get_8390_hdr; ei_status.reg_offset = back4_offsets; access_bitmode = 1; break; case MAC8390_CABLETRON: /* 16 bit card, register map is short forward */ ei_status.reset_8390 = &mac8390_no_reset; ei_status.block_input = &slow_sane_block_input; ei_status.block_output = &slow_sane_block_output; ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; ei_status.reg_offset = fwrd2_offsets; access_bitmode = 0; break; case MAC8390_DAYNA: case MAC8390_KINETICS: /* 16 bit memory */ /* dayna and similar */ ei_status.reset_8390 = &mac8390_no_reset; ei_status.block_input = &dayna_block_input; ei_status.block_output = &dayna_block_output; ei_status.get_8390_hdr = &dayna_get_8390_hdr; ei_status.reg_offset = fwrd4_offsets; access_bitmode = 0; break; default: printk(KERN_ERR "Card type %s is unsupported, sorry\n", cardname[type]); return -ENODEV; } NS8390_init(dev, 0); /* Good, done, now spit out some messages */ printk(KERN_INFO "%s: %s in slot %X (type %s)\n", dev->name, ndev->board->name, ndev->board->slot, cardname[type]); printk(KERN_INFO "MAC "); { int i; for (i = 0; i < 6; i++) { printk("%2.2x", dev->dev_addr[i]); if (i < 5) printk(":"); } } printk(" IRQ %d, shared memory at %#lx-%#lx, %d-bit access.\n", dev->irq, dev->mem_start, dev->mem_end-1, access_bitmode?32:16); return 0; }
static int __devinit hydra_init(struct zorro_dev *z) { struct net_device *dev; unsigned long board = ZTWO_VADDR(z->resource.start); unsigned long ioaddr = board+HYDRA_NIC_BASE; const char name[] = "NE2000"; int start_page, stop_page; int j; int err; static u32 hydra_offsets[16] = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, }; dev = alloc_ei_netdev(); if (!dev) return -ENOMEM; SET_MODULE_OWNER(dev); for(j = 0; j < ETHER_ADDR_LEN; j++) dev->dev_addr[j] = *((u8 *)(board + HYDRA_ADDRPROM + 2*j)); /* We must set the 8390 for word mode. */ z_writeb(0x4b, ioaddr + NE_EN0_DCFG); start_page = NESM_START_PG; stop_page = NESM_STOP_PG; dev->base_addr = ioaddr; dev->irq = IRQ_AMIGA_PORTS; /* Install the Interrupt handler */ if (request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, "Hydra Ethernet", dev)) { free_netdev(dev); return -EAGAIN; } ei_status.name = name; ei_status.tx_start_page = start_page; ei_status.stop_page = stop_page; ei_status.word16 = 1; ei_status.bigendian = 1; ei_status.rx_start_page = start_page + TX_PAGES; ei_status.reset_8390 = &hydra_reset_8390; ei_status.block_input = &hydra_block_input; ei_status.block_output = &hydra_block_output; ei_status.get_8390_hdr = &hydra_get_8390_hdr; ei_status.reg_offset = hydra_offsets; dev->open = &hydra_open; dev->stop = &hydra_close; #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = ei_poll; #endif NS8390_init(dev, 0); err = register_netdev(dev); if (err) { free_irq(IRQ_AMIGA_PORTS, dev); free_netdev(dev); return err; } zorro_set_drvdata(z, dev); printk(KERN_INFO "%s: Hydra at 0x%08lx, address " "%02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n", dev->name, z->resource.start, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); return 0; }