Beispiel #1
0
struct net_device * __init mac8390_probe(int unit)
{
    struct net_device *dev;
    volatile unsigned short *i;
    int version_disp = 0;
    struct nubus_dev * ndev = NULL;
    int err = -ENODEV;

    struct nubus_dir dir;
    struct nubus_dirent ent;
    int offset;
    static unsigned int slots;

    enum mac8390_type cardtype;

    /* probably should check for Nubus instead */

    if (!MACH_IS_MAC)
        return ERR_PTR(-ENODEV);

    dev = alloc_ei_netdev();
    if (!dev)
        return ERR_PTR(-ENOMEM);

    if (unit >= 0)
        sprintf(dev->name, "eth%d", unit);

    while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET, ndev))) {
        /* Have we seen it already? */
        if (slots & (1<<ndev->board->slot))
            continue;
        slots |= 1<<ndev->board->slot;

        if ((cardtype = mac8390_ident(ndev)) == MAC8390_NONE)
            continue;

        if (version_disp == 0) {
            version_disp = 1;
            printk(version);
        }

        dev->irq = SLOT2IRQ(ndev->board->slot);
        /* This is getting to be a habit */
        dev->base_addr = ndev->board->slot_addr | ((ndev->board->slot&0xf) << 20);

        /* Get some Nubus info - we will trust the card's idea
           of where its memory and registers are. */

        if (nubus_get_func_dir(ndev, &dir) == -1) {
            printk(KERN_ERR "%s: Unable to get Nubus functional"
                   " directory for slot %X!\n",
                   dev->name, ndev->board->slot);
            continue;
        }

        /* Get the MAC address */
        if ((nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent)) == -1) {
            printk(KERN_INFO "%s: Couldn't get MAC address!\n",
                   dev->name);
            continue;
        } else {
            nubus_get_rsrc_mem(dev->dev_addr, &ent, 6);
        }

        if (useresources[cardtype] == 1) {
            nubus_rewinddir(&dir);
            if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_BASEOS, &ent) == -1) {
                printk(KERN_ERR "%s: Memory offset resource"
                       " for slot %X not found!\n",
                       dev->name, ndev->board->slot);
                continue;
            }
            nubus_get_rsrc_mem(&offset, &ent, 4);
            dev->mem_start = dev->base_addr + offset;
            /* yes, this is how the Apple driver does it */
            dev->base_addr = dev->mem_start + 0x10000;
            nubus_rewinddir(&dir);
            if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_LENGTH, &ent) == -1) {
                printk(KERN_INFO "%s: Memory length resource"
                       " for slot %X not found"
                       ", probing\n",
                       dev->name, ndev->board->slot);
                offset = mac8390_memsize(dev->mem_start);
            } else {
                nubus_get_rsrc_mem(&offset, &ent, 4);
            }
            dev->mem_end = dev->mem_start + offset;
        } else {
            switch (cardtype) {
            case MAC8390_KINETICS:
            case MAC8390_DAYNA: /* it's the same */
                dev->base_addr =
                    (int)(ndev->board->slot_addr +
                          DAYNA_8390_BASE);
                dev->mem_start =
                    (int)(ndev->board->slot_addr +
                          DAYNA_8390_MEM);
                dev->mem_end =
                    dev->mem_start +
                    mac8390_memsize(dev->mem_start);
                break;
            case MAC8390_INTERLAN:
                dev->base_addr =
                    (int)(ndev->board->slot_addr +
                          INTERLAN_8390_BASE);
                dev->mem_start =
                    (int)(ndev->board->slot_addr +
                          INTERLAN_8390_MEM);
                dev->mem_end =
                    dev->mem_start +
                    mac8390_memsize(dev->mem_start);
                break;
            case MAC8390_CABLETRON:
                dev->base_addr =
                    (int)(ndev->board->slot_addr +
                          CABLETRON_8390_BASE);
                dev->mem_start =
                    (int)(ndev->board->slot_addr +
                          CABLETRON_8390_MEM);
                /* The base address is unreadable if 0x00
                 * has been written to the command register
                 * Reset the chip by writing E8390_NODMA +
                 *   E8390_PAGE0 + E8390_STOP just to be
                 *   sure
                 */
                i = (void *)dev->base_addr;
                *i = 0x21;
                dev->mem_end =
                    dev->mem_start +
                    mac8390_memsize(dev->mem_start);
                break;

            default:
                printk(KERN_ERR "Card type %s is"
                       " unsupported, sorry\n",
                       ndev->board->name);
                continue;
            }
        }

        /* Do the nasty 8390 stuff */
        if (!mac8390_initdev(dev, ndev, cardtype))
            break;
    }

    if (!ndev)
        goto out;
    err = register_netdev(dev);
    if (err)
        goto out;
    return dev;

