diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-04-25 13:58:51 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-04-26 06:19:45 -0400 |
commit | d27ed38765d6e01eaab443a7909f53a37f090e99 (patch) | |
tree | d4abd4a0364d0ba971dbde615cde8165d10bb905 /drivers/net/sky2.c | |
parent | 734cbc363b159caee158d5a83408c72d98bcacf0 (diff) |
[PATCH] sky2: add fake idle irq timer
Add an fake NAPI schedule once a second. This is an attempt to work around
for broken configurations with edge-triggered interrupts.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 618fde8622ca..6673ddf763a4 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -2086,6 +2086,20 @@ static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port, | |||
2086 | } | 2086 | } |
2087 | } | 2087 | } |
2088 | 2088 | ||
2089 | /* If idle then force a fake soft NAPI poll once a second | ||
2090 | * to work around cases where sharing an edge triggered interrupt. | ||
2091 | */ | ||
2092 | static void sky2_idle(unsigned long arg) | ||
2093 | { | ||
2094 | struct net_device *dev = (struct net_device *) arg; | ||
2095 | |||
2096 | local_irq_disable(); | ||
2097 | if (__netif_rx_schedule_prep(dev)) | ||
2098 | __netif_rx_schedule(dev); | ||
2099 | local_irq_enable(); | ||
2100 | } | ||
2101 | |||
2102 | |||
2089 | static int sky2_poll(struct net_device *dev0, int *budget) | 2103 | static int sky2_poll(struct net_device *dev0, int *budget) |
2090 | { | 2104 | { |
2091 | struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; | 2105 | struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; |
@@ -2134,6 +2148,8 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
2134 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | 2148 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); |
2135 | } | 2149 | } |
2136 | 2150 | ||
2151 | mod_timer(&hw->idle_timer, jiffies + HZ); | ||
2152 | |||
2137 | local_irq_disable(); | 2153 | local_irq_disable(); |
2138 | __netif_rx_complete(dev0); | 2154 | __netif_rx_complete(dev0); |
2139 | 2155 | ||
@@ -3288,6 +3304,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
3288 | 3304 | ||
3289 | sky2_write32(hw, B0_IMSK, Y2_IS_BASE); | 3305 | sky2_write32(hw, B0_IMSK, Y2_IS_BASE); |
3290 | 3306 | ||
3307 | setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) dev); | ||
3308 | |||
3291 | pci_set_drvdata(pdev, hw); | 3309 | pci_set_drvdata(pdev, hw); |
3292 | 3310 | ||
3293 | return 0; | 3311 | return 0; |
@@ -3323,13 +3341,15 @@ static void __devexit sky2_remove(struct pci_dev *pdev) | |||
3323 | if (!hw) | 3341 | if (!hw) |
3324 | return; | 3342 | return; |
3325 | 3343 | ||
3344 | del_timer_sync(&hw->idle_timer); | ||
3345 | |||
3346 | sky2_write32(hw, B0_IMSK, 0); | ||
3326 | dev0 = hw->dev[0]; | 3347 | dev0 = hw->dev[0]; |
3327 | dev1 = hw->dev[1]; | 3348 | dev1 = hw->dev[1]; |
3328 | if (dev1) | 3349 | if (dev1) |
3329 | unregister_netdev(dev1); | 3350 | unregister_netdev(dev1); |
3330 | unregister_netdev(dev0); | 3351 | unregister_netdev(dev0); |
3331 | 3352 | ||
3332 | sky2_write32(hw, B0_IMSK, 0); | ||
3333 | sky2_set_power_state(hw, PCI_D3hot); | 3353 | sky2_set_power_state(hw, PCI_D3hot); |
3334 | sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); | 3354 | sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); |
3335 | sky2_write8(hw, B0_CTST, CS_RST_SET); | 3355 | sky2_write8(hw, B0_CTST, CS_RST_SET); |