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); }
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; }