static int yatse_stop(struct net_device *ndev){ struct yatse_private *priv = netdev_priv(ndev); unsigned long flags; napi_disable(&priv->napi); printk(KERN_INFO "yatse: shutdown\n"); spin_lock_irqsave(&priv->mac_lock, flags); priv->link = 0; if(priv->phy_irq != PHY_POLL) phy_stop_interrupts(priv->phydev); phy_disconnect(priv->phydev); spin_unlock_irqrestore(&priv->mac_lock, flags); disable_irq(priv->dma.rx_irq); disable_irq(priv->dma.tx_irq); netif_stop_queue(ndev); spin_lock_irqsave(&priv->dma.rx_lock, flags); spin_lock(&priv->dma.tx_lock); yatse_dma_stop(&priv->dma); spin_unlock(&priv->dma.tx_lock); spin_unlock_irqrestore(&priv->dma.rx_lock, flags); tasklet_kill(&priv->tx_tasklet); napi_disable(&priv->napi); printk(KERN_INFO "yatse: shutdown complete\n"); return 0; }
/** * phy_disconnect - disable interrupts, stop state machine, and detach a PHY device * @phydev: target phy_device struct */ void phy_disconnect(struct phy_device *phydev) { if (phydev->irq > 0) phy_stop_interrupts(phydev); phy_stop_machine(phydev); phydev->adjust_link = NULL; phy_detach(phydev); }