Loading drivers/net/forcedeth.c +67 −12 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ * 0.50: 20 Jan 2006: Add 8021pq tagging support. * 0.51: 20 Jan 2006: Add 64bit consistent memory allocation for rings. * 0.52: 20 Jan 2006: Add MSI/MSIX support. * 0.53: 19 Mar 2006: Fix init from low power mode and add hw reset. * * Known bugs: * We suspect that on some hardware no TX done interrupts are generated. Loading @@ -116,7 +117,7 @@ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * superfluous timer interrupts from the nic. */ #define FORCEDETH_VERSION "0.52" #define FORCEDETH_VERSION "0.53" #define DRV_NAME "forcedeth" #include <linux/module.h> Loading Loading @@ -160,6 +161,7 @@ #define DEV_HAS_VLAN 0x0020 /* device supports vlan tagging and striping */ #define DEV_HAS_MSI 0x0040 /* device supports MSI */ #define DEV_HAS_MSI_X 0x0080 /* device supports MSI-X */ #define DEV_HAS_POWER_CNTRL 0x0100 /* device supports power savings */ enum { NvRegIrqStatus = 0x000, Loading Loading @@ -203,6 +205,8 @@ enum { #define NVREG_MISC1_HD 0x02 #define NVREG_MISC1_FORCE 0x3b0f3c NvRegMacReset = 0x3c, #define NVREG_MAC_RESET_ASSERT 0x0F3 NvRegTransmitterControl = 0x084, #define NVREG_XMITCTL_START 0x01 NvRegTransmitterStatus = 0x088, Loading Loading @@ -326,6 +330,10 @@ enum { NvRegMSIXMap0 = 0x3e0, NvRegMSIXMap1 = 0x3e4, NvRegMSIXIrqStatus = 0x3f0, NvRegPowerState2 = 0x600, #define NVREG_POWERSTATE2_POWERUP_MASK 0x0F11 #define NVREG_POWERSTATE2_POWERUP_REV_A3 0x0001 }; /* Big endian: should work, but is untested */ Loading Loading @@ -414,7 +422,8 @@ typedef union _ring_type { #define NV_RX3_VLAN_TAG_MASK (0x0000FFFF) /* Miscelaneous hardware related defines: */ #define NV_PCI_REGSZ 0x270 #define NV_PCI_REGSZ_VER1 0x270 #define NV_PCI_REGSZ_VER2 0x604 /* various timeout delays: all in usec */ #define NV_TXRX_RESET_DELAY 4 Loading @@ -431,6 +440,7 @@ typedef union _ring_type { #define NV_MIIBUSY_DELAY 50 #define NV_MIIPHY_DELAY 10 #define NV_MIIPHY_DELAYMAX 10000 #define NV_MAC_RESET_DELAY 64 #define NV_WAKEUPPATTERNS 5 #define NV_WAKEUPMASKENTRIES 4 Loading Loading @@ -552,6 +562,8 @@ struct fe_priv { u32 desc_ver; u32 txrxctl_bits; u32 vlanctl_bits; u32 driver_data; u32 register_size; void __iomem *base; Loading Loading @@ -919,6 +931,24 @@ static void nv_txrx_reset(struct net_device *dev) pci_push(base); } static void nv_mac_reset(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name); writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl); pci_push(base); writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset); pci_push(base); udelay(NV_MAC_RESET_DELAY); writel(0, base + NvRegMacReset); pci_push(base); udelay(NV_MAC_RESET_DELAY); writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl); pci_push(base); } /* * nv_get_stats: dev->get_stats function * Get latest stats value from the nic. Loading Loading @@ -1331,7 +1361,7 @@ static void nv_tx_timeout(struct net_device *dev) dev->name, (unsigned long)np->ring_addr, np->next_tx, np->nic_tx); printk(KERN_INFO "%s: Dumping tx registers\n", dev->name); for (i=0;i<0x400;i+= 32) { for (i=0;i<=np->register_size;i+= 32) { printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", i, readl(base + i + 0), readl(base + i + 4), Loading Loading @@ -2488,11 +2518,11 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } #define FORCEDETH_REGS_VER 1 #define FORCEDETH_REGS_SIZE 0x400 /* 256 32-bit registers */ static int nv_get_regs_len(struct net_device *dev) { return FORCEDETH_REGS_SIZE; struct fe_priv *np = netdev_priv(dev); return np->register_size; } static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf) Loading @@ -2504,7 +2534,7 @@ static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void regs->version = FORCEDETH_REGS_VER; spin_lock_irq(&np->lock); for (i=0;i<FORCEDETH_REGS_SIZE/sizeof(u32);i++) for (i = 0;i <= np->register_size/sizeof(u32); i++) rbuf[i] = readl(base + i*sizeof(u32)); spin_unlock_irq(&np->lock); } Loading Loading @@ -2608,6 +2638,8 @@ static int nv_open(struct net_device *dev) dprintk(KERN_DEBUG "nv_open: begin\n"); /* 1) erase previous misconfiguration */ if (np->driver_data & DEV_HAS_POWER_CNTRL) nv_mac_reset(dev); /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */ writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA); writel(0, base + NvRegMulticastAddrB); Loading Loading @@ -2878,6 +2910,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i unsigned long addr; u8 __iomem *base; int err, i; u32 powerstate; dev = alloc_etherdev(sizeof(struct fe_priv)); err = -ENOMEM; Loading Loading @@ -2910,6 +2943,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i if (err < 0) goto out_disable; if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL)) np->register_size = NV_PCI_REGSZ_VER2; else np->register_size = NV_PCI_REGSZ_VER1; err = -EINVAL; addr = 0; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { Loading @@ -2918,7 +2956,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i pci_resource_len(pci_dev, i), pci_resource_flags(pci_dev, i)); if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM && pci_resource_len(pci_dev, i) >= NV_PCI_REGSZ) { pci_resource_len(pci_dev, i) >= np->register_size) { addr = pci_resource_start(pci_dev, i); break; } Loading @@ -2929,6 +2967,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i goto out_relreg; } /* copy of driver data */ np->driver_data = id->driver_data; /* handle different descriptor versions */ if (id->driver_data & DEV_HAS_HIGH_DMA) { /* packet format 3: supports 40-bit addressing */ Loading Loading @@ -2986,7 +3027,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i } err = -ENOMEM; np->base = ioremap(addr, NV_PCI_REGSZ); np->base = ioremap(addr, np->register_size); if (!np->base) goto out_relreg; dev->base_addr = (unsigned long)np->base; Loading Loading @@ -3062,6 +3103,20 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i writel(0, base + NvRegWakeUpFlags); np->wolenabled = 0; if (id->driver_data & DEV_HAS_POWER_CNTRL) { u8 revision_id; pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id); /* take phy and nic out of low power mode */ powerstate = readl(base + NvRegPowerState2); powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK; if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_12 || id->device == PCI_DEVICE_ID_NVIDIA_NVENET_13) && revision_id >= 0xA3) powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3; writel(powerstate, base + NvRegPowerState2); } if (np->desc_ver == DESC_VER_1) { np->tx_flags = NV_TX_VALID; } else { Loading Loading @@ -3223,19 +3278,19 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP51 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12), .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL, }, { /* MCP51 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13), .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL, }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), .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, .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, }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), .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, .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, }, {0,}, }; Loading drivers/net/sky2.c +41 −11 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ #include "sky2.h" #define DRV_NAME "sky2" #define DRV_VERSION "1.1" #define DRV_VERSION "1.2" #define PFX DRV_NAME " " /* Loading Loading @@ -925,8 +925,7 @@ static inline struct sk_buff *sky2_alloc_skb(unsigned int size, gfp_t gfp_mask) skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask); if (likely(skb)) { unsigned long p = (unsigned long) skb->data; skb_reserve(skb, ((p + RX_SKB_ALIGN - 1) & ~(RX_SKB_ALIGN - 1)) - p); skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); } return skb; Loading Loading @@ -1686,13 +1685,12 @@ static void sky2_tx_timeout(struct net_device *dev) } #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* Want receive buffer size to be multiple of 64 bits * and incl room for vlan and truncation */ static inline unsigned sky2_buf_size(int mtu) { return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; return ALIGN(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; } static int sky2_change_mtu(struct net_device *dev, int new_mtu) Loading Loading @@ -2086,6 +2084,20 @@ static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port, } } /* If idle then force a fake soft NAPI poll once a second * to work around cases where sharing an edge triggered interrupt. */ static void sky2_idle(unsigned long arg) { struct net_device *dev = (struct net_device *) arg; local_irq_disable(); if (__netif_rx_schedule_prep(dev)) __netif_rx_schedule(dev); local_irq_enable(); } static int sky2_poll(struct net_device *dev0, int *budget) { struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; Loading @@ -2093,6 +2105,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) int work_done = 0; u32 status = sky2_read32(hw, B0_Y2_SP_EISR); restart_poll: if (unlikely(status & ~Y2_IS_STAT_BMU)) { if (status & Y2_IS_HW_ERR) sky2_hw_intr(hw); Loading Loading @@ -2123,7 +2136,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) } if (status & Y2_IS_STAT_BMU) { work_done = sky2_status_intr(hw, work_limit); work_done += sky2_status_intr(hw, work_limit - work_done); *budget -= work_done; dev0->quota -= work_done; Loading @@ -2133,9 +2146,24 @@ static int sky2_poll(struct net_device *dev0, int *budget) sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); } netif_rx_complete(dev0); mod_timer(&hw->idle_timer, jiffies + HZ); local_irq_disable(); __netif_rx_complete(dev0); status = sky2_read32(hw, B0_Y2_SP_LISR); if (unlikely(status)) { /* More work pending, try and keep going */ if (__netif_rx_schedule_prep(dev0)) { __netif_rx_reschedule(dev0, work_done); status = sky2_read32(hw, B0_Y2_SP_EISR); local_irq_enable(); goto restart_poll; } } local_irq_enable(); return 0; } Loading @@ -2153,8 +2181,6 @@ static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) prefetch(&hw->st_le[hw->st_idx]); if (likely(__netif_rx_schedule_prep(dev0))) __netif_rx_schedule(dev0); else printk(KERN_DEBUG PFX "irq race detected\n"); return IRQ_HANDLED; } Loading Loading @@ -2193,7 +2219,7 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) } static int sky2_reset(struct sky2_hw *hw) static int __devinit sky2_reset(struct sky2_hw *hw) { u16 status; u8 t8, pmd_type; Loading Loading @@ -3276,6 +3302,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev, sky2_write32(hw, B0_IMSK, Y2_IS_BASE); setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) dev); pci_set_drvdata(pdev, hw); return 0; Loading Loading @@ -3311,13 +3339,15 @@ static void __devexit sky2_remove(struct pci_dev *pdev) if (!hw) return; del_timer_sync(&hw->idle_timer); sky2_write32(hw, B0_IMSK, 0); dev0 = hw->dev[0]; dev1 = hw->dev[1]; if (dev1) unregister_netdev(dev1); unregister_netdev(dev0); sky2_write32(hw, B0_IMSK, 0); sky2_set_power_state(hw, PCI_D3hot); sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); sky2_write8(hw, B0_CTST, CS_RST_SET); Loading drivers/net/sky2.h +2 −0 Original line number Diff line number Diff line Loading @@ -1880,6 +1880,8 @@ struct sky2_hw { struct sky2_status_le *st_le; u32 st_idx; dma_addr_t st_dma; struct timer_list idle_timer; int msi_detected; wait_queue_head_t msi_wait; }; Loading include/linux/netdevice.h +10 −8 Original line number Diff line number Diff line Loading @@ -829,19 +829,21 @@ static inline void netif_rx_schedule(struct net_device *dev) __netif_rx_schedule(dev); } /* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). * Do not inline this? */ static inline void __netif_rx_reschedule(struct net_device *dev, int undo) { dev->quota += undo; list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list); __raise_softirq_irqoff(NET_RX_SOFTIRQ); } /* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). */ static inline int netif_rx_reschedule(struct net_device *dev, int undo) { if (netif_rx_schedule_prep(dev)) { unsigned long flags; dev->quota += undo; local_irq_save(flags); list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list); __raise_softirq_irqoff(NET_RX_SOFTIRQ); __netif_rx_reschedule(dev, undo); local_irq_restore(flags); return 1; } Loading Loading
drivers/net/forcedeth.c +67 −12 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ * 0.50: 20 Jan 2006: Add 8021pq tagging support. * 0.51: 20 Jan 2006: Add 64bit consistent memory allocation for rings. * 0.52: 20 Jan 2006: Add MSI/MSIX support. * 0.53: 19 Mar 2006: Fix init from low power mode and add hw reset. * * Known bugs: * We suspect that on some hardware no TX done interrupts are generated. Loading @@ -116,7 +117,7 @@ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * superfluous timer interrupts from the nic. */ #define FORCEDETH_VERSION "0.52" #define FORCEDETH_VERSION "0.53" #define DRV_NAME "forcedeth" #include <linux/module.h> Loading Loading @@ -160,6 +161,7 @@ #define DEV_HAS_VLAN 0x0020 /* device supports vlan tagging and striping */ #define DEV_HAS_MSI 0x0040 /* device supports MSI */ #define DEV_HAS_MSI_X 0x0080 /* device supports MSI-X */ #define DEV_HAS_POWER_CNTRL 0x0100 /* device supports power savings */ enum { NvRegIrqStatus = 0x000, Loading Loading @@ -203,6 +205,8 @@ enum { #define NVREG_MISC1_HD 0x02 #define NVREG_MISC1_FORCE 0x3b0f3c NvRegMacReset = 0x3c, #define NVREG_MAC_RESET_ASSERT 0x0F3 NvRegTransmitterControl = 0x084, #define NVREG_XMITCTL_START 0x01 NvRegTransmitterStatus = 0x088, Loading Loading @@ -326,6 +330,10 @@ enum { NvRegMSIXMap0 = 0x3e0, NvRegMSIXMap1 = 0x3e4, NvRegMSIXIrqStatus = 0x3f0, NvRegPowerState2 = 0x600, #define NVREG_POWERSTATE2_POWERUP_MASK 0x0F11 #define NVREG_POWERSTATE2_POWERUP_REV_A3 0x0001 }; /* Big endian: should work, but is untested */ Loading Loading @@ -414,7 +422,8 @@ typedef union _ring_type { #define NV_RX3_VLAN_TAG_MASK (0x0000FFFF) /* Miscelaneous hardware related defines: */ #define NV_PCI_REGSZ 0x270 #define NV_PCI_REGSZ_VER1 0x270 #define NV_PCI_REGSZ_VER2 0x604 /* various timeout delays: all in usec */ #define NV_TXRX_RESET_DELAY 4 Loading @@ -431,6 +440,7 @@ typedef union _ring_type { #define NV_MIIBUSY_DELAY 50 #define NV_MIIPHY_DELAY 10 #define NV_MIIPHY_DELAYMAX 10000 #define NV_MAC_RESET_DELAY 64 #define NV_WAKEUPPATTERNS 5 #define NV_WAKEUPMASKENTRIES 4 Loading Loading @@ -552,6 +562,8 @@ struct fe_priv { u32 desc_ver; u32 txrxctl_bits; u32 vlanctl_bits; u32 driver_data; u32 register_size; void __iomem *base; Loading Loading @@ -919,6 +931,24 @@ static void nv_txrx_reset(struct net_device *dev) pci_push(base); } static void nv_mac_reset(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name); writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl); pci_push(base); writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset); pci_push(base); udelay(NV_MAC_RESET_DELAY); writel(0, base + NvRegMacReset); pci_push(base); udelay(NV_MAC_RESET_DELAY); writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl); pci_push(base); } /* * nv_get_stats: dev->get_stats function * Get latest stats value from the nic. Loading Loading @@ -1331,7 +1361,7 @@ static void nv_tx_timeout(struct net_device *dev) dev->name, (unsigned long)np->ring_addr, np->next_tx, np->nic_tx); printk(KERN_INFO "%s: Dumping tx registers\n", dev->name); for (i=0;i<0x400;i+= 32) { for (i=0;i<=np->register_size;i+= 32) { printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", i, readl(base + i + 0), readl(base + i + 4), Loading Loading @@ -2488,11 +2518,11 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } #define FORCEDETH_REGS_VER 1 #define FORCEDETH_REGS_SIZE 0x400 /* 256 32-bit registers */ static int nv_get_regs_len(struct net_device *dev) { return FORCEDETH_REGS_SIZE; struct fe_priv *np = netdev_priv(dev); return np->register_size; } static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf) Loading @@ -2504,7 +2534,7 @@ static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void regs->version = FORCEDETH_REGS_VER; spin_lock_irq(&np->lock); for (i=0;i<FORCEDETH_REGS_SIZE/sizeof(u32);i++) for (i = 0;i <= np->register_size/sizeof(u32); i++) rbuf[i] = readl(base + i*sizeof(u32)); spin_unlock_irq(&np->lock); } Loading Loading @@ -2608,6 +2638,8 @@ static int nv_open(struct net_device *dev) dprintk(KERN_DEBUG "nv_open: begin\n"); /* 1) erase previous misconfiguration */ if (np->driver_data & DEV_HAS_POWER_CNTRL) nv_mac_reset(dev); /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */ writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA); writel(0, base + NvRegMulticastAddrB); Loading Loading @@ -2878,6 +2910,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i unsigned long addr; u8 __iomem *base; int err, i; u32 powerstate; dev = alloc_etherdev(sizeof(struct fe_priv)); err = -ENOMEM; Loading Loading @@ -2910,6 +2943,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i if (err < 0) goto out_disable; if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL)) np->register_size = NV_PCI_REGSZ_VER2; else np->register_size = NV_PCI_REGSZ_VER1; err = -EINVAL; addr = 0; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { Loading @@ -2918,7 +2956,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i pci_resource_len(pci_dev, i), pci_resource_flags(pci_dev, i)); if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM && pci_resource_len(pci_dev, i) >= NV_PCI_REGSZ) { pci_resource_len(pci_dev, i) >= np->register_size) { addr = pci_resource_start(pci_dev, i); break; } Loading @@ -2929,6 +2967,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i goto out_relreg; } /* copy of driver data */ np->driver_data = id->driver_data; /* handle different descriptor versions */ if (id->driver_data & DEV_HAS_HIGH_DMA) { /* packet format 3: supports 40-bit addressing */ Loading Loading @@ -2986,7 +3027,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i } err = -ENOMEM; np->base = ioremap(addr, NV_PCI_REGSZ); np->base = ioremap(addr, np->register_size); if (!np->base) goto out_relreg; dev->base_addr = (unsigned long)np->base; Loading Loading @@ -3062,6 +3103,20 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i writel(0, base + NvRegWakeUpFlags); np->wolenabled = 0; if (id->driver_data & DEV_HAS_POWER_CNTRL) { u8 revision_id; pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id); /* take phy and nic out of low power mode */ powerstate = readl(base + NvRegPowerState2); powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK; if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_12 || id->device == PCI_DEVICE_ID_NVIDIA_NVENET_13) && revision_id >= 0xA3) powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3; writel(powerstate, base + NvRegPowerState2); } if (np->desc_ver == DESC_VER_1) { np->tx_flags = NV_TX_VALID; } else { Loading Loading @@ -3223,19 +3278,19 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP51 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12), .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL, }, { /* MCP51 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13), .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL, }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), .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, .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, }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), .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, .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, }, {0,}, }; Loading
drivers/net/sky2.c +41 −11 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ #include "sky2.h" #define DRV_NAME "sky2" #define DRV_VERSION "1.1" #define DRV_VERSION "1.2" #define PFX DRV_NAME " " /* Loading Loading @@ -925,8 +925,7 @@ static inline struct sk_buff *sky2_alloc_skb(unsigned int size, gfp_t gfp_mask) skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask); if (likely(skb)) { unsigned long p = (unsigned long) skb->data; skb_reserve(skb, ((p + RX_SKB_ALIGN - 1) & ~(RX_SKB_ALIGN - 1)) - p); skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); } return skb; Loading Loading @@ -1686,13 +1685,12 @@ static void sky2_tx_timeout(struct net_device *dev) } #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* Want receive buffer size to be multiple of 64 bits * and incl room for vlan and truncation */ static inline unsigned sky2_buf_size(int mtu) { return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; return ALIGN(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; } static int sky2_change_mtu(struct net_device *dev, int new_mtu) Loading Loading @@ -2086,6 +2084,20 @@ static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port, } } /* If idle then force a fake soft NAPI poll once a second * to work around cases where sharing an edge triggered interrupt. */ static void sky2_idle(unsigned long arg) { struct net_device *dev = (struct net_device *) arg; local_irq_disable(); if (__netif_rx_schedule_prep(dev)) __netif_rx_schedule(dev); local_irq_enable(); } static int sky2_poll(struct net_device *dev0, int *budget) { struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; Loading @@ -2093,6 +2105,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) int work_done = 0; u32 status = sky2_read32(hw, B0_Y2_SP_EISR); restart_poll: if (unlikely(status & ~Y2_IS_STAT_BMU)) { if (status & Y2_IS_HW_ERR) sky2_hw_intr(hw); Loading Loading @@ -2123,7 +2136,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) } if (status & Y2_IS_STAT_BMU) { work_done = sky2_status_intr(hw, work_limit); work_done += sky2_status_intr(hw, work_limit - work_done); *budget -= work_done; dev0->quota -= work_done; Loading @@ -2133,9 +2146,24 @@ static int sky2_poll(struct net_device *dev0, int *budget) sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); } netif_rx_complete(dev0); mod_timer(&hw->idle_timer, jiffies + HZ); local_irq_disable(); __netif_rx_complete(dev0); status = sky2_read32(hw, B0_Y2_SP_LISR); if (unlikely(status)) { /* More work pending, try and keep going */ if (__netif_rx_schedule_prep(dev0)) { __netif_rx_reschedule(dev0, work_done); status = sky2_read32(hw, B0_Y2_SP_EISR); local_irq_enable(); goto restart_poll; } } local_irq_enable(); return 0; } Loading @@ -2153,8 +2181,6 @@ static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) prefetch(&hw->st_le[hw->st_idx]); if (likely(__netif_rx_schedule_prep(dev0))) __netif_rx_schedule(dev0); else printk(KERN_DEBUG PFX "irq race detected\n"); return IRQ_HANDLED; } Loading Loading @@ -2193,7 +2219,7 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) } static int sky2_reset(struct sky2_hw *hw) static int __devinit sky2_reset(struct sky2_hw *hw) { u16 status; u8 t8, pmd_type; Loading Loading @@ -3276,6 +3302,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev, sky2_write32(hw, B0_IMSK, Y2_IS_BASE); setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) dev); pci_set_drvdata(pdev, hw); return 0; Loading Loading @@ -3311,13 +3339,15 @@ static void __devexit sky2_remove(struct pci_dev *pdev) if (!hw) return; del_timer_sync(&hw->idle_timer); sky2_write32(hw, B0_IMSK, 0); dev0 = hw->dev[0]; dev1 = hw->dev[1]; if (dev1) unregister_netdev(dev1); unregister_netdev(dev0); sky2_write32(hw, B0_IMSK, 0); sky2_set_power_state(hw, PCI_D3hot); sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); sky2_write8(hw, B0_CTST, CS_RST_SET); Loading
drivers/net/sky2.h +2 −0 Original line number Diff line number Diff line Loading @@ -1880,6 +1880,8 @@ struct sky2_hw { struct sky2_status_le *st_le; u32 st_idx; dma_addr_t st_dma; struct timer_list idle_timer; int msi_detected; wait_queue_head_t msi_wait; }; Loading
include/linux/netdevice.h +10 −8 Original line number Diff line number Diff line Loading @@ -829,19 +829,21 @@ static inline void netif_rx_schedule(struct net_device *dev) __netif_rx_schedule(dev); } /* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). * Do not inline this? */ static inline void __netif_rx_reschedule(struct net_device *dev, int undo) { dev->quota += undo; list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list); __raise_softirq_irqoff(NET_RX_SOFTIRQ); } /* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). */ static inline int netif_rx_reschedule(struct net_device *dev, int undo) { if (netif_rx_schedule_prep(dev)) { unsigned long flags; dev->quota += undo; local_irq_save(flags); list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list); __raise_softirq_irqoff(NET_RX_SOFTIRQ); __netif_rx_reschedule(dev, undo); local_irq_restore(flags); return 1; } Loading