ethtool: Call ethtool's get/set_settings callbacks with cleaned data
[sfrench/cifs-2.6.git] / drivers / net / pcnet32.c
index aee3bb0358bf9b49801cff98602699870cdec0c1..b48aba9e42274de4609d3920d133021a11de4b6b 100644 (file)
@@ -295,12 +295,14 @@ struct pcnet32_private {
        struct net_device       *next;
        struct mii_if_info      mii_if;
        struct timer_list       watchdog_timer;
-       struct timer_list       blink_timer;
        u32                     msg_enable;     /* debug message level */
 
        /* each bit indicates an available PHY */
        u32                     phymask;
        unsigned short          chip_version;   /* which variant this is */
+
+       /* saved registers during ethtool blink */
+       u16                     save_regs[4];
 };
 
 static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *);
@@ -324,8 +326,6 @@ static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits);
 static void pcnet32_ethtool_test(struct net_device *dev,
                                 struct ethtool_test *eth_test, u64 * data);
 static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1);
-static int pcnet32_phys_id(struct net_device *dev, u32 data);
-static void pcnet32_led_blink_callback(struct net_device *dev);
 static int pcnet32_get_regs_len(struct net_device *dev);
 static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
                             void *ptr);
@@ -1022,7 +1022,8 @@ clean_up:
        return rc;
 }                              /* end pcnet32_loopback_test  */
 
-static void pcnet32_led_blink_callback(struct net_device *dev)
+static int pcnet32_set_phys_id(struct net_device *dev,
+                              enum ethtool_phys_id_state state)
 {
        struct pcnet32_private *lp = netdev_priv(dev);
        struct pcnet32_access *a = &lp->a;
@@ -1030,50 +1031,31 @@ static void pcnet32_led_blink_callback(struct net_device *dev)
        unsigned long flags;
        int i;
 
-       spin_lock_irqsave(&lp->lock, flags);
-       for (i = 4; i < 8; i++)
-               a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000);
-       spin_unlock_irqrestore(&lp->lock, flags);
-
-       mod_timer(&lp->blink_timer, PCNET32_BLINK_TIMEOUT);
-}
+       switch (state) {
+       case ETHTOOL_ID_ACTIVE:
+               /* Save the current value of the bcrs */
+               spin_lock_irqsave(&lp->lock, flags);
+               for (i = 4; i < 8; i++)
+                       lp->save_regs[i - 4] = a->read_bcr(ioaddr, i);
+               spin_unlock_irqrestore(&lp->lock, flags);
+               return 2;       /* cycle on/off twice per second */
 
-static int pcnet32_phys_id(struct net_device *dev, u32 data)
-{
-       struct pcnet32_private *lp = netdev_priv(dev);
-       struct pcnet32_access *a = &lp->a;
-       ulong ioaddr = dev->base_addr;
-       unsigned long flags;
-       int i, regs[4];
+       case ETHTOOL_ID_ON:
+       case ETHTOOL_ID_OFF:
+               /* Blink the led */
+               spin_lock_irqsave(&lp->lock, flags);
+               for (i = 4; i < 8; i++)
+                       a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000);
+               spin_unlock_irqrestore(&lp->lock, flags);
+               break;
 
-       if (!lp->blink_timer.function) {
-               init_timer(&lp->blink_timer);
-               lp->blink_timer.function = (void *)pcnet32_led_blink_callback;
-               lp->blink_timer.data = (unsigned long)dev;
+       case ETHTOOL_ID_INACTIVE:
+               /* Restore the original value of the bcrs */
+               spin_lock_irqsave(&lp->lock, flags);
+               for (i = 4; i < 8; i++)
+                       a->write_bcr(ioaddr, i, lp->save_regs[i - 4]);
+               spin_unlock_irqrestore(&lp->lock, flags);
        }
-
-       /* Save the current value of the bcrs */
-       spin_lock_irqsave(&lp->lock, flags);
-       for (i = 4; i < 8; i++)
-               regs[i - 4] = a->read_bcr(ioaddr, i);
-       spin_unlock_irqrestore(&lp->lock, flags);
-
-       mod_timer(&lp->blink_timer, jiffies);
-       set_current_state(TASK_INTERRUPTIBLE);
-
-       /* AV: the limit here makes no sense whatsoever */
-       if ((!data) || (data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ)))
-               data = (u32) (MAX_SCHEDULE_TIMEOUT / HZ);
-
-       msleep_interruptible(data * 1000);
-       del_timer_sync(&lp->blink_timer);
-
-       /* Restore the original value of the bcrs */
-       spin_lock_irqsave(&lp->lock, flags);
-       for (i = 4; i < 8; i++)
-               a->write_bcr(ioaddr, i, regs[i - 4]);
-       spin_unlock_irqrestore(&lp->lock, flags);
-
        return 0;
 }
 
