aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.rootkeys15
-rw-r--r--xen-2.4.16/drivers/net/8139cp.c1338
-rw-r--r--xen-2.4.16/drivers/net/Makefile4
-rw-r--r--xen-2.4.16/drivers/net/e1000/e1000_osdep.h1
-rw-r--r--xen-2.4.16/drivers/net/eepro100.c2312
-rw-r--r--xen-2.4.16/drivers/net/pcnet32.c1614
-rw-r--r--xen-2.4.16/drivers/net/tulip/.depend58
-rw-r--r--xen-2.4.16/drivers/net/tulip/21142.c239
-rw-r--r--xen-2.4.16/drivers/net/tulip/ChangeLog520
-rw-r--r--xen-2.4.16/drivers/net/tulip/Makefile8
-rw-r--r--xen-2.4.16/drivers/net/tulip/eeprom.c320
-rw-r--r--xen-2.4.16/drivers/net/tulip/interrupt.c560
-rw-r--r--xen-2.4.16/drivers/net/tulip/media.c563
-rw-r--r--xen-2.4.16/drivers/net/tulip/pnic.c171
-rw-r--r--xen-2.4.16/drivers/net/tulip/pnic2.c407
-rw-r--r--xen-2.4.16/drivers/net/tulip/timer.c220
-rw-r--r--xen-2.4.16/drivers/net/tulip/tulip.h499
-rw-r--r--xen-2.4.16/drivers/net/tulip/tulip_core.c1925
-rw-r--r--xen-2.4.16/include/asm-i386/smp.h2
-rw-r--r--xen-2.4.16/net/dev.c5
-rw-r--r--xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c59
21 files changed, 33 insertions, 10807 deletions
diff --git a/.rootkeys b/.rootkeys
index c712554b9b..fb5b75b6f1 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -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 (&ethcmd, 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(&ethcmd, 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(&ethcmd, 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;
}