static void ultramca_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG) << 8); #ifdef notdef /* Officially this is what we are doing, but the readl() is faster */ isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); #else ((unsigned int*)hdr)[0] = isa_readl(hdr_start); #endif }
/* Probe for the Etherlink II card at I/O port base IOADDR, returning non-zero on success. If found, set the station address and memory parameters in DEVICE. */ static int __init el2_probe1(struct net_device *dev, int ioaddr) { int i, iobase_reg, membase_reg, saved_406, wordlength, retval; static unsigned version_printed; unsigned long vendor_id; /* FIXME: code reads ioaddr + 0x400, we request ioaddr + 16 */ if (!request_region(ioaddr, EL2_IO_EXTENT, dev->name)) return -EBUSY; /* Reset and/or avoid any lurking NE2000 */ if (inb(ioaddr + 0x408) == 0xff) { mdelay(1); retval = -ENODEV; goto out; } /* We verify that it's a 3C503 board by checking the first three octets of its ethernet address. */ iobase_reg = inb(ioaddr+0x403); membase_reg = inb(ioaddr+0x404); /* ASIC location registers should be 0 or have only a single bit set. */ if ( (iobase_reg & (iobase_reg - 1)) || (membase_reg & (membase_reg - 1))) { retval = -ENODEV; goto out; } saved_406 = inb_p(ioaddr + 0x406); outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406); /* Reset it... */ outb_p(ECNTRL_THIN, ioaddr + 0x406); /* Map the station addr PROM into the lower I/O ports. We now check for both the old and new 3Com prefix */ outb(ECNTRL_SAPROM|ECNTRL_THIN, ioaddr + 0x406); vendor_id = inb(ioaddr)*0x10000 + inb(ioaddr + 1)*0x100 + inb(ioaddr + 2); if ((vendor_id != OLD_3COM_ID) && (vendor_id != NEW_3COM_ID)) { /* Restore the register we frobbed. */ outb(saved_406, ioaddr + 0x406); retval = -ENODEV; goto out; } if (ei_debug && version_printed++ == 0) printk(version); dev->base_addr = ioaddr; /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk ("3c503: unable to allocate memory for dev->priv.\n"); retval = -ENOMEM; goto out; } printk("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr); /* Retrieve and print the ethernet address. */ for (i = 0; i < 6; i++) printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i)); /* Map the 8390 back into the window. */ outb(ECNTRL_THIN, ioaddr + 0x406); /* Check for EL2/16 as described in tech. man. */ outb_p(E8390_PAGE0, ioaddr + E8390_CMD); outb_p(0, ioaddr + EN0_DCFG); outb_p(E8390_PAGE2, ioaddr + E8390_CMD); wordlength = inb_p(ioaddr + EN0_DCFG) & ENDCFG_WTS; outb_p(E8390_PAGE0, ioaddr + E8390_CMD); /* Probe for, turn on and clear the board's shared memory. */ if (ei_debug > 2) printk(" memory jumpers %2.2x ", membase_reg); outb(EGACFR_NORM, ioaddr + 0x405); /* Enable RAM */ /* This should be probed for (or set via an ioctl()) at run-time. Right now we use a sleazy hack to pass in the interface number at boot-time via the low bits of the mem_end field. That value is unused, and the low bits would be discarded even if it was used. */ #if defined(EI8390_THICK) || defined(EL2_AUI) ei_status.interface_num = 1; #else ei_status.interface_num = dev->mem_end & 0xf; #endif printk(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex"); if ((membase_reg & 0xf0) == 0) { dev->mem_start = 0; ei_status.name = "3c503-PIO"; } else { dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) + ((membase_reg & 0xA0) ? 0x4000 : 0); #define EL2_MEMSIZE (EL2_MB1_STOP_PG - EL2_MB1_START_PG)*256 #ifdef EL2MEMTEST /* This has never found an error, but someone might care. Note that it only tests the 2nd 8kB on 16kB 3c503/16 cards between card addr. 0x2000 and 0x3fff. */ { /* Check the card's memory. */ unsigned long mem_base = dev->mem_start; unsigned int test_val = 0xbbadf00d; isa_writel(0xba5eba5e, mem_base); for (i = sizeof(test_val); i < EL2_MEMSIZE; i+=sizeof(test_val)) { isa_writel(test_val, mem_base + i); if (isa_readl(mem_base) != 0xba5eba5e || isa_readl(mem_base + i) != test_val) { printk("3c503: memory failure or memory address conflict.\n"); dev->mem_start = 0; ei_status.name = "3c503-PIO"; break; } test_val += 0x55555555; isa_writel(0, mem_base + i); } } #endif /* EL2MEMTEST */ if (dev->mem_start) dev->mem_end = dev->rmem_end = dev->mem_start + EL2_MEMSIZE; if (wordlength) { /* No Tx pages to skip over to get to Rx */ dev->rmem_start = dev->mem_start; ei_status.name = "3c503/16"; } else { dev->rmem_start = TX_PAGES*256 + dev->mem_start; ei_status.name = "3c503"; } } /* Divide up the memory on the card. This is the same regardless of whether shared-mem or PIO is used. For 16 bit cards (16kB RAM), we use the entire 8k of bank1 for an Rx ring. We only use 3k of the bank0 for 2 full size Tx packet slots. For 8 bit cards, (8kB RAM) we use 3kB of bank1 for two Tx slots, and the remaining 5kB for an Rx ring. */ if (wordlength) { ei_status.tx_start_page = EL2_MB0_START_PG; ei_status.rx_start_page = EL2_MB1_START_PG; } else { ei_status.tx_start_page = EL2_MB1_START_PG; ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES; } /* Finish setting the board's parameters. */ ei_status.stop_page = EL2_MB1_STOP_PG; ei_status.word16 = wordlength; ei_status.reset_8390 = &el2_reset_8390; ei_status.get_8390_hdr = &el2_get_8390_hdr; ei_status.block_input = &el2_block_input; ei_status.block_output = &el2_block_output; if (dev->irq == 2) dev->irq = 9; else if (dev->irq > 5 && dev->irq != 9) { printk("3c503: configured interrupt %d invalid, will use autoIRQ.\n", dev->irq); dev->irq = 0; } ei_status.saved_irq = dev->irq; dev->open = &el2_open; dev->stop = &el2_close; if (dev->mem_start) printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n", dev->name, ei_status.name, (wordlength+1)<<3, dev->mem_start, dev->mem_end-1); else { ei_status.tx_start_page = EL2_MB1_START_PG; ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES; printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n", dev->name, ei_status.name, (wordlength+1)<<3); } return 0; out: release_region(ioaddr, EL2_IO_EXTENT); return retval; }