diff options
Diffstat (limited to 'drivers/net/3c59x.c')
-rw-r--r-- | drivers/net/3c59x.c | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index c754d88e5ec9..179871d9e71f 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -633,7 +633,11 @@ struct vortex_private { | |||
633 | open:1, | 633 | open:1, |
634 | medialock:1, | 634 | medialock:1, |
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 */ | ||
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 | */ | ||
637 | int drv_flags; | 641 | int drv_flags; |
638 | u16 status_enable; | 642 | u16 status_enable; |
639 | u16 intr_enable; | 643 | u16 intr_enable; |
@@ -646,7 +650,7 @@ struct vortex_private { | |||
646 | u16 io_size; /* Size of PCI region (for release_region) */ | 650 | u16 io_size; /* Size of PCI region (for release_region) */ |
647 | 651 | ||
648 | /* Serialises access to hardware other than MII and variables below. | 652 | /* Serialises access to hardware other than MII and variables below. |
649 | * The lock hierarchy is rtnl_lock > lock > mii_lock > window_lock. */ | 653 | * The lock hierarchy is rtnl_lock > {lock, mii_lock} > window_lock. */ |
650 | spinlock_t lock; | 654 | spinlock_t lock; |
651 | 655 | ||
652 | spinlock_t mii_lock; /* Serialises access to MII */ | 656 | spinlock_t mii_lock; /* Serialises access to MII */ |
@@ -1993,10 +1997,9 @@ vortex_error(struct net_device *dev, int status) | |||
1993 | } | 1997 | } |
1994 | } | 1998 | } |
1995 | 1999 | ||
1996 | if (status & RxEarly) { /* Rx early is unused. */ | 2000 | if (status & RxEarly) /* Rx early is unused. */ |
1997 | vortex_rx(dev); | ||
1998 | iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD); | 2001 | iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD); |
1999 | } | 2002 | |
2000 | if (status & StatsFull) { /* Empty statistics. */ | 2003 | if (status & StatsFull) { /* Empty statistics. */ |
2001 | static int DoneDidThat; | 2004 | static int DoneDidThat; |
2002 | if (vortex_debug > 4) | 2005 | if (vortex_debug > 4) |
@@ -2133,6 +2136,15 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2133 | dev->name, vp->cur_tx); | 2136 | dev->name, vp->cur_tx); |
2134 | } | 2137 | } |
2135 | 2138 | ||
2139 | /* | ||
2140 | * We can't allow a recursion from our interrupt handler back into the | ||
2141 | * tx routine, as they take the same spin lock, and that causes | ||
2142 | * deadlock. Just return NETDEV_TX_BUSY and let the stack try again in | ||
2143 | * a bit | ||
2144 | */ | ||
2145 | if (vp->handling_irq) | ||
2146 | return NETDEV_TX_BUSY; | ||
2147 | |||
2136 | if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) { | 2148 | if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) { |
2137 | if (vortex_debug > 0) | 2149 | if (vortex_debug > 0) |
2138 | pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n", | 2150 | pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n", |
@@ -2288,7 +2300,12 @@ vortex_interrupt(int irq, void *dev_id) | |||
2288 | if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) { | 2300 | if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) { |
2289 | if (status == 0xffff) | 2301 | if (status == 0xffff) |
2290 | break; | 2302 | break; |
2303 | if (status & RxEarly) | ||
2304 | vortex_rx(dev); | ||
2305 | spin_unlock(&vp->window_lock); | ||
2291 | vortex_error(dev, status); | 2306 | vortex_error(dev, status); |
2307 | spin_lock(&vp->window_lock); | ||
2308 | window_set(vp, 7); | ||
2292 | } | 2309 | } |
2293 | 2310 | ||
2294 | if (--work_done < 0) { | 2311 | if (--work_done < 0) { |
@@ -2335,11 +2352,13 @@ boomerang_interrupt(int irq, void *dev_id) | |||
2335 | 2352 | ||
2336 | ioaddr = vp->ioaddr; | 2353 | ioaddr = vp->ioaddr; |
2337 | 2354 | ||
2355 | |||
2338 | /* | 2356 | /* |
2339 | * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout | 2357 | * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout |
2340 | * and boomerang_start_xmit | 2358 | * and boomerang_start_xmit |
2341 | */ | 2359 | */ |
2342 | spin_lock(&vp->lock); | 2360 | spin_lock(&vp->lock); |
2361 | vp->handling_irq = 1; | ||
2343 | 2362 | ||
2344 | status = ioread16(ioaddr + EL3_STATUS); | 2363 | status = ioread16(ioaddr + EL3_STATUS); |
2345 | 2364 | ||
@@ -2447,6 +2466,7 @@ boomerang_interrupt(int irq, void *dev_id) | |||
2447 | pr_debug("%s: exiting interrupt, status %4.4x.\n", | 2466 | pr_debug("%s: exiting interrupt, status %4.4x.\n", |
2448 | dev->name, status); | 2467 | dev->name, status); |
2449 | handler_exit: | 2468 | handler_exit: |
2469 | vp->handling_irq = 0; | ||
2450 | spin_unlock(&vp->lock); | 2470 | spin_unlock(&vp->lock); |
2451 | return IRQ_HANDLED; | 2471 | return IRQ_HANDLED; |
2452 | } | 2472 | } |
@@ -2922,28 +2942,31 @@ static void vortex_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
2922 | { | 2942 | { |
2923 | struct vortex_private *vp = netdev_priv(dev); | 2943 | struct vortex_private *vp = netdev_priv(dev); |
2924 | 2944 | ||
2925 | spin_lock_irq(&vp->lock); | 2945 | if (!VORTEX_PCI(vp)) |
2946 | return; | ||
2947 | |||
2926 | wol->supported = WAKE_MAGIC; | 2948 | wol->supported = WAKE_MAGIC; |
2927 | 2949 | ||
2928 | wol->wolopts = 0; | 2950 | wol->wolopts = 0; |
2929 | if (vp->enable_wol) | 2951 | if (vp->enable_wol) |
2930 | wol->wolopts |= WAKE_MAGIC; | 2952 | wol->wolopts |= WAKE_MAGIC; |
2931 | spin_unlock_irq(&vp->lock); | ||
2932 | } | 2953 | } |
2933 | 2954 | ||
2934 | 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) |
2935 | { | 2956 | { |
2936 | 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 | |||
2937 | if (wol->wolopts & ~WAKE_MAGIC) | 2962 | if (wol->wolopts & ~WAKE_MAGIC) |
2938 | return -EINVAL; | 2963 | return -EINVAL; |
2939 | 2964 | ||
2940 | spin_lock_irq(&vp->lock); | ||
2941 | if (wol->wolopts & WAKE_MAGIC) | 2965 | if (wol->wolopts & WAKE_MAGIC) |
2942 | vp->enable_wol = 1; | 2966 | vp->enable_wol = 1; |
2943 | else | 2967 | else |
2944 | vp->enable_wol = 0; | 2968 | vp->enable_wol = 0; |
2945 | acpi_set_WOL(dev); | 2969 | acpi_set_WOL(dev); |
2946 | spin_unlock_irq(&vp->lock); | ||
2947 | 2970 | ||
2948 | return 0; | 2971 | return 0; |
2949 | } | 2972 | } |
@@ -2971,7 +2994,6 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
2971 | { | 2994 | { |
2972 | int err; | 2995 | int err; |
2973 | struct vortex_private *vp = netdev_priv(dev); | 2996 | struct vortex_private *vp = netdev_priv(dev); |
2974 | unsigned long flags; | ||
2975 | pci_power_t state = 0; | 2997 | pci_power_t state = 0; |
2976 | 2998 | ||
2977 | if(VORTEX_PCI(vp)) | 2999 | if(VORTEX_PCI(vp)) |
@@ -2981,9 +3003,7 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
2981 | 3003 | ||
2982 | if(state != 0) | 3004 | if(state != 0) |
2983 | pci_set_power_state(VORTEX_PCI(vp), PCI_D0); | 3005 | pci_set_power_state(VORTEX_PCI(vp), PCI_D0); |
2984 | spin_lock_irqsave(&vp->lock, flags); | ||
2985 | err = generic_mii_ioctl(&vp->mii, if_mii(rq), cmd, NULL); | 3006 | err = generic_mii_ioctl(&vp->mii, if_mii(rq), cmd, NULL); |
2986 | spin_unlock_irqrestore(&vp->lock, flags); | ||
2987 | if(state != 0) | 3007 | if(state != 0) |
2988 | pci_set_power_state(VORTEX_PCI(vp), state); | 3008 | pci_set_power_state(VORTEX_PCI(vp), state); |
2989 | 3009 | ||
@@ -3188,6 +3208,9 @@ static void acpi_set_WOL(struct net_device *dev) | |||
3188 | return; | 3208 | return; |
3189 | } | 3209 | } |
3190 | 3210 | ||
3211 | if (VORTEX_PCI(vp)->current_state < PCI_D3hot) | ||
3212 | return; | ||
3213 | |||
3191 | /* Change the power state to D3; RxEnable doesn't take effect. */ | 3214 | /* Change the power state to D3; RxEnable doesn't take effect. */ |
3192 | pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot); | 3215 | pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot); |
3193 | } | 3216 | } |