diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/sky2.c | 22 | ||||
-rw-r--r-- | drivers/net/sky2.h | 2 |
2 files changed, 23 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); |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 89dd18cd12f0..b026f5653f04 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -1880,6 +1880,8 @@ struct sky2_hw { | |||
1880 | struct sky2_status_le *st_le; | 1880 | struct sky2_status_le *st_le; |
1881 | u32 st_idx; | 1881 | u32 st_idx; |
1882 | dma_addr_t st_dma; | 1882 | dma_addr_t st_dma; |
1883 | |||
1884 | struct timer_list idle_timer; | ||
1883 | int msi_detected; | 1885 | int msi_detected; |
1884 | wait_queue_head_t msi_wait; | 1886 | wait_queue_head_t msi_wait; |
1885 | }; | 1887 | }; |