smsc95xx: Add module params to read MAC address
[linux-2.6.git] / drivers / net / fec_mpc52xx.c
index 25e6cc6..cb4416e 100644 (file)
@@ -14,6 +14,7 @@
  *
  */
 
+#include <linux/dma-mapping.h>
 #include <linux/module.h>
 
 #include <linux/kernel.h>
@@ -22,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/crc32.h>
 #include <linux/hardirq.h>
 #include <linux/delay.h>
@@ -335,6 +337,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev)
        bd->skb_pa = dma_map_single(dev->dev.parent, skb->data, skb->len,
                                    DMA_TO_DEVICE);
 
+       skb_tx_timestamp(skb);
        bcom_submit_next_buffer(priv->tx_dmatsk, skb);
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -366,9 +369,8 @@ static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct mpc52xx_fec_priv *priv = netdev_priv(dev);
-       unsigned long flags;
 
-       spin_lock_irqsave(&priv->lock, flags);
+       spin_lock(&priv->lock);
        while (bcom_buffer_done(priv->tx_dmatsk)) {
                struct sk_buff *skb;
                struct bcom_fec_bd *bd;
@@ -379,7 +381,7 @@ static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id)
 
                dev_kfree_skb_irq(skb);
        }
-       spin_unlock_irqrestore(&priv->lock, flags);
+       spin_unlock(&priv->lock);
 
        netif_wake_queue(dev);
 
@@ -395,9 +397,8 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id)
        struct bcom_fec_bd *bd;
        u32 status, physaddr;
        int length;
-       unsigned long flags;
 
-       spin_lock_irqsave(&priv->lock, flags);
+       spin_lock(&priv->lock);
 
        while (bcom_buffer_done(priv->rx_dmatsk)) {
 
@@ -429,19 +430,20 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id)
 
                /* Process the received skb - Drop the spin lock while
                 * calling into the network stack */
-               spin_unlock_irqrestore(&priv->lock, flags);
+               spin_unlock(&priv->lock);
 
                dma_unmap_single(dev->dev.parent, physaddr, rskb->len,
                                 DMA_FROM_DEVICE);
                length = status & BCOM_FEC_RX_BD_LEN_MASK;
                skb_put(rskb, length - 4);      /* length without CRC32 */
                rskb->protocol = eth_type_trans(rskb, dev);
-               netif_rx(rskb);
+               if (!skb_defer_rx_timestamp(skb))
+                       netif_rx(rskb);
 
-               spin_lock_irqsave(&priv->lock, flags);
+               spin_lock(&priv->lock);
        }
 
-       spin_unlock_irqrestore(&priv->lock, flags);
+       spin_unlock(&priv->lock);
 
        return IRQ_HANDLED;
 }
@@ -452,7 +454,6 @@ static irqreturn_t mpc52xx_fec_interrupt(int irq, void *dev_id)
        struct mpc52xx_fec_priv *priv = netdev_priv(dev);
        struct mpc52xx_fec __iomem *fec = priv->fec;
        u32 ievent;
-       unsigned long flags;
 
        ievent = in_be32(&fec->ievent);
 
@@ -470,9 +471,9 @@ static irqreturn_t mpc52xx_fec_interrupt(int irq, void *dev_id)
                if (net_ratelimit() && (ievent & FEC_IEVENT_XFIFO_ERROR))
                        dev_warn(&dev->dev, "FEC_IEVENT_XFIFO_ERROR\n");
 
-               spin_lock_irqsave(&priv->lock, flags);
+               spin_lock(&priv->lock);
                mpc52xx_fec_reset(dev);
-               spin_unlock_irqrestore(&priv->lock, flags);
+               spin_unlock(&priv->lock);
 
                return IRQ_HANDLED;
        }
@@ -771,11 +772,6 @@ static void mpc52xx_fec_reset(struct net_device *dev)
 
 
 /* ethtool interface */
-static void mpc52xx_fec_get_drvinfo(struct net_device *dev,
-               struct ethtool_drvinfo *info)
-{
-       strcpy(info->driver, DRIVER_NAME);
-}
 
 static int mpc52xx_fec_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
