diff options
Diffstat (limited to 'drivers/net/3c59x.c')
-rw-r--r-- | drivers/net/3c59x.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index a045559c81cf..179871d9e71f 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -635,6 +635,9 @@ struct vortex_private { | |||
635 | must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ | 635 | must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ |
636 | large_frames:1, /* accept large frames */ | 636 | large_frames:1, /* accept large frames */ |
637 | handling_irq:1; /* private in_irq indicator */ | 637 | handling_irq:1; /* private in_irq indicator */ |
638 | /* {get|set}_wol operations are already serialized by rtnl. | ||
639 | * no additional locking is required for the enable_wol and acpi_set_WOL() | ||
640 | */ | ||
638 | int drv_flags; | 641 | int drv_flags; |
639 | u16 status_enable; | 642 | u16 status_enable; |
640 | u16 intr_enable; | 643 | u16 intr_enable; |
@@ -1994,10 +1997,9 @@ vortex_error(struct net_device *dev, int status) | |||
1994 | } | 1997 | } |
1995 | } | 1998 | } |
1996 | 1999 | ||
1997 | if (status & RxEarly) { /* Rx early is unused. */ | 2000 | if (status & RxEarly) /* Rx early is unused. */ |
1998 | vortex_rx(dev); | ||
1999 | iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD); | 2001 | iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD); |
2000 | } | 2002 | |
2001 | if (status & StatsFull) { /* Empty statistics. */ | 2003 | if (status & StatsFull) { /* Empty statistics. */ |
2002 | static int DoneDidThat; | 2004 | static int DoneDidThat; |
2003 | if (vortex_debug > 4) | 2005 | if (vortex_debug > 4) |
@@ -2298,7 +2300,12 @@ vortex_interrupt(int irq, void *dev_id) | |||
2298 | if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) { | 2300 | if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) { |
2299 | if (status == 0xffff) | 2301 | if (status == 0xffff) |
2300 | break; | 2302 | break; |
2303 | if (status & RxEarly) | ||
2304 | vortex_rx(dev); | ||
2305 | spin_unlock(&vp->window_lock); | ||
2301 | vortex_error(dev, status); | 2306 | vortex_error(dev, status); |
2307 | spin_lock(&vp->window_lock); | ||
2308 | window_set(vp, 7); | ||
2302 | } | 2309 | } |
2303 | 2310 | ||
2304 | if (--work_done < 0) { | 2311 | if (--work_done < 0) { |
@@ -2935,28 +2942,31 @@ static void vortex_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
2935 | { | 2942 | { |
2936 | struct vortex_private *vp = netdev_priv(dev); | 2943 | struct vortex_private *vp = netdev_priv(dev); |
2937 | 2944 | ||
2938 | spin_lock_irq(&vp->lock); | 2945 | if (!VORTEX_PCI(vp)) |
2946 | return; | ||
2947 | |||
2939 | wol->supported = WAKE_MAGIC; | 2948 | wol->supported = WAKE_MAGIC; |
2940 | 2949 | ||
2941 | wol->wolopts = 0; | 2950 | wol->wolopts = 0; |
2942 | if (vp->enable_wol) | 2951 | if (vp->enable_wol) |
2943 | wol->wolopts |= WAKE_MAGIC; | 2952 | wol->wolopts |= WAKE_MAGIC; |
2944 | spin_unlock_irq(&vp->lock); | ||
2945 | } | 2953 | } |
2946 | 2954 | ||
2947 | static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 2955 | static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
2948 | { | 2956 | { |
2949 | struct vortex_private *vp = netdev_priv(dev); | 2957 | struct vortex_private *vp = netdev_priv(dev); |
2958 | |||
2959 | if (!VORTEX_PCI(vp)) | ||
2960 | return -EOPNOTSUPP; | ||
2961 | |||
2950 | if (wol->wolopts & ~WAKE_MAGIC) | 2962 | if (wol->wolopts & ~WAKE_MAGIC) |
2951 | return -EINVAL; | 2963 | return -EINVAL; |
2952 | 2964 | ||
2953 | spin_lock_irq(&vp->lock); | ||
2954 | if (wol->wolopts & WAKE_MAGIC) | 2965 | if (wol->wolopts & WAKE_MAGIC) |
2955 | vp->enable_wol = 1; | 2966 | vp->enable_wol = 1; |
2956 | else | 2967 | else |
2957 | vp->enable_wol = 0; | 2968 | vp->enable_wol = 0; |
2958 | acpi_set_WOL(dev); | 2969 | acpi_set_WOL(dev); |
2959 | spin_unlock_irq(&vp->lock); | ||
2960 | 2970 | ||
2961 | return 0; | 2971 | return 0; |
2962 | } | 2972 | } |
@@ -3198,6 +3208,9 @@ static void acpi_set_WOL(struct net_device *dev) | |||
3198 | return; | 3208 | return; |
3199 | } | 3209 | } |
3200 | 3210 | ||
3211 | if (VORTEX_PCI(vp)->current_state < PCI_D3hot) | ||
3212 | return; | ||
3213 | |||
3201 | /* Change the power state to D3; RxEnable doesn't take effect. */ | 3214 | /* Change the power state to D3; RxEnable doesn't take effect. */ |
3202 | pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot); | 3215 | pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot); |
3203 | } | 3216 | } |