diff options
Diffstat (limited to 'drivers/net/pcnet32.c')
-rw-r--r-- | drivers/net/pcnet32.c | 90 |
1 files changed, 36 insertions, 54 deletions
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 768037602dff..b48aba9e4227 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -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, @@ -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"); } |