Exemplo n.º 1
0
/*  Open the interface.
 *  The interface is opened whenever "ifconfig" actives it.
 */
static int emac_open(struct net_device *dev)
{
	struct emac_board_info *db = netdev_priv(dev);
	int ret;

	if (netif_msg_ifup(db))
		dev_dbg(db->dev, "enabling %s\n", dev->name);

	if (request_irq(dev->irq, &emac_interrupt, 0, dev->name, dev))
		return -EAGAIN;

	/* Initialize EMAC board */
	emac_reset(db);
	emac_init_device(dev);

	ret = emac_mdio_probe(dev);
	if (ret < 0) {
		free_irq(dev->irq, dev);
		netdev_err(dev, "cannot probe MDIO bus\n");
		return ret;
	}

	phy_start(dev->phydev);
	netif_start_queue(dev);

	return 0;
}
Exemplo n.º 2
0
static int emac_resume(struct platform_device *dev)
{
	struct net_device *ndev = platform_get_drvdata(dev);
	struct emac_board_info *db = netdev_priv(ndev);

	emac_reset(db);
	emac_init_device(ndev);
	netif_device_attach(ndev);

	return 0;
}
Exemplo n.º 3
0
/* Our watchdog timed out. Called by the networking layer */
static void emac_timeout(struct net_device *dev)
{
	struct emac_board_info *db = netdev_priv(dev);
	unsigned long flags;

	if (netif_msg_timer(db))
		dev_err(db->dev, "tx time out.\n");

	/* Save previous register address */
	spin_lock_irqsave(&db->lock, flags);

	netif_stop_queue(dev);
	emac_reset(db);
	emac_init_device(dev);
	/* We can accept TX packets again */
	netif_trans_update(dev);
	netif_wake_queue(dev);

	/* Restore previous register address */
	spin_unlock_irqrestore(&db->lock, flags);
}
Exemplo n.º 4
0
int eth_init()
{
	cpu_flags_t flags;

	emac_reset();
	emac_start();

	event_initGeneric(&recv_wait);
	event_initGeneric(&send_wait);

	// Register interrupt vector
	IRQ_SAVE_DISABLE(flags);

	/* Disable all emac interrupts */
	EMAC_IDR = 0xFFFFFFFF;

#if CPU_ARM_AT91
	// TODO: define sysirq_set...
	/* Set the vector. */
	AIC_SVR(EMAC_ID) = emac_irqHandler;
	/* Initialize to edge triggered with defined priority. */
	AIC_SMR(EMAC_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED;
	/* Clear pending interrupt */
	AIC_ICCR = BV(EMAC_ID);
	/* Enable the system IRQ */
	AIC_IECR = BV(EMAC_ID);
#else
	sysirq_setHandler(INT_EMAC, emac_irqHandler);
#endif

	/* Enable interrupts */
	EMAC_IER = EMAC_RX_INTS | EMAC_TX_INTS;

	IRQ_RESTORE(flags);

	return 0;
}
Exemplo n.º 5
0
/* Search EMAC board, allocate space and register it
 */
static int emac_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct emac_board_info *db;
	struct net_device *ndev;
	int ret = 0;
	const char *mac_addr;

	ndev = alloc_etherdev(sizeof(struct emac_board_info));
	if (!ndev) {
		dev_err(&pdev->dev, "could not allocate device.\n");
		return -ENOMEM;
	}

	SET_NETDEV_DEV(ndev, &pdev->dev);

	db = netdev_priv(ndev);
	memset(db, 0, sizeof(*db));

	db->dev = &pdev->dev;
	db->ndev = ndev;
	db->pdev = pdev;
	db->msg_enable = netif_msg_init(debug, EMAC_DEFAULT_MSG_ENABLE);

	spin_lock_init(&db->lock);

	db->membase = of_iomap(np, 0);
	if (!db->membase) {
		dev_err(&pdev->dev, "failed to remap registers\n");
		ret = -ENOMEM;
		goto out;
	}

	/* fill in parameters for net-dev structure */
	ndev->base_addr = (unsigned long)db->membase;
	ndev->irq = irq_of_parse_and_map(np, 0);
	if (ndev->irq == -ENXIO) {
		netdev_err(ndev, "No irq resource\n");
		ret = ndev->irq;
		goto out_iounmap;
	}

	db->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(db->clk)) {
		ret = PTR_ERR(db->clk);
		goto out_iounmap;
	}

	ret = clk_prepare_enable(db->clk);
	if (ret) {
		dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret);
		goto out_iounmap;
	}

	ret = sunxi_sram_claim(&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "Error couldn't map SRAM to device\n");
		goto out_clk_disable_unprepare;
	}

	db->phy_node = of_parse_phandle(np, "phy", 0);
	if (!db->phy_node) {
		dev_err(&pdev->dev, "no associated PHY\n");
		ret = -ENODEV;
		goto out_release_sram;
	}

	/* Read MAC-address from DT */
	mac_addr = of_get_mac_address(np);
	if (mac_addr)
		memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);

	/* Check if the MAC address is valid, if not get a random one */
	if (!is_valid_ether_addr(ndev->dev_addr)) {
		eth_hw_addr_random(ndev);
		dev_warn(&pdev->dev, "using random MAC address %pM\n",
			 ndev->dev_addr);
	}

	db->emacrx_completed_flag = 1;
	emac_powerup(ndev);
	emac_reset(db);

	ndev->netdev_ops = &emac_netdev_ops;
	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
	ndev->ethtool_ops = &emac_ethtool_ops;

	platform_set_drvdata(pdev, ndev);

	/* Carrier starts down, phylib will bring it up */
	netif_carrier_off(ndev);

	ret = register_netdev(ndev);
	if (ret) {
		dev_err(&pdev->dev, "Registering netdev failed!\n");
		ret = -ENODEV;
		goto out_release_sram;
	}

	dev_info(&pdev->dev, "%s: at %p, IRQ %d MAC: %pM\n",
		 ndev->name, db->membase, ndev->irq, ndev->dev_addr);

	return 0;