out:
    free_netdev(dev);
    return ERR_PTR(err);
}
Beispiel #2
0
static int __devinit mac_nubus_sonic_probe(struct net_device *dev)
{
	static int slots;
	struct nubus_dev* ndev = NULL;
	struct sonic_local* lp = netdev_priv(dev);
	unsigned long base_addr, prom_addr;
	u16 sonic_dcr;
	int id = -1;
	int reg_offset, dma_bitmode;

	
	while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK,
				       NUBUS_TYPE_ETHERNET, ndev)) != NULL)
	{
		
		if (slots & (1<<ndev->board->slot))
			continue;
		slots |= 1<<ndev->board->slot;

		
		if ((id = macsonic_ident(ndev)) != -1)
			break;
	}

	if (ndev == NULL)
		return -ENODEV;

	switch (id) {
	case MACSONIC_DUODOCK:
		base_addr = ndev->board->slot_addr + DUODOCK_SONIC_REGISTERS;
		prom_addr = ndev->board->slot_addr + DUODOCK_SONIC_PROM_BASE;
		sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT0 | SONIC_DCR_RFT1 |
		            SONIC_DCR_TFT0;
		reg_offset = 2;
		dma_bitmode = SONIC_BITMODE32;
		break;
	case MACSONIC_APPLE:
		base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS;
		prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE;
		sonic_dcr = SONIC_DCR_BMS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0;
		reg_offset = 0;
		dma_bitmode = SONIC_BITMODE32;
		break;
	case MACSONIC_APPLE16:
		base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS;
		prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE;
		sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 |
		            SONIC_DCR_PO1 | SONIC_DCR_BMS;
		reg_offset = 0;
		dma_bitmode = SONIC_BITMODE16;
		break;
	case MACSONIC_DAYNALINK:
		base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS;
		prom_addr = ndev->board->slot_addr + DAYNALINK_PROM_BASE;
		sonic_dcr = SONIC_DCR_RFT1 | SONIC_DCR_TFT0 |
		            SONIC_DCR_PO1 | SONIC_DCR_BMS;
		reg_offset = 0;
		dma_bitmode = SONIC_BITMODE16;
		break;
	case MACSONIC_DAYNA:
		base_addr = ndev->board->slot_addr + DAYNA_SONIC_REGISTERS;
		prom_addr = ndev->board->slot_addr + DAYNA_SONIC_MAC_ADDR;
		sonic_dcr = SONIC_DCR_BMS |
		            SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_PO1;
		reg_offset = 0;
		dma_bitmode = SONIC_BITMODE16;
		break;
	default:
		printk(KERN_ERR "macsonic: WTF, id is %d\n", id);
		return -ENODEV;
	}

	
	dev->base_addr = base_addr;
	lp->reg_offset = reg_offset;
	lp->dma_bitmode = dma_bitmode;
	dev->irq = SLOT2IRQ(ndev->board->slot);

	if (!sonic_version_printed) {
		printk(KERN_INFO "%s", version);
		sonic_version_printed = 1;
	}
	printk(KERN_INFO "%s: %s in slot %X\n",
	       dev_name(lp->device), ndev->board->name, ndev->board->slot);
	printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
	       dev_name(lp->device), SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset);

#if 0 
	printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device),
	       SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff);
#endif

	
	SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
	SONIC_WRITE(SONIC_DCR, sonic_dcr | (dma_bitmode ? SONIC_DCR_DW : 0));
	
	SONIC_WRITE(SONIC_DCR2, 0);

	
	SONIC_WRITE(SONIC_IMR, 0);
	SONIC_WRITE(SONIC_ISR, 0x7fff);

	
	if (mac_nubus_sonic_ethernet_addr(dev, prom_addr, id) != 0)
		return -ENODEV;

	
	return macsonic_init(dev);
}