Пример #1
0
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;
}
Пример #2
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 {
Пример #3
0
/* 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;
}
Пример #4
0
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;
}
Пример #5
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;
}
Пример #6
0
__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 {
Пример #7
0
/* 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;
}
Пример #8
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;
}
Пример #9
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;
}
Пример #10
0
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;
}