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 | } |
