diff options
-rw-r--r-- | drivers/net/pcnet32.c | 74 |
1 files changed, 28 insertions, 46 deletions
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index aee3bb0358bf..eb7ac4e48c71 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c | |||
@@ -295,12 +295,14 @@ struct pcnet32_private { | |||
295 | struct net_device *next; | 295 | struct net_device *next; |
296 | struct mii_if_info mii_if; | 296 | struct mii_if_info mii_if; |
297 | struct timer_list watchdog_timer; | 297 | struct timer_list watchdog_timer; |
298 | struct timer_list blink_timer; | ||
299 | u32 msg_enable; /* debug message level */ | 298 | u32 msg_enable; /* debug message level */ |
300 | 299 | ||
301 | /* each bit indicates an available PHY */ | 300 | /* each bit indicates an available PHY */ |
302 | u32 phymask; | 301 | u32 phymask; |
303 | unsigned short chip_version; /* which variant this is */ | 302 | unsigned short chip_version; /* which variant this is */ |
303 | |||
304 | /* saved registers during ethtool blink */ | ||
305 | u16 save_regs[4]; | ||
304 | }; | 306 | }; |
305 | 307 | ||
306 | static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *); | 308 | 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); | |||
324 | static void pcnet32_ethtool_test(struct net_device *dev, | 326 | static void pcnet32_ethtool_test(struct net_device *dev, |
325 | struct ethtool_test *eth_test, u64 * data); | 327 | struct ethtool_test *eth_test, u64 * data); |
326 | static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1); | 328 | static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1); |
327 | static int pcnet32_phys_id(struct net_device *dev, u32 data); | ||
328 | static void pcnet32_led_blink_callback(struct net_device *dev); | ||
329 | static int pcnet32_get_regs_len(struct net_device *dev); | 329 | static int pcnet32_get_regs_len(struct net_device *dev); |
330 | static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs, | 330 | static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs, |
331 | void *ptr); | 331 | void *ptr); |
@@ -1022,7 +1022,8 @@ clean_up: | |||
1022 | return rc; | 1022 | return rc; |
1023 | } /* end pcnet32_loopback_test */ | 1023 | } /* end pcnet32_loopback_test */ |
1024 | 1024 | ||
1025 | static void pcnet32_led_blink_callback(struct net_device *dev) | 1025 | static int pcnet32_set_phys_id(struct net_device *dev, |
1026 | enum ethtool_phys_id_state state) | ||
1026 | { | 1027 | { |
1027 | struct pcnet32_private *lp = netdev_priv(dev); | 1028 | struct pcnet32_private *lp = netdev_priv(dev); |
1028 | struct pcnet32_access *a = &lp->a; | 1029 | struct pcnet32_access *a = &lp->a; |
@@ -1030,50 +1031,31 @@ static void pcnet32_led_blink_callback(struct net_device *dev) | |||
1030 | unsigned long flags; | 1031 | unsigned long flags; |
1031 | int i; | 1032 | int i; |
1032 | 1033 | ||
1033 | spin_lock_irqsave(&lp->lock, flags); | 1034 | switch (state) { |
1034 | for (i = 4; i < 8; i++) | 1035 | case ETHTOOL_ID_ACTIVE: |
1035 | a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000); | 1036 | /* Save the current value of the bcrs */ |
1036 | spin_unlock_irqrestore(&lp->lock, flags); | 1037 | spin_lock_irqsave(&lp->lock, flags); |
1037 | 1038 | for (i = 4; i < 8; i++) | |
1038 | mod_timer(&lp->blink_timer, PCNET32_BLINK_TIMEOUT); | 1039 | lp->save_regs[i - 4] = a->read_bcr(ioaddr, i); |
1039 | } | 1040 | spin_unlock_irqrestore(&lp->lock, flags); |
1041 | return -EINVAL; | ||
1040 | 1042 | ||
1041 | static int pcnet32_phys_id(struct net_device *dev, u32 data) | 1043 | case ETHTOOL_ID_ON: |
1042 | { | 1044 | case ETHTOOL_ID_OFF: |
1043 | struct pcnet32_private *lp = netdev_priv(dev); | 1045 | /* Blink the led */ |
1044 | struct pcnet32_access *a = &lp->a; | 1046 | spin_lock_irqsave(&lp->lock, flags); |
1045 | ulong ioaddr = dev->base_addr; | 1047 | for (i = 4; i < 8; i++) |
1046 | unsigned long flags; | 1048 | a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000); |
1047 | int i, regs[4]; | 1049 | spin_unlock_irqrestore(&lp->lock, flags); |
1050 | break; | ||
1048 | 1051 | ||
1049 | if (!lp->blink_timer.function) { | 1052 | case ETHTOOL_ID_INACTIVE: |
1050 | init_timer(&lp->blink_timer); | 1053 | /* Restore the original value of the bcrs */ |
1051 | lp->blink_timer.function = (void *)pcnet32_led_blink_callback; | 1054 | spin_lock_irqsave(&lp->lock, flags); |
1052 | lp->blink_timer.data = (unsigned long)dev; | 1055 | for (i = 4; i < 8; i++) |
1056 | a->write_bcr(ioaddr, i, lp->save_regs[i - 4]); | ||
1057 | spin_unlock_irqrestore(&lp->lock, flags); | ||
1053 | } | 1058 | } |
1054 | |||
1055 | /* Save the current value of the bcrs */ | ||
1056 | spin_lock_irqsave(&lp->lock, flags); | ||
1057 | for (i = 4; i < 8; i++) | ||
1058 | regs[i - 4] = a->read_bcr(ioaddr, i); | ||
1059 | spin_unlock_irqrestore(&lp->lock, flags); | ||
1060 | |||
1061 | mod_timer(&lp->blink_timer, jiffies); | ||
1062 | set_current_state(TASK_INTERRUPTIBLE); | ||
1063 | |||
1064 | /* AV: the limit here makes no sense whatsoever */ | ||
1065 | if ((!data) || (data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ))) | ||
1066 | data = (u32) (MAX_SCHEDULE_TIMEOUT / HZ); | ||
1067 | |||
1068 | msleep_interruptible(data * 1000); | ||
1069 | del_timer_sync(&lp->blink_timer); | ||
1070 | |||
1071 | /* Restore the original value of the bcrs */ | ||
1072 | spin_lock_irqsave(&lp->lock, flags); | ||
1073 | for (i = 4; i < 8; i++) | ||
1074 | a->write_bcr(ioaddr, i, regs[i - 4]); | ||
1075 | spin_unlock_irqrestore(&lp->lock, flags); | ||
1076 | |||
1077 | return 0; | 1059 | return 0; |
1078 | } | 1060 | } |
1079 | 1061 | ||
@@ -1450,7 +1432,7 @@ static const struct ethtool_ops pcnet32_ethtool_ops = { | |||
1450 | .set_ringparam = pcnet32_set_ringparam, | 1432 | .set_ringparam = pcnet32_set_ringparam, |
1451 | .get_strings = pcnet32_get_strings, | 1433 | .get_strings = pcnet32_get_strings, |
1452 | .self_test = pcnet32_ethtool_test, | 1434 | .self_test = pcnet32_ethtool_test, |
1453 | .phys_id = pcnet32_phys_id, | 1435 | .set_phys_id = pcnet32_set_phys_id, |
1454 | .get_regs_len = pcnet32_get_regs_len, | 1436 | .get_regs_len = pcnet32_get_regs_len, |
1455 | .get_regs = pcnet32_get_regs, | 1437 | .get_regs = pcnet32_get_regs, |
1456 | .get_sset_count = pcnet32_get_sset_count, | 1438 | .get_sset_count = pcnet32_get_sset_count, |