@@ -1450,7 +1432,7 @@ static const struct ethtool_ops pcnet32_ethtool_ops = {
        .set_ringparam          = pcnet32_set_ringparam,
        .get_strings            = pcnet32_get_strings,
        .self_test              = pcnet32_ethtool_test,
-       .phys_id                = pcnet32_phys_id,
+       .set_phys_id            = pcnet32_set_phys_id,
        .get_regs_len           = pcnet32_get_regs_len,
        .get_regs               = pcnet32_get_regs,
        .get_sset_count         = pcnet32_get_sset_count,
@@ -1651,7 +1633,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
        /*
         *  On selected chips turn on the BCR18:NOUFLO bit. This stops transmit
         *  starting until the packet is loaded. Strike one for reliability, lose
-        *  one for latency - although on PCI this isnt a big loss. Older chips
+        *  one for latency - although on PCI this isn't a big loss. Older chips
         *  have FIFO's smaller than a packet, so you can't do this.
         *  Turn on BCR18:BurstRdEn and BCR18:BurstWrEn.
         */
@@ -2117,7 +2099,7 @@ static int pcnet32_open(struct net_device *dev)
                int first_phy = -1;
                u16 bmcr;
                u32 bcr9;
-               struct ethtool_cmd ecmd;
+               struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 
                /*
                 * There is really no good other way to handle multiple PHYs
@@ -2133,9 +2115,9 @@ static int pcnet32_open(struct net_device *dev)
                        ecmd.port = PORT_MII;
                        ecmd.transceiver = XCVR_INTERNAL;
                        ecmd.autoneg = AUTONEG_DISABLE;
-                       ecmd.speed =
-                           lp->
-                           options & PCNET32_PORT_100 ? SPEED_100 : SPEED_10;
+                       ethtool_cmd_speed_set(&ecmd,
+                                             (lp->options & PCNET32_PORT_100) ?
+                                             SPEED_100 : SPEED_10);
                        bcr9 = lp->a.read_bcr(ioaddr, 9);
 
                        if (lp->options & PCNET32_PORT_FD) {
@@ -2781,11 +2763,11 @@ static void pcnet32_check_media(struct net_device *dev, int verbose)
                netif_carrier_on(dev);
                if (lp->mii) {
                        if (netif_msg_link(lp)) {
-                               struct ethtool_cmd ecmd;
+                               struct ethtool_cmd ecmd = {
+                                       .cmd = ETHTOOL_GSET };
                                mii_ethtool_gset(&lp->mii_if, &ecmd);
-                               netdev_info(dev, "link up, %sMbps, %s-duplex\n",
-                                           (ecmd.speed == SPEED_100)
-                                           ? "100" : "10",
+                               netdev_info(dev, "link up, %uMbps, %s-duplex\n",
+                                           ethtool_cmd_speed(&ecmd),
                                            (ecmd.duplex == DUPLEX_FULL)
                                            ? "full" : "half");
                        }