Hey Alan, Here's the ns83820 update to 0.10. Relative to the last version, this one has 64 bit addressing fixups for x86 and ia64, zero copy is now working, 6KB jumbo frames are now enabled, configure help is added, and a few cosmetic cleanups. Cheers, -ben diff -urN /md0/kernels/2.4/v2.4.9-ac2/Documentation/Configure.help work-2.4.9-ac2/Documentation/Configure.help --- /md0/kernels/2.4/v2.4.9-ac2/Documentation/Configure.help Mon Aug 27 15:08:38 2001 +++ work-2.4.9-ac2/Documentation/Configure.help Mon Aug 27 17:45:09 2001 @@ -21754,6 +21754,14 @@ . The module will be called nsc-ircc.o. +National Semiconductor DP83820 series driver +CONFIG_NS83820 + This is a driver for the National Semiconductor DP83820 series + of gigabit ethernet MACs. Cards using this chipset include + the D-Link DGE-500T, PureData's PDP8023Z-TG, SMC's SMC9462TX, + SOHO-GA2000T, SOHO-GA2500T. The driver supports the use of + zero copy. + Toshiba Type-O IR Port device driver CONFIG_TOSHIBA_FIR Say Y here if you want to build support for the Toshiba Type-O IR diff -urN /md0/kernels/2.4/v2.4.9-ac2/drivers/net/ns83820.c work-2.4.9-ac2/drivers/net/ns83820.c --- /md0/kernels/2.4/v2.4.9-ac2/drivers/net/ns83820.c Mon Aug 27 15:08:42 2001 +++ work-2.4.9-ac2/drivers/net/ns83820.c Mon Aug 27 18:23:22 2001 @@ -1,6 +1,7 @@ -#define VERSION "0.7" +#define VERSION "0.10" /* ns83820.c by Benjamin LaHaise - * $Revision: 1.28 $ + * + * $Revision: 1.34 $ * * Copyright 2001 Benjamin LaHaise. * Copyright 2001 Red Hat. @@ -35,6 +36,9 @@ * fiddling with TXCFG * 20010810 0.6 - use pci dma api for ringbuffers, work on ia64 * 20010816 0.7 - misc cleanups + * 20010826 0.8 - fix critical zero copy bugs + * 0.9 - internal experiment + * 20010827 0.10 - fix ia64 unaligned access. * * Driver Overview * =============== @@ -48,6 +52,15 @@ * management, d) initialization and configuration. Where possible, * these code paths are designed to run in parallel. * + * This driver has been tested and found to work with the following + * cards (in no particular order): + * + * Cameo SOHO-GA2000T SOHO-GA2500T + * D-Link DGE-500T + * PureData PDP8023Z-TG + * SMC SMC9462TX + * + * Reports of success or failure would be greatly appreciated. */ //#define dprintk printk #define dprintk(x...) do { } while (0) @@ -75,7 +88,9 @@ #endif #ifdef CONFIG_HIGHMEM64G -//#define USE_64BIT_ADDR /* Disabled for now as it doesn't work. */ +#define USE_64BIT_ADDR +#elif defined(__ia64__) +#define USE_64BIT_ADDR #endif /* Tell davem to fix the pci dma api. Grrr. */ @@ -116,7 +131,7 @@ /* tunables */ -#define RX_BUF_SIZE 1536 /* 8192 */ +#define RX_BUF_SIZE 6144 /* 8192 */ #define NR_RX_DESC 256 #define NR_TX_DESC 256 @@ -404,11 +419,10 @@ * possible. */ #ifdef USE_64BIT_ADDR -static inline void build_rx_desc64(struct ns83820 *dev, u32 *desc, void *link, u64 buf, u32 cmdsts, u32 extsts) +static inline void build_rx_desc64(struct ns83820 *dev, u32 *desc, u64 link, u64 buf, u32 cmdsts, u32 extsts) { - u64 lnk = link ? virt_to_phys(link) : 0; - desc[0] = lnk; - desc[1] = 0; //lnk >> 32; + desc[0] = link; + desc[1] = link >> 32; desc[2] = buf; desc[3] = buf >> 32; desc[5] = extsts; @@ -419,9 +433,9 @@ #define build_rx_desc build_rx_desc64 #else -static inline void build_rx_desc32(struct ns83820 *dev, u32 *desc, void *link, u32 buf, u32 cmdsts, u32 extsts) +static inline void build_rx_desc32(struct ns83820 *dev, u32 *desc, u32 link, u32 buf, u32 cmdsts, u32 extsts) { - desc[0] = link ? (u32)virt_to_phys(link) : 0; + desc[0] = link; desc[1] = buf; desc[3] = extsts; mb(); @@ -432,7 +446,7 @@ #endif #define nr_rx_empty(dev) ((NR_RX_DESC-2 + dev->rx_info.next_rx - dev->rx_info.next_empty) % NR_RX_DESC) -static int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb) +static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb) { unsigned next_empty; u32 cmdsts; @@ -463,7 +477,7 @@ dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC; cmdsts = RX_BUF_SIZE | CMDSTS_INTR; buf = pci_map_single(dev->pci_dev, skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); - build_rx_desc(dev, sg, NULL, buf, cmdsts, 0); + build_rx_desc(dev, sg, 0, buf, cmdsts, 0); /* update link of previous rx */ if (next_empty != dev->rx_info.next_rx) dev->rx_info.descs[((NR_RX_DESC + next_empty - 1) % NR_RX_DESC) * DESC_SIZE] = dev->rx_info.phy_descs + (next_empty * DESC_SIZE * 4); @@ -551,11 +565,13 @@ netif_stop_queue(&dev->net_dev); } - printk(KERN_INFO "%s: link now %s mbps, %s duplex and %s.\n", - dev->net_dev.name, - speeds[((cfg / CFG_SPDSTS0) & 3)], - (cfg & CFG_DUPSTS) ? "full" : "half", - (cfg & CFG_LNKSTS) ? "up" : "down"); + if (cfg & CFG_LNKSTS) + printk(KERN_INFO "%s: link now %s mbps, %s duplex and up.\n", + dev->net_dev.name, + speeds[((cfg / CFG_SPDSTS0) & 3)], + (cfg & CFG_DUPSTS) ? "full" : "half"); + else + printk(KERN_INFO "%s: link now down.\n", dev->net_dev.name); } static int ns83820_setup_rx(struct ns83820 *dev) @@ -648,7 +664,7 @@ } /* rx_irq - * + * */ static void FASTCALL(rx_irq(struct ns83820 *dev)); static void rx_irq(struct ns83820 *dev) @@ -716,16 +732,15 @@ if ((extsts & 0x002a0000) && !(extsts & 0x00540000)) { skb->ip_summed = CHECKSUM_UNNECESSARY; } else { - if (len >500) printk("bad\n"); skb->ip_summed = CHECKSUM_NONE; } skb->protocol = eth_type_trans(skb, &dev->net_dev); switch (netif_rx(skb)) { case NET_RX_SUCCESS: - dev->ihr = 0; + dev->ihr = 3; break; case NET_RX_CN_LOW: - dev->ihr = 2; + dev->ihr = 3; break; case NET_RX_CN_MOD: dev->ihr = dev->ihr + 1; @@ -738,14 +753,14 @@ break; } if (dev->ihr > 255) - dev->ihr = 8; + dev->ihr = 255; #ifndef __i386__ done:; #endif } else { static int err; if (err++ < 20) { - Dprintk("error packet: %08x\n", cmdsts); + Dprintk("error packet: cmdsts: %08x extsts: %08x\n", cmdsts, extsts); } kfree_skb(skb); } @@ -895,10 +910,11 @@ } frag = skb_shinfo(skb)->frags; + if (!nr_frags) + frag = 0; extsts = 0; if (skb->ip_summed == CHECKSUM_HW) { extsts |= EXTSTS_IPPKT; - if (IPPROTO_TCP == skb->nh.iph->protocol) extsts |= EXTSTS_TCPPKT; else if (IPPROTO_UDP == skb->nh.iph->protocol) @@ -906,6 +922,8 @@ } len = skb->len; + if (nr_frags) + len -= skb->data_len; buf = pci_map_single(dev->pci_dev, skb->data, len, PCI_DMA_TODEVICE); first_desc = dev->tx_descs + (free_idx * DESC_SIZE); @@ -988,7 +1006,7 @@ if ((ISR_RXDESC) & isr) { rx_irq(dev); - writel(3, dev->base + IHR); + writel(4, dev->base + IHR); } if (nr_rx_empty(dev) >= NR_RX_DESC/4) {