Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[firefly-linux-kernel-4.4.55.git] / drivers / net / dm9000.c
index 12b4626102e1fbd77cff1a0558d55cfb177bad30..32a9a922f153abba70646dc32e3c0b02d265af54 100644 (file)
@@ -117,6 +117,9 @@ typedef struct board_info {
 
        struct mutex     addr_lock;     /* phy and eeprom access lock */
 
+       struct delayed_work phy_poll;
+       struct net_device  *ndev;
+
        spinlock_t lock;
 
        struct mii_if_info mii;
@@ -297,6 +300,10 @@ static void dm9000_set_io(struct board_info *db, int byte_width)
        }
 }
 
+static void dm9000_schedule_poll(board_info_t *db)
+{
+       schedule_delayed_work(&db->phy_poll, HZ * 2);
+}
 
 /* Our watchdog timed out. Called by the networking layer */
 static void dm9000_timeout(struct net_device *dev)
@@ -465,6 +472,17 @@ static const struct ethtool_ops dm9000_ethtool_ops = {
        .set_eeprom             = dm9000_set_eeprom,
 };
 
+static void
+dm9000_poll_work(struct work_struct *w)
+{
+       struct delayed_work *dw = container_of(w, struct delayed_work, work);
+       board_info_t *db = container_of(dw, board_info_t, phy_poll);
+
+       mii_check_media(&db->mii, netif_msg_link(db), 0);
+       
+       if (netif_running(db->ndev))
+               dm9000_schedule_poll(db);
+}
 
 /* dm9000_release_board
  *
@@ -503,7 +521,7 @@ dm9000_release_board(struct platform_device *pdev, struct board_info *db)
 /*
  * Search DM9000 board, allocate space and register it
  */
-static int
+static int __devinit
 dm9000_probe(struct platform_device *pdev)
 {
        struct dm9000_plat_data *pdata = pdev->dev.platform_data;
@@ -525,17 +543,21 @@ dm9000_probe(struct platform_device *pdev)
 
        SET_NETDEV_DEV(ndev, &pdev->dev);
 
-       dev_dbg(&pdev->dev, "dm9000_probe()");
+       dev_dbg(&pdev->dev, "dm9000_probe()\n");
 
        /* setup board info structure */
        db = (struct board_info *) ndev->priv;
        memset(db, 0, sizeof (*db));
 
        db->dev = &pdev->dev;
+       db->ndev = ndev;
 
        spin_lock_init(&db->lock);
        mutex_init(&db->addr_lock);
 
+       INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);
+
+
        if (pdev->num_resources < 2) {
                ret = -ENODEV;
                goto out;
@@ -761,6 +783,8 @@ dm9000_open(struct net_device *dev)
 
        mii_check_media(&db->mii, netif_msg_link(db), 1);
        netif_start_queue(dev);
+       
+       dm9000_schedule_poll(db);
 
        return 0;
 }
@@ -879,6 +903,8 @@ dm9000_stop(struct net_device *ndev)
        if (netif_msg_ifdown(db))
                dev_dbg(db->dev, "shutting down %s\n", ndev->name);
 
+       cancel_delayed_work(&db->phy_poll);
+
        netif_stop_queue(ndev);
        netif_carrier_off(ndev);
 
@@ -1288,6 +1314,8 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
        spin_unlock_irqrestore(&db->lock,flags);
 
        mutex_unlock(&db->addr_lock);
+
+       dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
        return ret;
 }
 
@@ -1301,6 +1329,7 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
        unsigned long flags;
        unsigned long reg_save;
 
+       dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
        mutex_lock(&db->addr_lock);
 
        spin_lock_irqsave(&db->lock,flags);
@@ -1372,7 +1401,7 @@ dm9000_drv_resume(struct platform_device *dev)
        return 0;
 }
 
-static int
+static int __devexit
 dm9000_drv_remove(struct platform_device *pdev)
 {
        struct net_device *ndev = platform_get_drvdata(pdev);
@@ -1393,7 +1422,7 @@ static struct platform_driver dm9000_driver = {
                .owner   = THIS_MODULE,
        },
        .probe   = dm9000_probe,
-       .remove  = dm9000_drv_remove,
+       .remove  = __devexit_p(dm9000_drv_remove),
        .suspend = dm9000_drv_suspend,
        .resume  = dm9000_drv_resume,
 };