bk://gkernel.bkbits.net/netdev-2.6 jgarzik@redhat.com|ChangeSet|20040417002129|02668 jgarzik # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/04/19 19:36:29-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-netdev # # drivers/net/r8169.c # 2004/04/19 19:36:26-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/net/Kconfig # 2004/04/19 19:36:26-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/net/8139too.c # 2004/04/19 19:36:26-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/16 20:26:17-07:00 akpm@bix.(none) # Merge bk://gkernel.bkbits.net/netdev-2.6 # into bix.(none):/usr/src/bk-netdev # # include/linux/netdevice.h # 2004/04/16 20:26:15-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/net/Kconfig # 2004/04/16 20:26:15-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/04/16 20:26:15-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/16 20:25:32-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-netdev # # include/linux/netdevice.h # 2004/04/16 20:25:30-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/net/sk_mca.c # 2004/04/16 20:25:30-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/net/Kconfig # 2004/04/16 20:25:30-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/04/16 20:25:30-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/16 20:21:29-04:00 jgarzik@redhat.com # Merge redhat.com:/spare/repo/linux-2.6 # into redhat.com:/spare/repo/netdev-2.6/ALL # # include/linux/netdevice.h # 2004/04/16 20:21:26-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # drivers/net/Kconfig # 2004/04/16 20:21:26-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # MAINTAINERS # 2004/04/16 20:21:25-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # ChangeSet # 2004/04/16 12:37:59-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-netdev # # include/linux/pci_ids.h # 2004/04/16 12:37:56-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/net/sk_mca.c # 2004/04/16 12:37:56-07:00 akpm@bix.(none) +0 -2 # Auto merged # # drivers/net/Kconfig # 2004/04/16 12:37:56-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/14 23:35:07-07:00 akpm@bix.(none) # Merge bk://gkernel.bkbits.net/netdev-2.6 # into bix.(none):/usr/src/bk-netdev # # include/linux/netdevice.h # 2004/04/14 23:35:05-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/net/Kconfig # 2004/04/14 23:35:05-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/04/14 23:35:04-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/14 23:41:57-04:00 jgarzik@redhat.com # Merge redhat.com:/spare/repo/netdev-2.6/misc # into redhat.com:/spare/repo/netdev-2.6/ALL # # include/linux/netdevice.h # 2004/04/14 23:41:54-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # drivers/net/Kconfig # 2004/04/14 23:41:54-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # MAINTAINERS # 2004/04/14 23:41:54-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # ChangeSet # 2004/04/14 18:28:19-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-netdev # # include/linux/pci_ids.h # 2004/04/14 18:28:16-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/13 17:39:02-07:00 akpm@bix.(none) # Merge # # drivers/net/r8169.c # 2004/04/13 17:39:01-07:00 akpm@bix.(none) +0 -0 # SCCS merged # # BitKeeper/deleted/.del-sis190.c~ba98a0b77ca71a32 # 2004/04/13 17:37:09-07:00 akpm@bix.(none) +0 -0 # Auto merged # # include/linux/pci_ids.h # 2004/04/13 17:37:09-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/net/Kconfig # 2004/04/13 17:37:09-07:00 akpm@bix.(none) +0 -0 # Auto merged # # MAINTAINERS # 2004/04/13 17:37:09-07:00 akpm@bix.(none) +0 -0 # Auto merged # # BitKeeper/deleted/.del-sis190.c~ba98a0b77ca71a32 # 2004/04/13 17:37:09-07:00 akpm@bix.(none) +0 -0 # Merge rename: drivers/net/sis190.c -> BitKeeper/deleted/.del-sis190.c~ba98a0b77ca71a32 # # ChangeSet # 2004/04/13 17:32:20-04:00 jgarzik@redhat.com # Merge redhat.com:/spare/repo/netdev-2.6/misc # into redhat.com:/spare/repo/netdev-2.6/ALL # # drivers/net/Kconfig # 2004/04/13 17:32:18-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # ChangeSet # 2004/04/06 11:02:38-04:00 jgarzik@redhat.com # [netdrvr r8169] add local DMA_xxBIT_MASK constants # # drivers/net/r8169.c # 2004/04/06 11:00:24-04:00 jgarzik@redhat.com +3 -0 # [netdrvr r8169] add local DMA_xxBIT_MASK constants # # ChangeSet # 2004/04/06 10:32:58-04:00 jgarzik@redhat.com # Merge redhat.com:/spare/repo/netdev-2.6/janitor # into redhat.com:/spare/repo/netdev-2.6/ALL # # include/linux/netdevice.h # 2004/04/06 10:32:55-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # ChangeSet # 2004/04/06 09:36:49-04:00 jgarzik@redhat.com # Merge redhat.com:/spare/repo/netdev-2.6/s2io # into redhat.com:/spare/repo/netdev-2.6/ALL # # include/linux/pci_ids.h # 2004/04/06 09:36:47-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # ChangeSet # 2004/04/06 08:37:52-04:00 hirofumi@mail.parknet.co.jp # [PATCH] 8139too: more useful debug info for tx_timeout # # Hi, # # I think this patch is useful for looking whether it's the real driver # bug or other bug. # # What do you think of this? If ok, please apply. # -- # OGAWA Hirofumi # # # # [PATCH] 8139too: more useful debug info for tx_timeout # # /* disable Tx ASAP, if not already */ # tmp8 = RTL_R8 (ChipCmd); # if (tmp8 & CmdTxEnb) # RTL_W8 (ChipCmd, CmdRxEnb); # # The above will clear the Tx Descs. So, this prints the debugging info # before rtl8139_tx_timeout() does it. And IntrStatus etc. also prints # anytime for the debug. # # drivers/net/8139too.c # 2004/04/05 12:35:48-04:00 hirofumi@mail.parknet.co.jp +11 -15 # 8139too: more useful debug info for tx_timeout # # ChangeSet # 2004/04/06 08:01:31-04:00 hch@lst.de # [PATCH] convert acenic to pci_driver API # # drivers/net/acenic.c # 2004/04/06 04:01:26-04:00 hch@lst.de +257 -313 # [PATCH] convert acenic to pci_driver API # # ChangeSet # 2004/04/06 08:01:18-04:00 hch@lst.de # [PATCH] kill acient compat cruft from acenic # # Kills lots of really old cruft and adds a little cruft to actually # make the driver work with recent 2.4 again. # # drivers/net/acenic.c # 2004/04/06 03:59:41-04:00 hch@lst.de +4 -225 # [PATCH] kill acient compat cruft from acenic # # Kills lots of really old cruft and adds a little cruft to actually # make the driver work with recent 2.4 again. # # ChangeSet # 2004/03/26 21:32:26-05:00 romieu@fr.zoreil.com # [netdrvr sis190] more RX path work # # - sis190_rx_interrupt converted to classical Rx skb handling; # - rx_copybreak *new. # # Some similarity with the r8169 driver can not be excluded. # # drivers/net/sis190.c # 2004/03/26 20:42:39-05:00 romieu@fr.zoreil.com +78 -38 # 2.6.5-rc2 - sis190 update # # ChangeSet # 2004/03/26 21:32:19-05:00 romieu@fr.zoreil.com # [netdrvr sis190] don't use one huge buffer for all RX skb's # # Replace the giant receive buffer with individually allocated skb. # # drivers/net/sis190.c # 2004/03/26 20:37:47-05:00 romieu@fr.zoreil.com +60 -26 # 2.6.5-rc2 - sis190 update # # ChangeSet # 2004/03/26 21:32:11-05:00 romieu@fr.zoreil.com # [netdrvr sis190] add dirty_rx to private structure # # Add dirty_rx (unused so far). # # drivers/net/sis190.c # 2004/03/26 20:37:25-05:00 romieu@fr.zoreil.com +5 -4 # 2.6.5-rc2 - sis190 update # # ChangeSet # 2004/03/26 21:32:04-05:00 romieu@fr.zoreil.com # [netdrvr sis190] separate out RX skb alloc, fill # # Still no functionnal change. See r8169 driver for details. # # drivers/net/sis190.c # 2004/03/26 20:37:12-05:00 romieu@fr.zoreil.com +38 -13 # 2.6.5-rc2 - sis190 update # # ChangeSet # 2004/03/26 21:31:57-05:00 romieu@fr.zoreil.com # [netdrvr sis190] add helpers # # New helpers (shamelessly stolen from r8169 driver): # - sis190_mark_as_last_descriptor; # - sis190_give_to_asic. # # drivers/net/sis190.c # 2004/03/26 20:36:46-05:00 romieu@fr.zoreil.com +14 -6 # 2.6.5-rc2 - sis190 update # # ChangeSet # 2004/03/26 21:31:50-05:00 romieu@fr.zoreil.com # [netdrvr sis190] sis190_open() fixes/updates # # - make sis190_open() look like r8169_open() as they do the same thing; # - ready sis190_init_ring for incoming DMA api changes; # - trade a "for" loop against a single line, idiomatic, memset(). # # drivers/net/sis190.c # 2004/03/26 17:47:11-05:00 romieu@fr.zoreil.com +29 -28 # 2.6.5-rc2 - sis190 update # # ChangeSet # 2004/03/26 21:31:42-05:00 romieu@fr.zoreil.com # [netdrvr sis190] add pci-disable-device # # Balance the call to pci_enable_device() in SiS190_init_one() with a call # to pci_disable_device() in SiS190_remove_one(). # # drivers/net/sis190.c # 2004/03/26 17:16:58-05:00 romieu@fr.zoreil.com +15 -9 # 2.6.5-rc2 - sis190 update # # ChangeSet # 2004/03/26 21:31:35-05:00 romieu@fr.zoreil.com # [netdrvr sis190] fix endianness issues # # Endianness issues. # Use of le32_to_cpu/cpu_to_le32 in the code which handles the different # components of the Rx descriptors (PSize/status/buf_addr/buf_Len). # # drivers/net/sis190.c # 2004/03/26 17:13:10-05:00 romieu@fr.zoreil.com +21 -24 # 2.6.5-rc2 - sis190 update # # ChangeSet # 2004/03/25 23:52:21-05:00 romieu@fr.zoreil.com # [netdrvr epic100] napi fixes # # Multiple invocation of __netif_rx_schedule() in epic_interrupt() while # epic_poll loops over __netif_rx_complete() leads to serious device # refcount leak. # # drivers/net/epic100.c # 2004/03/25 23:52:16-05:00 romieu@fr.zoreil.com +18 -15 # [netdrvr epic100] napi fixes # # Multiple invocation of __netif_rx_schedule() in epic_interrupt() while # epic_poll loops over __netif_rx_complete() leads to serious device # refcount leak. # # ChangeSet # 2004/03/22 19:07:18-05:00 romieu@fr.zoreil.com # [netdrvr epic100] napi 3/3 - transmit path # # drivers/net/epic100.c # 2004/03/22 18:18:40-05:00 romieu@fr.zoreil.com +9 -11 # 2.6.5-rc2 - epic100 napi # # ChangeSet # 2004/03/22 19:07:11-05:00 romieu@fr.zoreil.com # [netdrvr epic100] napi 2/3 - receive path # # drivers/net/epic100.c # 2004/03/22 18:18:33-05:00 romieu@fr.zoreil.com +116 -21 # 2.6.5-rc2 - epic100 napi # # ChangeSet # 2004/03/22 19:07:03-05:00 romieu@fr.zoreil.com # [netdrvr epic100] napi 1/3 - just shuffle some code around # # Isolate the classical TX part of epic_interrupt. Innocent code shuffling. # # drivers/net/epic100.c # 2004/03/22 16:53:18-05:00 romieu@fr.zoreil.com +76 -61 # 2.6.5-rc2 - epic100 napi # # ChangeSet # 2004/03/22 19:06:56-05:00 romieu@fr.zoreil.com # [netdrvr epic100] minor cleanups # # - extra pci_disable_device() to balance invocation of pci_enable_device() # in epic_init_one() (-> error path + epic_remove_one()); # - lazy return status in epic_init_one(), tsss...; # - memory dedicated to Rx descriptors was not freed after failure of # register_netdev() in epic_init_one(); # - use of epic_pause() in epic_close() offers a small window for a late # interruption just before the final free_irq(). Let's close the window to # avoid two epic_rx() threads racing with each other. # # drivers/net/epic100.c # 2004/03/22 16:53:16-05:00 romieu@fr.zoreil.com +40 -19 # 2.6.5-rc2 - epic100 fixup # diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c --- a/drivers/net/8139too.c Wed Apr 21 00:33:43 2004 +++ b/drivers/net/8139too.c Wed Apr 21 00:33:43 2004 @@ -1677,11 +1677,17 @@ u8 tmp8; unsigned long flags; - DPRINTK ("%s: Transmit timeout, status %2.2x %4.4x " - "media %2.2x.\n", dev->name, - RTL_R8 (ChipCmd), - RTL_R16 (IntrStatus), - RTL_R8 (MediaStatus)); + printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x " + "media %2.2x.\n", dev->name, RTL_R8 (ChipCmd), + RTL_R16(IntrStatus), RTL_R16(IntrMask), RTL_R8(MediaStatus)); + /* Emit info to figure out what went wrong. */ + printk (KERN_DEBUG "%s: Tx queue start entry %ld dirty entry %ld.\n", + dev->name, tp->cur_tx, tp->dirty_tx); + for (i = 0; i < NUM_TX_DESC; i++) + printk (KERN_DEBUG "%s: Tx descriptor %d is %8.8lx.%s\n", + dev->name, i, RTL_R32 (TxStatus0 + (i * 4)), + i == tp->dirty_tx % NUM_TX_DESC ? + " (queue head)" : ""); tp->xstats.tx_timeouts++; @@ -1694,15 +1700,6 @@ /* Disable interrupts by clearing the interrupt mask. */ RTL_W16 (IntrMask, 0x0000); - /* Emit info to figure out what went wrong. */ - printk (KERN_DEBUG "%s: Tx queue start entry %ld dirty entry %ld.\n", - dev->name, tp->cur_tx, tp->dirty_tx); - for (i = 0; i < NUM_TX_DESC; i++) - printk (KERN_DEBUG "%s: Tx descriptor %d is %8.8lx.%s\n", - dev->name, i, RTL_R32 (TxStatus0 + (i * 4)), - i == tp->dirty_tx % NUM_TX_DESC ? - " (queue head)" : ""); - /* Stop a shared interrupt from scavenging while we are. */ spin_lock_irqsave (&tp->lock, flags); rtl8139_tx_clear (tp); @@ -1714,7 +1711,6 @@ netif_wake_queue (dev); } spin_unlock(&tp->rx_lock); - } diff -Nru a/drivers/net/acenic.c b/drivers/net/acenic.c --- a/drivers/net/acenic.c Wed Apr 21 00:33:43 2004 +++ b/drivers/net/acenic.c Wed Apr 21 00:33:44 2004 @@ -131,7 +131,6 @@ #define PCI_DEVICE_ID_SGI_ACENIC 0x0009 #endif -#if LINUX_VERSION_CODE >= 0x20400 static struct pci_device_id acenic_pci_tbl[] = { { PCI_VENDOR_ID_ALTEON, PCI_DEVICE_ID_ALTEON_ACENIC_FIBRE, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, }, @@ -156,37 +155,6 @@ { } }; MODULE_DEVICE_TABLE(pci, acenic_pci_tbl); -#endif - - -#ifndef MODULE_LICENSE -#define MODULE_LICENSE(a) -#endif - -#ifndef wmb -#define wmb() mb() -#endif - -#ifndef __exit -#define __exit -#endif - -#ifndef __devinit -#define __devinit __init -#endif - -#ifndef SMP_CACHE_BYTES -#define SMP_CACHE_BYTES L1_CACHE_BYTES -#endif - -#ifndef SET_MODULE_OWNER -#define SET_MODULE_OWNER(dev) do{} while(0) -#define ACE_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -#define ACE_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -#else -#define ACE_MOD_INC_USE_COUNT do{} while(0) -#define ACE_MOD_DEC_USE_COUNT do{} while(0) -#endif #ifndef SET_NETDEV_DEV #define SET_NETDEV_DEV(net, pdev) do{} while(0) @@ -198,151 +166,8 @@ #define ace_sync_irq(irq) synchronize_irq() #endif -#if LINUX_VERSION_CODE < 0x2051e -#define local_irq_save(flags) do{__save_flags(flags) ; \ - __cli();} while(0) -#define local_irq_restore(flags) __restore_flags(flags) -#endif - -#if (LINUX_VERSION_CODE < 0x02030d) -#define pci_resource_start(dev, bar) dev->base_address[bar] -#elif (LINUX_VERSION_CODE < 0x02032c) -#define pci_resource_start(dev, bar) dev->resource[bar].start -#endif - -#if (LINUX_VERSION_CODE < 0x02030e) -#define net_device device -#endif - - -#if (LINUX_VERSION_CODE < 0x02032a) -typedef u32 dma_addr_t; - -static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t *dma_handle) -{ - void *virt_ptr; - - virt_ptr = kmalloc(size, GFP_KERNEL); - if (!virt_ptr) - return NULL; - *dma_handle = virt_to_bus(virt_ptr); - return virt_ptr; -} - -#define pci_free_consistent(cookie, size, ptr, dma_ptr) kfree(ptr) -#define pci_map_page(cookie, page, off, size, dir) \ - virt_to_bus(page_address(page)+(off)) -#define pci_unmap_page(cookie, address, size, dir) -#define pci_set_dma_mask(dev, mask) \ - (((u64)(mask) & 0xffffffff00000000) == 0 ? 0 : -EIO) -#define pci_dma_supported(dev, mask) \ - (((u64)(mask) & 0xffffffff00000000) == 0 ? 1 : 0) - -#elif (LINUX_VERSION_CODE < 0x02040d) - -/* - * 2.4.13 introduced pci_map_page()/pci_unmap_page() - for 2.4.12 and prior, - * fall back on pci_map_single()/pci_unnmap_single(). - * - * We are guaranteed that the page is mapped at this point since - * pci_map_page() is only used upon valid struct skb's. - */ -static inline dma_addr_t -pci_map_page(struct pci_dev *cookie, struct page *page, unsigned long off, - size_t size, int dir) -{ - void *page_virt; - - page_virt = page_address(page); - if (!page_virt) - BUG(); - return pci_map_single(cookie, (page_virt + off), size, dir); -} -#define pci_unmap_page(cookie, dma_addr, size, dir) \ - pci_unmap_single(cookie, dma_addr, size, dir) -#endif - -#if (LINUX_VERSION_CODE < 0x020412) -#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) -#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) -#define pci_unmap_addr(PTR, ADDR_NAME) 0 -#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do{} while(0) -#define pci_unmap_len(PTR, LEN_NAME) 0 -#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do{} while(0) -#endif - - -#if (LINUX_VERSION_CODE < 0x02032b) -/* - * SoftNet - * - * For pre-softnet kernels we need to tell the upper layer not to - * re-enter start_xmit() while we are in there. However softnet - * guarantees not to enter while we are in there so there is no need - * to do the netif_stop_queue() dance unless the transmit queue really - * gets stuck. This should also improve performance according to tests - * done by Aman Singla. - */ -#define dev_kfree_skb_irq(a) dev_kfree_skb(a) -#define netif_wake_queue(dev) clear_bit(0, &dev->tbusy) -#define netif_stop_queue(dev) set_bit(0, &dev->tbusy) -#define late_stop_netif_stop_queue(dev) do{} while(0) -#define early_stop_netif_stop_queue(dev) test_and_set_bit(0,&dev->tbusy) -#define early_stop_netif_wake_queue(dev) netif_wake_queue(dev) - -static inline void netif_start_queue(struct net_device *dev) -{ - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; -} - -#define ace_mark_net_bh() mark_bh(NET_BH) -#define netif_queue_stopped(dev) dev->tbusy -#define netif_running(dev) dev->start -#define ace_if_down(dev) do{dev->start = 0;} while(0) - -#define tasklet_struct tq_struct -static inline void tasklet_schedule(struct tasklet_struct *tasklet) -{ - queue_task(tasklet, &tq_immediate); - mark_bh(IMMEDIATE_BH); -} - -static inline void tasklet_init(struct tasklet_struct *tasklet, - void (*func)(unsigned long), - unsigned long data) -{ - tasklet->next = NULL; - tasklet->sync = 0; - tasklet->routine = (void (*)(void *))func; - tasklet->data = (void *)data; -} -#define tasklet_kill(tasklet) do{} while(0) -#else -#define late_stop_netif_stop_queue(dev) netif_stop_queue(dev) -#define early_stop_netif_stop_queue(dev) 0 -#define early_stop_netif_wake_queue(dev) do{} while(0) -#define ace_mark_net_bh() do{} while(0) -#define ace_if_down(dev) do{} while(0) -#endif - -#if (LINUX_VERSION_CODE >= 0x02031b) -#define NEW_NETINIT -#define ACE_PROBE_ARG void -#else -#define ACE_PROBE_ARG struct net_device *dev -#endif - -#ifndef min_t -#define min_t(type,a,b) (((a)<(b))?(a):(b)) -#endif - -#ifndef ARCH_HAS_PREFETCHW -#ifndef prefetchw -#define prefetchw(x) do{} while(0) -#endif +#ifndef offset_in_page +#define offset_in_page(ptr) ((unsigned long)(ptr) & ~PAGE_MASK) #endif #define ACE_MAX_MOD_PARMS 8 @@ -595,407 +420,323 @@ static int tx_ratio[ACE_MAX_MOD_PARMS]; static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1}; +MODULE_AUTHOR("Jes Sorensen "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver"); +MODULE_PARM(link, "1-" __MODULE_STRING(8) "i"); +MODULE_PARM(trace, "1-" __MODULE_STRING(8) "i"); +MODULE_PARM(tx_coal_tick, "1-" __MODULE_STRING(8) "i"); +MODULE_PARM(max_tx_desc, "1-" __MODULE_STRING(8) "i"); +MODULE_PARM(rx_coal_tick, "1-" __MODULE_STRING(8) "i"); +MODULE_PARM(max_rx_desc, "1-" __MODULE_STRING(8) "i"); +MODULE_PARM(tx_ratio, "1-" __MODULE_STRING(8) "i"); +MODULE_PARM_DESC(link, "AceNIC/3C985/NetGear link state"); +MODULE_PARM_DESC(trace, "AceNIC/3C985/NetGear firmware trace level"); +MODULE_PARM_DESC(tx_coal_tick, "AceNIC/3C985/GA620 max clock ticks to wait from first tx descriptor arrives"); +MODULE_PARM_DESC(max_tx_desc, "AceNIC/3C985/GA620 max number of transmit descriptors to wait"); +MODULE_PARM_DESC(rx_coal_tick, "AceNIC/3C985/GA620 max clock ticks to wait from first rx descriptor arrives"); +MODULE_PARM_DESC(max_rx_desc, "AceNIC/3C985/GA620 max number of receive descriptors to wait"); +MODULE_PARM_DESC(tx_ratio, "AceNIC/3C985/GA620 ratio of NIC memory used for TX/RX descriptors (range 0-63)"); + + static char version[] __initdata = "acenic.c: v0.92 08/05/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n" " http://home.cern.ch/~jes/gige/acenic.html\n"; -static struct net_device *root_dev; - -static int probed __initdata = 0; - - -int __devinit acenic_probe (ACE_PROBE_ARG) +static int __devinit acenic_probe_one(struct pci_dev *pdev, + const struct pci_device_id *id) { -#ifdef NEW_NETINIT struct net_device *dev; -#endif struct ace_private *ap; - struct pci_dev *pdev = NULL; - int boards_found = 0; - int version_disp; - - if (probed) - return -ENODEV; - probed++; - - version_disp = 0; - - while ((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET<<8, pdev))) { - - if (!((pdev->vendor == PCI_VENDOR_ID_ALTEON) && - ((pdev->device == PCI_DEVICE_ID_ALTEON_ACENIC_FIBRE) || - (pdev->device == PCI_DEVICE_ID_ALTEON_ACENIC_COPPER)))&& - !((pdev->vendor == PCI_VENDOR_ID_3COM) && - (pdev->device == PCI_DEVICE_ID_3COM_3C985)) && - !((pdev->vendor == PCI_VENDOR_ID_NETGEAR) && - ((pdev->device == PCI_DEVICE_ID_NETGEAR_GA620) || - (pdev->device == PCI_DEVICE_ID_NETGEAR_GA620T))) && - /* - * Farallon used the DEC vendor ID on their cards by - * mistake for a while - */ - !((pdev->vendor == PCI_VENDOR_ID_DEC) && - (pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX)) && - !((pdev->vendor == PCI_VENDOR_ID_ALTEON) && - (pdev->device == PCI_DEVICE_ID_FARALLON_PN9100T)) && - !((pdev->vendor == PCI_VENDOR_ID_SGI) && - (pdev->device == PCI_DEVICE_ID_SGI_ACENIC))) - continue; - - dev = alloc_etherdev(sizeof(struct ace_private)); - if (dev == NULL) { - printk(KERN_ERR "acenic: Unable to allocate " - "net_device structure!\n"); - break; - } + static int boards_found; - SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, &pdev->dev); + dev = alloc_etherdev(sizeof(struct ace_private)); + if (dev == NULL) { + printk(KERN_ERR "acenic: Unable to allocate " + "net_device structure!\n"); + return -ENOMEM; + } + + SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &pdev->dev); - ap = dev->priv; - ap->pdev = pdev; + ap = dev->priv; + ap->pdev = pdev; - dev->open = &ace_open; - dev->hard_start_xmit = &ace_start_xmit; - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; + dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; #if ACENIC_DO_VLAN - dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - dev->vlan_rx_register = ace_vlan_rx_register; - dev->vlan_rx_kill_vid = ace_vlan_rx_kill_vid; -#endif - if (1) { - static void ace_watchdog(struct net_device *dev); - dev->tx_timeout = &ace_watchdog; - dev->watchdog_timeo = 5*HZ; - } - dev->stop = &ace_close; - dev->get_stats = &ace_get_stats; - dev->set_multicast_list = &ace_set_multicast_list; - dev->do_ioctl = &ace_ioctl; - dev->set_mac_address = &ace_set_mac_addr; - dev->change_mtu = &ace_change_mtu; + dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + dev->vlan_rx_register = ace_vlan_rx_register; + dev->vlan_rx_kill_vid = ace_vlan_rx_kill_vid; +#endif + if (1) { + static void ace_watchdog(struct net_device *dev); + dev->tx_timeout = &ace_watchdog; + dev->watchdog_timeo = 5*HZ; + } - /* display version info if adapter is found */ - if (!version_disp) - { - /* set display flag to TRUE so that */ - /* we only display this string ONCE */ - version_disp = 1; - printk(version); - } + dev->open = &ace_open; + dev->stop = &ace_close; + dev->hard_start_xmit = &ace_start_xmit; + dev->get_stats = &ace_get_stats; + dev->set_multicast_list = &ace_set_multicast_list; + dev->do_ioctl = &ace_ioctl; + dev->set_mac_address = &ace_set_mac_addr; + dev->change_mtu = &ace_change_mtu; - if (pci_enable_device(pdev)) { - free_netdev(dev); - continue; - } + /* we only display this string ONCE */ + if (!boards_found) + printk(version); - /* - * Enable master mode before we start playing with the - * pci_command word since pci_set_master() will modify - * it. - */ - pci_set_master(pdev); + if (pci_enable_device(pdev)) + goto fail_free_netdev; - pci_read_config_word(pdev, PCI_COMMAND, &ap->pci_command); + /* + * Enable master mode before we start playing with the + * pci_command word since pci_set_master() will modify + * it. + */ + pci_set_master(pdev); - /* OpenFirmware on Mac's does not set this - DOH.. */ - if (!(ap->pci_command & PCI_COMMAND_MEMORY)) { - printk(KERN_INFO "%s: Enabling PCI Memory Mapped " - "access - was not enabled by BIOS/Firmware\n", - dev->name); - ap->pci_command = ap->pci_command | PCI_COMMAND_MEMORY; - pci_write_config_word(ap->pdev, PCI_COMMAND, - ap->pci_command); - wmb(); - } + pci_read_config_word(pdev, PCI_COMMAND, &ap->pci_command); - pci_read_config_byte(pdev, PCI_LATENCY_TIMER, - &ap->pci_latency); - if (ap->pci_latency <= 0x40) { - ap->pci_latency = 0x40; - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, - ap->pci_latency); - } + /* OpenFirmware on Mac's does not set this - DOH.. */ + if (!(ap->pci_command & PCI_COMMAND_MEMORY)) { + printk(KERN_INFO "%s: Enabling PCI Memory Mapped " + "access - was not enabled by BIOS/Firmware\n", + dev->name); + ap->pci_command = ap->pci_command | PCI_COMMAND_MEMORY; + pci_write_config_word(ap->pdev, PCI_COMMAND, + ap->pci_command); + wmb(); + } - /* - * Remap the regs into kernel space - this is abuse of - * dev->base_addr since it was means for I/O port - * addresses but who gives a damn. - */ - dev->base_addr = pci_resource_start(pdev, 0); - ap->regs = (struct ace_regs *)ioremap(dev->base_addr, 0x4000); - if (!ap->regs) { - printk(KERN_ERR "%s: Unable to map I/O register, " - "AceNIC %i will be disabled.\n", - dev->name, boards_found); - break; - } + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &ap->pci_latency); + if (ap->pci_latency <= 0x40) { + ap->pci_latency = 0x40; + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, ap->pci_latency); + } - switch(pdev->vendor) { - case PCI_VENDOR_ID_ALTEON: - if (pdev->device == PCI_DEVICE_ID_FARALLON_PN9100T) { - strncpy(ap->name, "Farallon PN9100-T " - "Gigabit Ethernet", sizeof (ap->name)); - printk(KERN_INFO "%s: Farallon PN9100-T ", - dev->name); - } else { - strncpy(ap->name, "AceNIC Gigabit Ethernet", - sizeof (ap->name)); - printk(KERN_INFO "%s: Alteon AceNIC ", - dev->name); - } - break; - case PCI_VENDOR_ID_3COM: - strncpy(ap->name, "3Com 3C985 Gigabit Ethernet", - sizeof (ap->name)); - printk(KERN_INFO "%s: 3Com 3C985 ", dev->name); - break; - case PCI_VENDOR_ID_NETGEAR: - strncpy(ap->name, "NetGear GA620 Gigabit Ethernet", - sizeof (ap->name)); - printk(KERN_INFO "%s: NetGear GA620 ", dev->name); - break; - case PCI_VENDOR_ID_DEC: - if (pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX) { - strncpy(ap->name, "Farallon PN9000-SX " - "Gigabit Ethernet", sizeof (ap->name)); - printk(KERN_INFO "%s: Farallon PN9000-SX ", - dev->name); - break; - } - case PCI_VENDOR_ID_SGI: - strncpy(ap->name, "SGI AceNIC Gigabit Ethernet", + /* + * Remap the regs into kernel space - this is abuse of + * dev->base_addr since it was means for I/O port + * addresses but who gives a damn. + */ + dev->base_addr = pci_resource_start(pdev, 0); + ap->regs = (struct ace_regs *)ioremap(dev->base_addr, 0x4000); + if (!ap->regs) { + printk(KERN_ERR "%s: Unable to map I/O register, " + "AceNIC %i will be disabled.\n", + dev->name, boards_found); + goto fail_free_netdev; + } + + switch(pdev->vendor) { + case PCI_VENDOR_ID_ALTEON: + if (pdev->device == PCI_DEVICE_ID_FARALLON_PN9100T) { + strncpy(ap->name, "Farallon PN9100-T " + "Gigabit Ethernet", sizeof (ap->name)); + printk(KERN_INFO "%s: Farallon PN9100-T ", + dev->name); + } else { + strncpy(ap->name, "AceNIC Gigabit Ethernet", sizeof (ap->name)); - printk(KERN_INFO "%s: SGI AceNIC ", dev->name); - break; - default: - strncpy(ap->name, "Unknown AceNIC based Gigabit " - "Ethernet", sizeof (ap->name)); - printk(KERN_INFO "%s: Unknown AceNIC ", dev->name); + printk(KERN_INFO "%s: Alteon AceNIC ", + dev->name); + } + break; + case PCI_VENDOR_ID_3COM: + strncpy(ap->name, "3Com 3C985 Gigabit Ethernet", + sizeof (ap->name)); + printk(KERN_INFO "%s: 3Com 3C985 ", dev->name); + break; + case PCI_VENDOR_ID_NETGEAR: + strncpy(ap->name, "NetGear GA620 Gigabit Ethernet", + sizeof (ap->name)); + printk(KERN_INFO "%s: NetGear GA620 ", dev->name); + break; + case PCI_VENDOR_ID_DEC: + if (pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX) { + strncpy(ap->name, "Farallon PN9000-SX " + "Gigabit Ethernet", sizeof (ap->name)); + printk(KERN_INFO "%s: Farallon PN9000-SX ", + dev->name); break; } - ap->name [sizeof (ap->name) - 1] = '\0'; - printk("Gigabit Ethernet at 0x%08lx, ", dev->base_addr); + case PCI_VENDOR_ID_SGI: + strncpy(ap->name, "SGI AceNIC Gigabit Ethernet", + sizeof (ap->name)); + printk(KERN_INFO "%s: SGI AceNIC ", dev->name); + break; + default: + strncpy(ap->name, "Unknown AceNIC based Gigabit " + "Ethernet", sizeof (ap->name)); + printk(KERN_INFO "%s: Unknown AceNIC ", dev->name); + break; + } + + ap->name [sizeof (ap->name) - 1] = '\0'; + printk("Gigabit Ethernet at 0x%08lx, ", dev->base_addr); #ifdef __sparc__ - printk("irq %s\n", __irq_itoa(pdev->irq)); + printk("irq %s\n", __irq_itoa(pdev->irq)); #else - printk("irq %i\n", pdev->irq); + printk("irq %i\n", pdev->irq); #endif #ifdef CONFIG_ACENIC_OMIT_TIGON_I - if ((readl(&ap->regs->HostCtrl) >> 28) == 4) { - printk(KERN_ERR "%s: Driver compiled without Tigon I" - " support - NIC disabled\n", dev->name); - ace_init_cleanup(dev); - free_netdev(dev); - continue; - } + if ((readl(&ap->regs->HostCtrl) >> 28) == 4) { + printk(KERN_ERR "%s: Driver compiled without Tigon I" + " support - NIC disabled\n", dev->name); + goto fail_uninit; + } #endif - if (ace_allocate_descriptors(dev)) { - /* - * ace_allocate_descriptors() calls - * ace_init_cleanup() on error. - */ - free_netdev(dev); - continue; - } + if (ace_allocate_descriptors(dev)) + goto fail_free_netdev; #ifdef MODULE - if (boards_found >= ACE_MAX_MOD_PARMS) - ap->board_idx = BOARD_IDX_OVERFLOW; - else - ap->board_idx = boards_found; + if (boards_found >= ACE_MAX_MOD_PARMS) + ap->board_idx = BOARD_IDX_OVERFLOW; + else + ap->board_idx = boards_found; #else - ap->board_idx = BOARD_IDX_STATIC; + ap->board_idx = BOARD_IDX_STATIC; #endif - if (ace_init(dev)) { - /* - * ace_init() calls ace_init_cleanup() on error. - */ - free_netdev(dev); - continue; - } + if (ace_init(dev)) + goto fail_free_netdev; - if (register_netdev(dev)) { - printk(KERN_ERR "acenic: device registration failed\n"); - ace_init_cleanup(dev); - free_netdev(dev); - continue; - } - - if (ap->pci_using_dac) - dev->features |= NETIF_F_HIGHDMA; - - boards_found++; + if (register_netdev(dev)) { + printk(KERN_ERR "acenic: device registration failed\n"); + goto fail_uninit; } - /* - * If we're at this point we're going through ace_probe() for - * the first time. Return success (0) if we've initialized 1 - * or more boards. Otherwise, return failure (-ENODEV). - */ - - if (boards_found > 0) - return 0; - else - return -ENODEV; -} + if (ap->pci_using_dac) + dev->features |= NETIF_F_HIGHDMA; + pci_set_drvdata(pdev, dev); -#ifdef MODULE -MODULE_AUTHOR("Jes Sorensen "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver"); -MODULE_PARM(link, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(trace, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(tx_coal_tick, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(max_tx_desc, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(rx_coal_tick, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(max_rx_desc, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(tx_ratio, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM_DESC(link, "AceNIC/3C985/NetGear link state"); -MODULE_PARM_DESC(trace, "AceNIC/3C985/NetGear firmware trace level"); -MODULE_PARM_DESC(tx_coal_tick, "AceNIC/3C985/GA620 max clock ticks to wait from first tx descriptor arrives"); -MODULE_PARM_DESC(max_tx_desc, "AceNIC/3C985/GA620 max number of transmit descriptors to wait"); -MODULE_PARM_DESC(rx_coal_tick, "AceNIC/3C985/GA620 max clock ticks to wait from first rx descriptor arrives"); -MODULE_PARM_DESC(max_rx_desc, "AceNIC/3C985/GA620 max number of receive descriptors to wait"); -MODULE_PARM_DESC(tx_ratio, "AceNIC/3C985/GA620 ratio of NIC memory used for TX/RX descriptors (range 0-63)"); -#endif + boards_found++; + return 0; + fail_uninit: + ace_init_cleanup(dev); + fail_free_netdev: + free_netdev(dev); + return -ENODEV; +} -static void __exit ace_module_cleanup(void) +static void __devexit acenic_remove_one(struct pci_dev *pdev) { - struct ace_private *ap; - struct ace_regs *regs; - struct net_device *next; + struct net_device *dev = pci_get_drvdata(pdev); + struct ace_private *ap = dev->priv; + struct ace_regs *regs = ap->regs; short i; - while (root_dev) { - ap = root_dev->priv; - next = ap->next; - unregister_netdev(root_dev); - - regs = ap->regs; + unregister_netdev(dev); - writel(readl(®s->CpuCtrl) | CPU_HALT, ®s->CpuCtrl); - if (ap->version >= 2) - writel(readl(®s->CpuBCtrl) | CPU_HALT, - ®s->CpuBCtrl); - /* - * This clears any pending interrupts - */ - writel(1, ®s->Mb0Lo); - readl(®s->CpuCtrl); /* flush */ + writel(readl(®s->CpuCtrl) | CPU_HALT, ®s->CpuCtrl); + if (ap->version >= 2) + writel(readl(®s->CpuBCtrl) | CPU_HALT, ®s->CpuBCtrl); + + /* + * This clears any pending interrupts + */ + writel(1, ®s->Mb0Lo); + readl(®s->CpuCtrl); /* flush */ - /* - * Make sure no other CPUs are processing interrupts - * on the card before the buffers are being released. - * Otherwise one might experience some `interesting' - * effects. - * - * Then release the RX buffers - jumbo buffers were - * already released in ace_close(). - */ - ace_sync_irq(root_dev->irq); + /* + * Make sure no other CPUs are processing interrupts + * on the card before the buffers are being released. + * Otherwise one might experience some `interesting' + * effects. + * + * Then release the RX buffers - jumbo buffers were + * already released in ace_close(). + */ + ace_sync_irq(dev->irq); - for (i = 0; i < RX_STD_RING_ENTRIES; i++) { - struct sk_buff *skb = ap->skb->rx_std_skbuff[i].skb; + for (i = 0; i < RX_STD_RING_ENTRIES; i++) { + struct sk_buff *skb = ap->skb->rx_std_skbuff[i].skb; - if (skb) { - struct ring_info *ringp; - dma_addr_t mapping; + if (skb) { + struct ring_info *ringp; + dma_addr_t mapping; - ringp = &ap->skb->rx_std_skbuff[i]; - mapping = pci_unmap_addr(ringp, mapping); - pci_unmap_page(ap->pdev, mapping, - ACE_STD_BUFSIZE - (2 + 16), - PCI_DMA_FROMDEVICE); + ringp = &ap->skb->rx_std_skbuff[i]; + mapping = pci_unmap_addr(ringp, mapping); + pci_unmap_page(ap->pdev, mapping, + ACE_STD_BUFSIZE - (2 + 16), + PCI_DMA_FROMDEVICE); - ap->rx_std_ring[i].size = 0; - ap->skb->rx_std_skbuff[i].skb = NULL; - dev_kfree_skb(skb); - } - } - if (ap->version >= 2) { - for (i = 0; i < RX_MINI_RING_ENTRIES; i++) { - struct sk_buff *skb = ap->skb->rx_mini_skbuff[i].skb; - - if (skb) { - struct ring_info *ringp; - dma_addr_t mapping; - - ringp = &ap->skb->rx_mini_skbuff[i]; - mapping = pci_unmap_addr(ringp,mapping); - pci_unmap_page(ap->pdev, mapping, - ACE_MINI_BUFSIZE - (2 + 16), - PCI_DMA_FROMDEVICE); - - ap->rx_mini_ring[i].size = 0; - ap->skb->rx_mini_skbuff[i].skb = NULL; - dev_kfree_skb(skb); - } - } + ap->rx_std_ring[i].size = 0; + ap->skb->rx_std_skbuff[i].skb = NULL; + dev_kfree_skb(skb); } - for (i = 0; i < RX_JUMBO_RING_ENTRIES; i++) { - struct sk_buff *skb = ap->skb->rx_jumbo_skbuff[i].skb; + } + + if (ap->version >= 2) { + for (i = 0; i < RX_MINI_RING_ENTRIES; i++) { + struct sk_buff *skb = ap->skb->rx_mini_skbuff[i].skb; + if (skb) { struct ring_info *ringp; dma_addr_t mapping; - ringp = &ap->skb->rx_jumbo_skbuff[i]; - mapping = pci_unmap_addr(ringp, mapping); + ringp = &ap->skb->rx_mini_skbuff[i]; + mapping = pci_unmap_addr(ringp,mapping); pci_unmap_page(ap->pdev, mapping, - ACE_JUMBO_BUFSIZE - (2 + 16), + ACE_MINI_BUFSIZE - (2 + 16), PCI_DMA_FROMDEVICE); - ap->rx_jumbo_ring[i].size = 0; - ap->skb->rx_jumbo_skbuff[i].skb = NULL; + ap->rx_mini_ring[i].size = 0; + ap->skb->rx_mini_skbuff[i].skb = NULL; dev_kfree_skb(skb); } } - - ace_init_cleanup(root_dev); - free_netdev(root_dev); - root_dev = next; } -} + for (i = 0; i < RX_JUMBO_RING_ENTRIES; i++) { + struct sk_buff *skb = ap->skb->rx_jumbo_skbuff[i].skb; + if (skb) { + struct ring_info *ringp; + dma_addr_t mapping; -int __init ace_module_init(void) -{ - int status; + ringp = &ap->skb->rx_jumbo_skbuff[i]; + mapping = pci_unmap_addr(ringp, mapping); + pci_unmap_page(ap->pdev, mapping, + ACE_JUMBO_BUFSIZE - (2 + 16), + PCI_DMA_FROMDEVICE); - root_dev = NULL; + ap->rx_jumbo_ring[i].size = 0; + ap->skb->rx_jumbo_skbuff[i].skb = NULL; + dev_kfree_skb(skb); + } + } -#ifdef NEW_NETINIT - status = acenic_probe(); -#else - status = acenic_probe(NULL); -#endif - return status; + ace_init_cleanup(dev); + free_netdev(dev); } +static struct pci_driver acenic_pci_driver = { + .name = "acenic", + .id_table = acenic_pci_tbl, + .probe = acenic_probe_one, + .remove = __devexit_p(acenic_remove_one), +}; -#if (LINUX_VERSION_CODE < 0x02032a) -#ifdef MODULE -int init_module(void) +static int __init acenic_init(void) { - return ace_module_init(); + return pci_module_init(&acenic_pci_driver); } - -void cleanup_module(void) +static void __exit acenic_exit(void) { - ace_module_cleanup(); + pci_unregister_driver(&acenic_pci_driver); } -#endif -#else -module_init(ace_module_init); -module_exit(ace_module_cleanup); -#endif +module_init(acenic_init); +module_exit(acenic_exit); static void ace_free_descriptors(struct net_device *dev) { @@ -1462,13 +1203,6 @@ } else dev->irq = pdev->irq; - /* - * Register the device here to be able to catch allocated - * interrupt handlers in case the firmware doesn't come up. - */ - ap->next = root_dev; - root_dev = dev; - #ifdef INDEX_DEBUG spin_lock_init(&ap->debug_lock); ap->last_tx = ACE_TX_RING_ENTRIES(ap) - 1; @@ -2642,8 +2376,6 @@ netif_start_queue(dev); - ACE_MOD_INC_USE_COUNT; - /* * Setup the bottom half rx ring refill handler */ @@ -2660,8 +2392,6 @@ unsigned long flags; short i; - ace_if_down(dev); - /* * Without (or before) releasing irq and stopping hardware, this * is an absolute non-sense, by the way. It will be reset instantly @@ -2733,7 +2463,6 @@ ace_unmask_irq(dev); local_irq_restore(flags); - ACE_MOD_DEC_USE_COUNT; return 0; } @@ -2789,12 +2518,6 @@ struct ace_regs *regs = ap->regs; struct tx_desc *desc; u32 idx, flagsize; - - /* - * This only happens with pre-softnet, ie. 2.2.x kernels. - */ - if (early_stop_netif_stop_queue(dev)) - return 1; restart: idx = ap->tx_prd; diff -Nru a/drivers/net/epic100.c b/drivers/net/epic100.c --- a/drivers/net/epic100.c Wed Apr 21 00:33:43 2004 +++ b/drivers/net/epic100.c Wed Apr 21 00:33:43 2004 @@ -96,9 +96,9 @@ Making the Tx ring too large decreases the effectiveness of channel bonding and packet priority. There are no ill effects from too-large receive rings. */ -#define TX_RING_SIZE 16 -#define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */ -#define RX_RING_SIZE 32 +#define TX_RING_SIZE 256 +#define TX_QUEUE_LEN 240 /* Limit ring entries actually used. */ +#define RX_RING_SIZE 256 #define TX_TOTAL_SIZE TX_RING_SIZE*sizeof(struct epic_tx_desc) #define RX_TOTAL_SIZE RX_RING_SIZE*sizeof(struct epic_rx_desc) @@ -292,6 +292,12 @@ StopTxDMA=0x20, StopRxDMA=0x40, RestartTx=0x80, }; +#define EpicRemoved 0xffffffff /* Chip failed or removed (CardBus) */ + +#define EpicNapiEvent (TxEmpty | TxDone | \ + RxDone | RxStarted | RxEarlyWarn | RxOverflow | RxFull) +#define EpicNormalEvent (0x0000ffff & ~EpicNapiEvent) + static u16 media2miictl[16] = { 0, 0x0C00, 0x0C00, 0x2000, 0x0100, 0x2100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -330,9 +336,12 @@ /* Ring pointers. */ spinlock_t lock; /* Group with Tx control cache line. */ + spinlock_t napi_lock; + unsigned int reschedule_in_poll; unsigned int cur_tx, dirty_tx; unsigned int cur_rx, dirty_rx; + u32 irq_mask; unsigned int rx_buf_sz; /* Based on MTU+slack. */ struct pci_dev *pci_dev; /* PCI bus location. */ @@ -359,7 +368,8 @@ static void epic_tx_timeout(struct net_device *dev); static void epic_init_ring(struct net_device *dev); static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev); -static int epic_rx(struct net_device *dev); +static int epic_rx(struct net_device *dev, int budget); +static int epic_poll(struct net_device *dev, int *budget); static irqreturn_t epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static struct ethtool_ops netdev_ethtool_ops; @@ -378,7 +388,7 @@ int irq; struct net_device *dev; struct epic_private *ep; - int i, option = 0, duplex = 0; + int i, ret, option = 0, duplex = 0; void *ring_space; dma_addr_t ring_dma; @@ -392,29 +402,33 @@ card_idx++; - i = pci_enable_device(pdev); - if (i) - return i; + ret = pci_enable_device(pdev); + if (ret) + goto out; irq = pdev->irq; if (pci_resource_len(pdev, 0) < pci_id_tbl[chip_idx].io_size) { printk (KERN_ERR "card %d: no PCI region space\n", card_idx); - return -ENODEV; + ret = -ENODEV; + goto err_out_disable; } pci_set_master(pdev); + ret = pci_request_regions(pdev, DRV_NAME); + if (ret < 0) + goto err_out_disable; + + ret = -ENOMEM; + dev = alloc_etherdev(sizeof (*ep)); if (!dev) { printk (KERN_ERR "card %d: no memory for eth device\n", card_idx); - return -ENOMEM; + goto err_out_free_res; } SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); - if (pci_request_regions(pdev, DRV_NAME)) - goto err_out_free_netdev; - #ifdef USE_IO_OPS ioaddr = pci_resource_start (pdev, 0); #else @@ -422,7 +436,7 @@ ioaddr = (long) ioremap (ioaddr, pci_resource_len (pdev, 1)); if (!ioaddr) { printk (KERN_ERR DRV_NAME " %d: ioremap failed\n", card_idx); - goto err_out_free_res; + goto err_out_free_netdev; } #endif @@ -459,7 +473,9 @@ dev->base_addr = ioaddr; dev->irq = irq; - spin_lock_init (&ep->lock); + spin_lock_init(&ep->lock); + spin_lock_init(&ep->napi_lock); + ep->reschedule_in_poll = 0; /* Bring the chip out of low-power mode. */ outl(0x4200, ioaddr + GENCTL); @@ -489,6 +505,9 @@ ep->pci_dev = pdev; ep->chip_id = chip_idx; ep->chip_flags = pci_id_tbl[chip_idx].drv_flags; + ep->irq_mask = + (ep->chip_flags & TYPE2_INTR ? PCIBusErr175 : PCIBusErr170) + | CntFull | TxUnderrun | EpicNapiEvent; /* Find the connected MII xcvrs. Doing this in open() would allow detecting external xcvrs later, but @@ -543,10 +562,12 @@ dev->ethtool_ops = &netdev_ethtool_ops; dev->watchdog_timeo = TX_TIMEOUT; dev->tx_timeout = &epic_tx_timeout; + dev->poll = epic_poll; + dev->weight = 64; - i = register_netdev(dev); - if (i) - goto err_out_unmap_tx; + ret = register_netdev(dev); + if (ret < 0) + goto err_out_unmap_rx; printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", dev->name, pci_id_tbl[chip_idx].name, ioaddr, dev->irq); @@ -554,19 +575,24 @@ printk("%2.2x:", dev->dev_addr[i]); printk("%2.2x.\n", dev->dev_addr[i]); - return 0; +out: + return ret; +err_out_unmap_rx: + pci_free_consistent(pdev, RX_TOTAL_SIZE, ep->rx_ring, ep->rx_ring_dma); err_out_unmap_tx: pci_free_consistent(pdev, TX_TOTAL_SIZE, ep->tx_ring, ep->tx_ring_dma); err_out_iounmap: #ifndef USE_IO_OPS iounmap(ioaddr); -err_out_free_res: -#endif - pci_release_regions(pdev); err_out_free_netdev: +#endif free_netdev(dev); - return -ENODEV; +err_out_free_res: + pci_release_regions(pdev); +err_out_disable: + pci_disable_device(pdev); + goto out; } /* Serial EEPROM section. */ @@ -592,6 +618,36 @@ #define EE_READ256_CMD (6 << 8) #define EE_ERASE_CMD (7 << 6) +static void epic_disable_int(struct net_device *dev, struct epic_private *ep) +{ + long ioaddr = dev->base_addr; + + outl(0x00000000, ioaddr + INTMASK); +} + +static inline void __epic_pci_commit(long ioaddr) +{ +#ifndef USE_IO_OPS + inl(ioaddr + INTMASK); +#endif +} + +static void epic_napi_irq_off(struct net_device *dev, struct epic_private *ep) +{ + long ioaddr = dev->base_addr; + + outl(ep->irq_mask & ~EpicNapiEvent, ioaddr + INTMASK); + __epic_pci_commit(ioaddr); +} + +static void epic_napi_irq_on(struct net_device *dev, struct epic_private *ep) +{ + long ioaddr = dev->base_addr; + + /* No need to commit possible posted write */ + outl(ep->irq_mask | EpicNapiEvent, ioaddr + INTMASK); +} + static int __devinit read_eeprom(long ioaddr, int location) { int i; @@ -752,9 +808,8 @@ /* Enable interrupts by setting the interrupt mask. */ outl((ep->chip_flags & TYPE2_INTR ? PCIBusErr175 : PCIBusErr170) - | CntFull | TxUnderrun | TxDone | TxEmpty - | RxError | RxOverflow | RxFull | RxHeader | RxDone, - ioaddr + INTMASK); + | CntFull | TxUnderrun + | RxError | RxHeader | EpicNapiEvent, ioaddr + INTMASK); if (debug > 1) printk(KERN_DEBUG "%s: epic_open() ioaddr %lx IRQ %d status %4.4x " @@ -795,7 +850,7 @@ } /* Remove the packets on the Rx queue. */ - epic_rx(dev); + epic_rx(dev, RX_RING_SIZE); } static void epic_restart(struct net_device *dev) @@ -841,9 +896,9 @@ /* Enable interrupts by setting the interrupt mask. */ outl((ep->chip_flags & TYPE2_INTR ? PCIBusErr175 : PCIBusErr170) - | CntFull | TxUnderrun | TxDone | TxEmpty - | RxError | RxOverflow | RxFull | RxHeader | RxDone, - ioaddr + INTMASK); + | CntFull | TxUnderrun + | RxError | RxHeader | EpicNapiEvent, ioaddr + INTMASK); + printk(KERN_DEBUG "%s: epic_restart() done, cmd status %4.4x, ctl %4.4x" " interrupt %4.4x.\n", dev->name, (int)inl(ioaddr + COMMAND), (int)inl(ioaddr + GENCTL), @@ -929,7 +984,6 @@ int i; ep->tx_full = 0; - ep->lock = (spinlock_t) SPIN_LOCK_UNLOCKED; ep->dirty_tx = ep->cur_tx = 0; ep->cur_rx = ep->dirty_rx = 0; ep->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32); @@ -1029,6 +1083,76 @@ return 0; } +static void epic_tx_error(struct net_device *dev, struct epic_private *ep, + int status) +{ + struct net_device_stats *stats = &ep->stats; + +#ifndef final_version + /* There was an major error, log it. */ + if (debug > 1) + printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n", + dev->name, status); +#endif + stats->tx_errors++; + if (status & 0x1050) + stats->tx_aborted_errors++; + if (status & 0x0008) + stats->tx_carrier_errors++; + if (status & 0x0040) + stats->tx_window_errors++; + if (status & 0x0010) + stats->tx_fifo_errors++; +} + +static void epic_tx(struct net_device *dev, struct epic_private *ep) +{ + unsigned int dirty_tx, cur_tx; + + /* + * Note: if this lock becomes a problem we can narrow the locked + * region at the cost of occasionally grabbing the lock more times. + */ + cur_tx = ep->cur_tx; + for (dirty_tx = ep->dirty_tx; cur_tx - dirty_tx > 0; dirty_tx++) { + struct sk_buff *skb; + int entry = dirty_tx % TX_RING_SIZE; + int txstatus = le32_to_cpu(ep->tx_ring[entry].txstatus); + + if (txstatus & DescOwn) + break; /* It still hasn't been Txed */ + + if (likely(txstatus & 0x0001)) { + ep->stats.collisions += (txstatus >> 8) & 15; + ep->stats.tx_packets++; + ep->stats.tx_bytes += ep->tx_skbuff[entry]->len; + } else + epic_tx_error(dev, ep, txstatus); + + /* Free the original skb. */ + skb = ep->tx_skbuff[entry]; + pci_unmap_single(ep->pci_dev, ep->tx_ring[entry].bufaddr, + skb->len, PCI_DMA_TODEVICE); + dev_kfree_skb_irq(skb); + ep->tx_skbuff[entry] = 0; + } + +#ifndef final_version + if (cur_tx - dirty_tx > TX_RING_SIZE) { + printk(KERN_WARNING + "%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n", + dev->name, dirty_tx, cur_tx, ep->tx_full); + dirty_tx += TX_RING_SIZE; + } +#endif + ep->dirty_tx = dirty_tx; + if (ep->tx_full && cur_tx - dirty_tx < TX_QUEUE_LEN - 4) { + /* The ring is no longer full, allow new TX entries. */ + ep->tx_full = 0; + netif_wake_queue(dev); + } +} + /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ static irqreturn_t epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs) @@ -1042,7 +1166,7 @@ do { status = inl(ioaddr + INTSTAT); /* Acknowledge all of the current interrupt sources ASAP. */ - outl(status & 0x00007fff, ioaddr + INTSTAT); + outl(status & EpicNormalEvent, ioaddr + INTSTAT); if (debug > 4) printk(KERN_DEBUG "%s: Interrupt, status=%#8.8x new " @@ -1053,74 +1177,21 @@ break; handled = 1; - if (status & (RxDone | RxStarted | RxEarlyWarn | RxOverflow)) - epic_rx(dev); - - if (status & (TxEmpty | TxDone)) { - unsigned int dirty_tx, cur_tx; - - /* Note: if this lock becomes a problem we can narrow the locked - region at the cost of occasionally grabbing the lock more - times. */ - spin_lock(&ep->lock); - cur_tx = ep->cur_tx; - dirty_tx = ep->dirty_tx; - for (; cur_tx - dirty_tx > 0; dirty_tx++) { - struct sk_buff *skb; - int entry = dirty_tx % TX_RING_SIZE; - int txstatus = le32_to_cpu(ep->tx_ring[entry].txstatus); - - if (txstatus & DescOwn) - break; /* It still hasn't been Txed */ - - if ( ! (txstatus & 0x0001)) { - /* There was an major error, log it. */ -#ifndef final_version - if (debug > 1) - printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n", - dev->name, txstatus); -#endif - ep->stats.tx_errors++; - if (txstatus & 0x1050) ep->stats.tx_aborted_errors++; - if (txstatus & 0x0008) ep->stats.tx_carrier_errors++; - if (txstatus & 0x0040) ep->stats.tx_window_errors++; - if (txstatus & 0x0010) ep->stats.tx_fifo_errors++; - } else { - ep->stats.collisions += (txstatus >> 8) & 15; - ep->stats.tx_packets++; - ep->stats.tx_bytes += ep->tx_skbuff[entry]->len; - } - - /* Free the original skb. */ - skb = ep->tx_skbuff[entry]; - pci_unmap_single(ep->pci_dev, ep->tx_ring[entry].bufaddr, - skb->len, PCI_DMA_TODEVICE); - dev_kfree_skb_irq(skb); - ep->tx_skbuff[entry] = 0; - } - -#ifndef final_version - if (cur_tx - dirty_tx > TX_RING_SIZE) { - printk(KERN_WARNING "%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n", - dev->name, dirty_tx, cur_tx, ep->tx_full); - dirty_tx += TX_RING_SIZE; - } -#endif - ep->dirty_tx = dirty_tx; - if (ep->tx_full - && cur_tx - dirty_tx < TX_QUEUE_LEN - 4) { - /* The ring is no longer full, allow new TX entries. */ - ep->tx_full = 0; - spin_unlock(&ep->lock); - netif_wake_queue(dev); + if ((status & EpicNapiEvent) && !ep->reschedule_in_poll) { + spin_lock(&ep->napi_lock); + if (netif_rx_schedule_prep(dev)) { + epic_napi_irq_off(dev, ep); + __netif_rx_schedule(dev); } else - spin_unlock(&ep->lock); + ep->reschedule_in_poll++; + spin_unlock(&ep->napi_lock); } + status &= ~EpicNapiEvent; /* Check uncommon events all at once. */ - if (status & (CntFull | TxUnderrun | RxOverflow | RxFull | - PCIBusErr170 | PCIBusErr175)) { - if (status == 0xffffffff) /* Chip failed or removed (CardBus). */ + if (status & + (CntFull | TxUnderrun | PCIBusErr170 | PCIBusErr175)) { + if (status == EpicRemoved) break; /* Always update the error counts to avoid overhead later. */ ep->stats.rx_missed_errors += inb(ioaddr + MPCNT); @@ -1133,11 +1204,6 @@ /* Restart the transmit process. */ outl(RestartTx, ioaddr + COMMAND); } - if (status & RxOverflow) { /* Missed a Rx frame. */ - ep->stats.rx_errors++; - } - if (status & (RxOverflow | RxFull)) - outw(RxQueued, ioaddr + COMMAND); if (status & PCIBusErr170) { printk(KERN_ERR "%s: PCI Bus Error! EPIC status %4.4x.\n", dev->name, status); @@ -1147,6 +1213,8 @@ /* Clear all error sources. */ outl(status & 0x7f18, ioaddr + INTSTAT); } + if (!(status & EpicNormalEvent)) + break; if (--boguscnt < 0) { printk(KERN_ERR "%s: Too much work at interrupt, " "IntrStatus=0x%8.8x.\n", @@ -1164,7 +1232,7 @@ return IRQ_RETVAL(handled); } -static int epic_rx(struct net_device *dev) +static int epic_rx(struct net_device *dev, int budget) { struct epic_private *ep = dev->priv; int entry = ep->cur_rx % RX_RING_SIZE; @@ -1174,6 +1242,10 @@ if (debug > 4) printk(KERN_DEBUG " In epic_rx(), entry %d %8.8x.\n", entry, ep->rx_ring[entry].rxstatus); + + if (rx_work_limit > budget) + rx_work_limit = budget; + /* If we own the next entry, it's a new packet. Send it up. */ while ((ep->rx_ring[entry].rxstatus & cpu_to_le32(DescOwn)) == 0) { int status = le32_to_cpu(ep->rx_ring[entry].rxstatus); @@ -1234,7 +1306,7 @@ ep->rx_skbuff[entry] = NULL; } skb->protocol = eth_type_trans(skb, dev); - netif_rx(skb); + netif_receive_skb(skb); dev->last_rx = jiffies; ep->stats.rx_packets++; ep->stats.rx_bytes += pkt_len; @@ -1262,6 +1334,61 @@ return work_done; } +static void epic_rx_err(struct net_device *dev, struct epic_private *ep) +{ + long ioaddr = dev->base_addr; + int status; + + status = inl(ioaddr + INTSTAT); + + if (status == EpicRemoved) + return; + if (status & RxOverflow) /* Missed a Rx frame. */ + ep->stats.rx_errors++; + if (status & (RxOverflow | RxFull)) + outw(RxQueued, ioaddr + COMMAND); +} + +static int epic_poll(struct net_device *dev, int *budget) +{ + struct epic_private *ep = dev->priv; + int work_done, orig_budget; + long ioaddr = dev->base_addr; + + orig_budget = (*budget > dev->quota) ? dev->quota : *budget; + +rx_action: + + epic_tx(dev, ep); + + work_done = epic_rx(dev, *budget); + + epic_rx_err(dev, ep); + + *budget -= work_done; + dev->quota -= work_done; + + if (netif_running(dev) && (work_done < orig_budget)) { + unsigned long flags; + + spin_lock_irqsave(&ep->napi_lock, flags); + + if (ep->reschedule_in_poll) { + ep->reschedule_in_poll--; + spin_unlock_irqrestore(&ep->napi_lock, flags); + goto rx_action; + } + + outl(EpicNapiEvent, ioaddr + INTSTAT); + epic_napi_irq_on(dev, ep); + __netif_rx_complete(dev); + + spin_unlock_irqrestore(&ep->napi_lock, flags); + } + + return (work_done >= orig_budget); +} + static int epic_close(struct net_device *dev) { long ioaddr = dev->base_addr; @@ -1276,9 +1403,13 @@ dev->name, (int)inl(ioaddr + INTSTAT)); del_timer_sync(&ep->timer); - epic_pause(dev); + + epic_disable_int(dev, ep); + free_irq(dev->irq, dev); + epic_pause(dev); + /* Free all the skbuffs in the Rx queue. */ for (i = 0; i < RX_RING_SIZE; i++) { skb = ep->rx_skbuff[i]; @@ -1476,6 +1607,7 @@ #endif pci_release_regions(pdev); free_netdev(dev); + pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); /* pci_power_off(pdev, -1); */ } diff -Nru a/drivers/net/r8169.c b/drivers/net/r8169.c --- a/drivers/net/r8169.c Wed Apr 21 00:33:44 2004 +++ b/drivers/net/r8169.c Wed Apr 21 00:33:44 2004 @@ -47,6 +47,9 @@ #include +#define DMA_64BIT_MASK 0xffffffffffffffffULL +#define DMA_32BIT_MASK 0xffffffffULL + #define RTL8169_VERSION "1.2" #define MODULENAME "r8169" #define RTL8169_DRIVER_NAME MODULENAME " Gigabit Ethernet driver " RTL8169_VERSION