diff options
21 files changed, 33 insertions, 10807 deletions
@@ -88,7 +88,6 @@ 3ddb79bdPyAvT_WZTAFhaX0jp-yXSw xen-2.4.16/drivers/ide/ide_modes.h 3e4a8d401aSwOzCScQXR3lsmNlAwUQ xen-2.4.16/drivers/ide/piix.c 3ddb79bfMlOcWUwjtg6oMYhGySHDDw xen-2.4.16/drivers/net/3c59x.c -3ddb79bfl_DWxZQFKiJ2BXrSedV4lg xen-2.4.16/drivers/net/8139cp.c 3ddb79c0tWiE8xIFHszxipeVCGKTSA xen-2.4.16/drivers/net/Makefile 3ddb79bfU-H1Hms4BuJEPPydjXUEaQ xen-2.4.16/drivers/net/Space.c 3e4540ccS4bfbx9rLiLElP0F1OVwZA xen-2.4.16/drivers/net/e1000/LICENSE @@ -100,28 +99,14 @@ 3e4540ccvQ9Dtoh9tV-L3ULUwN9X7g xen-2.4.16/drivers/net/e1000/e1000_main.c 3e4540cc3t7_y-YLeyMG2pX9xtdXPA xen-2.4.16/drivers/net/e1000/e1000_osdep.h 3e4540cct_8Ig-Y1W_vM2gS_u7mC0A xen-2.4.16/drivers/net/e1000/e1000_param.c -3ddb79c0GejJrp1U6W4G6dYi-RiH4A xen-2.4.16/drivers/net/eepro100.c 3e465c00t2nochqR27eEY_FBjxsUCw xen-2.4.16/drivers/net/ne/8390.c 3e465c00AIRmk20x1vYETtnL71eGvA xen-2.4.16/drivers/net/ne/8390.h 3e465c00UIvPTAtAcgcQWCVFa2bwww xen-2.4.16/drivers/net/ne/Makefile 3e465c00rWSHiXmHuOWLRf7r2n8S3g xen-2.4.16/drivers/net/ne/ne.c 3ddb79bfKvn9mt0kofpkw0QaWjxO6A xen-2.4.16/drivers/net/net_init.c -3ddb79c0fQgORkFlqWZdP-6cDHyFIQ xen-2.4.16/drivers/net/pcnet32.c 3ddb79bf_CBcu3QWYwq4bNAOnM2RqQ xen-2.4.16/drivers/net/setup.c 3e45a0c6u66EL2AI36eLOmf_abXs7g xen-2.4.16/drivers/net/tg3.c 3e45a0c6yrXj5pmQT0PvVSJ01YLABQ xen-2.4.16/drivers/net/tg3.h -3ddb79bfh8ucmq_HqRSaURalpeAmPg xen-2.4.16/drivers/net/tulip/.depend -3ddb79bfsJ-hdQ17EXTFiUOHisjNgQ xen-2.4.16/drivers/net/tulip/21142.c -3ddb79bf0lzTL-ywAdOO7vctTYAmJA xen-2.4.16/drivers/net/tulip/ChangeLog -3ddb79bfRbGBTu5mznHtxpFPtnQYSQ xen-2.4.16/drivers/net/tulip/Makefile -3ddb79bfLLamkCaJZDJ7i6qrCUhwBw xen-2.4.16/drivers/net/tulip/eeprom.c -3ddb79bf-zt39-zIUgWC9Kb4As--Ew xen-2.4.16/drivers/net/tulip/interrupt.c -3ddb79bfdr1I4DtFnXCzpaHkEkHE2Q xen-2.4.16/drivers/net/tulip/media.c -3ddb79bftPnJDLCAo0Do4KPr5raERA xen-2.4.16/drivers/net/tulip/pnic.c -3ddb79bf5lr4NIjy1oZOM_jhpxGidw xen-2.4.16/drivers/net/tulip/pnic2.c -3ddb79bfBhawkz-2DT9lakMPbqzljQ xen-2.4.16/drivers/net/tulip/timer.c -3ddb79bf7yw7hGBMM60aMgMgxY_G2g xen-2.4.16/drivers/net/tulip/tulip.h -3ddb79bfhUr3baP8Lf4oZjhBX7i5kw xen-2.4.16/drivers/net/tulip/tulip_core.c 3ddb79beUWngyIhMHgyPtuTem4o4JA xen-2.4.16/drivers/pci/Makefile 3ddb79beU9td0Mnm0VUMklerBa37qQ xen-2.4.16/drivers/pci/compat.c 3ddb79beHkGQE58z5t5gyUCYiwOxvw xen-2.4.16/drivers/pci/gen-devlist.c diff --git a/xen-2.4.16/drivers/net/8139cp.c b/xen-2.4.16/drivers/net/8139cp.c deleted file mode 100644 index 592a03237f..0000000000 --- a/xen-2.4.16/drivers/net/8139cp.c +++ /dev/null @@ -1,1338 +0,0 @@ -/* 8139cp.c: A Linux PCI Ethernet driver for the RealTek 8139C+ chips. */ -/* - Copyright 2001 Jeff Garzik <jgarzik@mandrakesoft.com> - - Copyright (C) 2000, 2001 David S. Miller (davem@redhat.com) [sungem.c] - Copyright 2001 Manfred Spraul [natsemi.c] - Copyright 1999-2001 by Donald Becker. [natsemi.c] - Written 1997-2001 by Donald Becker. [8139too.c] - Copyright 1998-2001 by Jes Sorensen, <jes@trained-monkey.org>. [acenic.c] - - This software may be used and distributed according to the terms of - the GNU General Public License (GPL), incorporated herein by reference. - Drivers based on or derived from this code fall under the GPL and must - retain the authorship, copyright and license notice. This file is not - a complete program and may only be used when the entire operating - system is licensed under the GPL. - - See the file COPYING in this distribution for more information. - - TODO, in rough priority order: - * dev->tx_timeout - * LinkChg interrupt - * ETHTOOL_[GS]SET - * Support forcing media type with a module parameter, - like dl2k.c/sundance.c - * Implement PCI suspend/resume - * Constants (module parms?) for Rx work limit - * support 64-bit PCI DMA - * Complete reset on PciErr - * Consider Rx interrupt mitigation using TimerIntr - * Implement 8139C+ statistics dump; maybe not... - h/w stats can be reset only by software reset - * Rx checksumming - * Tx checksumming - * ETHTOOL_GREGS, ETHTOOL_[GS]WOL, - ETHTOOL_[GS]MSGLVL, ETHTOOL_NWAY_RST - * Jumbo frames / dev->change_mtu - * Investigate using skb->priority with h/w VLAN priority - * Investigate using High Priority Tx Queue with skb->priority - * Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error - * Adjust Tx FIFO threshold and Max Tx DMA burst on Tx FIFO error - - */ - -#define DRV_NAME "8139cp" -#define DRV_VERSION "0.0.5" -#define DRV_RELDATE "Oct 19, 2001" - - -#include <linux/config.h> -#include <linux/module.h> -//#include <linux/kernel.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/ethtool.h> -#include <asm/io.h> -#include <asm/uaccess.h> - -/* These identify the driver base version and may not be removed. */ -static char version[] __devinitdata = -KERN_INFO DRV_NAME " 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n"; - -MODULE_AUTHOR("Jeff Garzik <jgarzik@mandrakesoft.com>"); -MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver"); -MODULE_LICENSE("GPL"); - -static int debug = -1; -MODULE_PARM (debug, "i"); -MODULE_PARM_DESC (debug, "8139cp bitmapped message enable number"); - -/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). - The RTL chips use a 64 element hash table based on the Ethernet CRC. */ -static int multicast_filter_limit = 32; -MODULE_PARM (multicast_filter_limit, "i"); -MODULE_PARM_DESC (multicast_filter_limit, "8139cp maximum number of filtered multicast addresses"); - -/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */ -/*#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \ - || defined(__sparc_) || defined(__ia64__) \ - || defined(__sh__) || defined(__mips__) -static int rx_copybreak = 1518; -#else -static int rx_copybreak = 100; -#endif*/ - -/* Xen doesn't do rx_copybreak in drivers. */ -static int rx_copybreak = 0; - -MODULE_PARM (rx_copybreak, "i"); -MODULE_PARM_DESC (rx_copybreak, "8139cp Breakpoint at which Rx packets are copied"); - -#define PFX DRV_NAME ": " - -#define CP_DEF_MSG_ENABLE (NETIF_MSG_DRV | \ - NETIF_MSG_PROBE | \ - NETIF_MSG_LINK) -#define CP_REGS_SIZE (0xff + 1) -#define CP_RX_RING_SIZE 64 -#define CP_TX_RING_SIZE 64 -#define CP_RING_BYTES \ - ((sizeof(struct cp_desc) * CP_RX_RING_SIZE) + \ - (sizeof(struct cp_desc) * CP_TX_RING_SIZE)) -#define NEXT_TX(N) (((N) + 1) & (CP_TX_RING_SIZE - 1)) -#define NEXT_RX(N) (((N) + 1) & (CP_RX_RING_SIZE - 1)) -#define TX_BUFFS_AVAIL(CP) \ - (((CP)->tx_tail <= (CP)->tx_head) ? \ - (CP)->tx_tail + (CP_TX_RING_SIZE - 1) - (CP)->tx_head : \ - (CP)->tx_tail - (CP)->tx_head - 1) -#define CP_CHIP_VERSION 0x76 - -#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ -#define RX_OFFSET 2 - -/* The following settings are log_2(bytes)-4: 0 == 16 bytes .. 6==1024, 7==end of packet. */ -#define RX_FIFO_THRESH 5 /* Rx buffer level before first PCI xfer. */ -#define RX_DMA_BURST 4 /* Maximum PCI burst, '4' is 256 */ -#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ -#define TX_EARLY_THRESH 256 /* Early Tx threshold, in bytes */ - -/* Time in jiffies before concluding the transmitter is hung. */ -#define TX_TIMEOUT (6*HZ) - - -enum { - /* NIC register offsets */ - MAC0 = 0x00, /* Ethernet hardware address. */ - MAR0 = 0x08, /* Multicast filter. */ - TxRingAddr = 0x20, /* 64-bit start addr of Tx ring */ - HiTxRingAddr = 0x28, /* 64-bit start addr of high priority Tx ring */ - Cmd = 0x37, /* Command register */ - IntrMask = 0x3C, /* Interrupt mask */ - IntrStatus = 0x3E, /* Interrupt status */ - TxConfig = 0x40, /* Tx configuration */ - ChipVersion = 0x43, /* 8-bit chip version, inside TxConfig */ - RxConfig = 0x44, /* Rx configuration */ - Cfg9346 = 0x50, /* EEPROM select/control; Cfg reg [un]lock */ - Config1 = 0x52, /* Config1 */ - Config3 = 0x59, /* Config3 */ - Config4 = 0x5A, /* Config4 */ - MultiIntr = 0x5C, /* Multiple interrupt select */ - Config5 = 0xD8, /* Config5 */ - TxPoll = 0xD9, /* Tell chip to check Tx descriptors for work */ - CpCmd = 0xE0, /* C+ Command register (C+ mode only) */ - RxRingAddr = 0xE4, /* 64-bit start addr of Rx ring */ - TxThresh = 0xEC, /* Early Tx threshold */ - OldRxBufAddr = 0x30, /* DMA address of Rx ring buffer (C mode) */ - OldTSD0 = 0x10, /* DMA address of first Tx desc (C mode) */ - - /* Tx and Rx status descriptors */ - DescOwn = (1 << 31), /* Descriptor is owned by NIC */ - RingEnd = (1 << 30), /* End of descriptor ring */ - FirstFrag = (1 << 29), /* First segment of a packet */ - LastFrag = (1 << 28), /* Final segment of a packet */ - TxError = (1 << 23), /* Tx error summary */ - RxError = (1 << 20), /* Rx error summary */ - IPCS = (1 << 18), /* Calculate IP checksum */ - UDPCS = (1 << 17), /* Calculate UDP/IP checksum */ - TCPCS = (1 << 16), /* Calculate TCP/IP checksum */ - IPFail = (1 << 15), /* IP checksum failed */ - UDPFail = (1 << 14), /* UDP/IP checksum failed */ - TCPFail = (1 << 13), /* TCP/IP checksum failed */ - NormalTxPoll = (1 << 6), /* One or more normal Tx packets to send */ - PID1 = (1 << 17), /* 2 protocol id bits: 0==non-IP, */ - PID0 = (1 << 16), /* 1==UDP/IP, 2==TCP/IP, 3==IP */ - TxFIFOUnder = (1 << 25), /* Tx FIFO underrun */ - TxOWC = (1 << 22), /* Tx Out-of-window collision */ - TxLinkFail = (1 << 21), /* Link failed during Tx of packet */ - TxMaxCol = (1 << 20), /* Tx aborted due to excessive collisions */ - TxColCntShift = 16, /* Shift, to get 4-bit Tx collision cnt */ - TxColCntMask = 0x01 | 0x02 | 0x04 | 0x08, /* 4-bit collision count */ - RxErrFrame = (1 << 27), /* Rx frame alignment error */ - RxMcast = (1 << 26), /* Rx multicast packet rcv'd */ - RxErrCRC = (1 << 18), /* Rx CRC error */ - RxErrRunt = (1 << 19), /* Rx error, packet < 64 bytes */ - RxErrLong = (1 << 21), /* Rx error, packet > 4096 bytes */ - RxErrFIFO = (1 << 22), /* Rx error, FIFO overflowed, pkt bad */ - - /* RxConfig register */ - RxCfgFIFOShift = 13, /* Shift, to get Rx FIFO thresh value */ - RxCfgDMAShift = 8, /* Shift, to get Rx Max DMA value */ - AcceptErr = 0x20, /* Accept packets with CRC errors */ - AcceptRunt = 0x10, /* Accept runt (<64 bytes) packets */ - AcceptBroadcast = 0x08, /* Accept broadcast packets */ - AcceptMulticast = 0x04, /* Accept multicast packets */ - AcceptMyPhys = 0x02, /* Accept pkts with our MAC as dest */ - AcceptAllPhys = 0x01, /* Accept all pkts w/ physical dest */ - - /* IntrMask / IntrStatus registers */ - PciErr = (1 << 15), /* System error on the PCI bus */ - TimerIntr = (1 << 14), /* Asserted when TCTR reaches TimerInt value */ - LenChg = (1 << 13), /* Cable length change */ - SWInt = (1 << 8), /* Software-requested interrupt */ - TxEmpty = (1 << 7), /* No Tx descriptors available */ - RxFIFOOvr = (1 << 6), /* Rx FIFO Overflow */ - LinkChg = (1 << 5), /* Packet underrun, or link change */ - RxEmpty = (1 << 4), /* No Rx descriptors available */ - TxErr = (1 << 3), /* Tx error */ - TxOK = (1 << 2), /* Tx packet sent */ - RxErr = (1 << 1), /* Rx error */ - RxOK = (1 << 0), /* Rx packet received */ - IntrResvd = (1 << 10), /* reserved, according to RealTek engineers, - but hardware likes to raise it */ - - IntrAll = PciErr | TimerIntr | LenChg | SWInt | TxEmpty | - RxFIFOOvr | LinkChg | RxEmpty | TxErr | TxOK | - RxErr | RxOK | IntrResvd, - - /* C mode command register */ - CmdReset = (1 << 4), /* Enable to reset; self-clearing */ - RxOn = (1 << 3), /* Rx mode enable */ - TxOn = (1 << 2), /* Tx mode enable */ - - /* C+ mode command register */ - RxChkSum = (1 << 5), /* Rx checksum offload enable */ - PCIMulRW = (1 << 3), /* Enable PCI read/write multiple */ - CpRxOn = (1 << 1), /* Rx mode enable */ - CpTxOn = (1 << 0), /* Tx mode enable */ - - /* Cfg9436 EEPROM control register */ - Cfg9346_Lock = 0x00, /* Lock ConfigX/MII register access */ - Cfg9346_Unlock = 0xC0, /* Unlock ConfigX/MII register access */ - - /* TxConfig register */ - IFG = (1 << 25) | (1 << 24), /* standard IEEE interframe gap */ - TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ - - /* Early Tx Threshold register */ - TxThreshMask = 0x3f, /* Mask bits 5-0 */ - TxThreshMax = 2048, /* Max early Tx threshold */ - - /* Config1 register */ - DriverLoaded = (1 << 5), /* Software marker, driver is loaded */ - PMEnable = (1 << 0), /* Enable various PM features of chip */ - - /* Config3 register */ - PARMEnable = (1 << 6), /* Enable auto-loading of PHY parms */ - - /* Config5 register */ - PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ -}; - -static const unsigned int cp_intr_mask = - PciErr | LinkChg | - RxOK | RxErr | RxEmpty | RxFIFOOvr | - TxOK | TxErr | TxEmpty; - -static const unsigned int cp_rx_config = - (RX_FIFO_THRESH << RxCfgFIFOShift) | - (RX_DMA_BURST << RxCfgDMAShift); - -struct cp_desc { - u32 opts1; - u32 opts2; - u32 addr_lo; - u32 addr_hi; -}; - -struct ring_info { - struct sk_buff *skb; - dma_addr_t mapping; - unsigned frag; -}; - -struct cp_extra_stats { - unsigned long rx_frags; -}; - -struct cp_private { - unsigned tx_head; - unsigned tx_tail; - unsigned rx_tail; - - void *regs; - struct net_device *dev; - spinlock_t lock; - - struct cp_desc *rx_ring; - struct cp_desc *tx_ring; - struct ring_info tx_skb[CP_TX_RING_SIZE]; - struct ring_info rx_skb[CP_RX_RING_SIZE]; - unsigned rx_buf_sz; - dma_addr_t ring_dma; - - u32 msg_enable; - - struct net_device_stats net_stats; - struct cp_extra_stats cp_stats; - - struct pci_dev *pdev; - u32 rx_config; - - struct sk_buff *frag_skb; - unsigned dropping_frag : 1; -}; - -#define cpr8(reg) readb(cp->regs + (reg)) -#define cpr16(reg) readw(cp->regs + (reg)) -#define cpr32(reg) readl(cp->regs + (reg)) -#define cpw8(reg,val) writeb((val), cp->regs + (reg)) -#define cpw16(reg,val) writew((val), cp->regs + (reg)) -#define cpw32(reg,val) writel((val), cp->regs + (reg)) -#define cpw8_f(reg,val) do { \ - writeb((val), cp->regs + (reg)); \ - readb(cp->regs + (reg)); \ - } while (0) -#define cpw16_f(reg,val) do { \ - writew((val), cp->regs + (reg)); \ - readw(cp->regs + (reg)); \ - } while (0) -#define cpw32_f(reg,val) do { \ - writel((val), cp->regs + (reg)); \ - readl(cp->regs + (reg)); \ - } while (0) - - -static void __cp_set_rx_mode (struct net_device *dev); -static void cp_tx (struct cp_private *cp); -static void cp_clean_rings (struct cp_private *cp); - - -static struct pci_device_id cp_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { }, -}; -MODULE_DEVICE_TABLE(pci, cp_pci_tbl); - -static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb) -{ - skb->protocol = eth_type_trans (skb, cp->dev); - - cp->net_stats.rx_packets++; - cp->net_stats.rx_bytes += skb->len; - cp->dev->last_rx = jiffies; - netif_rx (skb); -} - -static inline void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail, - u32 status, u32 len) -{ - if (netif_msg_rx_err (cp)) - printk (KERN_DEBUG - "%s: rx err, slot %d status 0x%x len %d\n", - cp->dev->name, rx_tail, status, len); - cp->net_stats.rx_errors++; - if (status & RxErrFrame) - cp->net_stats.rx_frame_errors++; - if (status & RxErrCRC) - cp->net_stats.rx_crc_errors++; - if (status & RxErrRunt) - cp->net_stats.rx_length_errors++; - if (status & RxErrLong) - cp->net_stats.rx_length_errors++; - if (status & RxErrFIFO) - cp->net_stats.rx_fifo_errors++; -} - -static void cp_rx_frag (struct cp_private *cp, unsigned rx_tail, - struct sk_buff *skb, u32 status, u32 len) -{ - struct sk_buff *copy_skb, *frag_skb = cp->frag_skb; - unsigned orig_len = frag_skb ? frag_skb->len : 0; - unsigned target_len = orig_len + len; - unsigned first_frag = status & FirstFrag; - unsigned last_frag = status & LastFrag; - - if (netif_msg_rx_status (cp)) - printk (KERN_DEBUG "%s: rx %s%sfrag, slot %d status 0x%x len %d\n", - cp->dev->name, - cp->dropping_frag ? "dropping " : "", - first_frag ? "first " : - last_frag ? "last " : "", - rx_tail, status, len); - - cp->cp_stats.rx_frags++; - - if (!frag_skb && !first_frag) - cp->dropping_frag = 1; - if (cp->dropping_frag) - goto drop_frag; - - copy_skb = dev_alloc_skb (target_len + RX_OFFSET); - if (!copy_skb) { - printk(KERN_WARNING "%s: rx slot %d alloc failed\n", - cp->dev->name, rx_tail); - - cp->dropping_frag = 1; -drop_frag: - if (frag_skb) { - dev_kfree_skb_irq(frag_skb); - cp->frag_skb = NULL; - } - if (last_frag) { - cp->net_stats.rx_dropped++; - cp->dropping_frag = 0; - } - return; - } - - copy_skb->dev = cp->dev; - skb_reserve(copy_skb, RX_OFFSET); - skb_put(copy_skb, target_len); - if (frag_skb) { - memcpy(copy_skb->data, frag_skb->data, orig_len); - dev_kfree_skb_irq(frag_skb); - } - pci_dma_sync_single(cp->pdev, cp->rx_skb[rx_tail].mapping, - len, PCI_DMA_FROMDEVICE); - memcpy(copy_skb->data + orig_len, skb->data, len); - - copy_skb->ip_summed = CHECKSUM_NONE; - - if (last_frag) { - if (status & (RxError | RxErrFIFO)) { - cp_rx_err_acct(cp, rx_tail, status, len); - dev_kfree_skb_irq(copy_skb); - } else - cp_rx_skb(cp, copy_skb); - cp->frag_skb = NULL; - } else { - cp->frag_skb = copy_skb; - } -} - -static void cp_rx (struct cp_private *cp) -{ - unsigned rx_tail = cp->rx_tail; - unsigned rx_work = 100; - - while (rx_work--) { - u32 status, len; - dma_addr_t mapping; - struct sk_buff *skb, *copy_skb; - unsigned copying_skb, buflen; - - skb = cp->rx_skb[rx_tail].skb; - if (!skb) - BUG(); - rmb(); - status = le32_to_cpu(cp->rx_ring[rx_tail].opts1); - if (status & DescOwn) - break; - - len = (status & 0x1fff) - 4; - mapping = cp->rx_skb[rx_tail].mapping; - - if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag)) { - cp_rx_frag(cp, rx_tail, skb, status, len); - goto rx_next; - } - - if (status & (RxError | RxErrFIFO)) { - cp_rx_err_acct(cp, rx_tail, status, len); - goto rx_next; - } - - copying_skb = (len <= rx_copybreak); - - if (netif_msg_rx_status(cp)) - printk(KERN_DEBUG "%s: rx slot %d status 0x%x len %d copying? %d\n", - cp->dev->name, rx_tail, status, len, - copying_skb); - - buflen = copying_skb ? len : cp->rx_buf_sz; - copy_skb = dev_alloc_skb (buflen + RX_OFFSET); - if (!copy_skb) { - cp->net_stats.rx_dropped++; - goto rx_next; - } - - skb_reserve(copy_skb, RX_OFFSET); - copy_skb->dev = cp->dev; - - if (!copying_skb) { - pci_unmap_single(cp->pdev, mapping, - buflen, PCI_DMA_FROMDEVICE); - skb->ip_summed = CHECKSUM_NONE; - skb_trim(skb, len); - - mapping = - cp->rx_skb[rx_tail].mapping = - pci_map_single(cp->pdev, copy_skb->data, - buflen, PCI_DMA_FROMDEVICE); - cp->rx_skb[rx_tail].skb = copy_skb; - skb_put(copy_skb, buflen); - } else { - skb_put(copy_skb, len); - pci_dma_sync_single(cp->pdev, mapping, len, PCI_DMA_FROMDEVICE); - memcpy(copy_skb->data, skb->data, len); - - /* We'll reuse the original ring buffer. */ - skb = copy_skb; - } - - cp_rx_skb(cp, skb); - -rx_next: - if (rx_tail == (CP_RX_RING_SIZE - 1)) - cp->rx_ring[rx_tail].opts1 = - cpu_to_le32(DescOwn | RingEnd | cp->rx_buf_sz); - else - cp->rx_ring[rx_tail].opts1 = - cpu_to_le32(DescOwn | cp->rx_buf_sz); - cp->rx_ring[rx_tail].opts2 = 0; - cp->rx_ring[rx_tail].addr_lo = cpu_to_le32(mapping); - rx_tail = NEXT_RX(rx_tail); - } - - if (!rx_work) - printk(KERN_WARNING "%s: rx work limit reached\n", cp->dev->name); - - cp->rx_tail = rx_tail; -} - -static void cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) -{ - struct net_device *dev = dev_instance; - struct cp_private *cp = dev->priv; - u16 status; - - status = cpr16(IntrStatus); - if (!status || (status == 0xFFFF)) - return; - - if (netif_msg_intr(cp)) - printk(KERN_DEBUG "%s: intr, status %04x cmd %02x cpcmd %04x\n", - dev->name, status, cpr8(Cmd), cpr16(CpCmd)); - - spin_lock(&cp->lock); - - if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr)) - cp_rx(cp); - if (status & (TxOK | TxErr | TxEmpty | SWInt)) - cp_tx(cp); - - cpw16_f(IntrStatus, status); - - if (status & PciErr) { - u16 pci_status; - - pci_read_config_word(cp->pdev, PCI_STATUS, &pci_status); - pci_write_config_word(cp->pdev, PCI_STATUS, pci_status); - printk(KERN_ERR "%s: PCI bus error, status=%04x, PCI status=%04x\n", - dev->name, status, pci_status); - } - - spin_unlock(&cp->lock); -} - -static void cp_tx (struct cp_private *cp) -{ - unsigned tx_head = cp->tx_head; - unsigned tx_tail = cp->tx_tail; - - while (tx_tail != tx_head) { - struct sk_buff *skb; - u32 status; - - rmb(); - status = le32_to_cpu(cp->tx_ring[tx_tail].opts1); - if (status & DescOwn) - break; - - skb = cp->tx_skb[tx_tail].skb; - if (!skb) - BUG(); - - pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping, - skb->len, PCI_DMA_TODEVICE); - - if (status & LastFrag) { - if (status & (TxError | TxFIFOUnder)) { - if (netif_msg_tx_err(cp)) - printk(KERN_DEBUG "%s: tx err, status 0x%x\n", - cp->dev->name, status); - cp->net_stats.tx_errors++; - if (status & TxOWC) - cp->net_stats.tx_window_errors++; - if (status & TxMaxCol) - cp->net_stats.tx_aborted_errors++; - if (status & TxLinkFail) - cp->net_stats.tx_carrier_errors++; - if (status & TxFIFOUnder) - cp->net_stats.tx_fifo_errors++; - } else { - cp->net_stats.collisions += - ((status >> TxColCntShift) & TxColCntMask); - cp->net_stats.tx_packets++; - cp->net_stats.tx_bytes += skb->len; - if (netif_msg_tx_done(cp)) - printk(KERN_DEBUG "%s: tx done, slot %d\n", cp->dev->name, tx_tail); - } - dev_kfree_skb_irq(skb); - } - - cp->tx_skb[tx_tail].skb = NULL; - - tx_tail = NEXT_TX(tx_tail); - } - - cp->tx_tail = tx_tail; - - if (netif_queue_stopped(cp->dev) && (TX_BUFFS_AVAIL(cp) > 1)) - netif_wake_queue(cp->dev); -} - -static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) -{ - struct cp_private *cp = dev->priv; - unsigned entry; - u32 eor; - - spin_lock_irq(&cp->lock); - - if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) { - netif_stop_queue(dev); - spin_unlock_irq(&cp->lock); - return 1; - } - - entry = cp->tx_head; - eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; - if (skb_shinfo(skb)->nr_frags == 0) { - struct cp_desc *txd = &cp->tx_ring[entry]; - u32 mapping, len; - - len = skb->len; - mapping = pci_map_single(cp->pdev, skb->data, len, PCI_DMA_TODEVICE); - eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; - txd->opts2 = 0; - txd->addr_lo = cpu_to_le32(mapping); - wmb(); - -#ifdef CP_TX_CHECKSUM - txd->opts1 = cpu_to_le32(eor | len | DescOwn | FirstFrag | - LastFrag | IPCS | UDPCS | TCPCS); -#else - txd->opts1 = cpu_to_le32(eor | len | DescOwn | FirstFrag | - LastFrag); -#endif - wmb(); - - cp->tx_skb[entry].skb = skb; - cp->tx_skb[entry].mapping = mapping; - cp->tx_skb[entry].frag = 0; - entry = NEXT_TX(entry); - } else { - struct cp_desc *txd; - u32 first_len, first_mapping; - int frag, first_entry = entry; - - /* We must give this initial chunk to the device last. - * Otherwise we could race with the device. - */ - first_len = skb->len - skb->data_len; - first_mapping = pci_map_single(cp->pdev, skb->data, - first_len, PCI_DMA_TODEVICE); - cp->tx_skb[entry].skb = skb; - cp->tx_skb[entry].mapping = first_mapping; - cp->tx_skb[entry].frag = 1; - entry = NEXT_TX(entry); - - for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { - skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; - u32 len, mapping; - u32 ctrl; - - len = this_frag->size; - mapping = pci_map_single(cp->pdev, - ((void *) page_address(this_frag->page) + - this_frag->page_offset), - len, PCI_DMA_TODEVICE); - eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; -#ifdef CP_TX_CHECKSUM - ctrl = eor | len | DescOwn | IPCS | UDPCS | TCPCS; -#else - ctrl = eor | len | DescOwn; -#endif - if (frag == skb_shinfo(skb)->nr_frags - 1) - ctrl |= LastFrag; - - txd = &cp->tx_ring[entry]; - txd->opts2 = 0; - txd->addr_lo = cpu_to_le32(mapping); - wmb(); - - txd->opts1 = cpu_to_le32(ctrl); - wmb(); - - cp->tx_skb[entry].skb = skb; - cp->tx_skb[entry].mapping = mapping; - cp->tx_skb[entry].frag = frag + 2; - entry = NEXT_TX(entry); - } - - txd = &cp->tx_ring[first_entry]; - txd->opts2 = 0; - txd->addr_lo = cpu_to_le32(first_mapping); - wmb(); - -#ifdef CP_TX_CHECKSUM - txd->opts1 = cpu_to_le32(first_len | FirstFrag | DescOwn | IPCS | UDPCS | TCPCS); -#else - txd->opts1 = cpu_to_le32(first_len | FirstFrag | DescOwn); -#endif - wmb(); - } - cp->tx_head = entry; - if (netif_msg_tx_queued(cp)) - printk(KERN_DEBUG "%s: tx queued, slot %d, skblen %d\n", - dev->name, entry, skb->len); - if (TX_BUFFS_AVAIL(cp) < 0) - BUG(); - if (TX_BUFFS_AVAIL(cp) == 0) - netif_stop_queue(dev); - - spin_unlock_irq(&cp->lock); - - cpw8(TxPoll, NormalTxPoll); - dev->trans_start = jiffies; - - return 0; -} - -/* Set or clear the multicast filter for this adaptor. - This routine is not state sensitive and need not be SMP locked. */ - -static unsigned const ethernet_polynomial = 0x04c11db7U; -static inline u32 ether_crc (int length, unsigned char *data) -{ - int crc = -1; - - while (--length >= 0) { - unsigned char current_octet = *data++; - int bit; - for (bit = 0; bit < 8; bit++, current_octet >>= 1) - crc = (crc << 1) ^ ((crc < 0) ^ (current_octet & 1) ? - ethernet_polynomial : 0); - } - - return crc; -} - -static void __cp_set_rx_mode (struct net_device *dev) -{ - struct cp_private *cp = dev->priv; - u32 mc_filter[2]; /* Multicast hash filter */ - int i, rx_mode; - u32 tmp; - - /* Note: do not reorder, GCC is clever about common statements. */ - if (dev->flags & IFF_PROMISC) { - /* Unconditionally log net taps. */ - printk (KERN_NOTICE "%s: Promiscuous mode enabled.\n", - dev->name); - rx_mode = - AcceptBroadcast | AcceptMulticast | AcceptMyPhys | - AcceptAllPhys; - mc_filter[1] = mc_filter[0] = 0xffffffff; - } else if ((dev->mc_count > multicast_filter_limit) - || (dev->flags & IFF_ALLMULTI)) { - /* Too many to filter perfectly -- accept all multicasts. */ - rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; - mc_filter[1] = mc_filter[0] = 0xffffffff; - } else { - struct dev_mc_list *mclist; - rx_mode = AcceptBroadcast | AcceptMyPhys; - mc_filter[1] = mc_filter[0] = 0; - for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; - i++, mclist = mclist->next) { - int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; - - mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31)); - rx_mode |= AcceptMulticast; - } - } - - /* We can safely update without stopping the chip. */ - tmp = cp_rx_config | rx_mode; - if (cp->rx_config != tmp) { - cpw32_f (RxConfig, tmp); - cp->rx_config = tmp; - } - cpw32_f (MAR0 + 0, mc_filter[0]); - cpw32_f (MAR0 + 4, mc_filter[1]); -} - -static void cp_set_rx_mode (struct net_device *dev) -{ - unsigned long flags; - struct cp_private *cp = dev->priv; - - spin_lock_irqsave (&cp->lock, flags); - __cp_set_rx_mode(dev); - spin_unlock_irqrestore (&cp->lock, flags); -} - -static void __cp_get_stats(struct cp_private *cp) -{ - /* XXX implement */ -} - -static struct net_device_stats *cp_get_stats(struct net_device *dev) -{ - struct cp_private *cp = dev->priv; - - /* The chip only need report frame silently dropped. */ - spin_lock_irq(&cp->lock); - if (netif_running(dev) && netif_device_present(dev)) - __cp_get_stats(cp); - spin_unlock_irq(&cp->lock); - - return &cp->net_stats; -} - -static void cp_stop_hw (struct cp_private *cp) -{ - cpw16(IntrMask, 0); - cpr16(IntrMask); - cpw8(Cmd, 0); - cpw16(CpCmd, 0); - cpr16(CpCmd); - cpw16(IntrStatus, ~(cpr16(IntrStatus))); - synchronize_irq(); - udelay(10); - - cp->rx_tail = 0; - cp->tx_head = cp->tx_tail = 0; -} - -static void cp_reset_hw (struct cp_private *cp) -{ - unsigned work = 1000; - - cpw8(Cmd, CmdReset); - - while (work--) { - if (!(cpr8(Cmd) & CmdReset)) - return; - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(10); - } - - printk(KERN_ERR "%s: hardware reset timeout\n", cp->dev->name); -} - -static void cp_init_hw (struct cp_private *cp) -{ - struct net_device *dev = cp->dev; - - cp_reset_hw(cp); - - cpw8_f (Cfg9346, Cfg9346_Unlock); - - /* Restore our idea of the MAC address. */ - cpw32_f (MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0))); - cpw32_f (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4))); - - cpw8(Cmd, RxOn | TxOn); - cpw16(CpCmd, PCIMulRW | CpRxOn | CpTxOn); - cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */ - - __cp_set_rx_mode(dev); - cpw32_f (TxConfig, IFG | (TX_DMA_BURST << TxDMAShift)); - - cpw8(Config1, cpr8(Config1) | DriverLoaded | PMEnable); - cpw8(Config3, PARMEnable); /* disables magic packet and WOL */ - cpw8(Config5, cpr8(Config5) & PMEStatus); /* disables more WOL stuff */ - - cpw32_f(HiTxRingAddr, 0); - cpw32_f(HiTxRingAddr + 4, 0); - cpw32_f(OldRxBufAddr, 0); - cpw32_f(OldTSD0, 0); - cpw32_f(OldTSD0 + 4, 0); - cpw32_f(OldTSD0 + 8, 0); - cpw32_f(OldTSD0 + 12, 0); - - cpw32_f(RxRingAddr, cp->ring_dma); - cpw32_f(RxRingAddr + 4, 0); - cpw32_f(TxRingAddr, cp->ring_dma + (sizeof(struct cp_desc) * CP_RX_RING_SIZE)); - cpw32_f(TxRingAddr + 4, 0); - - cpw16(MultiIntr, 0); - - cpw16(IntrMask, cp_intr_mask); - - cpw8_f (Cfg9346, Cfg9346_Lock); -} - -static int cp_refill_rx (struct cp_private *cp) -{ - unsigned i; - - for (i = 0; i < CP_RX_RING_SIZE; i++) { - struct sk_buff *skb; - - skb = dev_alloc_skb(cp->rx_buf_sz + RX_OFFSET); - if (!skb) - goto err_out; - - skb->dev = cp->dev; - skb_reserve(skb, RX_OFFSET); - skb_put(skb, cp->rx_buf_sz); - - cp->rx_skb[i].mapping = pci_map_single(cp->pdev, - skb->data, cp->rx_buf_sz, PCI_DMA_FROMDEVICE); - cp->rx_skb[i].skb = skb; - cp->rx_skb[i].frag = 0; - - if (i == (CP_RX_RING_SIZE - 1)) - cp->rx_ring[i].opts1 = - cpu_to_le32(DescOwn | RingEnd | cp->rx_buf_sz); - else - cp->rx_ring[i].opts1 = - cpu_to_le32(DescOwn | cp->rx_buf_sz); - cp->rx_ring[i].opts2 = 0; - cp->rx_ring[i].addr_lo = cpu_to_le32(cp->rx_skb[i].mapping); - cp->rx_ring[i].addr_hi = 0; - } - - return 0; - -err_out: - cp_clean_rings(cp); - return -ENOMEM; -} - -static int cp_init_rings (struct cp_private *cp) -{ - memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); - cp->tx_ring[CP_TX_RING_SIZE - 1].opts1 = cpu_to_le32(RingEnd); - - cp->rx_tail = 0; - cp->tx_head = cp->tx_tail = 0; - - return cp_refill_rx (cp); -} - -static int cp_alloc_rings (struct cp_private *cp) -{ - cp->rx_ring = pci_alloc_consistent(cp->pdev, CP_RING_BYTES, &cp->ring_dma); - if (!cp->rx_ring) - return -ENOMEM; - cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE]; - return cp_init_rings(cp); -} - -static void cp_clean_rings (struct cp_private *cp) -{ - unsigned i; - - memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE); - memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); - - for (i = 0; i < CP_RX_RING_SIZE; i++) { - if (cp->rx_skb[i].skb) { - pci_unmap_single(cp->pdev, cp->rx_skb[i].mapping, - cp->rx_buf_sz, PCI_DMA_FROMDEVICE); - dev_kfree_skb(cp->rx_skb[i].skb); - } - } - - for (i = 0; i < CP_TX_RING_SIZE; i++) { - if (cp->tx_skb[i].skb) { - struct sk_buff *skb = cp->tx_skb[i].skb; - pci_unmap_single(cp->pdev, cp->tx_skb[i].mapping, - skb->len, PCI_DMA_TODEVICE); - dev_kfree_skb(skb); - cp->net_stats.tx_dropped++; - } - } - - memset(&cp->rx_skb, 0, sizeof(struct ring_info) * CP_RX_RING_SIZE); - memset(&cp->tx_skb, 0, sizeof(struct ring_info) * CP_TX_RING_SIZE); -} - -static void cp_free_rings (struct cp_private *cp) -{ - cp_clean_rings(cp); - pci_free_consistent(cp->pdev, CP_RING_BYTES, cp->rx_ring, cp->ring_dma); - cp->rx_ring = NULL; - cp->tx_ring = NULL; -} - -static int cp_open (struct net_device *dev) -{ - struct cp_private *cp = dev->priv; - int rc; - - if (netif_msg_ifup(cp)) - printk(KERN_DEBUG "%s: enabling interface\n", dev->name); - - cp->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32); - - rc = cp_alloc_rings(cp); - if (rc) - return rc; - - cp_init_hw(cp); - - rc = request_irq(dev->irq, cp_interrupt, SA_SHIRQ, dev->name, dev); - if (rc) - goto err_out_hw; - - netif_start_queue(dev); - - return 0; - -err_out_hw: - cp_stop_hw(cp); - cp_free_rings(cp); - return rc; -} - -static int cp_close (struct net_device *dev) -{ - struct cp_private *cp = dev->priv; - - if (netif_msg_ifdown(cp)) - printk(KERN_DEBUG "%s: disabling interface\n", dev->name); - - netif_stop_queue(dev); - cp_stop_hw(cp); - free_irq(dev->irq, dev); - cp_free_rings(cp); - return 0; -} - -static int cp_ethtool_ioctl (struct cp_private *cp, void *useraddr) -{ - u32 ethcmd; - - /* dev_ioctl() in ../../net/core/dev.c has already checked - capable(CAP_NET_ADMIN), so don't bother with that here. */ - - if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: - { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, cp->pdev->slot_name); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - - default: - break; - } - - return -EOPNOTSUPP; -} - - -static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct cp_private *cp = dev->priv; - int rc = 0; - - switch (cmd) { - case SIOCETHTOOL: - return cp_ethtool_ioctl(cp, (void *) rq->ifr_data); - - default: - rc = -EOPNOTSUPP; - break; - } - - return rc; -} - - - -/* Serial EEPROM section. */ - -/* EEPROM_Ctrl bits. */ -#define EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */ -#define EE_CS 0x08 /* EEPROM chip select. */ -#define EE_DATA_WRITE 0x02 /* EEPROM chip data in. */ -#define EE_WRITE_0 0x00 -#define EE_WRITE_1 0x02 -#define EE_DATA_READ 0x01 /* EEPROM chip data out. */ -#define EE_ENB (0x80 | EE_CS) - -/* Delay between EEPROM clock transitions. - No extra delay is needed with 33Mhz PCI, but 66Mhz may change this. - */ - -#define eeprom_delay() readl(ee_addr) - -/* The EEPROM commands include the alway-set leading bit. */ -#define EE_WRITE_CMD (5) -#define EE_READ_CMD (6) -#define EE_ERASE_CMD (7) - -static int __devinit read_eeprom (void *ioaddr, int location, int addr_len) -{ - int i; - unsigned retval = 0; - void *ee_addr = ioaddr + Cfg9346; - int read_cmd = location | (EE_READ_CMD << addr_len); - - writeb (EE_ENB & ~EE_CS, ee_addr); - writeb (EE_ENB, ee_addr); - eeprom_delay (); - - /* Shift the read command bits out. */ - for (i = 4 + addr_len; i >= 0; i--) { - int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - writeb (EE_ENB | dataval, ee_addr); - eeprom_delay (); - writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); - eeprom_delay (); - } - writeb (EE_ENB, ee_addr); - eeprom_delay (); - - for (i = 16; i > 0; i--) { - writeb (EE_ENB | EE_SHIFT_CLK, ee_addr); - eeprom_delay (); - retval = - (retval << 1) | ((readb (ee_addr) & EE_DATA_READ) ? 1 : - 0); - writeb (EE_ENB, ee_addr); - eeprom_delay (); - } - - /* Terminate the EEPROM access. */ - writeb (~EE_CS, ee_addr); - eeprom_delay (); - - return retval; -} - -static int __devinit cp_init_one (struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct net_device *dev; - struct cp_private *cp; - int rc; - void *regs; - long pciaddr; - unsigned addr_len, i; - u8 pci_rev, cache_size; - u16 pci_command; - -#ifndef MODULE - static int version_printed; - if (version_printed++ == 0) - printk("%s", version); -#endif - - pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev); - - if (pdev->vendor == PCI_VENDOR_ID_REALTEK && - pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pci_rev < 0x20) { - printk(KERN_ERR PFX "pci dev %s (id %04x:%04x rev %02x) is not an 8139C+ compatible chip\n", - pdev->slot_name, pdev->vendor, pdev->device, pci_rev); - printk(KERN_ERR PFX "Ensure the \"8139too\" driver is installed!\n"); - return -ENODEV; - } - - dev = alloc_etherdev(sizeof(struct cp_private)); - if (!dev) - return -ENOMEM; - SET_MODULE_OWNER(dev); - cp = dev->priv; - cp->pdev = pdev; - cp->dev = dev; - cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug); - spin_lock_init (&cp->lock); - - rc = pci_enable_device(pdev); - if (rc) - goto err_out_free; - - rc = pci_request_regions(pdev, DRV_NAME); - if (rc) - goto err_out_disable; - - if (pdev->irq < 2) { - rc = -EIO; - printk(KERN_ERR PFX "invalid irq (%d) for pci dev %s\n", - pdev->irq, pdev->slot_name); - goto err_out_res; - } - pciaddr = pci_resource_start(pdev, 1); - if (!pciaddr) { - rc = -EIO; - printk(KERN_ERR PFX "no MMIO resource for pci dev %s\n", - pdev->slot_name); - goto err_out_res; - } - if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) { - rc = -EIO; - printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n", - pci_resource_len(pdev, 1), pdev->slot_name); - goto err_out_res; - } - - regs = ioremap_nocache(pciaddr, CP_REGS_SIZE); - if (!regs) { - rc = -EIO; - printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", - pci_resource_len(pdev, 1), pciaddr, pdev->slot_name); - goto err_out_res; - } - dev->base_addr = (unsigned long) regs; - cp->regs = regs; - - cp_stop_hw(cp); - - /* read MAC address from EEPROM */ - addr_len = read_eeprom (regs, 0, 8) == 0x8129 ? 8 : 6; - for (i = 0; i < 3; i++) - ((u16 *) (dev->dev_addr))[i] = - le16_to_cpu (read_eeprom (regs, i + 7, addr_len)); - - dev->open = cp_open; - dev->stop = cp_close; - dev->set_multicast_list = cp_set_rx_mode; - dev->hard_start_xmit = cp_start_xmit; - dev->get_stats = cp_get_stats; - dev->do_ioctl = cp_ioctl; -#if 0 - dev->tx_timeout = cp_tx_timeout; - dev->watchdog_timeo = TX_TIMEOUT; -#endif -#ifdef CP_TX_CHECKSUM - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; -#endif - - dev->irq = pdev->irq; - - rc = register_netdev(dev); - if (rc) - goto err_out_iomap; - - printk (KERN_INFO "%s: %s at 0x%lx, " - "%02x:%02x:%02x:%02x:%02x:%02x, " - "IRQ %d\n", - dev->name, - "RTL-8139C+", - dev->base_addr, - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5], - dev->irq); - - pci_set_drvdata(pdev, dev); - - /* - * Looks like this is necessary to deal with on all architectures, - * even this %$#%$# N440BX Intel based thing doesn't get it right. - * Ie. having two NICs in the machine, one will have the cache - * line set at boot time, the other will not. - */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_size); - cache_size <<= 2; - if (cache_size != SMP_CACHE_BYTES) { - printk(KERN_INFO "%s: PCI cache line size set incorrectly " - "(%i bytes) by BIOS/FW, ", dev->name, cache_size); - if (cache_size > SMP_CACHE_BYTES) - printk("expecting %i\n", SMP_CACHE_BYTES); - else { - printk("correcting to %i\n", SMP_CACHE_BYTES); - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, - SMP_CACHE_BYTES >> 2); - } - } - - /* enable busmastering and memory-write-invalidate */ - pci_read_config_word(pdev, PCI_COMMAND, &pci_command); - if (!(pci_command & PCI_COMMAND_INVALIDATE)) { - pci_command |= PCI_COMMAND_INVALIDATE; - pci_write_config_word(pdev, PCI_COMMAND, pci_command); - } - pci_set_master(pdev); - - return 0; - -err_out_iomap: - iounmap(regs); -err_out_res: - pci_release_regions(pdev); -err_out_disable: - pci_disable_device(pdev); -err_out_free: - kfree(dev); - return rc; -} - -static void __devexit cp_remove_one (struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct cp_private *cp = dev->priv; - - if (!dev) - BUG(); - unregister_netdev(dev); - iounmap(cp->regs); - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - kfree(dev); -} - -static struct pci_driver cp_driver = { - name: DRV_NAME, - id_table: cp_pci_tbl, - probe: cp_init_one, - remove: __devexit_p(cp_remove_one), -}; - -static int __init cp_init (void) -{ -#ifdef MODULE - printk("%s", version); -#endif - return pci_module_init (&cp_driver); -} - -static void __exit cp_exit (void) -{ - pci_unregister_driver (&cp_driver); -} - -module_init(cp_init); -module_exit(cp_exit); diff --git a/xen-2.4.16/drivers/net/Makefile b/xen-2.4.16/drivers/net/Makefile index 11fecb571b..34954de493 100644 --- a/xen-2.4.16/drivers/net/Makefile +++ b/xen-2.4.16/drivers/net/Makefile @@ -3,13 +3,11 @@ include $(BASEDIR)/Rules.mk default: $(OBJS) $(MAKE) -C ne - $(MAKE) -C tulip $(MAKE) -C e1000 - $(LD) -r -o driver.o e1000/e1000.o $(OBJS) tulip/tulip.o ne/ne_drv.o + $(LD) -r -o driver.o e1000/e1000.o $(OBJS) ne/ne_drv.o clean: $(MAKE) -C ne clean - $(MAKE) -C tulip clean rm -f *.o *~ core .PHONY: default clean diff --git a/xen-2.4.16/drivers/net/e1000/e1000_osdep.h b/xen-2.4.16/drivers/net/e1000/e1000_osdep.h index 259d8d8c78..40b62bfecd 100644 --- a/xen-2.4.16/drivers/net/e1000/e1000_osdep.h +++ b/xen-2.4.16/drivers/net/e1000/e1000_osdep.h @@ -69,7 +69,6 @@ typedef enum { TRUE = 1 } boolean_t; -#define ASSERT(x) if(!(x)) BUG() #define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B) //#define DBG 1 diff --git a/xen-2.4.16/drivers/net/eepro100.c b/xen-2.4.16/drivers/net/eepro100.c deleted file mode 100644 index eb47eb65cb..0000000000 --- a/xen-2.4.16/drivers/net/eepro100.c +++ /dev/null @@ -1,2312 +0,0 @@ -/* drivers/net/eepro100.c: An Intel i82557-559 Ethernet driver for Linux. */ -/* - NOTICE: For use with late 2.3 kernels only. - May not compile for kernels 2.3.43-47. - Written 1996-1999 by Donald Becker. - - The driver also contains updates by different kernel developers - (see incomplete list below). - Current maintainer is Andrey V. Savochkin <saw@saw.sw.com.sg>. - Please use this email address and linux-kernel mailing list for bug reports. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - This driver is for the Intel EtherExpress Pro100 (Speedo3) design. - It should work with all i82557/558/559 boards. - - Version history: - 1998 Apr - 2000 Feb Andrey V. Savochkin <saw@saw.sw.com.sg> - Serious fixes for multicast filter list setting, TX timeout routine; - RX ring refilling logic; other stuff - 2000 Feb Jeff Garzik <jgarzik@mandrakesoft.com> - Convert to new PCI driver interface - 2000 Mar 24 Dragan Stancevic <visitor@valinux.com> - Disabled FC and ER, to avoid lockups when when we get FCP interrupts. - 2000 Jul 17 Goutham Rao <goutham.rao@intel.com> - PCI DMA API fixes, adding pci_dma_sync_single calls where neccesary -*/ - -static const char *version = -"eepro100.c:v1.09j-t 9/29/99 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html\n" -"eepro100.c: $Revision: 1.36 $ 2000/11/17 Modified by Andrey V. Savochkin <saw@saw.sw.com.sg> and others\n"; - -/* A few user-configurable values that apply to all boards. - First set is undocumented and spelled per Intel recommendations. */ - -static int congenb /* = 0 */; /* Enable congestion control in the DP83840. */ -static int txfifo = 8; /* Tx FIFO threshold in 4 byte units, 0-15 */ -static int rxfifo = 8; /* Rx FIFO threshold, default 32 bytes. */ -/* Tx/Rx DMA burst length, 0-127, 0 == no preemption, tx==128 -> disabled. */ -static int txdmacount = 128; -static int rxdmacount /* = 0 */; - -/* Set the copy breakpoint for the copy-only-tiny-buffer Rx method. - Lower values use more memory, but are faster. */ -/*#if defined(__alpha__) || defined(__sparc__) || defined(__mips__) || \ - defined(__arm__) -static int rx_copybreak = 1518; -#else -static int rx_copybreak = 200; -#endif*/ - -/* Xen doesn't do rx_copybreak in drivers. */ -static int rx_copybreak = 0; - -/* Maximum events (Rx packets, etc.) to handle at each interrupt. */ -static int max_interrupt_work = 20; - -/* Maximum number of multicast addresses to filter (vs. rx-all-multicast) */ -static int multicast_filter_limit = 64; - -/* 'options' is used to pass a transceiver override or full-duplex flag - e.g. "options=16" for FD, "options=32" for 100mbps-only. */ -static int full_duplex[] = {-1, -1, -1, -1, -1, -1, -1, -1}; -static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1}; -static int debug = -1; /* The debug level */ - -#if !defined(__OPTIMIZE__) || !defined(__KERNEL__) -#warning You must compile this file with the correct options! -#warning See the last lines of the source file. -#error You must compile this driver with "-O". -#endif - -#include <linux/config.h> -#include <linux/lib.h> -//#include <linux/version.h> -#include <linux/module.h> - -//#include <linux/kernel.h> -//#include <linux/string.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/timer.h> -#include <linux/pci.h> -#include <linux/spinlock.h> -#include <linux/init.h> -#include <linux/mii.h> -#include <linux/delay.h> - -#include <asm/bitops.h> -#include <asm/io.h> -#include <asm/uaccess.h> - -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/ethtool.h> -#include <linux/delay.h> - -/* A few values that may be tweaked. */ - -/* The ring sizes should be a power of two for efficiency. */ -#undef RX_RING_SIZE -#undef TX_RING_SIZE -#define TX_RING_SIZE 32 -#define RX_RING_SIZE 32 - -/* How much slots multicast filter setup may take. - Do not descrease without changing set_rx_mode() implementaion. */ -#define TX_MULTICAST_SIZE 2 -#define TX_MULTICAST_RESERV (TX_MULTICAST_SIZE*2) -/* Actual number of TX packets queued, must be - <= TX_RING_SIZE-TX_MULTICAST_RESERV. */ -#define TX_QUEUE_LIMIT (TX_RING_SIZE-TX_MULTICAST_RESERV) -/* Hysteresis marking queue as no longer full. */ -#define TX_QUEUE_UNFULL (TX_QUEUE_LIMIT-4) - -/* Operational parameters that usually are not changed. */ - -/* Time in jiffies before concluding the transmitter is hung. */ -#define TX_TIMEOUT (2*HZ) -/* Size of an pre-allocated Rx buffer: <Ethernet MTU> + slack.*/ -#define PKT_BUF_SZ 1536 - -MODULE_AUTHOR("Maintainer: Andrey V. Savochkin <saw@saw.sw.com.sg>"); -MODULE_DESCRIPTION("Intel i82557/i82558/i82559 PCI EtherExpressPro driver"); -MODULE_LICENSE("GPL"); -MODULE_PARM(debug, "i"); -MODULE_PARM(options, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(congenb, "i"); -MODULE_PARM(txfifo, "i"); -MODULE_PARM(rxfifo, "i"); -MODULE_PARM(txdmacount, "i"); -MODULE_PARM(rxdmacount, "i"); -MODULE_PARM(rx_copybreak, "i"); -MODULE_PARM(max_interrupt_work, "i"); -MODULE_PARM(multicast_filter_limit, "i"); -MODULE_PARM_DESC(debug, "eepro100 debug level (0-6)"); -MODULE_PARM_DESC(options, "eepro100: Bits 0-3: tranceiver type, bit 4: full duplex, bit 5: 100Mbps"); -MODULE_PARM_DESC(full_duplex, "eepro100 full duplex setting(s) (1)"); -MODULE_PARM_DESC(congenb, "eepro100 Enable congestion control (1)"); -MODULE_PARM_DESC(txfifo, "eepro100 Tx FIFO threshold in 4 byte units, (0-15)"); -MODULE_PARM_DESC(rxfifo, "eepro100 Rx FIFO threshold in 4 byte units, (0-15)"); -MODULE_PARM_DESC(txdmaccount, "eepro100 Tx DMA burst length; 128 - disable (0-128)"); -MODULE_PARM_DESC(rxdmaccount, "eepro100 Rx DMA burst length; 128 - disable (0-128)"); -MODULE_PARM_DESC(rx_copybreak, "eepro100 copy breakpoint for copy-only-tiny-frames"); -MODULE_PARM_DESC(max_interrupt_work, "eepro100 maximum events handled per interrupt"); -MODULE_PARM_DESC(multicast_filter_limit, "eepro100 maximum number of filtered multicast addresses"); - -#define RUN_AT(x) (jiffies + (x)) - -/* ACPI power states don't universally work (yet) */ -#ifndef CONFIG_PM -#define SET_POWER_STATE(_dev, _state) pci_set_power_state(_dev, 0) -#else -#define SET_POWER_STATE(_dev, _state) pci_set_power_state(_dev, _state) -#endif /* CONFIG_PM */ - -#define netdevice_start(dev) -#define netdevice_stop(dev) -#define netif_set_tx_timeout(dev, tf, tm) \ - do { \ - (dev)->tx_timeout = (tf); \ - (dev)->watchdog_timeo = (tm); \ - } while(0) - -#ifndef PCI_DEVICE_ID_INTEL_ID1029 -#define PCI_DEVICE_ID_INTEL_ID1029 0x1029 -#endif -#ifndef PCI_DEVICE_ID_INTEL_ID1030 -#define PCI_DEVICE_ID_INTEL_ID1030 0x1030 -#endif - - -static int speedo_debug = 1; - -/* - Theory of Operation - -I. Board Compatibility - -This device driver is designed for the Intel i82557 "Speedo3" chip, Intel's -single-chip fast Ethernet controller for PCI, as used on the Intel -EtherExpress Pro 100 adapter. - -II. Board-specific settings - -PCI bus devices are configured by the system at boot time, so no jumpers -need to be set on the board. The system BIOS should be set to assign the -PCI INTA signal to an otherwise unused system IRQ line. While it's -possible to share PCI interrupt lines, it negatively impacts performance and -only recent kernels support it. - -III. Driver operation - -IIIA. General -The Speedo3 is very similar to other Intel network chips, that is to say -"apparently designed on a different planet". This chips retains the complex -Rx and Tx descriptors and multiple buffers pointers as previous chips, but -also has simplified Tx and Rx buffer modes. This driver uses the "flexible" -Tx mode, but in a simplified lower-overhead manner: it associates only a -single buffer descriptor with each frame descriptor. - -Despite the extra space overhead in each receive skbuff, the driver must use -the simplified Rx buffer mode to assure that only a single data buffer is -associated with each RxFD. The driver implements this by reserving space -for the Rx descriptor at the head of each Rx skbuff. - -The Speedo-3 has receive and command unit base addresses that are added to -almost all descriptor pointers. The driver sets these to zero, so that all -pointer fields are absolute addresses. - -The System Control Block (SCB) of some previous Intel chips exists on the -chip in both PCI I/O and memory space. This driver uses the I/O space -registers, but might switch to memory mapped mode to better support non-x86 -processors. - -IIIB. Transmit structure - -The driver must use the complex Tx command+descriptor mode in order to -have a indirect pointer to the skbuff data section. Each Tx command block -(TxCB) is associated with two immediately appended Tx Buffer Descriptor -(TxBD). A fixed ring of these TxCB+TxBD pairs are kept as part of the -speedo_private data structure for each adapter instance. - -The newer i82558 explicitly supports this structure, and can read the two -TxBDs in the same PCI burst as the TxCB. - -This ring structure is used for all normal transmit packets, but the -transmit packet descriptors aren't long enough for most non-Tx commands such -as CmdConfigure. This is complicated by the possibility that the chip has -already loaded the link address in the previous descriptor. So for these -commands we convert the next free descriptor on the ring to a NoOp, and point -that descriptor's link to the complex command. - -An additional complexity of these non-transmit commands are that they may be -added asynchronous to the normal transmit queue, so we disable interrupts -whenever the Tx descriptor ring is manipulated. - -A notable aspect of these special configure commands is that they do -work with the normal Tx ring entry scavenge method. The Tx ring scavenge -is done at interrupt time using the 'dirty_tx' index, and checking for the -command-complete bit. While the setup frames may have the NoOp command on the -Tx ring marked as complete, but not have completed the setup command, this -is not a problem. The tx_ring entry can be still safely reused, as the -tx_skbuff[] entry is always empty for config_cmd and mc_setup frames. - -Commands may have bits set e.g. CmdSuspend in the command word to either -suspend or stop the transmit/command unit. This driver always flags the last -command with CmdSuspend, erases the CmdSuspend in the previous command, and -then issues a CU_RESUME. -Note: Watch out for the potential race condition here: imagine - erasing the previous suspend - the chip processes the previous command - the chip processes the final command, and suspends - doing the CU_RESUME - the chip processes the next-yet-valid post-final-command. -So blindly sending a CU_RESUME is only safe if we do it immediately after -after erasing the previous CmdSuspend, without the possibility of an -intervening delay. Thus the resume command is always within the -interrupts-disabled region. This is a timing dependence, but handling this -condition in a timing-independent way would considerably complicate the code. - -Note: In previous generation Intel chips, restarting the command unit was a -notoriously slow process. This is presumably no longer true. - -IIIC. Receive structure - -Because of the bus-master support on the Speedo3 this driver uses the new -SKBUFF_RX_COPYBREAK scheme, rather than a fixed intermediate receive buffer. -This scheme allocates full-sized skbuffs as receive buffers. The value -SKBUFF_RX_COPYBREAK is used as the copying breakpoint: it is chosen to -trade-off the memory wasted by passing the full-sized skbuff to the queue -layer for all frames vs. the copying cost of copying a frame to a -correctly-sized skbuff. - -For small frames the copying cost is negligible (esp. considering that we -are pre-loading the cache with immediately useful header information), so we -allocate a new, minimally-sized skbuff. For large frames the copying cost -is non-trivial, and the larger copy might flush the cache of useful data, so -we pass up the skbuff the packet was received into. - -IV. Notes - -Thanks to Steve Williams of Intel for arranging the non-disclosure agreement -that stated that I could disclose the information. But I still resent -having to sign an Intel NDA when I'm helping Intel sell their own product! - -*/ - -static int speedo_found1(struct pci_dev *pdev, long ioaddr, int fnd_cnt, int acpi_idle_state); - -enum pci_flags_bit { - PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, - PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, -}; - -static inline unsigned int io_inw(unsigned long port) -{ - return inw(port); -} -static inline void io_outw(unsigned int val, unsigned long port) -{ - outw(val, port); -} - -#ifndef USE_IO -/* Currently alpha headers define in/out macros. - Undefine them. 2000/03/30 SAW */ -#undef inb -#undef inw -#undef inl -#undef outb -#undef outw -#undef outl -#define inb readb -#define inw readw -#define inl readl -#define outb writeb -#define outw writew -#define outl writel -#endif - -/* How to wait for the command unit to accept a command. - Typically this takes 0 ticks. */ -static inline void wait_for_cmd_done(long cmd_ioaddr) -{ - int wait = 1000; - do udelay(1) ; - while(inb(cmd_ioaddr) && --wait >= 0); -#ifndef final_version - if (wait < 0) - printk(KERN_ALERT "eepro100: wait_for_cmd_done timeout!\n"); -#endif -} - -/* Offsets to the various registers. - All accesses need not be longword aligned. */ -enum speedo_offsets { - SCBStatus = 0, SCBCmd = 2, /* Rx/Command Unit command and status. */ - SCBPointer = 4, /* General purpose pointer. */ - SCBPort = 8, /* Misc. commands and operands. */ - SCBflash = 12, SCBeeprom = 14, /* EEPROM and flash memory control. */ - SCBCtrlMDI = 16, /* MDI interface control. */ - SCBEarlyRx = 20, /* Early receive byte count. */ -}; -/* Commands that can be put in a command list entry. */ -enum commands { - CmdNOp = 0, CmdIASetup = 0x10000, CmdConfigure = 0x20000, - CmdMulticastList = 0x30000, CmdTx = 0x40000, CmdTDR = 0x50000, - CmdDump = 0x60000, CmdDiagnose = 0x70000, - CmdSuspend = 0x40000000, /* Suspend after completion. */ - CmdIntr = 0x20000000, /* Interrupt after completion. */ - CmdTxFlex = 0x00080000, /* Use "Flexible mode" for CmdTx command. */ -}; -/* Clear CmdSuspend (1<<30) avoiding interference with the card access to the - status bits. Previous driver versions used separate 16 bit fields for - commands and statuses. --SAW - */ -#if defined(__alpha__) -# define clear_suspend(cmd) clear_bit(30, &(cmd)->cmd_status); -#else -# if defined(__LITTLE_ENDIAN) -# define clear_suspend(cmd) ((__u16 *)&(cmd)->cmd_status)[1] &= ~0x4000 -# elif defined(__BIG_ENDIAN) -# define clear_suspend(cmd) ((__u16 *)&(cmd)->cmd_status)[1] &= ~0x0040 -# else -# error Unsupported byteorder -# endif -#endif - -enum SCBCmdBits { - SCBMaskCmdDone=0x8000, SCBMaskRxDone=0x4000, SCBMaskCmdIdle=0x2000, - SCBMaskRxSuspend=0x1000, SCBMaskEarlyRx=0x0800, SCBMaskFlowCtl=0x0400, - SCBTriggerIntr=0x0200, SCBMaskAll=0x0100, - /* The rest are Rx and Tx commands. */ - CUStart=0x0010, CUResume=0x0020, CUStatsAddr=0x0040, CUShowStats=0x0050, - CUCmdBase=0x0060, /* CU Base address (set to zero) . */ - CUDumpStats=0x0070, /* Dump then reset stats counters. */ - RxStart=0x0001, RxResume=0x0002, RxAbort=0x0004, RxAddrLoad=0x0006, - RxResumeNoResources=0x0007, -}; - -enum SCBPort_cmds { - PortReset=0, PortSelfTest=1, PortPartialReset=2, PortDump=3, -}; - -/* The Speedo3 Rx and Tx frame/buffer descriptors. */ -struct descriptor { /* A generic descriptor. */ - s32 cmd_status; /* All command and status fields. */ - u32 link; /* struct descriptor * */ - unsigned char params[0]; -}; - -/* The Speedo3 Rx and Tx buffer descriptors. */ -struct RxFD { /* Receive frame descriptor. */ - s32 status; - u32 link; /* struct RxFD * */ - u32 rx_buf_addr; /* void * */ - u32 count; -}; - -/* Selected elements of the Tx/RxFD.status word. */ -enum RxFD_bits { - RxComplete=0x8000, RxOK=0x2000, - RxErrCRC=0x0800, RxErrAlign=0x0400, RxErrTooBig=0x0200, RxErrSymbol=0x0010, - RxEth2Type=0x0020, RxNoMatch=0x0004, RxNoIAMatch=0x0002, - TxUnderrun=0x1000, StatusComplete=0x8000, -}; - -#define CONFIG_DATA_SIZE 22 -struct TxFD { /* Transmit frame descriptor set. */ - s32 status; - u32 link; /* void * */ - u32 tx_desc_addr; /* Always points to the tx_buf_addr element. */ - s32 count; /* # of TBD (=1), Tx start thresh., etc. */ - /* This constitutes two "TBD" entries -- we only use one. */ -#define TX_DESCR_BUF_OFFSET 16 - u32 tx_buf_addr0; /* void *, frame to be transmitted. */ - s32 tx_buf_size0; /* Length of Tx frame. */ - u32 tx_buf_addr1; /* void *, frame to be transmitted. */ - s32 tx_buf_size1; /* Length of Tx frame. */ - /* the structure must have space for at least CONFIG_DATA_SIZE starting - * from tx_desc_addr field */ -}; - -/* Multicast filter setting block. --SAW */ -struct speedo_mc_block { - struct speedo_mc_block *next; - unsigned int tx; - dma_addr_t frame_dma; - unsigned int len; - struct descriptor frame __attribute__ ((__aligned__(16))); -}; - -/* Elements of the dump_statistics block. This block must be lword aligned. */ -struct speedo_stats { - u32 tx_good_frames; - u32 tx_coll16_errs; - u32 tx_late_colls; - u32 tx_underruns; - u32 tx_lost_carrier; - u32 tx_deferred; - u32 tx_one_colls; - u32 tx_multi_colls; - u32 tx_total_colls; - u32 rx_good_frames; - u32 rx_crc_errs; - u32 rx_align_errs; - u32 rx_resource_errs; - u32 rx_overrun_errs; - u32 rx_colls_errs; - u32 rx_runt_errs; - u32 done_marker; -}; - -enum Rx_ring_state_bits { - RrNoMem=1, RrPostponed=2, RrNoResources=4, RrOOMReported=8, -}; - -/* Do not change the position (alignment) of the first few elements! - The later elements are grouped for cache locality. - - Unfortunately, all the positions have been shifted since there. - A new re-alignment is required. 2000/03/06 SAW */ -struct speedo_private { - struct TxFD *tx_ring; /* Commands (usually CmdTxPacket). */ - struct RxFD *rx_ringp[RX_RING_SIZE];/* Rx descriptor, used as ring. */ - /* The addresses of a Tx/Rx-in-place packets/buffers. */ - struct sk_buff *tx_skbuff[TX_RING_SIZE]; - struct sk_buff *rx_skbuff[RX_RING_SIZE]; - /* Mapped addresses of the rings. */ - dma_addr_t tx_ring_dma; -#define TX_RING_ELEM_DMA(sp, n) ((sp)->tx_ring_dma + (n)*sizeof(struct TxFD)) - dma_addr_t rx_ring_dma[RX_RING_SIZE]; - struct descriptor *last_cmd; /* Last command sent. */ - unsigned int cur_tx, dirty_tx; /* The ring entries to be free()ed. */ - spinlock_t lock; /* Group with Tx control cache line. */ - u32 tx_threshold; /* The value for txdesc.count. */ - struct RxFD *last_rxf; /* Last filled RX buffer. */ - dma_addr_t last_rxf_dma; - unsigned int cur_rx, dirty_rx; /* The next free ring entry */ - long last_rx_time; /* Last Rx, in jiffies, to handle Rx hang. */ - struct net_device_stats stats; - struct speedo_stats *lstats; - dma_addr_t lstats_dma; - int chip_id; - struct pci_dev *pdev; - struct timer_list timer; /* Media selection timer. */ - struct speedo_mc_block *mc_setup_head;/* Multicast setup frame list head. */ - struct speedo_mc_block *mc_setup_tail;/* Multicast setup frame list tail. */ - long in_interrupt; /* Word-aligned dev->interrupt */ - unsigned char acpi_pwr; - signed char rx_mode; /* Current PROMISC/ALLMULTI setting. */ - unsigned int tx_full:1; /* The Tx queue is full. */ - unsigned int full_duplex:1; /* Full-duplex operation requested. */ - unsigned int flow_ctrl:1; /* Use 802.3x flow control. */ - unsigned int rx_bug:1; /* Work around receiver hang errata. */ - unsigned char default_port:8; /* Last dev->if_port value. */ - unsigned char rx_ring_state; /* RX ring status flags. */ - unsigned short phy[2]; /* PHY media interfaces available. */ - unsigned short advertising; /* Current PHY advertised caps. */ - unsigned short partner; /* Link partner caps. */ -#ifdef CONFIG_PM - u32 pm_state[16]; -#endif -}; - -/* The parameters for a CmdConfigure operation. - There are so many options that it would be difficult to document each bit. - We mostly use the default or recommended settings. */ -static const char i82557_config_cmd[CONFIG_DATA_SIZE] = { - 22, 0x08, 0, 0, 0, 0, 0x32, 0x03, 1, /* 1=Use MII 0=Use AUI */ - 0, 0x2E, 0, 0x60, 0, - 0xf2, 0x48, 0, 0x40, 0xf2, 0x80, /* 0x40=Force full-duplex */ - 0x3f, 0x05, }; -static const char i82558_config_cmd[CONFIG_DATA_SIZE] = { - 22, 0x08, 0, 1, 0, 0, 0x22, 0x03, 1, /* 1=Use MII 0=Use AUI */ - 0, 0x2E, 0, 0x60, 0x08, 0x88, - 0x68, 0, 0x40, 0xf2, 0x84, /* Disable FC */ - 0x31, 0x05, }; - -/* PHY media interface chips. */ -static const char *phys[] = { - "None", "i82553-A/B", "i82553-C", "i82503", - "DP83840", "80c240", "80c24", "i82555", - "unknown-8", "unknown-9", "DP83840A", "unknown-11", - "unknown-12", "unknown-13", "unknown-14", "unknown-15", }; -enum phy_chips { NonSuchPhy=0, I82553AB, I82553C, I82503, DP83840, S80C240, - S80C24, I82555, DP83840A=10, }; -static const char is_mii[] = { 0, 1, 1, 0, 1, 1, 0, 1 }; -#define EE_READ_CMD (6) - -static int eepro100_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent); -static void eepro100_remove_one (struct pci_dev *pdev); -#ifdef CONFIG_PM -static int eepro100_suspend (struct pci_dev *pdev, u32 state); -static int eepro100_resume (struct pci_dev *pdev); -#endif - -static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len); -static int mdio_read(long ioaddr, int phy_id, int location); -static int mdio_write(long ioaddr, int phy_id, int location, int value); -static int speedo_open(struct net_device *dev); -static void speedo_resume(struct net_device *dev); -static void speedo_timer(unsigned long data); -static void speedo_init_rx_ring(struct net_device *dev); -static void speedo_tx_timeout(struct net_device *dev); -static int speedo_start_xmit(struct sk_buff *skb, struct net_device *dev); -static void speedo_refill_rx_buffers(struct net_device *dev, int force); -static int speedo_rx(struct net_device *dev); -static void speedo_tx_buffer_gc(struct net_device *dev); -static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -static int speedo_close(struct net_device *dev); -static struct net_device_stats *speedo_get_stats(struct net_device *dev); -static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static void set_rx_mode(struct net_device *dev); -static void speedo_show_state(struct net_device *dev); - - - -#ifdef honor_default_port -/* Optional driver feature to allow forcing the transceiver setting. - Not recommended. */ -static int mii_ctrl[8] = { 0x3300, 0x3100, 0x0000, 0x0100, - 0x2000, 0x2100, 0x0400, 0x3100}; -#endif - -static int __devinit eepro100_init_one (struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - unsigned long ioaddr; - int irq; - int acpi_idle_state = 0, pm; - static int cards_found /* = 0 */; - - static int did_version /* = 0 */; /* Already printed version info. */ - if (speedo_debug > 0 && did_version++ == 0) - printk(version); - - if (!request_region(pci_resource_start(pdev, 1), - pci_resource_len(pdev, 1), "eepro100")) { - printk (KERN_ERR "eepro100: cannot reserve I/O ports\n"); - goto err_out_none; - } - if (!request_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0), "eepro100")) { - printk (KERN_ERR "eepro100: cannot reserve MMIO region\n"); - goto err_out_free_pio_region; - } - - irq = pdev->irq; -#ifdef USE_IO - ioaddr = pci_resource_start(pdev, 1); - if (speedo_debug > 2) - printk("Found Intel i82557 PCI Speedo at I/O %#lx, IRQ %d.\n", - ioaddr, irq); -#else - ioaddr = (unsigned long)ioremap(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (!ioaddr) { - printk (KERN_ERR "eepro100: cannot remap MMIO region %lx @ %lx\n", - pci_resource_len(pdev, 0), pci_resource_start(pdev, 0)); - goto err_out_free_mmio_region; - } - if (speedo_debug > 2) - printk("Found Intel i82557 PCI Speedo, MMIO at %#lx, IRQ %d.\n", - pci_resource_start(pdev, 0), irq); -#endif - - /* save power state b4 pci_enable_device overwrites it */ - pm = pci_find_capability(pdev, PCI_CAP_ID_PM); - if (pm) { - u16 pwr_command; - pci_read_config_word(pdev, pm + PCI_PM_CTRL, &pwr_command); - acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK; - } - - if (pci_enable_device(pdev)) - goto err_out_free_mmio_region; - - pci_set_master(pdev); - - if (speedo_found1(pdev, ioaddr, cards_found, acpi_idle_state) == 0) - cards_found++; - else - goto err_out_iounmap; - - return 0; - -err_out_iounmap: ; -#ifndef USE_IO - iounmap ((void *)ioaddr); -#endif -err_out_free_mmio_region: - release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); -err_out_free_pio_region: - release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1)); -err_out_none: - return -ENODEV; -} - -static int speedo_found1(struct pci_dev *pdev, - long ioaddr, int card_idx, int acpi_idle_state) -{ - struct net_device *dev; - struct speedo_private *sp; - const char *product; - int i, option; - u16 eeprom[0x100]; - int size; - void *tx_ring_space; - dma_addr_t tx_ring_dma; - - size = TX_RING_SIZE * sizeof(struct TxFD) + sizeof(struct speedo_stats); - tx_ring_space = pci_alloc_consistent(pdev, size, &tx_ring_dma); - if (tx_ring_space == NULL) - return -1; - - dev = init_etherdev(NULL, sizeof(struct speedo_private)); - if (dev == NULL) { - printk(KERN_ERR "eepro100: Could not allocate ethernet device.\n"); - pci_free_consistent(pdev, size, tx_ring_space, tx_ring_dma); - return -1; - } - - if (dev->mem_start > 0) - option = dev->mem_start; - else if (card_idx >= 0 && options[card_idx] >= 0) - option = options[card_idx]; - else - option = 0; - - /* Read the station address EEPROM before doing the reset. - Nominally his should even be done before accepting the device, but - then we wouldn't have a device name with which to report the error. - The size test is for 6 bit vs. 8 bit address serial EEPROMs. - */ - { - unsigned long iobase; - int read_cmd, ee_size; - u16 sum; - int j; - - /* Use IO only to avoid postponed writes and satisfy EEPROM timing - requirements. */ - iobase = pci_resource_start(pdev, 1); - if ((do_eeprom_cmd(iobase, EE_READ_CMD << 24, 27) & 0xffe0000) - == 0xffe0000) { - ee_size = 0x100; - read_cmd = EE_READ_CMD << 24; - } else { - ee_size = 0x40; - read_cmd = EE_READ_CMD << 22; - } - - for (j = 0, i = 0, sum = 0; i < ee_size; i++) { - u16 value = do_eeprom_cmd(iobase, read_cmd | (i << 16), 27); - eeprom[i] = value; - sum += value; - if (i < 3) { - dev->dev_addr[j++] = value; - dev->dev_addr[j++] = value >> 8; - } - } - if (sum != 0xBABA) - printk(KERN_WARNING "%s: Invalid EEPROM checksum %#4.4x, " - "check settings before activating this device!\n", - dev->name, sum); - /* Don't unregister_netdev(dev); as the EEPro may actually be - usable, especially if the MAC address is set later. - On the other hand, it may be unusable if MDI data is corrupted. */ - } - - /* Reset the chip: stop Tx and Rx processes and clear counters. - This takes less than 10usec and will easily finish before the next - action. */ - outl(PortReset, ioaddr + SCBPort); - inl(ioaddr + SCBPort); - udelay(10); - - if (eeprom[3] & 0x0100) - product = "OEM i82557/i82558 10/100 Ethernet"; - else - product = pdev->name; - - printk(KERN_INFO "%s: %s, ", dev->name, product); - - for (i = 0; i < 5; i++) - printk("%2.2X:", dev->dev_addr[i]); - printk("%2.2X, ", dev->dev_addr[i]); -#ifdef USE_IO - printk("I/O at %#3lx, ", ioaddr); -#endif - printk("IRQ %d.\n", pdev->irq); - -#if 1 || defined(kernel_bloat) - /* OK, this is pure kernel bloat. I don't like it when other drivers - waste non-pageable kernel space to emit similar messages, but I need - them for bug reports. */ - { - const char *connectors[] = {" RJ45", " BNC", " AUI", " MII"}; - /* The self-test results must be paragraph aligned. */ - volatile s32 *self_test_results; - int boguscnt = 16000; /* Timeout for set-test. */ - if ((eeprom[3] & 0x03) != 0x03) - printk(KERN_INFO " Receiver lock-up bug exists -- enabling" - " work-around.\n"); - printk(KERN_INFO " Board assembly %4.4x%2.2x-%3.3d, Physical" - " connectors present:", - eeprom[8], eeprom[9]>>8, eeprom[9] & 0xff); - for (i = 0; i < 4; i++) - if (eeprom[5] & (1<<i)) - printk(connectors[i]); - printk("\n"KERN_INFO" Primary interface chip %s PHY #%d.\n", - phys[(eeprom[6]>>8)&15], eeprom[6] & 0x1f); - if (eeprom[7] & 0x0700) - printk(KERN_INFO " Secondary interface chip %s.\n", - phys[(eeprom[7]>>8)&7]); - if (((eeprom[6]>>8) & 0x3f) == DP83840 - || ((eeprom[6]>>8) & 0x3f) == DP83840A) { - int mdi_reg23 = mdio_read(ioaddr, eeprom[6] & 0x1f, 23) | 0x0422; - if (congenb) - mdi_reg23 |= 0x0100; - printk(KERN_INFO" DP83840 specific setup, setting register 23 to %4.4x.\n", - mdi_reg23); - mdio_write(ioaddr, eeprom[6] & 0x1f, 23, mdi_reg23); - } - if ((option >= 0) && (option & 0x70)) { - printk(KERN_INFO " Forcing %dMbs %s-duplex operation.\n", - (option & 0x20 ? 100 : 10), - (option & 0x10 ? "full" : "half")); - mdio_write(ioaddr, eeprom[6] & 0x1f, 0, - ((option & 0x20) ? 0x2000 : 0) | /* 100mbps? */ - ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */ - } - - /* Perform a system self-test. */ - self_test_results = (s32*) ((((long) tx_ring_space) + 15) & ~0xf); - self_test_results[0] = 0; - self_test_results[1] = -1; - outl(tx_ring_dma | PortSelfTest, ioaddr + SCBPort); - do { - udelay(10); - } while (self_test_results[1] == -1 && --boguscnt >= 0); - - if (boguscnt < 0) { /* Test optimized out. */ - printk(KERN_ERR "Self test failed, status %8.8x:\n" - KERN_ERR " Failure to initialize the i82557.\n" - KERN_ERR " Verify that the card is a bus-master" - " capable slot.\n", - self_test_results[1]); - } else - printk(KERN_INFO " General self-test: %s.\n" - KERN_INFO " Serial sub-system self-test: %s.\n" - KERN_INFO " Internal registers self-test: %s.\n" - KERN_INFO " ROM checksum self-test: %s (%#8.8x).\n", - self_test_results[1] & 0x1000 ? "failed" : "passed", - self_test_results[1] & 0x0020 ? "failed" : "passed", - self_test_results[1] & 0x0008 ? "failed" : "passed", - self_test_results[1] & 0x0004 ? "failed" : "passed", - self_test_results[0]); - } -#endif /* kernel_bloat */ - - outl(PortReset, ioaddr + SCBPort); - inl(ioaddr + SCBPort); - udelay(10); - - /* Return the chip to its original power state. */ - SET_POWER_STATE(pdev, acpi_idle_state); - - pci_set_drvdata (pdev, dev); - - dev->base_addr = ioaddr; - dev->irq = pdev->irq; - - sp = dev->priv; - sp->pdev = pdev; - sp->acpi_pwr = acpi_idle_state; - sp->tx_ring = tx_ring_space; - sp->tx_ring_dma = tx_ring_dma; - sp->lstats = (struct speedo_stats *)(sp->tx_ring + TX_RING_SIZE); - sp->lstats_dma = TX_RING_ELEM_DMA(sp, TX_RING_SIZE); - init_timer(&sp->timer); /* used in ioctl() */ - - sp->full_duplex = option >= 0 && (option & 0x10) ? 1 : 0; - if (card_idx >= 0) { - if (full_duplex[card_idx] >= 0) - sp->full_duplex = full_duplex[card_idx]; - } - sp->default_port = option >= 0 ? (option & 0x0f) : 0; - - sp->phy[0] = eeprom[6]; - sp->phy[1] = eeprom[7]; - sp->rx_bug = (eeprom[3] & 0x03) == 3 ? 0 : 1; - - if (sp->rx_bug) - printk(KERN_INFO " Receiver lock-up workaround activated.\n"); - - /* The Speedo-specific entries in the device structure. */ - dev->open = &speedo_open; - dev->hard_start_xmit = &speedo_start_xmit; - netif_set_tx_timeout(dev, &speedo_tx_timeout, TX_TIMEOUT); - dev->stop = &speedo_close; - dev->get_stats = &speedo_get_stats; - dev->set_multicast_list = &set_rx_mode; - dev->do_ioctl = &speedo_ioctl; - - return 0; -} - -/* Serial EEPROM section. - A "bit" grungy, but we work our way through bit-by-bit :->. */ -/* EEPROM_Ctrl bits. */ -#define EE_SHIFT_CLK 0x01 /* EEPROM shift clock. */ -#define EE_CS 0x02 /* EEPROM chip select. */ -#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ -#define EE_DATA_READ 0x08 /* EEPROM chip data out. */ -#define EE_ENB (0x4800 | EE_CS) -#define EE_WRITE_0 0x4802 -#define EE_WRITE_1 0x4806 -#define EE_OFFSET SCBeeprom - -/* The fixes for the code were kindly provided by Dragan Stancevic - <visitor@valinux.com> to strictly follow Intel specifications of EEPROM - access timing. - The publicly available sheet 64486302 (sec. 3.1) specifies 1us access - interval for serial EEPROM. However, it looks like that there is an - additional requirement dictating larger udelay's in the code below. - 2000/05/24 SAW */ -static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len) -{ - unsigned retval = 0; - long ee_addr = ioaddr + SCBeeprom; - - io_outw(EE_ENB, ee_addr); udelay(2); - io_outw(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2); - - /* Shift the command bits out. */ - do { - short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0; - io_outw(dataval, ee_addr); udelay(2); - io_outw(dataval | EE_SHIFT_CLK, ee_addr); udelay(2); - retval = (retval << 1) | ((io_inw(ee_addr) & EE_DATA_READ) ? 1 : 0); - } while (--cmd_len >= 0); - io_outw(EE_ENB, ee_addr); udelay(2); - - /* Terminate the EEPROM access. */ - io_outw(EE_ENB & ~EE_CS, ee_addr); - return retval; -} - -static int mdio_read(long ioaddr, int phy_id, int location) -{ - int val, boguscnt = 64*10; /* <64 usec. to complete, typ 27 ticks */ - outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI); - do { - val = inl(ioaddr + SCBCtrlMDI); - if (--boguscnt < 0) { - printk(KERN_ERR " mdio_read() timed out with val = %8.8x.\n", val); - break; - } - } while (! (val & 0x10000000)); - return val & 0xffff; -} - -static int mdio_write(long ioaddr, int phy_id, int location, int value) -{ - int val, boguscnt = 64*10; /* <64 usec. to complete, typ 27 ticks */ - outl(0x04000000 | (location<<16) | (phy_id<<21) | value, - ioaddr + SCBCtrlMDI); - do { - val = inl(ioaddr + SCBCtrlMDI); - if (--boguscnt < 0) { - printk(KERN_ERR" mdio_write() timed out with val = %8.8x.\n", val); - break; - } - } while (! (val & 0x10000000)); - return val & 0xffff; -} - - -static int -speedo_open(struct net_device *dev) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - long ioaddr = dev->base_addr; - int retval; - - if (speedo_debug > 1) - printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq); - - MOD_INC_USE_COUNT; - - SET_POWER_STATE(sp->pdev, 0); - - /* Set up the Tx queue early.. */ - sp->cur_tx = 0; - sp->dirty_tx = 0; - sp->last_cmd = 0; - sp->tx_full = 0; - spin_lock_init(&sp->lock); - sp->in_interrupt = 0; - - /* .. we can safely take handler calls during init. */ - retval = request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, dev->name, dev); - if (retval) { - MOD_DEC_USE_COUNT; - return retval; - } - - dev->if_port = sp->default_port; - -#ifdef oh_no_you_dont_unless_you_honour_the_options_passed_in_to_us - /* Retrigger negotiation to reset previous errors. */ - if ((sp->phy[0] & 0x8000) == 0) { - int phy_addr = sp->phy[0] & 0x1f ; - /* Use 0x3300 for restarting NWay, other values to force xcvr: - 0x0000 10-HD - 0x0100 10-FD - 0x2000 100-HD - 0x2100 100-FD - */ -#ifdef honor_default_port - mdio_write(ioaddr, phy_addr, 0, mii_ctrl[dev->default_port & 7]); -#else - mdio_write(ioaddr, phy_addr, 0, 0x3300); -#endif - } -#endif - - speedo_init_rx_ring(dev); - - /* Fire up the hardware. */ - outw(SCBMaskAll, ioaddr + SCBCmd); - speedo_resume(dev); - - netdevice_start(dev); - netif_start_queue(dev); - - /* Setup the chip and configure the multicast list. */ - sp->mc_setup_head = NULL; - sp->mc_setup_tail = NULL; - sp->flow_ctrl = sp->partner = 0; - sp->rx_mode = -1; /* Invalid -> always reset the mode. */ - set_rx_mode(dev); - if ((sp->phy[0] & 0x8000) == 0) - sp->advertising = mdio_read(ioaddr, sp->phy[0] & 0x1f, 4); - - if (speedo_debug > 2) { - printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n", - dev->name, inw(ioaddr + SCBStatus)); - } - - /* Set the timer. The timer serves a dual purpose: - 1) to monitor the media interface (e.g. link beat) and perhaps switch - to an alternate media type - 2) to monitor Rx activity, and restart the Rx process if the receiver - hangs. */ - sp->timer.expires = RUN_AT((24*HZ)/10); /* 2.4 sec. */ - sp->timer.data = (unsigned long)dev; - sp->timer.function = &speedo_timer; /* timer handler */ - add_timer(&sp->timer); - - /* No need to wait for the command unit to accept here. */ - if ((sp->phy[0] & 0x8000) == 0) - mdio_read(ioaddr, sp->phy[0] & 0x1f, 0); - - return 0; -} - -/* Start the chip hardware after a full reset. */ -static void speedo_resume(struct net_device *dev) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - long ioaddr = dev->base_addr; - - /* Start with a Tx threshold of 256 (0x..20.... 8 byte units). */ - sp->tx_threshold = 0x01208000; - - /* Set the segment registers to '0'. */ - wait_for_cmd_done(ioaddr + SCBCmd); - outl(0, ioaddr + SCBPointer); - /* impose a delay to avoid a bug */ - inl(ioaddr + SCBPointer); - udelay(10); - outb(RxAddrLoad, ioaddr + SCBCmd); - wait_for_cmd_done(ioaddr + SCBCmd); - outb(CUCmdBase, ioaddr + SCBCmd); - - /* Load the statistics block and rx ring addresses. */ - wait_for_cmd_done(ioaddr + SCBCmd); - outl(sp->lstats_dma, ioaddr + SCBPointer); - outb(CUStatsAddr, ioaddr + SCBCmd); - sp->lstats->done_marker = 0; - - if (sp->rx_ringp[sp->cur_rx % RX_RING_SIZE] == NULL) { - if (speedo_debug > 2) - printk(KERN_DEBUG "%s: NULL cur_rx in speedo_resume().\n", - dev->name); - } else { - wait_for_cmd_done(ioaddr + SCBCmd); - outl(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE], - ioaddr + SCBPointer); - outb(RxStart, ioaddr + SCBCmd); - } - - wait_for_cmd_done(ioaddr + SCBCmd); - outb(CUDumpStats, ioaddr + SCBCmd); - udelay(30); - - /* Fill the first command with our physical address. */ - { - struct descriptor *ias_cmd; - - ias_cmd = - (struct descriptor *)&sp->tx_ring[sp->cur_tx++ % TX_RING_SIZE]; - /* Avoid a bug(?!) here by marking the command already completed. */ - ias_cmd->cmd_status = cpu_to_le32((CmdSuspend | CmdIASetup) | 0xa000); - ias_cmd->link = - cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE)); - memcpy(ias_cmd->params, dev->dev_addr, 6); - sp->last_cmd = ias_cmd; - } - - /* Start the chip's Tx process and unmask interrupts. */ - wait_for_cmd_done(ioaddr + SCBCmd); - outl(TX_RING_ELEM_DMA(sp, sp->dirty_tx % TX_RING_SIZE), - ioaddr + SCBPointer); - /* We are not ACK-ing FCP and ER in the interrupt handler yet so they should - remain masked --Dragan */ - outw(CUStart | SCBMaskEarlyRx | SCBMaskFlowCtl, ioaddr + SCBCmd); -} - -/* Media monitoring and control. */ -static void speedo_timer(unsigned long data) -{ - struct net_device *dev = (struct net_device *)data; - struct speedo_private *sp = (struct speedo_private *)dev->priv; - long ioaddr = dev->base_addr; - int phy_num = sp->phy[0] & 0x1f; - - /* We have MII and lost link beat. */ - if ((sp->phy[0] & 0x8000) == 0) { - int partner = mdio_read(ioaddr, phy_num, 5); - if (partner != sp->partner) { - int flow_ctrl = sp->advertising & partner & 0x0400 ? 1 : 0; - if (speedo_debug > 2) { - printk(KERN_DEBUG "%s: Link status change.\n", dev->name); - printk(KERN_DEBUG "%s: Old partner %x, new %x, adv %x.\n", - dev->name, sp->partner, partner, sp->advertising); - } - sp->partner = partner; - if (flow_ctrl != sp->flow_ctrl) { - sp->flow_ctrl = flow_ctrl; - sp->rx_mode = -1; /* Trigger a reload. */ - } - /* Clear sticky bit. */ - mdio_read(ioaddr, phy_num, 1); - /* If link beat has returned... */ - if (mdio_read(ioaddr, phy_num, 1) & 0x0004) - dev->flags |= IFF_RUNNING; - else - dev->flags &= ~IFF_RUNNING; - } - } - if (speedo_debug > 3) { - printk(KERN_DEBUG "%s: Media control tick, status %4.4x.\n", - dev->name, inw(ioaddr + SCBStatus)); - } - if (sp->rx_mode < 0 || - (sp->rx_bug && jiffies - sp->last_rx_time > 2*HZ)) { - /* We haven't received a packet in a Long Time. We might have been - bitten by the receiver hang bug. This can be cleared by sending - a set multicast list command. */ - if (speedo_debug > 3) - printk(KERN_DEBUG "%s: Sending a multicast list set command" - " from a timer routine," - " m=%d, j=%ld, l=%ld.\n", - dev->name, sp->rx_mode, jiffies, sp->last_rx_time); - set_rx_mode(dev); - } - /* We must continue to monitor the media. */ - sp->timer.expires = RUN_AT(2*HZ); /* 2.0 sec. */ - add_timer(&sp->timer); -#if defined(timer_exit) - timer_exit(&sp->timer); -#endif -} - -static void speedo_show_state(struct net_device *dev) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - int i; - - /* Print a few items for debugging. */ - if (speedo_debug > 0) { - int i; - printk(KERN_DEBUG "%s: Tx ring dump, Tx queue %u / %u:\n", dev->name, - sp->cur_tx, sp->dirty_tx); - for (i = 0; i < TX_RING_SIZE; i++) - printk(KERN_DEBUG "%s: %c%c%2d %8.8x.\n", dev->name, - i == sp->dirty_tx % TX_RING_SIZE ? '*' : ' ', - i == sp->cur_tx % TX_RING_SIZE ? '=' : ' ', - i, sp->tx_ring[i].status); - } - printk(KERN_DEBUG "%s: Printing Rx ring" - " (next to receive into %u, dirty index %u).\n", - dev->name, sp->cur_rx, sp->dirty_rx); - - for (i = 0; i < RX_RING_SIZE; i++) - printk(KERN_DEBUG "%s: %c%c%c%2d %8.8x.\n", dev->name, - sp->rx_ringp[i] == sp->last_rxf ? 'l' : ' ', - i == sp->dirty_rx % RX_RING_SIZE ? '*' : ' ', - i == sp->cur_rx % RX_RING_SIZE ? '=' : ' ', - i, (sp->rx_ringp[i] != NULL) ? - (unsigned)sp->rx_ringp[i]->status : 0); - -#if 0 - { - long ioaddr = dev->base_addr; - int phy_num = sp->phy[0] & 0x1f; - for (i = 0; i < 16; i++) { - /* FIXME: what does it mean? --SAW */ - if (i == 6) i = 21; - printk(KERN_DEBUG "%s: PHY index %d register %d is %4.4x.\n", - dev->name, phy_num, i, mdio_read(ioaddr, phy_num, i)); - } - } -#endif - -} - -/* Initialize the Rx and Tx rings, along with various 'dev' bits. */ -static void -speedo_init_rx_ring(struct net_device *dev) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - struct RxFD *rxf, *last_rxf = NULL; - dma_addr_t last_rxf_dma = 0 /* to shut up the compiler */; - int i; - - sp->cur_rx = 0; - - for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb; - skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); - sp->rx_skbuff[i] = skb; - if (skb == NULL) - break; /* OK. Just initially short of Rx bufs. */ - skb->dev = dev; /* Mark as being used by this device. */ - rxf = (struct RxFD *)skb->tail; - sp->rx_ringp[i] = rxf; - sp->rx_ring_dma[i] = - pci_map_single(sp->pdev, rxf, - PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_BIDIRECTIONAL); - skb_reserve(skb, sizeof(struct RxFD)); - if (last_rxf) { - last_rxf->link = cpu_to_le32(sp->rx_ring_dma[i]); - pci_dma_sync_single(sp->pdev, last_rxf_dma, - sizeof(struct RxFD), PCI_DMA_TODEVICE); - } - last_rxf = rxf; - last_rxf_dma = sp->rx_ring_dma[i]; - rxf->status = cpu_to_le32(0x00000001); /* '1' is flag value only. */ - rxf->link = 0; /* None yet. */ - /* This field unused by i82557. */ - rxf->rx_buf_addr = 0xffffffff; - rxf->count = cpu_to_le32(PKT_BUF_SZ << 16); - pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[i], - sizeof(struct RxFD), PCI_DMA_TODEVICE); - } - sp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); - /* Mark the last entry as end-of-list. */ - last_rxf->status = cpu_to_le32(0xC0000002); /* '2' is flag value only. */ - pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[RX_RING_SIZE-1], - sizeof(struct RxFD), PCI_DMA_TODEVICE); - sp->last_rxf = last_rxf; - sp->last_rxf_dma = last_rxf_dma; -} - -static void speedo_purge_tx(struct net_device *dev) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - int entry; - - while ((int)(sp->cur_tx - sp->dirty_tx) > 0) { - entry = sp->dirty_tx % TX_RING_SIZE; - if (sp->tx_skbuff[entry]) { - sp->stats.tx_errors++; - pci_unmap_single(sp->pdev, - le32_to_cpu(sp->tx_ring[entry].tx_buf_addr0), - sp->tx_skbuff[entry]->len, PCI_DMA_TODEVICE); - dev_kfree_skb_irq(sp->tx_skbuff[entry]); - sp->tx_skbuff[entry] = 0; - } - sp->dirty_tx++; - } - while (sp->mc_setup_head != NULL) { - struct speedo_mc_block *t; - if (speedo_debug > 1) - printk(KERN_DEBUG "%s: freeing mc frame.\n", dev->name); - pci_unmap_single(sp->pdev, sp->mc_setup_head->frame_dma, - sp->mc_setup_head->len, PCI_DMA_TODEVICE); - t = sp->mc_setup_head->next; - kfree(sp->mc_setup_head); - sp->mc_setup_head = t; - } - sp->mc_setup_tail = NULL; - sp->tx_full = 0; - netif_wake_queue(dev); -} - -static void reset_mii(struct net_device *dev) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - long ioaddr = dev->base_addr; - /* Reset the MII transceiver, suggested by Fred Young @ scalable.com. */ - if ((sp->phy[0] & 0x8000) == 0) { - int phy_addr = sp->phy[0] & 0x1f; - int advertising = mdio_read(ioaddr, phy_addr, 4); - int mii_bmcr = mdio_read(ioaddr, phy_addr, 0); - mdio_write(ioaddr, phy_addr, 0, 0x0400); - mdio_write(ioaddr, phy_addr, 1, 0x0000); - mdio_write(ioaddr, phy_addr, 4, 0x0000); - mdio_write(ioaddr, phy_addr, 0, 0x8000); -#ifdef honor_default_port - mdio_write(ioaddr, phy_addr, 0, mii_ctrl[dev->default_port & 7]); -#else - mdio_read(ioaddr, phy_addr, 0); - mdio_write(ioaddr, phy_addr, 0, mii_bmcr); - mdio_write(ioaddr, phy_addr, 4, advertising); -#endif - } -} - -static void speedo_tx_timeout(struct net_device *dev) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - long ioaddr = dev->base_addr; - int status = inw(ioaddr + SCBStatus); - unsigned long flags; - - printk(KERN_WARNING "%s: Transmit timed out: status %4.4x " - " %4.4x at %d/%d command %8.8x.\n", - dev->name, status, inw(ioaddr + SCBCmd), - sp->dirty_tx, sp->cur_tx, - sp->tx_ring[sp->dirty_tx % TX_RING_SIZE].status); - - speedo_show_state(dev); -#if 0 - if ((status & 0x00C0) != 0x0080 - && (status & 0x003C) == 0x0010) { - /* Only the command unit has stopped. */ - printk(KERN_WARNING "%s: Trying to restart the transmitter...\n", - dev->name); - outl(TX_RING_ELEM_DMA(sp, dirty_tx % TX_RING_SIZE]), - ioaddr + SCBPointer); - outw(CUStart, ioaddr + SCBCmd); - reset_mii(dev); - } else { -#else - { -#endif - del_timer_sync(&sp->timer); - /* Reset the Tx and Rx units. */ - outl(PortReset, ioaddr + SCBPort); - /* We may get spurious interrupts here. But I don't think that they - may do much harm. 1999/12/09 SAW */ - udelay(10); - /* Disable interrupts. */ - outw(SCBMaskAll, ioaddr + SCBCmd); - synchronize_irq(); - speedo_tx_buffer_gc(dev); - /* Free as much as possible. - It helps to recover from a hang because of out-of-memory. - It also simplifies speedo_resume() in case TX ring is full or - close-to-be full. */ - speedo_purge_tx(dev); - speedo_refill_rx_buffers(dev, 1); - spin_lock_irqsave(&sp->lock, flags); - speedo_resume(dev); - sp->rx_mode = -1; - dev->trans_start = jiffies; - spin_unlock_irqrestore(&sp->lock, flags); - set_rx_mode(dev); /* it takes the spinlock itself --SAW */ - /* Reset MII transceiver. Do it before starting the timer to serialize - mdio_xxx operations. Yes, it's a paranoya :-) 2000/05/09 SAW */ - reset_mii(dev); - sp->timer.expires = RUN_AT(2*HZ); - add_timer(&sp->timer); - } - return; -} - -static int -speedo_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - long ioaddr = dev->base_addr; - int entry; - - /* Prevent interrupts from changing the Tx ring from underneath us. */ - unsigned long flags; - - spin_lock_irqsave(&sp->lock, flags); - - /* Check if there are enough space. */ - if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) { - printk(KERN_ERR "%s: incorrect tbusy state, fixed.\n", dev->name); - netif_stop_queue(dev); - sp->tx_full = 1; - spin_unlock_irqrestore(&sp->lock, flags); - return 1; - } - - /* Calculate the Tx descriptor entry. */ - entry = sp->cur_tx++ % TX_RING_SIZE; - - sp->tx_skbuff[entry] = skb; - sp->tx_ring[entry].status = - cpu_to_le32(CmdSuspend | CmdTx | CmdTxFlex); - if (!(entry & ((TX_RING_SIZE>>2)-1))) - sp->tx_ring[entry].status |= cpu_to_le32(CmdIntr); - sp->tx_ring[entry].link = - cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE)); - sp->tx_ring[entry].tx_desc_addr = - cpu_to_le32(TX_RING_ELEM_DMA(sp, entry) + TX_DESCR_BUF_OFFSET); - /* The data region is always in one buffer descriptor. */ - sp->tx_ring[entry].count = cpu_to_le32(sp->tx_threshold); - sp->tx_ring[entry].tx_buf_addr0 = - cpu_to_le32(pci_map_single(sp->pdev, skb->data, - skb->len, PCI_DMA_TODEVICE)); - sp->tx_ring[entry].tx_buf_size0 = cpu_to_le32(skb->len); - - /* workaround for hardware bug on 10 mbit half duplex */ - - if ((sp->partner==0) && (sp->chip_id==1)) { - wait_for_cmd_done(ioaddr + SCBCmd); - outb(0 , ioaddr + SCBCmd); - } - - /* Trigger the command unit resume. */ - wait_for_cmd_done(ioaddr + SCBCmd); - clear_suspend(sp->last_cmd); - /* We want the time window between clearing suspend flag on the previous - command and resuming CU to be as small as possible. - Interrupts in between are very undesired. --SAW */ - outb(CUResume, ioaddr + SCBCmd); - sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry]; - - /* Leave room for set_rx_mode(). If there is no more space than reserved - for multicast filter mark the ring as full. */ - if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) { - netif_stop_queue(dev); - sp->tx_full = 1; - } - - spin_unlock_irqrestore(&sp->lock, flags); - - dev->trans_start = jiffies; - - return 0; -} - -static void speedo_tx_buffer_gc(struct net_device *dev) -{ - unsigned int dirty_tx; - struct speedo_private *sp = (struct speedo_private *)dev->priv; - - dirty_tx = sp->dirty_tx; - while ((int)(sp->cur_tx - dirty_tx) > 0) { - int entry = dirty_tx % TX_RING_SIZE; - int status = le32_to_cpu(sp->tx_ring[entry].status); - - if (speedo_debug > 5) - printk(KERN_DEBUG " scavenge candidate %d status %4.4x.\n", - entry, status); - if ((status & StatusComplete) == 0) - break; /* It still hasn't been processed. */ - if (status & TxUnderrun) - if (sp->tx_threshold < 0x01e08000) { - if (speedo_debug > 2) - printk(KERN_DEBUG "%s: TX underrun, threshold adjusted.\n", - dev->name); - sp->tx_threshold += 0x00040000; - } - /* Free the original skb. */ - if (sp->tx_skbuff[entry]) { - sp->stats.tx_packets++; /* Count only user packets. */ - sp->stats.tx_bytes += sp->tx_skbuff[entry]->len; - pci_unmap_single(sp->pdev, - le32_to_cpu(sp->tx_ring[entry].tx_buf_addr0), - sp->tx_skbuff[entry]->len, PCI_DMA_TODEVICE); - dev_kfree_skb_irq(sp->tx_skbuff[entry]); - sp->tx_skbuff[entry] = 0; - } - dirty_tx++; - } - - if (speedo_debug && (int)(sp->cur_tx - dirty_tx) > TX_RING_SIZE) { - printk(KERN_ERR "out-of-sync dirty pointer, %d vs. %d," - " full=%d.\n", - dirty_tx, sp->cur_tx, sp->tx_full); - dirty_tx += TX_RING_SIZE; - } - - while (sp->mc_setup_head != NULL - && (int)(dirty_tx - sp->mc_setup_head->tx - 1) > 0) { - struct speedo_mc_block *t; - if (speedo_debug > 1) - printk(KERN_DEBUG "%s: freeing mc frame.\n", dev->name); - pci_unmap_single(sp->pdev, sp->mc_setup_head->frame_dma, - sp->mc_setup_head->len, PCI_DMA_TODEVICE); - t = sp->mc_setup_head->next; - kfree(sp->mc_setup_head); - sp->mc_setup_head = t; - } - if (sp->mc_setup_head == NULL) - sp->mc_setup_tail = NULL; - - sp->dirty_tx = dirty_tx; -} - -/* The interrupt handler does all of the Rx thread work and cleans up - after the Tx thread. */ -static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *)dev_instance; - struct speedo_private *sp; - long ioaddr, boguscnt = max_interrupt_work; - unsigned short status; - -#ifndef final_version - if (dev == NULL) { - printk(KERN_ERR "speedo_interrupt(): irq %d for unknown device.\n", irq); - return; - } -#endif - - ioaddr = dev->base_addr; - sp = (struct speedo_private *)dev->priv; - -#ifndef final_version - /* A lock to prevent simultaneous entry on SMP machines. */ - if (test_and_set_bit(0, (void*)&sp->in_interrupt)) { - printk(KERN_ERR"%s: SMP simultaneous entry of an interrupt handler.\n", - dev->name); - sp->in_interrupt = 0; /* Avoid halting machine. */ - return; - } -#endif - - do { - status = inw(ioaddr + SCBStatus); - /* Acknowledge all of the current interrupt sources ASAP. */ - /* Will change from 0xfc00 to 0xff00 when we start handling - FCP and ER interrupts --Dragan */ - outw(status & 0xfc00, ioaddr + SCBStatus); - - if (speedo_debug > 4) - printk(KERN_DEBUG "%s: interrupt status=%#4.4x.\n", - dev->name, status); - - if ((status & 0xfc00) == 0) - break; - - /* Always check if all rx buffers are allocated. --SAW */ - speedo_refill_rx_buffers(dev, 0); - - if ((status & 0x5000) || /* Packet received, or Rx error. */ - (sp->rx_ring_state&(RrNoMem|RrPostponed)) == RrPostponed) - /* Need to gather the postponed packet. */ - speedo_rx(dev); - - if (status & 0x1000) { - spin_lock(&sp->lock); - if ((status & 0x003c) == 0x0028) { /* No more Rx buffers. */ - struct RxFD *rxf; - printk(KERN_WARNING "%s: card reports no RX buffers.\n", - dev->name); - rxf = sp->rx_ringp[sp->cur_rx % RX_RING_SIZE]; - if (rxf == NULL) { - if (speedo_debug > 2) - printk(KERN_DEBUG - "%s: NULL cur_rx in speedo_interrupt().\n", - dev->name); - sp->rx_ring_state |= RrNoMem|RrNoResources; - } else if (rxf == sp->last_rxf) { - if (speedo_debug > 2) - printk(KERN_DEBUG - "%s: cur_rx is last in speedo_interrupt().\n", - dev->name); - sp->rx_ring_state |= RrNoMem|RrNoResources; - } else - outb(RxResumeNoResources, ioaddr + SCBCmd); - } else if ((status & 0x003c) == 0x0008) { /* No resources. */ - struct RxFD *rxf; - printk(KERN_WARNING "%s: card reports no resources.\n", - dev->name); - rxf = sp->rx_ringp[sp->cur_rx % RX_RING_SIZE]; - if (rxf == NULL) { - if (speedo_debug > 2) - printk(KERN_DEBUG - "%s: NULL cur_rx in speedo_interrupt().\n", - dev->name); - sp->rx_ring_state |= RrNoMem|RrNoResources; - } else if (rxf == sp->last_rxf) { - if (speedo_debug > 2) - printk(KERN_DEBUG - "%s: cur_rx is last in speedo_interrupt().\n", - dev->name); - sp->rx_ring_state |= RrNoMem|RrNoResources; - } else { - /* Restart the receiver. */ - outl(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE], - ioaddr + SCBPointer); - outb(RxStart, ioaddr + SCBCmd); - } - } - sp->stats.rx_errors++; - spin_unlock(&sp->lock); - } - - if ((sp->rx_ring_state&(RrNoMem|RrNoResources)) == RrNoResources) { - printk(KERN_WARNING - "%s: restart the receiver after a possible hang.\n", - dev->name); - spin_lock(&sp->lock); - /* Restart the receiver. - I'm not sure if it's always right to restart the receiver - here but I don't know another way to prevent receiver hangs. - 1999/12/25 SAW */ - outl(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE], - ioaddr + SCBPointer); - outb(RxStart, ioaddr + SCBCmd); - sp->rx_ring_state &= ~RrNoResources; - spin_unlock(&sp->lock); - } - - /* User interrupt, Command/Tx unit interrupt or CU not active. */ - if (status & 0xA400) { - spin_lock(&sp->lock); - speedo_tx_buffer_gc(dev); - if (sp->tx_full - && (int)(sp->cur_tx - sp->dirty_tx) < TX_QUEUE_UNFULL) { - /* The ring is no longer full. */ - sp->tx_full = 0; - netif_wake_queue(dev); /* Attention: under a spinlock. --SAW */ - } - spin_unlock(&sp->lock); - } - - if (--boguscnt < 0) { - printk(KERN_ERR "%s: Too much work at interrupt, status=0x%4.4x.\n", - dev->name, status); - /* Clear all interrupt sources. */ - /* Will change from 0xfc00 to 0xff00 when we start handling - FCP and ER interrupts --Dragan */ - outw(0xfc00, ioaddr + SCBStatus); - break; - } - } while (1); - - if (speedo_debug > 3) - printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n", - dev->name, inw(ioaddr + SCBStatus)); - - clear_bit(0, (void*)&sp->in_interrupt); - return; -} - -static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - struct RxFD *rxf; - struct sk_buff *skb; - /* Get a fresh skbuff to replace the consumed one. */ - skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); - sp->rx_skbuff[entry] = skb; - if (skb == NULL) { - sp->rx_ringp[entry] = NULL; - return NULL; - } - rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->tail; - sp->rx_ring_dma[entry] = - pci_map_single(sp->pdev, rxf, - PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE); - skb->dev = dev; - skb_reserve(skb, sizeof(struct RxFD)); - rxf->rx_buf_addr = 0xffffffff; - pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[entry], - sizeof(struct RxFD), PCI_DMA_TODEVICE); - return rxf; -} - -static inline void speedo_rx_link(struct net_device *dev, int entry, - struct RxFD *rxf, dma_addr_t rxf_dma) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - rxf->status = cpu_to_le32(0xC0000001); /* '1' for driver use only. */ - rxf->link = 0; /* None yet. */ - rxf->count = cpu_to_le32(PKT_BUF_SZ << 16); - sp->last_rxf->link = cpu_to_le32(rxf_dma); - sp->last_rxf->status &= cpu_to_le32(~0xC0000000); - pci_dma_sync_single(sp->pdev, sp->last_rxf_dma, - sizeof(struct RxFD), PCI_DMA_TODEVICE); - sp->last_rxf = rxf; - sp->last_rxf_dma = rxf_dma; -} - -static int speedo_refill_rx_buf(struct net_device *dev, int force) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - int entry; - struct RxFD *rxf; - - entry = sp->dirty_rx % RX_RING_SIZE; - if (sp->rx_skbuff[entry] == NULL) { - rxf = speedo_rx_alloc(dev, entry); - if (rxf == NULL) { - unsigned int forw; - int forw_entry; - if (speedo_debug > 2 || !(sp->rx_ring_state & RrOOMReported)) { - printk(KERN_WARNING "%s: can't fill rx buffer (force %d)!\n", - dev->name, force); - speedo_show_state(dev); - sp->rx_ring_state |= RrOOMReported; - } - if (!force) - return -1; /* Better luck next time! */ - /* Borrow an skb from one of next entries. */ - for (forw = sp->dirty_rx + 1; forw != sp->cur_rx; forw++) - if (sp->rx_skbuff[forw % RX_RING_SIZE] != NULL) - break; - if (forw == sp->cur_rx) - return -1; - forw_entry = forw % RX_RING_SIZE; - sp->rx_skbuff[entry] = sp->rx_skbuff[forw_entry]; - sp->rx_skbuff[forw_entry] = NULL; - rxf = sp->rx_ringp[forw_entry]; - sp->rx_ringp[forw_entry] = NULL; - sp->rx_ringp[entry] = rxf; - } - } else { - rxf = sp->rx_ringp[entry]; - } - speedo_rx_link(dev, entry, rxf, sp->rx_ring_dma[entry]); - sp->dirty_rx++; - sp->rx_ring_state &= ~(RrNoMem|RrOOMReported); /* Mark the progress. */ - return 0; -} - -static void speedo_refill_rx_buffers(struct net_device *dev, int force) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - - /* Refill the RX ring. */ - while ((int)(sp->cur_rx - sp->dirty_rx) > 0 && - speedo_refill_rx_buf(dev, force) != -1); -} - -static int -speedo_rx(struct net_device *dev) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - int entry = sp->cur_rx % RX_RING_SIZE; - int rx_work_limit = sp->dirty_rx + RX_RING_SIZE - sp->cur_rx; - int alloc_ok = 1; - - if (speedo_debug > 4) - printk(KERN_DEBUG " In speedo_rx().\n"); - /* If we own the next entry, it's a new packet. Send it up. */ - while (sp->rx_ringp[entry] != NULL) { - int status; - int pkt_len; - - pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[entry], - sizeof(struct RxFD), PCI_DMA_FROMDEVICE); - status = le32_to_cpu(sp->rx_ringp[entry]->status); - pkt_len = le32_to_cpu(sp->rx_ringp[entry]->count) & 0x3fff; - - if (!(status & RxComplete)) - break; - - if (--rx_work_limit < 0) - break; - - /* Check for a rare out-of-memory case: the current buffer is - the last buffer allocated in the RX ring. --SAW */ - if (sp->last_rxf == sp->rx_ringp[entry]) { - /* Postpone the packet. It'll be reaped at an interrupt when this - packet is no longer the last packet in the ring. */ - if (speedo_debug > 2) - printk(KERN_DEBUG "%s: RX packet postponed!\n", - dev->name); - sp->rx_ring_state |= RrPostponed; - break; - } - - if (speedo_debug > 4) - printk(KERN_DEBUG " speedo_rx() status %8.8x len %d.\n", status, - pkt_len); - if ((status & (RxErrTooBig|RxOK|0x0f90)) != RxOK) { - if (status & RxErrTooBig) - printk(KERN_ERR "%s: Ethernet frame overran the Rx buffer, " - "status %8.8x!\n", dev->name, status); - else if (! (status & RxOK)) { - /* There was a fatal error. This *should* be impossible. */ - sp->stats.rx_errors++; - printk(KERN_ERR "%s: Anomalous event in speedo_rx(), " - "status %8.8x.\n", - dev->name, status); - } - } else { - struct sk_buff *skb; - - /* Check if the packet is long enough to just accept without - copying to a properly sized skbuff. */ - if (pkt_len < rx_copybreak - && (skb = dev_alloc_skb(pkt_len + 2)) != 0) { - skb->dev = dev; - skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ - /* 'skb_put()' points to the start of sk_buff data area. */ - pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[entry], - sizeof(struct RxFD) + pkt_len, PCI_DMA_FROMDEVICE); - -#if 1 || USE_IP_CSUM - /* Packet is in one chunk -- we can copy + cksum. */ - eth_copy_and_sum(skb, sp->rx_skbuff[entry]->tail, pkt_len, 0); - skb_put(skb, pkt_len); -#else - memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->tail, - pkt_len); -#endif - } else { - /* Pass up the already-filled skbuff. */ - skb = sp->rx_skbuff[entry]; - if (skb == NULL) { - printk(KERN_ERR "%s: Inconsistent Rx descriptor chain.\n", - dev->name); - break; - } - sp->rx_skbuff[entry] = NULL; - skb_put(skb, pkt_len); - sp->rx_ringp[entry] = NULL; - pci_unmap_single(sp->pdev, sp->rx_ring_dma[entry], - PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE); - } - skb->protocol = eth_type_trans(skb, dev); - netif_rx(skb); - sp->stats.rx_packets++; - sp->stats.rx_bytes += pkt_len; - } - entry = (++sp->cur_rx) % RX_RING_SIZE; - sp->rx_ring_state &= ~RrPostponed; - /* Refill the recently taken buffers. - Do it one-by-one to handle traffic bursts better. */ - if (alloc_ok && speedo_refill_rx_buf(dev, 0) == -1) - alloc_ok = 0; - } - - /* Try hard to refill the recently taken buffers. */ - speedo_refill_rx_buffers(dev, 1); - - sp->last_rx_time = jiffies; - - return 0; -} - -static int -speedo_close(struct net_device *dev) -{ - long ioaddr = dev->base_addr; - struct speedo_private *sp = (struct speedo_private *)dev->priv; - int i; - - netdevice_stop(dev); - netif_stop_queue(dev); - - if (speedo_debug > 1) - printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n", - dev->name, inw(ioaddr + SCBStatus)); - - /* Shut off the media monitoring timer. */ - del_timer_sync(&sp->timer); - - /* Shutting down the chip nicely fails to disable flow control. So.. */ - outl(PortPartialReset, ioaddr + SCBPort); - - free_irq(dev->irq, dev); - - /* Print a few items for debugging. */ - if (speedo_debug > 3) - speedo_show_state(dev); - - /* Free all the skbuffs in the Rx and Tx queues. */ - for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = sp->rx_skbuff[i]; - sp->rx_skbuff[i] = 0; - /* Clear the Rx descriptors. */ - if (skb) { - pci_unmap_single(sp->pdev, - sp->rx_ring_dma[i], - PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE); - dev_kfree_skb(skb); - } - } - - for (i = 0; i < TX_RING_SIZE; i++) { - struct sk_buff *skb = sp->tx_skbuff[i]; - sp->tx_skbuff[i] = 0; - /* Clear the Tx descriptors. */ - if (skb) { - pci_unmap_single(sp->pdev, - le32_to_cpu(sp->tx_ring[i].tx_buf_addr0), - skb->len, PCI_DMA_TODEVICE); - dev_kfree_skb(skb); - } - } - - /* Free multicast setting blocks. */ - for (i = 0; sp->mc_setup_head != NULL; i++) { - struct speedo_mc_block *t; - t = sp->mc_setup_head->next; - kfree(sp->mc_setup_head); - sp->mc_setup_head = t; - } - sp->mc_setup_tail = NULL; - if (speedo_debug > 0) - printk(KERN_DEBUG "%s: %d multicast blocks dropped.\n", dev->name, i); - - SET_POWER_STATE(sp->pdev, 2); - - MOD_DEC_USE_COUNT; - - return 0; -} - -/* The Speedo-3 has an especially awkward and unusable method of getting - statistics out of the chip. It takes an unpredictable length of time - for the dump-stats command to complete. To avoid a busy-wait loop we - update the stats with the previous dump results, and then trigger a - new dump. - - Oh, and incoming frames are dropped while executing dump-stats! - */ -static struct net_device_stats * -speedo_get_stats(struct net_device *dev) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - long ioaddr = dev->base_addr; - - /* Update only if the previous dump finished. */ - if (sp->lstats->done_marker == le32_to_cpu(0xA007)) { - sp->stats.tx_aborted_errors += le32_to_cpu(sp->lstats->tx_coll16_errs); - sp->stats.tx_window_errors += le32_to_cpu(sp->lstats->tx_late_colls); - sp->stats.tx_fifo_errors += le32_to_cpu(sp->lstats->tx_underruns); - sp->stats.tx_fifo_errors += le32_to_cpu(sp->lstats->tx_lost_carrier); - /*sp->stats.tx_deferred += le32_to_cpu(sp->lstats->tx_deferred);*/ - sp->stats.collisions += le32_to_cpu(sp->lstats->tx_total_colls); - sp->stats.rx_crc_errors += le32_to_cpu(sp->lstats->rx_crc_errs); - sp->stats.rx_frame_errors += le32_to_cpu(sp->lstats->rx_align_errs); - sp->stats.rx_over_errors += le32_to_cpu(sp->lstats->rx_resource_errs); - sp->stats.rx_fifo_errors += le32_to_cpu(sp->lstats->rx_overrun_errs); - sp->stats.rx_length_errors += le32_to_cpu(sp->lstats->rx_runt_errs); - sp->lstats->done_marker = 0x0000; - if (netif_running(dev)) { - unsigned long flags; - /* Take a spinlock to make wait_for_cmd_done and sending the - command atomic. --SAW */ - spin_lock_irqsave(&sp->lock, flags); - wait_for_cmd_done(ioaddr + SCBCmd); - outb(CUDumpStats, ioaddr + SCBCmd); - spin_unlock_irqrestore(&sp->lock, flags); - } - } - return &sp->stats; -} - -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) -{ - u32 ethcmd; - struct speedo_private *sp = dev->priv; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strncpy(info.driver, "eepro100", sizeof(info.driver)-1); - strncpy(info.version, version, sizeof(info.version)-1); - if (sp && sp->pdev) - strcpy(info.bus_info, sp->pdev->slot_name); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - - } - - return -EOPNOTSUPP; -} - - - - - -static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - long ioaddr = dev->base_addr; - struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; - int phy = sp->phy[0] & 0x1f; - int saved_acpi; - int t; - - switch(cmd) { - case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ - data->phy_id = phy; - - case SIOCGMIIREG: /* Read MII PHY register. */ - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ - /* FIXME: these operations need to be serialized with MDIO - access from the timeout handler. - They are currently serialized only with MDIO access from the - timer routine. 2000/05/09 SAW */ - saved_acpi = SET_POWER_STATE(sp->pdev, 0); - t = del_timer_sync(&sp->timer); - data->val_out = mdio_read(ioaddr, data->phy_id & 0x1f, data->reg_num & 0x1f); - if (t) - add_timer(&sp->timer); /* may be set to the past --SAW */ - SET_POWER_STATE(sp->pdev, saved_acpi); - return 0; - - case SIOCSMIIREG: /* Write MII PHY register. */ - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - saved_acpi = SET_POWER_STATE(sp->pdev, 0); - t = del_timer_sync(&sp->timer); - mdio_write(ioaddr, data->phy_id, data->reg_num, data->val_in); - if (t) - add_timer(&sp->timer); /* may be set to the past --SAW */ - SET_POWER_STATE(sp->pdev, saved_acpi); - return 0; - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - default: - return -EOPNOTSUPP; - } -} - -/* Set or clear the multicast filter for this adaptor. - This is very ugly with Intel chips -- we usually have to execute an - entire configuration command, plus process a multicast command. - This is complicated. We must put a large configuration command and - an arbitrarily-sized multicast command in the transmit list. - To minimize the disruption -- the previous command might have already - loaded the link -- we convert the current command block, normally a Tx - command, into a no-op and link it to the new command. -*/ -static void set_rx_mode(struct net_device *dev) -{ - struct speedo_private *sp = (struct speedo_private *)dev->priv; - long ioaddr = dev->base_addr; - struct descriptor *last_cmd; - char new_rx_mode; - unsigned long flags; - int entry, i; - - if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ - new_rx_mode = 3; - } else if ((dev->flags & IFF_ALLMULTI) || - dev->mc_count > multicast_filter_limit) { - new_rx_mode = 1; - } else - new_rx_mode = 0; - - if (speedo_debug > 3) - printk(KERN_DEBUG "%s: set_rx_mode %d -> %d\n", dev->name, - sp->rx_mode, new_rx_mode); - - if ((int)(sp->cur_tx - sp->dirty_tx) > TX_RING_SIZE - TX_MULTICAST_SIZE) { - /* The Tx ring is full -- don't add anything! Hope the mode will be - * set again later. */ - sp->rx_mode = -1; - return; - } - - if (new_rx_mode != sp->rx_mode) { - u8 *config_cmd_data; - - spin_lock_irqsave(&sp->lock, flags); - entry = sp->cur_tx++ % TX_RING_SIZE; - last_cmd = sp->last_cmd; - sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry]; - - sp->tx_skbuff[entry] = 0; /* Redundant. */ - sp->tx_ring[entry].status = cpu_to_le32(CmdSuspend | CmdConfigure); - sp->tx_ring[entry].link = - cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE)); - config_cmd_data = (void *)&sp->tx_ring[entry].tx_desc_addr; - /* Construct a full CmdConfig frame. */ - memcpy(config_cmd_data, i82558_config_cmd, CONFIG_DATA_SIZE); - config_cmd_data[1] = (txfifo << 4) | rxfifo; - config_cmd_data[4] = rxdmacount; - config_cmd_data[5] = txdmacount + 0x80; - config_cmd_data[15] |= (new_rx_mode & 2) ? 1 : 0; - /* 0x80 doesn't disable FC 0x84 does. - Disable Flow control since we are not ACK-ing any FC interrupts - for now. --Dragan */ - config_cmd_data[19] = 0x84; - config_cmd_data[19] |= sp->full_duplex ? 0x40 : 0; - config_cmd_data[21] = (new_rx_mode & 1) ? 0x0D : 0x05; - if (sp->phy[0] & 0x8000) { /* Use the AUI port instead. */ - config_cmd_data[15] |= 0x80; - config_cmd_data[8] = 0; - } - /* Trigger the command unit resume. */ - wait_for_cmd_done(ioaddr + SCBCmd); - clear_suspend(last_cmd); - outb(CUResume, ioaddr + SCBCmd); - if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) { - netif_stop_queue(dev); - sp->tx_full = 1; - } - spin_unlock_irqrestore(&sp->lock, flags); - } - - if (new_rx_mode == 0 && dev->mc_count < 4) { - /* The simple case of 0-3 multicast list entries occurs often, and - fits within one tx_ring[] entry. */ - struct dev_mc_list *mclist; - u16 *setup_params, *eaddrs; - - spin_lock_irqsave(&sp->lock, flags); - entry = sp->cur_tx++ % TX_RING_SIZE; - last_cmd = sp->last_cmd; - sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry]; - - sp->tx_skbuff[entry] = 0; - sp->tx_ring[entry].status = cpu_to_le32(CmdSuspend | CmdMulticastList); - sp->tx_ring[entry].link = - cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE)); - sp->tx_ring[entry].tx_desc_addr = 0; /* Really MC list count. */ - setup_params = (u16 *)&sp->tx_ring[entry].tx_desc_addr; - *setup_params++ = cpu_to_le16(dev->mc_count*6); - /* Fill in the multicast addresses. */ - for (i = 0, mclist = dev->mc_list; i < dev->mc_count; - i++, mclist = mclist->next) { - eaddrs = (u16 *)mclist->dmi_addr; - *setup_params++ = *eaddrs++; - *setup_params++ = *eaddrs++; - *setup_params++ = *eaddrs++; - } - - wait_for_cmd_done(ioaddr + SCBCmd); - clear_suspend(last_cmd); - /* Immediately trigger the command unit resume. */ - outb(CUResume, ioaddr + SCBCmd); - - if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) { - netif_stop_queue(dev); - sp->tx_full = 1; - } - spin_unlock_irqrestore(&sp->lock, flags); - } else if (new_rx_mode == 0) { - struct dev_mc_list *mclist; - u16 *setup_params, *eaddrs; - struct speedo_mc_block *mc_blk; - struct descriptor *mc_setup_frm; - int i; - - mc_blk = kmalloc(sizeof(*mc_blk) + 2 + multicast_filter_limit*6, - GFP_ATOMIC); - if (mc_blk == NULL) { - printk(KERN_ERR "%s: Failed to allocate a setup frame.\n", - dev->name); - sp->rx_mode = -1; /* We failed, try again. */ - return; - } - mc_blk->next = NULL; - mc_blk->len = 2 + multicast_filter_limit*6; - mc_blk->frame_dma = - pci_map_single(sp->pdev, &mc_blk->frame, mc_blk->len, - PCI_DMA_TODEVICE); - mc_setup_frm = &mc_blk->frame; - - /* Fill the setup frame. */ - if (speedo_debug > 1) - printk(KERN_DEBUG "%s: Constructing a setup frame at %p.\n", - dev->name, mc_setup_frm); - mc_setup_frm->cmd_status = - cpu_to_le32(CmdSuspend | CmdIntr | CmdMulticastList); - /* Link set below. */ - setup_params = (u16 *)&mc_setup_frm->params; - *setup_params++ = cpu_to_le16(dev->mc_count*6); - /* Fill in the multicast addresses. */ - for (i = 0, mclist = dev->mc_list; i < dev->mc_count; - i++, mclist = mclist->next) { - eaddrs = (u16 *)mclist->dmi_addr; - *setup_params++ = *eaddrs++; - *setup_params++ = *eaddrs++; - *setup_params++ = *eaddrs++; - } - - /* Disable interrupts while playing with the Tx Cmd list. */ - spin_lock_irqsave(&sp->lock, flags); - - if (sp->mc_setup_tail) - sp->mc_setup_tail->next = mc_blk; - else - sp->mc_setup_head = mc_blk; - sp->mc_setup_tail = mc_blk; - mc_blk->tx = sp->cur_tx; - - entry = sp->cur_tx++ % TX_RING_SIZE; - last_cmd = sp->last_cmd; - sp->last_cmd = mc_setup_frm; - - /* Change the command to a NoOp, pointing to the CmdMulti command. */ - sp->tx_skbuff[entry] = 0; - sp->tx_ring[entry].status = cpu_to_le32(CmdNOp); - sp->tx_ring[entry].link = cpu_to_le32(mc_blk->frame_dma); - - /* Set the link in the setup frame. */ - mc_setup_frm->link = - cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE)); - - pci_dma_sync_single(sp->pdev, mc_blk->frame_dma, - mc_blk->len, PCI_DMA_TODEVICE); - - wait_for_cmd_done(ioaddr + SCBCmd); - clear_suspend(last_cmd); - /* Immediately trigger the command unit resume. */ - outb(CUResume, ioaddr + SCBCmd); - - if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) { - netif_stop_queue(dev); - sp->tx_full = 1; - } - spin_unlock_irqrestore(&sp->lock, flags); - - if (speedo_debug > 5) - printk(" CmdMCSetup frame length %d in entry %d.\n", - dev->mc_count, entry); - } - - sp->rx_mode = new_rx_mode; -} - -#ifdef CONFIG_PM -static int eepro100_suspend(struct pci_dev *pdev, u32 state) -{ - struct net_device *dev = pci_get_drvdata (pdev); - struct speedo_private *sp = (struct speedo_private *)dev->priv; - long ioaddr = dev->base_addr; - - pci_save_state(pdev, sp->pm_state); - - if (!netif_running(dev)) - return 0; - - netif_device_detach(dev); - outl(PortPartialReset, ioaddr + SCBPort); - - /* XXX call SET_POWER_STATE ()? */ - return 0; -} - -static int eepro100_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata (pdev); - struct speedo_private *sp = (struct speedo_private *)dev->priv; - long ioaddr = dev->base_addr; - - pci_restore_state(pdev, sp->pm_state); - - if (!netif_running(dev)) - return 0; - - /* I'm absolutely uncertain if this part of code may work. - The problems are: - - correct hardware reinitialization; - - correct driver behavior between different steps of the - reinitialization; - - serialization with other driver calls. - 2000/03/08 SAW */ - outw(SCBMaskAll, ioaddr + SCBCmd); - speedo_resume(dev); - netif_device_attach(dev); - sp->rx_mode = -1; - sp->flow_ctrl = sp->partner = 0; - set_rx_mode(dev); - return 0; -} -#endif /* CONFIG_PM */ - -static void __devexit eepro100_remove_one (struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata (pdev); - struct speedo_private *sp = (struct speedo_private *)dev->priv; - - unregister_netdev(dev); - - release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1)); - release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); - -#ifndef USE_IO - iounmap((char *)dev->base_addr); -#endif - - pci_free_consistent(pdev, TX_RING_SIZE * sizeof(struct TxFD) - + sizeof(struct speedo_stats), - sp->tx_ring, sp->tx_ring_dma); - pci_disable_device(pdev); - kfree(dev); -} - -static struct pci_device_id eepro100_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557, - PCI_ANY_ID, PCI_ANY_ID, }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562ET, - PCI_ANY_ID, PCI_ANY_ID, }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER, - PCI_ANY_ID, PCI_ANY_ID, }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1029, - PCI_ANY_ID, PCI_ANY_ID, }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030, - PCI_ANY_ID, PCI_ANY_ID, }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_7, - PCI_ANY_ID, PCI_ANY_ID, }, - { 0,} -}; -MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl); - -static struct pci_driver eepro100_driver = { - name: "eepro100", - id_table: eepro100_pci_tbl, - probe: eepro100_init_one, - remove: __devexit_p(eepro100_remove_one), -#ifdef CONFIG_PM - suspend: eepro100_suspend, - resume: eepro100_resume, -#endif /* CONFIG_PM */ -}; - -static int __init eepro100_init_module(void) -{ - if (debug >= 0 && speedo_debug != debug) - printk(KERN_INFO "eepro100.c: Debug level is %d.\n", debug); - if (debug >= 0) - speedo_debug = debug; - - return pci_module_init(&eepro100_driver); -} - -static void __exit eepro100_cleanup_module(void) -{ - pci_unregister_driver(&eepro100_driver); -} - -module_init(eepro100_init_module); -module_exit(eepro100_cleanup_module); diff --git a/xen-2.4.16/drivers/net/pcnet32.c b/xen-2.4.16/drivers/net/pcnet32.c deleted file mode 100644 index ce6c8341a2..0000000000 --- a/xen-2.4.16/drivers/net/pcnet32.c +++ /dev/null @@ -1,1614 +0,0 @@ -/* pcnet32.c: An AMD PCnet32 ethernet driver for linux. */ -/* - * Copyright 1996-1999 Thomas Bogendoerfer - * - * Derived from the lance driver written 1993,1994,1995 by Donald Becker. - * - * Copyright 1993 United States Government as represented by the - * Director, National Security Agency. - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * This driver is for PCnet32 and PCnetPCI based ethercards - */ -/************************************************************************** - * 23 Oct, 2000. - * Fixed a few bugs, related to running the controller in 32bit mode. - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - *************************************************************************/ - -static const char *version = "pcnet32.c:v1.25kf 26.9.1999 tsbogend@alpha.franken.de\n"; - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/lib.h> - -#include <linux/module.h> - -//#include <linux/kernel.h> -#include <linux/sched.h> -//#include <linux/string.h> -//#include <linux/ptrace.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/init.h> -#include <asm/bitops.h> -#include <asm/io.h> -//#include <asm/dma.h> - -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> -#include <linux/spinlock.h> - -static unsigned int pcnet32_portlist[] __initdata = {0x300, 0x320, 0x340, 0x360, 0}; - -/* - * PCI device identifiers for "new style" Linux PCI Device Drivers - */ -static struct pci_device_id pcnet32_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE_HOME, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { 0, } -}; - -static int pcnet32_debug = 1; -static int tx_start = 1; /* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */ - -static struct net_device *pcnet32_dev; - -static const int max_interrupt_work = 80; -static const int rx_copybreak = 0; /* 200; Xen doesn't do in-driver copybreak. */ - -#define PORT_AUI 0x00 -#define PORT_10BT 0x01 -#define PORT_GPSI 0x02 -#define PORT_MII 0x03 - -#define PORT_PORTSEL 0x03 -#define PORT_ASEL 0x04 -#define PORT_100 0x40 -#define PORT_FD 0x80 - -#define PCNET32_DMA_MASK 0xffffffff - -/* - * table to translate option values from tulip - * to internal options - */ -static unsigned char options_mapping[] = { - PORT_ASEL, /* 0 Auto-select */ - PORT_AUI, /* 1 BNC/AUI */ - PORT_AUI, /* 2 AUI/BNC */ - PORT_ASEL, /* 3 not supported */ - PORT_10BT | PORT_FD, /* 4 10baseT-FD */ - PORT_ASEL, /* 5 not supported */ - PORT_ASEL, /* 6 not supported */ - PORT_ASEL, /* 7 not supported */ - PORT_ASEL, /* 8 not supported */ - PORT_MII, /* 9 MII 10baseT */ - PORT_MII | PORT_FD, /* 10 MII 10baseT-FD */ - PORT_MII, /* 11 MII (autosel) */ - PORT_10BT, /* 12 10BaseT */ - PORT_MII | PORT_100, /* 13 MII 100BaseTx */ - PORT_MII | PORT_100 | PORT_FD, /* 14 MII 100BaseTx-FD */ - PORT_ASEL /* 15 not supported */ -}; - -#define MAX_UNITS 8 -static int options[MAX_UNITS]; -static int full_duplex[MAX_UNITS]; - -/* - * Theory of Operation - * - * This driver uses the same software structure as the normal lance - * driver. So look for a verbose description in lance.c. The differences - * to the normal lance driver is the use of the 32bit mode of PCnet32 - * and PCnetPCI chips. Because these chips are 32bit chips, there is no - * 16MB limitation and we don't need bounce buffers. - */ - -/* - * History: - * v0.01: Initial version - * only tested on Alpha Noname Board - * v0.02: changed IRQ handling for new interrupt scheme (dev_id) - * tested on a ASUS SP3G - * v0.10: fixed an odd problem with the 79C974 in a Compaq Deskpro XL - * looks like the 974 doesn't like stopping and restarting in a - * short period of time; now we do a reinit of the lance; the - * bug was triggered by doing ifconfig eth0 <ip> broadcast <addr> - * and hangs the machine (thanks to Klaus Liedl for debugging) - * v0.12: by suggestion from Donald Becker: Renamed driver to pcnet32, - * made it standalone (no need for lance.c) - * v0.13: added additional PCI detecting for special PCI devices (Compaq) - * v0.14: stripped down additional PCI probe (thanks to David C Niemi - * and sveneric@xs4all.nl for testing this on their Compaq boxes) - * v0.15: added 79C965 (VLB) probe - * added interrupt sharing for PCI chips - * v0.16: fixed set_multicast_list on Alpha machines - * v0.17: removed hack from dev.c; now pcnet32 uses ethif_probe in Space.c - * v0.19: changed setting of autoselect bit - * v0.20: removed additional Compaq PCI probe; there is now a working one - * in arch/i386/bios32.c - * v0.21: added endian conversion for ppc, from work by cort@cs.nmt.edu - * v0.22: added printing of status to ring dump - * v0.23: changed enet_statistics to net_devive_stats - * v0.90: added multicast filter - * added module support - * changed irq probe to new style - * added PCnetFast chip id - * added fix for receive stalls with Intel saturn chipsets - * added in-place rx skbs like in the tulip driver - * minor cleanups - * v0.91: added PCnetFast+ chip id - * back port to 2.0.x - * v1.00: added some stuff from Donald Becker's 2.0.34 version - * added support for byte counters in net_dev_stats - * v1.01: do ring dumps, only when debugging the driver - * increased the transmit timeout - * v1.02: fixed memory leak in pcnet32_init_ring() - * v1.10: workaround for stopped transmitter - * added port selection for modules - * detect special T1/E1 WAN card and setup port selection - * v1.11: fixed wrong checking of Tx errors - * v1.20: added check of return value kmalloc (cpeterso@cs.washington.edu) - * added save original kmalloc addr for freeing (mcr@solidum.com) - * added support for PCnetHome chip (joe@MIT.EDU) - * rewritten PCI card detection - * added dwio mode to get driver working on some PPC machines - * v1.21: added mii selection and mii ioctl - * v1.22: changed pci scanning code to make PPC people happy - * fixed switching to 32bit mode in pcnet32_open() (thanks - * to Michael Richard <mcr@solidum.com> for noticing this one) - * added sub vendor/device id matching (thanks again to - * Michael Richard <mcr@solidum.com>) - * added chip id for 79c973/975 (thanks to Zach Brown <zab@zabbo.net>) - * v1.23 fixed small bug, when manual selecting MII speed/duplex - * v1.24 Applied Thomas' patch to use TxStartPoint and thus decrease TxFIFO - * underflows. Added tx_start_pt module parameter. Increased - * TX_RING_SIZE from 16 to 32. Added #ifdef'd code to use DXSUFLO - * for FAST[+] chipsets. <kaf@fc.hp.com> - * v1.24ac Added SMP spinlocking - Alan Cox <alan@redhat.com> - * v1.25kf Added No Interrupt on successful Tx for some Tx's <kaf@fc.hp.com> - * v1.26 Converted to pci_alloc_consistent, Jamey Hicks / George France - * <jamey@crl.dec.com> - * v1.26p Fix oops on rmmod+insmod; plug i/o resource leak - Paul Gortmaker - */ - - -/* - * Set the number of Tx and Rx buffers, using Log_2(# buffers). - * Reasonable default values are 4 Tx buffers, and 16 Rx buffers. - * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4). - */ -#ifndef PCNET32_LOG_TX_BUFFERS -#define PCNET32_LOG_TX_BUFFERS 4 -#define PCNET32_LOG_RX_BUFFERS 5 -#endif - -#undef RX_RING_SIZE -#undef TX_RING_SIZE - -#define TX_RING_SIZE (1 << (PCNET32_LOG_TX_BUFFERS)) -#define TX_RING_MOD_MASK (TX_RING_SIZE - 1) -#define TX_RING_LEN_BITS ((PCNET32_LOG_TX_BUFFERS) << 12) - -#define RX_RING_SIZE (1 << (PCNET32_LOG_RX_BUFFERS)) -#define RX_RING_MOD_MASK (RX_RING_SIZE - 1) -#define RX_RING_LEN_BITS ((PCNET32_LOG_RX_BUFFERS) << 4) - -#define PKT_BUF_SZ 1544 - -/* Offsets from base I/O address. */ -#define PCNET32_WIO_RDP 0x10 -#define PCNET32_WIO_RAP 0x12 -#define PCNET32_WIO_RESET 0x14 -#define PCNET32_WIO_BDP 0x16 - -#define PCNET32_DWIO_RDP 0x10 -#define PCNET32_DWIO_RAP 0x14 -#define PCNET32_DWIO_RESET 0x18 -#define PCNET32_DWIO_BDP 0x1C - -#define PCNET32_TOTAL_SIZE 0x20 - -#define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ - -/* The PCNET32 Rx and Tx ring descriptors. */ -struct pcnet32_rx_head { - u32 base; - s16 buf_length; - s16 status; - u32 msg_length; - u32 reserved; -}; - -struct pcnet32_tx_head { - u32 base; - s16 length; - s16 status; - u32 misc; - u32 reserved; -}; - -/* The PCNET32 32-Bit initialization block, described in databook. */ -struct pcnet32_init_block { - u16 mode; - u16 tlen_rlen; - u8 phys_addr[6]; - u16 reserved; - u32 filter[2]; - /* Receive and transmit ring base, along with extra bits. */ - u32 rx_ring; - u32 tx_ring; -}; - -/* PCnet32 access functions */ -struct pcnet32_access { - u16 (*read_csr)(unsigned long, int); - void (*write_csr)(unsigned long, int, u16); - u16 (*read_bcr)(unsigned long, int); - void (*write_bcr)(unsigned long, int, u16); - u16 (*read_rap)(unsigned long); - void (*write_rap)(unsigned long, u16); - void (*reset)(unsigned long); -}; - -/* - * The first three fields of pcnet32_private are read by the ethernet device - * so we allocate the structure should be allocated by pci_alloc_consistent(). - */ -struct pcnet32_private { - /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */ - struct pcnet32_rx_head rx_ring[RX_RING_SIZE]; - struct pcnet32_tx_head tx_ring[TX_RING_SIZE]; - struct pcnet32_init_block init_block; - dma_addr_t dma_addr; /* DMA address of beginning of this object, returned by pci_alloc_consistent */ - struct pci_dev *pci_dev; /* Pointer to the associated pci device structure */ - const char *name; - /* The saved address of a sent-in-place packet/buffer, for skfree(). */ - struct sk_buff *tx_skbuff[TX_RING_SIZE]; - struct sk_buff *rx_skbuff[RX_RING_SIZE]; - dma_addr_t tx_dma_addr[TX_RING_SIZE]; - dma_addr_t rx_dma_addr[RX_RING_SIZE]; - struct pcnet32_access a; - spinlock_t lock; /* Guard lock */ - unsigned int cur_rx, cur_tx; /* The next free ring entry */ - unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ - struct net_device_stats stats; - char tx_full; - int options; - int shared_irq:1, /* shared irq possible */ - ltint:1, -#ifdef DO_DXSUFLO - dxsuflo:1, /* disable transmit stop on uflo */ -#endif - full_duplex:1, /* full duplex possible */ - mii:1; /* mii port available */ - struct net_device *next; -}; - -static int pcnet32_probe_vlbus(int cards_found); -static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *); -static int pcnet32_probe1(unsigned long, unsigned char, int, int, struct pci_dev *); -static int pcnet32_open(struct net_device *); -static int pcnet32_init_ring(struct net_device *); -static int pcnet32_start_xmit(struct sk_buff *, struct net_device *); -static int pcnet32_rx(struct net_device *); -static void pcnet32_tx_timeout (struct net_device *dev); -static void pcnet32_interrupt(int, void *, struct pt_regs *); -static int pcnet32_close(struct net_device *); -static struct net_device_stats *pcnet32_get_stats(struct net_device *); -static void pcnet32_set_multicast_list(struct net_device *); -#ifdef HAVE_PRIVATE_IOCTL -static int pcnet32_mii_ioctl(struct net_device *, struct ifreq *, int); -#endif - -enum pci_flags_bit { - PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, - PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, -}; - -struct pcnet32_pci_id_info { - const char *name; - u16 vendor_id, device_id, svid, sdid, flags; - int io_size; - int (*probe1) (unsigned long, unsigned char, int, int, struct pci_dev *); -}; - - -MODULE_DEVICE_TABLE (pci, pcnet32_pci_tbl); - -static u16 pcnet32_wio_read_csr (unsigned long addr, int index) -{ - outw (index, addr+PCNET32_WIO_RAP); - return inw (addr+PCNET32_WIO_RDP); -} - -static void pcnet32_wio_write_csr (unsigned long addr, int index, u16 val) -{ - outw (index, addr+PCNET32_WIO_RAP); - outw (val, addr+PCNET32_WIO_RDP); -} - -static u16 pcnet32_wio_read_bcr (unsigned long addr, int index) -{ - outw (index, addr+PCNET32_WIO_RAP); - return inw (addr+PCNET32_WIO_BDP); -} - -static void pcnet32_wio_write_bcr (unsigned long addr, int index, u16 val) -{ - outw (index, addr+PCNET32_WIO_RAP); - outw (val, addr+PCNET32_WIO_BDP); -} - -static u16 pcnet32_wio_read_rap (unsigned long addr) -{ - return inw (addr+PCNET32_WIO_RAP); -} - -static void pcnet32_wio_write_rap (unsigned long addr, u16 val) -{ - outw (val, addr+PCNET32_WIO_RAP); -} - -static void pcnet32_wio_reset (unsigned long addr) -{ - inw (addr+PCNET32_WIO_RESET); -} - -static int pcnet32_wio_check (unsigned long addr) -{ - outw (88, addr+PCNET32_WIO_RAP); - return (inw (addr+PCNET32_WIO_RAP) == 88); -} - -static struct pcnet32_access pcnet32_wio = { - pcnet32_wio_read_csr, - pcnet32_wio_write_csr, - pcnet32_wio_read_bcr, - pcnet32_wio_write_bcr, - pcnet32_wio_read_rap, - pcnet32_wio_write_rap, - pcnet32_wio_reset -}; - -static u16 pcnet32_dwio_read_csr (unsigned long addr, int index) -{ - outl (index, addr+PCNET32_DWIO_RAP); - return (inl (addr+PCNET32_DWIO_RDP) & 0xffff); -} - -static void pcnet32_dwio_write_csr (unsigned long addr, int index, u16 val) -{ - outl (index, addr+PCNET32_DWIO_RAP); - outl (val, addr+PCNET32_DWIO_RDP); -} - -static u16 pcnet32_dwio_read_bcr (unsigned long addr, int index) -{ - outl (index, addr+PCNET32_DWIO_RAP); - return (inl (addr+PCNET32_DWIO_BDP) & 0xffff); -} - -static void pcnet32_dwio_write_bcr (unsigned long addr, int index, u16 val) -{ - outl (index, addr+PCNET32_DWIO_RAP); - outl (val, addr+PCNET32_DWIO_BDP); -} - -static u16 pcnet32_dwio_read_rap (unsigned long addr) -{ - return (inl (addr+PCNET32_DWIO_RAP) & 0xffff); -} - -static void pcnet32_dwio_write_rap (unsigned long addr, u16 val) -{ - outl (val, addr+PCNET32_DWIO_RAP); -} - -static void pcnet32_dwio_reset (unsigned long addr) -{ - inl (addr+PCNET32_DWIO_RESET); -} - -static int pcnet32_dwio_check (unsigned long addr) -{ - outl (88, addr+PCNET32_DWIO_RAP); - return ((inl (addr+PCNET32_DWIO_RAP) & 0xffff) == 88); -} - -static struct pcnet32_access pcnet32_dwio = { - pcnet32_dwio_read_csr, - pcnet32_dwio_write_csr, - pcnet32_dwio_read_bcr, - pcnet32_dwio_write_bcr, - pcnet32_dwio_read_rap, - pcnet32_dwio_write_rap, - pcnet32_dwio_reset - -}; - - - -/* only probes for non-PCI devices, the rest are handled by pci_register_driver via pcnet32_probe_pci*/ -static int __init pcnet32_probe_vlbus(int cards_found) -{ - unsigned long ioaddr = 0; // FIXME dev ? dev->base_addr: 0; - unsigned int irq_line = 0; // FIXME dev ? dev->irq : 0; - int *port; - - printk(KERN_INFO "pcnet32_probe_vlbus: cards_found=%d\n", cards_found); -#ifndef __powerpc__ - if (ioaddr > 0x1ff) { - if (check_region(ioaddr, PCNET32_TOTAL_SIZE) == 0) - return pcnet32_probe1(ioaddr, irq_line, 0, 0, NULL); - else - return -ENODEV; - } else -#endif - if (ioaddr != 0) - return -ENXIO; - - /* now look for PCnet32 VLB cards */ - for (port = pcnet32_portlist; *port; port++) { - unsigned long ioaddr = *port; - - if ( check_region(ioaddr, PCNET32_TOTAL_SIZE) == 0) { - /* check if there is really a pcnet chip on that ioaddr */ - if ((inb(ioaddr + 14) == 0x57) && - (inb(ioaddr + 15) == 0x57) && - (pcnet32_probe1(ioaddr, 0, 0, 0, NULL) == 0)) - cards_found++; - } - } - return cards_found ? 0: -ENODEV; -} - - - -static int __devinit -pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - static int card_idx; - long ioaddr; - int err = 0; - - printk(KERN_INFO "pcnet32_probe_pci: found device %#08x.%#08x\n", ent->vendor, ent->device); - - if ((err = pci_enable_device(pdev)) < 0) { - printk(KERN_ERR "pcnet32.c: failed to enable device -- err=%d\n", err); - return err; - } - pci_set_master(pdev); - - ioaddr = pci_resource_start (pdev, 0); - printk(KERN_INFO " ioaddr=%#08lx resource_flags=%#08lx\n", ioaddr, pci_resource_flags (pdev, 0)); - if (!ioaddr) { - printk (KERN_ERR "no PCI IO resources, aborting\n"); - return -ENODEV; - } - - if (!pci_dma_supported(pdev, PCNET32_DMA_MASK)) { - printk(KERN_ERR "pcnet32.c: architecture does not support 32bit PCI busmaster DMA\n"); - return -ENODEV; - } - - return pcnet32_probe1(ioaddr, pdev->irq, 1, card_idx, pdev); -} - - -/* pcnet32_probe1 - * Called from both pcnet32_probe_vlbus and pcnet_probe_pci. - * pdev will be NULL when called from pcnet32_probe_vlbus. - */ -static int __devinit -pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int card_idx, struct pci_dev *pdev) -{ - struct pcnet32_private *lp; - struct resource *res; - dma_addr_t lp_dma_addr; - int i,media,fdx = 0, mii = 0, fset = 0; -#ifdef DO_DXSUFLO - int dxsuflo = 0; -#endif - int ltint = 0; - int chip_version; - char *chipname; - struct net_device *dev; - struct pcnet32_access *a = NULL; - - /* reset the chip */ - pcnet32_dwio_reset(ioaddr); - pcnet32_wio_reset(ioaddr); - - /* NOTE: 16-bit check is first, otherwise some older PCnet chips fail */ - if (pcnet32_wio_read_csr (ioaddr, 0) == 4 && pcnet32_wio_check (ioaddr)) { - a = &pcnet32_wio; - } else { - if (pcnet32_dwio_read_csr (ioaddr, 0) == 4 && pcnet32_dwio_check(ioaddr)) { - a = &pcnet32_dwio; - } else - return -ENODEV; - } - - chip_version = a->read_csr (ioaddr, 88) | (a->read_csr (ioaddr,89) << 16); - if (pcnet32_debug > 2) - printk(KERN_INFO " PCnet chip version is %#x.\n", chip_version); - if ((chip_version & 0xfff) != 0x003) - return -ENODEV; - chip_version = (chip_version >> 12) & 0xffff; - switch (chip_version) { - case 0x2420: - chipname = "PCnet/PCI 79C970"; /* PCI */ - break; - case 0x2430: - if (shared) - chipname = "PCnet/PCI 79C970"; /* 970 gives the wrong chip id back */ - else - chipname = "PCnet/32 79C965"; /* 486/VL bus */ - break; - case 0x2621: - chipname = "PCnet/PCI II 79C970A"; /* PCI */ - fdx = 1; - break; - case 0x2623: - chipname = "PCnet/FAST 79C971"; /* PCI */ - fdx = 1; mii = 1; fset = 1; - ltint = 1; - break; - case 0x2624: - chipname = "PCnet/FAST+ 79C972"; /* PCI */ - fdx = 1; mii = 1; fset = 1; - break; - case 0x2625: - chipname = "PCnet/FAST III 79C973"; /* PCI */ - fdx = 1; mii = 1; - break; - case 0x2626: - chipname = "PCnet/Home 79C978"; /* PCI */ - fdx = 1; - /* - * This is based on specs published at www.amd.com. This section - * assumes that a card with a 79C978 wants to go into 1Mb HomePNA - * mode. The 79C978 can also go into standard ethernet, and there - * probably should be some sort of module option to select the - * mode by which the card should operate - */ - /* switch to home wiring mode */ - media = a->read_bcr (ioaddr, 49); -#if 0 - if (pcnet32_debug > 2) - printk(KERN_DEBUG "pcnet32: pcnet32 media value %#x.\n", media); - media &= ~3; - media |= 1; -#endif - if (pcnet32_debug > 2) - printk(KERN_DEBUG "pcnet32: pcnet32 media reset to %#x.\n", media); - a->write_bcr (ioaddr, 49, media); - break; - case 0x2627: - chipname = "PCnet/FAST III 79C975"; /* PCI */ - fdx = 1; mii = 1; - break; - default: - printk(KERN_INFO "pcnet32: PCnet version %#x, no PCnet32 chip.\n",chip_version); - return -ENODEV; - } - - /* - * On selected chips turn on the BCR18:NOUFLO bit. This stops transmit - * starting until the packet is loaded. Strike one for reliability, lose - * one for latency - although on PCI this isnt a big loss. Older chips - * have FIFO's smaller than a packet, so you can't do this. - */ - - if(fset) - { - a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0800)); - a->write_csr(ioaddr, 80, (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00); -#ifdef DO_DXSUFLO - dxsuflo = 1; -#endif - ltint = 1; - } - - dev = init_etherdev(NULL, 0); - if(dev==NULL) - return -ENOMEM; - - printk(KERN_INFO "%s: %s at %#3lx,", dev->name, chipname, ioaddr); - - /* In most chips, after a chip reset, the ethernet address is read from the - * station address PROM at the base address and programmed into the - * "Physical Address Registers" CSR12-14. - * As a precautionary measure, we read the PROM values and complain if - * they disagree with the CSRs. Either way, we use the CSR values, and - * double check that they are valid. - */ - for (i = 0; i < 3; i++) { - unsigned int val; - val = a->read_csr(ioaddr, i+12) & 0x0ffff; - /* There may be endianness issues here. */ - dev->dev_addr[2*i] = val & 0x0ff; - dev->dev_addr[2*i+1] = (val >> 8) & 0x0ff; - } - { - u8 promaddr[6]; - for (i = 0; i < 6; i++) { - promaddr[i] = inb(ioaddr + i); - } - if( memcmp( promaddr, dev->dev_addr, 6) ) - { - printk(" warning PROM address does not match CSR address\n"); -#if defined(__i386__) - printk(KERN_WARNING "%s: Probably a Compaq, using the PROM address of", dev->name); - memcpy(dev->dev_addr, promaddr, 6); -#endif - } - } - /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */ - if( !is_valid_ether_addr(dev->dev_addr) ) - for (i = 0; i < 6; i++) - dev->dev_addr[i]=0; - - for (i = 0; i < 6; i++) - printk(" %2.2x", dev->dev_addr[i] ); - - if (((chip_version + 1) & 0xfffe) == 0x2624) { /* Version 0x2623 or 0x2624 */ - i = a->read_csr(ioaddr, 80) & 0x0C00; /* Check tx_start_pt */ - printk("\n" KERN_INFO " tx_start_pt(0x%04x):",i); - switch(i>>10) { - case 0: printk(" 20 bytes,"); break; - case 1: printk(" 64 bytes,"); break; - case 2: printk(" 128 bytes,"); break; - case 3: printk("~220 bytes,"); break; - } - i = a->read_bcr(ioaddr, 18); /* Check Burst/Bus control */ - printk(" BCR18(%x):",i&0xffff); - if (i & (1<<5)) printk("BurstWrEn "); - if (i & (1<<6)) printk("BurstRdEn "); - if (i & (1<<7)) printk("DWordIO "); - if (i & (1<<11)) printk("NoUFlow "); - i = a->read_bcr(ioaddr, 25); - printk("\n" KERN_INFO " SRAMSIZE=0x%04x,",i<<8); - i = a->read_bcr(ioaddr, 26); - printk(" SRAM_BND=0x%04x,",i<<8); - i = a->read_bcr(ioaddr, 27); - if (i & (1<<14)) printk("LowLatRx"); - } - - dev->base_addr = ioaddr; - res = request_region(ioaddr, PCNET32_TOTAL_SIZE, chipname); - if (res == NULL) - return -EBUSY; - - /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */ - if ((lp = pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL) { - release_resource(res); - return -ENOMEM; - } - - memset(lp, 0, sizeof(*lp)); - lp->dma_addr = lp_dma_addr; - lp->pci_dev = pdev; - printk("\n" KERN_INFO "pcnet32: pcnet32_private lp=%p lp_dma_addr=%#08x", lp, lp_dma_addr); - - spin_lock_init(&lp->lock); - - dev->priv = lp; - lp->name = chipname; - lp->shared_irq = shared; - lp->full_duplex = fdx; -#ifdef DO_DXSUFLO - lp->dxsuflo = dxsuflo; -#endif - lp->ltint = ltint; - lp->mii = mii; - if (options[card_idx] > sizeof (options_mapping)) - lp->options = PORT_ASEL; - else - lp->options = options_mapping[options[card_idx]]; - - if (fdx && !(lp->options & PORT_ASEL) && full_duplex[card_idx]) - lp->options |= PORT_FD; - - if (a == NULL) { - printk(KERN_ERR "pcnet32: No access methods\n"); - pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); - release_resource(res); - return -ENODEV; - } - lp->a = *a; - - /* detect special T1/E1 WAN card by checking for MAC address */ - if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0 && dev->dev_addr[2] == 0x75) - lp->options = PORT_FD | PORT_GPSI; - - lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */ - lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS); - for (i = 0; i < 6; i++) - lp->init_block.phys_addr[i] = dev->dev_addr[i]; - lp->init_block.filter[0] = 0x00000000; - lp->init_block.filter[1] = 0x00000000; - lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr + offsetof(struct pcnet32_private, rx_ring)); - lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr + offsetof(struct pcnet32_private, tx_ring)); - - /* switch pcnet32 to 32bit mode */ - a->write_bcr (ioaddr, 20, 2); - - a->write_csr (ioaddr, 1, (lp->dma_addr + offsetof(struct pcnet32_private, init_block)) & 0xffff); - a->write_csr (ioaddr, 2, (lp->dma_addr + offsetof(struct pcnet32_private, init_block)) >> 16); - - if (irq_line) { - dev->irq = irq_line; - } - - if (dev->irq >= 2) - printk(" assigned IRQ %d.\n", dev->irq); - else { - unsigned long irq_mask = probe_irq_on(); - - /* - * To auto-IRQ we enable the initialization-done and DMA error - * interrupts. For ISA boards we get a DMA error, but VLB and PCI - * boards will work. - */ - /* Trigger an initialization just for the interrupt. */ - a->write_csr (ioaddr, 0, 0x41); - mdelay (1); - - dev->irq = probe_irq_off (irq_mask); - if (dev->irq) - printk(", probed IRQ %d.\n", dev->irq); - else { - printk(", failed to detect IRQ line.\n"); - pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); - release_resource(res); - return -ENODEV; - } - } - - if (pcnet32_debug > 0) - printk(KERN_INFO "%s", version); - - /* The PCNET32-specific entries in the device structure. */ - dev->open = &pcnet32_open; - dev->hard_start_xmit = &pcnet32_start_xmit; - dev->stop = &pcnet32_close; - dev->get_stats = &pcnet32_get_stats; - dev->set_multicast_list = &pcnet32_set_multicast_list; -#ifdef HAVE_PRIVATE_IOCTL - dev->do_ioctl = &pcnet32_mii_ioctl; -#endif - dev->tx_timeout = pcnet32_tx_timeout; - dev->watchdog_timeo = (HZ >> 1); - - lp->next = pcnet32_dev; - pcnet32_dev = dev; - - /* Fill in the generic fields of the device structure. */ - ether_setup(dev); - return 0; -} - - -static int -pcnet32_open(struct net_device *dev) -{ - struct pcnet32_private *lp = dev->priv; - unsigned long ioaddr = dev->base_addr; - u16 val; - int i; - - if (dev->irq == 0 || - request_irq(dev->irq, &pcnet32_interrupt, - lp->shared_irq ? SA_SHIRQ : 0, lp->name, (void *)dev)) { - return -EAGAIN; - } - - /* Check for a valid station address */ - if( !is_valid_ether_addr(dev->dev_addr) ) - return -EINVAL; - - /* Reset the PCNET32 */ - lp->a.reset (ioaddr); - - /* switch pcnet32 to 32bit mode */ - lp->a.write_bcr (ioaddr, 20, 2); - - if (pcnet32_debug > 1) - printk(KERN_DEBUG "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n", - dev->name, dev->irq, - (u32) (lp->dma_addr + offsetof(struct pcnet32_private, tx_ring)), - (u32) (lp->dma_addr + offsetof(struct pcnet32_private, rx_ring)), - (u32) (lp->dma_addr + offsetof(struct pcnet32_private, init_block))); - - /* set/reset autoselect bit */ - val = lp->a.read_bcr (ioaddr, 2) & ~2; - if (lp->options & PORT_ASEL) - val |= 2; - lp->a.write_bcr (ioaddr, 2, val); - - /* handle full duplex setting */ - if (lp->full_duplex) { - val = lp->a.read_bcr (ioaddr, 9) & ~3; - if (lp->options & PORT_FD) { - val |= 1; - if (lp->options == (PORT_FD | PORT_AUI)) - val |= 2; - } - lp->a.write_bcr (ioaddr, 9, val); - } - - /* set/reset GPSI bit in test register */ - val = lp->a.read_csr (ioaddr, 124) & ~0x10; - if ((lp->options & PORT_PORTSEL) == PORT_GPSI) - val |= 0x10; - lp->a.write_csr (ioaddr, 124, val); - - if (lp->mii && !(lp->options & PORT_ASEL)) { - val = lp->a.read_bcr (ioaddr, 32) & ~0x38; /* disable Auto Negotiation, set 10Mpbs, HD */ - if (lp->options & PORT_FD) - val |= 0x10; - if (lp->options & PORT_100) - val |= 0x08; - lp->a.write_bcr (ioaddr, 32, val); - } else { - if (lp->options & PORT_ASEL) { /* enable auto negotiate, setup, disable fd */ - val = lp->a.read_bcr(ioaddr, 32) & ~0x98; - val |= 0x20; - lp->a.write_bcr(ioaddr, 32, val); - } - } - -#ifdef DO_DXSUFLO - if (lp->dxsuflo) { /* Disable transmit stop on underflow */ - val = lp->a.read_csr (ioaddr, 3); - val |= 0x40; - lp->a.write_csr (ioaddr, 3, val); - } -#endif - if (lp->ltint) { /* Enable TxDone-intr inhibitor */ - val = lp->a.read_csr (ioaddr, 5); - val |= (1<<14); - lp->a.write_csr (ioaddr, 5, val); - } - - lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7); - lp->init_block.filter[0] = 0x00000000; - lp->init_block.filter[1] = 0x00000000; - if (pcnet32_init_ring(dev)) - return -ENOMEM; - - /* Re-initialize the PCNET32, and start it when done. */ - lp->a.write_csr (ioaddr, 1, (lp->dma_addr + offsetof(struct pcnet32_private, init_block)) &0xffff); - lp->a.write_csr (ioaddr, 2, (lp->dma_addr + offsetof(struct pcnet32_private, init_block)) >> 16); - - lp->a.write_csr (ioaddr, 4, 0x0915); - lp->a.write_csr (ioaddr, 0, 0x0001); - - netif_start_queue(dev); - - i = 0; - while (i++ < 100) - if (lp->a.read_csr (ioaddr, 0) & 0x0100) - break; - /* - * We used to clear the InitDone bit, 0x0100, here but Mark Stockton - * reports that doing so triggers a bug in the '974. - */ - lp->a.write_csr (ioaddr, 0, 0x0042); - - if (pcnet32_debug > 2) - printk(KERN_DEBUG "%s: pcnet32 open after %d ticks, init block %#x csr0 %4.4x.\n", - dev->name, i, (u32) (lp->dma_addr + offsetof(struct pcnet32_private, init_block)), - lp->a.read_csr (ioaddr, 0)); - - - MOD_INC_USE_COUNT; - - return 0; /* Always succeed */ -} - -/* - * The LANCE has been halted for one reason or another (busmaster memory - * arbitration error, Tx FIFO underflow, driver stopped it to reconfigure, - * etc.). Modern LANCE variants always reload their ring-buffer - * configuration when restarted, so we must reinitialize our ring - * context before restarting. As part of this reinitialization, - * find all packets still on the Tx ring and pretend that they had been - * sent (in effect, drop the packets on the floor) - the higher-level - * protocols will time out and retransmit. It'd be better to shuffle - * these skbs to a temp list and then actually re-Tx them after - * restarting the chip, but I'm too lazy to do so right now. dplatt@3do.com - */ - -static void -pcnet32_purge_tx_ring(struct net_device *dev) -{ - struct pcnet32_private *lp = dev->priv; - int i; - - for (i = 0; i < TX_RING_SIZE; i++) { - if (lp->tx_skbuff[i]) { - pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[i], lp->tx_skbuff[i]->len, PCI_DMA_TODEVICE); - dev_kfree_skb(lp->tx_skbuff[i]); - lp->tx_skbuff[i] = NULL; - lp->tx_dma_addr[i] = 0; - } - } -} - - -/* Initialize the PCNET32 Rx and Tx rings. */ -static int -pcnet32_init_ring(struct net_device *dev) -{ - struct pcnet32_private *lp = dev->priv; - int i; - - lp->tx_full = 0; - lp->cur_rx = lp->cur_tx = 0; - lp->dirty_rx = lp->dirty_tx = 0; - - for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *rx_skbuff = lp->rx_skbuff[i]; - if (rx_skbuff == NULL) { - if (!(rx_skbuff = lp->rx_skbuff[i] = dev_alloc_skb (PKT_BUF_SZ))) { - /* there is not much, we can do at this point */ - printk(KERN_ERR "%s: pcnet32_init_ring dev_alloc_skb failed.\n",dev->name); - return -1; - } - skb_reserve (rx_skbuff, 2); - } - lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail, rx_skbuff->len, PCI_DMA_FROMDEVICE); - lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]); - lp->rx_ring[i].buf_length = le16_to_cpu(-PKT_BUF_SZ); - lp->rx_ring[i].status = le16_to_cpu(0x8000); - } - /* The Tx buffer address is filled in as needed, but we do need to clear - the upper ownership bit. */ - for (i = 0; i < TX_RING_SIZE; i++) { - lp->tx_ring[i].base = 0; - lp->tx_ring[i].status = 0; - lp->tx_dma_addr[i] = 0; - } - - lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS); - for (i = 0; i < 6; i++) - lp->init_block.phys_addr[i] = dev->dev_addr[i]; - lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr + offsetof(struct pcnet32_private, rx_ring)); - lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr + offsetof(struct pcnet32_private, tx_ring)); - return 0; -} - -static void -pcnet32_restart(struct net_device *dev, unsigned int csr0_bits) -{ - struct pcnet32_private *lp = dev->priv; - unsigned long ioaddr = dev->base_addr; - int i; - - pcnet32_purge_tx_ring(dev); - if (pcnet32_init_ring(dev)) - return; - - /* ReInit Ring */ - lp->a.write_csr (ioaddr, 0, 1); - i = 0; - while (i++ < 100) - if (lp->a.read_csr (ioaddr, 0) & 0x0100) - break; - - lp->a.write_csr (ioaddr, 0, csr0_bits); -} - - -static void -pcnet32_tx_timeout (struct net_device *dev) -{ - struct pcnet32_private *lp = dev->priv; - unsigned int ioaddr = dev->base_addr; - - /* Transmitter timeout, serious problems. */ - printk(KERN_ERR "%s: transmit timed out, status %4.4x, resetting.\n", - dev->name, lp->a.read_csr (ioaddr, 0)); - lp->a.write_csr (ioaddr, 0, 0x0004); - lp->stats.tx_errors++; - if (pcnet32_debug > 2) { - int i; - printk(KERN_DEBUG " Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.", - lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "", - lp->cur_rx); - for (i = 0 ; i < RX_RING_SIZE; i++) - printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ", - lp->rx_ring[i].base, -lp->rx_ring[i].buf_length, - lp->rx_ring[i].msg_length, (unsigned)lp->rx_ring[i].status); - for (i = 0 ; i < TX_RING_SIZE; i++) - printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ", - lp->tx_ring[i].base, -lp->tx_ring[i].length, - lp->tx_ring[i].misc, (unsigned)lp->tx_ring[i].status); - printk("\n"); - } - pcnet32_restart(dev, 0x0042); - - dev->trans_start = jiffies; - netif_start_queue(dev); -} - - -static int -pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct pcnet32_private *lp = dev->priv; - unsigned int ioaddr = dev->base_addr; - u16 status; - int entry; - unsigned long flags; - - if (pcnet32_debug > 3) { - printk(KERN_DEBUG "%s: pcnet32_start_xmit() called, csr0 %4.4x.\n", - dev->name, lp->a.read_csr (ioaddr, 0)); - } - - spin_lock_irqsave(&lp->lock, flags); - - /* Default status -- will not enable Successful-TxDone - * interrupt when that option is available to us. - */ - status = 0x8300; - if ((lp->ltint) && - ((lp->cur_tx - lp->dirty_tx == TX_RING_SIZE/2) || - (lp->cur_tx - lp->dirty_tx >= TX_RING_SIZE-2))) - { - /* Enable Successful-TxDone interrupt if we have - * 1/2 of, or nearly all of, our ring buffer Tx'd - * but not yet cleaned up. Thus, most of the time, - * we will not enable Successful-TxDone interrupts. - */ - status = 0x9300; - } - - /* Fill in a Tx ring entry */ - - /* Mask to ring buffer boundary. */ - entry = lp->cur_tx & TX_RING_MOD_MASK; - - /* Caution: the write order is important here, set the base address - with the "ownership" bits last. */ - - lp->tx_ring[entry].length = le16_to_cpu(-skb->len); - - lp->tx_ring[entry].misc = 0x00000000; - - lp->tx_skbuff[entry] = skb; - lp->tx_dma_addr[entry] = pci_map_single(lp->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE); - lp->tx_ring[entry].base = (u32)le32_to_cpu(lp->tx_dma_addr[entry]); - lp->tx_ring[entry].status = le16_to_cpu(status); - - lp->cur_tx++; - lp->stats.tx_bytes += skb->len; - - /* Trigger an immediate send poll. */ - lp->a.write_csr (ioaddr, 0, 0x0048); - - dev->trans_start = jiffies; - - if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0) - netif_start_queue(dev); - else { - lp->tx_full = 1; - netif_stop_queue(dev); - } - spin_unlock_irqrestore(&lp->lock, flags); - return 0; -} - -/* The PCNET32 interrupt handler. */ -static void -pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs) -{ - struct net_device *dev = dev_id; - struct pcnet32_private *lp; - unsigned long ioaddr; - u16 csr0,rap; - int boguscnt = max_interrupt_work; - int must_restart; - - if (dev == NULL) { - printk (KERN_DEBUG "pcnet32_interrupt(): irq %d for unknown device.\n", irq); - return; - } - - ioaddr = dev->base_addr; - lp = dev->priv; - - spin_lock(&lp->lock); - - rap = lp->a.read_rap(ioaddr); - while ((csr0 = lp->a.read_csr (ioaddr, 0)) & 0x8600 && --boguscnt >= 0) { - /* Acknowledge all of the current interrupt sources ASAP. */ - lp->a.write_csr (ioaddr, 0, csr0 & ~0x004f); - - must_restart = 0; - - if (pcnet32_debug > 5) - printk(KERN_DEBUG "%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n", - dev->name, csr0, lp->a.read_csr (ioaddr, 0)); - - if (csr0 & 0x0400) /* Rx interrupt */ - pcnet32_rx(dev); - - if (csr0 & 0x0200) { /* Tx-done interrupt */ - unsigned int dirty_tx = lp->dirty_tx; - - while (dirty_tx < lp->cur_tx) { - int entry = dirty_tx & TX_RING_MOD_MASK; - int status = (short)le16_to_cpu(lp->tx_ring[entry].status); - - if (status < 0) - break; /* It still hasn't been Txed */ - - lp->tx_ring[entry].base = 0; - - if (status & 0x4000) { - /* There was an major error, log it. */ - int err_status = le32_to_cpu(lp->tx_ring[entry].misc); - lp->stats.tx_errors++; - if (err_status & 0x04000000) lp->stats.tx_aborted_errors++; - if (err_status & 0x08000000) lp->stats.tx_carrier_errors++; - if (err_status & 0x10000000) lp->stats.tx_window_errors++; -#ifndef DO_DXSUFLO - if (err_status & 0x40000000) { - lp->stats.tx_fifo_errors++; - /* Ackk! On FIFO errors the Tx unit is turned off! */ - /* Remove this verbosity later! */ - printk(KERN_ERR "%s: Tx FIFO error! CSR0=%4.4x\n", - dev->name, csr0); - must_restart = 1; - } -#else - if (err_status & 0x40000000) { - lp->stats.tx_fifo_errors++; - if (! lp->dxsuflo) { /* If controller doesn't recover ... */ - /* Ackk! On FIFO errors the Tx unit is turned off! */ - /* Remove this verbosity later! */ - printk(KERN_ERR "%s: Tx FIFO error! CSR0=%4.4x\n", - dev->name, csr0); - must_restart = 1; - } - } -#endif - } else { - if (status & 0x1800) - lp->stats.collisions++; - lp->stats.tx_packets++; - } - - /* We must free the original skb */ - if (lp->tx_skbuff[entry]) { - pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[entry], lp->tx_skbuff[entry]->len, PCI_DMA_TODEVICE); - dev_kfree_skb_irq(lp->tx_skbuff[entry]); - lp->tx_skbuff[entry] = 0; - lp->tx_dma_addr[entry] = 0; - } - dirty_tx++; - } - -#ifndef final_version - if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) { - printk(KERN_ERR "out-of-sync dirty pointer, %d vs. %d, full=%d.\n", - dirty_tx, lp->cur_tx, lp->tx_full); - dirty_tx += TX_RING_SIZE; - } -#endif - if (lp->tx_full && - netif_queue_stopped(dev) && - dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) { - /* The ring is no longer full, clear tbusy. */ - lp->tx_full = 0; - netif_wake_queue (dev); - } - lp->dirty_tx = dirty_tx; - } - - /* Log misc errors. */ - if (csr0 & 0x4000) lp->stats.tx_errors++; /* Tx babble. */ - if (csr0 & 0x1000) { - /* - * this happens when our receive ring is full. This shouldn't - * be a problem as we will see normal rx interrupts for the frames - * in the receive ring. But there are some PCI chipsets (I can reproduce - * this on SP3G with Intel saturn chipset) which have sometimes problems - * and will fill up the receive ring with error descriptors. In this - * situation we don't get a rx interrupt, but a missed frame interrupt sooner - * or later. So we try to clean up our receive ring here. - */ - pcnet32_rx(dev); - lp->stats.rx_errors++; /* Missed a Rx frame. */ - } - if (csr0 & 0x0800) { - printk(KERN_ERR "%s: Bus master arbitration failure, status %4.4x.\n", - dev->name, csr0); - /* unlike for the lance, there is no restart needed */ - } - - if (must_restart) { - /* stop the chip to clear the error condition, then restart */ - lp->a.write_csr (ioaddr, 0, 0x0004); - pcnet32_restart(dev, 0x0002); - } - } - - /* Clear any other interrupt, and set interrupt enable. */ - lp->a.write_csr (ioaddr, 0, 0x7940); - lp->a.write_rap(ioaddr,rap); - - if (pcnet32_debug > 4) - printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n", - dev->name, lp->a.read_csr (ioaddr, 0)); - - spin_unlock(&lp->lock); -} - -static int -pcnet32_rx(struct net_device *dev) -{ - struct pcnet32_private *lp = dev->priv; - int entry = lp->cur_rx & RX_RING_MOD_MASK; - - /* If we own the next entry, it's a new packet. Send it up. */ - while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) { - int status = (short)le16_to_cpu(lp->rx_ring[entry].status) >> 8; - - if (status != 0x03) { /* There was an error. */ - /* - * There is a tricky error noted by John Murphy, - * <murf@perftech.com> to Russ Nelson: Even with full-sized - * buffers it's possible for a jabber packet to use two - * buffers, with only the last correctly noting the error. - */ - if (status & 0x01) /* Only count a general error at the */ - lp->stats.rx_errors++; /* end of a packet.*/ - if (status & 0x20) lp->stats.rx_frame_errors++; - if (status & 0x10) lp->stats.rx_over_errors++; - if (status & 0x08) lp->stats.rx_crc_errors++; - if (status & 0x04) lp->stats.rx_fifo_errors++; - lp->rx_ring[entry].status &= le16_to_cpu(0x03ff); - } else { - /* Malloc up new buffer, compatible with net-2e. */ - short pkt_len = (le32_to_cpu(lp->rx_ring[entry].msg_length) & 0xfff)-4; - struct sk_buff *skb; - - if(pkt_len < 60) { - printk(KERN_ERR "%s: Runt packet!\n",dev->name); - lp->stats.rx_errors++; - } else { - int rx_in_place = 0; - - if (pkt_len > rx_copybreak) { - struct sk_buff *newskb; - - if ((newskb = dev_alloc_skb (PKT_BUF_SZ))) { - skb_reserve (newskb, 2); - skb = lp->rx_skbuff[entry]; - skb_put (skb, pkt_len); - lp->rx_skbuff[entry] = newskb; - newskb->dev = dev; - lp->rx_dma_addr[entry] = pci_map_single(lp->pci_dev, newskb->tail, newskb->len, PCI_DMA_FROMDEVICE); - lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]); - rx_in_place = 1; - } else - skb = NULL; - } else { - skb = dev_alloc_skb(pkt_len+2); - } - - if (skb == NULL) { - int i; - printk(KERN_ERR "%s: Memory squeeze, deferring packet.\n", dev->name); - for (i = 0; i < RX_RING_SIZE; i++) - if ((short)le16_to_cpu(lp->rx_ring[(entry+i) & RX_RING_MOD_MASK].status) < 0) - break; - - if (i > RX_RING_SIZE -2) { - lp->stats.rx_dropped++; - lp->rx_ring[entry].status |= le16_to_cpu(0x8000); - lp->cur_rx++; - } - break; - } - skb->dev = dev; - if (!rx_in_place) { - skb_reserve(skb,2); /* 16 byte align */ - skb_put(skb,pkt_len); /* Make room */ - eth_copy_and_sum(skb, - (unsigned char *)(lp->rx_skbuff[entry]->tail), - pkt_len,0); - } - lp->stats.rx_bytes += skb->len; - skb->protocol=eth_type_trans(skb,dev); - netif_rx(skb); - lp->stats.rx_packets++; - } - } - /* - * The docs say that the buffer length isn't touched, but Andrew Boyd - * of QNX reports that some revs of the 79C965 clear it. - */ - lp->rx_ring[entry].buf_length = le16_to_cpu(-PKT_BUF_SZ); - lp->rx_ring[entry].status |= le16_to_cpu(0x8000); - entry = (++lp->cur_rx) & RX_RING_MOD_MASK; - } - - return 0; -} - -static int -pcnet32_close(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - struct pcnet32_private *lp = dev->priv; - int i; - - netif_stop_queue(dev); - - lp->stats.rx_missed_errors = lp->a.read_csr (ioaddr, 112); - - if (pcnet32_debug > 1) - printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", - dev->name, lp->a.read_csr (ioaddr, 0)); - - /* We stop the PCNET32 here -- it occasionally polls memory if we don't. */ - lp->a.write_csr (ioaddr, 0, 0x0004); - - /* - * Switch back to 16bit mode to avoid problems with dumb - * DOS packet driver after a warm reboot - */ - lp->a.write_bcr (ioaddr, 20, 4); - - free_irq(dev->irq, dev); - - /* free all allocated skbuffs */ - for (i = 0; i < RX_RING_SIZE; i++) { - lp->rx_ring[i].status = 0; - if (lp->rx_skbuff[i]) { - pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], lp->rx_skbuff[i]->len, PCI_DMA_FROMDEVICE); - dev_kfree_skb(lp->rx_skbuff[i]); - } - lp->rx_skbuff[i] = NULL; - lp->rx_dma_addr[i] = 0; - } - - for (i = 0; i < TX_RING_SIZE; i++) { - if (lp->tx_skbuff[i]) { - pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[i], lp->tx_skbuff[i]->len, PCI_DMA_TODEVICE); - dev_kfree_skb(lp->tx_skbuff[i]); - } - lp->tx_skbuff[i] = NULL; - lp->tx_dma_addr[i] = 0; - } - - MOD_DEC_USE_COUNT; - - return 0; -} - -static struct net_device_stats * -pcnet32_get_stats(struct net_device *dev) -{ - struct pcnet32_private *lp = dev->priv; - unsigned long ioaddr = dev->base_addr; - u16 saved_addr; - unsigned long flags; - - spin_lock_irqsave(&lp->lock, flags); - saved_addr = lp->a.read_rap(ioaddr); - lp->stats.rx_missed_errors = lp->a.read_csr (ioaddr, 112); - lp->a.write_rap(ioaddr, saved_addr); - spin_unlock_irqrestore(&lp->lock, flags); - - return &lp->stats; -} - -/* taken from the sunlance driver, which it took from the depca driver */ -static void pcnet32_load_multicast (struct net_device *dev) -{ - struct pcnet32_private *lp = dev->priv; - volatile struct pcnet32_init_block *ib = &lp->init_block; - volatile u16 *mcast_table = (u16 *)&ib->filter; - struct dev_mc_list *dmi=dev->mc_list; - char *addrs; - int i, j, bit, byte; - u32 crc, poly = CRC_POLYNOMIAL_LE; - - /* set all multicast bits */ - if (dev->flags & IFF_ALLMULTI){ - ib->filter [0] = 0xffffffff; - ib->filter [1] = 0xffffffff; - return; - } - /* clear the multicast filter */ - ib->filter [0] = 0; - ib->filter [1] = 0; - - /* Add addresses */ - for (i = 0; i < dev->mc_count; i++){ - addrs = dmi->dmi_addr; - dmi = dmi->next; - - /* multicast address? */ - if (!(*addrs & 1)) - continue; - - crc = 0xffffffff; - for (byte = 0; byte < 6; byte++) - for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) { - int test; - - test = ((bit ^ crc) & 0x01); - crc >>= 1; - - if (test) { - crc = crc ^ poly; - } - } - - crc = crc >> 26; - mcast_table [crc >> 4] |= 1 << (crc & 0xf); - } - return; -} - - -/* - * Set or clear the multicast filter for this adaptor. - */ -static void pcnet32_set_multicast_list(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - struct pcnet32_private *lp = dev->priv; - - if (dev->flags&IFF_PROMISC) { - /* Log any net taps. */ - printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name); - lp->init_block.mode = le16_to_cpu(0x8000 | (lp->options & PORT_PORTSEL) << 7); - } else { - lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7); - pcnet32_load_multicast (dev); - } - - lp->a.write_csr (ioaddr, 0, 0x0004); /* Temporarily stop the lance. */ - - pcnet32_restart(dev, 0x0042); /* Resume normal operation */ -} - -#ifdef HAVE_PRIVATE_IOCTL -static int pcnet32_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - unsigned long ioaddr = dev->base_addr; - struct pcnet32_private *lp = dev->priv; - u16 *data = (u16 *)&rq->ifr_data; - int phyaddr = lp->a.read_bcr (ioaddr, 33); - - if (lp->mii) { - switch(cmd) { - case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ - data[0] = (phyaddr >> 5) & 0x1f; - /* Fall Through */ - case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ - lp->a.write_bcr (ioaddr, 33, ((data[0] & 0x1f) << 5) | (data[1] & 0x1f)); - data[3] = lp->a.read_bcr (ioaddr, 34); - lp->a.write_bcr (ioaddr, 33, phyaddr); - return 0; - case SIOCDEVPRIVATE+2: /* Write the specified MII register */ - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - lp->a.write_bcr (ioaddr, 33, ((data[0] & 0x1f) << 5) | (data[1] & 0x1f)); - lp->a.write_bcr (ioaddr, 34, data[2]); - lp->a.write_bcr (ioaddr, 33, phyaddr); - return 0; - default: - return -EOPNOTSUPP; - } - } - return -EOPNOTSUPP; -} -#endif /* HAVE_PRIVATE_IOCTL */ - -static struct pci_driver pcnet32_driver = { - name: "pcnet32", - probe: pcnet32_probe_pci, - remove: NULL, - id_table: pcnet32_pci_tbl, -}; - -MODULE_PARM(debug, "i"); -MODULE_PARM(max_interrupt_work, "i"); -MODULE_PARM(rx_copybreak, "i"); -MODULE_PARM(tx_start_pt, "i"); -MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); -MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); -MODULE_AUTHOR("Thomas Bogendoerfer"); -MODULE_DESCRIPTION("Driver for PCnet32 and PCnetPCI based ethercards"); -MODULE_LICENSE("GPL"); - -/* An additional parameter that may be passed in... */ -static int debug = -1; -static int tx_start_pt = -1; - -static int __init pcnet32_init_module(void) -{ - int cards_found = 0; - int err; - - if (debug > 0) - pcnet32_debug = debug; - if ((tx_start_pt >= 0) && (tx_start_pt <= 3)) - tx_start = tx_start_pt; - - pcnet32_dev = NULL; - /* find the PCI devices */ -#define USE_PCI_REGISTER_DRIVER -#ifdef USE_PCI_REGISTER_DRIVER - if ((err = pci_module_init(&pcnet32_driver)) < 0 ) - return err; -#else - { - struct pci_device_id *devid = pcnet32_pci_tbl; - for (devid = pcnet32_pci_tbl; devid != NULL && devid->vendor != 0; devid++) { - struct pci_dev *pdev = pci_find_subsys(devid->vendor, devid->device, devid->subvendor, devid->subdevice, NULL); - if (pdev != NULL) { - if (pcnet32_probe_pci(pdev, devid) >= 0) { - cards_found++; - } - } - } - } -#endif - return 0; - /* find any remaining VLbus devices */ - return pcnet32_probe_vlbus(cards_found); -} - -static void __exit pcnet32_cleanup_module(void) -{ - struct net_device *next_dev; - - /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ - while (pcnet32_dev) { - struct pcnet32_private *lp = pcnet32_dev->priv; - next_dev = lp->next; - unregister_netdev(pcnet32_dev); - release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE); - if (lp->pci_dev != NULL) - pci_unregister_driver(&pcnet32_driver); - pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); - kfree(pcnet32_dev); - pcnet32_dev = next_dev; - } -} - -module_init(pcnet32_init_module); -module_exit(pcnet32_cleanup_module); - -/* - * Local variables: - * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c pcnet32.c" - * c-indent-level: 4 - * tab-width: 8 - * End: - */ diff --git a/xen-2.4.16/drivers/net/tulip/.depend b/xen-2.4.16/drivers/net/tulip/.depend deleted file mode 100644 index d2cbd43c1b..0000000000 --- a/xen-2.4.16/drivers/net/tulip/.depend +++ /dev/null @@ -1,58 +0,0 @@ -21142.o: 21142.c \ - tulip.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/pci.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/delay.h -eeprom.o: eeprom.c \ - tulip.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/init.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/asm/unaligned.h -interrupt.o: interrupt.c \ - tulip.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/etherdevice.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/pci.h \ - $(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/net/hw/flowcontrol.h) -media.o: media.c \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/kernel.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/mii.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/init.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/delay.h \ - tulip.h -pnic2.o: pnic2.c \ - tulip.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/pci.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/delay.h -pnic.o: pnic.c \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/kernel.h \ - tulip.h -timer.o: timer.c \ - tulip.h -tulip_core.o: tulip_core.c \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/module.h \ - tulip.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/pci.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/init.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/etherdevice.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/delay.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/mii.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/ethtool.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/asm/unaligned.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/asm/uaccess.h \ - $(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/net/hw/flowcontrol.h) \ - $(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/tulip/mwi.h) \ - $(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/ddb5476.h) \ - $(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/ddb5477.h) \ - $(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/pm.h) -tulip.h: \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/kernel.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/types.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/spinlock.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/netdevice.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/timer.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/delay.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/asm/io.h \ - /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/asm/irq.h \ - $(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/tulip/mmio.h) \ - $(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/net/hw/flowcontrol.h) - @touch tulip.h -.PRECIOUS: tulip.h \ - diff --git a/xen-2.4.16/drivers/net/tulip/21142.c b/xen-2.4.16/drivers/net/tulip/21142.c deleted file mode 100644 index 3a88c44120..0000000000 --- a/xen-2.4.16/drivers/net/tulip/21142.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - drivers/net/tulip/21142.c - - Maintained by Jeff Garzik <jgarzik@mandrakesoft.com> - Copyright 2000,2001 The Linux Kernel Team - Written/copyright 1994-2001 by Donald Becker. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - Please refer to Documentation/DocBook/tulip.{pdf,ps,html} - for more information on this driver, or visit the project - Web page at http://sourceforge.net/projects/tulip/ - -*/ - -#include "tulip.h" -#include <linux/pci.h> -#include <linux/delay.h> - - -static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, }; -u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, }; -static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; - - -/* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list - of available transceivers. */ -void t21142_timer(unsigned long data) -{ - struct net_device *dev = (struct net_device *)data; - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - int csr12 = inl(ioaddr + CSR12); - int next_tick = 60*HZ; - int new_csr6 = 0; - - if (tulip_debug > 2) - printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n", - dev->name, csr12, medianame[dev->if_port]); - if (tulip_media_cap[dev->if_port] & MediaIsMII) { - tulip_check_duplex(dev); - next_tick = 60*HZ; - } else if (tp->nwayset) { - /* Don't screw up a negotiated session! */ - if (tulip_debug > 1) - printk(KERN_INFO"%s: Using NWay-set %s media, csr12 %8.8x.\n", - dev->name, medianame[dev->if_port], csr12); - } else if (tp->medialock) { - ; - } else if (dev->if_port == 3) { - if (csr12 & 2) { /* No 100mbps link beat, revert to 10mbps. */ - if (tulip_debug > 1) - printk(KERN_INFO"%s: No 21143 100baseTx link beat, %8.8x, " - "trying NWay.\n", dev->name, csr12); - t21142_start_nway(dev); - next_tick = 3*HZ; - } - } else if ((csr12 & 0x7000) != 0x5000) { - /* Negotiation failed. Search media types. */ - if (tulip_debug > 1) - printk(KERN_INFO"%s: 21143 negotiation failed, status %8.8x.\n", - dev->name, csr12); - if (!(csr12 & 4)) { /* 10mbps link beat good. */ - new_csr6 = 0x82420000; - dev->if_port = 0; - outl(0, ioaddr + CSR13); - outl(0x0003FFFF, ioaddr + CSR14); - outw(t21142_csr15[dev->if_port], ioaddr + CSR15); - outl(t21142_csr13[dev->if_port], ioaddr + CSR13); - } else { - /* Select 100mbps port to check for link beat. */ - new_csr6 = 0x83860000; - dev->if_port = 3; - outl(0, ioaddr + CSR13); - outl(0x0003FF7F, ioaddr + CSR14); - outw(8, ioaddr + CSR15); - outl(1, ioaddr + CSR13); - } - if (tulip_debug > 1) - printk(KERN_INFO"%s: Testing new 21143 media %s.\n", - dev->name, medianame[dev->if_port]); - if (new_csr6 != (tp->csr6 & ~0x00D5)) { - tp->csr6 &= 0x00D5; - tp->csr6 |= new_csr6; - outl(0x0301, ioaddr + CSR12); - tulip_restart_rxtx(tp); - } - next_tick = 3*HZ; - } - - /* mod_timer synchronizes us with potential add_timer calls - * from interrupts. - */ - mod_timer(&tp->timer, RUN_AT(next_tick)); -} - - -void t21142_start_nway(struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - int csr14 = ((tp->sym_advertise & 0x0780) << 9) | - ((tp->sym_advertise & 0x0020) << 1) | 0xffbf; - - dev->if_port = 0; - tp->nway = tp->mediasense = 1; - tp->nwayset = tp->lpar = 0; - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: Restarting 21143 autonegotiation, csr14=%8.8x.\n", - dev->name, csr14); - outl(0x0001, ioaddr + CSR13); - udelay(100); - outl(csr14, ioaddr + CSR14); - tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? FullDuplex : 0); - outl(tp->csr6, ioaddr + CSR6); - if (tp->mtable && tp->mtable->csr15dir) { - outl(tp->mtable->csr15dir, ioaddr + CSR15); - outl(tp->mtable->csr15val, ioaddr + CSR15); - } else - outw(0x0008, ioaddr + CSR15); - outl(0x1301, ioaddr + CSR12); /* Trigger NWAY. */ -} - - - -void t21142_lnk_change(struct net_device *dev, int csr5) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - int csr12 = inl(ioaddr + CSR12); - - if (tulip_debug > 1) - printk(KERN_INFO"%s: 21143 link status interrupt %8.8x, CSR5 %x, " - "%8.8x.\n", dev->name, csr12, csr5, inl(ioaddr + CSR14)); - - /* If NWay finished and we have a negotiated partner capability. */ - if (tp->nway && !tp->nwayset && (csr12 & 0x7000) == 0x5000) { - int setup_done = 0; - int negotiated = tp->sym_advertise & (csr12 >> 16); - tp->lpar = csr12 >> 16; - tp->nwayset = 1; - if (negotiated & 0x0100) dev->if_port = 5; - else if (negotiated & 0x0080) dev->if_port = 3; - else if (negotiated & 0x0040) dev->if_port = 4; - else if (negotiated & 0x0020) dev->if_port = 0; - else { - tp->nwayset = 0; - if ((csr12 & 2) == 0 && (tp->sym_advertise & 0x0180)) - dev->if_port = 3; - } - tp->full_duplex = (tulip_media_cap[dev->if_port] & MediaAlwaysFD) ? 1:0; - - if (tulip_debug > 1) { - if (tp->nwayset) - printk(KERN_INFO "%s: Switching to %s based on link " - "negotiation %4.4x & %4.4x = %4.4x.\n", - dev->name, medianame[dev->if_port], tp->sym_advertise, - tp->lpar, negotiated); - else - printk(KERN_INFO "%s: Autonegotiation failed, using %s," - " link beat status %4.4x.\n", - dev->name, medianame[dev->if_port], csr12); - } - - if (tp->mtable) { - int i; - for (i = 0; i < tp->mtable->leafcount; i++) - if (tp->mtable->mleaf[i].media == dev->if_port) { - tp->cur_index = i; - tulip_select_media(dev, 1); - setup_done = 1; - break; - } - } - if ( ! setup_done) { - tp->csr6 = (dev->if_port & 1 ? 0x838E0000 : 0x82420000) | (tp->csr6 & 0x20ff); - if (tp->full_duplex) - tp->csr6 |= 0x0200; - outl(1, ioaddr + CSR13); - } -#if 0 /* Restart shouldn't be needed. */ - outl(tp->csr6 | RxOn, ioaddr + CSR6); - if (tulip_debug > 2) - printk(KERN_DEBUG "%s: Restarting Tx and Rx, CSR5 is %8.8x.\n", - dev->name, inl(ioaddr + CSR5)); -#endif - tulip_start_rxtx(tp); - if (tulip_debug > 2) - printk(KERN_DEBUG "%s: Setting CSR6 %8.8x/%x CSR12 %8.8x.\n", - dev->name, tp->csr6, inl(ioaddr + CSR6), - inl(ioaddr + CSR12)); - } else if ((tp->nwayset && (csr5 & 0x08000000) - && (dev->if_port == 3 || dev->if_port == 5) - && (csr12 & 2) == 2) || - (tp->nway && (csr5 & (TPLnkFail)))) { - /* Link blew? Maybe restart NWay. */ - del_timer_sync(&tp->timer); - t21142_start_nway(dev); - tp->timer.expires = RUN_AT(3*HZ); - add_timer(&tp->timer); - } else if (dev->if_port == 3 || dev->if_port == 5) { - if (tulip_debug > 1) - printk(KERN_INFO"%s: 21143 %s link beat %s.\n", - dev->name, medianame[dev->if_port], - (csr12 & 2) ? "failed" : "good"); - if ((csr12 & 2) && ! tp->medialock) { - del_timer_sync(&tp->timer); - t21142_start_nway(dev); - tp->timer.expires = RUN_AT(3*HZ); - add_timer(&tp->timer); - } else if (dev->if_port == 5) - outl(inl(ioaddr + CSR14) & ~0x080, ioaddr + CSR14); - } else if (dev->if_port == 0 || dev->if_port == 4) { - if ((csr12 & 4) == 0) - printk(KERN_INFO"%s: 21143 10baseT link beat good.\n", - dev->name); - } else if (!(csr12 & 4)) { /* 10mbps link beat good. */ - if (tulip_debug) - printk(KERN_INFO"%s: 21143 10mbps sensed media.\n", - dev->name); - dev->if_port = 0; - } else if (tp->nwayset) { - if (tulip_debug) - printk(KERN_INFO"%s: 21143 using NWay-set %s, csr6 %8.8x.\n", - dev->name, medianame[dev->if_port], tp->csr6); - } else { /* 100mbps link beat good. */ - if (tulip_debug) - printk(KERN_INFO"%s: 21143 100baseTx sensed media.\n", - dev->name); - dev->if_port = 3; - tp->csr6 = 0x838E0000 | (tp->csr6 & 0x20ff); - outl(0x0003FF7F, ioaddr + CSR14); - outl(0x0301, ioaddr + CSR12); - tulip_restart_rxtx(tp); - } -} - - diff --git a/xen-2.4.16/drivers/net/tulip/ChangeLog b/xen-2.4.16/drivers/net/tulip/ChangeLog deleted file mode 100644 index a515efcfd3..0000000000 --- a/xen-2.4.16/drivers/net/tulip/ChangeLog +++ /dev/null @@ -1,520 +0,0 @@ -2001-11-13 David S. Miller <davem@redhat.com> - - * tulip_core.c (tulip_mwi_config): Kill unused label early_out. - -2001-11-06 Richard Mortimer <richm@oldelvet.netscapeonline.co.uk> - - * tulip_core.c: Correct set of values to mask out of csr0, - for DM9102A chips. Limit burst/alignment of DM9102A chips - on Sparcs. - -2001-11-06 Jun Sun <jsun@mvista.com> - - * tulip_core.c: Support finding MAC address on - two MIPS boards, DDB5476 and DDB5477. - -2001-11-06 Kevin B. Hendricks <khendricks@ivey.uwo.ca> - - * Makefile, tulip.h, tulip_core.c, pnic2.c, 21142.c: - Fixes for PNIC II support. - -2001-11-06 David S. Miller <davem@redhat.com> - - * tulip_core.c: Support reading MAC address from - Sparc OBP property local-mac-address. - -2001-07-17 Erik A. Hendriks <hendriks@lanl.gov> - - * 21142.c: Merge fix from tulip.c 0.92w which prevents the - overwriting of csr6 bits we want to preserve. - -2001-07-10 Jeff Golds <jgolds@resilience.com> - - * tulip_core.c: Fix two comments - -2001-07-06 Stephen Degler <sdegler@degler.net> - - * media.c: - The media selection process at the end of NWAY is busted - because for the case of MII/SYM it needs to be: - - csr13 <- 0 - csr14 <- 0 - csr6 <- the value calculated is okay. - - In the other media cases csr14 is computed by - t21142_csr14val[dev->if_port], which seems ok. The value of - zero as opposed to 3FFFFF comes straight from appendix D of the - 21143 data book, and it makes logical sense because you're - bypassing all the SIA interface when you usa MII or SYM (see - figure 1-1 in the data book if your're visually oriented) - -2001-07-03 Jeff Golds <jgolds@resilience.com> - - * tulip_core.c (tulip_clean_tx_ring): - Clear status for in-progress Tx's, and count - Tx errors for all packets being released. - -2001-06-16 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip.h, tulip_core.c: - Integrate MMIO support from devel branch, but default - it to off for stable kernel and driver series. - -2001-06-16 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c (tulip_init_one): - Free descriptor rings on error. - -2001-06-16 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c (tulip_mwi_config, tulip_init_one): - Large update to csr0 bus configuration code. This is not stable - yet, so it is only conditionally enabled, via CONFIG_TULIP_MWI. - -2001-06-16 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c: - Initialize timer in tulip_init_one and tulip_down, - not in tulip_up. - -2001-06-14 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c: - - Update tulip_suspend, tulip_resume for new PCI PM API. - - Surround suspend/resume code with CONFIG_PM. - -2001-06-12 Jeff Golds <jgolds@resilience.com> - - * tulip_core.c: - - Reset sw ring ptrs in tulip_up. Fixes PM resume case. - - Clean rx and tx rings on device down. - -2001-06-05 David Miller <davem@redhat.com> - - * tulip_core (set_rx_mode): Do not use set_bit - on an integer variable. Also fix endianness issue. - -2001-06-04 Jeff Garzik <jgarzik@mandrakesoft.com> - - * interrupt.c: - Simplify rx processing when CONFIG_NET_HW_FLOWCONTROL is - active, and in the process fix a bug where flow control - and low load caused rx not to be acknowledged properly. - -2001-06-01 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip.h: - - Remove tulip_outl_csr helper, redundant. - - Add tulip_start_rxtx inline helper. - - tulip_stop_rxtx helper: Add synchronization. Always use current - csr6 value, instead of tp->csr6 value or value passed as arg. - - tulip_restart_rxtx helper: Add synchronization. Always - use tp->csr6 for desired mode, not value passed as arg. - - New RxOn, TxOn, RxTx constants for csr6 modes. - - Remove now-redundant constants csr6_st, csr6_sr. - - * 21142.c, interrupt.c, media.c, pnic.c, tulip_core.c: - Update for above rxtx helper changes. - - * interrupt.c: - - whitespace cleanup around #ifdef CONFIG_NET_HW_FLOWCONTROL, - convert tabs to spaces. - - Move tp->stats.rx_missed_errors update outside the ifdef. - -2001-05-18 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c: Added ethtool support. - ETHTOOL_GDRVINFO ioctl only, for now. - -2001-05-14 Robert Olsson <Robert.Olsson@data.slu.se> - - * Restored HW_FLOWCONTROL from Linux 2.1 series tulip (ANK) - plus Jamal's NETIF_RX_* feedback control. - -2001-05-14 Robert Olsson <Robert.Olsson@data.slu.se> - - * Added support for 21143's Interrupt Mitigation. - Jamal original instigator. - -2001-05-14 Robert Olsson <Robert.Olsson@data.slu.se> - - * tulip_refill_rx prototype added to tulip.h - -2001-05-13 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c: Remove HAS_PCI_MWI flag from Comet, untested. - -2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c, tulip.h: Remove Conexant PCI id, no chip - docs are available to fix problems with support. - -2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c (tulip_init_one): Do not call - unregister_netdev in error cleanup. Remnant of old - usage of init_etherdev. - -2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com> - - * media.c (tulip_find_mii): Simple write the updated BMCR - twice, as it seems the best thing to do for both broken and - sane chips. - If the mii_advert value, as read from MII_ADVERTISE, is zero, - then generate a value we should advertise from the capability - bits in BMSR. - Fill in tp->advertising for all cases. - Just to be safe, clear all unwanted bits. - -2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c (private_ioctl): Fill in tp->advertising - when advertising value is changed by the user. - -2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c: Mark Comet chips as needed the updated MWI - csr0 configuration. - -2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com> - - * media.c, tulip_core.c: Move MII scan into - from inlined inside tulip_init_one to new function - tulip_find_mii in media.c. - -2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com> - - * media.c (tulip_check_duplex): - Only restart Rx/Tx engines if they are active - (and csr6 changes) - -2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c (tulip_mwi_config): - Clamp values read from PCI cache line size register to - values acceptable to tulip chip. Done for safety and - -almost- certainly unneeded. - -2001-05-11 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c (tulip_init_one): - Instead of unconditionally enabling autonegotiation, disable - autonegotiation if not using the default port. Further, - flip the nway bit immediately, and then update the - speed/duplex in a separate MII transaction. We do this - because some boards require that nway be disabled separately, - before media selection is forced. - - TODO: Investigate if we can simply write the same value - to BMCR twice, to avoid setting unnecessarily changing - phy settings. - -2001-05-11 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip.h, tulip_core.c: If HAS_PCI_MWI is set for a - given chip, adjust the csr0 values not according to - provided values but according to system cache line size. - Currently cache alignment is matched as closely to cache - line size as possible. Currently programmable burst limit - is set (ie. never unlimited), and always equal to cache - alignment and system cache size. Currently MWI bit is set - only if the MWI bit is present in the PCI command register. - -2001-05-11 Jeff Garzik <jgarzik@mandrakesoft.com> - - * media.c (tulip_select_media): - For media types 1 and 3, only use the provided eeprom - advertising value if it is non-zero. - (tulip_check_duplex): - Do not exit ASAP if full_duplex_lock is set. This - ensures that the csr6 value is written if an update - is needed. - -2001-05-10 Jeff Garzik <jgarzik@mandrakesoft.com> - - Merge PNIC-II-specific stuff from Becker's tulip.c: - - * tulip.h, 21142.c (pnic2_lnk_change): new function - * tulip_core.c (tulip_init_one): use it - - * tulip_core.c (tulip_tx_timeout): Add specific - debugging for PNIC2. - -2001-05-10 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c (tulip_init_one): Print out - tulip%d instead of PCI device number, for - consistency. - -2001-05-10 Jeff Garzik <jgarzik@mandrakesoft.com> - - * Merge changes from Becker's tulip.c: - Fix bugs in ioctl. - Fix several bugs by distinguishing between MII - and SYM advertising values. - Set CSR14 autonegotiation bit for media types 2 and 4, - where the SIA CSR setup values are not provided. - -2001-05-10 Jeff Garzik <jgarzik@mandrakesoft.com> - - * media.c (tulip_select_media): Only update MII - advertising value if startup arg < 2. - - * tulip.h: Do not enable CSR13/14/15 autoconfiguration - for 21041. - - * tulip_core.c: - 21041: add specific code for reset, and do not set CAC bit - When resetting media, for media table type 11 media, pass - value 2 as 'startup' arg to select_media, to avoid updating - MII advertising value. - -2001-05-10 Jeff Garzik <jgarzik@mandrakesoft.com> - - * pnic.c (pnic_check_duplex): remove - pnic.c (pnic_lnk_change, pnic_timer): use - tulip_check_duplex not pnic_check_duplex. - - * media.c (tulip_check_duplex): - Clean up to use symbolic names instead of numeric constants. - Set TxThreshold mode as necessary as well as clearing it. - Update csr6 if csr6 changes, not simply if duplex changes. - - (found by Manfred Spraul) - -2001-05-10 Jeff Garzik <jgarzik@mandrakesoft.com> - - * 21142.c, eeprom.c, tulip.h, tulip_core.c: - Remove DPRINTK as another, better method of - debug message printing is available. - -2001-05-09 Jeff Garzik <jgarzik@mandrakesoft.com> - - * 21142.c (t21142_lnk_change): Pass arg startup==1 - to tulip_select_media, in order to force csr13 to be - zeroed out prior to going to full duplex mode. Fixes - autonegotiation on a quad-port Znyx card. - (from Stephen Dengler) - -2001-05-09 Russell King <rmk@arm.linux.org.uk> - - * interrupt.c: Better PCI bus error reporting. - -2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c: Now that dev->name is only available late - in the probe, insert a hack to replace a not-evaluated - "eth%d" string with an evaluated "tulip%d" string. - Also, remove obvious comment and an indentation cleanup. - -2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c: If we are a module, always print out the - version string. If we are built into the kernel, only print - the version string if at least one tulip is detected. - -2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com> - - Merged from Becker's tulip.c 0.92t: - - * tulip_core.c: Add support for Conexant LANfinity. - -2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c: Only suspend/resume if the interface - is up and running. Use alloc_etherdev and pci_request_regions. - Spelling fix. - -2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c: Remove code that existed when one or more of - the following defines existed. These defines were never used - by normal users in practice: TULIP_FULL_DUPLEX, - TULIP_DEFAULT_MEDIA, and TULIP_NO_MEDIA_SWITCH. - - * tulip.h, eeprom.c: Move EE_* constants from tulip.h to eeprom.c. - * tulip.h, media.c: Move MDIO_* constants from tulip.h to media.c. - - * media.c: Add barrier() to mdio_read/write's PNIC status check - loops. - -2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com> - - Merged from Becker's tulip.c 0.92t: - - * tulip.h: Add MEDIA_MASK constant for bounding medianame[] - array lookups. - * eeprom.c, media.c, timer.c, tulip_core.c: Use it. - - * media.c, tulip_core.c: mdio_{read,write} cleanup. Since this - is called [pretty much] directly from ioctl, we mask - read/write arguments to limit the values passed. - Added mii_lock. Added comet_miireg2offset and better - Comet-specific mdio_read/write code. Pay closer attention - to the bits we set in ioctl. Remove spinlocks from ioctl, - they are in mdio_read/write now. Use mask to limit - phy number in tulip_init_one's MII scan. - -2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com> - - Merged from Becker's tulip.c 0.92t: - - * 21142.c, tulip_core.c: PNIC2 MAC address and NWay fixes. - * tulip.h: Add FullDuplex constant, used in above change. - -2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com> - - * timer.c: Do not call netif_carrier_{on,off}, it is not used in - the main tree. Leave code in, disabled, as markers for future - carrier notification. - -2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com> - - Merged from Becker's tulip.c 0.92t, except for the tulip.h - whitespace cleanup: - - * interrupt.c: If Rx stops, make sure to update the - multicast filter before restarting. - * tulip.h: Add COMET_MAC_ADDR feature flag, clean up flags. - Add Accept* Rx mode bit constants. - Add mc_filter[] to driver private struct. - * tulip_core.c: Add new Comet PCI id 0x1113:0x9511. - Add COMET_MAC_ADDR feature flag to comet entry in board info array. - Prefer to test COMET_MAC_ADDR flag to testing chip_id for COMET, - when dealing with the Comet's MAC address. - Enable Tx underrun recovery for Comet chips. - Use new Accept* constants in set_rx_mode. - Prefer COMET_MAC_ADDR flag test to chip_id test in set_rx_mode. - Store built mc_filter for later use in intr handler by Comets. - -2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c: Use tp->cur_tx when building the - setup frame, instead of assuming that the setup - frame is always built in slot zero. This case is - hit during PM resume. - -2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com> - - * *.c: Update file headers (copyright, urls, etc.) - * Makefile: re-order to that chip-specific modules on own line - * eeprom.c: BSS/zero-init cleanup (Andrey Panin) - * tulip_core.c: merge medianame[] update from tulip.c. - Additional arch-specific rx_copybreak, csr0 values. (various) - -2001-02-20 Jeff Garzik <jgarzik@mandrakesoft.com> - - * media.c (tulip_select_media): No need to initialize - new_csr6, all cases initialize it properly. - -2001-02-18 Manfred Spraul <manfred@colorfullife.com> - - * interrupt.c (tulip_refill_rx): Make public. - If PNIC chip stops due to lack of Rx buffers, restart it. - (tulip_interrupt): PNIC doesn't have a h/w timer, emulate - with software timers. - * pnic.c (pnic_check_duplex): New function, PNIC-specific - version of tulip_check_duplex. - (pnic_lnk_change): Call pnic_check_duplex. If we use an - external MII, then we mustn't use the internal negotiation. - (pnic_timer): Support Rx refilling on work overflow in - interrupt handler, as PNIC doesn't support a h/w timer. - * tulip_core.c (tulip_tbl[]): Modify default csr6 - -2001-02-11 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c (tulip_init_one): Call pci_enable_device - to ensure wakeup/resource assignment before checking those - values. - (tulip_init_one): Replace PCI ids with constants from pci_id.h. - (tulip_suspend, tulip_resume, tulip_remove_one): Call - pci_power_on/off (commented out for now). - -2001-02-10 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip.h: Add CFDD_xxx bits for Tulip power management - * tulip_core.c (tulip_set_power_state): New function, - manipulating Tulip chip power state where supported. - (tulip_up, tulip_down, tulip_init_one): Use it. - -2001-02-10 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c (tulip_tx_timeout): Call netif_wake_queue - to ensure the next Tx is always sent to us. - -2001-01-27 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c (tulip_remove_one): Fix mem leak by freeing - tp->media_tbl. Add check for !dev, reformat code appropriately. - -2001-01-27 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_tbl[]: Comment all entries to make order and chip_id - relationship more clear. - * tulip_pci_tbl[]: Add new Accton PCI id (COMET chipset). - -2001-01-16 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c: static vars no longer explicitly - initialized to zero. - * eeprom.c (tulip_read_eeprom): Make sure to delay between - EE_ENB and EE_ENB|EE_SHIFT_CLK. Merged from becker tulip.c. - -2001-01-05 Peter De Schrijver <p2@mind.be> - - * eeprom.c (tulip_parse_eeprom): Interpret a bit more of 21142 - extended format type 3 info blocks in a tulip SROM. - -2001-01-03 Matti Aarnio <matti.aarnio@zmailer.org> - - * media.c (tulip_select_media): Support media types 5 and 6 - -2001-??-?? ?? - - * tulip_core.c: Add comment about LanMedia needing - a different driver. - Enable workarounds for early PCI chipsets. - Add IA64 csr0 support, update HPPA csr0 support. - -2000-12-17 Alan Cox <alan@redhat.com> - - * eeprom.c, timer.c, tulip.h, tulip_core.c: Merge support - for the Davicom's quirks into the main tulip. - Patch by Tobias Ringstrom - -2000-11-08 Jim Studt <jim@federated.com> - - * eeprom.c (tulip_parse_eeprom): Check array bounds for - medianame[] and block_name[] arrays to avoid oops due - to bad values returned from hardware. - -2000-11-02 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c (set_rx_mode): This is synchronized via - dev->xmit_lock, so only the queueing of the setup frame needs to - be locked, against tulip_interrupt. - -2000-11-02 Alexey Kuznetov <kuznet@ms2.inr.ac.ru> - - * timer.c (tulip_timer): Call netif_carrier_{on,off} to report - link state to the rest of the kernel, and userspace. - * interrupt.c (tulip_interrupt): Remove tx_full. - * tulip.h: Likewise. - * tulip_core.c (tulip_init_ring, tulip_start_xmit, set_rx_mode): - Likewise. - -2000-10-18 Jeff Garzik <jgarzik@mandrakesoft.com> - - * tulip_core.c: (tulip_init_one) Print out ethernet interface - on error. Print out a message when pci_enable_device fails. - Handle DMA alloc failure. - -2000-10-18 Jeff Garzik <jgarzik@mandrakesoft.com> - - * Makefile: New file. - * tulip_core.c (tulip_init_one): Correct error messages - on PIO/MMIO region reserve failure. - (tulip_init_one) Add new check to ensure that PIO region is - sufficient for our needs. - diff --git a/xen-2.4.16/drivers/net/tulip/Makefile b/xen-2.4.16/drivers/net/tulip/Makefile deleted file mode 100644 index a96b5b9835..0000000000 --- a/xen-2.4.16/drivers/net/tulip/Makefile +++ /dev/null @@ -1,8 +0,0 @@ - -include $(BASEDIR)/Rules.mk - -default: $(OBJS) - $(LD) -r -o tulip.o $(OBJS) - -clean: - rm -f *.o *~ core diff --git a/xen-2.4.16/drivers/net/tulip/eeprom.c b/xen-2.4.16/drivers/net/tulip/eeprom.c deleted file mode 100644 index beb1430cc4..0000000000 --- a/xen-2.4.16/drivers/net/tulip/eeprom.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - drivers/net/tulip/eeprom.c - - Maintained by Jeff Garzik <jgarzik@mandrakesoft.com> - Copyright 2000,2001 The Linux Kernel Team - Written/copyright 1994-2001 by Donald Becker. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - Please refer to Documentation/DocBook/tulip.{pdf,ps,html} - for more information on this driver, or visit the project - Web page at http://sourceforge.net/projects/tulip/ - -*/ - -#include "tulip.h" -#include <linux/init.h> -#include <asm/unaligned.h> - - - -/* Serial EEPROM section. */ -/* The main routine to parse the very complicated SROM structure. - Search www.digital.com for "21X4 SROM" to get details. - This code is very complex, and will require changes to support - additional cards, so I'll be verbose about what is going on. - */ - -/* Known cards that have old-style EEPROMs. */ -static struct eeprom_fixup eeprom_fixups[] __devinitdata = { - {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c, - 0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }}, - {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f, - 0x0000, 0x009E, /* 10baseT */ - 0x0004, 0x009E, /* 10baseT-FD */ - 0x0903, 0x006D, /* 100baseTx */ - 0x0905, 0x006D, /* 100baseTx-FD */ }}, - {"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f, - 0x0107, 0x8021, /* 100baseFx */ - 0x0108, 0x8021, /* 100baseFx-FD */ - 0x0100, 0x009E, /* 10baseT */ - 0x0104, 0x009E, /* 10baseT-FD */ - 0x0103, 0x006D, /* 100baseTx */ - 0x0105, 0x006D, /* 100baseTx-FD */ }}, - {"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513, - 0x1001, 0x009E, /* 10base2, CSR12 0x10*/ - 0x0000, 0x009E, /* 10baseT */ - 0x0004, 0x009E, /* 10baseT-FD */ - 0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */ - 0x0305, 0x006D, /* 100baseTx-FD CSR12 0x03 */}}, - {"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F, - 0x1B01, 0x0000, /* 10base2, CSR12 0x1B */ - 0x0B00, 0x009E, /* 10baseT, CSR12 0x0B */ - 0x0B04, 0x009E, /* 10baseT-FD,CSR12 0x0B */ - 0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */ - 0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */ - }}, - {"NetWinder", 0x00, 0x10, 0x57, - /* Default media = MII - * MII block, reset sequence (3) = 0x0821 0x0000 0x0001, capabilities 0x01e1 - */ - { 0x1e00, 0x0000, 0x000b, 0x8f01, 0x0103, 0x0300, 0x0821, 0x000, 0x0001, 0x0000, 0x01e1 } - }, - {0, 0, 0, 0, {}}}; - - -static const char *block_name[] __devinitdata = { - "21140 non-MII", - "21140 MII PHY", - "21142 Serial PHY", - "21142 MII PHY", - "21143 SYM PHY", - "21143 reset method" -}; - - -void __devinit tulip_parse_eeprom(struct net_device *dev) -{ - /* The last media info list parsed, for multiport boards. */ - static struct mediatable *last_mediatable; - static unsigned char *last_ee_data; - static int controller_index; - struct tulip_private *tp = (struct tulip_private *)dev->priv; - unsigned char *ee_data = tp->eeprom; - int i; - - tp->mtable = 0; - /* Detect an old-style (SA only) EEPROM layout: - memcmp(eedata, eedata+16, 8). */ - for (i = 0; i < 8; i ++) - if (ee_data[i] != ee_data[16+i]) - break; - if (i >= 8) { - if (ee_data[0] == 0xff) { - if (last_mediatable) { - controller_index++; - printk(KERN_INFO "%s: Controller %d of multiport board.\n", - dev->name, controller_index); - tp->mtable = last_mediatable; - ee_data = last_ee_data; - goto subsequent_board; - } else - printk(KERN_INFO "%s: Missing EEPROM, this interface may " - "not work correctly!\n", - dev->name); - return; - } - /* Do a fix-up based on the vendor half of the station address prefix. */ - for (i = 0; eeprom_fixups[i].name; i++) { - if (dev->dev_addr[0] == eeprom_fixups[i].addr0 - && dev->dev_addr[1] == eeprom_fixups[i].addr1 - && dev->dev_addr[2] == eeprom_fixups[i].addr2) { - if (dev->dev_addr[2] == 0xE8 && ee_data[0x1a] == 0x55) - i++; /* An Accton EN1207, not an outlaw Maxtech. */ - memcpy(ee_data + 26, eeprom_fixups[i].newtable, - sizeof(eeprom_fixups[i].newtable)); - printk(KERN_INFO "%s: Old format EEPROM on '%s' board. Using" - " substitute media control info.\n", - dev->name, eeprom_fixups[i].name); - break; - } - } - if (eeprom_fixups[i].name == NULL) { /* No fixup found. */ - printk(KERN_INFO "%s: Old style EEPROM with no media selection " - "information.\n", - dev->name); - return; - } - } - - controller_index = 0; - if (ee_data[19] > 1) { /* Multiport board. */ - last_ee_data = ee_data; - } -subsequent_board: - - if (ee_data[27] == 0) { /* No valid media table. */ - } else if (tp->chip_id == DC21041) { - unsigned char *p = (void *)ee_data + ee_data[27 + controller_index*3]; - int media = get_u16(p); - int count = p[2]; - p += 3; - - printk(KERN_INFO "%s: 21041 Media table, default media %4.4x (%s).\n", - dev->name, media, - media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]); - for (i = 0; i < count; i++) { - unsigned char media_block = *p++; - int media_code = media_block & MEDIA_MASK; - if (media_block & 0x40) - p += 6; - printk(KERN_INFO "%s: 21041 media #%d, %s.\n", - dev->name, media_code, medianame[media_code]); - } - } else { - unsigned char *p = (void *)ee_data + ee_data[27]; - unsigned char csr12dir = 0; - int count, new_advertise = 0; - struct mediatable *mtable; - u16 media = get_u16(p); - - p += 2; - if (tp->flags & CSR12_IN_SROM) - csr12dir = *p++; - count = *p++; - - /* there is no phy information, don't even try to build mtable */ - if (count == 0) { - if (tulip_debug > 0) - printk(KERN_WARNING "%s: no phy info, aborting mtable build\n", dev->name); - return; - } - - mtable = (struct mediatable *) - kmalloc(sizeof(struct mediatable) + count*sizeof(struct medialeaf), - GFP_KERNEL); - if (mtable == NULL) - return; /* Horrible, impossible failure. */ - last_mediatable = tp->mtable = mtable; - mtable->defaultmedia = media; - mtable->leafcount = count; - mtable->csr12dir = csr12dir; - mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0; - mtable->csr15dir = mtable->csr15val = 0; - - printk(KERN_INFO "%s: EEPROM default media type %s.\n", dev->name, - media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]); - for (i = 0; i < count; i++) { - struct medialeaf *leaf = &mtable->mleaf[i]; - - if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */ - leaf->type = 0; - leaf->media = p[0] & 0x3f; - leaf->leafdata = p; - if ((p[2] & 0x61) == 0x01) /* Bogus, but Znyx boards do it. */ - mtable->has_mii = 1; - p += 4; - } else { - leaf->type = p[1]; - if (p[1] == 0x05) { - mtable->has_reset = i; - leaf->media = p[2] & 0x0f; - } else if (tp->chip_id == DM910X && p[1] == 0x80) { - /* Hack to ignore Davicom delay period block */ - mtable->leafcount--; - count--; - i--; - leaf->leafdata = p + 2; - p += (p[0] & 0x3f) + 1; - continue; - } else if (p[1] & 1) { - int gpr_len, reset_len; - - mtable->has_mii = 1; - leaf->media = 11; - gpr_len=p[3]*2; - reset_len=p[4+gpr_len]*2; - new_advertise |= get_u16(&p[7+gpr_len+reset_len]); - } else { - mtable->has_nonmii = 1; - leaf->media = p[2] & MEDIA_MASK; - /* Davicom's media number for 100BaseTX is strange */ - if (tp->chip_id == DM910X && leaf->media == 1) - leaf->media = 3; - switch (leaf->media) { - case 0: new_advertise |= 0x0020; break; - case 4: new_advertise |= 0x0040; break; - case 3: new_advertise |= 0x0080; break; - case 5: new_advertise |= 0x0100; break; - case 6: new_advertise |= 0x0200; break; - } - if (p[1] == 2 && leaf->media == 0) { - if (p[2] & 0x40) { - u32 base15 = get_unaligned((u16*)&p[7]); - mtable->csr15dir = - (get_unaligned((u16*)&p[9])<<16) + base15; - mtable->csr15val = - (get_unaligned((u16*)&p[11])<<16) + base15; - } else { - mtable->csr15dir = get_unaligned((u16*)&p[3])<<16; - mtable->csr15val = get_unaligned((u16*)&p[5])<<16; - } - } - } - leaf->leafdata = p + 2; - p += (p[0] & 0x3f) + 1; - } - if (tulip_debug > 1 && leaf->media == 11) { - unsigned char *bp = leaf->leafdata; - printk(KERN_INFO "%s: MII interface PHY %d, setup/reset " - "sequences %d/%d long, capabilities %2.2x %2.2x.\n", - dev->name, bp[0], bp[1], bp[2 + bp[1]*2], - bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]); - } - printk(KERN_INFO "%s: Index #%d - Media %s (#%d) described " - "by a %s (%d) block.\n", - dev->name, i, medianame[leaf->media & 15], leaf->media, - leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>", - leaf->type); - } - if (new_advertise) - tp->sym_advertise = new_advertise; - } -} -/* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/ - -/* EEPROM_Ctrl bits. */ -#define EE_SHIFT_CLK 0x02 /* EEPROM shift clock. */ -#define EE_CS 0x01 /* EEPROM chip select. */ -#define EE_DATA_WRITE 0x04 /* Data from the Tulip to EEPROM. */ -#define EE_WRITE_0 0x01 -#define EE_WRITE_1 0x05 -#define EE_DATA_READ 0x08 /* Data from the EEPROM chip. */ -#define EE_ENB (0x4800 | EE_CS) - -/* Delay between EEPROM clock transitions. - Even at 33Mhz current PCI implementations don't overrun the EEPROM clock. - We add a bus turn-around to insure that this remains true. */ -#define eeprom_delay() inl(ee_addr) - -/* The EEPROM commands include the alway-set leading bit. */ -#define EE_READ_CMD (6) - -/* Note: this routine returns extra data bits for size detection. */ -int __devinit tulip_read_eeprom(long ioaddr, int location, int addr_len) -{ - int i; - unsigned retval = 0; - long ee_addr = ioaddr + CSR9; - int read_cmd = location | (EE_READ_CMD << addr_len); - - outl(EE_ENB & ~EE_CS, ee_addr); - outl(EE_ENB, ee_addr); - - /* Shift the read command bits out. */ - for (i = 4 + addr_len; i >= 0; i--) { - short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - outl(EE_ENB | dataval, ee_addr); - eeprom_delay(); - outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); - eeprom_delay(); - retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0); - } - outl(EE_ENB, ee_addr); - eeprom_delay(); - - for (i = 16; i > 0; i--) { - outl(EE_ENB | EE_SHIFT_CLK, ee_addr); - eeprom_delay(); - retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0); - outl(EE_ENB, ee_addr); - eeprom_delay(); - } - - /* Terminate the EEPROM access. */ - outl(EE_ENB & ~EE_CS, ee_addr); - return retval; -} - diff --git a/xen-2.4.16/drivers/net/tulip/interrupt.c b/xen-2.4.16/drivers/net/tulip/interrupt.c deleted file mode 100644 index 2cf54c6120..0000000000 --- a/xen-2.4.16/drivers/net/tulip/interrupt.c +++ /dev/null @@ -1,560 +0,0 @@ -/* - drivers/net/tulip/interrupt.c - - Maintained by Jeff Garzik <jgarzik@mandrakesoft.com> - Copyright 2000,2001 The Linux Kernel Team - Written/copyright 1994-2001 by Donald Becker. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - Please refer to Documentation/DocBook/tulip.{pdf,ps,html} - for more information on this driver, or visit the project - Web page at http://sourceforge.net/projects/tulip/ - -*/ - -#include "tulip.h" -#include <linux/config.h> -#include <linux/etherdevice.h> -#include <linux/pci.h> - - -int tulip_rx_copybreak; -unsigned int tulip_max_interrupt_work; - -#ifdef CONFIG_NET_HW_FLOWCONTROL - -#define MIT_SIZE 15 -unsigned int mit_table[MIT_SIZE+1] = -{ - /* CRS11 21143 hardware Mitigation Control Interrupt - We use only RX mitigation we other techniques for - TX intr. mitigation. - - 31 Cycle Size (timer control) - 30:27 TX timer in 16 * Cycle size - 26:24 TX No pkts before Int. - 23:20 RX timer in Cycle size - 19:17 RX No pkts before Int. - 16 Continues Mode (CM) - */ - - 0x0, /* IM disabled */ - 0x80150000, /* RX time = 1, RX pkts = 2, CM = 1 */ - 0x80150000, - 0x80270000, - 0x80370000, - 0x80490000, - 0x80590000, - 0x80690000, - 0x807B0000, - 0x808B0000, - 0x809D0000, - 0x80AD0000, - 0x80BD0000, - 0x80CF0000, - 0x80DF0000, -// 0x80FF0000 /* RX time = 16, RX pkts = 7, CM = 1 */ - 0x80F10000 /* RX time = 16, RX pkts = 0, CM = 1 */ -}; -#endif - - -int tulip_refill_rx(struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - int entry; - int refilled = 0; - - /* Refill the Rx ring buffers. */ - for (; tp->cur_rx - tp->dirty_rx > 0; tp->dirty_rx++) { - entry = tp->dirty_rx % RX_RING_SIZE; - if (tp->rx_buffers[entry].skb == NULL) { - struct sk_buff *skb; - dma_addr_t mapping; - - skb = tp->rx_buffers[entry].skb = dev_alloc_skb(PKT_BUF_SZ); - if (skb == NULL) - break; - - mapping = pci_map_single(tp->pdev, skb->tail, PKT_BUF_SZ, - PCI_DMA_FROMDEVICE); - tp->rx_buffers[entry].mapping = mapping; - - skb->dev = dev; /* Mark as being used by this device. */ - tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping); - refilled++; - } - tp->rx_ring[entry].status = cpu_to_le32(DescOwned); - } - if(tp->chip_id == LC82C168) { - if(((inl(dev->base_addr + CSR5)>>17)&0x07) == 4) { - /* Rx stopped due to out of buffers, - * restart it - */ - outl(0x01, dev->base_addr + CSR2); - } - } - return refilled; -} - - -static int tulip_rx(struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - int entry = tp->cur_rx % RX_RING_SIZE; - int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx; - int received = 0; - -#ifdef CONFIG_NET_HW_FLOWCONTROL - int drop = 0, mit_sel = 0; - -/* that one buffer is needed for mit activation; or might be a - bug in the ring buffer code; check later -- JHS*/ - - if (rx_work_limit >=RX_RING_SIZE) rx_work_limit--; -#endif - - if (tulip_debug > 4) - printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry, - tp->rx_ring[entry].status); - /* If we own the next entry, it is a new packet. Send it up. */ - while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) { - s32 status = le32_to_cpu(tp->rx_ring[entry].status); - - if (tulip_debug > 5) - printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n", - dev->name, entry, status); - if (--rx_work_limit < 0) - break; - if ((status & 0x38008300) != 0x0300) { - if ((status & 0x38000300) != 0x0300) { - /* Ingore earlier buffers. */ - if ((status & 0xffff) != 0x7fff) { - if (tulip_debug > 1) - printk(KERN_WARNING "%s: Oversized Ethernet frame " - "spanned multiple buffers, status %8.8x!\n", - dev->name, status); - tp->stats.rx_length_errors++; - } - } else if (status & RxDescFatalErr) { - /* There was a fatal error. */ - if (tulip_debug > 2) - printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n", - dev->name, status); - tp->stats.rx_errors++; /* end of a packet.*/ - if (status & 0x0890) tp->stats.rx_length_errors++; - if (status & 0x0004) tp->stats.rx_frame_errors++; - if (status & 0x0002) tp->stats.rx_crc_errors++; - if (status & 0x0001) tp->stats.rx_fifo_errors++; - } - } else { - /* Omit the four octet CRC from the length. */ - short pkt_len = ((status >> 16) & 0x7ff) - 4; - struct sk_buff *skb; - -#ifndef final_version - if (pkt_len > 1518) { - printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n", - dev->name, pkt_len, pkt_len); - pkt_len = 1518; - tp->stats.rx_length_errors++; - } -#endif - -#ifdef CONFIG_NET_HW_FLOWCONTROL - drop = atomic_read(&netdev_dropping); - if (drop) - goto throttle; -#endif - /* Check if the packet is long enough to accept without copying - to a minimally-sized skbuff. */ - if (pkt_len < tulip_rx_copybreak - && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { - //if (0) { - skb->dev = dev; - skb_reserve(skb, 2); /* 16 byte align the IP header */ - pci_dma_sync_single(tp->pdev, - tp->rx_buffers[entry].mapping, - pkt_len, PCI_DMA_FROMDEVICE); -#if ! defined(__alpha__) - eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail, - pkt_len, 0); - skb_put(skb, pkt_len); -#else - memcpy(skb_put(skb, pkt_len), - tp->rx_buffers[entry].skb->tail, - pkt_len); -#endif - } else { /* Pass up the skb already on the Rx ring. */ - char *temp = skb_put(skb = tp->rx_buffers[entry].skb, - pkt_len); - -#ifndef final_version - if (tp->rx_buffers[entry].mapping != - le32_to_cpu(tp->rx_ring[entry].buffer1)) { - printk(KERN_ERR "%s: Internal fault: The skbuff addresses " - "do not match in tulip_rx: %08x vs. %08x %p / %p.\n", - dev->name, - le32_to_cpu(tp->rx_ring[entry].buffer1), - tp->rx_buffers[entry].mapping, - skb->head, temp); - } -#endif - - pci_unmap_single(tp->pdev, tp->rx_buffers[entry].mapping, - PKT_BUF_SZ, PCI_DMA_FROMDEVICE); - - tp->rx_buffers[entry].skb = NULL; - tp->rx_buffers[entry].mapping = 0; - } - skb->protocol = eth_type_trans(skb, dev); -#ifdef CONFIG_NET_HW_FLOWCONTROL - mit_sel = -#endif - netif_rx(skb); - -#ifdef CONFIG_NET_HW_FLOWCONTROL - switch (mit_sel) { - case NET_RX_SUCCESS: - case NET_RX_CN_LOW: - case NET_RX_CN_MOD: - break; - - case NET_RX_CN_HIGH: - rx_work_limit -= NET_RX_CN_HIGH; /* additional*/ - break; - case NET_RX_DROP: - rx_work_limit = -1; - break; - default: - printk("unknown feedback return code %d\n", mit_sel); - break; - } - - drop = atomic_read(&netdev_dropping); - if (drop) { -throttle: - rx_work_limit = -1; - mit_sel = NET_RX_DROP; - - if (tp->fc_bit) { - long ioaddr = dev->base_addr; - - /* disable Rx & RxNoBuf ints. */ - outl(tulip_tbl[tp->chip_id].valid_intrs&RX_A_NBF_STOP, ioaddr + CSR7); - set_bit(tp->fc_bit, &netdev_fc_xoff); - } - } -#endif - dev->last_rx = jiffies; - tp->stats.rx_packets++; - tp->stats.rx_bytes += pkt_len; - } - received++; - entry = (++tp->cur_rx) % RX_RING_SIZE; - } -#ifdef CONFIG_NET_HW_FLOWCONTROL - - /* We use this simplistic scheme for IM. It's proven by - real life installations. We can have IM enabled - continuesly but this would cause unnecessary latency. - Unfortunely we can't use all the NET_RX_* feedback here. - This would turn on IM for devices that is not contributing - to backlog congestion with unnecessary latency. - - We monitor the the device RX-ring and have: - - HW Interrupt Mitigation either ON or OFF. - - ON: More then 1 pkt received (per intr.) OR we are dropping - OFF: Only 1 pkt received - - Note. We only use min and max (0, 15) settings from mit_table */ - - - if( tp->flags & HAS_INTR_MITIGATION) { - if((received > 1 || mit_sel == NET_RX_DROP) - && tp->mit_sel != 15 ) { - tp->mit_sel = 15; - tp->mit_change = 1; /* Force IM change */ - } - if((received <= 1 && mit_sel != NET_RX_DROP) && tp->mit_sel != 0 ) { - tp->mit_sel = 0; - tp->mit_change = 1; /* Force IM change */ - } - } - - return RX_RING_SIZE+1; /* maxrx+1 */ -#else - return received; -#endif -} - - -/* The interrupt handler does all of the Rx thread work and cleans up - after the Tx thread. */ -void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *)dev_instance; - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - int csr5; - int entry; - int missed; - int rx = 0; - int tx = 0; - int oi = 0; - int maxrx = RX_RING_SIZE; - int maxtx = TX_RING_SIZE; - int maxoi = TX_RING_SIZE; - unsigned int work_count = tulip_max_interrupt_work; - - /* Let's see whether the interrupt really is for us */ - csr5 = inl(ioaddr + CSR5); - - if ((csr5 & (NormalIntr|AbnormalIntr)) == 0) - return; - - tp->nir++; - - do { - /* Acknowledge all of the current interrupt sources ASAP. */ - outl(csr5 & 0x0001ffff, ioaddr + CSR5); - - if (tulip_debug > 4) - printk(KERN_DEBUG "%s: interrupt csr5=%#8.8x new csr5=%#8.8x.\n", - dev->name, csr5, inl(dev->base_addr + CSR5)); - - if (csr5 & (RxIntr | RxNoBuf)) { -#ifdef CONFIG_NET_HW_FLOWCONTROL - if ((!tp->fc_bit) || - (!test_bit(tp->fc_bit, &netdev_fc_xoff))) -#endif - rx += tulip_rx(dev); - tulip_refill_rx(dev); - } - - if (csr5 & (TxNoBuf | TxDied | TxIntr | TimerInt)) { - unsigned int dirty_tx; - - spin_lock(&tp->lock); - - for (dirty_tx = tp->dirty_tx; tp->cur_tx - dirty_tx > 0; - dirty_tx++) { - int entry = dirty_tx % TX_RING_SIZE; - int status = le32_to_cpu(tp->tx_ring[entry].status); - - if (status < 0) - break; /* It still has not been Txed */ - - /* Check for Rx filter setup frames. */ - if (tp->tx_buffers[entry].skb == NULL) { - /* test because dummy frames not mapped */ - if (tp->tx_buffers[entry].mapping) - pci_unmap_single(tp->pdev, - tp->tx_buffers[entry].mapping, - sizeof(tp->setup_frame), - PCI_DMA_TODEVICE); - continue; - } - - if (status & 0x8000) { - /* There was an major error, log it. */ -#ifndef final_version - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n", - dev->name, status); -#endif - tp->stats.tx_errors++; - if (status & 0x4104) tp->stats.tx_aborted_errors++; - if (status & 0x0C00) tp->stats.tx_carrier_errors++; - if (status & 0x0200) tp->stats.tx_window_errors++; - if (status & 0x0002) tp->stats.tx_fifo_errors++; - if ((status & 0x0080) && tp->full_duplex == 0) - tp->stats.tx_heartbeat_errors++; - } else { - tp->stats.tx_bytes += - tp->tx_buffers[entry].skb->len; - tp->stats.collisions += (status >> 3) & 15; - tp->stats.tx_packets++; - } - - pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping, - tp->tx_buffers[entry].skb->len, - PCI_DMA_TODEVICE); - - /* Free the original skb. */ - dev_kfree_skb_irq(tp->tx_buffers[entry].skb); - tp->tx_buffers[entry].skb = NULL; - tp->tx_buffers[entry].mapping = 0; - tx++; - } - -#ifndef final_version - if (tp->cur_tx - dirty_tx > TX_RING_SIZE) { - printk(KERN_ERR "%s: Out-of-sync dirty pointer, %d vs. %d.\n", - dev->name, dirty_tx, tp->cur_tx); - dirty_tx += TX_RING_SIZE; - } -#endif - - if (tp->cur_tx - dirty_tx < TX_RING_SIZE - 2) - netif_wake_queue(dev); - - tp->dirty_tx = dirty_tx; - if (csr5 & TxDied) { - if (tulip_debug > 2) - printk(KERN_WARNING "%s: The transmitter stopped." - " CSR5 is %x, CSR6 %x, new CSR6 %x.\n", - dev->name, csr5, inl(ioaddr + CSR6), tp->csr6); - tulip_restart_rxtx(tp); - } - spin_unlock(&tp->lock); - } - - /* Log errors. */ - if (csr5 & AbnormalIntr) { /* Abnormal error summary bit. */ - if (csr5 == 0xffffffff) - break; - if (csr5 & TxJabber) tp->stats.tx_errors++; - if (csr5 & TxFIFOUnderflow) { - if ((tp->csr6 & 0xC000) != 0xC000) - tp->csr6 += 0x4000; /* Bump up the Tx threshold */ - else - tp->csr6 |= 0x00200000; /* Store-n-forward. */ - /* Restart the transmit process. */ - tulip_restart_rxtx(tp); - outl(0, ioaddr + CSR1); - } - if (csr5 & (RxDied | RxNoBuf)) { - if (tp->flags & COMET_MAC_ADDR) { - outl(tp->mc_filter[0], ioaddr + 0xAC); - outl(tp->mc_filter[1], ioaddr + 0xB0); - } - } - if (csr5 & RxDied) { /* Missed a Rx frame. */ - tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff; -#ifdef CONFIG_NET_HW_FLOWCONTROL - if (tp->fc_bit && !test_bit(tp->fc_bit, &netdev_fc_xoff)) { - tp->stats.rx_errors++; - tulip_start_rxtx(tp); - } -#else - tp->stats.rx_errors++; - tulip_start_rxtx(tp); -#endif - } - /* - * NB: t21142_lnk_change() does a del_timer_sync(), so be careful if this - * call is ever done under the spinlock - */ - if (csr5 & (TPLnkPass | TPLnkFail | 0x08000000)) { - if (tp->link_change) - (tp->link_change)(dev, csr5); - } - if (csr5 & SytemError) { - int error = (csr5 >> 23) & 7; - /* oops, we hit a PCI error. The code produced corresponds - * to the reason: - * 0 - parity error - * 1 - master abort - * 2 - target abort - * Note that on parity error, we should do a software reset - * of the chip to get it back into a sane state (according - * to the 21142/3 docs that is). - * -- rmk - */ - printk(KERN_ERR "%s: (%lu) System Error occured (%d)\n", - dev->name, tp->nir, error); - } - /* Clear all error sources, included undocumented ones! */ - outl(0x0800f7ba, ioaddr + CSR5); - oi++; - } - if (csr5 & TimerInt) { - - if (tulip_debug > 2) - printk(KERN_ERR "%s: Re-enabling interrupts, %8.8x.\n", - dev->name, csr5); -#ifdef CONFIG_NET_HW_FLOWCONTROL - if (tp->fc_bit && (test_bit(tp->fc_bit, &netdev_fc_xoff))) - if (net_ratelimit()) printk("BUG!! enabling interupt when FC off (timerintr.) \n"); -#endif - outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7); - tp->ttimer = 0; - oi++; - } - if (tx > maxtx || rx > maxrx || oi > maxoi) { - if (tulip_debug > 1) - printk(KERN_WARNING "%s: Too much work during an interrupt, " - "csr5=0x%8.8x. (%lu) (%d,%d,%d)\n", dev->name, csr5, tp->nir, tx, rx, oi); - - /* Acknowledge all interrupt sources. */ - outl(0x8001ffff, ioaddr + CSR5); - if (tp->flags & HAS_INTR_MITIGATION) { -#ifdef CONFIG_NET_HW_FLOWCONTROL - if(tp->mit_change) { - outl(mit_table[tp->mit_sel], ioaddr + CSR11); - tp->mit_change = 0; - } -#else - /* Josip Loncaric at ICASE did extensive experimentation - to develop a good interrupt mitigation setting.*/ - outl(0x8b240000, ioaddr + CSR11); -#endif - } else if (tp->chip_id == LC82C168) { - /* the LC82C168 doesn't have a hw timer.*/ - outl(0x00, ioaddr + CSR7); - mod_timer(&tp->timer, RUN_AT(HZ/50)); - } else { - /* Mask all interrupting sources, set timer to - re-enable. */ -#ifndef CONFIG_NET_HW_FLOWCONTROL - outl(((~csr5) & 0x0001ebef) | AbnormalIntr | TimerInt, ioaddr + CSR7); - outl(0x0012, ioaddr + CSR11); -#endif - } - break; - } - - work_count--; - if (work_count == 0) - break; - - csr5 = inl(ioaddr + CSR5); - } while ((csr5 & (NormalIntr|AbnormalIntr)) != 0); - - tulip_refill_rx(dev); - - /* check if the card is in suspend mode */ - entry = tp->dirty_rx % RX_RING_SIZE; - if (tp->rx_buffers[entry].skb == NULL) { - if (tulip_debug > 1) - printk(KERN_WARNING "%s: in rx suspend mode: (%lu) (tp->cur_rx = %u, ttimer = %d, rx = %d) go/stay in suspend mode\n", dev->name, tp->nir, tp->cur_rx, tp->ttimer, rx); - if (tp->chip_id == LC82C168) { - outl(0x00, ioaddr + CSR7); - mod_timer(&tp->timer, RUN_AT(HZ/50)); - } else { - if (tp->ttimer == 0 || (inl(ioaddr + CSR11) & 0xffff) == 0) { - if (tulip_debug > 1) - printk(KERN_WARNING "%s: in rx suspend mode: (%lu) set timer\n", dev->name, tp->nir); - outl(tulip_tbl[tp->chip_id].valid_intrs | TimerInt, - ioaddr + CSR7); - outl(TimerInt, ioaddr + CSR5); - outl(12, ioaddr + CSR11); - tp->ttimer = 1; - } - } - } - - if ((missed = inl(ioaddr + CSR8) & 0x1ffff)) { - tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed; - } - - if (tulip_debug > 4) - printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#4.4x.\n", - dev->name, inl(ioaddr + CSR5)); - -} diff --git a/xen-2.4.16/drivers/net/tulip/media.c b/xen-2.4.16/drivers/net/tulip/media.c deleted file mode 100644 index e0bb197dc5..0000000000 --- a/xen-2.4.16/drivers/net/tulip/media.c +++ /dev/null @@ -1,563 +0,0 @@ -/* - drivers/net/tulip/media.c - - Maintained by Jeff Garzik <jgarzik@mandrakesoft.com> - Copyright 2000,2001 The Linux Kernel Team - Written/copyright 1994-2001 by Donald Becker. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - Please refer to Documentation/DocBook/tulip.{pdf,ps,html} - for more information on this driver, or visit the project - Web page at http://sourceforge.net/projects/tulip/ - -*/ - -//#include <linux/kernel.h> -#include <linux/mii.h> -#include <linux/init.h> -#include <linux/delay.h> -#include "tulip.h" - - -/* This is a mysterious value that can be written to CSR11 in the 21040 (only) - to support a pre-NWay full-duplex signaling mechanism using short frames. - No one knows what it should be, but if left at its default value some - 10base2(!) packets trigger a full-duplex-request interrupt. */ -#define FULL_DUPLEX_MAGIC 0x6969 - -/* The maximum data clock rate is 2.5 Mhz. The minimum timing is usually - met by back-to-back PCI I/O cycles, but we insert a delay to avoid - "overclocking" issues or future 66Mhz PCI. */ -#define mdio_delay() inl(mdio_addr) - -/* Read and write the MII registers using software-generated serial - MDIO protocol. It is just different enough from the EEPROM protocol - to not share code. The maxium data clock rate is 2.5 Mhz. */ -#define MDIO_SHIFT_CLK 0x10000 -#define MDIO_DATA_WRITE0 0x00000 -#define MDIO_DATA_WRITE1 0x20000 -#define MDIO_ENB 0x00000 /* Ignore the 0x02000 databook setting. */ -#define MDIO_ENB_IN 0x40000 -#define MDIO_DATA_READ 0x80000 - -static const unsigned char comet_miireg2offset[32] = { - 0xB4, 0xB8, 0xBC, 0xC0, 0xC4, 0xC8, 0xCC, 0, 0,0,0,0, 0,0,0,0, - 0,0xD0,0,0, 0,0,0,0, 0,0,0,0, 0, 0xD4, 0xD8, 0xDC, }; - - -/* MII transceiver control section. - Read and write the MII registers using software-generated serial - MDIO protocol. See the MII specifications or DP83840A data sheet - for details. */ - -int tulip_mdio_read(struct net_device *dev, int phy_id, int location) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - int i; - int read_cmd = (0xf6 << 10) | ((phy_id & 0x1f) << 5) | location; - int retval = 0; - long ioaddr = dev->base_addr; - long mdio_addr = ioaddr + CSR9; - unsigned long flags; - - if (location & ~0x1f) - return 0xffff; - - if (tp->chip_id == COMET && phy_id == 30) { - if (comet_miireg2offset[location]) - return inl(ioaddr + comet_miireg2offset[location]); - return 0xffff; - } - - spin_lock_irqsave(&tp->mii_lock, flags); - if (tp->chip_id == LC82C168) { - int i = 1000; - outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0); - inl(ioaddr + 0xA0); - inl(ioaddr + 0xA0); - while (--i > 0) { - barrier(); - if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000)) - break; - } - spin_unlock_irqrestore(&tp->mii_lock, flags); - return retval & 0xffff; - } - - /* Establish sync by sending at least 32 logic ones. */ - for (i = 32; i >= 0; i--) { - outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr); - mdio_delay(); - outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr); - mdio_delay(); - } - /* Shift the read command bits out. */ - for (i = 15; i >= 0; i--) { - int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0; - - outl(MDIO_ENB | dataval, mdio_addr); - mdio_delay(); - outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr); - mdio_delay(); - } - /* Read the two transition, 16 data, and wire-idle bits. */ - for (i = 19; i > 0; i--) { - outl(MDIO_ENB_IN, mdio_addr); - mdio_delay(); - retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0); - outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); - mdio_delay(); - } - - spin_unlock_irqrestore(&tp->mii_lock, flags); - return (retval>>1) & 0xffff; -} - -void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int val) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - int i; - int cmd = (0x5002 << 16) | ((phy_id & 0x1f) << 23) | (location<<18) | (val & 0xffff); - long ioaddr = dev->base_addr; - long mdio_addr = ioaddr + CSR9; - unsigned long flags; - - if (location & ~0x1f) - return; - - if (tp->chip_id == COMET && phy_id == 30) { - if (comet_miireg2offset[location]) - outl(val, ioaddr + comet_miireg2offset[location]); - return; - } - - spin_lock_irqsave(&tp->mii_lock, flags); - if (tp->chip_id == LC82C168) { - int i = 1000; - outl(cmd, ioaddr + 0xA0); - do { - barrier(); - if ( ! (inl(ioaddr + 0xA0) & 0x80000000)) - break; - } while (--i > 0); - spin_unlock_irqrestore(&tp->mii_lock, flags); - return; - } - - /* Establish sync by sending 32 logic ones. */ - for (i = 32; i >= 0; i--) { - outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr); - mdio_delay(); - outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr); - mdio_delay(); - } - /* Shift the command bits out. */ - for (i = 31; i >= 0; i--) { - int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0; - outl(MDIO_ENB | dataval, mdio_addr); - mdio_delay(); - outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr); - mdio_delay(); - } - /* Clear out extra bits. */ - for (i = 2; i > 0; i--) { - outl(MDIO_ENB_IN, mdio_addr); - mdio_delay(); - outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); - mdio_delay(); - } - - spin_unlock_irqrestore(&tp->mii_lock, flags); -} - - -/* Set up the transceiver control registers for the selected media type. */ -void tulip_select_media(struct net_device *dev, int startup) -{ - long ioaddr = dev->base_addr; - struct tulip_private *tp = (struct tulip_private *)dev->priv; - struct mediatable *mtable = tp->mtable; - u32 new_csr6; - int i; - - if (mtable) { - struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index]; - unsigned char *p = mleaf->leafdata; - switch (mleaf->type) { - case 0: /* 21140 non-MII xcvr. */ - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: Using a 21140 non-MII transceiver" - " with control setting %2.2x.\n", - dev->name, p[1]); - dev->if_port = p[0]; - if (startup) - outl(mtable->csr12dir | 0x100, ioaddr + CSR12); - outl(p[1], ioaddr + CSR12); - new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18); - break; - case 2: case 4: { - u16 setup[5]; - u32 csr13val, csr14val, csr15dir, csr15val; - for (i = 0; i < 5; i++) - setup[i] = get_u16(&p[i*2 + 1]); - - dev->if_port = p[0] & MEDIA_MASK; - if (tulip_media_cap[dev->if_port] & MediaAlwaysFD) - tp->full_duplex = 1; - - if (startup && mtable->has_reset) { - struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset]; - unsigned char *rst = rleaf->leafdata; - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: Resetting the transceiver.\n", - dev->name); - for (i = 0; i < rst[0]; i++) - outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15); - } - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: 21143 non-MII %s transceiver control " - "%4.4x/%4.4x.\n", - dev->name, medianame[dev->if_port], setup[0], setup[1]); - if (p[0] & 0x40) { /* SIA (CSR13-15) setup values are provided. */ - csr13val = setup[0]; - csr14val = setup[1]; - csr15dir = (setup[3]<<16) | setup[2]; - csr15val = (setup[4]<<16) | setup[2]; - outl(0, ioaddr + CSR13); - outl(csr14val, ioaddr + CSR14); - outl(csr15dir, ioaddr + CSR15); /* Direction */ - outl(csr15val, ioaddr + CSR15); /* Data */ - outl(csr13val, ioaddr + CSR13); - } else { - csr13val = 1; - csr14val = 0; - csr15dir = (setup[0]<<16) | 0x0008; - csr15val = (setup[1]<<16) | 0x0008; - if (dev->if_port <= 4) - csr14val = t21142_csr14[dev->if_port]; - if (startup) { - outl(0, ioaddr + CSR13); - outl(csr14val, ioaddr + CSR14); - } - outl(csr15dir, ioaddr + CSR15); /* Direction */ - outl(csr15val, ioaddr + CSR15); /* Data */ - if (startup) outl(csr13val, ioaddr + CSR13); - } - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: Setting CSR15 to %8.8x/%8.8x.\n", - dev->name, csr15dir, csr15val); - if (mleaf->type == 4) - new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18); - else - new_csr6 = 0x82420000; - break; - } - case 1: case 3: { - int phy_num = p[0]; - int init_length = p[1]; - u16 *misc_info, tmp_info; - - dev->if_port = 11; - new_csr6 = 0x020E0000; - if (mleaf->type == 3) { /* 21142 */ - u16 *init_sequence = (u16*)(p+2); - u16 *reset_sequence = &((u16*)(p+3))[init_length]; - int reset_length = p[2 + init_length*2]; - misc_info = reset_sequence + reset_length; - if (startup) - for (i = 0; i < reset_length; i++) - outl(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); - for (i = 0; i < init_length; i++) - outl(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15); - } else { - u8 *init_sequence = p + 2; - u8 *reset_sequence = p + 3 + init_length; - int reset_length = p[2 + init_length]; - misc_info = (u16*)(reset_sequence + reset_length); - if (startup) { - outl(mtable->csr12dir | 0x100, ioaddr + CSR12); - for (i = 0; i < reset_length; i++) - outl(reset_sequence[i], ioaddr + CSR12); - } - for (i = 0; i < init_length; i++) - outl(init_sequence[i], ioaddr + CSR12); - } - tmp_info = get_u16(&misc_info[1]); - if (tmp_info) - tp->advertising[phy_num] = tmp_info | 1; - if (tmp_info && startup < 2) { - if (tp->mii_advertise == 0) - tp->mii_advertise = tp->advertising[phy_num]; - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: Advertising %4.4x on MII %d.\n", - dev->name, tp->mii_advertise, tp->phys[phy_num]); - tulip_mdio_write(dev, tp->phys[phy_num], 4, tp->mii_advertise); - } - break; - } - case 5: case 6: { - u16 setup[5]; - - new_csr6 = 0; /* FIXME */ - - for (i = 0; i < 5; i++) - setup[i] = get_u16(&p[i*2 + 1]); - - if (startup && mtable->has_reset) { - struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset]; - unsigned char *rst = rleaf->leafdata; - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: Resetting the transceiver.\n", - dev->name); - for (i = 0; i < rst[0]; i++) - outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15); - } - - break; - } - default: - printk(KERN_DEBUG "%s: Invalid media table selection %d.\n", - dev->name, mleaf->type); - new_csr6 = 0x020E0000; - } - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: Using media type %s, CSR12 is %2.2x.\n", - dev->name, medianame[dev->if_port], - inl(ioaddr + CSR12) & 0xff); - } else if (tp->chip_id == DC21041) { - int port = dev->if_port <= 4 ? dev->if_port : 0; - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: 21041 using media %s, CSR12 is %4.4x.\n", - dev->name, medianame[port == 3 ? 12: port], - inl(ioaddr + CSR12)); - outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */ - outl(t21041_csr14[port], ioaddr + CSR14); - outl(t21041_csr15[port], ioaddr + CSR15); - outl(t21041_csr13[port], ioaddr + CSR13); - new_csr6 = 0x80020000; - } else if (tp->chip_id == LC82C168) { - if (startup && ! tp->medialock) - dev->if_port = tp->mii_cnt ? 11 : 0; - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: PNIC PHY status is %3.3x, media %s.\n", - dev->name, inl(ioaddr + 0xB8), medianame[dev->if_port]); - if (tp->mii_cnt) { - new_csr6 = 0x810C0000; - outl(0x0001, ioaddr + CSR15); - outl(0x0201B07A, ioaddr + 0xB8); - } else if (startup) { - /* Start with 10mbps to do autonegotiation. */ - outl(0x32, ioaddr + CSR12); - new_csr6 = 0x00420000; - outl(0x0001B078, ioaddr + 0xB8); - outl(0x0201B078, ioaddr + 0xB8); - } else if (dev->if_port == 3 || dev->if_port == 5) { - outl(0x33, ioaddr + CSR12); - new_csr6 = 0x01860000; - /* Trigger autonegotiation. */ - outl(startup ? 0x0201F868 : 0x0001F868, ioaddr + 0xB8); - } else { - outl(0x32, ioaddr + CSR12); - new_csr6 = 0x00420000; - outl(0x1F078, ioaddr + 0xB8); - } - } else if (tp->chip_id == DC21040) { /* 21040 */ - /* Turn on the xcvr interface. */ - int csr12 = inl(ioaddr + CSR12); - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: 21040 media type is %s, CSR12 is %2.2x.\n", - dev->name, medianame[dev->if_port], csr12); - if (tulip_media_cap[dev->if_port] & MediaAlwaysFD) - tp->full_duplex = 1; - new_csr6 = 0x20000; - /* Set the full duplux match frame. */ - outl(FULL_DUPLEX_MAGIC, ioaddr + CSR11); - outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */ - if (t21040_csr13[dev->if_port] & 8) { - outl(0x0705, ioaddr + CSR14); - outl(0x0006, ioaddr + CSR15); - } else { - outl(0xffff, ioaddr + CSR14); - outl(0x0000, ioaddr + CSR15); - } - outl(0x8f01 | t21040_csr13[dev->if_port], ioaddr + CSR13); - } else { /* Unknown chip type with no media table. */ - if (tp->default_port == 0) - dev->if_port = tp->mii_cnt ? 11 : 3; - if (tulip_media_cap[dev->if_port] & MediaIsMII) { - new_csr6 = 0x020E0000; - } else if (tulip_media_cap[dev->if_port] & MediaIsFx) { - new_csr6 = 0x028600000; - } else - new_csr6 = 0x038600000; - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: No media description table, assuming " - "%s transceiver, CSR12 %2.2x.\n", - dev->name, medianame[dev->if_port], - inl(ioaddr + CSR12)); - } - - tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0); - return; -} - -/* - Check the MII negotiated duplex and change the CSR6 setting if - required. - Return 0 if everything is OK. - Return < 0 if the transceiver is missing or has no link beat. - */ -int tulip_check_duplex(struct net_device *dev) -{ - struct tulip_private *tp = dev->priv; - unsigned int bmsr, lpa, negotiated, new_csr6; - - bmsr = tulip_mdio_read(dev, tp->phys[0], MII_BMSR); - lpa = tulip_mdio_read(dev, tp->phys[0], MII_LPA); - if (tulip_debug > 1) - printk(KERN_INFO "%s: MII status %4.4x, Link partner report " - "%4.4x.\n", dev->name, bmsr, lpa); - if (bmsr == 0xffff) - return -2; - if ((bmsr & BMSR_LSTATUS) == 0) { - int new_bmsr = tulip_mdio_read(dev, tp->phys[0], MII_BMSR); - if ((new_bmsr & BMSR_LSTATUS) == 0) { - if (tulip_debug > 1) - printk(KERN_INFO "%s: No link beat on the MII interface," - " status %4.4x.\n", dev->name, new_bmsr); - return -1; - } - } - negotiated = lpa & tp->advertising[0]; - tp->full_duplex = mii_duplex(tp->full_duplex_lock, negotiated); - - new_csr6 = tp->csr6; - - if (negotiated & LPA_100) new_csr6 &= ~TxThreshold; - else new_csr6 |= TxThreshold; - if (tp->full_duplex) new_csr6 |= FullDuplex; - else new_csr6 &= ~FullDuplex; - - if (new_csr6 != tp->csr6) { - tp->csr6 = new_csr6; - tulip_restart_rxtx(tp); - - if (tulip_debug > 0) - printk(KERN_INFO "%s: Setting %s-duplex based on MII" - "#%d link partner capability of %4.4x.\n", - dev->name, tp->full_duplex ? "full" : "half", - tp->phys[0], lpa); - return 1; - } - - return 0; -} - -void __devinit tulip_find_mii (struct net_device *dev, int board_idx) -{ - struct tulip_private *tp = dev->priv; - int phyn, phy_idx = 0; - int mii_reg0; - int mii_advert; - unsigned int to_advert, new_bmcr, ane_switch; - - /* Find the connected MII xcvrs. - Doing this in open() would allow detecting external xcvrs later, - but takes much time. */ - for (phyn = 1; phyn <= 32 && phy_idx < sizeof (tp->phys); phyn++) { - int phy = phyn & 0x1f; - int mii_status = tulip_mdio_read (dev, phy, MII_BMSR); - if ((mii_status & 0x8301) == 0x8001 || - ((mii_status & BMSR_100BASE4) == 0 - && (mii_status & 0x7800) != 0)) { - /* preserve Becker logic, gain indentation level */ - } else { - continue; - } - - mii_reg0 = tulip_mdio_read (dev, phy, MII_BMCR); - mii_advert = tulip_mdio_read (dev, phy, MII_ADVERTISE); - ane_switch = 0; - - /* if not advertising at all, gen an - * advertising value from the capability - * bits in BMSR - */ - if ((mii_advert & ADVERTISE_ALL) == 0) { - unsigned int tmpadv = tulip_mdio_read (dev, phy, MII_BMSR); - mii_advert = ((tmpadv >> 6) & 0x3e0) | 1; - } - - if (tp->mii_advertise) { - tp->advertising[phy_idx] = - to_advert = tp->mii_advertise; - } else if (tp->advertising[phy_idx]) { - to_advert = tp->advertising[phy_idx]; - } else { - tp->advertising[phy_idx] = - tp->mii_advertise = - to_advert = mii_advert; - } - - tp->phys[phy_idx++] = phy; - - printk (KERN_INFO "tulip%d: MII transceiver #%d " - "config %4.4x status %4.4x advertising %4.4x.\n", - board_idx, phy, mii_reg0, mii_status, mii_advert); - - /* Fixup for DLink with miswired PHY. */ - if (mii_advert != to_advert) { - printk (KERN_DEBUG "tulip%d: Advertising %4.4x on PHY %d," - " previously advertising %4.4x.\n", - board_idx, to_advert, phy, mii_advert); - tulip_mdio_write (dev, phy, 4, to_advert); - } - - /* Enable autonegotiation: some boards default to off. */ - if (tp->default_port == 0) { - new_bmcr = mii_reg0 | BMCR_ANENABLE; - if (new_bmcr != mii_reg0) { - new_bmcr |= BMCR_ANRESTART; - ane_switch = 1; - } - } - /* ...or disable nway, if forcing media */ - else { - new_bmcr = mii_reg0 & ~BMCR_ANENABLE; - if (new_bmcr != mii_reg0) - ane_switch = 1; - } - - /* clear out bits we never want at this point */ - new_bmcr &= ~(BMCR_CTST | BMCR_FULLDPLX | BMCR_ISOLATE | - BMCR_PDOWN | BMCR_SPEED100 | BMCR_LOOPBACK | - BMCR_RESET); - - if (tp->full_duplex) - new_bmcr |= BMCR_FULLDPLX; - if (tulip_media_cap[tp->default_port] & MediaIs100) - new_bmcr |= BMCR_SPEED100; - - if (new_bmcr != mii_reg0) { - /* some phys need the ANE switch to - * happen before forced media settings - * will "take." However, we write the - * same value twice in order not to - * confuse the sane phys. - */ - if (ane_switch) { - tulip_mdio_write (dev, phy, MII_BMCR, new_bmcr); - udelay (10); - } - tulip_mdio_write (dev, phy, MII_BMCR, new_bmcr); - } - } - tp->mii_cnt = phy_idx; - if (tp->mtable && tp->mtable->has_mii && phy_idx == 0) { - printk (KERN_INFO "tulip%d: ***WARNING***: No MII transceiver found!\n", - board_idx); - tp->phys[0] = 1; - } -} diff --git a/xen-2.4.16/drivers/net/tulip/pnic.c b/xen-2.4.16/drivers/net/tulip/pnic.c deleted file mode 100644 index 6739dd30fc..0000000000 --- a/xen-2.4.16/drivers/net/tulip/pnic.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - drivers/net/tulip/pnic.c - - Maintained by Jeff Garzik <jgarzik@mandrakesoft.com> - Copyright 2000,2001 The Linux Kernel Team - Written/copyright 1994-2001 by Donald Becker. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - Please refer to Documentation/DocBook/tulip.{pdf,ps,html} - for more information on this driver, or visit the project - Web page at http://sourceforge.net/projects/tulip/ - -*/ - -//#include <linux/kernel.h> -#include "tulip.h" - - -void pnic_do_nway(struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - u32 phy_reg = inl(ioaddr + 0xB8); - u32 new_csr6 = tp->csr6 & ~0x40C40200; - - if (phy_reg & 0x78000000) { /* Ignore baseT4 */ - if (phy_reg & 0x20000000) dev->if_port = 5; - else if (phy_reg & 0x40000000) dev->if_port = 3; - else if (phy_reg & 0x10000000) dev->if_port = 4; - else if (phy_reg & 0x08000000) dev->if_port = 0; - tp->nwayset = 1; - new_csr6 = (dev->if_port & 1) ? 0x01860000 : 0x00420000; - outl(0x32 | (dev->if_port & 1), ioaddr + CSR12); - if (dev->if_port & 1) - outl(0x1F868, ioaddr + 0xB8); - if (phy_reg & 0x30000000) { - tp->full_duplex = 1; - new_csr6 |= 0x00000200; - } - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: PNIC autonegotiated status %8.8x, %s.\n", - dev->name, phy_reg, medianame[dev->if_port]); - if (tp->csr6 != new_csr6) { - tp->csr6 = new_csr6; - /* Restart Tx */ - tulip_restart_rxtx(tp); - dev->trans_start = jiffies; - } - } -} - -void pnic_lnk_change(struct net_device *dev, int csr5) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - int phy_reg = inl(ioaddr + 0xB8); - - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: PNIC link changed state %8.8x, CSR5 %8.8x.\n", - dev->name, phy_reg, csr5); - if (inl(ioaddr + CSR5) & TPLnkFail) { - outl((inl(ioaddr + CSR7) & ~TPLnkFail) | TPLnkPass, ioaddr + CSR7); - /* If we use an external MII, then we mustn't use the - * internal negotiation. - */ - if (tulip_media_cap[dev->if_port] & MediaIsMII) - return; - if (! tp->nwayset || jiffies - dev->trans_start > 1*HZ) { - tp->csr6 = 0x00420000 | (tp->csr6 & 0x0000fdff); - outl(tp->csr6, ioaddr + CSR6); - outl(0x30, ioaddr + CSR12); - outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */ - dev->trans_start = jiffies; - } - } else if (inl(ioaddr + CSR5) & TPLnkPass) { - if (tulip_media_cap[dev->if_port] & MediaIsMII) { - spin_lock(&tp->lock); - tulip_check_duplex(dev); - spin_unlock(&tp->lock); - } else { - pnic_do_nway(dev); - } - outl((inl(ioaddr + CSR7) & ~TPLnkPass) | TPLnkFail, ioaddr + CSR7); - } -} - -void pnic_timer(unsigned long data) -{ - struct net_device *dev = (struct net_device *)data; - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - int next_tick = 60*HZ; - - if(!inl(ioaddr + CSR7)) { - /* the timer was called due to a work overflow - * in the interrupt handler. Skip the connection - * checks, the nic is definitively speaking with - * his link partner. - */ - goto too_good_connection; - } - - if (tulip_media_cap[dev->if_port] & MediaIsMII) { - spin_lock_irq(&tp->lock); - if (tulip_check_duplex(dev) > 0) - next_tick = 3*HZ; - spin_unlock_irq(&tp->lock); - } else { - int csr12 = inl(ioaddr + CSR12); - int new_csr6 = tp->csr6 & ~0x40C40200; - int phy_reg = inl(ioaddr + 0xB8); - int csr5 = inl(ioaddr + CSR5); - - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: PNIC timer PHY status %8.8x, %s " - "CSR5 %8.8x.\n", - dev->name, phy_reg, medianame[dev->if_port], csr5); - if (phy_reg & 0x04000000) { /* Remote link fault */ - outl(0x0201F078, ioaddr + 0xB8); - next_tick = 1*HZ; - tp->nwayset = 0; - } else if (phy_reg & 0x78000000) { /* Ignore baseT4 */ - pnic_do_nway(dev); - next_tick = 60*HZ; - } else if (csr5 & TPLnkFail) { /* 100baseTx link beat */ - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: %s link beat failed, CSR12 %4.4x, " - "CSR5 %8.8x, PHY %3.3x.\n", - dev->name, medianame[dev->if_port], csr12, - inl(ioaddr + CSR5), inl(ioaddr + 0xB8)); - next_tick = 3*HZ; - if (tp->medialock) { - } else if (tp->nwayset && (dev->if_port & 1)) { - next_tick = 1*HZ; - } else if (dev->if_port == 0) { - dev->if_port = 3; - outl(0x33, ioaddr + CSR12); - new_csr6 = 0x01860000; - outl(0x1F868, ioaddr + 0xB8); - } else { - dev->if_port = 0; - outl(0x32, ioaddr + CSR12); - new_csr6 = 0x00420000; - outl(0x1F078, ioaddr + 0xB8); - } - if (tp->csr6 != new_csr6) { - tp->csr6 = new_csr6; - /* Restart Tx */ - tulip_restart_rxtx(tp); - dev->trans_start = jiffies; - if (tulip_debug > 1) - printk(KERN_INFO "%s: Changing PNIC configuration to %s " - "%s-duplex, CSR6 %8.8x.\n", - dev->name, medianame[dev->if_port], - tp->full_duplex ? "full" : "half", new_csr6); - } - } - } -too_good_connection: - mod_timer(&tp->timer, RUN_AT(next_tick)); - if(!inl(ioaddr + CSR7)) { - if (tulip_debug > 1) - printk(KERN_INFO "%s: sw timer wakeup.\n", dev->name); - disable_irq(dev->irq); - tulip_refill_rx(dev); - enable_irq(dev->irq); - outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7); - } -} diff --git a/xen-2.4.16/drivers/net/tulip/pnic2.c b/xen-2.4.16/drivers/net/tulip/pnic2.c deleted file mode 100644 index 9b209d2c84..0000000000 --- a/xen-2.4.16/drivers/net/tulip/pnic2.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - drivers/net/tulip/pnic2.c - - Maintained by Jeff Garzik <jgarzik@mandrakesoft.com> - Copyright 2000,2001 The Linux Kernel Team - Written/copyright 1994-2001 by Donald Becker. - Modified to hep support PNIC_II by Kevin B. Hendricks - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - Please refer to Documentation/DocBook/tulip.{pdf,ps,html} - for more information on this driver, or visit the project - Web page at http://sourceforge.net/projects/tulip/ - -*/ - - -/* Understanding the PNIC_II - everything is this file is based - * on the PNIC_II_PDF datasheet which is sorely lacking in detail - * - * As I understand things, here are the registers and bits that - * explain the masks and constants used in this file that are - * either different from the 21142/3 or important for basic operation. - * - * - * CSR 6 (mask = 0xfe3bd1fd of bits not to change) - * ----- - * Bit 24 - SCR - * Bit 23 - PCS - * Bit 22 - TTM (Trasmit Threshold Mode) - * Bit 18 - Port Select - * Bit 13 - Start - 1, Stop - 0 Transmissions - * Bit 11:10 - Loop Back Operation Mode - * Bit 9 - Full Duplex mode (Advertise 10BaseT-FD is CSR14<7> is set) - * Bit 1 - Start - 1, Stop - 0 Receive - * - * - * CSR 14 (mask = 0xfff0ee39 of bits not to change) - * ------ - * Bit 19 - PAUSE-Pause - * Bit 18 - Advertise T4 - * Bit 17 - Advertise 100baseTx-FD - * Bit 16 - Advertise 100baseTx-HD - * Bit 12 - LTE - Link Test Enable - * Bit 7 - ANE - Auto Negotiate Enable - * Bit 6 - HDE - Advertise 10baseT-HD - * Bit 2 - Reset to Power down - kept as 1 for normal operation - * Bit 1 - Loop Back enable for 10baseT MCC - * - * - * CSR 12 - * ------ - * Bit 25 - Partner can do T4 - * Bit 24 - Partner can do 100baseTx-FD - * Bit 23 - Partner can do 100baseTx-HD - * Bit 22 - Partner can do 10baseT-FD - * Bit 21 - Partner can do 10baseT-HD - * Bit 15 - LPN is 1 if all above bits are valid other wise 0 - * Bit 14:12 - autonegotiation state (write 001 to start autonegotiate) - * Bit 3 - Autopolarity state - * Bit 2 - LS10B - link state of 10baseT 0 - good, 1 - failed - * Bit 1 - LS100B - link state of 100baseT 0 - good, 1- faild - * - * - * Data Port Selection Info - *------------------------- - * - * CSR14<7> CSR6<18> CSR6<22> CSR6<23> CSR6<24> MODE/PORT - * 1 0 0 (X) 0 (X) 1 NWAY - * 0 0 1 0 (X) 0 10baseT - * 0 1 0 1 1 (X) 100baseT - * - * - */ - - - -#include "tulip.h" -#include <linux/pci.h> -#include <linux/delay.h> - - -void pnic2_timer(unsigned long data) -{ - struct net_device *dev = (struct net_device *)data; - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - int next_tick = 60*HZ; - - if (tulip_debug > 3) - printk(KERN_INFO"%s: PNIC2 negotiation status %8.8x.\n", - dev->name,inl(ioaddr + CSR12)); - - if (next_tick) { - mod_timer(&tp->timer, RUN_AT(next_tick)); - } -} - - -void pnic2_start_nway(struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - int csr14; - int csr12; - - /* set up what to advertise during the negotiation */ - - /* load in csr14 and mask off bits not to touch - * comment at top of file explains mask value - */ - csr14 = (inl(ioaddr + CSR14) & 0xfff0ee39); - - /* bit 17 - advetise 100baseTx-FD */ - if (tp->sym_advertise & 0x0100) csr14 |= 0x00020000; - - /* bit 16 - advertise 100baseTx-HD */ - if (tp->sym_advertise & 0x0080) csr14 |= 0x00010000; - - /* bit 6 - advertise 10baseT-HD */ - if (tp->sym_advertise & 0x0020) csr14 |= 0x00000040; - - /* Now set bit 12 Link Test Enable, Bit 7 Autonegotiation Enable - * and bit 0 Don't PowerDown 10baseT - */ - csr14 |= 0x00001184; - - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: Restarting PNIC2 autonegotiation, " - "csr14=%8.8x.\n", dev->name, csr14); - - /* tell pnic2_lnk_change we are doing an nway negotiation */ - dev->if_port = 0; - tp->nway = tp->mediasense = 1; - tp->nwayset = tp->lpar = 0; - - /* now we have to set up csr6 for NWAY state */ - - tp->csr6 = inl(ioaddr + CSR6); - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: On Entry to Nway, " - "csr6=%8.8x.\n", dev->name, tp->csr6); - - /* mask off any bits not to touch - * comment at top of file explains mask value - */ - tp->csr6 = tp->csr6 & 0xfe3bd1fd; - - /* don't forget that bit 9 is also used for advertising */ - /* advertise 10baseT-FD for the negotiation (bit 9) */ - if (tp->sym_advertise & 0x0040) tp->csr6 |= 0x00000200; - - /* set bit 24 for nway negotiation mode ... - * see Data Port Selection comment at top of file - * and "Stop" - reset both Transmit (bit 13) and Receive (bit 1) - */ - tp->csr6 |= 0x01000000; - outl(csr14, ioaddr + CSR14); - outl(tp->csr6, ioaddr + CSR6); - udelay(100); - - /* all set up so now force the negotiation to begin */ - - /* read in current values and mask off all but the - * Autonegotiation bits 14:12. Writing a 001 to those bits - * should start the autonegotiation - */ - csr12 = (inl(ioaddr + CSR12) & 0xffff8fff); - csr12 |= 0x1000; - outl(csr12, ioaddr + CSR12); -} - - - -void pnic2_lnk_change(struct net_device *dev, int csr5) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - int csr14; - - /* read the staus register to find out what is up */ - int csr12 = inl(ioaddr + CSR12); - - if (tulip_debug > 1) - printk(KERN_INFO"%s: PNIC2 link status interrupt %8.8x, " - " CSR5 %x, %8.8x.\n", dev->name, csr12, - csr5, inl(ioaddr + CSR14)); - - /* If NWay finished and we have a negotiated partner capability. - * check bits 14:12 for bit pattern 101 - all is good - */ - if (tp->nway && !tp->nwayset) { - - /* we did an auto negotiation */ - - if ((csr12 & 0x7000) == 0x5000) { - - /* negotiation ended successfully */ - - /* get the link partners reply and mask out all but - * bits 24-21 which show the partners capabilites - * and match those to what we advertised - * - * then begin to interpret the results of the negotiation. - * Always go in this order : (we are ignoring T4 for now) - * 100baseTx-FD, 100baseTx-HD, 10baseT-FD, 10baseT-HD - */ - - int negotiated = ((csr12 >> 16) & 0x01E0) & tp->sym_advertise; - tp->lpar = (csr12 >> 16); - tp->nwayset = 1; - - if (negotiated & 0x0100) dev->if_port = 5; - else if (negotiated & 0x0080) dev->if_port = 3; - else if (negotiated & 0x0040) dev->if_port = 4; - else if (negotiated & 0x0020) dev->if_port = 0; - else { - if (tulip_debug > 1) - printk(KERN_INFO "%s: funny autonegotiate result " - "csr12 %8.8x advertising %4.4x\n", - dev->name, csr12, tp->sym_advertise); - tp->nwayset = 0; - /* so check if 100baseTx link state is okay */ - if ((csr12 & 2) == 0 && (tp->sym_advertise & 0x0180)) - dev->if_port = 3; - } - - /* now record the duplex that was negotiated */ - tp->full_duplex = 0; - if ((dev->if_port == 4) || (dev->if_port == 5)) - tp->full_duplex = 1; - - if (tulip_debug > 1) { - if (tp->nwayset) - printk(KERN_INFO "%s: Switching to %s based on link " - "negotiation %4.4x & %4.4x = %4.4x.\n", - dev->name, medianame[dev->if_port], - tp->sym_advertise, tp->lpar, negotiated); - } - - /* remember to turn off bit 7 - autonegotiate - * enable so we can properly end nway mode and - * set duplex (ie. use csr6<9> again) - */ - csr14 = (inl(ioaddr + CSR14) & 0xffffff7f); - outl(csr14,ioaddr + CSR14); - - - /* now set the data port and operating mode - * (see the Data Port Selection comments at - * the top of the file - */ - - /* get current csr6 and mask off bits not to touch */ - /* see comment at top of file */ - - tp->csr6 = (inl(ioaddr + CSR6) & 0xfe3bd1fd); - - /* so if using if_port 3 or 5 then select the 100baseT - * port else select the 10baseT port. - * See the Data Port Selection table at the top - * of the file which was taken from the PNIC_II.PDF - * datasheet - */ - if (dev->if_port & 1) tp->csr6 |= 0x01840000; - else tp->csr6 |= 0x00400000; - - /* now set the full duplex bit appropriately */ - if (tp->full_duplex) tp->csr6 |= 0x00000200; - - outl(1, ioaddr + CSR13); - - if (tulip_debug > 2) - printk(KERN_DEBUG "%s: Setting CSR6 %8.8x/%x CSR12 " - "%8.8x.\n", dev->name, tp->csr6, - inl(ioaddr + CSR6), inl(ioaddr + CSR12)); - - /* now the following actually writes out the - * new csr6 values - */ - tulip_start_rxtx(tp); - - return; - - } else { - printk(KERN_INFO "%s: Autonegotiation failed, " - "using %s, link beat status %4.4x.\n", - dev->name, medianame[dev->if_port], csr12); - - /* remember to turn off bit 7 - autonegotiate - * enable so we don't forget - */ - csr14 = (inl(ioaddr + CSR14) & 0xffffff7f); - outl(csr14,ioaddr + CSR14); - - /* what should we do when autonegotiate fails? - * should we try again or default to baseline - * case. I just don't know. - * - * for now default to some baseline case - */ - - dev->if_port = 0; - tp->nway = 0; - tp->nwayset = 1; - - /* set to 10baseTx-HD - see Data Port Selection - * comment given at the top of the file - */ - tp->csr6 = (inl(ioaddr + CSR6) & 0xfe3bd1fd); - tp->csr6 |= 0x00400000; - - tulip_restart_rxtx(tp); - - return; - - } - } - - if ((tp->nwayset && (csr5 & 0x08000000) - && (dev->if_port == 3 || dev->if_port == 5) - && (csr12 & 2) == 2) || (tp->nway && (csr5 & (TPLnkFail)))) { - - /* Link blew? Maybe restart NWay. */ - - if (tulip_debug > 2) - printk(KERN_DEBUG "%s: Ugh! Link blew?\n", dev->name); - - del_timer_sync(&tp->timer); - pnic2_start_nway(dev); - tp->timer.expires = RUN_AT(3*HZ); - add_timer(&tp->timer); - - return; - } - - - if (dev->if_port == 3 || dev->if_port == 5) { - - /* we are at 100mb and a potential link change occurred */ - - if (tulip_debug > 1) - printk(KERN_INFO"%s: PNIC2 %s link beat %s.\n", - dev->name, medianame[dev->if_port], - (csr12 & 2) ? "failed" : "good"); - - /* check 100 link beat */ - - tp->nway = 0; - tp->nwayset = 1; - - /* if failed then try doing an nway to get in sync */ - if ((csr12 & 2) && ! tp->medialock) { - del_timer_sync(&tp->timer); - pnic2_start_nway(dev); - tp->timer.expires = RUN_AT(3*HZ); - add_timer(&tp->timer); - } - - return; - } - - if (dev->if_port == 0 || dev->if_port == 4) { - - /* we are at 10mb and a potential link change occurred */ - - if (tulip_debug > 1) - printk(KERN_INFO"%s: PNIC2 %s link beat %s.\n", - dev->name, medianame[dev->if_port], - (csr12 & 4) ? "failed" : "good"); - - - tp->nway = 0; - tp->nwayset = 1; - - /* if failed, try doing an nway to get in sync */ - if ((csr12 & 4) && ! tp->medialock) { - del_timer_sync(&tp->timer); - pnic2_start_nway(dev); - tp->timer.expires = RUN_AT(3*HZ); - add_timer(&tp->timer); - } - - return; - } - - - if (tulip_debug > 1) - printk(KERN_INFO"%s: PNIC2 Link Change Default?\n",dev->name); - - /* if all else fails default to trying 10baseT-HD */ - dev->if_port = 0; - - /* make sure autonegotiate enable is off */ - csr14 = (inl(ioaddr + CSR14) & 0xffffff7f); - outl(csr14,ioaddr + CSR14); - - /* set to 10baseTx-HD - see Data Port Selection - * comment given at the top of the file - */ - tp->csr6 = (inl(ioaddr + CSR6) & 0xfe3bd1fd); - tp->csr6 |= 0x00400000; - - tulip_restart_rxtx(tp); -} - diff --git a/xen-2.4.16/drivers/net/tulip/timer.c b/xen-2.4.16/drivers/net/tulip/timer.c deleted file mode 100644 index 4079772ae9..0000000000 --- a/xen-2.4.16/drivers/net/tulip/timer.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - drivers/net/tulip/timer.c - - Maintained by Jeff Garzik <jgarzik@mandrakesoft.com> - Copyright 2000,2001 The Linux Kernel Team - Written/copyright 1994-2001 by Donald Becker. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - Please refer to Documentation/DocBook/tulip.{pdf,ps,html} - for more information on this driver, or visit the project - Web page at http://sourceforge.net/projects/tulip/ - -*/ - -#include "tulip.h" - - -void tulip_timer(unsigned long data) -{ - struct net_device *dev = (struct net_device *)data; - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - u32 csr12 = inl(ioaddr + CSR12); - int next_tick = 2*HZ; - - if (tulip_debug > 2) { - printk(KERN_DEBUG "%s: Media selection tick, %s, status %8.8x mode" - " %8.8x SIA %8.8x %8.8x %8.8x %8.8x.\n", - dev->name, medianame[dev->if_port], inl(ioaddr + CSR5), - inl(ioaddr + CSR6), csr12, inl(ioaddr + CSR13), - inl(ioaddr + CSR14), inl(ioaddr + CSR15)); - } - switch (tp->chip_id) { - case DC21040: - if (!tp->medialock && csr12 & 0x0002) { /* Network error */ - printk(KERN_INFO "%s: No link beat found.\n", - dev->name); - dev->if_port = (dev->if_port == 2 ? 0 : 2); - tulip_select_media(dev, 0); - dev->trans_start = jiffies; - } - break; - case DC21041: - if (tulip_debug > 2) - printk(KERN_DEBUG "%s: 21041 media tick CSR12 %8.8x.\n", - dev->name, csr12); - if (tp->medialock) break; - switch (dev->if_port) { - case 0: case 3: case 4: - if (csr12 & 0x0004) { /*LnkFail */ - /* 10baseT is dead. Check for activity on alternate port. */ - tp->mediasense = 1; - if (csr12 & 0x0200) - dev->if_port = 2; - else - dev->if_port = 1; - printk(KERN_INFO "%s: No 21041 10baseT link beat, Media switched to %s.\n", - dev->name, medianame[dev->if_port]); - outl(0, ioaddr + CSR13); /* Reset */ - outl(t21041_csr14[dev->if_port], ioaddr + CSR14); - outl(t21041_csr15[dev->if_port], ioaddr + CSR15); - outl(t21041_csr13[dev->if_port], ioaddr + CSR13); - next_tick = 10*HZ; /* 2.4 sec. */ - } else - next_tick = 30*HZ; - break; - case 1: /* 10base2 */ - case 2: /* AUI */ - if (csr12 & 0x0100) { - next_tick = (30*HZ); /* 30 sec. */ - tp->mediasense = 0; - } else if ((csr12 & 0x0004) == 0) { - printk(KERN_INFO "%s: 21041 media switched to 10baseT.\n", - dev->name); - dev->if_port = 0; - tulip_select_media(dev, 0); - next_tick = (24*HZ)/10; /* 2.4 sec. */ - } else if (tp->mediasense || (csr12 & 0x0002)) { - dev->if_port = 3 - dev->if_port; /* Swap ports. */ - tulip_select_media(dev, 0); - next_tick = 20*HZ; - } else { - next_tick = 20*HZ; - } - break; - } - break; - case DC21140: - case DC21142: - case MX98713: - case COMPEX9881: - case DM910X: - default: { - struct medialeaf *mleaf; - unsigned char *p; - if (tp->mtable == NULL) { /* No EEPROM info, use generic code. */ - /* Not much that can be done. - Assume this a generic MII or SYM transceiver. */ - next_tick = 60*HZ; - if (tulip_debug > 2) - printk(KERN_DEBUG "%s: network media monitor CSR6 %8.8x " - "CSR12 0x%2.2x.\n", - dev->name, inl(ioaddr + CSR6), csr12 & 0xff); - break; - } - mleaf = &tp->mtable->mleaf[tp->cur_index]; - p = mleaf->leafdata; - switch (mleaf->type) { - case 0: case 4: { - /* Type 0 serial or 4 SYM transceiver. Check the link beat bit. */ - int offset = mleaf->type == 4 ? 5 : 2; - s8 bitnum = p[offset]; - if (p[offset+1] & 0x80) { - if (tulip_debug > 1) - printk(KERN_DEBUG"%s: Transceiver monitor tick " - "CSR12=%#2.2x, no media sense.\n", - dev->name, csr12); - if (mleaf->type == 4) { - if (mleaf->media == 3 && (csr12 & 0x02)) - goto select_next_media; - } - break; - } - if (tulip_debug > 2) - printk(KERN_DEBUG "%s: Transceiver monitor tick: CSR12=%#2.2x" - " bit %d is %d, expecting %d.\n", - dev->name, csr12, (bitnum >> 1) & 7, - (csr12 & (1 << ((bitnum >> 1) & 7))) != 0, - (bitnum >= 0)); - /* Check that the specified bit has the proper value. */ - if ((bitnum < 0) != - ((csr12 & (1 << ((bitnum >> 1) & 7))) != 0)) { - if (tulip_debug > 2) - printk(KERN_DEBUG "%s: Link beat detected for %s.\n", dev->name, - medianame[mleaf->media & MEDIA_MASK]); - if ((p[2] & 0x61) == 0x01) /* Bogus Znyx board. */ - goto actually_mii; - /* netif_carrier_on(dev); */ - break; - } - /* netif_carrier_off(dev); */ - if (tp->medialock) - break; - select_next_media: - if (--tp->cur_index < 0) { - /* We start again, but should instead look for default. */ - tp->cur_index = tp->mtable->leafcount - 1; - } - dev->if_port = tp->mtable->mleaf[tp->cur_index].media; - if (tulip_media_cap[dev->if_port] & MediaIsFD) - goto select_next_media; /* Skip FD entries. */ - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: No link beat on media %s," - " trying transceiver type %s.\n", - dev->name, medianame[mleaf->media & MEDIA_MASK], - medianame[tp->mtable->mleaf[tp->cur_index].media]); - tulip_select_media(dev, 0); - /* Restart the transmit process. */ - tulip_restart_rxtx(tp); - next_tick = (24*HZ)/10; - break; - } - case 1: case 3: /* 21140, 21142 MII */ - actually_mii: - if (tulip_check_duplex(dev) < 0) - { /* netif_carrier_off(dev); */ } - else - { /* netif_carrier_on(dev); */ } - next_tick = 60*HZ; - break; - case 2: /* 21142 serial block has no link beat. */ - default: - break; - } - } - break; - } - /* mod_timer synchronizes us with potential add_timer calls - * from interrupts. - */ - mod_timer(&tp->timer, RUN_AT(next_tick)); -} - - -void mxic_timer(unsigned long data) -{ - struct net_device *dev = (struct net_device *)data; - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - int next_tick = 60*HZ; - - if (tulip_debug > 3) { - printk(KERN_INFO"%s: MXIC negotiation status %8.8x.\n", dev->name, - inl(ioaddr + CSR12)); - } - if (next_tick) { - mod_timer(&tp->timer, RUN_AT(next_tick)); - } -} - - -void comet_timer(unsigned long data) -{ - struct net_device *dev = (struct net_device *)data; - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - int next_tick = 60*HZ; - - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: Comet link status %4.4x partner capability " - "%4.4x.\n", - dev->name, inl(ioaddr + 0xB8), inl(ioaddr + 0xC8)); - /* mod_timer synchronizes us with potential add_timer calls - * from interrupts. - */ - mod_timer(&tp->timer, RUN_AT(next_tick)); -} - diff --git a/xen-2.4.16/drivers/net/tulip/tulip.h b/xen-2.4.16/drivers/net/tulip/tulip.h deleted file mode 100644 index 716bc9294a..0000000000 --- a/xen-2.4.16/drivers/net/tulip/tulip.h +++ /dev/null @@ -1,499 +0,0 @@ -/* - drivers/net/tulip/tulip.h - - Copyright 2000,2001 The Linux Kernel Team - Written/copyright 1994-2001 by Donald Becker. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - Please refer to Documentation/DocBook/tulip.{pdf,ps,html} - for more information on this driver, or visit the project - Web page at http://sourceforge.net/projects/tulip/ - -*/ - -#ifndef __NET_TULIP_H__ -#define __NET_TULIP_H__ - -#include <linux/config.h> -//#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/spinlock.h> -#include <linux/netdevice.h> -#include <linux/timer.h> -#include <linux/delay.h> -#include <asm/io.h> -#include <asm/irq.h> - - - -/* undefine, or define to various debugging levels (>4 == obscene levels) */ -#define TULIP_DEBUG 1 - -/* undefine USE_IO_OPS for MMIO, define for PIO */ -#ifdef CONFIG_TULIP_MMIO -# undef USE_IO_OPS -#else -# define USE_IO_OPS 1 -#endif - - - -struct tulip_chip_table { - char *chip_name; - int io_size; - int valid_intrs; /* CSR7 interrupt enable settings */ - int flags; - void (*media_timer) (unsigned long data); -}; - - -enum tbl_flag { - HAS_MII = 0x0001, - HAS_MEDIA_TABLE = 0x0002, - CSR12_IN_SROM = 0x0004, - ALWAYS_CHECK_MII = 0x0008, - HAS_ACPI = 0x0010, - MC_HASH_ONLY = 0x0020, /* Hash-only multicast filter. */ - HAS_PNICNWAY = 0x0080, - HAS_NWAY = 0x0040, /* Uses internal NWay xcvr. */ - HAS_INTR_MITIGATION = 0x0100, - IS_ASIX = 0x0200, - HAS_8023X = 0x0400, - COMET_MAC_ADDR = 0x0800, - HAS_PCI_MWI = 0x1000, -}; - - -/* chip types. careful! order is VERY IMPORTANT here, as these - * are used throughout the driver as indices into arrays */ -/* Note 21142 == 21143. */ -enum chips { - DC21040 = 0, - DC21041 = 1, - DC21140 = 2, - DC21142 = 3, DC21143 = 3, - LC82C168, - MX98713, - MX98715, - MX98725, - AX88140, - PNIC2, - COMET, - COMPEX9881, - I21145, - DM910X, -}; - - -enum MediaIs { - MediaIsFD = 1, - MediaAlwaysFD = 2, - MediaIsMII = 4, - MediaIsFx = 8, - MediaIs100 = 16 -}; - - -/* Offsets to the Command and Status Registers, "CSRs". All accesses - must be longword instructions and quadword aligned. */ -enum tulip_offsets { - CSR0 = 0, - CSR1 = 0x08, - CSR2 = 0x10, - CSR3 = 0x18, - CSR4 = 0x20, - CSR5 = 0x28, - CSR6 = 0x30, - CSR7 = 0x38, - CSR8 = 0x40, - CSR9 = 0x48, - CSR10 = 0x50, - CSR11 = 0x58, - CSR12 = 0x60, - CSR13 = 0x68, - CSR14 = 0x70, - CSR15 = 0x78, -}; - -/* register offset and bits for CFDD PCI config reg */ -enum pci_cfg_driver_reg { - CFDD = 0x40, - CFDD_Sleep = (1 << 31), - CFDD_Snooze = (1 << 30), -}; - - -/* The bits in the CSR5 status registers, mostly interrupt sources. */ -enum status_bits { - TimerInt = 0x800, - SytemError = 0x2000, - TPLnkFail = 0x1000, - TPLnkPass = 0x10, - NormalIntr = 0x10000, - AbnormalIntr = 0x8000, - RxJabber = 0x200, - RxDied = 0x100, - RxNoBuf = 0x80, - RxIntr = 0x40, - TxFIFOUnderflow = 0x20, - TxJabber = 0x08, - TxNoBuf = 0x04, - TxDied = 0x02, - TxIntr = 0x01, -}; - - -enum tulip_mode_bits { - TxThreshold = (1 << 22), - FullDuplex = (1 << 9), - TxOn = 0x2000, - AcceptBroadcast = 0x0100, - AcceptAllMulticast = 0x0080, - AcceptAllPhys = 0x0040, - AcceptRunt = 0x0008, - RxOn = 0x0002, - RxTx = (TxOn | RxOn), -}; - - -enum tulip_busconfig_bits { - MWI = (1 << 24), - MRL = (1 << 23), - MRM = (1 << 21), - CALShift = 14, - BurstLenShift = 8, -}; - - -/* The Tulip Rx and Tx buffer descriptors. */ -struct tulip_rx_desc { - s32 status; - s32 length; - u32 buffer1; - u32 buffer2; -}; - - -struct tulip_tx_desc { - s32 status; - s32 length; - u32 buffer1; - u32 buffer2; /* We use only buffer 1. */ -}; - - -enum desc_status_bits { - DescOwned = 0x80000000, - RxDescFatalErr = 0x8000, - RxWholePkt = 0x0300, -}; - - -enum t21041_csr13_bits { - csr13_eng = (0xEF0<<4), /* for eng. purposes only, hardcode at EF0h */ - csr13_aui = (1<<3), /* clear to force 10bT, set to force AUI/BNC */ - csr13_cac = (1<<2), /* CSR13/14/15 autoconfiguration */ - csr13_srl = (1<<0), /* When reset, resets all SIA functions, machines */ - - csr13_mask_auibnc = (csr13_eng | csr13_aui | csr13_srl), - csr13_mask_10bt = (csr13_eng | csr13_srl), -}; - -enum t21143_csr6_bits { - csr6_sc = (1<<31), - csr6_ra = (1<<30), - csr6_ign_dest_msb = (1<<26), - csr6_mbo = (1<<25), - csr6_scr = (1<<24), /* scramble mode flag: can't be set */ - csr6_pcs = (1<<23), /* Enables PCS functions (symbol mode requires csr6_ps be set) default is set */ - csr6_ttm = (1<<22), /* Transmit Threshold Mode, set for 10baseT, 0 for 100BaseTX */ - csr6_sf = (1<<21), /* Store and forward. If set ignores TR bits */ - csr6_hbd = (1<<19), /* Heart beat disable. Disables SQE function in 10baseT */ - csr6_ps = (1<<18), /* Port Select. 0 (defualt) = 10baseT, 1 = 100baseTX: can't be set */ - csr6_ca = (1<<17), /* Collision Offset Enable. If set uses special algorithm in low collision situations */ - csr6_trh = (1<<15), /* Transmit Threshold high bit */ - csr6_trl = (1<<14), /* Transmit Threshold low bit */ - - /*************************************************************** - * This table shows transmit threshold values based on media * - * and these two registers (from PNIC1 & 2 docs) Note: this is * - * all meaningless if sf is set. * - ***************************************************************/ - - /*********************************** - * (trh,trl) * 100BaseTX * 10BaseT * - *********************************** - * (0,0) * 128 * 72 * - * (0,1) * 256 * 96 * - * (1,0) * 512 * 128 * - * (1,1) * 1024 * 160 * - ***********************************/ - - csr6_fc = (1<<12), /* Forces a collision in next transmission (for testing in loopback mode) */ - csr6_om_int_loop = (1<<10), /* internal (FIFO) loopback flag */ - csr6_om_ext_loop = (1<<11), /* external (PMD) loopback flag */ - /* set both and you get (PHY) loopback */ - csr6_fd = (1<<9), /* Full duplex mode, disables hearbeat, no loopback */ - csr6_pm = (1<<7), /* Pass All Multicast */ - csr6_pr = (1<<6), /* Promiscuous mode */ - csr6_sb = (1<<5), /* Start(1)/Stop(0) backoff counter */ - csr6_if = (1<<4), /* Inverse Filtering, rejects only addresses in address table: can't be set */ - csr6_pb = (1<<3), /* Pass Bad Frames, (1) causes even bad frames to be passed on */ - csr6_ho = (1<<2), /* Hash-only filtering mode: can't be set */ - csr6_hp = (1<<0), /* Hash/Perfect Receive Filtering Mode: can't be set */ - - csr6_mask_capture = (csr6_sc | csr6_ca), - csr6_mask_defstate = (csr6_mask_capture | csr6_mbo), - csr6_mask_hdcap = (csr6_mask_defstate | csr6_hbd | csr6_ps), - csr6_mask_hdcaptt = (csr6_mask_hdcap | csr6_trh | csr6_trl), - csr6_mask_fullcap = (csr6_mask_hdcaptt | csr6_fd), - csr6_mask_fullpromisc = (csr6_pr | csr6_pm), - csr6_mask_filters = (csr6_hp | csr6_ho | csr6_if), - csr6_mask_100bt = (csr6_scr | csr6_pcs | csr6_hbd), -}; - - -/* Keep the ring sizes a power of two for efficiency. - 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. */ -#undef TX_RING_SIZE -#undef RX_RING_SIZE -#define TX_RING_SIZE 16 -#define RX_RING_SIZE 32 - -#define MEDIA_MASK 31 - -#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer. */ - -#define TULIP_MIN_CACHE_LINE 8 /* in units of 32-bit words */ - -#if defined(__sparc__) || defined(__hppa__) -/* The UltraSparc PCI controllers will disconnect at every 64-byte - * crossing anyways so it makes no sense to tell Tulip to burst - * any more than that. - */ -#define TULIP_MAX_CACHE_LINE 16 /* in units of 32-bit words */ -#else -#define TULIP_MAX_CACHE_LINE 32 /* in units of 32-bit words */ -#endif - - -/* Ring-wrap flag in length field, use for last ring entry. - 0x01000000 means chain on buffer2 address, - 0x02000000 means use the ring start address in CSR2/3. - Note: Some work-alike chips do not function correctly in chained mode. - The ASIX chip works only in chained mode. - Thus we indicates ring mode, but always write the 'next' field for - chained mode as well. -*/ -#define DESC_RING_WRAP 0x02000000 - - -#define EEPROM_SIZE 128 /* 2 << EEPROM_ADDRLEN */ - - -#define RUN_AT(x) (jiffies + (x)) - -#if defined(__i386__) /* AKA get_unaligned() */ -#define get_u16(ptr) (*(u16 *)(ptr)) -#else -#define get_u16(ptr) (((u8*)(ptr))[0] + (((u8*)(ptr))[1]<<8)) -#endif - -struct medialeaf { - u8 type; - u8 media; - unsigned char *leafdata; -}; - - -struct mediatable { - u16 defaultmedia; - u8 leafcount; - u8 csr12dir; /* General purpose pin directions. */ - unsigned has_mii:1; - unsigned has_nonmii:1; - unsigned has_reset:6; - u32 csr15dir; - u32 csr15val; /* 21143 NWay setting. */ - struct medialeaf mleaf[0]; -}; - - -struct mediainfo { - struct mediainfo *next; - int info_type; - int index; - unsigned char *info; -}; - -struct ring_info { - struct sk_buff *skb; - dma_addr_t mapping; -}; - - -struct tulip_private { - const char *product_name; - struct net_device *next_module; - struct tulip_rx_desc *rx_ring; - struct tulip_tx_desc *tx_ring; - dma_addr_t rx_ring_dma; - dma_addr_t tx_ring_dma; - /* The saved address of a sent-in-place packet/buffer, for skfree(). */ - struct ring_info tx_buffers[TX_RING_SIZE]; - /* The addresses of receive-in-place skbuffs. */ - struct ring_info rx_buffers[RX_RING_SIZE]; - u16 setup_frame[96]; /* Pseudo-Tx frame to init address table. */ - int chip_id; - int revision; - int flags; - struct net_device_stats stats; - struct timer_list timer; /* Media selection timer. */ - u32 mc_filter[2]; - spinlock_t lock; - spinlock_t mii_lock; - unsigned int cur_rx, cur_tx; /* The next free ring entry */ - unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ - -#ifdef CONFIG_NET_HW_FLOWCONTROL -#define RX_A_NBF_STOP 0xffffff3f /* To disable RX and RX-NOBUF ints. */ - int fc_bit; - int mit_sel; - int mit_change; /* Signal for Interrupt Mitigtion */ -#endif - unsigned int full_duplex:1; /* Full-duplex operation requested. */ - unsigned int full_duplex_lock:1; - unsigned int fake_addr:1; /* Multiport board faked address. */ - unsigned int default_port:4; /* Last dev->if_port value. */ - unsigned int media2:4; /* Secondary monitored media port. */ - unsigned int medialock:1; /* Don't sense media type. */ - unsigned int mediasense:1; /* Media sensing in progress. */ - unsigned int nway:1, nwayset:1; /* 21143 internal NWay. */ - unsigned int csr0; /* CSR0 setting. */ - unsigned int csr6; /* Current CSR6 control settings. */ - unsigned char eeprom[EEPROM_SIZE]; /* Serial EEPROM contents. */ - void (*link_change) (struct net_device * dev, int csr5); - u16 sym_advertise, mii_advertise; /* NWay capabilities advertised. */ - u16 lpar; /* 21143 Link partner ability. */ - u16 advertising[4]; - signed char phys[4], mii_cnt; /* MII device addresses. */ - struct mediatable *mtable; - int cur_index; /* Current media index. */ - int saved_if_port; - struct pci_dev *pdev; - int ttimer; - int susp_rx; - unsigned long nir; - unsigned long base_addr; - int pad0, pad1; /* Used for 8-byte alignment */ -}; - - -struct eeprom_fixup { - char *name; - unsigned char addr0; - unsigned char addr1; - unsigned char addr2; - u16 newtable[32]; /* Max length below. */ -}; - - -/* 21142.c */ -extern u16 t21142_csr14[]; -void t21142_timer(unsigned long data); -void t21142_start_nway(struct net_device *dev); -void t21142_lnk_change(struct net_device *dev, int csr5); - - -/* PNIC2.c */ -void pnic2_lnk_change(struct net_device *dev, int csr5); -void pnic2_timer(unsigned long data); -void pnic2_start_nway(struct net_device *dev); -void pnic2_lnk_change(struct net_device *dev, int csr5); - -/* eeprom.c */ -void tulip_parse_eeprom(struct net_device *dev); -int tulip_read_eeprom(long ioaddr, int location, int addr_len); - -/* interrupt.c */ -extern unsigned int tulip_max_interrupt_work; -extern int tulip_rx_copybreak; -void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -int tulip_refill_rx(struct net_device *dev); - -/* media.c */ -int tulip_mdio_read(struct net_device *dev, int phy_id, int location); -void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int value); -void tulip_select_media(struct net_device *dev, int startup); -int tulip_check_duplex(struct net_device *dev); -void tulip_find_mii (struct net_device *dev, int board_idx); - -/* pnic.c */ -void pnic_do_nway(struct net_device *dev); -void pnic_lnk_change(struct net_device *dev, int csr5); -void pnic_timer(unsigned long data); - -/* timer.c */ -void tulip_timer(unsigned long data); -void mxic_timer(unsigned long data); -void comet_timer(unsigned long data); - -/* tulip_core.c */ -extern int tulip_debug; -extern const char * const medianame[]; -extern const char tulip_media_cap[]; -extern struct tulip_chip_table tulip_tbl[]; -extern u8 t21040_csr13[]; -extern u16 t21041_csr13[]; -extern u16 t21041_csr14[]; -extern u16 t21041_csr15[]; - -#ifndef USE_IO_OPS -#undef inb -#undef inw -#undef inl -#undef outb -#undef outw -#undef outl -#define inb(addr) readb((void*)(addr)) -#define inw(addr) readw((void*)(addr)) -#define inl(addr) readl((void*)(addr)) -#define outb(val,addr) writeb((val), (void*)(addr)) -#define outw(val,addr) writew((val), (void*)(addr)) -#define outl(val,addr) writel((val), (void*)(addr)) -#endif /* !USE_IO_OPS */ - - - -static inline void tulip_start_rxtx(struct tulip_private *tp) -{ - long ioaddr = tp->base_addr; - outl(tp->csr6 | RxTx, ioaddr + CSR6); - barrier(); - (void) inl(ioaddr + CSR6); /* mmio sync */ -} - -static inline void tulip_stop_rxtx(struct tulip_private *tp) -{ - long ioaddr = tp->base_addr; - u32 csr6 = inl(ioaddr + CSR6); - - if (csr6 & RxTx) { - outl(csr6 & ~RxTx, ioaddr + CSR6); - barrier(); - (void) inl(ioaddr + CSR6); /* mmio sync */ - } -} - -static inline void tulip_restart_rxtx(struct tulip_private *tp) -{ - tulip_stop_rxtx(tp); - udelay(5); - tulip_start_rxtx(tp); -} - -#endif /* __NET_TULIP_H__ */ diff --git a/xen-2.4.16/drivers/net/tulip/tulip_core.c b/xen-2.4.16/drivers/net/tulip/tulip_core.c deleted file mode 100644 index f2a8c5f331..0000000000 --- a/xen-2.4.16/drivers/net/tulip/tulip_core.c +++ /dev/null @@ -1,1925 +0,0 @@ -/* tulip_core.c: A DEC 21x4x-family ethernet driver for Linux. */ - -/* - Maintained by Jeff Garzik <jgarzik@mandrakesoft.com> - Copyright 2000,2001 The Linux Kernel Team - Written/copyright 1994-2001 by Donald Becker. - - This software may be used and distributed according to the terms - of the GNU General Public License, incorporated herein by reference. - - Please refer to Documentation/DocBook/tulip.{pdf,ps,html} - for more information on this driver, or visit the project - Web page at http://sourceforge.net/projects/tulip/ - -*/ - -#define DRV_NAME "tulip" -#define DRV_VERSION "0.9.15-pre9" -#define DRV_RELDATE "Nov 6, 2001" - -#include <linux/config.h> -#include <linux/module.h> -#include "tulip.h" -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/etherdevice.h> -#include <linux/delay.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include <asm/unaligned.h> -#include <asm/uaccess.h> - -#ifdef __sparc__ -#include <asm/pbm.h> -#endif - -static char version[] __devinitdata = - "Linux Tulip driver version " DRV_VERSION " (" DRV_RELDATE ")\n"; - - -/* A few user-configurable values. */ - -/* Maximum events (Rx packets, etc.) to handle at each interrupt. */ -static unsigned int max_interrupt_work = 25; - -#define MAX_UNITS 8 -/* Used to pass the full-duplex flag, etc. */ -static int full_duplex[MAX_UNITS]; -static int options[MAX_UNITS]; -static int mtu[MAX_UNITS]; /* Jumbo MTU for interfaces. */ - -/* The possible media types that can be set in options[] are: */ -const char * const medianame[32] = { - "10baseT", "10base2", "AUI", "100baseTx", - "10baseT-FDX", "100baseTx-FDX", "100baseT4", "100baseFx", - "100baseFx-FDX", "MII 10baseT", "MII 10baseT-FDX", "MII", - "10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FDX", "MII 100baseT4", - "MII 100baseFx-HDX", "MII 100baseFx-FDX", "Home-PNA 1Mbps", "Invalid-19", - "","","","", "","","","", "","","","Transceiver reset", -}; - -/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */ -/*#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \ - || defined(__sparc_) || defined(__ia64__) \ - || defined(__sh__) || defined(__mips__) -static int rx_copybreak = 1518; -#else -static int rx_copybreak = 100; -#endif -*/ -/* Xen doesn't do rx_copybreak in drivers. */ -static int rx_copybreak = 0; - -/* - Set the bus performance register. - Typical: Set 16 longword cache alignment, no burst limit. - Cache alignment bits 15:14 Burst length 13:8 - 0000 No alignment 0x00000000 unlimited 0800 8 longwords - 4000 8 longwords 0100 1 longword 1000 16 longwords - 8000 16 longwords 0200 2 longwords 2000 32 longwords - C000 32 longwords 0400 4 longwords - Warning: many older 486 systems are broken and require setting 0x00A04800 - 8 longword cache alignment, 8 longword burst. - ToDo: Non-Intel setting could be better. -*/ - -#if defined(__alpha__) || defined(__ia64__) || defined(__x86_64__) -static int csr0 = 0x01A00000 | 0xE000; -#elif defined(__i386__) || defined(__powerpc__) -static int csr0 = 0x01A00000 | 0x8000; -#elif defined(__sparc__) || defined(__hppa__) -/* The UltraSparc PCI controllers will disconnect at every 64-byte - * crossing anyways so it makes no sense to tell Tulip to burst - * any more than that. - */ -static int csr0 = 0x01A00000 | 0x9000; -#elif defined(__arm__) || defined(__sh__) -static int csr0 = 0x01A00000 | 0x4800; -#else -#warning Processor architecture undefined! -static int csr0 = 0x00A00000 | 0x4800; -#endif - -/* Operational parameters that usually are not changed. */ -/* Time in jiffies before concluding the transmitter is hung. */ -#define TX_TIMEOUT (4*HZ) - - -MODULE_AUTHOR("The Linux Kernel Team"); -MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver"); -MODULE_LICENSE("GPL"); -MODULE_PARM(tulip_debug, "i"); -MODULE_PARM(max_interrupt_work, "i"); -MODULE_PARM(rx_copybreak, "i"); -MODULE_PARM(csr0, "i"); -MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); -MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); - -#define PFX DRV_NAME ": " - -#ifdef TULIP_DEBUG -int tulip_debug = TULIP_DEBUG; -#else -int tulip_debug = 1; -#endif - - - -/* - * This table use during operation for capabilities and media timer. - * - * It is indexed via the values in 'enum chips' - */ - -struct tulip_chip_table tulip_tbl[] = { - /* DC21040 */ - { "Digital DC21040 Tulip", 128, 0x0001ebef, 0, tulip_timer }, - - /* DC21041 */ - { "Digital DC21041 Tulip", 128, 0x0001ebef, - HAS_MEDIA_TABLE | HAS_NWAY, tulip_timer }, - - /* DC21140 */ - { "Digital DS21140 Tulip", 128, 0x0001ebef, - HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer }, - - /* DC21142, DC21143 */ - { "Digital DS21143 Tulip", 128, 0x0801fbff, - HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY - | HAS_INTR_MITIGATION | HAS_PCI_MWI, t21142_timer }, - - /* LC82C168 */ - { "Lite-On 82c168 PNIC", 256, 0x0001fbef, - HAS_MII | HAS_PNICNWAY, pnic_timer }, - - /* MX98713 */ - { "Macronix 98713 PMAC", 128, 0x0001ebef, - HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer }, - - /* MX98715 */ - { "Macronix 98715 PMAC", 256, 0x0001ebef, - HAS_MEDIA_TABLE, mxic_timer }, - - /* MX98725 */ - { "Macronix 98725 PMAC", 256, 0x0001ebef, - HAS_MEDIA_TABLE, mxic_timer }, - - /* AX88140 */ - { "ASIX AX88140", 128, 0x0001fbff, - HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY - | IS_ASIX, tulip_timer }, - - /* PNIC2 */ - { "Lite-On PNIC-II", 256, 0x0801fbff, - HAS_MII | HAS_NWAY | HAS_8023X | HAS_PCI_MWI, pnic2_timer }, - - /* COMET */ - { "ADMtek Comet", 256, 0x0001abef, - MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer }, - - /* COMPEX9881 */ - { "Compex 9881 PMAC", 128, 0x0001ebef, - HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer }, - - /* I21145 */ - { "Intel DS21145 Tulip", 128, 0x0801fbff, - HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI - | HAS_NWAY | HAS_PCI_MWI, t21142_timer }, - - /* DM910X */ - { "Davicom DM9102/DM9102A", 128, 0x0001ebef, - HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI, - tulip_timer }, -}; - - -static struct pci_device_id tulip_pci_tbl[] __devinitdata = { - { 0x1011, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21040 }, - { 0x1011, 0x0014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21041 }, - { 0x1011, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21140 }, - { 0x1011, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21143 }, - { 0x11AD, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, LC82C168 }, - { 0x10d9, 0x0512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98713 }, - { 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, -/* { 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98725 },*/ - { 0x125B, 0x1400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AX88140 }, - { 0x11AD, 0xc115, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PNIC2 }, - { 0x1317, 0x0981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, - { 0x1317, 0x0985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, - { 0x1317, 0x1985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, - { 0x13D1, 0xAB02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, - { 0x13D1, 0xAB03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, - { 0x104A, 0x0981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, - { 0x104A, 0x2774, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, - { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 }, - { 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 }, - { 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, - { 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, - { 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, - { 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, - { 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, - { } /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci, tulip_pci_tbl); - - -/* A full-duplex map for media types. */ -const char tulip_media_cap[32] = -{0,0,0,16, 3,19,16,24, 27,4,7,5, 0,20,23,20, 28,31,0,0, }; -u8 t21040_csr13[] = {2,0x0C,8,4, 4,0,0,0, 0,0,0,0, 4,0,0,0}; - -/* 21041 transceiver register settings: 10-T, 10-2, AUI, 10-T, 10T-FD*/ -u16 t21041_csr13[] = { - csr13_mask_10bt, /* 10-T */ - csr13_mask_auibnc, /* 10-2 */ - csr13_mask_auibnc, /* AUI */ - csr13_mask_10bt, /* 10-T */ - csr13_mask_10bt, /* 10T-FD */ -}; -u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, }; -u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; - - -static void tulip_tx_timeout(struct net_device *dev); -static void tulip_init_ring(struct net_device *dev); -static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev); -static int tulip_open(struct net_device *dev); -static int tulip_close(struct net_device *dev); -static void tulip_up(struct net_device *dev); -static void tulip_down(struct net_device *dev); -static struct net_device_stats *tulip_get_stats(struct net_device *dev); -static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static void set_rx_mode(struct net_device *dev); - - - -static void tulip_set_power_state (struct tulip_private *tp, - int sleep, int snooze) -{ - if (tp->flags & HAS_ACPI) { - u32 tmp, newtmp; - pci_read_config_dword (tp->pdev, CFDD, &tmp); - newtmp = tmp & ~(CFDD_Sleep | CFDD_Snooze); - if (sleep) - newtmp |= CFDD_Sleep; - else if (snooze) - newtmp |= CFDD_Snooze; - if (tmp != newtmp) - pci_write_config_dword (tp->pdev, CFDD, newtmp); - } - -} - - -static void tulip_up(struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - int next_tick = 3*HZ; - int i; - - /* Wake the chip from sleep/snooze mode. */ - tulip_set_power_state (tp, 0, 0); - - /* On some chip revs we must set the MII/SYM port before the reset!? */ - if (tp->mii_cnt || (tp->mtable && tp->mtable->has_mii)) - outl(0x00040000, ioaddr + CSR6); - - /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */ - outl(0x00000001, ioaddr + CSR0); - udelay(100); - - /* Deassert reset. - Wait the specified 50 PCI cycles after a reset by initializing - Tx and Rx queues and the address filter list. */ - outl(tp->csr0, ioaddr + CSR0); - udelay(100); - - if (tulip_debug > 1) - printk(KERN_DEBUG "%s: tulip_up(), irq==%d.\n", dev->name, dev->irq); - - outl(tp->rx_ring_dma, ioaddr + CSR3); - outl(tp->tx_ring_dma, ioaddr + CSR4); - tp->cur_rx = tp->cur_tx = 0; - tp->dirty_rx = tp->dirty_tx = 0; - - if (tp->flags & MC_HASH_ONLY) { - u32 addr_low = cpu_to_le32(get_unaligned((u32 *)dev->dev_addr)); - u32 addr_high = cpu_to_le32(get_unaligned((u16 *)(dev->dev_addr+4))); - if (tp->chip_id == AX88140) { - outl(0, ioaddr + CSR13); - outl(addr_low, ioaddr + CSR14); - outl(1, ioaddr + CSR13); - outl(addr_high, ioaddr + CSR14); - } else if (tp->flags & COMET_MAC_ADDR) { - outl(addr_low, ioaddr + 0xA4); - outl(addr_high, ioaddr + 0xA8); - outl(0, ioaddr + 0xAC); - outl(0, ioaddr + 0xB0); - } - } else { - /* This is set_rx_mode(), but without starting the transmitter. */ - u16 *eaddrs = (u16 *)dev->dev_addr; - u16 *setup_frm = &tp->setup_frame[15*6]; - dma_addr_t mapping; - - /* 21140 bug: you must add the broadcast address. */ - memset(tp->setup_frame, 0xff, sizeof(tp->setup_frame)); - /* Fill the final entry of the table with our physical address. */ - *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; - *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; - *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; - - mapping = pci_map_single(tp->pdev, tp->setup_frame, - sizeof(tp->setup_frame), - PCI_DMA_TODEVICE); - tp->tx_buffers[tp->cur_tx].skb = NULL; - tp->tx_buffers[tp->cur_tx].mapping = mapping; - - /* Put the setup frame on the Tx list. */ - tp->tx_ring[tp->cur_tx].length = cpu_to_le32(0x08000000 | 192); - tp->tx_ring[tp->cur_tx].buffer1 = cpu_to_le32(mapping); - tp->tx_ring[tp->cur_tx].status = cpu_to_le32(DescOwned); - - tp->cur_tx++; - } - - tp->saved_if_port = dev->if_port; - if (dev->if_port == 0) - dev->if_port = tp->default_port; - - /* Allow selecting a default media. */ - i = 0; - if (tp->mtable == NULL) - goto media_picked; - if (dev->if_port) { - int looking_for = tulip_media_cap[dev->if_port] & MediaIsMII ? 11 : - (dev->if_port == 12 ? 0 : dev->if_port); - for (i = 0; i < tp->mtable->leafcount; i++) - if (tp->mtable->mleaf[i].media == looking_for) { - printk(KERN_INFO "%s: Using user-specified media %s.\n", - dev->name, medianame[dev->if_port]); - goto media_picked; - } - } - if ((tp->mtable->defaultmedia & 0x0800) == 0) { - int looking_for = tp->mtable->defaultmedia & MEDIA_MASK; - for (i = 0; i < tp->mtable->leafcount; i++) - if (tp->mtable->mleaf[i].media == looking_for) { - printk(KERN_INFO "%s: Using EEPROM-set media %s.\n", - dev->name, medianame[looking_for]); - goto media_picked; - } - } - /* Start sensing first non-full-duplex media. */ - for (i = tp->mtable->leafcount - 1; - (tulip_media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--) - ; -media_picked: - - tp->csr6 = 0; - tp->cur_index = i; - tp->nwayset = 0; - - if (dev->if_port) { - if (tp->chip_id == DC21143 && - (tulip_media_cap[dev->if_port] & MediaIsMII)) { - /* We must reset the media CSRs when we force-select MII mode. */ - outl(0x0000, ioaddr + CSR13); - outl(0x0000, ioaddr + CSR14); - outl(0x0008, ioaddr + CSR15); - } - tulip_select_media(dev, 1); - } else if (tp->chip_id == DC21041) { - dev->if_port = 0; - tp->nway = tp->mediasense = 1; - tp->nwayset = tp->lpar = 0; - outl(0x00000000, ioaddr + CSR13); - outl(0xFFFFFFFF, ioaddr + CSR14); - outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */ - tp->csr6 = 0x80020000; - if (tp->sym_advertise & 0x0040) - tp->csr6 |= FullDuplex; - outl(tp->csr6, ioaddr + CSR6); - outl(0x0000EF01, ioaddr + CSR13); - - } else if (tp->chip_id == DC21142) { - if (tp->mii_cnt) { - tulip_select_media(dev, 1); - if (tulip_debug > 1) - printk(KERN_INFO "%s: Using MII transceiver %d, status " - "%4.4x.\n", - dev->name, tp->phys[0], tulip_mdio_read(dev, tp->phys[0], 1)); - outl(csr6_mask_defstate, ioaddr + CSR6); - tp->csr6 = csr6_mask_hdcap; - dev->if_port = 11; - outl(0x0000, ioaddr + CSR13); - outl(0x0000, ioaddr + CSR14); - } else - t21142_start_nway(dev); - } else if (tp->chip_id == PNIC2) { - /* for initial startup advertise 10/100 Full and Half */ - tp->sym_advertise = 0x01E0; - /* enable autonegotiate end interrupt */ - outl(inl(ioaddr+CSR5)| 0x00008010, ioaddr + CSR5); - outl(inl(ioaddr+CSR7)| 0x00008010, ioaddr + CSR7); - pnic2_start_nway(dev); - } else if (tp->chip_id == LC82C168 && ! tp->medialock) { - if (tp->mii_cnt) { - dev->if_port = 11; - tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0); - outl(0x0001, ioaddr + CSR15); - } else if (inl(ioaddr + CSR5) & TPLnkPass) - pnic_do_nway(dev); - else { - /* Start with 10mbps to do autonegotiation. */ - outl(0x32, ioaddr + CSR12); - tp->csr6 = 0x00420000; - outl(0x0001B078, ioaddr + 0xB8); - outl(0x0201B078, ioaddr + 0xB8); - next_tick = 1*HZ; - } - } else if ((tp->chip_id == MX98713 || tp->chip_id == COMPEX9881) - && ! tp->medialock) { - dev->if_port = 0; - tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0); - outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); - } else if (tp->chip_id == MX98715 || tp->chip_id == MX98725) { - /* Provided by BOLO, Macronix - 12/10/1998. */ - dev->if_port = 0; - tp->csr6 = 0x01a80200; - outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); - outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0); - } else if (tp->chip_id == COMET) { - /* Enable automatic Tx underrun recovery. */ - outl(inl(ioaddr + 0x88) | 1, ioaddr + 0x88); - dev->if_port = tp->mii_cnt ? 11 : 0; - tp->csr6 = 0x00040000; - } else if (tp->chip_id == AX88140) { - tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100; - } else - tulip_select_media(dev, 1); - - /* Start the chip's Tx to process setup frame. */ - tulip_stop_rxtx(tp); - barrier(); - udelay(5); - outl(tp->csr6 | TxOn, ioaddr + CSR6); - - /* Enable interrupts by setting the interrupt mask. */ - outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5); - outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7); - tulip_start_rxtx(tp); - outl(0, ioaddr + CSR2); /* Rx poll demand */ - - if (tulip_debug > 2) { - printk(KERN_DEBUG "%s: Done tulip_up(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n", - dev->name, inl(ioaddr + CSR0), inl(ioaddr + CSR5), - inl(ioaddr + CSR6)); - } - - /* Set the timer to switch to check for link beat and perhaps switch - to an alternate media type. */ - tp->timer.expires = RUN_AT(next_tick); - add_timer(&tp->timer); -} - -#ifdef CONFIG_NET_HW_FLOWCONTROL -/* Enable receiver */ -void tulip_xon(struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - - clear_bit(tp->fc_bit, &netdev_fc_xoff); - if (netif_running(dev)){ - - tulip_refill_rx(dev); - outl(tulip_tbl[tp->chip_id].valid_intrs, dev->base_addr+CSR7); - } -} -#endif - -static int -tulip_open(struct net_device *dev) -{ -#ifdef CONFIG_NET_HW_FLOWCONTROL - struct tulip_private *tp = (struct tulip_private *)dev->priv; -#endif - int retval; - MOD_INC_USE_COUNT; - - if ((retval = request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev))) { - MOD_DEC_USE_COUNT; - return retval; - } - - tulip_init_ring (dev); - - tulip_up (dev); - -#ifdef CONFIG_NET_HW_FLOWCONTROL - tp->fc_bit = netdev_register_fc(dev, tulip_xon); -#endif - - netif_start_queue (dev); - - return 0; -} - - -static void tulip_tx_timeout(struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - unsigned long flags; - - spin_lock_irqsave (&tp->lock, flags); - - if (tulip_media_cap[dev->if_port] & MediaIsMII) { - /* Do nothing -- the media monitor should handle this. */ - if (tulip_debug > 1) - printk(KERN_WARNING "%s: Transmit timeout using MII device.\n", - dev->name); - } else if (tp->chip_id == DC21040) { - if ( !tp->medialock && inl(ioaddr + CSR12) & 0x0002) { - dev->if_port = (dev->if_port == 2 ? 0 : 2); - printk(KERN_INFO "%s: 21040 transmit timed out, switching to " - "%s.\n", - dev->name, medianame[dev->if_port]); - tulip_select_media(dev, 0); - } - goto out; - } else if (tp->chip_id == DC21041) { - int csr12 = inl(ioaddr + CSR12); - - printk(KERN_WARNING "%s: 21041 transmit timed out, status %8.8x, " - "CSR12 %8.8x, CSR13 %8.8x, CSR14 %8.8x, resetting...\n", - dev->name, inl(ioaddr + CSR5), csr12, - inl(ioaddr + CSR13), inl(ioaddr + CSR14)); - tp->mediasense = 1; - if ( ! tp->medialock) { - if (dev->if_port == 1 || dev->if_port == 2) - if (csr12 & 0x0004) { - dev->if_port = 2 - dev->if_port; - } else - dev->if_port = 0; - else - dev->if_port = 1; - tulip_select_media(dev, 0); - } - } else if (tp->chip_id == DC21140 || tp->chip_id == DC21142 - || tp->chip_id == MX98713 || tp->chip_id == COMPEX9881 - || tp->chip_id == DM910X) { - printk(KERN_WARNING "%s: 21140 transmit timed out, status %8.8x, " - "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n", - dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR12), - inl(ioaddr + CSR13), inl(ioaddr + CSR14), inl(ioaddr + CSR15)); - if ( ! tp->medialock && tp->mtable) { - do - --tp->cur_index; - while (tp->cur_index >= 0 - && (tulip_media_cap[tp->mtable->mleaf[tp->cur_index].media] - & MediaIsFD)); - if (--tp->cur_index < 0) { - /* We start again, but should instead look for default. */ - tp->cur_index = tp->mtable->leafcount - 1; - } - tulip_select_media(dev, 0); - printk(KERN_WARNING "%s: transmit timed out, switching to %s " - "media.\n", dev->name, medianame[dev->if_port]); - } - } else if (tp->chip_id == PNIC2) { - printk(KERN_WARNING "%s: PNIC2 transmit timed out, status %8.8x, " - "CSR6/7 %8.8x / %8.8x CSR12 %8.8x, resetting...\n", - dev->name, (int)inl(ioaddr + CSR5), (int)inl(ioaddr + CSR6), - (int)inl(ioaddr + CSR7), (int)inl(ioaddr + CSR12)); - } else { - printk(KERN_WARNING "%s: Transmit timed out, status %8.8x, CSR12 " - "%8.8x, resetting...\n", - dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR12)); - dev->if_port = 0; - } - -#if defined(way_too_many_messages) - if (tulip_debug > 3) { - int i; - for (i = 0; i < RX_RING_SIZE; i++) { - u8 *buf = (u8 *)(tp->rx_ring[i].buffer1); - int j; - printk(KERN_DEBUG "%2d: %8.8x %8.8x %8.8x %8.8x " - "%2.2x %2.2x %2.2x.\n", - i, (unsigned int)tp->rx_ring[i].status, - (unsigned int)tp->rx_ring[i].length, - (unsigned int)tp->rx_ring[i].buffer1, - (unsigned int)tp->rx_ring[i].buffer2, - buf[0], buf[1], buf[2]); - for (j = 0; buf[j] != 0xee && j < 1600; j++) - if (j < 100) printk(" %2.2x", buf[j]); - printk(" j=%d.\n", j); - } - printk(KERN_DEBUG " Rx ring %8.8x: ", (int)tp->rx_ring); - for (i = 0; i < RX_RING_SIZE; i++) - printk(" %8.8x", (unsigned int)tp->rx_ring[i].status); - printk("\n" KERN_DEBUG " Tx ring %8.8x: ", (int)tp->tx_ring); - for (i = 0; i < TX_RING_SIZE; i++) - printk(" %8.8x", (unsigned int)tp->tx_ring[i].status); - printk("\n"); - } -#endif - - /* Stop and restart the chip's Tx processes . */ -#ifdef CONFIG_NET_HW_FLOWCONTROL - if (tp->fc_bit && test_bit(tp->fc_bit,&netdev_fc_xoff)) - printk("BUG tx_timeout restarting rx when fc on\n"); -#endif - tulip_restart_rxtx(tp); - /* Trigger an immediate transmit demand. */ - outl(0, ioaddr + CSR1); - - tp->stats.tx_errors++; - -out: - spin_unlock_irqrestore (&tp->lock, flags); - dev->trans_start = jiffies; - netif_wake_queue (dev); -} - - -/* Initialize the Rx and Tx rings, along with various 'dev' bits. */ -static void tulip_init_ring(struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - int i; - - tp->susp_rx = 0; - tp->ttimer = 0; - tp->nir = 0; - - for (i = 0; i < RX_RING_SIZE; i++) { - tp->rx_ring[i].status = 0x00000000; - tp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ); - tp->rx_ring[i].buffer2 = cpu_to_le32(tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * (i + 1)); - tp->rx_buffers[i].skb = NULL; - tp->rx_buffers[i].mapping = 0; - } - /* Mark the last entry as wrapping the ring. */ - tp->rx_ring[i-1].length = cpu_to_le32(PKT_BUF_SZ | DESC_RING_WRAP); - tp->rx_ring[i-1].buffer2 = cpu_to_le32(tp->rx_ring_dma); - - for (i = 0; i < RX_RING_SIZE; i++) { - dma_addr_t mapping; - - /* Note the receive buffer must be longword aligned. - dev_alloc_skb() provides 16 byte alignment. But do *not* - use skb_reserve() to align the IP header! */ - struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ); - tp->rx_buffers[i].skb = skb; - if (skb == NULL) - break; - mapping = pci_map_single(tp->pdev, skb->tail, - PKT_BUF_SZ, PCI_DMA_FROMDEVICE); - tp->rx_buffers[i].mapping = mapping; - skb->dev = dev; /* Mark as being used by this device. */ - tp->rx_ring[i].status = cpu_to_le32(DescOwned); /* Owned by Tulip chip */ - tp->rx_ring[i].buffer1 = cpu_to_le32(mapping); - } - tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); - - /* The Tx buffer descriptor is filled in as needed, but we - do need to clear the ownership bit. */ - for (i = 0; i < TX_RING_SIZE; i++) { - tp->tx_buffers[i].skb = NULL; - tp->tx_buffers[i].mapping = 0; - tp->tx_ring[i].status = 0x00000000; - tp->tx_ring[i].buffer2 = cpu_to_le32(tp->tx_ring_dma + sizeof(struct tulip_tx_desc) * (i + 1)); - } - tp->tx_ring[i-1].buffer2 = cpu_to_le32(tp->tx_ring_dma); -} - -static int -tulip_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - int entry; - u32 flag; - dma_addr_t mapping; - - spin_lock_irq(&tp->lock); - - /* Calculate the next Tx descriptor entry. */ - entry = tp->cur_tx % TX_RING_SIZE; - - tp->tx_buffers[entry].skb = skb; - mapping = pci_map_single(tp->pdev, skb->data, - skb->len, PCI_DMA_TODEVICE); - tp->tx_buffers[entry].mapping = mapping; - tp->tx_ring[entry].buffer1 = cpu_to_le32(mapping); - - if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE/2) {/* Typical path */ - flag = 0x60000000; /* No interrupt */ - } else if (tp->cur_tx - tp->dirty_tx == TX_RING_SIZE/2) { - flag = 0xe0000000; /* Tx-done intr. */ - } else if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE - 2) { - flag = 0x60000000; /* No Tx-done intr. */ - } else { /* Leave room for set_rx_mode() to fill entries. */ - flag = 0xe0000000; /* Tx-done intr. */ - netif_stop_queue(dev); - } - if (entry == TX_RING_SIZE-1) - flag = 0xe0000000 | DESC_RING_WRAP; - - tp->tx_ring[entry].length = cpu_to_le32(skb->len | flag); - /* if we were using Transmit Automatic Polling, we would need a - * wmb() here. */ - tp->tx_ring[entry].status = cpu_to_le32(DescOwned); - wmb(); - - tp->cur_tx++; - - /* Trigger an immediate transmit demand. */ - outl(0, dev->base_addr + CSR1); - - spin_unlock_irq(&tp->lock); - - dev->trans_start = jiffies; - - return 0; -} - -static void tulip_clean_tx_ring(struct tulip_private *tp) -{ - unsigned int dirty_tx; - - for (dirty_tx = tp->dirty_tx ; tp->cur_tx - dirty_tx > 0; - dirty_tx++) { - int entry = dirty_tx % TX_RING_SIZE; - int status = le32_to_cpu(tp->tx_ring[entry].status); - - if (status < 0) { - tp->stats.tx_errors++; /* It wasn't Txed */ - tp->tx_ring[entry].status = 0; - } - - /* Check for Tx filter setup frames. */ - if (tp->tx_buffers[entry].skb == NULL) { - /* test because dummy frames not mapped */ - if (tp->tx_buffers[entry].mapping) - pci_unmap_single(tp->pdev, - tp->tx_buffers[entry].mapping, - sizeof(tp->setup_frame), - PCI_DMA_TODEVICE); - continue; - } - - pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping, - tp->tx_buffers[entry].skb->len, - PCI_DMA_TODEVICE); - - /* Free the original skb. */ - dev_kfree_skb_irq(tp->tx_buffers[entry].skb); - tp->tx_buffers[entry].skb = NULL; - tp->tx_buffers[entry].mapping = 0; - } -} - -static void tulip_down (struct net_device *dev) -{ - long ioaddr = dev->base_addr; - struct tulip_private *tp = (struct tulip_private *) dev->priv; - unsigned long flags; - - del_timer_sync (&tp->timer); - - spin_lock_irqsave (&tp->lock, flags); - - /* Disable interrupts by clearing the interrupt mask. */ - outl (0x00000000, ioaddr + CSR7); - - /* Stop the Tx and Rx processes. */ - tulip_stop_rxtx(tp); - - /* prepare receive buffers */ - tulip_refill_rx(dev); - - /* release any unconsumed transmit buffers */ - tulip_clean_tx_ring(tp); - - /* 21040 -- Leave the card in 10baseT state. */ - if (tp->chip_id == DC21040) - outl (0x00000004, ioaddr + CSR13); - - if (inl (ioaddr + CSR6) != 0xffffffff) - tp->stats.rx_missed_errors += inl (ioaddr + CSR8) & 0xffff; - - spin_unlock_irqrestore (&tp->lock, flags); - - init_timer(&tp->timer); - tp->timer.data = (unsigned long)dev; - tp->timer.function = tulip_tbl[tp->chip_id].media_timer; - - dev->if_port = tp->saved_if_port; - - /* Leave the driver in snooze, not sleep, mode. */ - tulip_set_power_state (tp, 0, 1); -} - - -static int tulip_close (struct net_device *dev) -{ - long ioaddr = dev->base_addr; - struct tulip_private *tp = (struct tulip_private *) dev->priv; - int i; - - netif_stop_queue (dev); - -#ifdef CONFIG_NET_HW_FLOWCONTROL - if (tp->fc_bit) { - int bit = tp->fc_bit; - tp->fc_bit = 0; - netdev_unregister_fc(bit); - } -#endif - tulip_down (dev); - - if (tulip_debug > 1) - printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", - dev->name, inl (ioaddr + CSR5)); - - free_irq (dev->irq, dev); - - /* Free all the skbuffs in the Rx queue. */ - for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = tp->rx_buffers[i].skb; - dma_addr_t mapping = tp->rx_buffers[i].mapping; - - tp->rx_buffers[i].skb = NULL; - tp->rx_buffers[i].mapping = 0; - - tp->rx_ring[i].status = 0; /* Not owned by Tulip chip. */ - tp->rx_ring[i].length = 0; - tp->rx_ring[i].buffer1 = 0xBADF00D0; /* An invalid address. */ - if (skb) { - pci_unmap_single(tp->pdev, mapping, PKT_BUF_SZ, - PCI_DMA_FROMDEVICE); - dev_kfree_skb (skb); - } - } - for (i = 0; i < TX_RING_SIZE; i++) { - struct sk_buff *skb = tp->tx_buffers[i].skb; - - if (skb != NULL) { - pci_unmap_single(tp->pdev, tp->tx_buffers[i].mapping, - skb->len, PCI_DMA_TODEVICE); - dev_kfree_skb (skb); - } - tp->tx_buffers[i].skb = NULL; - tp->tx_buffers[i].mapping = 0; - } - - MOD_DEC_USE_COUNT; - - return 0; -} - -static struct net_device_stats *tulip_get_stats(struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - - if (netif_running(dev)) { - unsigned long flags; - - spin_lock_irqsave (&tp->lock, flags); - - tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff; - - spin_unlock_irqrestore(&tp->lock, flags); - } - - return &tp->stats; -} - - -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) -{ - struct tulip_private *np = dev->priv; - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strcpy(info.driver, DRV_NAME); - strcpy(info.version, DRV_VERSION); - strcpy(info.bus_info, np->pdev->slot_name); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - - } - - return -EOPNOTSUPP; -} - -/* Provide ioctl() calls to examine the MII xcvr state. */ -static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct tulip_private *tp = dev->priv; - long ioaddr = dev->base_addr; - struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data; - const unsigned int phy_idx = 0; - int phy = tp->phys[phy_idx] & 0x1f; - unsigned int regnum = data->reg_num; - - switch (cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ - if (tp->mii_cnt) - data->phy_id = phy; - else if (tp->flags & HAS_NWAY) - data->phy_id = 32; - else if (tp->chip_id == COMET) - data->phy_id = 1; - else - return -ENODEV; - - case SIOCGMIIREG: /* Read MII PHY register. */ - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ - if (data->phy_id == 32 && (tp->flags & HAS_NWAY)) { - int csr12 = inl (ioaddr + CSR12); - int csr14 = inl (ioaddr + CSR14); - switch (regnum) { - case 0: - if (((csr14<<5) & 0x1000) || - (dev->if_port == 5 && tp->nwayset)) - data->val_out = 0x1000; - else - data->val_out = (tulip_media_cap[dev->if_port]&MediaIs100 ? 0x2000 : 0) - | (tulip_media_cap[dev->if_port]&MediaIsFD ? 0x0100 : 0); - break; - case 1: - data->val_out = - 0x1848 + - ((csr12&0x7000) == 0x5000 ? 0x20 : 0) + - ((csr12&0x06) == 6 ? 0 : 4); - if (tp->chip_id != DC21041) - data->val_out |= 0x6048; - break; - case 4: - /* Advertised value, bogus 10baseTx-FD value from CSR6. */ - data->val_out = - ((inl(ioaddr + CSR6) >> 3) & 0x0040) + - ((csr14 >> 1) & 0x20) + 1; - if (tp->chip_id != DC21041) - data->val_out |= ((csr14 >> 9) & 0x03C0); - break; - case 5: data->val_out = tp->lpar; break; - default: data->val_out = 0; break; - } - } else { - data->val_out = tulip_mdio_read (dev, data->phy_id & 0x1f, regnum); - } - return 0; - - case SIOCSMIIREG: /* Write MII PHY register. */ - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ - if (!capable (CAP_NET_ADMIN)) - return -EPERM; - if (regnum & ~0x1f) - return -EINVAL; - if (data->phy_id == phy) { - u16 value = data->val_in; - switch (regnum) { - case 0: /* Check for autonegotiation on or reset. */ - tp->full_duplex_lock = (value & 0x9000) ? 0 : 1; - if (tp->full_duplex_lock) - tp->full_duplex = (value & 0x0100) ? 1 : 0; - break; - case 4: - tp->advertising[phy_idx] = - tp->mii_advertise = data->val_in; - break; - } - } - if (data->phy_id == 32 && (tp->flags & HAS_NWAY)) { - u16 value = data->val_in; - if (regnum == 0) { - if ((value & 0x1200) == 0x1200) { - if (tp->chip_id == PNIC2) { - pnic2_start_nway (dev); - } else { - t21142_start_nway (dev); - } - } - } else if (regnum == 4) - tp->sym_advertise = value; - } else { - tulip_mdio_write (dev, data->phy_id & 0x1f, regnum, data->val_in); - } - return 0; - default: - return -EOPNOTSUPP; - } - - return -EOPNOTSUPP; -} - - -/* Set or clear the multicast filter for this adaptor. - Note that we only use exclusion around actually queueing the - new frame, not around filling tp->setup_frame. This is non-deterministic - when re-entered but still correct. */ - -/* The little-endian AUTODIN32 ethernet CRC calculation. - N.B. Do not use for bulk data, use a table-based routine instead. - This is common code and should be moved to net/core/crc.c */ -static unsigned const ethernet_polynomial_le = 0xedb88320U; -static inline u32 ether_crc_le(int length, unsigned char *data) -{ - u32 crc = 0xffffffff; /* Initial value. */ - while(--length >= 0) { - unsigned char current_octet = *data++; - int bit; - for (bit = 8; --bit >= 0; current_octet >>= 1) { - if ((crc ^ current_octet) & 1) { - crc >>= 1; - crc ^= ethernet_polynomial_le; - } else - crc >>= 1; - } - } - return crc; -} -static unsigned const ethernet_polynomial = 0x04c11db7U; -static inline u32 ether_crc(int length, unsigned char *data) -{ - int crc = -1; - - while(--length >= 0) { - unsigned char current_octet = *data++; - int bit; - for (bit = 0; bit < 8; bit++, current_octet >>= 1) - crc = (crc << 1) ^ - ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0); - } - return crc; -} - -#undef set_bit_le -#define set_bit_le(i,p) do { ((char *)(p))[(i)/8] |= (1<<((i)%8)); } while(0) - -static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - u16 hash_table[32]; - struct dev_mc_list *mclist; - int i; - u16 *eaddrs; - - memset(hash_table, 0, sizeof(hash_table)); - set_bit_le(255, hash_table); /* Broadcast entry */ - /* This should work on big-endian machines as well. */ - for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; - i++, mclist = mclist->next) { - int index = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff; - - set_bit_le(index, hash_table); - - for (i = 0; i < 32; i++) { - *setup_frm++ = hash_table[i]; - *setup_frm++ = hash_table[i]; - } - setup_frm = &tp->setup_frame[13*6]; - } - - /* Fill the final entry with our physical address. */ - eaddrs = (u16 *)dev->dev_addr; - *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; - *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; - *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; -} - -static void build_setup_frame_perfect(u16 *setup_frm, struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - struct dev_mc_list *mclist; - int i; - u16 *eaddrs; - - /* We have <= 14 addresses so we can use the wonderful - 16 address perfect filtering of the Tulip. */ - for (i = 0, mclist = dev->mc_list; i < dev->mc_count; - i++, mclist = mclist->next) { - eaddrs = (u16 *)mclist->dmi_addr; - *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++; - *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++; - *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++; - } - /* Fill the unused entries with the broadcast address. */ - memset(setup_frm, 0xff, (15-i)*12); - setup_frm = &tp->setup_frame[15*6]; - - /* Fill the final entry with our physical address. */ - eaddrs = (u16 *)dev->dev_addr; - *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; - *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; - *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; -} - - -static void set_rx_mode(struct net_device *dev) -{ - struct tulip_private *tp = (struct tulip_private *)dev->priv; - long ioaddr = dev->base_addr; - int csr6; - - csr6 = inl(ioaddr + CSR6) & ~0x00D5; - - tp->csr6 &= ~0x00D5; - if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ - tp->csr6 |= AcceptAllMulticast | AcceptAllPhys; - csr6 |= AcceptAllMulticast | AcceptAllPhys; - /* Unconditionally log net taps. */ - printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name); - } else if ((dev->mc_count > 1000) || (dev->flags & IFF_ALLMULTI)) { - /* Too many to filter well -- accept all multicasts. */ - tp->csr6 |= AcceptAllMulticast; - csr6 |= AcceptAllMulticast; - } else if (tp->flags & MC_HASH_ONLY) { - /* Some work-alikes have only a 64-entry hash filter table. */ - /* Should verify correctness on big-endian/__powerpc__ */ - struct dev_mc_list *mclist; - int i; - if (dev->mc_count > 64) { /* Arbitrary non-effective limit. */ - tp->csr6 |= AcceptAllMulticast; - csr6 |= AcceptAllMulticast; - } else { - u32 mc_filter[2] = {0, 0}; /* Multicast hash filter */ - int filterbit; - for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; - i++, mclist = mclist->next) { - if (tp->flags & COMET_MAC_ADDR) - filterbit = ether_crc_le(ETH_ALEN, mclist->dmi_addr); - else - filterbit = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; - filterbit &= 0x3f; - mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31)); - if (tulip_debug > 2) { - printk(KERN_INFO "%s: Added filter for %2.2x:%2.2x:%2.2x:" - "%2.2x:%2.2x:%2.2x %8.8x bit %d.\n", dev->name, - mclist->dmi_addr[0], mclist->dmi_addr[1], - mclist->dmi_addr[2], mclist->dmi_addr[3], - mclist->dmi_addr[4], mclist->dmi_addr[5], - ether_crc(ETH_ALEN, mclist->dmi_addr), filterbit); - } - } - if (mc_filter[0] == tp->mc_filter[0] && - mc_filter[1] == tp->mc_filter[1]) - ; /* No change. */ - else if (tp->flags & IS_ASIX) { - outl(2, ioaddr + CSR13); - outl(mc_filter[0], ioaddr + CSR14); - outl(3, ioaddr + CSR13); - outl(mc_filter[1], ioaddr + CSR14); - } else if (tp->flags & COMET_MAC_ADDR) { - outl(mc_filter[0], ioaddr + 0xAC); - outl(mc_filter[1], ioaddr + 0xB0); - } - tp->mc_filter[0] = mc_filter[0]; - tp->mc_filter[1] = mc_filter[1]; - } - } else { - unsigned long flags; - - /* Note that only the low-address shortword of setup_frame is valid! - The values are doubled for big-endian architectures. */ - if (dev->mc_count > 14) { /* Must use a multicast hash table. */ - build_setup_frame_hash(tp->setup_frame, dev); - } else { - build_setup_frame_perfect(tp->setup_frame, dev); - } - - spin_lock_irqsave(&tp->lock, flags); - - if (tp->cur_tx - tp->dirty_tx > TX_RING_SIZE - 2) { - /* Same setup recently queued, we need not add it. */ - } else { - u32 tx_flags = 0x08000000 | 192; - unsigned int entry; - int dummy = -1; - - /* Now add this frame to the Tx list. */ - - entry = tp->cur_tx++ % TX_RING_SIZE; - - if (entry != 0) { - /* Avoid a chip errata by prefixing a dummy entry. */ - tp->tx_buffers[entry].skb = NULL; - tp->tx_buffers[entry].mapping = 0; - tp->tx_ring[entry].length = - (entry == TX_RING_SIZE-1) ? cpu_to_le32(DESC_RING_WRAP) : 0; - tp->tx_ring[entry].buffer1 = 0; - /* Must set DescOwned later to avoid race with chip */ - dummy = entry; - entry = tp->cur_tx++ % TX_RING_SIZE; - } - - tp->tx_buffers[entry].skb = NULL; - tp->tx_buffers[entry].mapping = - pci_map_single(tp->pdev, tp->setup_frame, - sizeof(tp->setup_frame), - PCI_DMA_TODEVICE); - /* Put the setup frame on the Tx list. */ - if (entry == TX_RING_SIZE-1) - tx_flags |= DESC_RING_WRAP; /* Wrap ring. */ - tp->tx_ring[entry].length = cpu_to_le32(tx_flags); - tp->tx_ring[entry].buffer1 = - cpu_to_le32(tp->tx_buffers[entry].mapping); - tp->tx_ring[entry].status = cpu_to_le32(DescOwned); - if (dummy >= 0) - tp->tx_ring[dummy].status = cpu_to_le32(DescOwned); - if (tp->cur_tx - tp->dirty_tx >= TX_RING_SIZE - 2) - netif_stop_queue(dev); - - /* Trigger an immediate transmit demand. */ - outl(0, ioaddr + CSR1); - } - - spin_unlock_irqrestore(&tp->lock, flags); - } - - outl(csr6, ioaddr + CSR6); -} - -#ifdef CONFIG_TULIP_MWI -static void __devinit tulip_mwi_config (struct pci_dev *pdev, - struct net_device *dev) -{ - struct tulip_private *tp = dev->priv; - u8 cache; - u16 pci_command, new_command; - u32 csr0; - - if (tulip_debug > 3) - printk(KERN_DEBUG "%s: tulip_mwi_config()\n", pdev->slot_name); - - tp->csr0 = csr0 = 0; - - /* check for sane cache line size. from acenic.c. */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache); - if ((cache << 2) != SMP_CACHE_BYTES) { - printk(KERN_WARNING "%s: PCI cache line size set incorrectly " - "(%i bytes) by BIOS/FW, correcting to %i\n", - pdev->slot_name, (cache << 2), SMP_CACHE_BYTES); - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, - SMP_CACHE_BYTES >> 2); - udelay(5); - } - - /* read cache line size again, hardware may not have accepted - * our cache line size change - */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache); - if (!cache) - goto out; - - /* if we have any cache line size at all, we can do MRM */ - csr0 |= MRM; - - /* ...and barring hardware bugs, MWI */ - if (!(tp->chip_id == DC21143 && tp->revision == 65)) - csr0 |= MWI; - - /* set or disable MWI in the standard PCI command bit. - * Check for the case where mwi is desired but not available - */ - pci_read_config_word(pdev, PCI_COMMAND, &pci_command); - if (csr0 & MWI) new_command = pci_command | PCI_COMMAND_INVALIDATE; - else new_command = pci_command & ~PCI_COMMAND_INVALIDATE; - if (new_command != pci_command) { - pci_write_config_word(pdev, PCI_COMMAND, new_command); - udelay(5); - pci_read_config_word(pdev, PCI_COMMAND, &pci_command); - if ((csr0 & MWI) && (!(pci_command & PCI_COMMAND_INVALIDATE))) - csr0 &= ~MWI; - } - - /* assign per-cacheline-size cache alignment and - * burst length values - */ - switch (cache) { - case 8: - csr0 |= MRL | (1 << CALShift) | (16 << BurstLenShift); - break; - case 16: - csr0 |= MRL | (2 << CALShift) | (16 << BurstLenShift); - break; - case 32: - csr0 |= MRL | (3 << CALShift) | (32 << BurstLenShift); - break; - default: - goto out; - } - - tp->csr0 = csr0; - goto out; - - if (csr0 & MWI) { - pci_command &= ~PCI_COMMAND_INVALIDATE; - pci_write_config_word(pdev, PCI_COMMAND, pci_command); - csr0 &= ~MWI; - } - tp->csr0 = csr0 | (8 << BurstLenShift) | (1 << CALShift); - -out: - if (tulip_debug > 2) - printk(KERN_DEBUG "%s: MWI config cacheline=%d, csr0=%08x\n", - pdev->slot_name, cache, csr0); -} -#endif - -static int __devinit tulip_init_one (struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct tulip_private *tp; - /* See note below on the multiport cards. */ - static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'}; - static int last_irq; - static int multiport_cnt; /* For four-port boards w/one EEPROM */ - u8 chip_rev; - int i, irq; - unsigned short sum; - u8 ee_data[EEPROM_SIZE]; - struct net_device *dev; - long ioaddr; - static int board_idx = -1; - int chip_idx = ent->driver_data; - unsigned int t2104x_mode = 0; - unsigned int eeprom_missing = 0; - unsigned int force_csr0 = 0; - -#ifndef MODULE - static int did_version; /* Already printed version info. */ - if (tulip_debug > 0 && did_version++ == 0) - printk (KERN_INFO "%s", version); -#endif - - board_idx++; - - /* - * Lan media wire a tulip chip to a wan interface. Needs a very - * different driver (lmc driver) - */ - - if (pdev->subsystem_vendor == PCI_VENDOR_ID_LMC) { - printk (KERN_ERR PFX "skipping LMC card.\n"); - return -ENODEV; - } - - /* - * Early DM9100's need software CRC and the DMFE driver - */ - - if (pdev->vendor == 0x1282 && pdev->device == 0x9100) - { - u32 dev_rev; - /* Read Chip revision */ - pci_read_config_dword(pdev, PCI_REVISION_ID, &dev_rev); - if(dev_rev < 0x02000030) - { - printk(KERN_ERR PFX "skipping early DM9100 with Crc bug (use dmfe)\n"); - return -ENODEV; - } - } - - /* - * Looks for early PCI chipsets where people report hangs - * without the workarounds being on. - */ - - /* Intel Saturn. Switch to 8 long words burst, 8 long word cache aligned - Aries might need this too. The Saturn errata are not pretty reading but - thankfully its an old 486 chipset. - */ - - if (pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424, NULL)) { - csr0 = MRL | MRM | (8 << BurstLenShift) | (1 << CALShift); - force_csr0 = 1; - } - /* The dreaded SiS496 486 chipset. Same workaround as above. */ - if (pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, NULL)) { - csr0 = MRL | MRM | (8 << BurstLenShift) | (1 << CALShift); - force_csr0 = 1; - } - - /* bugfix: the ASIX must have a burst limit or horrible things happen. */ - if (chip_idx == AX88140) { - if ((csr0 & 0x3f00) == 0) - csr0 |= 0x2000; - } - - /* PNIC doesn't have MWI/MRL/MRM... */ - if (chip_idx == LC82C168) - csr0 &= ~0xfff10000; /* zero reserved bits 31:20, 16 */ - - /* DM9102A has troubles with MRM & clear reserved bits 24:22, 20, 16, 7:1 */ - if (pdev->vendor == 0x1282 && pdev->device == 0x9102) - csr0 &= ~0x01f100ff; - -#if defined(__sparc__) - /* DM9102A needs 32-dword alignment/burst length on sparc - chip bug? */ - if (pdev->vendor == 0x1282 && pdev->device == 0x9102) - csr0 = (csr0 & ~0xff00) | 0xe000; -#endif - - /* - * And back to business - */ - - i = pci_enable_device(pdev); - if (i) { - printk (KERN_ERR PFX - "Cannot enable tulip board #%d, aborting\n", - board_idx); - return i; - } - - ioaddr = pci_resource_start (pdev, 0); - irq = pdev->irq; - - /* alloc_etherdev ensures aligned and zeroed private structures */ - dev = alloc_etherdev (sizeof (*tp)); - if (!dev) { - printk (KERN_ERR PFX "ether device alloc failed, aborting\n"); - return -ENOMEM; - } - - if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) { - printk (KERN_ERR PFX "%s: I/O region (0x%lx@0x%lx) too small, " - "aborting\n", pdev->slot_name, - pci_resource_len (pdev, 0), - pci_resource_start (pdev, 0)); - goto err_out_free_netdev; - } - - /* grab all resources from both PIO and MMIO regions, as we - * don't want anyone else messing around with our hardware */ - if (pci_request_regions (pdev, "tulip")) - goto err_out_free_netdev; - -#ifndef USE_IO_OPS - ioaddr = (unsigned long) ioremap (pci_resource_start (pdev, 1), - tulip_tbl[chip_idx].io_size); - if (!ioaddr) - goto err_out_free_res; -#endif - - pci_read_config_byte (pdev, PCI_REVISION_ID, &chip_rev); - - /* - * initialize private data structure 'tp' - * it is zeroed and aligned in alloc_etherdev - */ - tp = dev->priv; - - tp->rx_ring = pci_alloc_consistent(pdev, - sizeof(struct tulip_rx_desc) * RX_RING_SIZE + - sizeof(struct tulip_tx_desc) * TX_RING_SIZE, - &tp->rx_ring_dma); - if (!tp->rx_ring) - goto err_out_mtable; - tp->tx_ring = (struct tulip_tx_desc *)(tp->rx_ring + RX_RING_SIZE); - tp->tx_ring_dma = tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * RX_RING_SIZE; - - tp->chip_id = chip_idx; - tp->flags = tulip_tbl[chip_idx].flags; - tp->pdev = pdev; - tp->base_addr = ioaddr; - tp->revision = chip_rev; - tp->csr0 = csr0; - spin_lock_init(&tp->lock); - spin_lock_init(&tp->mii_lock); - init_timer(&tp->timer); - tp->timer.data = (unsigned long)dev; - tp->timer.function = tulip_tbl[tp->chip_id].media_timer; - - dev->base_addr = ioaddr; - dev->irq = irq; - -#ifdef CONFIG_TULIP_MWI - if (!force_csr0 && (tp->flags & HAS_PCI_MWI)) - tulip_mwi_config (pdev, dev); -#else - /* MWI is broken for DC21143 rev 65... */ - if (chip_idx == DC21143 && chip_rev == 65) - tp->csr0 &= ~MWI; -#endif - - /* Stop the chip's Tx and Rx processes. */ - tulip_stop_rxtx(tp); - - pci_set_master(pdev); - - /* Clear the missed-packet counter. */ - inl(ioaddr + CSR8); - - if (chip_idx == DC21041) { - if (inl(ioaddr + CSR9) & 0x8000) { - chip_idx = DC21040; - t2104x_mode = 1; - } else { - t2104x_mode = 2; - } - } - - /* The station address ROM is read byte serially. The register must - be polled, waiting for the value to be read bit serially from the - EEPROM. - */ - sum = 0; - if (chip_idx == DC21040) { - outl(0, ioaddr + CSR9); /* Reset the pointer with a dummy write. */ - for (i = 0; i < 6; i++) { - int value, boguscnt = 100000; - do - value = inl(ioaddr + CSR9); - while (value < 0 && --boguscnt > 0); - dev->dev_addr[i] = value; - sum += value & 0xff; - } - } else if (chip_idx == LC82C168) { - for (i = 0; i < 3; i++) { - int value, boguscnt = 100000; - outl(0x600 | i, ioaddr + 0x98); - do - value = inl(ioaddr + CSR9); - while (value < 0 && --boguscnt > 0); - put_unaligned(le16_to_cpu(value), ((u16*)dev->dev_addr) + i); - sum += value & 0xffff; - } - } else if (chip_idx == COMET) { - /* No need to read the EEPROM. */ - put_unaligned(inl(ioaddr + 0xA4), (u32 *)dev->dev_addr); - put_unaligned(inl(ioaddr + 0xA8), (u16 *)(dev->dev_addr + 4)); - for (i = 0; i < 6; i ++) - sum += dev->dev_addr[i]; - } else { - /* A serial EEPROM interface, we read now and sort it out later. */ - int sa_offset = 0; - int ee_addr_size = tulip_read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6; - - for (i = 0; i < sizeof(ee_data)/2; i++) - ((u16 *)ee_data)[i] = - le16_to_cpu(tulip_read_eeprom(ioaddr, i, ee_addr_size)); - - /* DEC now has a specification (see Notes) but early board makers - just put the address in the first EEPROM locations. */ - /* This does memcmp(eedata, eedata+16, 8) */ - for (i = 0; i < 8; i ++) - if (ee_data[i] != ee_data[16+i]) - sa_offset = 20; - if (ee_data[0] == 0xff && ee_data[1] == 0xff && ee_data[2] == 0) { - sa_offset = 2; /* Grrr, damn Matrox boards. */ - multiport_cnt = 4; - } -#ifdef CONFIG_DDB5476 - if ((pdev->bus->number == 0) && (PCI_SLOT(pdev->devfn) == 6)) { - /* DDB5476 MAC address in first EEPROM locations. */ - sa_offset = 0; - /* No media table either */ - tp->flags &= ~HAS_MEDIA_TABLE; - } -#endif -#ifdef CONFIG_DDB5477 - if ((pdev->bus->number == 0) && (PCI_SLOT(pdev->devfn) == 4)) { - /* DDB5477 MAC address in first EEPROM locations. */ - sa_offset = 0; - /* No media table either */ - tp->flags &= ~HAS_MEDIA_TABLE; - } -#endif - for (i = 0; i < 6; i ++) { - dev->dev_addr[i] = ee_data[i + sa_offset]; - sum += ee_data[i + sa_offset]; - } - } - /* Lite-On boards have the address byte-swapped. */ - if ((dev->dev_addr[0] == 0xA0 || dev->dev_addr[0] == 0xC0) - && dev->dev_addr[1] == 0x00) - for (i = 0; i < 6; i+=2) { - char tmp = dev->dev_addr[i]; - dev->dev_addr[i] = dev->dev_addr[i+1]; - dev->dev_addr[i+1] = tmp; - } - /* On the Zynx 315 Etherarray and other multiport boards only the - first Tulip has an EEPROM. - On Sparc systems the mac address is held in the OBP property - "local-mac-address". - The addresses of the subsequent ports are derived from the first. - Many PCI BIOSes also incorrectly report the IRQ line, so we correct - that here as well. */ - if (sum == 0 || sum == 6*0xff) { -#if defined(__sparc__) - struct pcidev_cookie *pcp = pdev->sysdata; -#endif - eeprom_missing = 1; - for (i = 0; i < 5; i++) - dev->dev_addr[i] = last_phys_addr[i]; - dev->dev_addr[i] = last_phys_addr[i] + 1; -#if defined(__sparc__) - if ((pcp != NULL) && prom_getproplen(pcp->prom_node, - "local-mac-address") == 6) { - prom_getproperty(pcp->prom_node, "local-mac-address", - dev->dev_addr, 6); - } -#endif -#if defined(__i386__) /* Patch up x86 BIOS bug. */ - if (last_irq) - irq = last_irq; -#endif - } - - for (i = 0; i < 6; i++) - last_phys_addr[i] = dev->dev_addr[i]; - last_irq = irq; - - /* The lower four bits are the media type. */ - if (board_idx >= 0 && board_idx < MAX_UNITS) { - if (options[board_idx] & MEDIA_MASK) - tp->default_port = options[board_idx] & MEDIA_MASK; - if ((options[board_idx] & FullDuplex) || full_duplex[board_idx] > 0) - tp->full_duplex = 1; - if (mtu[board_idx] > 0) - dev->mtu = mtu[board_idx]; - } - if (dev->mem_start & MEDIA_MASK) - tp->default_port = dev->mem_start & MEDIA_MASK; - if (tp->default_port) { - printk(KERN_INFO "tulip%d: Transceiver selection forced to %s.\n", - board_idx, medianame[tp->default_port & MEDIA_MASK]); - tp->medialock = 1; - if (tulip_media_cap[tp->default_port] & MediaAlwaysFD) - tp->full_duplex = 1; - } - if (tp->full_duplex) - tp->full_duplex_lock = 1; - - if (tulip_media_cap[tp->default_port] & MediaIsMII) { - u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 }; - tp->mii_advertise = media2advert[tp->default_port - 9]; - tp->mii_advertise |= (tp->flags & HAS_8023X); /* Matching bits! */ - } - - if (tp->flags & HAS_MEDIA_TABLE) { - memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom)); - - sprintf(dev->name, "tulip%d", board_idx); /* hack */ - tulip_parse_eeprom(dev); - strcpy(dev->name, "eth%d"); /* un-hack */ - } - - if ((tp->flags & ALWAYS_CHECK_MII) || - (tp->mtable && tp->mtable->has_mii) || - ( ! tp->mtable && (tp->flags & HAS_MII))) { - if (tp->mtable && tp->mtable->has_mii) { - for (i = 0; i < tp->mtable->leafcount; i++) - if (tp->mtable->mleaf[i].media == 11) { - tp->cur_index = i; - tp->saved_if_port = dev->if_port; - tulip_select_media(dev, 2); - dev->if_port = tp->saved_if_port; - break; - } - } - - /* Find the connected MII xcvrs. - Doing this in open() would allow detecting external xcvrs - later, but takes much time. */ - tulip_find_mii (dev, board_idx); - } - - /* The Tulip-specific entries in the device structure. */ - dev->open = tulip_open; - dev->hard_start_xmit = tulip_start_xmit; - dev->tx_timeout = tulip_tx_timeout; - dev->watchdog_timeo = TX_TIMEOUT; - dev->stop = tulip_close; - dev->get_stats = tulip_get_stats; - dev->do_ioctl = private_ioctl; - dev->set_multicast_list = set_rx_mode; - - if (register_netdev(dev)) - goto err_out_free_ring; - - printk(KERN_INFO "%s: %s rev %d at %#3lx,", - dev->name, tulip_tbl[chip_idx].chip_name, chip_rev, ioaddr); - pci_set_drvdata(pdev, dev); - - if (t2104x_mode == 1) - printk(" 21040 compatible mode,"); - else if (t2104x_mode == 2) - printk(" 21041 mode,"); - if (eeprom_missing) - printk(" EEPROM not present,"); - for (i = 0; i < 6; i++) - printk("%c%2.2X", i ? ':' : ' ', dev->dev_addr[i]); - printk(", IRQ %d.\n", irq); - - if (tp->chip_id == PNIC2) - tp->link_change = pnic2_lnk_change; - else if ((tp->flags & HAS_NWAY) || tp->chip_id == DC21041) - tp->link_change = t21142_lnk_change; - else if (tp->flags & HAS_PNICNWAY) - tp->link_change = pnic_lnk_change; - - /* Reset the xcvr interface and turn on heartbeat. */ - switch (chip_idx) { - case DC21041: - if (tp->sym_advertise == 0) - tp->sym_advertise = 0x0061; - outl(0x00000000, ioaddr + CSR13); - outl(0xFFFFFFFF, ioaddr + CSR14); - outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */ - outl(inl(ioaddr + CSR6) | csr6_fd, ioaddr + CSR6); - outl(0x0000EF01, ioaddr + CSR13); - break; - case DC21040: - outl(0x00000000, ioaddr + CSR13); - outl(0x00000004, ioaddr + CSR13); - break; - case DC21140: - case DM910X: - default: - if (tp->mtable) - outl(tp->mtable->csr12dir | 0x100, ioaddr + CSR12); - break; - case DC21142: - if (tp->mii_cnt || tulip_media_cap[dev->if_port] & MediaIsMII) { - outl(csr6_mask_defstate, ioaddr + CSR6); - outl(0x0000, ioaddr + CSR13); - outl(0x0000, ioaddr + CSR14); - outl(csr6_mask_hdcap, ioaddr + CSR6); - } else - t21142_start_nway(dev); - break; - case PNIC2: - /* just do a reset for sanity sake */ - outl(0x0000, ioaddr + CSR13); - outl(0x0000, ioaddr + CSR14); - break; - case LC82C168: - if ( ! tp->mii_cnt) { - tp->nway = 1; - tp->nwayset = 0; - outl(csr6_ttm | csr6_ca, ioaddr + CSR6); - outl(0x30, ioaddr + CSR12); - outl(0x0001F078, ioaddr + CSR6); - outl(0x0201F078, ioaddr + CSR6); /* Turn on autonegotiation. */ - } - break; - case MX98713: - case COMPEX9881: - outl(0x00000000, ioaddr + CSR6); - outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */ - outl(0x00000001, ioaddr + CSR13); - break; - case MX98715: - case MX98725: - outl(0x01a80000, ioaddr + CSR6); - outl(0xFFFFFFFF, ioaddr + CSR14); - outl(0x00001000, ioaddr + CSR12); - break; - case COMET: - /* No initialization necessary. */ - break; - } - - /* put the chip in snooze mode until opened */ - tulip_set_power_state (tp, 0, 1); - - return 0; - -err_out_free_ring: - pci_free_consistent (pdev, - sizeof (struct tulip_rx_desc) * RX_RING_SIZE + - sizeof (struct tulip_tx_desc) * TX_RING_SIZE, - tp->rx_ring, tp->rx_ring_dma); - -err_out_mtable: - if (tp->mtable) - kfree (tp->mtable); -#ifndef USE_IO_OPS - iounmap((void *)ioaddr); - -err_out_free_res: -#endif - pci_release_regions (pdev); - -err_out_free_netdev: - kfree (dev); - return -ENODEV; -} - - -#ifdef CONFIG_PM - -static int tulip_suspend (struct pci_dev *pdev, u32 state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - if (dev && netif_running (dev) && netif_device_present (dev)) { - netif_device_detach (dev); - tulip_down (dev); - /* pci_power_off(pdev, -1); */ - } - return 0; -} - - -static int tulip_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - if (dev && netif_running (dev) && !netif_device_present (dev)) { -#if 1 - pci_enable_device (pdev); -#endif - /* pci_power_on(pdev); */ - tulip_up (dev); - netif_device_attach (dev); - } - return 0; -} - -#endif /* CONFIG_PM */ - - -static void __devexit tulip_remove_one (struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata (pdev); - struct tulip_private *tp; - - if (!dev) - return; - - tp = dev->priv; - pci_free_consistent (pdev, - sizeof (struct tulip_rx_desc) * RX_RING_SIZE + - sizeof (struct tulip_tx_desc) * TX_RING_SIZE, - tp->rx_ring, tp->rx_ring_dma); - unregister_netdev (dev); - if (tp->mtable) - kfree (tp->mtable); -#ifndef USE_IO_OPS - iounmap((void *)dev->base_addr); -#endif - kfree (dev); - pci_release_regions (pdev); - pci_set_drvdata (pdev, NULL); - - /* pci_power_off (pdev, -1); */ -} - - -static struct pci_driver tulip_driver = { - name: DRV_NAME, - id_table: tulip_pci_tbl, - probe: tulip_init_one, - remove: __devexit_p(tulip_remove_one), -#ifdef CONFIG_PM - suspend: tulip_suspend, - resume: tulip_resume, -#endif /* CONFIG_PM */ -}; - - -static int __init tulip_init (void) -{ -#ifdef MODULE - printk (KERN_INFO "%s", version); -#endif - - /* copy module parms into globals */ - tulip_rx_copybreak = rx_copybreak; - tulip_max_interrupt_work = max_interrupt_work; - - /* probe for and init boards */ - return pci_module_init (&tulip_driver); -} - - -static void __exit tulip_cleanup (void) -{ - pci_unregister_driver (&tulip_driver); -} - - -module_init(tulip_init); -module_exit(tulip_cleanup); diff --git a/xen-2.4.16/include/asm-i386/smp.h b/xen-2.4.16/include/asm-i386/smp.h index 560f5ead19..cfec568c43 100644 --- a/xen-2.4.16/include/asm-i386/smp.h +++ b/xen-2.4.16/include/asm-i386/smp.h @@ -13,9 +13,7 @@ #ifdef CONFIG_SMP #define TARGET_CPUS cpu_online_map -#define INT_DELIVERY_MODE 1 /* logical delivery broadcast to all procs */ #else -#define INT_DELIVERY_MODE 1 /* logical delivery */ #define TARGET_CPUS 0x01 #endif diff --git a/xen-2.4.16/net/dev.c b/xen-2.4.16/net/dev.c index 99e0c94fd7..f5d85547a5 100644 --- a/xen-2.4.16/net/dev.c +++ b/xen-2.4.16/net/dev.c @@ -2043,12 +2043,13 @@ long do_net_update(void) for ( j = 0; j < current->num_net_vifs; j++) { - current_vif = current->net_vif_list[j]; - net_ring = current_vif->net_ring; int target; u8 *g_data; unsigned short protocol; + current_vif = current->net_vif_list[j]; + net_ring = current_vif->net_ring; + /* First, we send out pending TX descriptors if they exist on this ring. */ diff --git a/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c b/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c index 5795d889e8..0eb8003512 100644 --- a/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c +++ b/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c @@ -35,7 +35,7 @@ #define TX_RING_ADD(_i,_j) (((_i)+(_j)) & (TX_RING_SIZE-1)) #define RX_RING_ADD(_i,_j) (((_i)+(_j)) & (RX_RING_SIZE-1)) -#define RX_BUF_SIZE 2049 /* (was 1600) Ethernet MTU + plenty of slack! */ +#define RX_BUF_SIZE ((PAGE_SIZE/2)+1) /* Fool the slab allocator :-) */ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs); static void network_tx_int(int irq, void *dev_id, struct pt_regs *ptregs); @@ -92,9 +92,9 @@ static int network_open(struct net_device *dev) np->rx_skb_ring = kmalloc(RX_RING_SIZE * sizeof(struct sk_buff *), GFP_KERNEL); np->net_ring->tx_ring = kmalloc(TX_RING_SIZE * sizeof(tx_entry_t), - GFP_KERNEL); + GFP_KERNEL); np->net_ring->rx_ring = kmalloc(RX_RING_SIZE * sizeof(rx_entry_t), - GFP_KERNEL); + GFP_KERNEL); if ( (np->tx_skb_ring == NULL) || (np->rx_skb_ring == NULL) || (np->net_ring->tx_ring == NULL) || (np->net_ring->rx_ring == NULL) ) { @@ -106,7 +106,7 @@ static int network_open(struct net_device *dev) network_alloc_rx_buffers(dev); error = request_irq(NET_RX_IRQ, network_rx_int, 0, - "net-rx", dev); + "net-rx", dev); if ( error ) { printk(KERN_WARNING "%s: Could not allocate receive interrupt\n", @@ -115,7 +115,7 @@ static int network_open(struct net_device *dev) } error = request_irq(NET_TX_IRQ, network_tx_int, 0, - "net-tx", dev); + "net-tx", dev); if ( error ) { printk(KERN_WARNING "%s: Could not allocate transmit interrupt\n", @@ -171,20 +171,20 @@ static void network_tx_buf_gc(struct net_device *dev) inline unsigned long get_ppte(unsigned long addr) { - unsigned long ppte = 0xdeadbeef; - pgd_t *pgd; pmd_t *pmd; pte_t *ptep; - pgd = pgd_offset_k(addr); + unsigned long ppte = 0xdeadbeef; + pgd_t *pgd; pmd_t *pmd; pte_t *ptep; + pgd = pgd_offset_k(addr); - if (pgd_none(*pgd) || pgd_bad(*pgd)) BUG(); + if (pgd_none(*pgd) || pgd_bad(*pgd)) BUG(); - pmd = pmd_offset(pgd, addr); - if (pmd_none(*pmd)) BUG(); - if (pmd_bad(*pmd)) BUG(); + pmd = pmd_offset(pgd, addr); + if (pmd_none(*pmd)) BUG(); + if (pmd_bad(*pmd)) BUG(); - ptep = pte_offset(pmd, addr); - ppte = (unsigned long)phys_to_machine(virt_to_phys(ptep)); + ptep = pte_offset(pmd, addr); + ppte = (unsigned long)phys_to_machine(virt_to_phys(ptep)); - return ppte; + return ppte; } static void network_alloc_rx_buffers(struct net_device *dev) @@ -250,8 +250,8 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) } np->tx_skb_ring[i] = skb; - np->net_ring->tx_ring[i].addr - = (unsigned long)phys_to_machine(virt_to_phys(skb->data)); + np->net_ring->tx_ring[i].addr = + (unsigned long)phys_to_machine(virt_to_phys(skb->data)); np->net_ring->tx_ring[i].size = skb->len; np->net_ring->tx_prod = TX_RING_INC(i); atomic_inc(&np->tx_entries); @@ -264,8 +264,8 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) { np->tx_full = 1; netif_stop_queue(dev); - np->net_ring->tx_event = TX_RING_ADD(np->tx_idx, - atomic_read(&np->tx_entries) >> 1); + np->net_ring->tx_event = + TX_RING_ADD(np->tx_idx, atomic_read(&np->tx_entries) >> 1); } else { @@ -295,23 +295,24 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs) { if (np->net_ring->rx_ring[i].status != RING_STATUS_OK) { - printk("bad buffer on RX ring!(%d)\n", - np->net_ring->rx_ring[i].status); - continue; + printk("bad buffer on RX ring!(%d)\n", + np->net_ring->rx_ring[i].status); + continue; } skb = np->rx_skb_ring[i]; phys_to_machine_mapping[virt_to_phys(skb->head) >> PAGE_SHIFT] = (*(unsigned long *)phys_to_virt( - machine_to_phys(np->net_ring->rx_ring[i].addr)) - ) >> PAGE_SHIFT; + machine_to_phys(np->net_ring->rx_ring[i].addr)) + ) >> PAGE_SHIFT; skb_put(skb, np->net_ring->rx_ring[i].size); skb->protocol = eth_type_trans(skb, dev); - /* Set up shinfo -- from alloc_skb - * This was particularily nasty: the shared info is hidden at the back of the data area - * (presumably so it can be shared), but on page flip it gets very spunked. + /* + * Set up shinfo -- from alloc_skb This was particularily nasty: the + * shared info is hidden at the back of the data area (presumably so + * it can be shared), but on page flip it gets very spunked. */ atomic_set(&(skb_shinfo(skb)->dataref), 1); @@ -331,9 +332,7 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs) /* Deal with hypervisor racing our resetting of rx_event. */ smp_mb(); - if ( np->net_ring->rx_cons != i ) { - goto again; - } + if ( np->net_ring->rx_cons != i ) goto again; } |