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 __init ne3210_probe1(struct net_device *dev, int ioaddr) { int i, retval; unsigned long eisa_id; const char *ifmap[] = {"UTP", "?", "BNC", "AUI"}; if (!request_region(dev->base_addr, NE3210_IO_EXTENT, dev->name)) return -EBUSY; if (inb_p(ioaddr + NE3210_ID_PORT) == 0xff) { retval = -ENODEV; goto out; } #if NE3210_DEBUG & NE3210_D_PROBE printk("ne3210-debug: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + NE3210_ID_PORT)); printk("ne3210-debug: config regs: %#x %#x\n", inb(ioaddr + NE3210_CFG1), inb(ioaddr + NE3210_CFG2)); #endif /* Check the EISA ID of the card. */ eisa_id = inl(ioaddr + NE3210_ID_PORT); if (eisa_id != NE3210_ID) { retval = -ENODEV; goto out; } #if 0 /* Check the vendor ID as well. Not really required. */ if (inb(ioaddr + NE3210_SA_PROM + 0) != NE3210_ADDR0 || inb(ioaddr + NE3210_SA_PROM + 1) != NE3210_ADDR1 || inb(ioaddr + NE3210_SA_PROM + 2) != NE3210_ADDR2 ) { printk("ne3210.c: card not found"); for(i = 0; i < ETHER_ADDR_LEN; i++) printk(" %02x", inb(ioaddr + NE3210_SA_PROM + i)); printk(" (invalid prefix).\n"); retval = -ENODEV; goto out; } #endif /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk ("ne3210.c: unable to allocate memory for dev->priv!\n"); retval = -ENOMEM; goto out; } printk("ne3210.c: NE3210 in EISA slot %d, media: %s, addr:", ioaddr/0x1000, ifmap[inb(ioaddr + NE3210_CFG2) >> 6]); for(i = 0; i < ETHER_ADDR_LEN; i++) printk(" %02x", (dev->dev_addr[i] = inb(ioaddr + NE3210_SA_PROM + i))); printk(".\nne3210.c: "); /* Snarf the interrupt now. CFG file has them all listed as `edge' with share=NO */ if (dev->irq == 0) { unsigned char irq_reg = inb(ioaddr + NE3210_CFG2) >> 3; dev->irq = irq_map[irq_reg & 0x07]; printk("using"); } else {
/* 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; }
int main(int argc, char **argv) { char dev_if[16]; int opt; int err = 0; int daemonize = 0; int log_level = LOG_WARN; char *log_file = NULL; memset(dev_if, '\0', sizeof(dev_if)); strncpy(dev_if, PHOST_DEFAULT_TAP_DEVICE, sizeof(dev_if) - 1); phost_set_program_name(basename(argv[0])); /* parse options */ while(1){ opt = getopt(argc, argv, "Dd:i:p:l:n:v"); if(opt < 0){ break; } switch(opt){ case 'D': daemonize = 1; break; case 'd': if(optarg){ if(atoi(optarg) < LOG_LEVEL_MAX){ log_level = atoi(optarg); } else{ phost_print_usage(); exit(1); } } else{ err |= 1; } break; case 'i': if(optarg){ memset(dev_if, '\0', sizeof(dev_if)); strncpy(dev_if, optarg, sizeof(dev_if) - 1); } else{ err |= 1; } break; case 'p': if(optarg){ memset(pid_dir, '\0', sizeof(pid_dir)); strncpy(pid_dir, optarg, sizeof(pid_dir) - 1); } else{ err |= 1; } break; case 'l': if(optarg){ memset(log_dir, '\0', sizeof(log_dir)); strncpy(log_dir, optarg, sizeof(log_dir) - 1); } else{ err |= 1; } break; case 'n': if(optarg){ memset(host_name, '\0', sizeof(host_name)); strncpy(host_name, optarg, sizeof(host_name) - 1); } else{ err |= 1; } break; case 'v': log_file = LOG_OUT_STDOUT; log_level = LOG_DEBUG; break; default: err |= 1; } } if(err){ phost_print_usage(); exit(1); } if(log_file == NULL){ log_file = (char*)malloc(sizeof(char)*(strlen(log_dir)+strlen(PHOST_LOG_FILE)+strlen(dev_if)+3)); sprintf(log_file, "%s/%s.%s", log_dir, PHOST_LOG_FILE, dev_if); } /* check if this process is run with root privilege */ if(getuid() != 0){ fprintf(stderr, "[ERROR] `%s' must be run with root privilege.\n", program_name); exit(1); } /* register signal handler */ signal(SIGINT, phost_handle_signals); signal(SIGTERM, phost_handle_signals); signal(SIGPIPE, SIG_IGN); signal(SIGUSR1, SIG_IGN); signal(SIGUSR2, SIG_IGN); /* initializations */ if(log_init(log_level, log_file) < 0){ fprintf(stderr, "[ERROR] cannot initialize logger.\n"); exit(1); } if(daemonize && (phost_daemonize() < 0)){ fprintf(stderr, "[ERROR] cannot daemonize.\n"); exit(1); } if(strncmp(dev_if, "tap", 3) != 0){ if(ethdev_init(dev_if) < 0){ fprintf(stderr, "[ERROR] cannot initialize Ethernet device (%s).\n", dev_if); exit(1); } trx_init(ethdev_read, ethdev_send); } else{ if(tap_init(dev_if) < 0){ fprintf(stderr, "[ERROR] cannot create tap device (%s).\n", dev_if); exit(1); } trx_init(tap_read, tap_send); } phost_set_global_params(); phost_create_pid_file(host_name); cmdif_init(dev_if, stats_udp_send_update); arp_init(host_mac_addr, host_ip_addr); ipv4_init(host_ip_addr, host_ip_mask); udp_init(stats_udp_recv_update); pkt_dump = (char*)malloc(sizeof(char)*PKT_BUF_SIZE*2); while(run){ phost_run(); cmdif_run(); arp_age_entries(); } free(pkt_dump); cmdif_close(); tap_close(); phost_delete_pid_file(host_name); phost_unset_global_params(); log_close(); return 0; }
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; }
__initfunc(int ne3210_probe1(struct device *dev, int ioaddr)) { int i; unsigned long eisa_id; const char *ifmap[] = {"UTP", "?", "BNC", "AUI"}; if (inb_p(ioaddr + NE3210_ID_PORT) == 0xff) return -ENODEV; #if NE3210_DEBUG & NE3210_D_PROBE printk("ne3210-debug: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + NE3210_ID_PORT)); printk("ne3210-debug: config regs: %#x %#x\n", inb(ioaddr + NE3210_CFG1), inb(ioaddr + NE3210_CFG2)); #endif /* Check the EISA ID of the card. */ eisa_id = inl(ioaddr + NE3210_ID_PORT); if (eisa_id != NE3210_ID) { return ENODEV; } #if 0 /* Check the vendor ID as well. Not really required. */ if (inb(ioaddr + NE3210_SA_PROM + 0) != NE3210_ADDR0 || inb(ioaddr + NE3210_SA_PROM + 1) != NE3210_ADDR1 || inb(ioaddr + NE3210_SA_PROM + 2) != NE3210_ADDR2 ) { printk("ne3210.c: card not found"); for(i = 0; i < ETHER_ADDR_LEN; i++) printk(" %02x", inb(ioaddr + NE3210_SA_PROM + i)); printk(" (invalid prefix).\n"); return ENODEV; } #endif if (load_8390_module("ne3210.c")) return -ENOSYS; /* We should have a "dev" from Space.c or the static module table. */ if (dev == NULL) { printk("ne3210.c: Passed a NULL device.\n"); dev = init_etherdev(0, 0); } /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk ("ne3210.c: unable to allocate memory for dev->priv!\n"); return -ENOMEM; } printk("ne3210.c: NE3210 in EISA slot %d, media: %s, addr:", ioaddr/0x1000, ifmap[inb(ioaddr + NE3210_CFG2) >> 6]); for(i = 0; i < ETHER_ADDR_LEN; i++) printk(" %02x", (dev->dev_addr[i] = inb(ioaddr + NE3210_SA_PROM + i))); printk(".\nne3210.c: "); /* Snarf the interrupt now. CFG file has them all listed as `edge' with share=NO */ if (dev->irq == 0) { unsigned char irq_reg = inb(ioaddr + NE3210_CFG2) >> 3; dev->irq = irq_map[irq_reg & 0x07]; printk("using"); } else {
/* 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; }
int hpprobe1(struct device *dev, int ioaddr) { int i, board_id, wordmode; char *name; unsigned char *station_addr = dev->dev_addr; /* Check for the HP physical address, 08 00 09 xx xx xx. */ /* This really isn't good enough: we may pick up HP LANCE boards also! Avoid the lance 0x5757 signature. */ if (inb(ioaddr) != 0x08 || inb(ioaddr+1) != 0x00 || inb(ioaddr+2) != 0x09 || inb(ioaddr+14) == 0x57) return ENODEV; /* Set up the parameters based on the board ID. If you have additional mappings, please mail them to [email protected]. */ if ((board_id = inb(ioaddr + HP_ID)) & 0x80) { name = "HP27247"; wordmode = 1; } else { name = "HP27250"; wordmode = 0; } /* Grab the region so we can find another board if something fails. */ snarf_region(ioaddr, HP_IO_EXTENT); printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr); for(i = 0; i < ETHER_ADDR_LEN; i++) printk(" %2.2x", station_addr[i] = inb(ioaddr + i)); /* Snarf the interrupt now. Someday this could be moved to open(). */ if (dev->irq < 2) { int irq_16list[] = { 11, 10, 5, 3, 4, 7, 9, 0}; int irq_8list[] = { 7, 5, 3, 4, 9, 0}; int *irqp = wordmode ? irq_16list : irq_8list; do { int irq = *irqp; if (request_irq (irq, NULL) != -EBUSY) { autoirq_setup(0); /* Twinkle the interrupt, and check if it's seen. */ outb_p(irqmap[irq] | HP_RUN, ioaddr + HP_CONFIGURE); outb_p( 0x00 | HP_RUN, ioaddr + HP_CONFIGURE); if (irq == autoirq_report(0) /* It's a good IRQ line! */ && request_irq (irq, &ei_interrupt) == 0) { printk(" selecting IRQ %d.\n", irq); dev->irq = *irqp; break; } } } while (*++irqp); if (*irqp == 0) { printk(" no free IRQ lines.\n"); return EBUSY; } } else { if (dev->irq == 2) dev->irq = 9; if (irqaction(dev->irq, &ei_sigaction)) { printk (" unable to get IRQ %d.\n", dev->irq); return EBUSY; } } if (ei_debug > 1) printk(version); /* Set the base address to point to the NIC, not the "real" base! */ dev->base_addr = ioaddr + NIC_OFFSET; ethdev_init(dev); ei_status.name = name; ei_status.word16 = wordmode; ei_status.tx_start_page = HP_START_PG; ei_status.rx_start_page = HP_START_PG + TX_PAGES; ei_status.stop_page = wordmode ? HP_16BSTOP_PG : HP_8BSTOP_PG; ei_status.reset_8390 = &hp_reset_8390; ei_status.block_input = &hp_block_input; ei_status.block_output = &hp_block_output; hp_init_card(dev); return 0; }
/* 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, dev->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)); } /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk ("hp-plus.c: unable to allocate memory for dev->priv.\n"); retval = -ENOMEM; goto out; } /* 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_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; 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; 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; 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; out: release_region(ioaddr, HP_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; }