Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
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;
	/* 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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 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;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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);
}
Ejemplo n.º 14
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, 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;
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
0
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;
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
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;
}