out_release_sram:
	sunxi_sram_release(&pdev->dev);
out_clk_disable_unprepare:
	clk_disable_unprepare(db->clk);
out_iounmap:
	iounmap(db->membase);
out:
	dev_err(db->dev, "not found (%d).\n", ret);

	free_netdev(ndev);

	return ret;
}
Exemplo n.º 6
0
/* Search EMAC board, allocate space and register it
 */
static int emac_probe(struct vmm_device *pdev,
			const struct vmm_devtree_nodeid *devid)
{
	struct device_node *np = pdev->node;
	struct emac_board_info *db;
	struct net_device *ndev;
	int ret = 0;
	const char *mac_addr;
	virtual_addr_t  reg_addr;

	ndev = alloc_etherdev(sizeof(struct emac_board_info));
	if (!ndev) {
		dev_err(pdev, "%s: could not allocate device.\n", __func__);
		return -ENOMEM;
	}

	strlcpy(ndev->name, pdev->name, sizeof(ndev->name));

	SET_NETDEV_DEV(ndev, pdev);

	db = netdev_priv(ndev);
	memset(db, 0, sizeof(*db));

	db->ndev = ndev;
	db->pdev = pdev;

	spin_lock_init(&db->lock);

	if ((ret = vmm_devtree_request_regmap(np, &reg_addr, 0,
					      "Sun4i EMAC"))) {
		vmm_printf("%s: Failed to ioreamp\n", __func__);
		return -ENOMEM;
	}

	db->membase = (void *) reg_addr;

	/* fill in parameters for net-dev structure */
	ndev->base_addr = (unsigned long)db->membase;

	ret = vmm_devtree_irq_get(np, &ndev->irq, 0);
	if (ret) {
		vmm_printf("%s: No irq resource\n", __func__);
		goto out;
	}

	db->clk = clk_get(pdev, NULL);
	if (IS_ERR(db->clk))
		goto out;

	clk_prepare_enable(db->clk);

	db->phy_node = vmm_devtree_parse_phandle(np, "phy", 0);
	if (!db->phy_node) {
		dev_err(pdev, "%s: no associated PHY\n", __func__);
		ret = -ENODEV;
		goto out;
	}

	/* Read MAC-address from DT */
	mac_addr = of_get_mac_address(np);
	if (mac_addr)
		memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);

	/* Check if the MAC address is valid, if not get a random one */
	if (!is_valid_ether_addr(ndev->dev_addr)) {
		eth_hw_addr_random(ndev);
		dev_info(pdev, "using random MAC address: ");
		print_mac_address_fmt(ndev->dev_addr);
	}

	db->emacrx_completed_flag = 1;
	emac_powerup(ndev);
	emac_reset(db);

	ether_setup(ndev);

	ndev->netdev_ops = &emac_netdev_ops;
	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
	ndev->ethtool_ops = &emac_ethtool_ops;

	platform_set_drvdata(pdev, ndev);

	/* Carrier starts down, phylib will bring it up */
	netif_carrier_off(ndev);

	ret = register_netdev(ndev);
	if (ret) {
		dev_err(pdev, "%s: Registering netdev failed!\n", __func__);
		ret = -ENODEV;
		goto out;
	}

	dev_info(pdev, "%s: at %p, IRQ %d MAC: ",
		 ndev->name, db->membase, ndev->irq);
	print_mac_address_fmt(ndev->dev_addr);

	return 0;

out:
	dev_err(pdev, "%s: not found (%d).\n", __func__, ret);
	free_netdev(ndev);

	return ret;
}