aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-04-26 06:21:31 -0400
committerJeff Garzik <jeff@garzik.org>2006-04-26 06:21:31 -0400
commit9f1da23b631f92393f58f664348ffc5faeaddeb3 (patch)
tree68c7bf9c0f4b11117cf6b3cde5fa5c4f2929088a /drivers/net
parent00355cd938bac2a6006efa140352958784431f1f (diff)
parent86a0f04387bfa814618bf0c2c8b203899c4fa5d2 (diff)
Merge branch 'upstream-fixes' into upstream
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/forcedeth.c79
-rw-r--r--drivers/net/sky2.c52
-rw-r--r--drivers/net/sky2.h2
3 files changed, 110 insertions, 23 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 7627a75f4f7c..9788b1ef2e7d 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -105,6 +105,7 @@
105 * 0.50: 20 Jan 2006: Add 8021pq tagging support. 105 * 0.50: 20 Jan 2006: Add 8021pq tagging support.
106 * 0.51: 20 Jan 2006: Add 64bit consistent memory allocation for rings. 106 * 0.51: 20 Jan 2006: Add 64bit consistent memory allocation for rings.
107 * 0.52: 20 Jan 2006: Add MSI/MSIX support. 107 * 0.52: 20 Jan 2006: Add MSI/MSIX support.
108 * 0.53: 19 Mar 2006: Fix init from low power mode and add hw reset.
108 * 109 *
109 * Known bugs: 110 * Known bugs:
110 * We suspect that on some hardware no TX done interrupts are generated. 111 * We suspect that on some hardware no TX done interrupts are generated.
@@ -116,7 +117,7 @@
116 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few 117 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
117 * superfluous timer interrupts from the nic. 118 * superfluous timer interrupts from the nic.
118 */ 119 */
119#define FORCEDETH_VERSION "0.52" 120#define FORCEDETH_VERSION "0.53"
120#define DRV_NAME "forcedeth" 121#define DRV_NAME "forcedeth"
121 122
122#include <linux/module.h> 123#include <linux/module.h>
@@ -160,6 +161,7 @@
160#define DEV_HAS_VLAN 0x0020 /* device supports vlan tagging and striping */ 161#define DEV_HAS_VLAN 0x0020 /* device supports vlan tagging and striping */
161#define DEV_HAS_MSI 0x0040 /* device supports MSI */ 162#define DEV_HAS_MSI 0x0040 /* device supports MSI */
162#define DEV_HAS_MSI_X 0x0080 /* device supports MSI-X */ 163#define DEV_HAS_MSI_X 0x0080 /* device supports MSI-X */
164#define DEV_HAS_POWER_CNTRL 0x0100 /* device supports power savings */
163 165
164enum { 166enum {
165 NvRegIrqStatus = 0x000, 167 NvRegIrqStatus = 0x000,
@@ -203,6 +205,8 @@ enum {
203#define NVREG_MISC1_HD 0x02 205#define NVREG_MISC1_HD 0x02
204#define NVREG_MISC1_FORCE 0x3b0f3c 206#define NVREG_MISC1_FORCE 0x3b0f3c
205 207
208 NvRegMacReset = 0x3c,
209#define NVREG_MAC_RESET_ASSERT 0x0F3
206 NvRegTransmitterControl = 0x084, 210 NvRegTransmitterControl = 0x084,
207#define NVREG_XMITCTL_START 0x01 211#define NVREG_XMITCTL_START 0x01
208 NvRegTransmitterStatus = 0x088, 212 NvRegTransmitterStatus = 0x088,
@@ -326,6 +330,10 @@ enum {
326 NvRegMSIXMap0 = 0x3e0, 330 NvRegMSIXMap0 = 0x3e0,
327 NvRegMSIXMap1 = 0x3e4, 331 NvRegMSIXMap1 = 0x3e4,
328 NvRegMSIXIrqStatus = 0x3f0, 332 NvRegMSIXIrqStatus = 0x3f0,
333
334 NvRegPowerState2 = 0x600,
335#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F11
336#define NVREG_POWERSTATE2_POWERUP_REV_A3 0x0001
329}; 337};
330 338
331/* Big endian: should work, but is untested */ 339/* Big endian: should work, but is untested */
@@ -414,7 +422,8 @@ typedef union _ring_type {
414#define NV_RX3_VLAN_TAG_MASK (0x0000FFFF) 422#define NV_RX3_VLAN_TAG_MASK (0x0000FFFF)
415 423
416/* Miscelaneous hardware related defines: */ 424/* Miscelaneous hardware related defines: */
417#define NV_PCI_REGSZ 0x270 425#define NV_PCI_REGSZ_VER1 0x270
426#define NV_PCI_REGSZ_VER2 0x604
418 427
419/* various timeout delays: all in usec */ 428/* various timeout delays: all in usec */
420#define NV_TXRX_RESET_DELAY 4 429#define NV_TXRX_RESET_DELAY 4
@@ -431,6 +440,7 @@ typedef union _ring_type {
431#define NV_MIIBUSY_DELAY 50 440#define NV_MIIBUSY_DELAY 50
432#define NV_MIIPHY_DELAY 10 441#define NV_MIIPHY_DELAY 10
433#define NV_MIIPHY_DELAYMAX 10000 442#define NV_MIIPHY_DELAYMAX 10000
443#define NV_MAC_RESET_DELAY 64
434 444
435#define NV_WAKEUPPATTERNS 5 445#define NV_WAKEUPPATTERNS 5
436#define NV_WAKEUPMASKENTRIES 4 446#define NV_WAKEUPMASKENTRIES 4
@@ -552,6 +562,8 @@ struct fe_priv {
552 u32 desc_ver; 562 u32 desc_ver;
553 u32 txrxctl_bits; 563 u32 txrxctl_bits;
554 u32 vlanctl_bits; 564 u32 vlanctl_bits;
565 u32 driver_data;
566 u32 register_size;
555 567
556 void __iomem *base; 568 void __iomem *base;
557 569
@@ -919,6 +931,24 @@ static void nv_txrx_reset(struct net_device *dev)
919 pci_push(base); 931 pci_push(base);
920} 932}
921 933
934static void nv_mac_reset(struct net_device *dev)
935{
936 struct fe_priv *np = netdev_priv(dev);
937 u8 __iomem *base = get_hwbase(dev);
938
939 dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name);
940 writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl);
941 pci_push(base);
942 writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset);
943 pci_push(base);
944 udelay(NV_MAC_RESET_DELAY);
945 writel(0, base + NvRegMacReset);
946 pci_push(base);
947 udelay(NV_MAC_RESET_DELAY);
948 writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
949 pci_push(base);
950}
951
922/* 952/*
923 * nv_get_stats: dev->get_stats function 953 * nv_get_stats: dev->get_stats function
924 * Get latest stats value from the nic. 954 * Get latest stats value from the nic.
@@ -1331,7 +1361,7 @@ static void nv_tx_timeout(struct net_device *dev)
1331 dev->name, (unsigned long)np->ring_addr, 1361 dev->name, (unsigned long)np->ring_addr,
1332 np->next_tx, np->nic_tx); 1362 np->next_tx, np->nic_tx);
1333 printk(KERN_INFO "%s: Dumping tx registers\n", dev->name); 1363 printk(KERN_INFO "%s: Dumping tx registers\n", dev->name);
1334 for (i=0;i<0x400;i+= 32) { 1364 for (i=0;i<=np->register_size;i+= 32) {
1335 printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", 1365 printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
1336 i, 1366 i,
1337 readl(base + i + 0), readl(base + i + 4), 1367 readl(base + i + 0), readl(base + i + 4),
@@ -2488,11 +2518,11 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
2488} 2518}
2489 2519
2490#define FORCEDETH_REGS_VER 1 2520#define FORCEDETH_REGS_VER 1
2491#define FORCEDETH_REGS_SIZE 0x400 /* 256 32-bit registers */
2492 2521
2493static int nv_get_regs_len(struct net_device *dev) 2522static int nv_get_regs_len(struct net_device *dev)
2494{ 2523{
2495 return FORCEDETH_REGS_SIZE; 2524 struct fe_priv *np = netdev_priv(dev);
2525 return np->register_size;
2496} 2526}
2497 2527
2498static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf) 2528static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf)
@@ -2504,7 +2534,7 @@ static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void
2504 2534
2505 regs->version = FORCEDETH_REGS_VER; 2535 regs->version = FORCEDETH_REGS_VER;
2506 spin_lock_irq(&np->lock); 2536 spin_lock_irq(&np->lock);
2507 for (i=0;i<FORCEDETH_REGS_SIZE/sizeof(u32);i++) 2537 for (i = 0;i <= np->register_size/sizeof(u32); i++)
2508 rbuf[i] = readl(base + i*sizeof(u32)); 2538 rbuf[i] = readl(base + i*sizeof(u32));
2509 spin_unlock_irq(&np->lock); 2539 spin_unlock_irq(&np->lock);
2510} 2540}
@@ -2608,6 +2638,8 @@ static int nv_open(struct net_device *dev)
2608 dprintk(KERN_DEBUG "nv_open: begin\n"); 2638 dprintk(KERN_DEBUG "nv_open: begin\n");
2609 2639
2610 /* 1) erase previous misconfiguration */ 2640 /* 1) erase previous misconfiguration */
2641 if (np->driver_data & DEV_HAS_POWER_CNTRL)
2642 nv_mac_reset(dev);
2611 /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */ 2643 /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */
2612 writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA); 2644 writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA);
2613 writel(0, base + NvRegMulticastAddrB); 2645 writel(0, base + NvRegMulticastAddrB);
@@ -2878,6 +2910,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
2878 unsigned long addr; 2910 unsigned long addr;
2879 u8 __iomem *base; 2911 u8 __iomem *base;
2880 int err, i; 2912 int err, i;
2913 u32 powerstate;
2881 2914
2882 dev = alloc_etherdev(sizeof(struct fe_priv)); 2915 dev = alloc_etherdev(sizeof(struct fe_priv));
2883 err = -ENOMEM; 2916 err = -ENOMEM;
@@ -2910,6 +2943,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
2910 if (err < 0) 2943 if (err < 0)
2911 goto out_disable; 2944 goto out_disable;
2912 2945
2946 if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL))
2947 np->register_size = NV_PCI_REGSZ_VER2;
2948 else
2949 np->register_size = NV_PCI_REGSZ_VER1;
2950
2913 err = -EINVAL; 2951 err = -EINVAL;
2914 addr = 0; 2952 addr = 0;
2915 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 2953 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
@@ -2918,7 +2956,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
2918 pci_resource_len(pci_dev, i), 2956 pci_resource_len(pci_dev, i),
2919 pci_resource_flags(pci_dev, i)); 2957 pci_resource_flags(pci_dev, i));
2920 if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM && 2958 if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM &&
2921 pci_resource_len(pci_dev, i) >= NV_PCI_REGSZ) { 2959 pci_resource_len(pci_dev, i) >= np->register_size) {
2922 addr = pci_resource_start(pci_dev, i); 2960 addr = pci_resource_start(pci_dev, i);
2923 break; 2961 break;
2924 } 2962 }
@@ -2929,6 +2967,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
2929 goto out_relreg; 2967 goto out_relreg;
2930 } 2968 }
2931 2969
2970 /* copy of driver data */
2971 np->driver_data = id->driver_data;
2972
2932 /* handle different descriptor versions */ 2973 /* handle different descriptor versions */
2933 if (id->driver_data & DEV_HAS_HIGH_DMA) { 2974 if (id->driver_data & DEV_HAS_HIGH_DMA) {
2934 /* packet format 3: supports 40-bit addressing */ 2975 /* packet format 3: supports 40-bit addressing */
@@ -2986,7 +3027,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
2986 } 3027 }
2987 3028
2988 err = -ENOMEM; 3029 err = -ENOMEM;
2989 np->base = ioremap(addr, NV_PCI_REGSZ); 3030 np->base = ioremap(addr, np->register_size);
2990 if (!np->base) 3031 if (!np->base)
2991 goto out_relreg; 3032 goto out_relreg;
2992 dev->base_addr = (unsigned long)np->base; 3033 dev->base_addr = (unsigned long)np->base;
@@ -3062,6 +3103,20 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
3062 writel(0, base + NvRegWakeUpFlags); 3103 writel(0, base + NvRegWakeUpFlags);
3063 np->wolenabled = 0; 3104 np->wolenabled = 0;
3064 3105
3106 if (id->driver_data & DEV_HAS_POWER_CNTRL) {
3107 u8 revision_id;
3108 pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id);
3109
3110 /* take phy and nic out of low power mode */
3111 powerstate = readl(base + NvRegPowerState2);
3112 powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK;
3113 if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_12 ||
3114 id->device == PCI_DEVICE_ID_NVIDIA_NVENET_13) &&
3115 revision_id >= 0xA3)
3116 powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3;
3117 writel(powerstate, base + NvRegPowerState2);
3118 }
3119
3065 if (np->desc_ver == DESC_VER_1) { 3120 if (np->desc_ver == DESC_VER_1) {
3066 np->tx_flags = NV_TX_VALID; 3121 np->tx_flags = NV_TX_VALID;
3067 } else { 3122 } else {
@@ -3223,19 +3278,19 @@ static struct pci_device_id pci_tbl[] = {
3223 }, 3278 },
3224 { /* MCP51 Ethernet Controller */ 3279 { /* MCP51 Ethernet Controller */
3225 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12), 3280 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12),
3226 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, 3281 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL,
3227 }, 3282 },
3228 { /* MCP51 Ethernet Controller */ 3283 { /* MCP51 Ethernet Controller */
3229 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13), 3284 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13),
3230 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, 3285 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL,
3231 }, 3286 },
3232 { /* MCP55 Ethernet Controller */ 3287 { /* MCP55 Ethernet Controller */
3233 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), 3288 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
3234 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X, 3289 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL,
3235 }, 3290 },
3236 { /* MCP55 Ethernet Controller */ 3291 { /* MCP55 Ethernet Controller */
3237 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), 3292 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
3238 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X, 3293 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL,
3239 }, 3294 },
3240 {0,}, 3295 {0,},
3241}; 3296};
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 67b0eab16589..227df9876a2c 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -51,7 +51,7 @@
51#include "sky2.h" 51#include "sky2.h"
52 52
53#define DRV_NAME "sky2" 53#define DRV_NAME "sky2"
54#define DRV_VERSION "1.1" 54#define DRV_VERSION "1.2"
55#define PFX DRV_NAME " " 55#define PFX DRV_NAME " "
56 56
57/* 57/*
@@ -925,8 +925,7 @@ static inline struct sk_buff *sky2_alloc_skb(unsigned int size, gfp_t gfp_mask)
925 skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask); 925 skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask);
926 if (likely(skb)) { 926 if (likely(skb)) {
927 unsigned long p = (unsigned long) skb->data; 927 unsigned long p = (unsigned long) skb->data;
928 skb_reserve(skb, 928 skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
929 ((p + RX_SKB_ALIGN - 1) & ~(RX_SKB_ALIGN - 1)) - p);
930 } 929 }
931 930
932 return skb; 931 return skb;
@@ -1686,13 +1685,12 @@ static void sky2_tx_timeout(struct net_device *dev)
1686} 1685}
1687 1686
1688 1687
1689#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
1690/* Want receive buffer size to be multiple of 64 bits 1688/* Want receive buffer size to be multiple of 64 bits
1691 * and incl room for vlan and truncation 1689 * and incl room for vlan and truncation
1692 */ 1690 */
1693static inline unsigned sky2_buf_size(int mtu) 1691static inline unsigned sky2_buf_size(int mtu)
1694{ 1692{
1695 return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; 1693 return ALIGN(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8;
1696} 1694}
1697 1695
1698static int sky2_change_mtu(struct net_device *dev, int new_mtu) 1696static int sky2_change_mtu(struct net_device *dev, int new_mtu)
@@ -2086,6 +2084,20 @@ static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port,
2086 } 2084 }
2087} 2085}
2088 2086
2087/* If idle then force a fake soft NAPI poll once a second
2088 * to work around cases where sharing an edge triggered interrupt.
2089 */
2090static void sky2_idle(unsigned long arg)
2091{
2092 struct net_device *dev = (struct net_device *) arg;
2093
2094 local_irq_disable();
2095 if (__netif_rx_schedule_prep(dev))
2096 __netif_rx_schedule(dev);
2097 local_irq_enable();
2098}
2099
2100
2089static int sky2_poll(struct net_device *dev0, int *budget) 2101static int sky2_poll(struct net_device *dev0, int *budget)
2090{ 2102{
2091 struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; 2103 struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
@@ -2093,6 +2105,7 @@ static int sky2_poll(struct net_device *dev0, int *budget)
2093 int work_done = 0; 2105 int work_done = 0;
2094 u32 status = sky2_read32(hw, B0_Y2_SP_EISR); 2106 u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
2095 2107
2108 restart_poll:
2096 if (unlikely(status & ~Y2_IS_STAT_BMU)) { 2109 if (unlikely(status & ~Y2_IS_STAT_BMU)) {
2097 if (status & Y2_IS_HW_ERR) 2110 if (status & Y2_IS_HW_ERR)
2098 sky2_hw_intr(hw); 2111 sky2_hw_intr(hw);
@@ -2123,7 +2136,7 @@ static int sky2_poll(struct net_device *dev0, int *budget)
2123 } 2136 }
2124 2137
2125 if (status & Y2_IS_STAT_BMU) { 2138 if (status & Y2_IS_STAT_BMU) {
2126 work_done = sky2_status_intr(hw, work_limit); 2139 work_done += sky2_status_intr(hw, work_limit - work_done);
2127 *budget -= work_done; 2140 *budget -= work_done;
2128 dev0->quota -= work_done; 2141 dev0->quota -= work_done;
2129 2142
@@ -2133,9 +2146,24 @@ static int sky2_poll(struct net_device *dev0, int *budget)
2133 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); 2146 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
2134 } 2147 }
2135 2148
2136 netif_rx_complete(dev0); 2149 mod_timer(&hw->idle_timer, jiffies + HZ);
2150
2151 local_irq_disable();
2152 __netif_rx_complete(dev0);
2137 2153
2138 status = sky2_read32(hw, B0_Y2_SP_LISR); 2154 status = sky2_read32(hw, B0_Y2_SP_LISR);
2155
2156 if (unlikely(status)) {
2157 /* More work pending, try and keep going */
2158 if (__netif_rx_schedule_prep(dev0)) {
2159 __netif_rx_reschedule(dev0, work_done);
2160 status = sky2_read32(hw, B0_Y2_SP_EISR);
2161 local_irq_enable();
2162 goto restart_poll;
2163 }
2164 }
2165
2166 local_irq_enable();
2139 return 0; 2167 return 0;
2140} 2168}
2141 2169
@@ -2153,8 +2181,6 @@ static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs)
2153 prefetch(&hw->st_le[hw->st_idx]); 2181 prefetch(&hw->st_le[hw->st_idx]);
2154 if (likely(__netif_rx_schedule_prep(dev0))) 2182 if (likely(__netif_rx_schedule_prep(dev0)))
2155 __netif_rx_schedule(dev0); 2183 __netif_rx_schedule(dev0);
2156 else
2157 printk(KERN_DEBUG PFX "irq race detected\n");
2158 2184
2159 return IRQ_HANDLED; 2185 return IRQ_HANDLED;
2160} 2186}
@@ -2193,7 +2219,7 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk)
2193} 2219}
2194 2220
2195 2221
2196static int sky2_reset(struct sky2_hw *hw) 2222static int __devinit sky2_reset(struct sky2_hw *hw)
2197{ 2223{
2198 u16 status; 2224 u16 status;
2199 u8 t8, pmd_type; 2225 u8 t8, pmd_type;
@@ -3276,6 +3302,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
3276 3302
3277 sky2_write32(hw, B0_IMSK, Y2_IS_BASE); 3303 sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
3278 3304
3305 setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) dev);
3306
3279 pci_set_drvdata(pdev, hw); 3307 pci_set_drvdata(pdev, hw);
3280 3308
3281 return 0; 3309 return 0;
@@ -3311,13 +3339,15 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
3311 if (!hw) 3339 if (!hw)
3312 return; 3340 return;
3313 3341
3342 del_timer_sync(&hw->idle_timer);
3343
3344 sky2_write32(hw, B0_IMSK, 0);
3314 dev0 = hw->dev[0]; 3345 dev0 = hw->dev[0];
3315 dev1 = hw->dev[1]; 3346 dev1 = hw->dev[1];
3316 if (dev1) 3347 if (dev1)
3317 unregister_netdev(dev1); 3348 unregister_netdev(dev1);
3318 unregister_netdev(dev0); 3349 unregister_netdev(dev0);
3319 3350
3320 sky2_write32(hw, B0_IMSK, 0);
3321 sky2_set_power_state(hw, PCI_D3hot); 3351 sky2_set_power_state(hw, PCI_D3hot);
3322 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); 3352 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
3323 sky2_write8(hw, B0_CTST, CS_RST_SET); 3353 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};