X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fstarfire.c;h=bf873ea2579733f572f25886b9a0ab9d358cbf3d;hb=refs%2Fheads%2Fvserver;hp=9b47edbd9783f533185506b34029409b646b7528;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 9b47edbd9..bf873ea25 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -2,7 +2,7 @@ /* Written 1998-2000 by Donald Becker. - Current maintainer is Ion Badulescu . Please + Current maintainer is Ion Badulescu . Please send all bug reports to me, and not to Donald Becker, as this code has been heavily modified from Donald's original version. @@ -22,122 +22,14 @@ Support and updates available at http://www.scyld.com/network/starfire.html + [link no longer provides useful info -jgarzik] - ----------------------------------------------------------- - - Linux kernel-specific changes: - - LK1.1.1 (jgarzik): - - Use PCI driver interface - - Fix MOD_xxx races - - softnet fixups - - LK1.1.2 (jgarzik): - - Merge Becker version 0.15 - - LK1.1.3 (Andrew Morton) - - Timer cleanups - - LK1.1.4 (jgarzik): - - Merge Becker version 1.03 - - LK1.2.1 (Ion Badulescu ) - - Support hardware Rx/Tx checksumming - - Use the GFP firmware taken from Adaptec's Netware driver - - LK1.2.2 (Ion Badulescu) - - Backported to 2.2.x - - LK1.2.3 (Ion Badulescu) - - Fix the flaky mdio interface - - More compat clean-ups - - LK1.2.4 (Ion Badulescu) - - More 2.2.x initialization fixes - - LK1.2.5 (Ion Badulescu) - - Several fixes from Manfred Spraul - - LK1.2.6 (Ion Badulescu) - - Fixed ifup/ifdown/ifup problem in 2.4.x - - LK1.2.7 (Ion Badulescu) - - Removed unused code - - Made more functions static and __init - - LK1.2.8 (Ion Badulescu) - - Quell bogus error messages, inform about the Tx threshold - - Removed #ifdef CONFIG_PCI, this driver is PCI only - - LK1.2.9 (Ion Badulescu) - - Merged Jeff Garzik's changes from 2.4.4-pre5 - - Added 2.2.x compatibility stuff required by the above changes - - LK1.2.9a (Ion Badulescu) - - More updates from Jeff Garzik - - LK1.3.0 (Ion Badulescu) - - Merged zerocopy support - - LK1.3.1 (Ion Badulescu) - - Added ethtool support - - Added GPIO (media change) interrupt support - - LK1.3.2 (Ion Badulescu) - - Fixed 2.2.x compatibility issues introduced in 1.3.1 - - Fixed ethtool ioctl returning uninitialized memory - - LK1.3.3 (Ion Badulescu) - - Initialize the TxMode register properly - - Don't dereference dev->priv after freeing it - - LK1.3.4 (Ion Badulescu) - - Fixed initialization timing problems - - Fixed interrupt mask definitions - - LK1.3.5 (jgarzik) - - ethtool NWAY_RST, GLINK, [GS]MSGLVL support - - LK1.3.6: - - Sparc64 support and fixes (Ion Badulescu) - - Better stats and error handling (Ion Badulescu) - - Use new pci_set_mwi() PCI API function (jgarzik) - - LK1.3.7 (Ion Badulescu) - - minimal implementation of tx_timeout() - - correctly shutdown the Rx/Tx engines in netdev_close() - - added calls to netif_carrier_on/off - (patch from Stefan Rompf ) - - VLAN support - - LK1.3.8 (Ion Badulescu) - - adjust DMA burst size on sparc64 - - 64-bit support - - reworked zerocopy support for 64-bit buffers - - working and usable interrupt mitigation/latency - - reduced Tx interrupt frequency for lower interrupt overhead - - LK1.3.9 (Ion Badulescu) - - bugfix for mcast filter - - enable the right kind of Tx interrupts (TxDMADone, not TxDone) - - LK1.4.0 (Ion Badulescu) - - NAPI support - - LK1.4.1 (Ion Badulescu) - - flush PCI posting buffers after disabling Rx interrupts - - put the chip to a D3 slumber on driver unload - - added config option to enable/disable NAPI - -TODO: bugfixes (no bugs known as of right now) */ #define DRV_NAME "starfire" -#define DRV_VERSION "1.03+LK1.4.1" -#define DRV_RELDATE "February 10, 2002" +#define DRV_VERSION "2.0" +#define DRV_RELDATE "June 27, 2006" -#include -#include #include #include #include @@ -145,40 +37,33 @@ TODO: bugfixes (no bugs known as of right now) #include #include #include +#include +#include +#include +#include +#include #include /* Processor type for cache alignment. */ #include #include -/* - * Adaptec's license for their drivers (which is where I got the - * firmware files) does not allow one to redistribute them. Thus, we can't - * include the firmware with this driver. - * - * However, should a legal-to-distribute firmware become available, - * the driver developer would need only to obtain the firmware in the - * form of a C header file. - * Once that's done, the #undef below must be changed into a #define - * for this driver to really use the firmware. Note that Rx/Tx - * hardware TCP checksumming is not possible without the firmware. - * - * WANTED: legal firmware to include with this GPL'd driver. - */ -#undef HAS_FIRMWARE +#include "starfire_firmware.h" /* * The current frame processor firmware fails to checksum a fragment * of length 1. If and when this is fixed, the #define below can be removed. */ #define HAS_BROKEN_FIRMWARE + /* - * Define this if using the driver with the zero-copy patch + * If using the broken firmware, data must be padded to the next 32-bit boundary. */ -#if defined(HAS_FIRMWARE) && defined(MAX_SKB_FRAGS) -#define ZEROCOPY +#ifdef HAS_BROKEN_FIRMWARE +#define PADDING_MASK 3 #endif -#ifdef HAS_FIRMWARE -#include "starfire_firmware.h" -#endif /* HAS_FIRMWARE */ +/* + * Define this if using the driver with the zero-copy patch + */ +#define ZEROCOPY #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #define VLAN_SUPPORT @@ -200,13 +85,9 @@ static int max_interrupt_work = 20; static int mtu; /* Maximum number of multicast addresses to filter (vs. rx-all-multicast). The Starfire has a 512 element hash table based on the Ethernet CRC. */ -static int multicast_filter_limit = 512; +static const int multicast_filter_limit = 512; /* Whether to do TCP/UDP checksums in hardware */ -#ifdef HAS_FIRMWARE static int enable_hw_cksum = 1; -#else -static int enable_hw_cksum = 0; -#endif #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ /* @@ -271,9 +152,10 @@ static int full_duplex[MAX_UNITS] = {0, }; * This SUCKS. * We need a much better method to determine if dma_addr_t is 64-bit. */ -#if (defined(__i386__) && defined(CONFIG_HIGHMEM) && (LINUX_VERSION_CODE > 0x20500 || defined(CONFIG_HIGHMEM64G))) || defined(__x86_64__) || defined (__ia64__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) +#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) /* 64-bit dma_addr_t */ #define ADDR_64BITS /* This chip uses 64 bit addresses. */ +#define netdrv_addr_t u64 #define cpu_to_dma(x) cpu_to_le64(x) #define dma_to_cpu(x) le64_to_cpu(x) #define RX_DESC_Q_ADDR_SIZE RxDescQAddr64bit @@ -282,6 +164,7 @@ static int full_duplex[MAX_UNITS] = {0, }; #define TX_COMPL_Q_ADDR_SIZE TxComplQAddr64bit #define RX_DESC_ADDR_SIZE RxDescAddr64bit #else /* 32-bit dma_addr_t */ +#define netdrv_addr_t u32 #define cpu_to_dma(x) cpu_to_le32(x) #define dma_to_cpu(x) le32_to_cpu(x) #define RX_DESC_Q_ADDR_SIZE RxDescQAddr32bit @@ -291,46 +174,15 @@ static int full_duplex[MAX_UNITS] = {0, }; #define RX_DESC_ADDR_SIZE RxDescAddr32bit #endif -#ifdef MAX_SKB_FRAGS #define skb_first_frag_len(skb) skb_headlen(skb) #define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1) -#else /* not MAX_SKB_FRAGS */ -#define skb_first_frag_len(skb) (skb->len) -#define skb_num_frags(skb) 1 -#endif /* not MAX_SKB_FRAGS */ - -/* 2.2.x compatibility code */ -#if LINUX_VERSION_CODE < 0x20300 - -#include "starfire-kcomp22.h" - -#else /* LINUX_VERSION_CODE > 0x20300 */ - -#include -#include -#include - -#include - -#define COMPAT_MOD_INC_USE_COUNT -#define COMPAT_MOD_DEC_USE_COUNT - -#define init_tx_timer(dev, func, timeout) \ - dev->tx_timeout = func; \ - dev->watchdog_timeo = timeout; -#define kick_tx_timer(dev, func, timeout) - -#define netif_start_if(dev) -#define netif_stop_if(dev) - -#define PCI_SLOT_NAME(pci_dev) pci_name(pci_dev) - -#endif /* LINUX_VERSION_CODE > 0x20300 */ #ifdef HAVE_NETDEV_POLL #define init_poll(dev) \ +do { \ dev->poll = &netdev_poll; \ - dev->weight = max_interrupt_work; + dev->weight = max_interrupt_work; \ +} while (0) #define netdev_rx(dev, ioaddr) \ do { \ u32 intr_enable; \ @@ -344,7 +196,7 @@ do { \ /* Paranoia check */ \ intr_enable = readl(ioaddr + IntrEnable); \ if (intr_enable & (IntrRxDone | IntrRxEmpty)) { \ - printk("%s: interrupt while in polling mode!\n", dev->name); \ + printk(KERN_INFO "%s: interrupt while in polling mode!\n", dev->name); \ intr_enable &= ~(IntrRxDone | IntrRxEmpty); \ writel(intr_enable, ioaddr + IntrEnable); \ } \ @@ -367,23 +219,24 @@ do { \ /* These identify the driver base version and may not be removed. */ -static char version[] __devinitdata = +static const char version[] __devinitdata = KERN_INFO "starfire.c:v1.03 7/26/2000 Written by Donald Becker \n" KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n"; MODULE_AUTHOR("Donald Becker "); MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver"); MODULE_LICENSE("GPL"); - -MODULE_PARM(max_interrupt_work, "i"); -MODULE_PARM(mtu, "i"); -MODULE_PARM(debug, "i"); -MODULE_PARM(rx_copybreak, "i"); -MODULE_PARM(intr_latency, "i"); -MODULE_PARM(small_frames, "i"); -MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); -MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); -MODULE_PARM(enable_hw_cksum, "i"); +MODULE_VERSION(DRV_VERSION); + +module_param(max_interrupt_work, int, 0); +module_param(mtu, int, 0); +module_param(debug, int, 0); +module_param(rx_copybreak, int, 0); +module_param(intr_latency, int, 0); +module_param(small_frames, int, 0); +module_param_array(options, int, NULL, 0); +module_param_array(full_duplex, int, NULL, 0); +module_param(enable_hw_cksum, int, 0); MODULE_PARM_DESC(max_interrupt_work, "Maximum events handled per interrupt"); MODULE_PARM_DESC(mtu, "MTU (all boards)"); MODULE_PARM_DESC(debug, "Debug level (0-6)"); @@ -428,7 +281,7 @@ on the 32/64 bitness of the architecture), and relies on automatic minimum-length padding. It does not use the completion queue consumer index, but instead checks for non-zero status entries. -For receive this driver uses type 0/1/2/3 receive descriptors. The driver +For receive this driver uses type 2/3 receive descriptors. The driver allocates full frame size skbuffs for the Rx ring buffers, so all frames should fit in a single descriptor. The driver does not use the completion queue consumer index, but instead checks for non-zero status entries. @@ -479,7 +332,7 @@ IVc. Errata */ - + enum chip_capability_flags {CanHaveMII=1, }; @@ -494,7 +347,7 @@ static struct pci_device_id starfire_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, starfire_pci_tbl); /* A chip capabilities table, matching the CH_xxx entries in xxx_pci_tbl[] above. */ -static struct chip_info { +static const struct chip_info { const char *name; int drv_flags; } netdrv_tbl[] __devinitdata = { @@ -673,7 +526,6 @@ struct full_rx_done_desc { u32 timestamp; }; /* XXX: this is ugly and I'm not sure it's worth the trouble -Ion */ -#ifdef HAS_FIRMWARE #ifdef VLAN_SUPPORT typedef struct full_rx_done_desc rx_done_desc; #define RxComplType RxComplType3 @@ -681,15 +533,6 @@ typedef struct full_rx_done_desc rx_done_desc; typedef struct csum_rx_done_desc rx_done_desc; #define RxComplType RxComplType2 #endif /* not VLAN_SUPPORT */ -#else /* not HAS_FIRMWARE */ -#ifdef VLAN_SUPPORT -typedef struct basic_rx_done_desc rx_done_desc; -#define RxComplType RxComplType1 -#else /* not VLAN_SUPPORT */ -typedef struct short_rx_done_desc rx_done_desc; -#define RxComplType RxComplType0 -#endif /* not VLAN_SUPPORT */ -#endif /* not HAS_FIRMWARE */ enum rx_done_bits { RxOK=0x20000000, RxFIFOErr=0x10000000, RxBufQ2=0x08000000, @@ -779,6 +622,7 @@ struct netdev_private { struct mii_if_info mii_if; /* MII lib hooks/info */ int phy_cnt; /* MII device addresses. */ unsigned char phys[PHY_CNT]; /* MII device addresses. */ + void __iomem *base; }; @@ -789,7 +633,7 @@ static void check_duplex(struct net_device *dev); static void tx_timeout(struct net_device *dev); static void init_ring(struct net_device *dev); static int start_tx(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs); +static irqreturn_t intr_handler(int irq, void *dev_instance); static void netdev_error(struct net_device *dev, int intr_status); static int __netdev_rx(struct net_device *dev, int *quota); static void refill_rx_ring(struct net_device *dev); @@ -799,12 +643,13 @@ static struct net_device_stats *get_stats(struct net_device *dev); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int netdev_close(struct net_device *dev); static void netdev_media_change(struct net_device *dev); +static const struct ethtool_ops ethtool_ops; #ifdef VLAN_SUPPORT static void netdev_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) { - struct netdev_private *np = dev->priv; + struct netdev_private *np = netdev_priv(dev); spin_lock(&np->lock); if (debug > 2) @@ -816,7 +661,7 @@ static void netdev_vlan_rx_register(struct net_device *dev, struct vlan_group *g static void netdev_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) { - struct netdev_private *np = dev->priv; + struct netdev_private *np = netdev_priv(dev); spin_lock(&np->lock); if (debug > 1) @@ -827,7 +672,7 @@ static void netdev_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) static void netdev_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) { - struct netdev_private *np = dev->priv; + struct netdev_private *np = netdev_priv(dev); spin_lock(&np->lock); if (debug > 1) @@ -848,6 +693,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, struct net_device *dev; static int card_idx = -1; long ioaddr; + void __iomem *base; int drv_flags, io_size; int boguscnt; @@ -880,33 +726,27 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, irq = pdev->irq; - if (pci_request_regions (pdev, dev->name)) { + if (pci_request_regions (pdev, DRV_NAME)) { printk(KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx); goto err_out_free_netdev; } - /* ioremap is borken in Linux-2.2.x/sparc64 */ -#if !defined(CONFIG_SPARC64) || LINUX_VERSION_CODE > 0x20300 - ioaddr = (long) ioremap(ioaddr, io_size); - if (!ioaddr) { + base = ioremap(ioaddr, io_size); + if (!base) { printk(KERN_ERR DRV_NAME " %d: cannot remap %#x @ %#lx, aborting\n", card_idx, io_size, ioaddr); goto err_out_free_res; } -#endif /* !CONFIG_SPARC64 || Linux 2.3.0+ */ pci_set_master(pdev); /* enable MWI -- it vastly improves Rx performance on sparc64 */ pci_set_mwi(pdev); -#ifdef MAX_SKB_FRAGS - dev->features |= NETIF_F_SG; -#endif /* MAX_SKB_FRAGS */ #ifdef ZEROCOPY /* Starfire can do TCP/UDP checksumming */ if (enable_hw_cksum) - dev->features |= NETIF_F_IP_CSUM; + dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; #endif /* ZEROCOPY */ #ifdef VLAN_SUPPORT dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; @@ -920,27 +760,27 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, /* Serial EEPROM reads are hidden by the hardware. */ for (i = 0; i < 6; i++) - dev->dev_addr[i] = readb(ioaddr + EEPROMCtrl + 20 - i); + dev->dev_addr[i] = readb(base + EEPROMCtrl + 20 - i); #if ! defined(final_version) /* Dump the EEPROM contents during development. */ if (debug > 4) for (i = 0; i < 0x20; i++) printk("%2.2x%s", - (unsigned int)readb(ioaddr + EEPROMCtrl + i), + (unsigned int)readb(base + EEPROMCtrl + i), i % 16 != 15 ? " " : "\n"); #endif /* Issue soft reset */ - writel(MiiSoftReset, ioaddr + TxMode); + writel(MiiSoftReset, base + TxMode); udelay(1000); - writel(0, ioaddr + TxMode); + writel(0, base + TxMode); /* Reset the chip to erase previous misconfiguration. */ - writel(1, ioaddr + PCIDeviceConfig); + writel(1, base + PCIDeviceConfig); boguscnt = 1000; while (--boguscnt > 0) { udelay(10); - if ((readl(ioaddr + PCIDeviceConfig) & 1) == 0) + if ((readl(base + PCIDeviceConfig) & 1) == 0) break; } if (boguscnt == 0) @@ -948,10 +788,11 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, /* wait a little longer */ udelay(1000); - dev->base_addr = ioaddr; + dev->base_addr = (unsigned long)base; dev->irq = irq; - np = dev->priv; + np = netdev_priv(dev); + np->base = base; spin_lock_init(&np->lock); pci_set_drvdata(pdev, dev); @@ -1009,12 +850,14 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, /* The chip-specific entries in the device structure. */ dev->open = &netdev_open; dev->hard_start_xmit = &start_tx; - init_tx_timer(dev, tx_timeout, TX_TIMEOUT); + dev->tx_timeout = tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; init_poll(dev); dev->stop = &netdev_close; dev->get_stats = &get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &netdev_ioctl; + SET_ETHTOOL_OPS(dev, ðtool_ops); if (mtu) dev->mtu = mtu; @@ -1022,8 +865,8 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, if (register_netdev(dev)) goto err_out_cleardev; - printk(KERN_INFO "%s: %s at %#lx, ", - dev->name, netdrv_tbl[chip_idx].name, ioaddr); + printk(KERN_INFO "%s: %s at %p, ", + dev->name, netdrv_tbl[chip_idx].name, base); for (i = 0; i < 5; i++) printk("%2.2x:", dev->dev_addr[i]); printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq); @@ -1039,7 +882,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, if ((mdio_read(dev, phy, MII_BMCR) & BMCR_RESET) == 0) break; if (boguscnt == 0) { - printk("%s: PHY reset never completed!\n", dev->name); + printk("%s: PHY#%d reset never completed!\n", dev->name, phy); continue; } mii_status = mdio_read(dev, phy, MII_BMSR); @@ -1066,7 +909,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, err_out_cleardev: pci_set_drvdata(pdev, NULL); - iounmap((void *)ioaddr); + iounmap(base); err_out_free_res: pci_release_regions (pdev); err_out_free_netdev: @@ -1078,7 +921,8 @@ err_out_free_netdev: /* Read the MII Management Data I/O (MDIO) interfaces. */ static int mdio_read(struct net_device *dev, int phy_id, int location) { - long mdio_addr = dev->base_addr + MIICtrl + (phy_id<<7) + (location<<2); + struct netdev_private *np = netdev_priv(dev); + void __iomem *mdio_addr = np->base + MIICtrl + (phy_id<<7) + (location<<2); int result, boguscnt=1000; /* ??? Should we add a busy-wait here? */ do @@ -1094,7 +938,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int location) static void mdio_write(struct net_device *dev, int phy_id, int location, int value) { - long mdio_addr = dev->base_addr + MIICtrl + (phy_id<<7) + (location<<2); + struct netdev_private *np = netdev_priv(dev); + void __iomem *mdio_addr = np->base + MIICtrl + (phy_id<<7) + (location<<2); writel(value, mdio_addr); /* The busy-wait will occur before a read. */ } @@ -1102,20 +947,16 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val static int netdev_open(struct net_device *dev) { - struct netdev_private *np = dev->priv; - long ioaddr = dev->base_addr; + struct netdev_private *np = netdev_priv(dev); + void __iomem *ioaddr = np->base; int i, retval; size_t tx_done_q_size, rx_done_q_size, tx_ring_size, rx_ring_size; /* Do we ever need to reset the chip??? */ - COMPAT_MOD_INC_USE_COUNT; - - retval = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev); - if (retval) { - COMPAT_MOD_DEC_USE_COUNT; + retval = request_irq(dev->irq, &intr_handler, IRQF_SHARED, dev->name, dev); + if (retval) return retval; - } /* Disable the Rx and Tx, and reset the chip. */ writel(0, ioaddr + GenCtrl); @@ -1132,8 +973,8 @@ static int netdev_open(struct net_device *dev) rx_ring_size = sizeof(struct starfire_rx_desc) * RX_RING_SIZE; np->queue_mem_size = tx_done_q_size + rx_done_q_size + tx_ring_size + rx_ring_size; np->queue_mem = pci_alloc_consistent(np->pci_dev, np->queue_mem_size, &np->queue_mem_dma); - if (np->queue_mem == 0) { - COMPAT_MOD_DEC_USE_COUNT; + if (np->queue_mem == NULL) { + free_irq(dev->irq, dev); return -ENOMEM; } @@ -1199,7 +1040,7 @@ static int netdev_open(struct net_device *dev) writew(0, ioaddr + PerfFilterTable + 8); for (i = 1; i < 16; i++) { u16 *eaddrs = (u16 *)dev->dev_addr; - long setup_frm = ioaddr + PerfFilterTable + i * 16; + void __iomem *setup_frm = ioaddr + PerfFilterTable + i * 16; writew(cpu_to_be16(eaddrs[2]), setup_frm); setup_frm += 4; writew(cpu_to_be16(eaddrs[1]), setup_frm); setup_frm += 4; writew(cpu_to_be16(eaddrs[0]), setup_frm); setup_frm += 8; @@ -1216,7 +1057,6 @@ static int netdev_open(struct net_device *dev) writel(np->intr_timer_ctrl, ioaddr + IntrTimerCtrl); - netif_start_if(dev); netif_start_queue(dev); if (debug > 1) @@ -1243,13 +1083,11 @@ static int netdev_open(struct net_device *dev) writel(ETH_P_8021Q, ioaddr + VlanType); #endif /* VLAN_SUPPORT */ -#ifdef HAS_FIRMWARE /* Load Rx/Tx firmware into the frame processors */ for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++) writel(firmware_rx[i], ioaddr + RxGfpMem + i * 4); for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++) writel(firmware_tx[i], ioaddr + TxGfpMem + i * 4); -#endif /* HAS_FIRMWARE */ if (enable_hw_cksum) /* Enable the Rx and Tx units, and the Rx/Tx frame processors. */ writel(TxEnable|TxGFPEnable|RxEnable|RxGFPEnable, ioaddr + GenCtrl); @@ -1267,7 +1105,7 @@ static int netdev_open(struct net_device *dev) static void check_duplex(struct net_device *dev) { - struct netdev_private *np = dev->priv; + struct netdev_private *np = netdev_priv(dev); u16 reg0; int silly_count = 1000; @@ -1302,8 +1140,8 @@ static void check_duplex(struct net_device *dev) static void tx_timeout(struct net_device *dev) { - struct netdev_private *np = dev->priv; - long ioaddr = dev->base_addr; + struct netdev_private *np = netdev_priv(dev); + void __iomem *ioaddr = np->base; int old_debug; printk(KERN_WARNING "%s: Transmit timed out, status %#8.8x, " @@ -1332,7 +1170,7 @@ static void tx_timeout(struct net_device *dev) /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ static void init_ring(struct net_device *dev) { - struct netdev_private *np = dev->priv; + struct netdev_private *np = netdev_priv(dev); int i; np->cur_rx = np->cur_tx = np->reap_tx = 0; @@ -1346,12 +1184,12 @@ static void init_ring(struct net_device *dev) np->rx_info[i].skb = skb; if (skb == NULL) break; - np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE); + np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb->dev = dev; /* Mark as being used by this device. */ /* Grrr, we cannot offset to correctly align the IP header. */ np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid); } - writew(i - 1, dev->base_addr + RxDescQIdx); + writew(i - 1, np->base + RxDescQIdx); np->dirty_rx = (unsigned int)(i - RX_RING_SIZE); /* Clear the remainder of the Rx buffer ring. */ @@ -1378,13 +1216,11 @@ static void init_ring(struct net_device *dev) static int start_tx(struct sk_buff *skb, struct net_device *dev) { - struct netdev_private *np = dev->priv; + struct netdev_private *np = netdev_priv(dev); unsigned int entry; u32 status; int i; - kick_tx_timer(dev, tx_timeout, TX_TIMEOUT); - /* * be cautious here, wrapping the queue has weird semantics * and we may not have enough slots even when it seems we do. @@ -1395,21 +1231,9 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) } #if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE) - { - int has_bad_length = 0; - - if (skb_first_frag_len(skb) == 1) - has_bad_length = 1; - else { - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) - if (skb_shinfo(skb)->frags[i].size == 1) { - has_bad_length = 1; - break; - } - } - - if (has_bad_length) - skb_checksum_help(skb); + if (skb->ip_summed == CHECKSUM_PARTIAL) { + if (skb_padto(skb, (skb->len + PADDING_MASK) & ~PADDING_MASK)) + return NETDEV_TX_OK; } #endif /* ZEROCOPY && HAS_BROKEN_FIRMWARE */ @@ -1429,7 +1253,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) status |= TxDescIntr; np->reap_tx = 0; } - if (skb->ip_summed == CHECKSUM_HW) { + if (skb->ip_summed == CHECKSUM_PARTIAL) { status |= TxCalTCP; np->stats.tx_compressed++; } @@ -1438,12 +1262,10 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) np->tx_info[entry].mapping = pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE); } else { -#ifdef MAX_SKB_FRAGS skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i - 1]; status |= this_frag->size; np->tx_info[entry].mapping = pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE); -#endif /* MAX_SKB_FRAGS */ } np->tx_ring[entry].addr = cpu_to_dma(np->tx_info[entry].mapping); @@ -1472,7 +1294,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) wmb(); /* Update the producer index. */ - writel(entry * (sizeof(starfire_tx_desc) / 8), dev->base_addr + TxProducerIdx); + writel(entry * (sizeof(starfire_tx_desc) / 8), np->base + TxProducerIdx); /* 4 is arbitrary, but should be ok */ if ((np->cur_tx - np->dirty_tx) + 4 > TX_RING_SIZE) @@ -1486,19 +1308,16 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) +static irqreturn_t intr_handler(int irq, void *dev_instance) { struct net_device *dev = dev_instance; - struct netdev_private *np; - long ioaddr; + struct netdev_private *np = netdev_priv(dev); + void __iomem *ioaddr = np->base; int boguscnt = max_interrupt_work; int consumer; int tx_status; int handled = 0; - ioaddr = dev->base_addr; - np = dev->priv; - do { u32 intr_status = readl(ioaddr + IntrClear); @@ -1539,7 +1358,6 @@ static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs np->tx_info[entry].mapping = 0; np->dirty_tx += np->tx_info[entry].used_slots; entry = (entry + np->tx_info[entry].used_slots) % TX_RING_SIZE; -#ifdef MAX_SKB_FRAGS { int i; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { @@ -1551,7 +1369,7 @@ static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs entry++; } } -#endif /* MAX_SKB_FRAGS */ + dev_kfree_skb_irq(skb); } np->tx_done_q[np->tx_done].status = 0; @@ -1597,7 +1415,7 @@ static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs for clarity, code sharing between NAPI/non-NAPI, and better register allocation. */ static int __netdev_rx(struct net_device *dev, int *quota) { - struct netdev_private *np = dev->priv; + struct netdev_private *np = netdev_priv(dev); u32 desc_status; int retcode = 0; @@ -1611,7 +1429,7 @@ static int __netdev_rx(struct net_device *dev, int *quota) if (debug > 4) printk(KERN_DEBUG " netdev_rx() status of %d was %#8.8x.\n", np->rx_done, desc_status); if (!(desc_status & RxOK)) { - /* There was a error. */ + /* There was an error. */ if (debug > 2) printk(KERN_DEBUG " netdev_rx() Rx error was %#8.8x.\n", desc_status); np->stats.rx_errors++; @@ -1640,7 +1458,7 @@ static int __netdev_rx(struct net_device *dev, int *quota) pci_dma_sync_single_for_cpu(np->pci_dev, np->rx_info[entry].mapping, pkt_len, PCI_DMA_FROMDEVICE); - eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0); + eth_copy_and_sum(skb, np->rx_info[entry].skb->data, pkt_len, 0); pci_dma_sync_single_for_device(np->pci_dev, np->rx_info[entry].mapping, pkt_len, PCI_DMA_FROMDEVICE); @@ -1664,11 +1482,10 @@ static int __netdev_rx(struct net_device *dev, int *quota) #endif skb->protocol = eth_type_trans(skb, dev); -#if defined(HAS_FIRMWARE) || defined(VLAN_SUPPORT) +#ifdef VLAN_SUPPORT if (debug > 4) printk(KERN_DEBUG " netdev_rx() status2 of %d was %#4.4x.\n", np->rx_done, le16_to_cpu(desc->status2)); #endif -#ifdef HAS_FIRMWARE if (le16_to_cpu(desc->status2) & 0x0100) { skb->ip_summed = CHECKSUM_UNNECESSARY; np->stats.rx_compressed++; @@ -1683,11 +1500,10 @@ static int __netdev_rx(struct net_device *dev, int *quota) * Until then, the printk stays. :-) -Ion */ else if (le16_to_cpu(desc->status2) & 0x0040) { - skb->ip_summed = CHECKSUM_HW; + skb->ip_summed = CHECKSUM_COMPLETE; skb->csum = le16_to_cpu(desc->csum); printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2)); } -#endif /* HAS_FIRMWARE */ #ifdef VLAN_SUPPORT if (np->vlgrp && le16_to_cpu(desc->status2) & 0x0200) { if (debug > 4) @@ -1705,7 +1521,7 @@ static int __netdev_rx(struct net_device *dev, int *quota) desc->status = 0; np->rx_done = (np->rx_done + 1) % DONE_Q_SIZE; } - writew(np->rx_done, dev->base_addr + CompletionQConsumerIdx); + writew(np->rx_done, np->base + CompletionQConsumerIdx); out: refill_rx_ring(dev); @@ -1720,7 +1536,8 @@ static int __netdev_rx(struct net_device *dev, int *quota) static int netdev_poll(struct net_device *dev, int *budget) { u32 intr_status; - long ioaddr = dev->base_addr; + struct netdev_private *np = netdev_priv(dev); + void __iomem *ioaddr = np->base; int retcode = 0, quota = dev->quota; do { @@ -1752,7 +1569,7 @@ static int netdev_poll(struct net_device *dev, int *budget) static void refill_rx_ring(struct net_device *dev) { - struct netdev_private *np = dev->priv; + struct netdev_private *np = netdev_priv(dev); struct sk_buff *skb; int entry = -1; @@ -1765,7 +1582,7 @@ static void refill_rx_ring(struct net_device *dev) if (skb == NULL) break; /* Better luck next round. */ np->rx_info[entry].mapping = - pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE); + pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb->dev = dev; /* Mark as being used by this device. */ np->rx_ring[entry].rxaddr = cpu_to_dma(np->rx_info[entry].mapping | RxDescValid); @@ -1774,14 +1591,14 @@ static void refill_rx_ring(struct net_device *dev) np->rx_ring[entry].rxaddr |= cpu_to_dma(RxDescEndRing); } if (entry >= 0) - writew(entry, dev->base_addr + RxDescQIdx); + writew(entry, np->base + RxDescQIdx); } static void netdev_media_change(struct net_device *dev) { - struct netdev_private *np = dev->priv; - long ioaddr = dev->base_addr; + struct netdev_private *np = netdev_priv(dev); + void __iomem *ioaddr = np->base; u16 reg0, reg1, reg4, reg5; u32 new_tx_mode; u32 new_intr_timer_ctrl; @@ -1855,12 +1672,12 @@ static void netdev_media_change(struct net_device *dev) static void netdev_error(struct net_device *dev, int intr_status) { - struct netdev_private *np = dev->priv; + struct netdev_private *np = netdev_priv(dev); /* Came close to underrunning the Tx FIFO, increase threshold. */ if (intr_status & IntrTxDataLow) { if (np->tx_threshold <= PKT_BUF_SZ / 16) { - writel(++np->tx_threshold, dev->base_addr + TxThreshold); + writel(++np->tx_threshold, np->base + TxThreshold); printk(KERN_NOTICE "%s: PCI bus congestion, increasing Tx FIFO threshold to %d bytes\n", dev->name, np->tx_threshold * 16); } else @@ -1882,8 +1699,8 @@ static void netdev_error(struct net_device *dev, int intr_status) static struct net_device_stats *get_stats(struct net_device *dev) { - long ioaddr = dev->base_addr; - struct netdev_private *np = dev->priv; + struct netdev_private *np = netdev_priv(dev); + void __iomem *ioaddr = np->base; /* This adapter architecture needs no SMP locks. */ np->stats.tx_bytes = readl(ioaddr + 0x57010); @@ -1907,22 +1724,19 @@ static struct net_device_stats *get_stats(struct net_device *dev) } -/* Chips may use the upper or lower CRC bits, and may reverse and/or invert - them. Select the endian-ness that results in minimal calculations. -*/ static void set_rx_mode(struct net_device *dev) { - long ioaddr = dev->base_addr; + struct netdev_private *np = netdev_priv(dev); + void __iomem *ioaddr = np->base; u32 rx_mode = MinVLANPrio; struct dev_mc_list *mclist; int i; #ifdef VLAN_SUPPORT - struct netdev_private *np = dev->priv; rx_mode |= VlanMode; if (np->vlgrp) { int vlan_count = 0; - long filter_addr = ioaddr + HashTable + 8; + void __iomem *filter_addr = ioaddr + HashTable + 8; for (i = 0; i < VLAN_VID_MASK; i++) { if (np->vlgrp->vlan_devices[i]) { if (vlan_count >= 32) @@ -1951,7 +1765,7 @@ static void set_rx_mode(struct net_device *dev) rx_mode |= AcceptBroadcast|AcceptAllMulticast|PerfectFilter; } else if (dev->mc_count <= 14) { /* Use the 16 element perfect filter, skip first two entries. */ - long filter_addr = ioaddr + PerfFilterTable + 2 * 16; + void __iomem *filter_addr = ioaddr + PerfFilterTable + 2 * 16; u16 *eaddrs; for (i = 2, mclist = dev->mc_list; mclist && i < dev->mc_count + 2; i++, mclist = mclist->next) { @@ -1969,13 +1783,15 @@ static void set_rx_mode(struct net_device *dev) rx_mode |= AcceptBroadcast|PerfectFilter; } else { /* Must use a multicast hash table. */ - long filter_addr; + void __iomem *filter_addr; u16 *eaddrs; u16 mc_filter[32] __attribute__ ((aligned(sizeof(long)))); /* Multicast hash filter */ memset(mc_filter, 0, sizeof(mc_filter)); for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) { + /* The chip uses the upper 9 CRC bits + as index into the hash table */ int bit_nr = ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 23; __u32 *fptr = (__u32 *) &mc_filter[(bit_nr >> 4) & ~1]; @@ -1996,118 +1812,100 @@ static void set_rx_mode(struct net_device *dev) writel(rx_mode, ioaddr + RxFilterMode); } +static int check_if_running(struct net_device *dev) +{ + if (!netif_running(dev)) + return -EINVAL; + return 0; +} -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct ethtool_cmd ecmd; - struct netdev_private *np = dev->priv; - - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - - switch (ecmd.cmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info; - memset(&info, 0, sizeof(info)); - info.cmd = ecmd.cmd; - strcpy(info.driver, DRV_NAME); - strcpy(info.version, DRV_VERSION); - *info.fw_version = 0; - strcpy(info.bus_info, PCI_SLOT_NAME(np->pci_dev)); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } + struct netdev_private *np = netdev_priv(dev); + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, pci_name(np->pci_dev)); +} - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - check_duplex(dev); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&np->mii_if); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&np->mii_if); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } +static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +{ + struct netdev_private *np = netdev_priv(dev); + spin_lock_irq(&np->lock); + mii_ethtool_gset(&np->mii_if, ecmd); + spin_unlock_irq(&np->lock); + return 0; +} - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - default: - return -EOPNOTSUPP; - } +static int set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +{ + struct netdev_private *np = netdev_priv(dev); + int res; + spin_lock_irq(&np->lock); + res = mii_ethtool_sset(&np->mii_if, ecmd); + spin_unlock_irq(&np->lock); + check_duplex(dev); + return res; } +static int nway_reset(struct net_device *dev) +{ + struct netdev_private *np = netdev_priv(dev); + return mii_nway_restart(&np->mii_if); +} + +static u32 get_link(struct net_device *dev) +{ + struct netdev_private *np = netdev_priv(dev); + return mii_link_ok(&np->mii_if); +} + +static u32 get_msglevel(struct net_device *dev) +{ + return debug; +} + +static void set_msglevel(struct net_device *dev, u32 val) +{ + debug = val; +} + +static const struct ethtool_ops ethtool_ops = { + .begin = check_if_running, + .get_drvinfo = get_drvinfo, + .get_settings = get_settings, + .set_settings = set_settings, + .nway_reset = nway_reset, + .get_link = get_link, + .get_msglevel = get_msglevel, + .set_msglevel = set_msglevel, +}; static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct netdev_private *np = dev->priv; - struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data; + struct netdev_private *np = netdev_priv(dev); + struct mii_ioctl_data *data = if_mii(rq); int rc; if (!netif_running(dev)) return -EINVAL; - if (cmd == SIOCETHTOOL) - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - else { - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL); - spin_unlock_irq(&np->lock); + spin_lock_irq(&np->lock); + rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL); + spin_unlock_irq(&np->lock); - if ((cmd == SIOCSMIIREG) && (data->phy_id == np->phys[0])) - check_duplex(dev); - } + if ((cmd == SIOCSMIIREG) && (data->phy_id == np->phys[0])) + check_duplex(dev); return rc; } static int netdev_close(struct net_device *dev) { - long ioaddr = dev->base_addr; - struct netdev_private *np = dev->priv; + struct netdev_private *np = netdev_priv(dev); + void __iomem *ioaddr = np->base; int i; netif_stop_queue(dev); - netif_stop_if(dev); if (debug > 1) { printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %#8.8x.\n", @@ -2165,31 +1963,60 @@ static int netdev_close(struct net_device *dev) np->tx_info[i].skb = NULL; } - COMPAT_MOD_DEC_USE_COUNT; + return 0; +} + +#ifdef CONFIG_PM +static int starfire_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + + if (netif_running(dev)) { + netif_device_detach(dev); + netdev_close(dev); + } + + pci_save_state(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev,state)); return 0; } +static int starfire_resume(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + + if (netif_running(dev)) { + netdev_open(dev); + netif_device_attach(dev); + } + + return 0; +} +#endif /* CONFIG_PM */ + static void __devexit starfire_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct netdev_private *np; + struct netdev_private *np = netdev_priv(dev); - if (!dev) - BUG(); + BUG_ON(!dev); + + unregister_netdev(dev); - np = dev->priv; if (np->queue_mem) pci_free_consistent(pdev, np->queue_mem_size, np->queue_mem, np->queue_mem_dma); - unregister_netdev(dev); /* XXX: add wakeup code -- requires firmware for MagicPacket */ - pci_set_power_state(pdev, 3); /* go to sleep in D3 mode */ + pci_set_power_state(pdev, PCI_D3hot); /* go to sleep in D3 mode */ pci_disable_device(pdev); - iounmap((char *)dev->base_addr); + iounmap(np->base); pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); @@ -2201,6 +2028,10 @@ static struct pci_driver starfire_driver = { .name = DRV_NAME, .probe = starfire_init_one, .remove = __devexit_p(starfire_remove_one), +#ifdef CONFIG_PM + .suspend = starfire_suspend, + .resume = starfire_resume, +#endif /* CONFIG_PM */ .id_table = starfire_pci_tbl, }; @@ -2210,19 +2041,20 @@ static int __init starfire_init (void) /* when a module, this is printed whether or not devices are found in probe */ #ifdef MODULE printk(version); +#ifdef HAVE_NETDEV_POLL + printk(KERN_INFO DRV_NAME ": polling (NAPI) enabled\n"); +#else + printk(KERN_INFO DRV_NAME ": polling (NAPI) disabled\n"); #endif -#ifndef ADDR_64BITS +#endif + /* we can do this test only at run-time... sigh */ - if (sizeof(dma_addr_t) == sizeof(u64)) { - printk("This driver has not been ported to this 64-bit architecture yet\n"); + if (sizeof(dma_addr_t) != sizeof(netdrv_addr_t)) { + printk("This driver has dma_addr_t issues, please send email to maintainer\n"); return -ENODEV; } -#endif /* not ADDR_64BITS */ -#ifndef HAS_FIRMWARE - /* unconditionally disable hw cksums if firmware is not present */ - enable_hw_cksum = 0; -#endif /* not HAS_FIRMWARE */ - return pci_module_init (&starfire_driver); + + return pci_register_driver(&starfire_driver); }