@@ -810,7 +806,6 @@ static void mpc52xx_fec_set_msglevel(struct net_device *dev, u32 level)
 }
 
 static const struct ethtool_ops mpc52xx_fec_ethtool_ops = {
-       .get_drvinfo = mpc52xx_fec_get_drvinfo,
        .get_settings = mpc52xx_fec_get_settings,
        .set_settings = mpc52xx_fec_set_settings,
        .get_link = ethtool_op_get_link,
@@ -826,7 +821,7 @@ static int mpc52xx_fec_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        if (!priv->phydev)
                return -ENOTSUPP;
 
-       return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
+       return phy_mii_ioctl(priv->phydev, rq, cmd);
 }
 
 static const struct net_device_ops mpc52xx_fec_netdev_ops = {
@@ -849,8 +844,7 @@ static const struct net_device_ops mpc52xx_fec_netdev_ops = {
 /* OF Driver                                                                */
 /* ======================================================================== */
 
-static int __devinit
-mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
+static int __devinit mpc52xx_fec_probe(struct platform_device *op)
 {
        int rv;
        struct net_device *ndev;
@@ -875,17 +869,22 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
        if (rv) {
                printk(KERN_ERR DRIVER_NAME ": "
                                "Error while parsing device node resource\n" );
-               return rv;
+               goto err_netdev;
        }
-       if ((mem.end - mem.start + 1) < sizeof(struct mpc52xx_fec)) {
+       if (resource_size(&mem) < sizeof(struct mpc52xx_fec)) {
                printk(KERN_ERR DRIVER_NAME
-                       " - invalid resource size (%lx < %x), check mpc52xx_devices.c\n",
-                       (unsigned long)(mem.end - mem.start + 1), sizeof(struct mpc52xx_fec));
-               return -EINVAL;
+                      " - invalid resource size (%lx < %x), check mpc52xx_devices.c\n",
+                      (unsigned long)resource_size(&mem),
+                      sizeof(struct mpc52xx_fec));
+               rv = -EINVAL;
+               goto err_netdev;
        }
 
-       if (!request_mem_region(mem.start, sizeof(struct mpc52xx_fec), DRIVER_NAME))
-               return -EBUSY;
+       if (!request_mem_region(mem.start, sizeof(struct mpc52xx_fec),
+                               DRIVER_NAME)) {
+               rv = -EBUSY;
+               goto err_netdev;
+       }
 
        /* Init ether ndev with what we have */
        ndev->netdev_ops        = &mpc52xx_fec_netdev_ops;
@@ -901,7 +900,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
 
        if (!priv->fec) {
                rv = -ENOMEM;
-               goto probe_error;
+               goto err_mem_region;
        }
 
        /* Bestcomm init */
@@ -914,7 +913,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
        if (!priv->rx_dmatsk || !priv->tx_dmatsk) {
                printk(KERN_ERR DRIVER_NAME ": Can not init SDMA tasks\n" );
                rv = -ENOMEM;
-               goto probe_error;
+               goto err_rx_tx_dmatsk;
        }
 
        /* Get the IRQ we need one by one */
@@ -966,40 +965,32 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
 
        rv = register_netdev(ndev);
        if (rv < 0)
-               goto probe_error;
+               goto err_node;
 
        /* We're done ! */
        dev_set_drvdata(&op->dev, ndev);
 
        return 0;
 
-
-       /* Error handling - free everything that might be allocated */
-probe_error:
-
-       if (priv->phy_node)
-               of_node_put(priv->phy_node);
-       priv->phy_node = NULL;
-
+err_node:
+       of_node_put(priv->phy_node);
        irq_dispose_mapping(ndev->irq);
-
+err_rx_tx_dmatsk:
        if (priv->rx_dmatsk)
                bcom_fec_rx_release(priv->rx_dmatsk);
        if (priv->tx_dmatsk)
                bcom_fec_tx_release(priv->tx_dmatsk);
-
-       if (priv->fec)
-               iounmap(priv->fec);
-
+       iounmap(priv->fec);
+err_mem_region:
        release_mem_region(mem.start, sizeof(struct mpc52xx_fec));
-
+err_netdev:
        free_netdev(ndev);
 
        return rv;
 }
 
 static int
-mpc52xx_fec_remove(struct of_device *op)
+mpc52xx_fec_remove(struct platform_device *op)
 {
        struct net_device *ndev;
        struct mpc52xx_fec_priv *priv;
@@ -1029,7 +1020,7 @@ mpc52xx_fec_remove(struct of_device *op)
 }
 
 #ifdef CONFIG_PM
-static int mpc52xx_fec_of_suspend(struct of_device *op, pm_message_t state)
+static int mpc52xx_fec_of_suspend(struct platform_device *op, pm_message_t state)
 {
        struct net_device *dev = dev_get_drvdata(&op->dev);
 
@@ -1039,7 +1030,7 @@ static int mpc52xx_fec_of_suspend(struct of_device *op, pm_message_t state)
        return 0;
 }
 
-static int mpc52xx_fec_of_resume(struct of_device *op)
+static int mpc52xx_fec_of_resume(struct platform_device *op)
 {
        struct net_device *dev = dev_get_drvdata(&op->dev);
 
@@ -1062,7 +1053,7 @@ static struct of_device_id mpc52xx_fec_match[] = {
 
 MODULE_DEVICE_TABLE(of, mpc52xx_fec_match);
 
-static struct of_platform_driver mpc52xx_fec_driver = {
+static struct platform_driver mpc52xx_fec_driver = {
        .driver = {
                .name = DRIVER_NAME,
                .owner = THIS_MODULE,
@@ -1086,21 +1077,21 @@ mpc52xx_fec_init(void)
 {
 #ifdef CONFIG_FEC_MPC52xx_MDIO
        int ret;
-       ret = of_register_platform_driver(&mpc52xx_fec_mdio_driver);
+       ret = platform_driver_register(&mpc52xx_fec_mdio_driver);
        if (ret) {
                printk(KERN_ERR DRIVER_NAME ": failed to register mdio driver\n");
                return ret;
        }
 #endif
-       return of_register_platform_driver(&mpc52xx_fec_driver);
+       return platform_driver_register(&mpc52xx_fec_driver);
 }
 
 static void __exit
 mpc52xx_fec_exit(void)
 {
-       of_unregister_platform_driver(&mpc52xx_fec_driver);
+       platform_driver_unregister(&mpc52xx_fec_driver);
 #ifdef CONFIG_FEC_MPC52xx_MDIO
-       of_unregister_platform_driver(&mpc52xx_fec_mdio_driver);
+       platform_driver_unregister(&mpc52xx_fec_mdio_driver);
 #endif
 }