static int ccat_eth_dma_probe(struct ccat_function *func)
{
	struct ccat_eth_priv *priv = ccat_eth_alloc_netdev(func);
	int status;

	if (!priv)
		return -ENOMEM;

	status = ccat_eth_priv_init_dma(priv);
	if (status) {
		pr_warn("%s(): DMA initialization failed.\n", __FUNCTION__);
		free_netdev(priv->netdev);
		return status;
	}
	return ccat_eth_init_netdev(priv);
}
Beispiel #2
0
struct ccat_eth_priv *ccat_eth_init(const struct ccat_device *const ccatdev,
				    const void __iomem * const addr)
{
	struct ccat_eth_priv *priv;
	struct net_device *const netdev = alloc_etherdev(sizeof(*priv));

	priv = netdev_priv(netdev);
	priv->netdev = netdev;
	priv->ccatdev = ccatdev;

	/* ccat register mappings */
	memcpy_fromio(&priv->info, addr, sizeof(priv->info));
	ccat_eth_priv_init_mappings(priv);

	if (ccat_eth_priv_init_dma(priv)) {
		pr_warn("%s(): DMA initialization failed.\n", __FUNCTION__);
		free_netdev(netdev);
		return NULL;
	}

	/* init netdev with MAC and stack callbacks */
	memcpy_fromio(netdev->dev_addr, priv->reg.mii + 8, netdev->addr_len);
	netdev->netdev_ops = &ccat_eth_netdev_ops;

	/* use as EtherCAT device? */
	priv->ecdev = ecdev_offer(netdev, ec_poll_rx, THIS_MODULE);
	if (priv->ecdev) {
		priv->carrier_off = ecdev_carrier_off;
		priv->carrier_ok = ecdev_carrier_ok;
		priv->carrier_on = ecdev_carrier_on;
		priv->kfree_skb_any = ecdev_kfree_skb_any;
		priv->start_queue = ecdev_nop;
		priv->stop_queue = ecdev_nop;
		priv->unregister = unregister_ecdev;

		priv->carrier_off(netdev);
		if (ecdev_open(priv->ecdev)) {
			pr_info("unable to register network device.\n");
			ecdev_withdraw(priv->ecdev);
			ccat_eth_priv_free_dma(priv);
			free_netdev(netdev);
			return NULL;
		}
		return priv;
	}

	/* EtherCAT disabled -> prepare normal ethernet mode */
	priv->carrier_off = netif_carrier_off;
	priv->carrier_ok = netif_carrier_ok;
	priv->carrier_on = netif_carrier_on;
	priv->kfree_skb_any = dev_kfree_skb_any;
	priv->start_queue = netif_start_queue;
	priv->stop_queue = netif_stop_queue;
	priv->unregister = unregister_netdev;

	priv->carrier_off(netdev);
	if (register_netdev(netdev)) {
		pr_info("unable to register network device.\n");
		ccat_eth_priv_free_dma(priv);
		free_netdev(netdev);
		return NULL;
	}
	pr_info("registered %s as network device.\n", netdev->name);
	return priv;
}