diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/Documentation/networking/dl2k.txt net-drivers-2.5/Documentation/networking/dl2k.txt --- /home/jgarzik/vanilla/kernel-2.5.7/Documentation/networking/dl2k.txt Mon Mar 18 20:37:06 2002 +++ net-drivers-2.5/Documentation/networking/dl2k.txt Wed Mar 20 19:05:20 2002 @@ -1,7 +1,7 @@ D-Link DL2000-based Gigabit Ethernet Adapter Installation for Linux - Jan 02, 2002 + Jan 29, 2002 Contents ======== @@ -199,8 +199,8 @@ 6 1000Mbps full duplex. By default, the NIC operates at autosense. - Note that only 1000mbps_fd and 1000mbps_hd - types are available for fiber adapter. + 1000mbps_fd and 1000mbps_hd types are only + available for fiber adapter. vlan=[0|1] - Specifies the VLAN ID. If vlan=0, the Virtual Local Area Network (VLAN) function is diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/acenic.c net-drivers-2.5/drivers/net/acenic.c --- /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/acenic.c Mon Mar 18 20:37:14 2002 +++ net-drivers-2.5/drivers/net/acenic.c Wed Mar 20 14:11:44 2002 @@ -65,7 +65,10 @@ #include #include #include + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #include +#endif #ifdef SIOCETHTOOL #include @@ -320,9 +323,11 @@ #if (defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)) && \ defined(NETIF_F_HW_VLAN_RX) -#define ACENIC_DO_VLAN 1 +#define ACENIC_DO_VLAN 1 +#define ACE_RCB_VLAN_FLAG RCB_FLG_VLAN_ASSIST #else -#define ACENIC_DO_VLAN 0 +#define ACENIC_DO_VLAN 0 +#define ACE_RCB_VLAN_FLAG 0 #endif #include "acenic.h" @@ -563,7 +568,7 @@ static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1}; static char version[] __initdata = - "acenic.c: v0.88 03/14/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n" + "acenic.c: v0.89 03/15/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n" " http://home.cern.ch/~jes/gige/acenic.html\n"; static struct net_device *root_dev; @@ -1461,10 +1466,8 @@ set_aceaddr(&info->rx_std_ctrl.rngptr, ap->rx_ring_base_dma); info->rx_std_ctrl.max_len = ACE_STD_MTU + ETH_HLEN + 4; - info->rx_std_ctrl.flags = RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR; -#if ACENIC_DO_VLAN - info->rx_std_ctrl.flags |= RCB_FLG_VLAN_ASSIST; -#endif + info->rx_std_ctrl.flags = + RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG; memset(ap->rx_std_ring, 0, RX_STD_RING_ENTRIES * sizeof(struct rx_desc)); @@ -1479,10 +1482,8 @@ (ap->rx_ring_base_dma + (sizeof(struct rx_desc) * RX_STD_RING_ENTRIES))); info->rx_jumbo_ctrl.max_len = 0; - info->rx_jumbo_ctrl.flags = RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR; -#if ACENIC_DO_VLAN - info->rx_jumbo_ctrl.flags |= RCB_FLG_VLAN_ASSIST; -#endif + info->rx_jumbo_ctrl.flags = + RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG; memset(ap->rx_jumbo_ring, 0, RX_JUMBO_RING_ENTRIES * sizeof(struct rx_desc)); @@ -1504,10 +1505,7 @@ RX_JUMBO_RING_ENTRIES)))); info->rx_mini_ctrl.max_len = ACE_MINI_SIZE; info->rx_mini_ctrl.flags = - RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR; -#if ACENIC_DO_VLAN - info->rx_mini_ctrl.flags |= RCB_FLG_VLAN_ASSIST; -#endif + RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR|ACE_RCB_VLAN_FLAG; for (i = 0; i < RX_MINI_RING_ENTRIES; i++) ap->rx_mini_ring[i].flags = @@ -1554,7 +1552,7 @@ } info->tx_ctrl.max_len = ACE_TX_RING_ENTRIES(ap); - tmp = RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR; + tmp = RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG; /* * The Tigon I does not like having the TX ring in host memory ;-( @@ -1564,9 +1562,6 @@ #if TX_COAL_INTS_ONLY tmp |= RCB_FLG_COAL_INT_ONLY; #endif -#if ACENIC_DO_VLAN - tmp |= RCB_FLG_VLAN_ASSIST; -#endif info->tx_ctrl.flags = tmp; set_aceaddr(&info->tx_csm_ptr, ap->tx_csm_dma); @@ -1592,7 +1587,7 @@ ace_set_rxtx_parms(dev, 0); if (board_idx == BOARD_IDX_OVERFLOW) { - printk(KERN_WARNING "%s: more then %i NICs detected, " + printk(KERN_WARNING "%s: more than %i NICs detected, " "ignoring module parameters!\n", dev->name, ACE_MAX_MOD_PARMS); } else if (board_idx >= 0) { @@ -2181,14 +2176,6 @@ } -#if ACENIC_DO_VLAN -static int ace_vlan_rx(struct ace_private *ap, struct sk_buff *skb, u16 vlan_tag) -{ - return vlan_hwaccel_rx(skb, ap->vlgrp, vlan_tag); -} -#endif - - static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm) { struct ace_private *ap = dev->priv; @@ -2274,11 +2261,9 @@ } /* send it up */ - #if ACENIC_DO_VLAN - if (ap->vlgrp != NULL && - (bd_flags & BD_FLG_VLAN_TAG)) { - ace_vlan_rx(ap, skb, retdesc->vlan); + if (ap->vlgrp && (bd_flags & BD_FLG_VLAN_TAG)) { + vlan_hwaccel_rx(skb, ap->vlgrp, retdesc->vlan); } else #endif netif_rx(skb); diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/acenic.h net-drivers-2.5/drivers/net/acenic.h --- /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/acenic.h Mon Mar 18 20:37:14 2002 +++ net-drivers-2.5/drivers/net/acenic.h Wed Mar 20 14:11:47 2002 @@ -642,10 +642,6 @@ struct ace_skb *skb; dma_addr_t info_dma; /* 32/64 bit */ -#if ACENIC_DO_VLAN - struct vlan_group *vlgrp; -#endif - int version, link; int promisc, mcast_all; @@ -655,7 +651,6 @@ struct tx_desc *tx_ring; u32 tx_prd; volatile u32 tx_ret_csm; - struct timer_list timer; int tx_ring_entries; /* @@ -674,6 +669,10 @@ struct rx_desc *rx_jumbo_ring; struct rx_desc *rx_mini_ring; struct rx_desc *rx_return_ring; + +#if ACENIC_DO_VLAN + struct vlan_group *vlgrp; +#endif int tasklet_pending, jumbo; struct tasklet_struct ace_tasklet; diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/de620.c net-drivers-2.5/drivers/net/de620.c --- /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/de620.c Mon Mar 18 20:37:02 2002 +++ net-drivers-2.5/drivers/net/de620.c Wed Mar 20 19:05:57 2002 @@ -449,11 +449,17 @@ return ret; } - if (adapter_init(dev)) - return -EIO; + if (adapter_init(dev)) { + ret = -EIO; + goto out_free_irq; + } netif_start_queue(dev); return 0; + +out_free_irq: + free_irq(dev->irq, dev); + return ret; } /************************************************ @@ -850,7 +856,10 @@ return -EBUSY; } #endif - request_region(dev->base_addr, 3, "de620"); + if (!request_region(dev->base_addr, 3, "de620")) { + printk(KERN_ERR "io 0x%3lX, which is busy.\n", dev->base_addr); + return -EBUSY; + } /* else, got it! */ printk(", Ethernet Address: %2.2X", diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/dl2k.c net-drivers-2.5/drivers/net/dl2k.c --- /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/dl2k.c Mon Mar 18 20:37:13 2002 +++ net-drivers-2.5/drivers/net/dl2k.c Wed Mar 20 19:05:57 2002 @@ -1,6 +1,6 @@ /* D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */ /* - Copyright (c) 2001 by D-Link Corporation + Copyright (c) 2001,2002 by D-Link Corporation Written by Edward Peng. Created 03-May-2001, base on Linux' sundance.c. @@ -27,12 +27,14 @@ Added tx_coalesce paramter. 1.07 2002/01/03 Fixed miscount of RX frame error. 1.08 2002/01/17 Fixed the multicast bug. + 1.09 2002/03/07 Move rx-poll-now to re-fill loop. + Added rio_timer() to watch rx buffers. */ #include "dl2k.h" static char version[] __devinitdata = - KERN_INFO "D-Link DL2000-based linux driver v1.08 2002/01/17\n"; + KERN_INFO "D-Link DL2000-based linux driver v1.09 2002/03/07\n"; #define MAX_UNITS 8 static int mtu[MAX_UNITS]; @@ -42,9 +44,10 @@ static int tx_flow[MAX_UNITS]; static int rx_flow[MAX_UNITS]; static int copy_thresh; -static int rx_coalesce = DEFAULT_RXC; -static int rx_timeout = DEFAULT_RXT; -static int tx_coalesce = DEFAULT_TXC; +static int rx_coalesce; /* Rx frame count each interrupt */ +static int rx_timeout; /* Rx DMA wait time in 64ns increments */ +static int tx_coalesce = DEFAULT_TXC; /* HW xmit count each TxComplete [1-8] */ + MODULE_AUTHOR ("Edward Peng"); MODULE_DESCRIPTION ("D-Link DL2000-based Gigabit Ethernet Adapter"); @@ -71,6 +74,7 @@ static int multicast_filter_limit = 0x40; static int rio_open (struct net_device *dev); +static void rio_timer (unsigned long data); static void tx_timeout (struct net_device *dev); static void alloc_list (struct net_device *dev); static int start_xmit (struct sk_buff *skb, struct net_device *dev); @@ -146,6 +150,7 @@ np->chip_id = chip_idx; np->pdev = pdev; spin_lock_init (&np->lock); + spin_lock_init (&np->rx_lock); /* Parse manual configuration */ np->an_enable = 1; @@ -260,6 +265,7 @@ np->an_enable = 1; mii_set_media (dev); } + pci_read_config_byte(pdev, PCI_REVISION_ID, &np->pci_rev_id); /* Reset all logic functions */ writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset, @@ -340,7 +346,7 @@ } /* Check CRC */ - crc = ~ether_crc_le(256 - 4, sromdata); + crc = ~ether_crc_le(256 - 4, sromdata); if (psrom->crc != crc) { printk (KERN_ERR "%s: EEPROM data CRC error.\n", dev->name); return -1; @@ -421,8 +427,10 @@ ioaddr + RxDMAIntCtrl); } /* Set RIO to poll every N*320nsec. */ - writeb (0xff, ioaddr + RxDMAPollPeriod); + writeb (0x20, ioaddr + RxDMAPollPeriod); writeb (0xff, ioaddr + TxDMAPollPeriod); + writeb (0x30, ioaddr + RxDMABurstThresh); + writeb (0x30, ioaddr + RxDMAUrgentThresh); netif_start_queue (dev); writel (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl); /* VLAN supported */ @@ -445,9 +453,59 @@ /* clear statistics */ get_stats (dev); + init_timer (&np->timer); + np->timer.expires = jiffies + 1*HZ; + np->timer.data = (unsigned long) dev; + np->timer.function = &rio_timer; + add_timer (&np->timer); return 0; } +static void +rio_timer (unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct netdev_private *np = dev->priv; + unsigned int entry; + int next_tick = 1*HZ; + unsigned long flags; + /* Recover rx ring exhausted error */ + if (np->cur_rx - np->old_rx >= RX_RING_SIZE) { + printk(KERN_INFO "Try to recover rx ring exhausted...\n"); + spin_lock_irqsave(&np->rx_lock, flags); + /* Re-allocate skbuffs to fill the descriptor ring */ + for (; np->cur_rx - np->old_rx > 0; np->old_rx++) { + struct sk_buff *skb; + entry = np->old_rx % RX_RING_SIZE; + /* Dropped packets don't need to re-allocate */ + if (np->rx_skbuff[entry] == NULL) { + skb = dev_alloc_skb (np->rx_buf_sz); + if (skb == NULL) { + np->rx_ring[entry].fraginfo = 0; + printk (KERN_INFO + "%s: Still unable to re-allocate Rx skbuff.#%d\n", + dev->name, entry); + break; + } + np->rx_skbuff[entry] = skb; + skb->dev = dev; + /* 16 byte align the IP header */ + skb_reserve (skb, 2); + np->rx_ring[entry].fraginfo = + cpu_to_le64 (pci_map_single + (np->pdev, skb->tail, np->rx_buf_sz, + PCI_DMA_FROMDEVICE)); + } + np->rx_ring[entry].fraginfo |= + cpu_to_le64 (np->rx_buf_sz) << 48; + np->rx_ring[entry].status = 0; + } /* end for */ + spin_unlock_irqrestore (&np->rx_lock, flags); + } /* end if */ + np->timer.expires = jiffies + next_tick; + add_timer(&np->timer); +} + static void tx_timeout (struct net_device *dev) { @@ -499,16 +557,14 @@ np->tx_ring[i].status = cpu_to_le64 (TFDDone); np->tx_ring[i].next_desc = cpu_to_le64 (np->tx_ring_dma + ((i+1)%TX_RING_SIZE) * - sizeof (struct - netdev_desc)); + sizeof (struct netdev_desc)); } /* Initialize Rx descriptors */ for (i = 0; i < RX_RING_SIZE; i++) { np->rx_ring[i].next_desc = cpu_to_le64 (np->rx_ring_dma + ((i + 1) % RX_RING_SIZE) * - sizeof (struct - netdev_desc)); + sizeof (struct netdev_desc)); np->rx_ring[i].status = 0; np->rx_ring[i].fraginfo = 0; np->rx_skbuff[i] = 0; @@ -529,8 +585,8 @@ skb_reserve (skb, 2); /* 16 byte align the IP header. */ /* Rubicon now supports 40 bits of addressing space. */ np->rx_ring[i].fraginfo = - cpu_to_le64 (pci_map_single - (np->pdev, skb->tail, np->rx_buf_sz, + cpu_to_le64 ( pci_map_single ( + np->pdev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48; } @@ -773,6 +829,8 @@ int entry = np->cur_rx % RX_RING_SIZE; int cnt = np->old_rx + RX_RING_SIZE - np->cur_rx; int rx_shift; + + spin_lock (&np->rx_lock); if (np->old_rx > RX_RING_SIZE) { rx_shift = RX_RING_SIZE; np->old_rx -= rx_shift; @@ -828,12 +886,14 @@ skb_put (skb, pkt_len); } skb->protocol = eth_type_trans (skb, dev); -#if 0 +#if 0 /* Checksum done by hw, but csum value unavailable. */ - if (!(frame_status & (TCPError | UDPError | IPError))) { + if (np->pci_rev_id >= 0x0c && + !(frame_status & (TCPError | UDPError | IPError))) { skb->ip_summed = CHECKSUM_UNNECESSARY; - } + } #endif + netif_rx (skb); dev->last_rx = jiffies; } @@ -849,9 +909,10 @@ skb = dev_alloc_skb (np->rx_buf_sz); if (skb == NULL) { np->rx_ring[entry].fraginfo = 0; - printk (KERN_ERR - "%s: Allocate Rx buffer error!", - dev->name); + printk (KERN_INFO + "%s: receive_packet: " + "Unable to re-allocate Rx skbuff.#%d\n", + dev->name, entry); break; } np->rx_skbuff[entry] = skb; @@ -866,13 +927,12 @@ np->rx_ring[entry].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48; np->rx_ring[entry].status = 0; + /* RxDMAPollNow */ + writel (readl (dev->base_addr + DMACtrl) | 0x00000010, + dev->base_addr + DMACtrl); } - - /* RxDMAPollNow */ - writel (readl (dev->base_addr + DMACtrl) | 0x00000010, - dev->base_addr + DMACtrl); - DEBUG_RFD_DUMP (np, 2); + spin_unlock(&np->rx_lock); return 0; } @@ -1006,7 +1066,7 @@ hash_table[0] = hash_table[1] = 0; /* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */ - hash_table[1] |= 0x02000000; + hash_table[1] |= cpu_to_le32(0x02000000); if (dev->flags & IFF_PROMISC) { /* Receive all frames promiscuously. */ rx_mode = ReceiveAllFrames; @@ -1020,11 +1080,16 @@ rx_mode = ReceiveBroadcast | ReceiveMulticastHash | ReceiveUnicast; for (i=0, mclist = dev->mc_list; mclist && i < dev->mc_count; - i++, mclist=mclist->next) { + i++, mclist=mclist->next) { + crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr); - for (index=0, bit=0; bit<6; bit++, crc<<=1) { - if (crc & 0x80000000) index |= 1 << bit; - } + + /* The inverted high significant 6 bits of CRC are + used as an index to hashtable */ + for (index = 0, bit = 0; bit < 6; bit++) + if (test_bit(31 - bit, &crc)) + set_bit(bit, &index); + hash_table[index / 32] |= (1 << (index % 32)); } } else { @@ -1094,6 +1159,7 @@ np->old_rx); break; case SIOCDEVPRIVATE + 8: + printk("TX ring:\n"); for (i = 0; i < TX_RING_SIZE; i++) { desc = &np->tx_ring[i]; printk @@ -1629,7 +1695,8 @@ writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl); synchronize_irq (); free_irq (dev->irq, dev); - + del_timer_sync (&np->timer); + /* Free all the skbuffs in the queue. */ for (i = 0; i < RX_RING_SIZE; i++) { np->rx_ring[i].status = 0; @@ -1679,10 +1746,10 @@ } static struct pci_driver rio_driver = { - name:"dl2k", - id_table:rio_pci_tbl, - probe:rio_probe1, - remove: __devexit_p(rio_remove1), + name: "dl2k", + id_table: rio_pci_tbl, + probe: rio_probe1, + remove: __devexit_p(rio_remove1), }; static int __init diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/dl2k.h net-drivers-2.5/drivers/net/dl2k.h --- /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/dl2k.h Mon Mar 18 20:37:12 2002 +++ net-drivers-2.5/drivers/net/dl2k.h Wed Mar 20 19:05:57 2002 @@ -1,6 +1,6 @@ /* D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */ /* - Copyright (c) 2001 by D-Link Corporation + Copyright (c) 2001, 2002 by D-Link Corporation Written by Edward Peng. Created 03-May-2001, base on Linux' sundance.c. @@ -649,6 +649,7 @@ dma_addr_t rx_ring_dma; struct pci_dev *pdev; spinlock_t lock; + spinlock_t rx_lock; struct net_device_stats stats; unsigned int rx_buf_sz; /* Based on MTU+slack. */ unsigned int speed; /* Operating speed */ @@ -664,9 +665,11 @@ unsigned int tx_flow:1; /* Tx flow control enable */ unsigned int rx_flow:1; /* Rx flow control enable */ unsigned int phy_media:1; /* 1: fiber, 0: copper */ + unsigned char pci_rev_id; /* PCI revision ID */ struct netdev_desc *last_tx; /* Last Tx descriptor used. */ unsigned long cur_rx, old_rx; /* Producer/consumer ring indices */ unsigned long cur_tx, old_tx; + struct timer_list timer; int wake_polarity; char name[256]; /* net device description */ u8 duplex_polarity; diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/e100/Makefile net-drivers-2.5/drivers/net/e100/Makefile --- /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/e100/Makefile Mon Mar 18 20:37:18 2002 +++ net-drivers-2.5/drivers/net/e100/Makefile Wed Mar 20 19:06:02 2002 @@ -10,7 +10,7 @@ O_TARGET := e100.o obj-y := e100_main.o e100_config.o e100_proc.o e100_phy.o \ - e100_eeprom.o + e100_eeprom.o e100_test.o obj-m := $(O_TARGET) include $(TOPDIR)/Rules.make diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/e100/e100.h net-drivers-2.5/drivers/net/e100/e100.h --- /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/e100/e100.h Mon Mar 18 20:37:10 2002 +++ net-drivers-2.5/drivers/net/e100/e100.h Wed Mar 20 19:06:02 2002 @@ -899,6 +899,15 @@ int PollingMaxWork; u32 b_params; }; +#ifdef ETHTOOL_TEST +struct ethtool_lpbk_data{ + dma_addr_t dma_handle; + tcb_t *tcb; + rfd_t *rfd; + +}; +#endif + struct e100_private { u32 flags; /* board management flags */ @@ -988,6 +997,9 @@ u32 wolopts; u16 ip_lbytes; #endif +#ifdef ETHTOOL_TEST +struct ethtool_lpbk_data loopback; +#endif #ifdef CONFIG_PM u32 pci_state[16]; @@ -1027,5 +1039,24 @@ u8 recover, u8 full_reset); extern unsigned char e100_hw_reset_recover(struct e100_private *bdp, u32 reset_cmd); + +#ifdef ETHTOOL_TEST + +#define ROM_TEST_FAIL 0x01 +#define REGISTER_TEST_FAIL 0x02 +#define SELF_TEST_FAIL 0x04 +#define TEST_TIMEOUT 0x08 + +enum test_offsets { + E100_EEPROM_TEST_FAIL = 0, + E100_CHIP_TIMEOUT, + E100_ROM_TEST_FAIL, + E100_REG_TEST_FAIL, + E100_MAC_TEST_FAIL, + E100_LPBK_MAC_FAIL, + E100_LPBK_PHY_FAIL, + E100_MAX_TEST_RES +}; +#endif #endif diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/e100/e100_config.c net-drivers-2.5/drivers/net/e100/e100_config.c --- /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/e100/e100_config.c Mon Mar 18 20:37:11 2002 +++ net-drivers-2.5/drivers/net/e100/e100_config.c Wed Mar 20 19:06:03 2002 @@ -593,3 +593,102 @@ } #endif +#ifdef ETHTOOL_TEST +/** + * e100_config_loopback_mode + * @bdp: atapter's private data struct + * @mode: loopback mode(phy/mac/none) + * + */ +unsigned char +e100_config_loopback_mode(struct e100_private *bdp, u8 mode) +{ + unsigned char bc_changed = false; + u8 config_byte; + + spin_lock_bh(&(bdp->config_lock)); + + switch (mode) { + case NO_LOOPBACK: + config_byte = CB_CFIG_LOOPBACK_NORMAL; + break; + case MAC_LOOPBACK: + config_byte = CB_CFIG_LOOPBACK_INTERNAL; + break; + case PHY_LOOPBACK: + config_byte = CB_CFIG_LOOPBACK_EXTERNAL; + break; + default: + printk(KERN_NOTICE "e100_config_loopback_mode: " + "Invalid argument 'mode': %d\n", mode); + goto exit; + } + + if ((bdp->config[10] & CB_CFIG_LOOPBACK_MODE) != config_byte) { + + bdp->config[10] &= (~CB_CFIG_LOOPBACK_MODE); + bdp->config[10] |= config_byte; + E100_CONFIG(bdp, 10); + bc_changed = true; + } + +exit: + spin_unlock_bh(&(bdp->config_lock)); + return bc_changed; +} +unsigned char +e100_config_tcb_ext_enable(struct e100_private *bdp, unsigned char enable) +{ + unsigned char bc_changed = false; + + spin_lock_bh(&(bdp->config_lock)); + + if (enable) { + if (bdp->config[6] & CB_CFIG_EXT_TCB_DIS) { + + bdp->config[6] &= (~CB_CFIG_EXT_TCB_DIS); + E100_CONFIG(bdp, 6); + bc_changed = true; + } + + } else { + if (!(bdp->config[6] & CB_CFIG_EXT_TCB_DIS)) { + + bdp->config[6] |= CB_CFIG_EXT_TCB_DIS; + E100_CONFIG(bdp, 6); + bc_changed = true; + } + } + spin_unlock_bh(&(bdp->config_lock)); + + return bc_changed; +} +unsigned char +e100_config_dynamic_tbd(struct e100_private *bdp, unsigned char enable) +{ + unsigned char bc_changed = false; + + spin_lock_bh(&(bdp->config_lock)); + + if (enable) { + if (!(bdp->config[7] & CB_CFIG_DYNTBD_EN)) { + + bdp->config[7] |= CB_CFIG_DYNTBD_EN; + E100_CONFIG(bdp, 7); + bc_changed = true; + } + + } else { + if (bdp->config[7] & CB_CFIG_DYNTBD_EN) { + + bdp->config[7] &= (~CB_CFIG_DYNTBD_EN); + E100_CONFIG(bdp, 7); + bc_changed = true; + } + } + spin_unlock_bh(&(bdp->config_lock)); + + return bc_changed; +} +#endif + diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/e100/e100_config.h net-drivers-2.5/drivers/net/e100/e100_config.h --- /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/e100/e100_config.h Mon Mar 18 20:37:07 2002 +++ net-drivers-2.5/drivers/net/e100/e100_config.h Wed Mar 20 19:06:03 2002 @@ -190,6 +190,10 @@ #define CB_CFIG_LONG_RX_OK BIT_3 +#define NO_LOOPBACK 0 +#define MAC_LOOPBACK 0x01 +#define PHY_LOOPBACK 0x02 + /* function prototypes */ extern void e100_config_init(struct e100_private *bdp); extern unsigned char e100_force_config(struct e100_private *bdp); @@ -201,5 +205,8 @@ unsigned char enable); extern void e100_config_ifs(struct e100_private *bdp); extern void e100_config_force_dplx(struct e100_private *bdp); +extern u8 e100_config_loopback_mode(struct e100_private *bdp, u8 mode); +extern u8 e100_config_dynamic_tbd(struct e100_private *bdp, u8 enable); +extern u8 e100_config_tcb_ext_enable(struct e100_private *bdp, u8 enable); #endif /* _E100_CONFIG_INC_ */ diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/e100/e100_main.c net-drivers-2.5/drivers/net/e100/e100_main.c --- /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/e100/e100_main.c Mon Mar 18 20:37:14 2002 +++ net-drivers-2.5/drivers/net/e100/e100_main.c Wed Mar 20 19:06:03 2002 @@ -147,6 +147,23 @@ static u16 e100_get_ip_lbytes(struct net_device *dev); extern void e100_config_wol(struct e100_private *bdp); #endif +#ifdef ETHTOOL_TEST +extern u32 e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags); +static int e100_ethtool_test(struct net_device *, struct ifreq *); +#endif +#ifdef ETHTOOL_GSTRINGS +static int e100_ethtool_gstrings(struct net_device *, struct ifreq *); +static char *test_strings[] = { + "E100_EEPROM_TEST_FAIL", + "E100_CHIP_TIMEOUT", + "E100_ROM_TEST_FAIL", + "E100_REG_TEST_FAIL", + "E100_MAC_TEST_FAIL", + "E100_LPBK_MAC_FAIL", + "E100_LPBK_PHY_FAIL" +}; + +#endif #endif /*E100_ETHTOOL_IOCTL */ #ifdef SIOCGMIIPHY @@ -165,7 +182,7 @@ /* Global Data structures and variables */ char e100_copyright[] __devinitdata = "Copyright (c) 2002 Intel Corporation"; -#define E100_VERSION "2.0.24-pre1" +#define E100_VERSION "2.0.25-pre1" #define E100_FULL_DRIVER_NAME "Intel(R) PRO/100 Fast Ethernet Adapter - Loadable driver, ver " @@ -382,6 +399,7 @@ MODULE_AUTHOR("Intel Corporation, "); MODULE_DESCRIPTION(E100_FULL_DRIVER_NAME E100_VERSION); MODULE_LICENSE("Dual BSD/GPL"); +EXPORT_NO_SYMBOLS; E100_PARAM(TxDescriptors, "Number of transmit descriptors"); E100_PARAM(RxDescriptors, "Number of receive descriptors"); @@ -2715,8 +2733,10 @@ ntcb_hdr->cb_lnk_ptr = 0; wmb(); + if (in_interrupt()) + return e100_delayed_exec_non_cu_cmd(bdp, command); - if (in_interrupt() || netif_running(bdp->device)) + if (netif_running(bdp->device) && (!bdp->driver_isolated)) return e100_delayed_exec_non_cu_cmd(bdp, command); spin_lock_bh(&(bdp->bd_non_tx_lock)); @@ -3302,6 +3322,16 @@ rc = e100_ethtool_wol(dev, ifr); break; #endif +#ifdef ETHTOOL_TEST + case ETHTOOL_TEST: + rc = e100_ethtool_test(dev, ifr); + break; +#endif +#ifdef ETHTOOL_GSTRINGS + case ETHTOOL_GSTRINGS: + rc = e100_ethtool_gstrings(dev,ifr); + break; +#endif default: break; } //switch @@ -3464,6 +3494,36 @@ } #endif +#ifdef ETHTOOL_TEST +static int +e100_ethtool_test(struct net_device *dev, struct ifreq *ifr) +{ + struct ethtool_test *info; + int rc = -EFAULT; + + info = kmalloc(sizeof(*info) + E100_MAX_TEST_RES * sizeof(u64), + GFP_ATOMIC); + + if (!info) + return -EFAULT; + + memset((void *) info, 0, sizeof(*info) + + E100_MAX_TEST_RES * sizeof(u64)); + + if (copy_from_user(info, ifr->ifr_data, sizeof(*info))) + goto exit; + + info->flags = e100_run_diag(dev, info->data, info->flags); + + if (!copy_to_user(ifr->ifr_data, info, + sizeof(*info) + E100_MAX_TEST_RES * sizeof(u64))) + rc = 0; +exit: + kfree(info); + return rc; +} +#endif + #ifdef ETHTOOL_NWAY_RST static int e100_ethtool_nway_rst(struct net_device *dev, struct ifreq *ifr) @@ -3505,7 +3565,9 @@ #ifdef ETHTOOL_GEEPROM info.eedump_len = (bdp->eeprom_size << 1); #endif - +#ifdef ETHTOOL_TEST + info.testinfo_len = E100_MAX_TEST_RES; +#endif if (copy_to_user(ifr->ifr_data, &info, sizeof (info))) return -EFAULT; @@ -3737,6 +3799,51 @@ return res; } +#endif + +#ifdef ETHTOOL_GSTRINGS +static int e100_ethtool_gstrings(struct net_device *dev, struct ifreq *ifr) +{ + struct ethtool_gstrings info; + char *strings = NULL; + char *usr_strings; + int i; + + memset((void *) &info, 0, sizeof(info)); + + usr_strings = (u8 *) (ifr->ifr_data + + offsetof(struct ethtool_gstrings, data)); + + if (copy_from_user(&info, ifr->ifr_data, sizeof (info))) + return -EFAULT; + + switch (info.string_set) { + case ETH_SS_TEST: + if (info.len > E100_MAX_TEST_RES) + info.len = E100_MAX_TEST_RES; + strings = kmalloc(info.len * ETH_GSTRING_LEN, GFP_ATOMIC); + if (!strings) + return -EFAULT; + memset(strings, 0, info.len * ETH_GSTRING_LEN); + + for (i = 0; i < info.len; i++) { + sprintf(strings + i * ETH_GSTRING_LEN, "%-31s", + test_strings[i]); + } + break; + default: + return -EOPNOTSUPP; + } + + if (copy_to_user(ifr->ifr_data, &info, sizeof (info))) + return -EFAULT; + + if (copy_to_user(usr_strings, strings, info.len * ETH_GSTRING_LEN)) + return -EFAULT; + + kfree(strings); + return 0; +} #endif #endif /*E100_ETHTOOL_IOCTL */ diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/e100/e100_test.c net-drivers-2.5/drivers/net/e100/e100_test.c --- /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/e100/e100_test.c Thu Jan 1 00:00:00 1970 +++ net-drivers-2.5/drivers/net/e100/e100_test.c Wed Mar 20 19:06:04 2002 @@ -0,0 +1,467 @@ +/******************************************************************************* + +This software program is available to you under a choice of one of two +licenses. You may choose to be licensed under either the GNU General Public +License 2.0, June 1991, available at http://www.fsf.org/copyleft/gpl.html, +or the Intel BSD + Patent License, the text of which follows: + +Recipient has requested a license and Intel Corporation ("Intel") is willing +to grant a license for the software entitled Linux Base Driver for the +Intel(R) PRO/100 Family of Adapters (e100) (the "Software") being provided +by Intel Corporation. The following definitions apply to this license: + +"Licensed Patents" means patent claims licensable by Intel Corporation which +are necessarily infringed by the use of sale of the Software alone or when +combined with the operating system referred to below. + +"Recipient" means the party to whom Intel delivers this Software. + +"Licensee" means Recipient and those third parties that receive a license to +any operating system available under the GNU General Public License 2.0 or +later. + +Copyright (c) 1999 - 2002 Intel Corporation. +All rights reserved. + +The license is provided to Recipient and Recipient's Licensees under the +following terms. + +Redistribution and use in source and binary forms of the Software, with or +without modification, are permitted provided that the following conditions +are met: + +Redistributions of source code of the Software may retain the above +copyright notice, this list of conditions and the following disclaimer. + +Redistributions in binary form of the Software may reproduce the above +copyright notice, this list of conditions and the following disclaimer in +the documentation and/or materials provided with the distribution. + +Neither the name of Intel Corporation nor the names of its contributors +shall be used to endorse or promote products derived from this Software +without specific prior written permission. + +Intel hereby grants Recipient and Licensees a non-exclusive, worldwide, +royalty-free patent license under Licensed Patents to make, use, sell, offer +to sell, import and otherwise transfer the Software, if any, in source code +and object code form. This license shall include changes to the Software +that are error corrections or other minor changes to the Software that do +not add functionality or features when the Software is incorporated in any +version of an operating system that has been distributed under the GNU +General Public License 2.0 or later. This patent license shall apply to the +combination of the Software and any operating system licensed under the GNU +General Public License 2.0 or later if, at the time Intel provides the +Software to Recipient, such addition of the Software to the then publicly +available versions of such operating systems available under the GNU General +Public License 2.0 or later (whether in gold, beta or alpha form) causes +such combination to be covered by the Licensed Patents. The patent license +shall not apply to any other combinations which include the Software. NO +hardware per se is licensed hereunder. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) HOWEVER CAUSED +AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#include "e100.h" +#include "e100_config.h" +#ifdef ETHTOOL_TEST + +extern u16 e100_eeprom_read(struct e100_private *, u16); +extern int e100_wait_exec_cmplx(struct e100_private *, u32,u8); +extern void e100_phy_reset(struct e100_private *bdp); + +static u8 e100_diag_selftest(struct net_device *); +static u8 e100_diag_eeprom(struct net_device *); +static u8 e100_diag_loopback(struct net_device *); + +static u8 e100_diag_one_loopback (struct net_device *, u8); +static u8 e100_diag_rcv_loopback_pkt(struct e100_private *); +static void e100_diag_config_loopback(struct e100_private *, u8, u8, u8 *,u8 *); +static u8 e100_diag_loopback_alloc(struct e100_private *); +static void e100_diag_loopback_cu_ru_exec(struct e100_private *); +static u8 e100_diag_check_pkt(u8 *); +static void e100_diag_loopback_free(struct e100_private *); + +#define LB_PACKET_SIZE 1500 + +/** + * e100_run_diag - main test execution handler - checks mask of requests and calls the diag routines + * @dev: atapter's net device data struct + * @test_info: array with test request mask also used to store test results + * + * RETURNS: updated flags field of struct ethtool_test + */ +u32 +e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags) +{ + struct e100_private* bdp = dev->priv; + u8 test_result = true; + + e100_isolate_driver(bdp); + + if (flags & ETH_TEST_FL_OFFLINE) { + u8 fail_mask; + + fail_mask = e100_diag_selftest(dev); + if (fail_mask) { + test_result = false; + if (fail_mask & REGISTER_TEST_FAIL) + test_info [E100_REG_TEST_FAIL] = true; + if (fail_mask & ROM_TEST_FAIL) + test_info [E100_ROM_TEST_FAIL] = true; + if (fail_mask & SELF_TEST_FAIL) + test_info [E100_MAC_TEST_FAIL] = true; + if (fail_mask & TEST_TIMEOUT) + test_info [E100_CHIP_TIMEOUT] = true; + } + + fail_mask = e100_diag_loopback(dev); + if (fail_mask) { + test_result = false; + if (fail_mask & PHY_LOOPBACK) + test_info [E100_LPBK_PHY_FAIL] = true; + if (fail_mask & MAC_LOOPBACK) + test_info [E100_LPBK_MAC_FAIL] = true; + } + } + + if (!e100_diag_eeprom(dev)) { + test_result = false; + test_info [E100_EEPROM_TEST_FAIL] = true; + } + + /* fully recover only if the device is open*/ + if (netif_running(dev)) { + e100_deisolate_driver(bdp, true, false); + } else { + e100_deisolate_driver(bdp, false, false); + } + /*Let card recover from the test*/ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ * 2); + + return flags | (test_result ? 0 : ETH_TEST_FL_FAILED); +} + +/** + * e100_diag_selftest - run hardware selftest + * @dev: atapter's net device data struct + */ +static u8 +e100_diag_selftest(struct net_device *dev) +{ + struct e100_private *bdp = dev->priv; + u32 st_timeout, st_result; + u8 retval = 0; + + if (!e100_selftest(bdp, &st_timeout, &st_result)) { + if (!st_timeout) { + if (st_result & CB_SELFTEST_REGISTER_BIT) + retval |= REGISTER_TEST_FAIL; + if (st_result & CB_SELFTEST_DIAG_BIT) + retval |= SELF_TEST_FAIL; + if (st_result & CB_SELFTEST_ROM_BIT) + retval |= ROM_TEST_FAIL; + } else { + retval = TEST_TIMEOUT; + } + } + + e100_hw_reset_recover(bdp,PORT_SOFTWARE_RESET); + + return retval; +} + +/** + * e100_diag_eeprom - validate eeprom checksum correctness + * @dev: atapter's net device data struct + * + */ +static u8 +e100_diag_eeprom (struct net_device *dev) +{ + struct e100_private *bdp = dev->priv; + u16 i, eeprom_sum, eeprom_actual_csm; + + for (i = 0, eeprom_sum = 0; i < (bdp->eeprom_size - 1); i++) { + eeprom_sum += e100_eeprom_read(bdp, i); + } + + eeprom_actual_csm = e100_eeprom_read(bdp, bdp->eeprom_size - 1); + + if (eeprom_actual_csm == (u16)(EEPROM_SUM - eeprom_sum)) { + return true; + } + + return false; +} + +/** + * e100_diag_loopback - performs loopback test + * @dev: atapter's net device data struct + */ +static u8 +e100_diag_loopback (struct net_device *dev) +{ + u8 rc = 0; + + if (!e100_diag_one_loopback(dev, PHY_LOOPBACK)) { + rc |= PHY_LOOPBACK; + } + + if (!e100_diag_one_loopback(dev, MAC_LOOPBACK)) { + rc |= MAC_LOOPBACK; + } + + return rc; +} + +/** + * e100_diag_loopback - performs loopback test + * @dev: atapter's net device data struct + * @mode: lopback test type + */ +static u8 +e100_diag_one_loopback (struct net_device *dev, u8 mode) +{ + struct e100_private *bdp = dev->priv; + u8 res = false; + u8 saved_dynamic_tbd = false; + u8 saved_extended_tcb = false; + + if (!e100_diag_loopback_alloc(bdp)) + return false; + + /* change the config block to standard tcb and the correct loopback */ + e100_diag_config_loopback(bdp, true, mode, + &saved_extended_tcb, &saved_dynamic_tbd); + + e100_diag_loopback_cu_ru_exec(bdp); + + if (e100_diag_rcv_loopback_pkt(bdp)) { + res = true; + } + + e100_diag_loopback_free(bdp); + + /* change the config block to previous tcb mode and the no loopback */ + e100_diag_config_loopback(bdp, false, mode, + &saved_extended_tcb, &saved_dynamic_tbd); + return res; +} + +/** + * e100_diag_config_loopback - setup/clear loopback before/after lpbk test + * @bdp: atapter's private data struct + * @set_loopback: true if the function is called to set lb + * @loopback_mode: the loopback mode(MAC or PHY) + * @tcb_extended: true if need to set extended tcb mode after clean loopback + * @dynamic_tbd: true if needed to set dynamic tbd mode after clean loopback + * + */ +void +e100_diag_config_loopback(struct e100_private* bdp, + u8 set_loopback, + u8 loopback_mode, + u8* tcb_extended, + u8* dynamic_tbd) +{ + /* if set_loopback == true - we want to clear tcb_extended/dynamic_tbd. + * the previous values are saved in the params tcb_extended/dynamic_tbd + * if set_loopback == false - we want to restore previous value. + */ + if (set_loopback || (*tcb_extended)) + *tcb_extended = e100_config_tcb_ext_enable(bdp,*tcb_extended); + + if (set_loopback || (*dynamic_tbd)) + *dynamic_tbd = e100_config_dynamic_tbd(bdp,*dynamic_tbd); + + if (set_loopback) { + e100_config_loopback_mode(bdp,loopback_mode); + } else { + e100_config_loopback_mode(bdp,NO_LOOPBACK); + } + + e100_config(bdp); + + if (loopback_mode == PHY_LOOPBACK) { + unsigned long expires = jiffies + HZ * 5; + + if (set_loopback) + e100_phy_reset(bdp); + + /* wait up to 5 secs for PHY loopback ON/OFF to take effect */ + while ((e100_get_link_state(bdp) != set_loopback) && + time_before(jiffies, expires)) { + yield(); + } + } else { /* For MAC loopback wait 500 msec to take effect */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 2); + } +} + +/** + * e100_diag_loopback_alloc - alloc & initate tcb and rfd for the loopback + * @bdp: atapter's private data struct + * + */ +static u8 +e100_diag_loopback_alloc(struct e100_private *bdp) +{ + dma_addr_t dma_handle; + tcb_t *tcb; + rfd_t *rfd; + tbd_t *tbd; + + tcb = pci_alloc_consistent(bdp->pdev, + (sizeof (tcb_t) + sizeof (tbd_t) + + LB_PACKET_SIZE), + &dma_handle); + if (tcb == NULL) + return false; + + memset(tcb, 0x00, sizeof (tcb_t) + LB_PACKET_SIZE); + tcb->tcb_phys = dma_handle; + tcb->tcb_hdr.cb_status = 0; + tcb->tcb_hdr.cb_cmd = + cpu_to_le16(CB_EL_BIT | CB_TRANSMIT | CB_TX_SF_BIT); + tcb->tcb_hdr.cb_lnk_ptr = cpu_to_le32(tcb->tcb_phys); + tcb->tcb_tbd_ptr = cpu_to_le32(0xffffffff); + tcb->tcb_cnt = 0; + tcb->tcb_thrshld = bdp->tx_thld; + tcb->tcb_tbd_num = 1; + tcb->tcb_tbd_ptr = cpu_to_le32(tcb->tcb_phys + sizeof (tcb_t)); + tbd = (tbd_t *) ((u8 *) tcb + sizeof (tcb_t)); + tbd->tbd_buf_addr = + cpu_to_le32(le32_to_cpu(tcb->tcb_tbd_ptr) + sizeof (tbd_t)); + tbd->tbd_buf_cnt = __constant_cpu_to_le16(1024); + memset((void *) ((u8 *) tbd + sizeof (tbd_t)), 0xFF, 1024); + memset((void *) ((u8 *) tbd + sizeof (tbd_t) + 512), 0xBA, 512); + wmb(); + rfd = pci_alloc_consistent(bdp->pdev, sizeof (rfd_t), &dma_handle); + + if (rfd == NULL) { + pci_free_consistent(bdp->pdev, + sizeof (tcb_t) + sizeof (tbd_t) + + LB_PACKET_SIZE, tcb, tcb->tcb_phys); + return false; + } + + memset(rfd, 0x00, sizeof (rfd_t)); + + /* init all fields in rfd */ + rfd->rfd_header.cb_status = 0; + rfd->rfd_header.cb_cmd = cpu_to_le16(RFD_EL_BIT); + rfd->rfd_act_cnt = 0; + rfd->rfd_sz = cpu_to_le16(ETH_FRAME_LEN + CHKSUM_SIZE); + bdp->loopback.dma_handle = dma_handle; + bdp->loopback.tcb = tcb; + bdp->loopback.rfd = rfd; + wmb(); + return true; +} + +/** + * e100_diag_loopback_cu_ru_exec - activates cu and ru to send & receive the pkt + * @bdp: atapter's private data struct + * + */ +static void +e100_diag_loopback_cu_ru_exec(struct e100_private *bdp) +{ + /*load CU & RU base */ + if (!e100_wait_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE)) + printk("@@@ SCB_CUC_LOAD_BASE failed\n"); + if(!e100_wait_exec_cmplx(bdp, 0, SCB_RUC_LOAD_BASE)) + printk("@@@ SCB_RUC_LOAD_BASE failed!\n"); + if(!e100_wait_exec_cmplx(bdp, bdp->loopback.dma_handle, SCB_RUC_START)) + printk("@@@ SCB_RUC_START failed!\n"); + + bdp->next_cu_cmd = START_WAIT; + e100_start_cu(bdp, bdp->loopback.tcb); + bdp->last_tcb = NULL; + rmb(); +} +/** + * e100_diag_check_pkt - checks if a given packet is a loopback packet + * @bdp: atapter's private data struct + * + * Returns true if OK false otherwise. + */ +static u8 +e100_diag_check_pkt(u8 *datap) +{ + if( (*datap)==0xFF) { + if(*(datap + 600) == 0xBA) { + return true; + } + } + return false; +} + +/** + * e100_diag_rcv_loopback_pkt - waits for receive and checks lpbk packet + * @bdp: atapter's private data struct + * + * Returns true if OK false otherwise. + */ +static u8 +e100_diag_rcv_loopback_pkt(struct e100_private* bdp) +{ + rfd_t *rfdp; + u16 rfd_status; + unsigned long expires = jiffies + HZ * 2; + + rfdp =bdp->loopback.rfd; + + rfd_status = le16_to_cpu(rfdp->rfd_header.cb_status); + + while (!(rfd_status & RFD_STATUS_COMPLETE)) { + if (time_before(jiffies, expires)) { + yield(); + rmb(); + rfd_status = le16_to_cpu(rfdp->rfd_header.cb_status); + } else { + break; + } + } + + if (rfd_status & RFD_STATUS_COMPLETE) + return e100_diag_check_pkt(((u8 *)rfdp+bdp->rfd_size)); + else + return false; +} + +/** + * e100_diag_loopback_free - free data allocated for loopback pkt send/receive + * @bdp: atapter's private data struct + * + */ +static void +e100_diag_loopback_free (struct e100_private *bdp) +{ + pci_free_consistent(bdp->pdev, + sizeof(tcb_t) + sizeof(tbd_t) + LB_PACKET_SIZE, + bdp->loopback.tcb, bdp->loopback.tcb->tcb_phys); + + pci_free_consistent(bdp->pdev, sizeof(rfd_t), bdp->loopback.rfd, + bdp->loopback.dma_handle); +} + +#endif + + + + + + + + diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/epic100.c net-drivers-2.5/drivers/net/epic100.c --- /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/epic100.c Mon Mar 18 20:37:14 2002 +++ net-drivers-2.5/drivers/net/epic100.c Wed Mar 20 19:05:57 2002 @@ -60,11 +60,14 @@ LK1.1.12: * fix power-up sequence + LK1.1.13: + * revert version 1.1.12, power-up sequence "fix" + */ #define DRV_NAME "epic100" -#define DRV_VERSION "1.11+LK1.1.12" -#define DRV_RELDATE "Jan 18, 2002" +#define DRV_VERSION "1.11+LK1.1.13" +#define DRV_RELDATE "Mar 20, 2002" /* The user-configurable values. @@ -678,8 +681,9 @@ required by the details of which bits are reset and the transceiver wiring on the Ositech CardBus card. */ - - outl(0x12, ioaddr + MIICfg); +#if 0 + outl(dev->if_port == 1 ? 0x13 : 0x12, ioaddr + MIICfg); +#endif if (ep->chip_flags & MII_PWRDWN) outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/wireless/orinoco_plx.c net-drivers-2.5/drivers/net/wireless/orinoco_plx.c --- /home/jgarzik/vanilla/kernel-2.5.7/drivers/net/wireless/orinoco_plx.c Mon Mar 18 20:37:19 2002 +++ net-drivers-2.5/drivers/net/wireless/orinoco_plx.c Wed Mar 20 19:06:13 2002 @@ -267,21 +267,28 @@ pci_set_drvdata(pdev, NULL); } - static struct pci_device_id orinoco_plx_pci_id_table[] __devinitdata = { - {0x1638, 0x1100, PCI_ANY_ID, PCI_ANY_ID,}, + {0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,}, /* Netgear MA301 */ +#if 0 + {0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,}, /* Correga */ +#endif + {0x1638, 0x1100, PCI_ANY_ID, PCI_ANY_ID,}, /* SMC EZConnect SMC2602W, + Eumitcom PCI WL11000, + Addtron AWA-100*/ + {0x16ab, 0x1100, PCI_ANY_ID, PCI_ANY_ID,}, /* Global Sun Tech GL24110P */ + {0x16ab, 0x1101, PCI_ANY_ID, PCI_ANY_ID,}, /* Reported working, but unknown */ + {0x16ab, 0x1102, PCI_ANY_ID, PCI_ANY_ID,}, /* Linksys WDT11 */ + {0x16ec, 0x3685, PCI_ANY_ID, PCI_ANY_ID,}, /* USR 2415 */ + {0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,}, /* Belkin F5D6000 */ {0,}, }; - MODULE_DEVICE_TABLE(pci, orinoco_plx_pci_id_table); static struct pci_driver orinoco_plx_driver = { - name:"orinoco_plx", - id_table:orinoco_plx_pci_id_table, - probe:orinoco_plx_init_one, - remove:__devexit_p(orinoco_plx_remove_one), - suspend:0, - resume:0 + name: "orinoco_plx", + id_table: orinoco_plx_pci_id_table, + probe: orinoco_plx_init_one, + remove: __devexit_p(orinoco_plx_remove_one), }; static int __init orinoco_plx_init(void) diff -Naur -X /g/g/lib/dontdiff /home/jgarzik/vanilla/kernel-2.5.7/include/linux/ethtool.h net-drivers-2.5/include/linux/ethtool.h --- /home/jgarzik/vanilla/kernel-2.5.7/include/linux/ethtool.h Mon Mar 18 20:37:08 2002 +++ net-drivers-2.5/include/linux/ethtool.h Wed Mar 20 19:07:13 2002 @@ -36,7 +36,8 @@ char bus_info[ETHTOOL_BUSINFO_LEN]; /* Bus info for this IF. */ /* For PCI devices, use pci_dev->slot_name. */ char reserved1[32]; - char reserved2[24]; + char reserved2[20]; + u32 testinfo_len; u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */ u32 regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */ }; @@ -210,6 +211,34 @@ u32 tx_pause; }; +#define ETH_GSTRING_LEN 32 +enum ethtool_stringset { + ETH_SS_TEST = 0, + ETH_SS_STATS, +}; + +/* for passing string sets for data tagging */ +struct ethtool_gstrings { + u32 cmd; /* ETHTOOL_GSTRINGS */ + u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/ + u32 len; /* number of strings in the string set */ + u8 data[0]; +}; + +enum ethtool_test_flags { + ETH_TEST_FL_OFFLINE = (1 << 0), /* online / offline */ + ETH_TEST_FL_FAILED = (1 << 1), /* test passed / failed */ +}; + +/* for requesting NIC test and getting results*/ +struct ethtool_test { + u32 cmd; /* ETHTOOL_TEST */ + u32 flags; /* ETH_TEST_FL_xxx */ + u32 reserved; + u32 len; /* result length, in number of u64 elements */ + u64 data[0]; +}; + /* CMDs currently supported */ #define ETHTOOL_GSET 0x00000001 /* Get settings. */ #define ETHTOOL_SSET 0x00000002 /* Set settings, privileged. */ @@ -222,13 +251,13 @@ #define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation, priv. */ #define ETHTOOL_GLINK 0x0000000a /* Get link status (ethtool_value) */ #define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */ -#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data */ +#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data, priv. */ #define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */ -#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config */ +#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config, priv. */ #define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */ -#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters */ +#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters, priv. */ #define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */ -#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters */ +#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters, priv. */ #define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */ #define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */ #define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */ @@ -236,7 +265,9 @@ #define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable * (ethtool_value) */ #define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable - * (ethtool_value) */ + * (ethtool_value), priv. */ +#define ETHTOOL_TEST 0x0000001a /* execute NIC self-test, priv. */ +#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET