Example #1
0
static int __exit ar2313_remove(struct platform_device *pdev)
{
    struct net_device *dev = platform_get_drvdata(pdev);
    rx_tasklet_cleanup(dev);
    ar2313_init_cleanup(dev);
    unregister_netdev(dev);
    kfree(dev);
    return 0;
}
Example #2
0
int __init ar2313_probe(struct platform_device *pdev)
{
	struct net_device *dev;
	struct ar2313_private *sp;
	struct resource *res;
	unsigned long ar_eth_base;
	char buf[64];

	dev = alloc_etherdev(sizeof(struct ar2313_private));

	if (dev == NULL) {
		printk(KERN_ERR
			   "ar2313: Unable to allocate net_device structure!\n");
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, dev);

	sp = netdev_priv(dev);
	sp->dev = dev;
	sp->cfg = pdev->dev.platform_data;

	sprintf(buf, "eth%d_membase", pdev->id);
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, buf);
	if (!res)
		return -ENODEV;

	sp->link = 0;
	ar_eth_base = res->start;
	sp->phy = sp->cfg->phy;

	sprintf(buf, "eth%d_irq", pdev->id);
	dev->irq = platform_get_irq_byname(pdev, buf);

	spin_lock_init(&sp->lock);

	/* initialize func pointers */
	dev->open = &ar2313_open;
	dev->stop = &ar2313_close;
	dev->hard_start_xmit = &ar2313_start_xmit;

	dev->set_multicast_list = &ar2313_multicast_list;
#ifdef TX_TIMEOUT
	dev->tx_timeout = ar2313_tx_timeout;
	dev->watchdog_timeo = AR2313_TX_TIMEOUT;
#endif
	dev->do_ioctl = &ar2313_ioctl;

	// SAMEER: do we need this?
	dev->features |= NETIF_F_HIGHDMA;

	tasklet_init(&sp->rx_tasklet, rx_tasklet_func, (unsigned long) dev);
	tasklet_disable(&sp->rx_tasklet);

	sp->eth_regs =
		ioremap_nocache(virt_to_phys(ar_eth_base), sizeof(*sp->eth_regs));
	if (!sp->eth_regs) {
		printk("Can't remap eth registers\n");
		return (-ENXIO);
	}

	/*
	 * When there's only one MAC, PHY regs are typically on ENET0,
	 * even though the MAC might be on ENET1.
	 * Needto remap PHY regs separately in this case
	 */
	if (virt_to_phys(ar_eth_base) == virt_to_phys(sp->phy_regs))
		sp->phy_regs = sp->eth_regs;
	else {
		sp->phy_regs =
			ioremap_nocache(virt_to_phys(sp->cfg->phy_base),
							sizeof(*sp->phy_regs));
		if (!sp->phy_regs) {
			printk("Can't remap phy registers\n");
			return (-ENXIO);
		}
	}

	sp->dma_regs =
		ioremap_nocache(virt_to_phys(ar_eth_base + 0x1000),
						sizeof(*sp->dma_regs));
	dev->base_addr = (unsigned int) sp->dma_regs;
	if (!sp->dma_regs) {
		printk("Can't remap DMA registers\n");
		return (-ENXIO);
	}

	sp->int_regs = ioremap_nocache(virt_to_phys(sp->cfg->reset_base), 4);
	if (!sp->int_regs) {
		printk("Can't remap INTERRUPT registers\n");
		return (-ENXIO);
	}

	strncpy(sp->name, "Atheros AR231x", sizeof(sp->name) - 1);
	sp->name[sizeof(sp->name) - 1] = '\0';
	memcpy(dev->dev_addr, sp->cfg->macaddr, 6);
	sp->board_idx = BOARD_IDX_STATIC;

	if (ar2313_init(dev)) {
		/*
		 * ar2313_init() calls ar2313_init_cleanup() on error.
		 */
		kfree(dev);
		return -ENODEV;
	}

	if (register_netdev(dev)) {
		printk("%s: register_netdev failed\n", __func__);
		return -1;
	}

	printk("%s: %s: %02x:%02x:%02x:%02x:%02x:%02x, irq %d\n",
		   dev->name, sp->name,
		   dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
		   dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5], dev->irq);

	sp->mii_bus.priv = dev;
	sp->mii_bus.read = mdiobus_read;
	sp->mii_bus.write = mdiobus_write;
	sp->mii_bus.reset = mdiobus_reset;
	sp->mii_bus.name = "ar2313_eth_mii";
	sp->mii_bus.id = 0;
	sp->mii_bus.irq = kmalloc(sizeof(int), GFP_KERNEL);
	*sp->mii_bus.irq = PHY_POLL;

	mdiobus_register(&sp->mii_bus);

	if (mdiobus_probe(dev) != 0) {
		printk(KERN_ERR "ar2313: mdiobus_probe failed");
		rx_tasklet_cleanup(dev);
		ar2313_init_cleanup(dev);
		unregister_netdev(dev);
		kfree(dev);
	} else {
		/* start link poll timer */
		ar2313_setup_timer(dev);
	}

	return 0;
}