aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/3c59x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/3c59x.c')
-rw-r--r--drivers/net/3c59x.c27
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
2947static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 2955static 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 }