aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/arm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/arm')
-rw-r--r--drivers/net/arm/Kconfig46
-rw-r--r--drivers/net/arm/Makefile10
-rw-r--r--drivers/net/arm/am79c961a.c750
-rw-r--r--drivers/net/arm/am79c961a.h148
-rw-r--r--drivers/net/arm/ether00.c1017
-rw-r--r--drivers/net/arm/ether1.c1110
-rw-r--r--drivers/net/arm/ether1.h281
-rw-r--r--drivers/net/arm/ether3.c936
-rw-r--r--drivers/net/arm/ether3.h177
-rw-r--r--drivers/net/arm/etherh.c862
10 files changed, 0 insertions, 5337 deletions
diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig
deleted file mode 100644
index 470364deded..00000000000
--- a/drivers/net/arm/Kconfig
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# Acorn Network device configuration
-# These are for Acorn's Expansion card network interfaces
-#
-config ARM_AM79C961A
- bool "ARM EBSA110 AM79C961A support"
- depends on NET_ETHERNET && ARM && ARCH_EBSA110
- select CRC32
- help
- If you wish to compile a kernel for the EBSA-110, then you should
- always answer Y to this.
-
-config ARM_ETHER1
- tristate "Acorn Ether1 support"
- depends on NET_ETHERNET && ARM && ARCH_ACORN
- help
- If you have an Acorn system with one of these (AKA25) network cards,
- you should say Y to this option if you wish to use it with Linux.
-
-config ARM_ETHER3
- tristate "Acorn/ANT Ether3 support"
- depends on NET_ETHERNET && ARM && ARCH_ACORN
- help
- If you have an Acorn system with one of these network cards, you
- should say Y to this option if you wish to use it with Linux.
-
-config ARM_ETHERH
- tristate "I-cubed EtherH/ANT EtherM support"
- depends on NET_ETHERNET && ARM && ARCH_ACORN
- select CRC32
- help
- If you have an Acorn system with one of these network cards, you
- should say Y to this option if you wish to use it with Linux.
-
-config ARM_ETHER00
- tristate "Altera Ether00 support"
- depends on NET_ETHERNET && ARM && ARCH_CAMELOT
- help
- This is the driver for Altera's ether00 ethernet mac IP core. Say
- Y here if you want to build support for this into the kernel. It
- is also available as a module (say M here) that can be inserted/
- removed from the kernel at the same time as the PLD is configured.
- If this driver is running on an epxa10 development board then it
- will generate a suitable hw address based on the board serial
- number (MTD support is required for this). Otherwise you will
- need to set a suitable hw address using ifconfig.
diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile
deleted file mode 100644
index b0d706834d8..00000000000
--- a/drivers/net/arm/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# File: drivers/net/arm/Makefile
-#
-# Makefile for the ARM network device drivers
-#
-
-obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o
-obj-$(CONFIG_ARM_ETHER00) += ether00.o
-obj-$(CONFIG_ARM_ETHERH) += etherh.o
-obj-$(CONFIG_ARM_ETHER3) += ether3.o
-obj-$(CONFIG_ARM_ETHER1) += ether1.o
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
deleted file mode 100644
index 9b659e3c8d6..00000000000
--- a/drivers/net/arm/am79c961a.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/*
- * linux/drivers/net/am79c961.c
- *
- * by Russell King <rmk@arm.linux.org.uk> 1995-2001.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Derived from various things including skeleton.c
- *
- * This is a special driver for the am79c961A Lance chip used in the
- * Intel (formally Digital Equipment Corp) EBSA110 platform. Please
- * note that this can not be built as a module (it doesn't make sense).
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/crc32.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#define TX_BUFFERS 15
-#define RX_BUFFERS 25
-
-#include "am79c961a.h"
-
-static irqreturn_t
-am79c961_interrupt (int irq, void *dev_id, struct pt_regs *regs);
-
-static unsigned int net_debug = NET_DEBUG;
-
-static const char version[] =
- "am79c961 ethernet driver (C) 1995-2001 Russell King v0.04\n";
-
-/* --------------------------------------------------------------------------- */
-
-#ifdef __arm__
-static void write_rreg(u_long base, u_int reg, u_int val)
-{
- __asm__(
- "str%?h %1, [%2] @ NET_RAP\n\t"
- "str%?h %0, [%2, #-4] @ NET_RDP"
- :
- : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
-}
-
-static inline unsigned short read_rreg(u_long base_addr, u_int reg)
-{
- unsigned short v;
- __asm__(
- "str%?h %1, [%2] @ NET_RAP\n\t"
- "ldr%?h %0, [%2, #-4] @ NET_RDP"
- : "=r" (v)
- : "r" (reg), "r" (ISAIO_BASE + 0x0464));
- return v;
-}
-
-static inline void write_ireg(u_long base, u_int reg, u_int val)
-{
- __asm__(
- "str%?h %1, [%2] @ NET_RAP\n\t"
- "str%?h %0, [%2, #8] @ NET_IDP"
- :
- : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
-}
-
-static inline unsigned short read_ireg(u_long base_addr, u_int reg)
-{
- u_short v;
- __asm__(
- "str%?h %1, [%2] @ NAT_RAP\n\t"
- "str%?h %0, [%2, #8] @ NET_IDP\n\t"
- : "=r" (v)
- : "r" (reg), "r" (ISAIO_BASE + 0x0464));
- return v;
-}
-
-#define am_writeword(dev,off,val) __raw_writew(val, ISAMEM_BASE + ((off) << 1))
-#define am_readword(dev,off) __raw_readw(ISAMEM_BASE + ((off) << 1))
-
-static inline void
-am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
-{
- offset = ISAMEM_BASE + (offset << 1);
- length = (length + 1) & ~1;
- if ((int)buf & 2) {
- __asm__ __volatile__("str%?h %2, [%0], #4"
- : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
- buf += 2;
- length -= 2;
- }
- while (length > 8) {
- unsigned int tmp, tmp2;
- __asm__ __volatile__(
- "ldm%?ia %1!, {%2, %3}\n\t"
- "str%?h %2, [%0], #4\n\t"
- "mov%? %2, %2, lsr #16\n\t"
- "str%?h %2, [%0], #4\n\t"
- "str%?h %3, [%0], #4\n\t"
- "mov%? %3, %3, lsr #16\n\t"
- "str%?h %3, [%0], #4"
- : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2)
- : "0" (offset), "1" (buf));
- length -= 8;
- }
- while (length > 0) {
- __asm__ __volatile__("str%?h %2, [%0], #4"
- : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
- buf += 2;
- length -= 2;
- }
-}
-
-static inline void
-am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
-{
- offset = ISAMEM_BASE + (offset << 1);
- length = (length + 1) & ~1;
- if ((int)buf & 2) {
- unsigned int tmp;
- __asm__ __volatile__(
- "ldr%?h %2, [%0], #4\n\t"
- "str%?b %2, [%1], #1\n\t"
- "mov%? %2, %2, lsr #8\n\t"
- "str%?b %2, [%1], #1"
- : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf));
- length -= 2;
- }
- while (length > 8) {
- unsigned int tmp, tmp2, tmp3;
- __asm__ __volatile__(
- "ldr%?h %2, [%0], #4\n\t"
- "ldr%?h %3, [%0], #4\n\t"
- "orr%? %2, %2, %3, lsl #16\n\t"
- "ldr%?h %3, [%0], #4\n\t"
- "ldr%?h %4, [%0], #4\n\t"
- "orr%? %3, %3, %4, lsl #16\n\t"
- "stm%?ia %1!, {%2, %3}"
- : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3)
- : "0" (offset), "1" (buf));
- length -= 8;
- }
- while (length > 0) {
- unsigned int tmp;
- __asm__ __volatile__(
- "ldr%?h %2, [%0], #4\n\t"
- "str%?b %2, [%1], #1\n\t"
- "mov%? %2, %2, lsr #8\n\t"
- "str%?b %2, [%1], #1"
- : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf));
- length -= 2;
- }
-}
-#else
-#error Not compatible
-#endif
-
-static int
-am79c961_ramtest(struct net_device *dev, unsigned int val)
-{
- unsigned char *buffer = kmalloc (65536, GFP_KERNEL);
- int i, error = 0, errorcount = 0;
-
- if (!buffer)
- return 0;
- memset (buffer, val, 65536);
- am_writebuffer(dev, 0, buffer, 65536);
- memset (buffer, val ^ 255, 65536);
- am_readbuffer(dev, 0, buffer, 65536);
- for (i = 0; i < 65536; i++) {
- if (buffer[i] != val && !error) {
- printk ("%s: buffer error (%02X %02X) %05X - ", dev->name, val, buffer[i], i);
- error = 1;
- errorcount ++;
- } else if (error && buffer[i] == val) {
- printk ("%05X\n", i);
- error = 0;
- }
- }
- if (error)
- printk ("10000\n");
- kfree (buffer);
- return errorcount;
-}
-
-static void
-am79c961_init_for_open(struct net_device *dev)
-{
- struct dev_priv *priv = netdev_priv(dev);
- unsigned long flags;
- unsigned char *p;
- u_int hdr_addr, first_free_addr;
- int i;
-
- /*
- * Stop the chip.
- */
- spin_lock_irqsave(priv->chip_lock, flags);
- write_rreg (dev->base_addr, CSR0, CSR0_BABL|CSR0_CERR|CSR0_MISS|CSR0_MERR|CSR0_TINT|CSR0_RINT|CSR0_STOP);
- spin_unlock_irqrestore(priv->chip_lock, flags);
-
- write_ireg (dev->base_addr, 5, 0x00a0); /* Receive address LED */
- write_ireg (dev->base_addr, 6, 0x0081); /* Collision LED */
- write_ireg (dev->base_addr, 7, 0x0090); /* XMIT LED */
- write_ireg (dev->base_addr, 2, 0x0000); /* MODE register selects media */
-
- for (i = LADRL; i <= LADRH; i++)
- write_rreg (dev->base_addr, i, 0);
-
- for (i = PADRL, p = dev->dev_addr; i <= PADRH; i++, p += 2)
- write_rreg (dev->base_addr, i, p[0] | (p[1] << 8));
-
- i = MODE_PORT_10BT;
- if (dev->flags & IFF_PROMISC)
- i |= MODE_PROMISC;
-
- write_rreg (dev->base_addr, MODE, i);
- write_rreg (dev->base_addr, POLLINT, 0);
- write_rreg (dev->base_addr, SIZERXR, -RX_BUFFERS);
- write_rreg (dev->base_addr, SIZETXR, -TX_BUFFERS);
-
- first_free_addr = RX_BUFFERS * 8 + TX_BUFFERS * 8 + 16;
- hdr_addr = 0;
-
- priv->rxhead = 0;
- priv->rxtail = 0;
- priv->rxhdr = hdr_addr;
-
- for (i = 0; i < RX_BUFFERS; i++) {
- priv->rxbuffer[i] = first_free_addr;
- am_writeword (dev, hdr_addr, first_free_addr);
- am_writeword (dev, hdr_addr + 2, RMD_OWN);
- am_writeword (dev, hdr_addr + 4, (-1600));
- am_writeword (dev, hdr_addr + 6, 0);
- first_free_addr += 1600;
- hdr_addr += 8;
- }
- priv->txhead = 0;
- priv->txtail = 0;
- priv->txhdr = hdr_addr;
- for (i = 0; i < TX_BUFFERS; i++) {
- priv->txbuffer[i] = first_free_addr;
- am_writeword (dev, hdr_addr, first_free_addr);
- am_writeword (dev, hdr_addr + 2, TMD_STP|TMD_ENP);
- am_writeword (dev, hdr_addr + 4, 0xf000);
- am_writeword (dev, hdr_addr + 6, 0);
- first_free_addr += 1600;
- hdr_addr += 8;
- }
-
- write_rreg (dev->base_addr, BASERXL, priv->rxhdr);
- write_rreg (dev->base_addr, BASERXH, 0);
- write_rreg (dev->base_addr, BASETXL, priv->txhdr);
- write_rreg (dev->base_addr, BASERXH, 0);
- write_rreg (dev->base_addr, CSR0, CSR0_STOP);
- write_rreg (dev->base_addr, CSR3, CSR3_IDONM|CSR3_BABLM|CSR3_DXSUFLO);
- write_rreg (dev->base_addr, CSR4, CSR4_APAD_XMIT|CSR4_MFCOM|CSR4_RCVCCOM|CSR4_TXSTRTM|CSR4_JABM);
- write_rreg (dev->base_addr, CSR0, CSR0_IENA|CSR0_STRT);
-}
-
-static void am79c961_timer(unsigned long data)
-{
- struct net_device *dev = (struct net_device *)data;
- struct dev_priv *priv = netdev_priv(dev);
- unsigned int lnkstat, carrier;
-
- lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST;
- carrier = netif_carrier_ok(dev);
-
- if (lnkstat && !carrier)
- netif_carrier_on(dev);
- else if (!lnkstat && carrier)
- netif_carrier_off(dev);
-
- mod_timer(&priv->timer, jiffies + 5*HZ);
-}
-
-/*
- * Open/initialize the board.
- */
-static int
-am79c961_open(struct net_device *dev)
-{
- struct dev_priv *priv = netdev_priv(dev);
- int ret;
-
- memset (&priv->stats, 0, sizeof (priv->stats));
-
- ret = request_irq(dev->irq, am79c961_interrupt, 0, dev->name, dev);
- if (ret)
- return ret;
-
- am79c961_init_for_open(dev);
-
- netif_carrier_off(dev);
-
- priv->timer.expires = jiffies;
- add_timer(&priv->timer);
-
- netif_start_queue(dev);
-
- return 0;
-}
-
-/*
- * The inverse routine to am79c961_open().
- */
-static int
-am79c961_close(struct net_device *dev)
-{
- struct dev_priv *priv = netdev_priv(dev);
- unsigned long flags;
-
- del_timer_sync(&priv->timer);
-
- netif_stop_queue(dev);
- netif_carrier_off(dev);
-
- spin_lock_irqsave(priv->chip_lock, flags);
- write_rreg (dev->base_addr, CSR0, CSR0_STOP);
- write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
- spin_unlock_irqrestore(priv->chip_lock, flags);
-
- free_irq (dev->irq, dev);
-
- return 0;
-}
-
-/*
- * Get the current statistics.
- */
-static struct net_device_stats *am79c961_getstats (struct net_device *dev)
-{
- struct dev_priv *priv = netdev_priv(dev);
- return &priv->stats;
-}
-
-static void am79c961_mc_hash(struct dev_mc_list *dmi, unsigned short *hash)
-{
- if (dmi->dmi_addrlen == ETH_ALEN && dmi->dmi_addr[0] & 0x01) {
- int idx, bit;
- u32 crc;
-
- crc = ether_crc_le(ETH_ALEN, dmi->dmi_addr);
-
- idx = crc >> 30;
- bit = (crc >> 26) & 15;
-
- hash[idx] |= 1 << bit;
- }
-}
-
-/*
- * Set or clear promiscuous/multicast mode filter for this adapter.
- */
-static void am79c961_setmulticastlist (struct net_device *dev)
-{
- struct dev_priv *priv = netdev_priv(dev);
- unsigned long flags;
- unsigned short multi_hash[4], mode;
- int i, stopped;
-
- mode = MODE_PORT_10BT;
-
- if (dev->flags & IFF_PROMISC) {
- mode |= MODE_PROMISC;
- } else if (dev->flags & IFF_ALLMULTI) {
- memset(multi_hash, 0xff, sizeof(multi_hash));
- } else {
- struct dev_mc_list *dmi;
-
- memset(multi_hash, 0x00, sizeof(multi_hash));
-
- for (dmi = dev->mc_list; dmi; dmi = dmi->next)
- am79c961_mc_hash(dmi, multi_hash);
- }
-
- spin_lock_irqsave(priv->chip_lock, flags);
-
- stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP;
-
- if (!stopped) {
- /*
- * Put the chip into suspend mode
- */
- write_rreg(dev->base_addr, CTRL1, CTRL1_SPND);
-
- /*
- * Spin waiting for chip to report suspend mode
- */
- while ((read_rreg(dev->base_addr, CTRL1) & CTRL1_SPND) == 0) {
- spin_unlock_irqrestore(priv->chip_lock, flags);
- nop();
- spin_lock_irqsave(priv->chip_lock, flags);
- }
- }
-
- /*
- * Update the multicast hash table
- */
- for (i = 0; i < sizeof(multi_hash) / sizeof(multi_hash[0]); i++)
- write_rreg(dev->base_addr, i + LADRL, multi_hash[i]);
-
- /*
- * Write the mode register
- */
- write_rreg(dev->base_addr, MODE, mode);
-
- if (!stopped) {
- /*
- * Put the chip back into running mode
- */
- write_rreg(dev->base_addr, CTRL1, 0);
- }
-
- spin_unlock_irqrestore(priv->chip_lock, flags);
-}
-
-static void am79c961_timeout(struct net_device *dev)
-{
- printk(KERN_WARNING "%s: transmit timed out, network cable problem?\n",
- dev->name);
-
- /*
- * ought to do some setup of the tx side here
- */
-
- netif_wake_queue(dev);
-}
-
-/*
- * Transmit a packet
- */
-static int
-am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev)
-{
- struct dev_priv *priv = netdev_priv(dev);
- unsigned int hdraddr, bufaddr;
- unsigned int head;
- unsigned long flags;
-
- head = priv->txhead;
- hdraddr = priv->txhdr + (head << 3);
- bufaddr = priv->txbuffer[head];
- head += 1;
- if (head >= TX_BUFFERS)
- head = 0;
-
- am_writebuffer (dev, bufaddr, skb->data, skb->len);
- am_writeword (dev, hdraddr + 4, -skb->len);
- am_writeword (dev, hdraddr + 2, TMD_OWN|TMD_STP|TMD_ENP);
- priv->txhead = head;
-
- spin_lock_irqsave(priv->chip_lock, flags);
- write_rreg (dev->base_addr, CSR0, CSR0_TDMD|CSR0_IENA);
- dev->trans_start = jiffies;
- spin_unlock_irqrestore(priv->chip_lock, flags);
-
- /*
- * If the next packet is owned by the ethernet device,
- * then the tx ring is full and we can't add another
- * packet.
- */
- if (am_readword(dev, priv->txhdr + (priv->txhead << 3) + 2) & TMD_OWN)
- netif_stop_queue(dev);
-
- dev_kfree_skb(skb);
-
- return 0;
-}
-
-/*
- * If we have a good packet(s), get it/them out of the buffers.
- */
-static void
-am79c961_rx(struct net_device *dev, struct dev_priv *priv)
-{
- do {
- struct sk_buff *skb;
- u_int hdraddr;
- u_int pktaddr;
- u_int status;
- int len;
-
- hdraddr = priv->rxhdr + (priv->rxtail << 3);
- pktaddr = priv->rxbuffer[priv->rxtail];
-
- status = am_readword (dev, hdraddr + 2);
- if (status & RMD_OWN) /* do we own it? */
- break;
-
- priv->rxtail ++;
- if (priv->rxtail >= RX_BUFFERS)
- priv->rxtail = 0;
-
- if ((status & (RMD_ERR|RMD_STP|RMD_ENP)) != (RMD_STP|RMD_ENP)) {
- am_writeword (dev, hdraddr + 2, RMD_OWN);
- priv->stats.rx_errors ++;
- if (status & RMD_ERR) {
- if (status & RMD_FRAM)
- priv->stats.rx_frame_errors ++;
- if (status & RMD_CRC)
- priv->stats.rx_crc_errors ++;
- } else if (status & RMD_STP)
- priv->stats.rx_length_errors ++;
- continue;
- }
-
- len = am_readword(dev, hdraddr + 6);
- skb = dev_alloc_skb(len + 2);
-
- if (skb) {
- skb->dev = dev;
- skb_reserve(skb, 2);
-
- am_readbuffer(dev, pktaddr, skb_put(skb, len), len);
- am_writeword(dev, hdraddr + 2, RMD_OWN);
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- priv->stats.rx_bytes += len;
- priv->stats.rx_packets ++;
- } else {
- am_writeword (dev, hdraddr + 2, RMD_OWN);
- printk (KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name);
- priv->stats.rx_dropped ++;
- break;
- }
- } while (1);
-}
-
-/*
- * Update stats for the transmitted packet
- */
-static void
-am79c961_tx(struct net_device *dev, struct dev_priv *priv)
-{
- do {
- short len;
- u_int hdraddr;
- u_int status;
-
- hdraddr = priv->txhdr + (priv->txtail << 3);
- status = am_readword (dev, hdraddr + 2);
- if (status & TMD_OWN)
- break;
-
- priv->txtail ++;
- if (priv->txtail >= TX_BUFFERS)
- priv->txtail = 0;
-
- if (status & TMD_ERR) {
- u_int status2;
-
- priv->stats.tx_errors ++;
-
- status2 = am_readword (dev, hdraddr + 6);
-
- /*
- * Clear the error byte
- */
- am_writeword (dev, hdraddr + 6, 0);
-
- if (status2 & TST_RTRY)
- priv->stats.collisions += 16;
- if (status2 & TST_LCOL)
- priv->stats.tx_window_errors ++;
- if (status2 & TST_LCAR)
- priv->stats.tx_carrier_errors ++;
- if (status2 & TST_UFLO)
- priv->stats.tx_fifo_errors ++;
- continue;
- }
- priv->stats.tx_packets ++;
- len = am_readword (dev, hdraddr + 4);
- priv->stats.tx_bytes += -len;
- } while (priv->txtail != priv->txhead);
-
- netif_wake_queue(dev);
-}
-
-static irqreturn_t
-am79c961_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct net_device *dev = (struct net_device *)dev_id;
- struct dev_priv *priv = netdev_priv(dev);
- u_int status, n = 100;
- int handled = 0;
-
- do {
- status = read_rreg(dev->base_addr, CSR0);
- write_rreg(dev->base_addr, CSR0, status &
- (CSR0_IENA|CSR0_TINT|CSR0_RINT|
- CSR0_MERR|CSR0_MISS|CSR0_CERR|CSR0_BABL));
-
- if (status & CSR0_RINT) {
- handled = 1;
- am79c961_rx(dev, priv);
- }
- if (status & CSR0_TINT) {
- handled = 1;
- am79c961_tx(dev, priv);
- }
- if (status & CSR0_MISS) {
- handled = 1;
- priv->stats.rx_dropped ++;
- }
- if (status & CSR0_CERR) {
- handled = 1;
- mod_timer(&priv->timer, jiffies);
- }
- } while (--n && status & (CSR0_RINT | CSR0_TINT));
-
- return IRQ_RETVAL(handled);
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void am79c961_poll_controller(struct net_device *dev)
-{
- unsigned long flags;
- local_irq_save(flags);
- am79c961_interrupt(dev->irq, dev, NULL);
- local_irq_restore(flags);
-}
-#endif
-
-/*
- * Initialise the chip. Note that we always expect
- * to be entered with interrupts enabled.
- */
-static int
-am79c961_hw_init(struct net_device *dev)
-{
- struct dev_priv *priv = netdev_priv(dev);
-
- spin_lock_irq(&priv->chip_lock);
- write_rreg (dev->base_addr, CSR0, CSR0_STOP);
- write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
- spin_unlock_irq(&priv->chip_lock);
-
- am79c961_ramtest(dev, 0x66);
- am79c961_ramtest(dev, 0x99);
-
- return 0;
-}
-
-static void __init am79c961_banner(void)
-{
- static unsigned version_printed;
-
- if (net_debug && version_printed++ == 0)
- printk(KERN_INFO "%s", version);
-}
-
-static int __init am79c961_init(void)
-{
- struct net_device *dev;
- struct dev_priv *priv;
- int i, ret;
-
- dev = alloc_etherdev(sizeof(struct dev_priv));
- ret = -ENOMEM;
- if (!dev)
- goto out;
-
- priv = netdev_priv(dev);
-
- /*
- * Fixed address and IRQ lines here.
- * The PNP initialisation should have been
- * done by the ether bootp loader.
- */
- dev->base_addr = 0x220;
- dev->irq = IRQ_EBSA110_ETHERNET;
-
- ret = -ENODEV;
- if (!request_region(dev->base_addr, 0x18, dev->name))
- goto nodev;
-
- /*
- * Reset the device.
- */
- inb(dev->base_addr + NET_RESET);
- udelay(5);
-
- /*
- * Check the manufacturer part of the
- * ether address.
- */
- if (inb(dev->base_addr) != 0x08 ||
- inb(dev->base_addr + 2) != 0x00 ||
- inb(dev->base_addr + 4) != 0x2b)
- goto release;
-
- am79c961_banner();
- printk(KERN_INFO "%s: ether address ", dev->name);
-
- /* Retrive and print the ethernet address. */
- for (i = 0; i < 6; i++) {
- dev->dev_addr[i] = inb(dev->base_addr + i * 2) & 0xff;
- printk (i == 5 ? "%02x\n" : "%02x:", dev->dev_addr[i]);
- }
-
- spin_lock_init(&priv->chip_lock);
- init_timer(&priv->timer);
- priv->timer.data = (unsigned long)dev;
- priv->timer.function = am79c961_timer;
-
- if (am79c961_hw_init(dev))
- goto release;
-
- dev->open = am79c961_open;
- dev->stop = am79c961_close;
- dev->hard_start_xmit = am79c961_sendpacket;
- dev->get_stats = am79c961_getstats;
- dev->set_multicast_list = am79c961_setmulticastlist;
- dev->tx_timeout = am79c961_timeout;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = am79c961_poll_controller;
-#endif
-
- ret = register_netdev(dev);
- if (ret == 0)
- return 0;
-
-release:
- release_region(dev->base_addr, 0x18);
-nodev:
- free_netdev(dev);
-out:
- return ret;
-}
-
-__initcall(am79c961_init);
diff --git a/drivers/net/arm/am79c961a.h b/drivers/net/arm/am79c961a.h
deleted file mode 100644
index 1e9b05050cb..00000000000
--- a/drivers/net/arm/am79c961a.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * linux/drivers/net/am79c961.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _LINUX_am79c961a_H
-#define _LINUX_am79c961a_H
-
-/* use 0 for production, 1 for verification, >2 for debug. debug flags: */
-#define DEBUG_TX 2
-#define DEBUG_RX 4
-#define DEBUG_INT 8
-#define DEBUG_IC 16
-#ifndef NET_DEBUG
-#define NET_DEBUG 0
-#endif
-
-#define NET_UID 0
-#define NET_RDP 0x10
-#define NET_RAP 0x12
-#define NET_RESET 0x14
-#define NET_IDP 0x16
-
-/*
- * RAP registers
- */
-#define CSR0 0
-#define CSR0_INIT 0x0001
-#define CSR0_STRT 0x0002
-#define CSR0_STOP 0x0004
-#define CSR0_TDMD 0x0008
-#define CSR0_TXON 0x0010
-#define CSR0_RXON 0x0020
-#define CSR0_IENA 0x0040
-#define CSR0_INTR 0x0080
-#define CSR0_IDON 0x0100
-#define CSR0_TINT 0x0200
-#define CSR0_RINT 0x0400
-#define CSR0_MERR 0x0800
-#define CSR0_MISS 0x1000
-#define CSR0_CERR 0x2000
-#define CSR0_BABL 0x4000
-#define CSR0_ERR 0x8000
-
-#define CSR3 3
-#define CSR3_EMBA 0x0008
-#define CSR3_DXMT2PD 0x0010
-#define CSR3_LAPPEN 0x0020
-#define CSR3_DXSUFLO 0x0040
-#define CSR3_IDONM 0x0100
-#define CSR3_TINTM 0x0200
-#define CSR3_RINTM 0x0400
-#define CSR3_MERRM 0x0800
-#define CSR3_MISSM 0x1000
-#define CSR3_BABLM 0x4000
-#define CSR3_MASKALL 0x5F00
-
-#define CSR4 4
-#define CSR4_JABM 0x0001
-#define CSR4_JAB 0x0002
-#define CSR4_TXSTRTM 0x0004
-#define CSR4_TXSTRT 0x0008
-#define CSR4_RCVCCOM 0x0010
-#define CSR4_RCVCCO 0x0020
-#define CSR4_MFCOM 0x0100
-#define CSR4_MFCO 0x0200
-#define CSR4_ASTRP_RCV 0x0400
-#define CSR4_APAD_XMIT 0x0800
-
-#define CTRL1 5
-#define CTRL1_SPND 0x0001
-
-#define LADRL 8
-#define LADRM1 9
-#define LADRM2 10
-#define LADRH 11
-#define PADRL 12
-#define PADRM 13
-#define PADRH 14
-
-#define MODE 15
-#define MODE_DISRX 0x0001
-#define MODE_DISTX 0x0002
-#define MODE_LOOP 0x0004
-#define MODE_DTCRC 0x0008
-#define MODE_COLL 0x0010
-#define MODE_DRETRY 0x0020
-#define MODE_INTLOOP 0x0040
-#define MODE_PORT_AUI 0x0000
-#define MODE_PORT_10BT 0x0080
-#define MODE_DRXPA 0x2000
-#define MODE_DRXBA 0x4000
-#define MODE_PROMISC 0x8000
-
-#define BASERXL 24
-#define BASERXH 25
-#define BASETXL 30
-#define BASETXH 31
-
-#define POLLINT 47
-
-#define SIZERXR 76
-#define SIZETXR 78
-
-#define CSR_MFC 112
-
-#define RMD_ENP 0x0100
-#define RMD_STP 0x0200
-#define RMD_CRC 0x0800
-#define RMD_FRAM 0x2000
-#define RMD_ERR 0x4000
-#define RMD_OWN 0x8000
-
-#define TMD_ENP 0x0100
-#define TMD_STP 0x0200
-#define TMD_MORE 0x1000
-#define TMD_ERR 0x4000
-#define TMD_OWN 0x8000
-
-#define TST_RTRY 0x0400
-#define TST_LCAR 0x0800
-#define TST_LCOL 0x1000
-#define TST_UFLO 0x4000
-#define TST_BUFF 0x8000
-
-#define ISALED0 0x0004
-#define ISALED0_LNKST 0x8000
-
-struct dev_priv {
- struct net_device_stats stats;
- unsigned long rxbuffer[RX_BUFFERS];
- unsigned long txbuffer[TX_BUFFERS];
- unsigned char txhead;
- unsigned char txtail;
- unsigned char rxhead;
- unsigned char rxtail;
- unsigned long rxhdr;
- unsigned long txhdr;
- spinlock_t chip_lock;
- struct timer_list timer;
-};
-
-extern int am79c961_probe (struct net_device *dev);
-
-#endif
diff --git a/drivers/net/arm/ether00.c b/drivers/net/arm/ether00.c
deleted file mode 100644
index 4f1f4e31bda..00000000000
--- a/drivers/net/arm/ether00.c
+++ /dev/null
@@ -1,1017 +0,0 @@
-/*
- * drivers/net/ether00.c
- *
- * Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* includes */
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <linux/etherdevice.h>
-#include <linux/module.h>
-#include <linux/tqueue.h>
-#include <linux/mtd/mtd.h>
-#include <linux/pld/pld_hotswap.h>
-#include <asm/arch/excalibur.h>
-#include <asm/arch/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/sizes.h>
-
-#include <asm/arch/ether00.h>
-#include <asm/arch/tdkphy.h>
-
-
-MODULE_AUTHOR("Clive Davies");
-MODULE_DESCRIPTION("Altera Ether00 IP core driver");
-MODULE_LICENSE("GPL");
-
-#define PKT_BUF_SZ 1540 /* Size of each rx buffer */
-#define ETH_NR 4 /* Number of MACs this driver supports */
-
-#define DEBUG(x)
-
-#define __dma_va(x) (unsigned int)((unsigned int)priv->dma_data+(((unsigned int)(x))&(EXC_SPSRAM_BLOCK0_SIZE-1)))
-#define __dma_pa(x) (unsigned int)(EXC_SPSRAM_BLOCK0_BASE+(((unsigned int)(x))-(unsigned int)priv->dma_data))
-
-#define ETHER00_BASE 0
-#define ETHER00_TYPE
-#define ETHER00_NAME "ether00"
-#define MAC_REG_SIZE 0x400 /* size of MAC register area */
-
-
-
-/* typedefs */
-
-/* The definition of the driver control structure */
-
-#define RX_NUM_BUFF 10
-#define RX_NUM_FDESC 10
-#define TX_NUM_FDESC 10
-
-struct tx_fda_ent{
- FDA_DESC fd;
- BUF_DESC bd;
- BUF_DESC pad;
-};
-struct rx_fda_ent{
- FDA_DESC fd;
- BUF_DESC bd;
- BUF_DESC pad;
-};
-struct rx_blist_ent{
- FDA_DESC fd;
- BUF_DESC bd;
- BUF_DESC pad;
-};
-struct net_priv
-{
- struct net_device_stats stats;
- struct sk_buff* skb;
- void* dma_data;
- struct rx_blist_ent* rx_blist_vp;
- struct rx_fda_ent* rx_fda_ptr;
- struct tx_fda_ent* tx_fdalist_vp;
- struct tq_struct tq_memupdate;
- unsigned char memupdate_scheduled;
- unsigned char rx_disabled;
- unsigned char queue_stopped;
- spinlock_t rx_lock;
-};
-
-static const char vendor_id[2]={0x07,0xed};
-
-#ifdef ETHER00_DEBUG
-
-/* Dump (most) registers for debugging puposes */
-
-static void dump_regs(struct net_device *dev){
- struct net_priv* priv=dev->priv;
- unsigned int* i;
-
- printk("\n RX free descriptor area:\n");
-
- for(i=(unsigned int*)priv->rx_fda_ptr;
- i<((unsigned int*)(priv->rx_fda_ptr+RX_NUM_FDESC));){
- printk("%#8x %#8x %#8x %#8x\n",*i,*(i+1),*(i+2),*(i+3));
- i+=4;
- }
-
- printk("\n RX buffer list:\n");
-
- for(i=(unsigned int*)priv->rx_blist_vp;
- i<((unsigned int*)(priv->rx_blist_vp+RX_NUM_BUFF));){
- printk("%#8x %#8x %#8x %#8x\n",*i,*(i+1),*(i+2),*(i+3));
- i+=4;
- }
-
- printk("\n TX frame descriptor list:\n");
-
- for(i=(unsigned int*)priv->tx_fdalist_vp;
- i<((unsigned int*)(priv->tx_fdalist_vp+TX_NUM_FDESC));){
- printk("%#8x %#8x %#8x %#8x\n",*i,*(i+1),*(i+2),*(i+3));
- i+=4;
- }
-
- printk("\ndma ctl=%#x\n",readw(ETHER_DMA_CTL(dev->base_addr)));
- printk("txfrmptr=%#x\n",readw(ETHER_TXFRMPTR(dev->base_addr)));
- printk("txthrsh=%#x\n",readw(ETHER_TXTHRSH(dev->base_addr)));
- printk("txpollctr=%#x\n",readw(ETHER_TXPOLLCTR(dev->base_addr)));
- printk("blfrmptr=%#x\n",readw(ETHER_BLFRMPTR(dev->base_addr)));
- printk("rxfragsize=%#x\n",readw(ETHER_RXFRAGSIZE(dev->base_addr)));
- printk("tx_int_en=%#x\n",readw(ETHER_INT_EN(dev->base_addr)));
- printk("fda_bas=%#x\n",readw(ETHER_FDA_BAS(dev->base_addr)));
- printk("fda_lim=%#x\n",readw(ETHER_FDA_LIM(dev->base_addr)));
- printk("int_src=%#x\n",readw(ETHER_INT_SRC(dev->base_addr)));
- printk("pausecnt=%#x\n",readw(ETHER_PAUSECNT(dev->base_addr)));
- printk("rempaucnt=%#x\n",readw(ETHER_REMPAUCNT(dev->base_addr)));
- printk("txconfrmstat=%#x\n",readw(ETHER_TXCONFRMSTAT(dev->base_addr)));
- printk("mac_ctl=%#x\n",readw(ETHER_MAC_CTL(dev->base_addr)));
- printk("arc_ctl=%#x\n",readw(ETHER_ARC_CTL(dev->base_addr)));
- printk("tx_ctl=%#x\n",readw(ETHER_TX_CTL(dev->base_addr)));
-}
-#endif /* ETHER00_DEBUG */
-
-
-static int ether00_write_phy(struct net_device *dev, short address, short value)
-{
- volatile int count = 1024;
- writew(value,ETHER_MD_DATA(dev->base_addr));
- writew( ETHER_MD_CA_BUSY_MSK |
- ETHER_MD_CA_WR_MSK |
- (address & ETHER_MD_CA_ADDR_MSK),
- ETHER_MD_CA(dev->base_addr));
-
- /* Wait for the command to complete */
- while((readw(ETHER_MD_CA(dev->base_addr)) & ETHER_MD_CA_BUSY_MSK)&&count){
- count--;
- }
- if (!count){
- printk("Write to phy failed, addr=%#x, data=%#x\n",address, value);
- return -EIO;
- }
- return 0;
-}
-
-static int ether00_read_phy(struct net_device *dev, short address)
-{
- volatile int count = 1024;
- writew( ETHER_MD_CA_BUSY_MSK |
- (address & ETHER_MD_CA_ADDR_MSK),
- ETHER_MD_CA(dev->base_addr));
-
- /* Wait for the command to complete */
- while((readw(ETHER_MD_CA(dev->base_addr)) & ETHER_MD_CA_BUSY_MSK)&&count){
- count--;
- }
- if (!count){
- printk(KERN_WARNING "Read from phy timed out\n");
- return -EIO;
- }
- return readw(ETHER_MD_DATA(dev->base_addr));
-}
-
-static void ether00_phy_int(int irq_num, void* dev_id, struct pt_regs* regs)
-{
- struct net_device* dev=dev_id;
- int irq_status;
-
- irq_status=ether00_read_phy(dev, PHY_IRQ_CONTROL);
-
- if(irq_status & PHY_IRQ_CONTROL_ANEG_COMP_INT_MSK){
- /*
- * Autonegotiation complete on epxa10db. The mac doesn't
- * twig if we're in full duplex so we need to check the
- * phy status register and configure the mac accordingly
- */
- if(ether00_read_phy(dev, PHY_STATUS)&(PHY_STATUS_10T_F_MSK|PHY_STATUS_100_X_F_MSK)){
- int tmp;
- tmp=readl(ETHER_MAC_CTL(dev->base_addr));
- writel(tmp|ETHER_MAC_CTL_FULLDUP_MSK,ETHER_MAC_CTL(dev->base_addr));
- }
- }
-
- if(irq_status&PHY_IRQ_CONTROL_LS_CHG_INT_MSK){
-
- if(ether00_read_phy(dev, PHY_STATUS)& PHY_STATUS_LINK_MSK){
- /* Link is up */
- netif_carrier_on(dev);
- //printk("Carrier on\n");
- }else{
- netif_carrier_off(dev);
- //printk("Carrier off\n");
-
- }
- }
-
-}
-
-static void setup_blist_entry(struct sk_buff* skb,struct rx_blist_ent* blist_ent_ptr){
- /* Make the buffer consistent with the cache as the mac is going to write
- * directly into it*/
- blist_ent_ptr->fd.FDSystem=(unsigned int)skb;
- blist_ent_ptr->bd.BuffData=(char*)__pa(skb->data);
- consistent_sync(skb->data,PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
- /* align IP on 16 Byte (DMA_CTL set to skip 2 bytes) */
- skb_reserve(skb,2);
- blist_ent_ptr->bd.BuffLength=PKT_BUF_SZ-2;
- blist_ent_ptr->fd.FDLength=1;
- blist_ent_ptr->fd.FDCtl=FDCTL_COWNSFD_MSK;
- blist_ent_ptr->bd.BDCtl=BDCTL_COWNSBD_MSK;
-}
-
-
-static int ether00_mem_init(struct net_device* dev)
-{
- struct net_priv* priv=dev->priv;
- struct tx_fda_ent *tx_fd_ptr,*tx_end_ptr;
- struct rx_blist_ent* blist_ent_ptr;
- int i;
-
- /*
- * Grab a block of on chip SRAM to contain the control stuctures for
- * the ethernet MAC. This uncached becuase it needs to be accesses by both
- * bus masters (cpu + mac). However, it shouldn't matter too much in terms
- * of speed as its on chip memory
- */
- priv->dma_data=ioremap_nocache(EXC_SPSRAM_BLOCK0_BASE,EXC_SPSRAM_BLOCK0_SIZE );
- if (!priv->dma_data)
- return -ENOMEM;
-
- priv->rx_fda_ptr=(struct rx_fda_ent*)priv->dma_data;
- /*
- * Now share it out amongst the Frame descriptors and the buffer list
- */
- priv->rx_blist_vp=(struct rx_blist_ent*)((unsigned int)priv->dma_data+RX_NUM_FDESC*sizeof(struct rx_fda_ent));
-
- /*
- *Initalise the FDA list
- */
- /* set ownership to the controller */
- memset(priv->rx_fda_ptr,0x80,RX_NUM_FDESC*sizeof(struct rx_fda_ent));
-
- /*
- *Initialise the buffer list
- */
- blist_ent_ptr=priv->rx_blist_vp;
- i=0;
- while(blist_ent_ptr<(priv->rx_blist_vp+RX_NUM_BUFF)){
- struct sk_buff *skb;
- blist_ent_ptr->fd.FDLength=1;
- skb=dev_alloc_skb(PKT_BUF_SZ);
- if(skb){
- setup_blist_entry(skb,blist_ent_ptr);
- blist_ent_ptr->fd.FDNext=(FDA_DESC*)__dma_pa(blist_ent_ptr+1);
- blist_ent_ptr->bd.BDStat=i++;
- blist_ent_ptr++;
- }
- else
- {
- printk("Failed to initalise buffer list\n");
- }
-
- }
- blist_ent_ptr--;
- blist_ent_ptr->fd.FDNext=(FDA_DESC*)__dma_pa(priv->rx_blist_vp);
-
- priv->tx_fdalist_vp=(struct tx_fda_ent*)(priv->rx_blist_vp+RX_NUM_BUFF);
-
- /* Initialise the buffers to be a circular list. The mac will then go poll
- * the list until it finds a frame ready to transmit */
- tx_end_ptr=priv->tx_fdalist_vp+TX_NUM_FDESC;
- for(tx_fd_ptr=priv->tx_fdalist_vp;tx_fd_ptr<tx_end_ptr;tx_fd_ptr++){
- tx_fd_ptr->fd.FDNext=(FDA_DESC*)__dma_pa((tx_fd_ptr+1));
- tx_fd_ptr->fd.FDCtl=1;
- tx_fd_ptr->fd.FDStat=0;
- tx_fd_ptr->fd.FDLength=1;
-
- }
- /* Change the last FDNext pointer to make a circular list */
- tx_fd_ptr--;
- tx_fd_ptr->fd.FDNext=(FDA_DESC*)__dma_pa(priv->tx_fdalist_vp);
-
- /* Point the device at the chain of Rx and Tx Buffers */
- writel((unsigned int)__dma_pa(priv->rx_fda_ptr),ETHER_FDA_BAS(dev->base_addr));
- writel((RX_NUM_FDESC-1)*sizeof(struct rx_fda_ent),ETHER_FDA_LIM(dev->base_addr));
- writel((unsigned int)__dma_pa(priv->rx_blist_vp),ETHER_BLFRMPTR(dev->base_addr));
-
- writel((unsigned int)__dma_pa(priv->tx_fdalist_vp),ETHER_TXFRMPTR(dev->base_addr));
-
- return 0;
-}
-
-
-void ether00_mem_update(void* dev_id)
-{
- struct net_device* dev=dev_id;
- struct net_priv* priv=dev->priv;
- struct sk_buff* skb;
- struct tx_fda_ent *fda_ptr=priv->tx_fdalist_vp;
- struct rx_blist_ent* blist_ent_ptr;
- unsigned long flags;
-
- priv->tq_memupdate.sync=0;
- //priv->tq_memupdate.list=
- priv->memupdate_scheduled=0;
-
- /* Transmit interrupt */
- while(fda_ptr<(priv->tx_fdalist_vp+TX_NUM_FDESC)){
- if(!(FDCTL_COWNSFD_MSK&fda_ptr->fd.FDCtl) && (ETHER_TX_STAT_COMP_MSK&fda_ptr->fd.FDStat)){
- priv->stats.tx_packets++;
- priv->stats.tx_bytes+=fda_ptr->bd.BuffLength;
- skb=(struct sk_buff*)fda_ptr->fd.FDSystem;
- //printk("%d:txcln:fda=%#x skb=%#x\n",jiffies,fda_ptr,skb);
- dev_kfree_skb(skb);
- fda_ptr->fd.FDSystem=0;
- fda_ptr->fd.FDStat=0;
- fda_ptr->fd.FDCtl=0;
- }
- fda_ptr++;
- }
- /* Fill in any missing buffers from the received queue */
- spin_lock_irqsave(&priv->rx_lock,flags);
- blist_ent_ptr=priv->rx_blist_vp;
- while(blist_ent_ptr<(priv->rx_blist_vp+RX_NUM_BUFF)){
- /* fd.FDSystem of 0 indicates we failed to allocate the buffer in the ISR */
- if(!blist_ent_ptr->fd.FDSystem){
- struct sk_buff *skb;
- skb=dev_alloc_skb(PKT_BUF_SZ);
- blist_ent_ptr->fd.FDSystem=(unsigned int)skb;
- if(skb){
- setup_blist_entry(skb,blist_ent_ptr);
- }
- else
- {
- break;
- }
- }
- blist_ent_ptr++;
- }
- spin_unlock_irqrestore(&priv->rx_lock,flags);
- if(priv->queue_stopped){
- //printk("%d:cln:start q\n",jiffies);
- netif_start_queue(dev);
- }
- if(priv->rx_disabled){
- //printk("%d:enable_irq\n",jiffies);
- priv->rx_disabled=0;
- writel(ETHER_RX_CTL_RXEN_MSK,ETHER_RX_CTL(dev->base_addr));
-
- }
-}
-
-
-static void ether00_int( int irq_num, void* dev_id, struct pt_regs* regs)
-{
- struct net_device* dev=dev_id;
- struct net_priv* priv=dev->priv;
-
- unsigned int interruptValue;
-
- interruptValue=readl(ETHER_INT_SRC(dev->base_addr));
-
- //printk("INT_SRC=%x\n",interruptValue);
-
- if(!(readl(ETHER_INT_SRC(dev->base_addr)) & ETHER_INT_SRC_IRQ_MSK))
- {
- return; /* Interrupt wasn't caused by us!! */
- }
-
- if(readl(ETHER_INT_SRC(dev->base_addr))&
- (ETHER_INT_SRC_INTMACRX_MSK |
- ETHER_INT_SRC_FDAEX_MSK |
- ETHER_INT_SRC_BLEX_MSK)) {
- struct rx_blist_ent* blist_ent_ptr;
- struct rx_fda_ent* fda_ent_ptr;
- struct sk_buff* skb;
-
- fda_ent_ptr=priv->rx_fda_ptr;
- spin_lock(&priv->rx_lock);
- while(fda_ent_ptr<(priv->rx_fda_ptr+RX_NUM_FDESC)){
- int result;
-
- if(!(fda_ent_ptr->fd.FDCtl&FDCTL_COWNSFD_MSK))
- {
- /* This frame is ready for processing */
- /*find the corresponding buffer in the bufferlist */
- blist_ent_ptr=priv->rx_blist_vp+fda_ent_ptr->bd.BDStat;
- skb=(struct sk_buff*)blist_ent_ptr->fd.FDSystem;
-
- /* Pass this skb up the stack */
- skb->dev=dev;
- skb_put(skb,fda_ent_ptr->fd.FDLength);
- skb->protocol=eth_type_trans(skb,dev);
- skb->ip_summed=CHECKSUM_UNNECESSARY;
- result=netif_rx(skb);
- /* Update statistics */
- priv->stats.rx_packets++;
- priv->stats.rx_bytes+=fda_ent_ptr->fd.FDLength;
-
- /* Free the FDA entry */
- fda_ent_ptr->bd.BDStat=0xff;
- fda_ent_ptr->fd.FDCtl=FDCTL_COWNSFD_MSK;
-
- /* Allocate a new skb and point the bd entry to it */
- blist_ent_ptr->fd.FDSystem=0;
- skb=dev_alloc_skb(PKT_BUF_SZ);
- //printk("allocskb=%#x\n",skb);
- if(skb){
- setup_blist_entry(skb,blist_ent_ptr);
-
- }
- else if(!priv->memupdate_scheduled){
- int tmp;
- /* There are no buffers at the moment, so schedule */
- /* the background task to sort this out */
- schedule_task(&priv->tq_memupdate);
- priv->memupdate_scheduled=1;
- printk(KERN_DEBUG "%s:No buffers",dev->name);
- /* If this interrupt was due to a lack of buffers then
- * we'd better stop the receiver too */
- if(interruptValue&ETHER_INT_SRC_BLEX_MSK){
- priv->rx_disabled=1;
- tmp=readl(ETHER_INT_SRC(dev->base_addr));
- writel(tmp&~ETHER_RX_CTL_RXEN_MSK,ETHER_RX_CTL(dev->base_addr));
- printk(KERN_DEBUG "%s:Halting rx",dev->name);
- }
-
- }
-
- }
- fda_ent_ptr++;
- }
- spin_unlock(&priv->rx_lock);
-
- /* Clear the interrupts */
- writel(ETHER_INT_SRC_INTMACRX_MSK | ETHER_INT_SRC_FDAEX_MSK
- | ETHER_INT_SRC_BLEX_MSK,ETHER_INT_SRC(dev->base_addr));
-
- }
-
- if(readl(ETHER_INT_SRC(dev->base_addr))&ETHER_INT_SRC_INTMACTX_MSK){
-
- if(!priv->memupdate_scheduled){
- schedule_task(&priv->tq_memupdate);
- priv->memupdate_scheduled=1;
- }
- /* Clear the interrupt */
- writel(ETHER_INT_SRC_INTMACTX_MSK,ETHER_INT_SRC(dev->base_addr));
- }
-
- if (readl(ETHER_INT_SRC(dev->base_addr)) & (ETHER_INT_SRC_SWINT_MSK|
- ETHER_INT_SRC_INTEARNOT_MSK|
- ETHER_INT_SRC_INTLINK_MSK|
- ETHER_INT_SRC_INTEXBD_MSK|
- ETHER_INT_SRC_INTTXCTLCMP_MSK))
- {
- /*
- * Not using any of these so they shouldn't happen
- *
- * In the cased of INTEXBD - if you allocate more
- * than 28 decsriptors you may need to think about this
- */
- printk("Not using this interrupt\n");
- }
-
- if (readl(ETHER_INT_SRC(dev->base_addr)) &
- (ETHER_INT_SRC_INTSBUS_MSK |
- ETHER_INT_SRC_INTNRABT_MSK
- |ETHER_INT_SRC_DMPARERR_MSK))
- {
- /*
- * Hardware errors, we can either ignore them and hope they go away
- *or reset the device, I'll try the first for now to see if they happen
- */
- printk("Hardware error\n");
- }
-}
-
-static void ether00_setup_ethernet_address(struct net_device* dev)
-{
- int tmp;
-
- dev->addr_len=6;
- writew(0,ETHER_ARC_ADR(dev->base_addr));
- writel((dev->dev_addr[0]<<24) |
- (dev->dev_addr[1]<<16) |
- (dev->dev_addr[2]<<8) |
- dev->dev_addr[3],
- ETHER_ARC_DATA(dev->base_addr));
-
- writew(4,ETHER_ARC_ADR(dev->base_addr));
- tmp=readl(ETHER_ARC_DATA(dev->base_addr));
- tmp&=0xffff;
- tmp|=(dev->dev_addr[4]<<24) | (dev->dev_addr[5]<<16);
- writel(tmp, ETHER_ARC_DATA(dev->base_addr));
- /* Enable this entry in the ARC */
-
- writel(1,ETHER_ARC_ENA(dev->base_addr));
-
- return;
-}
-
-
-static void ether00_reset(struct net_device *dev)
-{
- /* reset the controller */
- writew(ETHER_MAC_CTL_RESET_MSK,ETHER_MAC_CTL(dev->base_addr));
-
- /*
- * Make sure we're not going to send anything
- */
-
- writew(ETHER_TX_CTL_TXHALT_MSK,ETHER_TX_CTL(dev->base_addr));
-
- /*
- * Make sure we're not going to receive anything
- */
- writew(ETHER_RX_CTL_RXHALT_MSK,ETHER_RX_CTL(dev->base_addr));
-
- /*
- * Disable Interrupts for now, and set the burst size to 8 bytes
- */
-
- writel(ETHER_DMA_CTL_INTMASK_MSK |
- ((8 << ETHER_DMA_CTL_DMBURST_OFST) & ETHER_DMA_CTL_DMBURST_MSK)
- |(2<<ETHER_DMA_CTL_RXALIGN_OFST),
- ETHER_DMA_CTL(dev->base_addr));
-
-
- /*
- * Set TxThrsh - start transmitting a packet after 1514
- * bytes or when a packet is complete, whichever comes first
- */
- writew(1514,ETHER_TXTHRSH(dev->base_addr));
-
- /*
- * Set TxPollCtr. Each cycle is
- * 61.44 microseconds with a 33 MHz bus
- */
- writew(1,ETHER_TXPOLLCTR(dev->base_addr));
-
- /*
- * Set Rx_Ctl - Turn off reception and let RxData turn it
- * on later
- */
- writew(ETHER_RX_CTL_RXHALT_MSK,ETHER_RX_CTL(dev->base_addr));
-
-}
-
-
-static void ether00_set_multicast(struct net_device* dev)
-{
- int count=dev->mc_count;
-
- /* Set promiscuous mode if it's asked for. */
-
- if (dev->flags&IFF_PROMISC){
-
- writew( ETHER_ARC_CTL_COMPEN_MSK |
- ETHER_ARC_CTL_BROADACC_MSK |
- ETHER_ARC_CTL_GROUPACC_MSK |
- ETHER_ARC_CTL_STATIONACC_MSK,
- ETHER_ARC_CTL(dev->base_addr));
- return;
- }
-
- /*
- * Get all multicast packets if required, or if there are too
- * many addresses to fit in hardware
- */
- if (dev->flags & IFF_ALLMULTI){
- writew( ETHER_ARC_CTL_COMPEN_MSK |
- ETHER_ARC_CTL_GROUPACC_MSK |
- ETHER_ARC_CTL_BROADACC_MSK,
- ETHER_ARC_CTL(dev->base_addr));
- return;
- }
- if (dev->mc_count > (ETHER_ARC_SIZE - 1)){
-
- printk(KERN_WARNING "Too many multicast addresses for hardware to filter - receiving all multicast packets\n");
- writew( ETHER_ARC_CTL_COMPEN_MSK |
- ETHER_ARC_CTL_GROUPACC_MSK |
- ETHER_ARC_CTL_BROADACC_MSK,
- ETHER_ARC_CTL(dev->base_addr));
- return;
- }
-
- if(dev->mc_count){
- struct dev_mc_list *mc_list_ent=dev->mc_list;
- unsigned int temp,i;
- DEBUG(printk("mc_count=%d mc_list=%#x\n",dev-> mc_count, dev->mc_list));
- DEBUG(printk("mc addr=%02#x%02x%02x%02x%02x%02x\n",
- mc_list_ent->dmi_addr[5],
- mc_list_ent->dmi_addr[4],
- mc_list_ent->dmi_addr[3],
- mc_list_ent->dmi_addr[2],
- mc_list_ent->dmi_addr[1],
- mc_list_ent->dmi_addr[0]);)
-
- /*
- * The first 6 bytes are the MAC address, so
- * don't change them!
- */
- writew(4,ETHER_ARC_ADR(dev->base_addr));
- temp=readl(ETHER_ARC_DATA(dev->base_addr));
- temp&=0xffff0000;
-
- /* Disable the current multicast stuff */
- writel(1,ETHER_ARC_ENA(dev->base_addr));
-
- for(;;){
- temp|=mc_list_ent->dmi_addr[1] |
- mc_list_ent->dmi_addr[0]<<8;
- writel(temp,ETHER_ARC_DATA(dev->base_addr));
-
- i=readl(ETHER_ARC_ADR(dev->base_addr));
- writew(i+4,ETHER_ARC_ADR(dev->base_addr));
-
- temp=mc_list_ent->dmi_addr[5]|
- mc_list_ent->dmi_addr[4]<<8 |
- mc_list_ent->dmi_addr[3]<<16 |
- mc_list_ent->dmi_addr[2]<<24;
- writel(temp,ETHER_ARC_DATA(dev->base_addr));
-
- count--;
- if(!mc_list_ent->next || !count){
- break;
- }
- DEBUG(printk("mc_list_next=%#x\n",mc_list_ent->next);)
- mc_list_ent=mc_list_ent->next;
-
-
- i=readl(ETHER_ARC_ADR(dev->base_addr));
- writel(i+4,ETHER_ARC_ADR(dev->base_addr));
-
- temp=mc_list_ent->dmi_addr[3]|
- mc_list_ent->dmi_addr[2]<<8 |
- mc_list_ent->dmi_addr[1]<<16 |
- mc_list_ent->dmi_addr[0]<<24;
- writel(temp,ETHER_ARC_DATA(dev->base_addr));
-
- i=readl(ETHER_ARC_ADR(dev->base_addr));
- writel(i+4,ETHER_ARC_ADR(dev->base_addr));
-
- temp=mc_list_ent->dmi_addr[4]<<16 |
- mc_list_ent->dmi_addr[5]<<24;
-
- writel(temp,ETHER_ARC_DATA(dev->base_addr));
-
- count--;
- if(!mc_list_ent->next || !count){
- break;
- }
- mc_list_ent=mc_list_ent->next;
- }
-
-
- if(count)
- printk(KERN_WARNING "Multicast list size error\n");
-
-
- writew( ETHER_ARC_CTL_BROADACC_MSK|
- ETHER_ARC_CTL_COMPEN_MSK,
- ETHER_ARC_CTL(dev->base_addr));
-
- }
-
- /* enable the active ARC enties */
- writew((1<<(count+2))-1,ETHER_ARC_ENA(dev->base_addr));
-}
-
-
-static int ether00_open(struct net_device* dev)
-{
- int result,tmp;
- struct net_priv* priv;
-
- if (!is_valid_ether_addr(dev->dev_addr))
- return -EINVAL;
-
- /* Install interrupt handlers */
- result=request_irq(dev->irq,ether00_int,0,"ether00",dev);
- if(result)
- goto open_err1;
-
- result=request_irq(2,ether00_phy_int,0,"ether00_phy",dev);
- if(result)
- goto open_err2;
-
- ether00_reset(dev);
- result=ether00_mem_init(dev);
- if(result)
- goto open_err3;
-
-
- ether00_setup_ethernet_address(dev);
-
- ether00_set_multicast(dev);
-
- result=ether00_write_phy(dev,PHY_CONTROL, PHY_CONTROL_ANEGEN_MSK | PHY_CONTROL_RANEG_MSK);
- if(result)
- goto open_err4;
- result=ether00_write_phy(dev,PHY_IRQ_CONTROL, PHY_IRQ_CONTROL_LS_CHG_IE_MSK |
- PHY_IRQ_CONTROL_ANEG_COMP_IE_MSK);
- if(result)
- goto open_err4;
-
- /* Start the device enable interrupts */
- writew(ETHER_RX_CTL_RXEN_MSK
-// | ETHER_RX_CTL_STRIPCRC_MSK
- | ETHER_RX_CTL_ENGOOD_MSK
- | ETHER_RX_CTL_ENRXPAR_MSK| ETHER_RX_CTL_ENLONGERR_MSK
- | ETHER_RX_CTL_ENOVER_MSK| ETHER_RX_CTL_ENCRCERR_MSK,
- ETHER_RX_CTL(dev->base_addr));
-
- writew(ETHER_TX_CTL_TXEN_MSK|
- ETHER_TX_CTL_ENEXDEFER_MSK|
- ETHER_TX_CTL_ENLCARR_MSK|
- ETHER_TX_CTL_ENEXCOLL_MSK|
- ETHER_TX_CTL_ENLATECOLL_MSK|
- ETHER_TX_CTL_ENTXPAR_MSK|
- ETHER_TX_CTL_ENCOMP_MSK,
- ETHER_TX_CTL(dev->base_addr));
-
- tmp=readl(ETHER_DMA_CTL(dev->base_addr));
- writel(tmp&~ETHER_DMA_CTL_INTMASK_MSK,ETHER_DMA_CTL(dev->base_addr));
-
- return 0;
-
- open_err4:
- ether00_reset(dev);
- open_err3:
- free_irq(2,dev);
- open_err2:
- free_irq(dev->irq,dev);
- open_err1:
- return result;
-
-}
-
-
-static int ether00_tx(struct sk_buff* skb, struct net_device* dev)
-{
- struct net_priv *priv=dev->priv;
- struct tx_fda_ent *fda_ptr;
- int i;
-
-
- /*
- * Find an empty slot in which to stick the frame
- */
- fda_ptr=(struct tx_fda_ent*)__dma_va(readl(ETHER_TXFRMPTR(dev->base_addr)));
- i=0;
- while(i<TX_NUM_FDESC){
- if (fda_ptr->fd.FDStat||(fda_ptr->fd.FDCtl & FDCTL_COWNSFD_MSK)){
- fda_ptr =(struct tx_fda_ent*) __dma_va((struct tx_fda_ent*)fda_ptr->fd.FDNext);
- }
- else {
- break;
- }
- i++;
- }
-
- /* Write the skb data from the cache*/
- consistent_sync(skb->data,skb->len,PCI_DMA_TODEVICE);
- fda_ptr->bd.BuffData=(char*)__pa(skb->data);
- fda_ptr->bd.BuffLength=(unsigned short)skb->len;
- /* Save the pointer to the skb for freeing later */
- fda_ptr->fd.FDSystem=(unsigned int)skb;
- fda_ptr->fd.FDStat=0;
- /* Pass ownership of the buffers to the controller */
- fda_ptr->fd.FDCtl=1;
- fda_ptr->fd.FDCtl|=FDCTL_COWNSFD_MSK;
-
- /* If the next buffer in the list is full, stop the queue */
- fda_ptr=(struct tx_fda_ent*)__dma_va(fda_ptr->fd.FDNext);
- if ((fda_ptr->fd.FDStat)||(fda_ptr->fd.FDCtl & FDCTL_COWNSFD_MSK)){
- netif_stop_queue(dev);
- priv->queue_stopped=1;
- }
-
- return 0;
-}
-
-static struct net_device_stats *ether00_stats(struct net_device* dev)
-{
- struct net_priv *priv=dev->priv;
- return &priv->stats;
-}
-
-
-static int ether00_stop(struct net_device* dev)
-{
- struct net_priv *priv=dev->priv;
- int tmp;
-
- /* Stop/disable the device. */
- tmp=readw(ETHER_RX_CTL(dev->base_addr));
- tmp&=~(ETHER_RX_CTL_RXEN_MSK | ETHER_RX_CTL_ENGOOD_MSK);
- tmp|=ETHER_RX_CTL_RXHALT_MSK;
- writew(tmp,ETHER_RX_CTL(dev->base_addr));
-
- tmp=readl(ETHER_TX_CTL(dev->base_addr));
- tmp&=~ETHER_TX_CTL_TXEN_MSK;
- tmp|=ETHER_TX_CTL_TXHALT_MSK;
- writel(tmp,ETHER_TX_CTL(dev->base_addr));
-
- /* Free up system resources */
- free_irq(dev->irq,dev);
- free_irq(2,dev);
- iounmap(priv->dma_data);
-
- return 0;
-}
-
-
-static void ether00_get_ethernet_address(struct net_device* dev)
-{
- struct mtd_info *mymtd=NULL;
- int i;
- size_t retlen;
-
- /*
- * For the Epxa10 dev board (camelot), the ethernet MAC
- * address is of the form 00:aa:aa:00:xx:xx where
- * 00:aa:aa is the Altera vendor ID and xx:xx is the
- * last 2 bytes of the board serial number, as programmed
- * into the OTP area of the flash device on EBI1. If this
- * isn't an expa10 dev board, or there's no mtd support to
- * read the serial number from flash then we'll force the
- * use to set their own mac address using ifconfig.
- */
-
-#ifdef CONFIG_ARCH_CAMELOT
-#ifdef CONFIG_MTD
- /* get the mtd_info structure for the first mtd device*/
- for(i=0;i<MAX_MTD_DEVICES;i++){
- mymtd=get_mtd_device(NULL,i);
- if(!mymtd||!strcmp(mymtd->name,"EPXA10DB flash"))
- break;
- }
-
- if(!mymtd || !mymtd->read_user_prot_reg){
- printk(KERN_WARNING "%s: Failed to read MAC address from flash\n",dev->name);
- }else{
- mymtd->read_user_prot_reg(mymtd,2,1,&retlen,&dev->dev_addr[5]);
- mymtd->read_user_prot_reg(mymtd,3,1,&retlen,&dev->dev_addr[4]);
- dev->dev_addr[3]=0;
- dev->dev_addr[2]=vendor_id[1];
- dev->dev_addr[1]=vendor_id[0];
- dev->dev_addr[0]=0;
- }
-#else
- printk(KERN_WARNING "%s: MTD support required to read MAC address from EPXA10 dev board\n", dev->name);
-#endif
-#endif
-
- if (!is_valid_ether_addr(dev->dev_addr))
- printk("%s: Invalid ethernet MAC address. Please set using "
- "ifconfig\n", dev->name);
-
-}
-
-/*
- * Keep a mapping of dev_info addresses -> port lines to use when
- * removing ports dev==NULL indicates unused entry
- */
-
-
-static struct net_device* dev_list[ETH_NR];
-
-static int ether00_add_device(struct pldhs_dev_info* dev_info,void* dev_ps_data)
-{
- struct net_device *dev;
- struct net_priv *priv;
- void *map_addr;
- int result;
- int i;
-
- i=0;
- while(dev_list[i] && i < ETH_NR)
- i++;
-
- if(i==ETH_NR){
- printk(KERN_WARNING "ether00: Maximum number of ports reached\n");
- return 0;
- }
-
-
- if (!request_mem_region(dev_info->base_addr, MAC_REG_SIZE, "ether00"))
- return -EBUSY;
-
- dev = alloc_etherdev(sizeof(struct net_priv));
- if(!dev) {
- result = -ENOMEM;
- goto out_release;
- }
- priv = dev->priv;
-
- priv->tq_memupdate.routine=ether00_mem_update;
- priv->tq_memupdate.data=(void*) dev;
-
- spin_lock_init(&priv->rx_lock);
-
- map_addr=ioremap_nocache(dev_info->base_addr,SZ_4K);
- if(!map_addr){
- result = -ENOMEM;
- out_kfree;
- }
-
- dev->open=ether00_open;
- dev->stop=ether00_stop;
- dev->set_multicast_list=ether00_set_multicast;
- dev->hard_start_xmit=ether00_tx;
- dev->get_stats=ether00_stats;
-
- ether00_get_ethernet_address(dev);
-
- SET_MODULE_OWNER(dev);
-
- dev->base_addr=(unsigned int)map_addr;
- dev->irq=dev_info->irq;
- dev->features=NETIF_F_DYNALLOC | NETIF_F_HW_CSUM;
-
- result=register_netdev(dev);
- if(result){
- printk("Ether00: Error %i registering driver\n",result);
- goto out_unmap;
- }
- printk("registered ether00 device at %#x\n",dev_info->base_addr);
-
- dev_list[i]=dev;
-
- return result;
-
- out_unmap:
- iounmap(map_addr);
- out_kfree:
- free_netdev(dev);
- out_release:
- release_mem_region(dev_info->base_addr, MAC_REG_SIZE);
- return result;
-}
-
-
-static int ether00_remove_devices(void)
-{
- int i;
-
- for(i=0;i<ETH_NR;i++){
- if(dev_list[i]){
- netif_device_detach(dev_list[i]);
- unregister_netdev(dev_list[i]);
- iounmap((void*)dev_list[i]->base_addr);
- release_mem_region(dev_list[i]->base_addr, MAC_REG_SIZE);
- free_netdev(dev_list[i]);
- dev_list[i]=0;
- }
- }
- return 0;
-}
-
-static struct pld_hotswap_ops ether00_pldhs_ops={
- .name = ETHER00_NAME,
- .add_device = ether00_add_device,
- .remove_devices = ether00_remove_devices,
-};
-
-
-static void __exit ether00_cleanup_module(void)
-{
- int result;
- result=ether00_remove_devices();
- if(result)
- printk(KERN_WARNING "ether00: failed to remove all devices\n");
-
- pldhs_unregister_driver(ETHER00_NAME);
-}
-module_exit(ether00_cleanup_module);
-
-
-static int __init ether00_mod_init(void)
-{
- printk("mod init\n");
- return pldhs_register_driver(&ether00_pldhs_ops);
-
-}
-
-module_init(ether00_mod_init);
-
diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c
deleted file mode 100644
index 36475eb2727..00000000000
--- a/drivers/net/arm/ether1.c
+++ /dev/null
@@ -1,1110 +0,0 @@
-/*
- * linux/drivers/acorn/net/ether1.c
- *
- * Copyright (C) 1996-2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Acorn ether1 driver (82586 chip) for Acorn machines
- *
- * We basically keep two queues in the cards memory - one for transmit
- * and one for receive. Each has a head and a tail. The head is where
- * we/the chip adds packets to be transmitted/received, and the tail
- * is where the transmitter has got to/where the receiver will stop.
- * Both of these queues are circular, and since the chip is running
- * all the time, we have to be careful when we modify the pointers etc
- * so that the buffer memory contents is valid all the time.
- *
- * Change log:
- * 1.00 RMK Released
- * 1.01 RMK 19/03/1996 Transfers the last odd byte onto/off of the card now.
- * 1.02 RMK 25/05/1997 Added code to restart RU if it goes not ready
- * 1.03 RMK 14/09/1997 Cleaned up the handling of a reset during the TX interrupt.
- * Should prevent lockup.
- * 1.04 RMK 17/09/1997 Added more info when initialsation of chip goes wrong.
- * TDR now only reports failure when chip reports non-zero
- * TDR time-distance.
- * 1.05 RMK 31/12/1997 Removed calls to dev_tint for 2.1
- * 1.06 RMK 10/02/2000 Updated for 2.3.43
- * 1.07 RMK 13/05/2000 Updated for 2.3.99-pre8
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/ecard.h>
-
-#define __ETHER1_C
-#include "ether1.h"
-
-static unsigned int net_debug = NET_DEBUG;
-
-#define BUFFER_SIZE 0x10000
-#define TX_AREA_START 0x00100
-#define TX_AREA_END 0x05000
-#define RX_AREA_START 0x05000
-#define RX_AREA_END 0x0fc00
-
-static int ether1_open(struct net_device *dev);
-static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t ether1_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static int ether1_close(struct net_device *dev);
-static struct net_device_stats *ether1_getstats(struct net_device *dev);
-static void ether1_setmulticastlist(struct net_device *dev);
-static void ether1_timeout(struct net_device *dev);
-
-/* ------------------------------------------------------------------------- */
-
-static char version[] __initdata = "ether1 ethernet driver (c) 2000 Russell King v1.07\n";
-
-#define BUS_16 16
-#define BUS_8 8
-
-/* ------------------------------------------------------------------------- */
-
-#define DISABLEIRQS 1
-#define NORMALIRQS 0
-
-#define ether1_readw(dev, addr, type, offset, svflgs) ether1_inw_p (dev, addr + (int)(&((type *)0)->offset), svflgs)
-#define ether1_writew(dev, val, addr, type, offset, svflgs) ether1_outw_p (dev, val, addr + (int)(&((type *)0)->offset), svflgs)
-
-static inline unsigned short
-ether1_inw_p (struct net_device *dev, int addr, int svflgs)
-{
- unsigned long flags;
- unsigned short ret;
-
- if (svflgs)
- local_irq_save (flags);
-
- writeb(addr >> 12, REG_PAGE);
- ret = readw(ETHER1_RAM + ((addr & 4095) << 1));
- if (svflgs)
- local_irq_restore (flags);
- return ret;
-}
-
-static inline void
-ether1_outw_p (struct net_device *dev, unsigned short val, int addr, int svflgs)
-{
- unsigned long flags;
-
- if (svflgs)
- local_irq_save (flags);
-
- writeb(addr >> 12, REG_PAGE);
- writew(val, ETHER1_RAM + ((addr & 4095) << 1));
- if (svflgs)
- local_irq_restore (flags);
-}
-
-/*
- * Some inline assembler to allow fast transfers on to/off of the card.
- * Since this driver depends on some features presented by the ARM
- * specific architecture, and that you can't configure this driver
- * without specifiing ARM mode, this is not a problem.
- *
- * This routine is essentially an optimised memcpy from the card's
- * onboard RAM to kernel memory.
- */
-static void
-ether1_writebuffer (struct net_device *dev, void *data, unsigned int start, unsigned int length)
-{
- unsigned int page, thislen, offset;
- void __iomem *addr;
-
- offset = start & 4095;
- page = start >> 12;
- addr = ETHER1_RAM + (offset << 1);
-
- if (offset + length > 4096)
- thislen = 4096 - offset;
- else
- thislen = length;
-
- do {
- int used;
-
- writeb(page, REG_PAGE);
- length -= thislen;
-
- __asm__ __volatile__(
- "subs %3, %3, #2\n\
- bmi 2f\n\
-1: ldr %0, [%1], #2\n\
- mov %0, %0, lsl #16\n\
- orr %0, %0, %0, lsr #16\n\
- str %0, [%2], #4\n\
- subs %3, %3, #2\n\
- bmi 2f\n\
- ldr %0, [%1], #2\n\
- mov %0, %0, lsl #16\n\
- orr %0, %0, %0, lsr #16\n\
- str %0, [%2], #4\n\
- subs %3, %3, #2\n\
- bmi 2f\n\
- ldr %0, [%1], #2\n\
- mov %0, %0, lsl #16\n\
- orr %0, %0, %0, lsr #16\n\
- str %0, [%2], #4\n\
- subs %3, %3, #2\n\
- bmi 2f\n\
- ldr %0, [%1], #2\n\
- mov %0, %0, lsl #16\n\
- orr %0, %0, %0, lsr #16\n\
- str %0, [%2], #4\n\
- subs %3, %3, #2\n\
- bpl 1b\n\
-2: adds %3, %3, #1\n\
- ldreqb %0, [%1]\n\
- streqb %0, [%2]"
- : "=&r" (used), "=&r" (data)
- : "r" (addr), "r" (thislen), "1" (data));
-
- addr = ETHER1_RAM;
-
- thislen = length;
- if (thislen > 4096)
- thislen = 4096;
- page++;
- } while (thislen);
-}
-
-static void
-ether1_readbuffer (struct net_device *dev, void *data, unsigned int start, unsigned int length)
-{
- unsigned int page, thislen, offset;
- void __iomem *addr;
-
- offset = start & 4095;
- page = start >> 12;
- addr = ETHER1_RAM + (offset << 1);
-
- if (offset + length > 4096)
- thislen = 4096 - offset;
- else
- thislen = length;
-
- do {
- int used;
-
- writeb(page, REG_PAGE);
- length -= thislen;
-
- __asm__ __volatile__(
- "subs %3, %3, #2\n\
- bmi 2f\n\
-1: ldr %0, [%2], #4\n\
- strb %0, [%1], #1\n\
- mov %0, %0, lsr #8\n\
- strb %0, [%1], #1\n\
- subs %3, %3, #2\n\
- bmi 2f\n\
- ldr %0, [%2], #4\n\
- strb %0, [%1], #1\n\
- mov %0, %0, lsr #8\n\
- strb %0, [%1], #1\n\
- subs %3, %3, #2\n\
- bmi 2f\n\
- ldr %0, [%2], #4\n\
- strb %0, [%1], #1\n\
- mov %0, %0, lsr #8\n\
- strb %0, [%1], #1\n\
- subs %3, %3, #2\n\
- bmi 2f\n\
- ldr %0, [%2], #4\n\
- strb %0, [%1], #1\n\
- mov %0, %0, lsr #8\n\
- strb %0, [%1], #1\n\
- subs %3, %3, #2\n\
- bpl 1b\n\
-2: adds %3, %3, #1\n\
- ldreqb %0, [%2]\n\
- streqb %0, [%1]"
- : "=&r" (used), "=&r" (data)
- : "r" (addr), "r" (thislen), "1" (data));
-
- addr = ETHER1_RAM;
-
- thislen = length;
- if (thislen > 4096)
- thislen = 4096;
- page++;
- } while (thislen);
-}
-
-static int __init
-ether1_ramtest(struct net_device *dev, unsigned char byte)
-{
- unsigned char *buffer = kmalloc (BUFFER_SIZE, GFP_KERNEL);
- int i, ret = BUFFER_SIZE;
- int max_errors = 15;
- int bad = -1;
- int bad_start = 0;
-
- if (!buffer)
- return 1;
-
- memset (buffer, byte, BUFFER_SIZE);
- ether1_writebuffer (dev, buffer, 0, BUFFER_SIZE);
- memset (buffer, byte ^ 0xff, BUFFER_SIZE);
- ether1_readbuffer (dev, buffer, 0, BUFFER_SIZE);
-
- for (i = 0; i < BUFFER_SIZE; i++) {
- if (buffer[i] != byte) {
- if (max_errors >= 0 && bad != buffer[i]) {
- if (bad != -1)
- printk ("\n");
- printk (KERN_CRIT "%s: RAM failed with (%02X instead of %02X) at 0x%04X",
- dev->name, buffer[i], byte, i);
- ret = -ENODEV;
- max_errors --;
- bad = buffer[i];
- bad_start = i;
- }
- } else {
- if (bad != -1) {
- if (bad_start == i - 1)
- printk ("\n");
- else
- printk (" - 0x%04X\n", i - 1);
- bad = -1;
- }
- }
- }
-
- if (bad != -1)
- printk (" - 0x%04X\n", BUFFER_SIZE);
- kfree (buffer);
-
- return ret;
-}
-
-static int
-ether1_reset (struct net_device *dev)
-{
- writeb(CTRL_RST|CTRL_ACK, REG_CONTROL);
- return BUS_16;
-}
-
-static int __init
-ether1_init_2(struct net_device *dev)
-{
- int i;
- dev->mem_start = 0;
-
- i = ether1_ramtest (dev, 0x5a);
-
- if (i > 0)
- i = ether1_ramtest (dev, 0x1e);
-
- if (i <= 0)
- return -ENODEV;
-
- dev->mem_end = i;
- return 0;
-}
-
-/*
- * These are the structures that are loaded into the ether RAM card to
- * initialise the 82586
- */
-
-/* at 0x0100 */
-#define NOP_ADDR (TX_AREA_START)
-#define NOP_SIZE (0x06)
-static nop_t init_nop = {
- 0,
- CMD_NOP,
- NOP_ADDR
-};
-
-/* at 0x003a */
-#define TDR_ADDR (0x003a)
-#define TDR_SIZE (0x08)
-static tdr_t init_tdr = {
- 0,
- CMD_TDR | CMD_INTR,
- NOP_ADDR,
- 0
-};
-
-/* at 0x002e */
-#define MC_ADDR (0x002e)
-#define MC_SIZE (0x0c)
-static mc_t init_mc = {
- 0,
- CMD_SETMULTICAST,
- TDR_ADDR,
- 0,
- { { 0, } }
-};
-
-/* at 0x0022 */
-#define SA_ADDR (0x0022)
-#define SA_SIZE (0x0c)
-static sa_t init_sa = {
- 0,
- CMD_SETADDRESS,
- MC_ADDR,
- { 0, }
-};
-
-/* at 0x0010 */
-#define CFG_ADDR (0x0010)
-#define CFG_SIZE (0x12)
-static cfg_t init_cfg = {
- 0,
- CMD_CONFIG,
- SA_ADDR,
- 8,
- 8,
- CFG8_SRDY,
- CFG9_PREAMB8 | CFG9_ADDRLENBUF | CFG9_ADDRLEN(6),
- 0,
- 0x60,
- 0,
- CFG13_RETRY(15) | CFG13_SLOTH(2),
- 0,
-};
-
-/* at 0x0000 */
-#define SCB_ADDR (0x0000)
-#define SCB_SIZE (0x10)
-static scb_t init_scb = {
- 0,
- SCB_CMDACKRNR | SCB_CMDACKCNA | SCB_CMDACKFR | SCB_CMDACKCX,
- CFG_ADDR,
- RX_AREA_START,
- 0,
- 0,
- 0,
- 0
-};
-
-/* at 0xffee */
-#define ISCP_ADDR (0xffee)
-#define ISCP_SIZE (0x08)
-static iscp_t init_iscp = {
- 1,
- SCB_ADDR,
- 0x0000,
- 0x0000
-};
-
-/* at 0xfff6 */
-#define SCP_ADDR (0xfff6)
-#define SCP_SIZE (0x0a)
-static scp_t init_scp = {
- SCP_SY_16BBUS,
- { 0, 0 },
- ISCP_ADDR,
- 0
-};
-
-#define RFD_SIZE (0x16)
-static rfd_t init_rfd = {
- 0,
- 0,
- 0,
- 0,
- { 0, },
- { 0, },
- 0
-};
-
-#define RBD_SIZE (0x0a)
-static rbd_t init_rbd = {
- 0,
- 0,
- 0,
- 0,
- ETH_FRAME_LEN + 8
-};
-
-#define TX_SIZE (0x08)
-#define TBD_SIZE (0x08)
-
-static int
-ether1_init_for_open (struct net_device *dev)
-{
- int i, status, addr, next, next2;
- int failures = 0;
- unsigned long timeout;
-
- writeb(CTRL_RST|CTRL_ACK, REG_CONTROL);
-
- for (i = 0; i < 6; i++)
- init_sa.sa_addr[i] = dev->dev_addr[i];
-
- /* load data structures into ether1 RAM */
- ether1_writebuffer (dev, &init_scp, SCP_ADDR, SCP_SIZE);
- ether1_writebuffer (dev, &init_iscp, ISCP_ADDR, ISCP_SIZE);
- ether1_writebuffer (dev, &init_scb, SCB_ADDR, SCB_SIZE);
- ether1_writebuffer (dev, &init_cfg, CFG_ADDR, CFG_SIZE);
- ether1_writebuffer (dev, &init_sa, SA_ADDR, SA_SIZE);
- ether1_writebuffer (dev, &init_mc, MC_ADDR, MC_SIZE);
- ether1_writebuffer (dev, &init_tdr, TDR_ADDR, TDR_SIZE);
- ether1_writebuffer (dev, &init_nop, NOP_ADDR, NOP_SIZE);
-
- if (ether1_readw(dev, CFG_ADDR, cfg_t, cfg_command, NORMALIRQS) != CMD_CONFIG) {
- printk (KERN_ERR "%s: detected either RAM fault or compiler bug\n",
- dev->name);
- return 1;
- }
-
- /*
- * setup circularly linked list of { rfd, rbd, buffer }, with
- * all rfds circularly linked, rbds circularly linked.
- * First rfd is linked to scp, first rbd is linked to first
- * rfd. Last rbd has a suspend command.
- */
- addr = RX_AREA_START;
- do {
- next = addr + RFD_SIZE + RBD_SIZE + ETH_FRAME_LEN + 10;
- next2 = next + RFD_SIZE + RBD_SIZE + ETH_FRAME_LEN + 10;
-
- if (next2 >= RX_AREA_END) {
- next = RX_AREA_START;
- init_rfd.rfd_command = RFD_CMDEL | RFD_CMDSUSPEND;
- priv(dev)->rx_tail = addr;
- } else
- init_rfd.rfd_command = 0;
- if (addr == RX_AREA_START)
- init_rfd.rfd_rbdoffset = addr + RFD_SIZE;
- else
- init_rfd.rfd_rbdoffset = 0;
- init_rfd.rfd_link = next;
- init_rbd.rbd_link = next + RFD_SIZE;
- init_rbd.rbd_bufl = addr + RFD_SIZE + RBD_SIZE;
-
- ether1_writebuffer (dev, &init_rfd, addr, RFD_SIZE);
- ether1_writebuffer (dev, &init_rbd, addr + RFD_SIZE, RBD_SIZE);
- addr = next;
- } while (next2 < RX_AREA_END);
-
- priv(dev)->tx_link = NOP_ADDR;
- priv(dev)->tx_head = NOP_ADDR + NOP_SIZE;
- priv(dev)->tx_tail = TDR_ADDR;
- priv(dev)->rx_head = RX_AREA_START;
-
- /* release reset & give 586 a prod */
- priv(dev)->resetting = 1;
- priv(dev)->initialising = 1;
- writeb(CTRL_RST, REG_CONTROL);
- writeb(0, REG_CONTROL);
- writeb(CTRL_CA, REG_CONTROL);
-
- /* 586 should now unset iscp.busy */
- timeout = jiffies + HZ/2;
- while (ether1_readw(dev, ISCP_ADDR, iscp_t, iscp_busy, DISABLEIRQS) == 1) {
- if (time_after(jiffies, timeout)) {
- printk (KERN_WARNING "%s: can't initialise 82586: iscp is busy\n", dev->name);
- return 1;
- }
- }
-
- /* check status of commands that we issued */
- timeout += HZ/10;
- while (((status = ether1_readw(dev, CFG_ADDR, cfg_t, cfg_status, DISABLEIRQS))
- & STAT_COMPLETE) == 0) {
- if (time_after(jiffies, timeout))
- break;
- }
-
- if ((status & (STAT_COMPLETE | STAT_OK)) != (STAT_COMPLETE | STAT_OK)) {
- printk (KERN_WARNING "%s: can't initialise 82586: config status %04X\n", dev->name, status);
- printk (KERN_DEBUG "%s: SCB=[STS=%04X CMD=%04X CBL=%04X RFA=%04X]\n", dev->name,
- ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS),
- ether1_readw(dev, SCB_ADDR, scb_t, scb_command, NORMALIRQS),
- ether1_readw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS),
- ether1_readw(dev, SCB_ADDR, scb_t, scb_rfa_offset, NORMALIRQS));
- failures += 1;
- }
-
- timeout += HZ/10;
- while (((status = ether1_readw(dev, SA_ADDR, sa_t, sa_status, DISABLEIRQS))
- & STAT_COMPLETE) == 0) {
- if (time_after(jiffies, timeout))
- break;
- }
-
- if ((status & (STAT_COMPLETE | STAT_OK)) != (STAT_COMPLETE | STAT_OK)) {
- printk (KERN_WARNING "%s: can't initialise 82586: set address status %04X\n", dev->name, status);
- printk (KERN_DEBUG "%s: SCB=[STS=%04X CMD=%04X CBL=%04X RFA=%04X]\n", dev->name,
- ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS),
- ether1_readw(dev, SCB_ADDR, scb_t, scb_command, NORMALIRQS),
- ether1_readw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS),
- ether1_readw(dev, SCB_ADDR, scb_t, scb_rfa_offset, NORMALIRQS));
- failures += 1;
- }
-
- timeout += HZ/10;
- while (((status = ether1_readw(dev, MC_ADDR, mc_t, mc_status, DISABLEIRQS))
- & STAT_COMPLETE) == 0) {
- if (time_after(jiffies, timeout))
- break;
- }
-
- if ((status & (STAT_COMPLETE | STAT_OK)) != (STAT_COMPLETE | STAT_OK)) {
- printk (KERN_WARNING "%s: can't initialise 82586: set multicast status %04X\n", dev->name, status);
- printk (KERN_DEBUG "%s: SCB=[STS=%04X CMD=%04X CBL=%04X RFA=%04X]\n", dev->name,
- ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS),
- ether1_readw(dev, SCB_ADDR, scb_t, scb_command, NORMALIRQS),
- ether1_readw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS),
- ether1_readw(dev, SCB_ADDR, scb_t, scb_rfa_offset, NORMALIRQS));
- failures += 1;
- }
-
- timeout += HZ;
- while (((status = ether1_readw(dev, TDR_ADDR, tdr_t, tdr_status, DISABLEIRQS))
- & STAT_COMPLETE) == 0) {
- if (time_after(jiffies, timeout))
- break;
- }
-
- if ((status & (STAT_COMPLETE | STAT_OK)) != (STAT_COMPLETE | STAT_OK)) {
- printk (KERN_WARNING "%s: can't tdr (ignored)\n", dev->name);
- printk (KERN_DEBUG "%s: SCB=[STS=%04X CMD=%04X CBL=%04X RFA=%04X]\n", dev->name,
- ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS),
- ether1_readw(dev, SCB_ADDR, scb_t, scb_command, NORMALIRQS),
- ether1_readw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS),
- ether1_readw(dev, SCB_ADDR, scb_t, scb_rfa_offset, NORMALIRQS));
- } else {
- status = ether1_readw(dev, TDR_ADDR, tdr_t, tdr_result, DISABLEIRQS);
- if (status & TDR_XCVRPROB)
- printk (KERN_WARNING "%s: i/f failed tdr: transceiver problem\n", dev->name);
- else if ((status & (TDR_SHORT|TDR_OPEN)) && (status & TDR_TIME)) {
-#ifdef FANCY
- printk (KERN_WARNING "%s: i/f failed tdr: cable %s %d.%d us away\n", dev->name,
- status & TDR_SHORT ? "short" : "open", (status & TDR_TIME) / 10,
- (status & TDR_TIME) % 10);
-#else
- printk (KERN_WARNING "%s: i/f failed tdr: cable %s %d clks away\n", dev->name,
- status & TDR_SHORT ? "short" : "open", (status & TDR_TIME));
-#endif
- }
- }
-
- if (failures)
- ether1_reset (dev);
- return failures ? 1 : 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int
-ether1_txalloc (struct net_device *dev, int size)
-{
- int start, tail;
-
- size = (size + 1) & ~1;
- tail = priv(dev)->tx_tail;
-
- if (priv(dev)->tx_head + size > TX_AREA_END) {
- if (tail > priv(dev)->tx_head)
- return -1;
- start = TX_AREA_START;
- if (start + size > tail)
- return -1;
- priv(dev)->tx_head = start + size;
- } else {
- if (priv(dev)->tx_head < tail && (priv(dev)->tx_head + size) > tail)
- return -1;
- start = priv(dev)->tx_head;
- priv(dev)->tx_head += size;
- }
-
- return start;
-}
-
-static int
-ether1_open (struct net_device *dev)
-{
- if (!is_valid_ether_addr(dev->dev_addr)) {
- printk(KERN_WARNING "%s: invalid ethernet MAC address\n",
- dev->name);
- return -EINVAL;
- }
-
- if (request_irq(dev->irq, ether1_interrupt, 0, "ether1", dev))
- return -EAGAIN;
-
- memset (&priv(dev)->stats, 0, sizeof (struct net_device_stats));
-
- if (ether1_init_for_open (dev)) {
- free_irq (dev->irq, dev);
- return -EAGAIN;
- }
-
- netif_start_queue(dev);
-
- return 0;
-}
-
-static void
-ether1_timeout(struct net_device *dev)
-{
- printk(KERN_WARNING "%s: transmit timeout, network cable problem?\n",
- dev->name);
- printk(KERN_WARNING "%s: resetting device\n", dev->name);
-
- ether1_reset (dev);
-
- if (ether1_init_for_open (dev))
- printk (KERN_ERR "%s: unable to restart interface\n", dev->name);
-
- priv(dev)->stats.tx_errors++;
- netif_wake_queue(dev);
-}
-
-static int
-ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
-{
- int tmp, tst, nopaddr, txaddr, tbdaddr, dataddr;
- unsigned long flags;
- tx_t tx;
- tbd_t tbd;
- nop_t nop;
-
- if (priv(dev)->restart) {
- printk(KERN_WARNING "%s: resetting device\n", dev->name);
-
- ether1_reset(dev);
-
- if (ether1_init_for_open(dev))
- printk(KERN_ERR "%s: unable to restart interface\n", dev->name);
- else
- priv(dev)->restart = 0;
- }
-
- if (skb->len < ETH_ZLEN) {
- skb = skb_padto(skb, ETH_ZLEN);
- if (skb == NULL)
- goto out;
- }
-
- /*
- * insert packet followed by a nop
- */
- txaddr = ether1_txalloc (dev, TX_SIZE);
- tbdaddr = ether1_txalloc (dev, TBD_SIZE);
- dataddr = ether1_txalloc (dev, skb->len);
- nopaddr = ether1_txalloc (dev, NOP_SIZE);
-
- tx.tx_status = 0;
- tx.tx_command = CMD_TX | CMD_INTR;
- tx.tx_link = nopaddr;
- tx.tx_tbdoffset = tbdaddr;
- tbd.tbd_opts = TBD_EOL | skb->len;
- tbd.tbd_link = I82586_NULL;
- tbd.tbd_bufl = dataddr;
- tbd.tbd_bufh = 0;
- nop.nop_status = 0;
- nop.nop_command = CMD_NOP;
- nop.nop_link = nopaddr;
-
- local_irq_save(flags);
- ether1_writebuffer (dev, &tx, txaddr, TX_SIZE);
- ether1_writebuffer (dev, &tbd, tbdaddr, TBD_SIZE);
- ether1_writebuffer (dev, skb->data, dataddr, skb->len);
- ether1_writebuffer (dev, &nop, nopaddr, NOP_SIZE);
- tmp = priv(dev)->tx_link;
- priv(dev)->tx_link = nopaddr;
-
- /* now reset the previous nop pointer */
- ether1_writew(dev, txaddr, tmp, nop_t, nop_link, NORMALIRQS);
-
- local_irq_restore(flags);
-
- /* handle transmit */
- dev->trans_start = jiffies;
-
- /* check to see if we have room for a full sized ether frame */
- tmp = priv(dev)->tx_head;
- tst = ether1_txalloc (dev, TX_SIZE + TBD_SIZE + NOP_SIZE + ETH_FRAME_LEN);
- priv(dev)->tx_head = tmp;
- dev_kfree_skb (skb);
-
- if (tst == -1)
- netif_stop_queue(dev);
-
- out:
- return 0;
-}
-
-static void
-ether1_xmit_done (struct net_device *dev)
-{
- nop_t nop;
- int caddr, tst;
-
- caddr = priv(dev)->tx_tail;
-
-again:
- ether1_readbuffer (dev, &nop, caddr, NOP_SIZE);
-
- switch (nop.nop_command & CMD_MASK) {
- case CMD_TDR:
- /* special case */
- if (ether1_readw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS)
- != (unsigned short)I82586_NULL) {
- ether1_writew(dev, SCB_CMDCUCSTART | SCB_CMDRXSTART, SCB_ADDR, scb_t,
- scb_command, NORMALIRQS);
- writeb(CTRL_CA, REG_CONTROL);
- }
- priv(dev)->tx_tail = NOP_ADDR;
- return;
-
- case CMD_NOP:
- if (nop.nop_link == caddr) {
- if (priv(dev)->initialising == 0)
- printk (KERN_WARNING "%s: strange command complete with no tx command!\n", dev->name);
- else
- priv(dev)->initialising = 0;
- return;
- }
- if (caddr == nop.nop_link)
- return;
- caddr = nop.nop_link;
- goto again;
-
- case CMD_TX:
- if (nop.nop_status & STAT_COMPLETE)
- break;
- printk (KERN_ERR "%s: strange command complete without completed command\n", dev->name);
- priv(dev)->restart = 1;
- return;
-
- default:
- printk (KERN_WARNING "%s: strange command %d complete! (offset %04X)", dev->name,
- nop.nop_command & CMD_MASK, caddr);
- priv(dev)->restart = 1;
- return;
- }
-
- while (nop.nop_status & STAT_COMPLETE) {
- if (nop.nop_status & STAT_OK) {
- priv(dev)->stats.tx_packets ++;
- priv(dev)->stats.collisions += (nop.nop_status & STAT_COLLISIONS);
- } else {
- priv(dev)->stats.tx_errors ++;
-
- if (nop.nop_status & STAT_COLLAFTERTX)
- priv(dev)->stats.collisions ++;
- if (nop.nop_status & STAT_NOCARRIER)
- priv(dev)->stats.tx_carrier_errors ++;
- if (nop.nop_status & STAT_TXLOSTCTS)
- printk (KERN_WARNING "%s: cts lost\n", dev->name);
- if (nop.nop_status & STAT_TXSLOWDMA)
- priv(dev)->stats.tx_fifo_errors ++;
- if (nop.nop_status & STAT_COLLEXCESSIVE)
- priv(dev)->stats.collisions += 16;
- }
-
- if (nop.nop_link == caddr) {
- printk (KERN_ERR "%s: tx buffer chaining error: tx command points to itself\n", dev->name);
- break;
- }
-
- caddr = nop.nop_link;
- ether1_readbuffer (dev, &nop, caddr, NOP_SIZE);
- if ((nop.nop_command & CMD_MASK) != CMD_NOP) {
- printk (KERN_ERR "%s: tx buffer chaining error: no nop after tx command\n", dev->name);
- break;
- }
-
- if (caddr == nop.nop_link)
- break;
-
- caddr = nop.nop_link;
- ether1_readbuffer (dev, &nop, caddr, NOP_SIZE);
- if ((nop.nop_command & CMD_MASK) != CMD_TX) {
- printk (KERN_ERR "%s: tx buffer chaining error: no tx command after nop\n", dev->name);
- break;
- }
- }
- priv(dev)->tx_tail = caddr;
-
- caddr = priv(dev)->tx_head;
- tst = ether1_txalloc (dev, TX_SIZE + TBD_SIZE + NOP_SIZE + ETH_FRAME_LEN);
- priv(dev)->tx_head = caddr;
- if (tst != -1)
- netif_wake_queue(dev);
-}
-
-static void
-ether1_recv_done (struct net_device *dev)
-{
- int status;
- int nexttail, rbdaddr;
- rbd_t rbd;
-
- do {
- status = ether1_readw(dev, priv(dev)->rx_head, rfd_t, rfd_status, NORMALIRQS);
- if ((status & RFD_COMPLETE) == 0)
- break;
-
- rbdaddr = ether1_readw(dev, priv(dev)->rx_head, rfd_t, rfd_rbdoffset, NORMALIRQS);
- ether1_readbuffer (dev, &rbd, rbdaddr, RBD_SIZE);
-
- if ((rbd.rbd_status & (RBD_EOF | RBD_ACNTVALID)) == (RBD_EOF | RBD_ACNTVALID)) {
- int length = rbd.rbd_status & RBD_ACNT;
- struct sk_buff *skb;
-
- length = (length + 1) & ~1;
- skb = dev_alloc_skb (length + 2);
-
- if (skb) {
- skb->dev = dev;
- skb_reserve (skb, 2);
-
- ether1_readbuffer (dev, skb_put (skb, length), rbd.rbd_bufl, length);
-
- skb->protocol = eth_type_trans (skb, dev);
- netif_rx (skb);
- priv(dev)->stats.rx_packets ++;
- } else
- priv(dev)->stats.rx_dropped ++;
- } else {
- printk(KERN_WARNING "%s: %s\n", dev->name,
- (rbd.rbd_status & RBD_EOF) ? "oversized packet" : "acnt not valid");
- priv(dev)->stats.rx_dropped ++;
- }
-
- nexttail = ether1_readw(dev, priv(dev)->rx_tail, rfd_t, rfd_link, NORMALIRQS);
- /* nexttail should be rx_head */
- if (nexttail != priv(dev)->rx_head)
- printk(KERN_ERR "%s: receiver buffer chaining error (%04X != %04X)\n",
- dev->name, nexttail, priv(dev)->rx_head);
- ether1_writew(dev, RFD_CMDEL | RFD_CMDSUSPEND, nexttail, rfd_t, rfd_command, NORMALIRQS);
- ether1_writew(dev, 0, priv(dev)->rx_tail, rfd_t, rfd_command, NORMALIRQS);
- ether1_writew(dev, 0, priv(dev)->rx_tail, rfd_t, rfd_status, NORMALIRQS);
- ether1_writew(dev, 0, priv(dev)->rx_tail, rfd_t, rfd_rbdoffset, NORMALIRQS);
-
- priv(dev)->rx_tail = nexttail;
- priv(dev)->rx_head = ether1_readw(dev, priv(dev)->rx_head, rfd_t, rfd_link, NORMALIRQS);
- } while (1);
-}
-
-static irqreturn_t
-ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs)
-{
- struct net_device *dev = (struct net_device *)dev_id;
- int status;
-
- status = ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS);
-
- if (status) {
- ether1_writew(dev, status & (SCB_STRNR | SCB_STCNA | SCB_STFR | SCB_STCX),
- SCB_ADDR, scb_t, scb_command, NORMALIRQS);
- writeb(CTRL_CA | CTRL_ACK, REG_CONTROL);
- if (status & SCB_STCX) {
- ether1_xmit_done (dev);
- }
- if (status & SCB_STCNA) {
- if (priv(dev)->resetting == 0)
- printk (KERN_WARNING "%s: CU went not ready ???\n", dev->name);
- else
- priv(dev)->resetting += 1;
- if (ether1_readw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS)
- != (unsigned short)I82586_NULL) {
- ether1_writew(dev, SCB_CMDCUCSTART, SCB_ADDR, scb_t, scb_command, NORMALIRQS);
- writeb(CTRL_CA, REG_CONTROL);
- }
- if (priv(dev)->resetting == 2)
- priv(dev)->resetting = 0;
- }
- if (status & SCB_STFR) {
- ether1_recv_done (dev);
- }
- if (status & SCB_STRNR) {
- if (ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS) & SCB_STRXSUSP) {
- printk (KERN_WARNING "%s: RU went not ready: RU suspended\n", dev->name);
- ether1_writew(dev, SCB_CMDRXRESUME, SCB_ADDR, scb_t, scb_command, NORMALIRQS);
- writeb(CTRL_CA, REG_CONTROL);
- priv(dev)->stats.rx_dropped ++; /* we suspended due to lack of buffer space */
- } else
- printk(KERN_WARNING "%s: RU went not ready: %04X\n", dev->name,
- ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS));
- printk (KERN_WARNING "RU ptr = %04X\n", ether1_readw(dev, SCB_ADDR, scb_t, scb_rfa_offset,
- NORMALIRQS));
- }
- } else
- writeb(CTRL_ACK, REG_CONTROL);
-
- return IRQ_HANDLED;
-}
-
-static int
-ether1_close (struct net_device *dev)
-{
- ether1_reset (dev);
-
- free_irq(dev->irq, dev);
-
- return 0;
-}
-
-static struct net_device_stats *
-ether1_getstats (struct net_device *dev)
-{
- return &priv(dev)->stats;
-}
-
-/*
- * Set or clear the multicast filter for this adaptor.
- * num_addrs == -1 Promiscuous mode, receive all packets.
- * num_addrs == 0 Normal mode, clear multicast list.
- * num_addrs > 0 Multicast mode, receive normal and MC packets, and do
- * best-effort filtering.
- */
-static void
-ether1_setmulticastlist (struct net_device *dev)
-{
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void __init ether1_banner(void)
-{
- static unsigned int version_printed = 0;
-
- if (net_debug && version_printed++ == 0)
- printk(KERN_INFO "%s", version);
-}
-
-static int __devinit
-ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
-{
- struct net_device *dev;
- int i, ret = 0;
-
- ether1_banner();
-
- ret = ecard_request_resources(ec);
- if (ret)
- goto out;
-
- dev = alloc_etherdev(sizeof(struct ether1_priv));
- if (!dev) {
- ret = -ENOMEM;
- goto release;
- }
-
- SET_MODULE_OWNER(dev);
- SET_NETDEV_DEV(dev, &ec->dev);
-
- dev->irq = ec->irq;
- priv(dev)->base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
- ecard_resource_len(ec, ECARD_RES_IOCFAST));
- if (!priv(dev)->base) {
- ret = -ENOMEM;
- goto free;
- }
-
- if ((priv(dev)->bus_type = ether1_reset(dev)) == 0) {
- ret = -ENODEV;
- goto free;
- }
-
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = readb(IDPROM_ADDRESS + (i << 2));
-
- if (ether1_init_2(dev)) {
- ret = -ENODEV;
- goto free;
- }
-
- dev->open = ether1_open;
- dev->stop = ether1_close;
- dev->hard_start_xmit = ether1_sendpacket;
- dev->get_stats = ether1_getstats;
- dev->set_multicast_list = ether1_setmulticastlist;
- dev->tx_timeout = ether1_timeout;
- dev->watchdog_timeo = 5 * HZ / 100;
-
- ret = register_netdev(dev);
- if (ret)
- goto free;
-
- printk(KERN_INFO "%s: ether1 in slot %d, ",
- dev->name, ec->slot_no);
-
- for (i = 0; i < 6; i++)
- printk ("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
-
- ecard_set_drvdata(ec, dev);
- return 0;
-
- free:
- if (priv(dev)->base)
- iounmap(priv(dev)->base);
- free_netdev(dev);
- release:
- ecard_release_resources(ec);
- out:
- return ret;
-}
-
-static void __devexit ether1_remove(struct expansion_card *ec)
-{
- struct net_device *dev = ecard_get_drvdata(ec);
-
- ecard_set_drvdata(ec, NULL);
-
- unregister_netdev(dev);
- iounmap(priv(dev)->base);
- free_netdev(dev);
- ecard_release_resources(ec);
-}
-
-static const struct ecard_id ether1_ids[] = {
- { MANU_ACORN, PROD_ACORN_ETHER1 },
- { 0xffff, 0xffff }
-};
-
-static struct ecard_driver ether1_driver = {
- .probe = ether1_probe,
- .remove = __devexit_p(ether1_remove),
- .id_table = ether1_ids,
- .drv = {
- .name = "ether1",
- },
-};
-
-static int __init ether1_init(void)
-{
- return ecard_register_driver(&ether1_driver);
-}
-
-static void __exit ether1_exit(void)
-{
- ecard_remove_driver(&ether1_driver);
-}
-
-module_init(ether1_init);
-module_exit(ether1_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/arm/ether1.h b/drivers/net/arm/ether1.h
deleted file mode 100644
index c8a4b2389d8..00000000000
--- a/drivers/net/arm/ether1.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * linux/drivers/acorn/net/ether1.h
- *
- * Copyright (C) 1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Network driver for Acorn Ether1 cards.
- */
-
-#ifndef _LINUX_ether1_H
-#define _LINUX_ether1_H
-
-#ifdef __ETHER1_C
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 0
-#endif
-
-#define priv(dev) ((struct ether1_priv *)netdev_priv(dev))
-
-/* Page register */
-#define REG_PAGE (priv(dev)->base + 0x0000)
-
-/* Control register */
-#define REG_CONTROL (priv(dev)->base + 0x0004)
-#define CTRL_RST 0x01
-#define CTRL_LOOPBACK 0x02
-#define CTRL_CA 0x04
-#define CTRL_ACK 0x08
-
-#define ETHER1_RAM (priv(dev)->base + 0x2000)
-
-/* HW address */
-#define IDPROM_ADDRESS (priv(dev)->base + 0x0024)
-
-struct ether1_priv {
- void __iomem *base;
- struct net_device_stats stats;
- unsigned int tx_link;
- unsigned int tx_head;
- volatile unsigned int tx_tail;
- volatile unsigned int rx_head;
- volatile unsigned int rx_tail;
- unsigned char bus_type;
- unsigned char resetting;
- unsigned char initialising : 1;
- unsigned char restart : 1;
-};
-
-#define I82586_NULL (-1)
-
-typedef struct { /* tdr */
- unsigned short tdr_status;
- unsigned short tdr_command;
- unsigned short tdr_link;
- unsigned short tdr_result;
-#define TDR_TIME (0x7ff)
-#define TDR_SHORT (1 << 12)
-#define TDR_OPEN (1 << 13)
-#define TDR_XCVRPROB (1 << 14)
-#define TDR_LNKOK (1 << 15)
-} tdr_t;
-
-typedef struct { /* transmit */
- unsigned short tx_status;
- unsigned short tx_command;
- unsigned short tx_link;
- unsigned short tx_tbdoffset;
-} tx_t;
-
-typedef struct { /* tbd */
- unsigned short tbd_opts;
-#define TBD_CNT (0x3fff)
-#define TBD_EOL (1 << 15)
- unsigned short tbd_link;
- unsigned short tbd_bufl;
- unsigned short tbd_bufh;
-} tbd_t;
-
-typedef struct { /* rfd */
- unsigned short rfd_status;
-#define RFD_NOEOF (1 << 6)
-#define RFD_FRAMESHORT (1 << 7)
-#define RFD_DMAOVRN (1 << 8)
-#define RFD_NORESOURCES (1 << 9)
-#define RFD_ALIGNERROR (1 << 10)
-#define RFD_CRCERROR (1 << 11)
-#define RFD_OK (1 << 13)
-#define RFD_FDCONSUMED (1 << 14)
-#define RFD_COMPLETE (1 << 15)
- unsigned short rfd_command;
-#define RFD_CMDSUSPEND (1 << 14)
-#define RFD_CMDEL (1 << 15)
- unsigned short rfd_link;
- unsigned short rfd_rbdoffset;
- unsigned char rfd_dest[6];
- unsigned char rfd_src[6];
- unsigned short rfd_len;
-} rfd_t;
-
-typedef struct { /* rbd */
- unsigned short rbd_status;
-#define RBD_ACNT (0x3fff)
-#define RBD_ACNTVALID (1 << 14)
-#define RBD_EOF (1 << 15)
- unsigned short rbd_link;
- unsigned short rbd_bufl;
- unsigned short rbd_bufh;
- unsigned short rbd_len;
-} rbd_t;
-
-typedef struct { /* nop */
- unsigned short nop_status;
- unsigned short nop_command;
- unsigned short nop_link;
-} nop_t;
-
-typedef struct { /* set multicast */
- unsigned short mc_status;
- unsigned short mc_command;
- unsigned short mc_link;
- unsigned short mc_cnt;
- unsigned char mc_addrs[1][6];
-} mc_t;
-
-typedef struct { /* set address */
- unsigned short sa_status;
- unsigned short sa_command;
- unsigned short sa_link;
- unsigned char sa_addr[6];
-} sa_t;
-
-typedef struct { /* config command */
- unsigned short cfg_status;
- unsigned short cfg_command;
- unsigned short cfg_link;
- unsigned char cfg_bytecnt; /* size foll data: 4 - 12 */
- unsigned char cfg_fifolim; /* FIFO threshold */
- unsigned char cfg_byte8;
-#define CFG8_SRDY (1 << 6)
-#define CFG8_SAVEBADF (1 << 7)
- unsigned char cfg_byte9;
-#define CFG9_ADDRLEN(x) (x)
-#define CFG9_ADDRLENBUF (1 << 3)
-#define CFG9_PREAMB2 (0 << 4)
-#define CFG9_PREAMB4 (1 << 4)
-#define CFG9_PREAMB8 (2 << 4)
-#define CFG9_PREAMB16 (3 << 4)
-#define CFG9_ILOOPBACK (1 << 6)
-#define CFG9_ELOOPBACK (1 << 7)
- unsigned char cfg_byte10;
-#define CFG10_LINPRI(x) (x)
-#define CFG10_ACR(x) (x << 4)
-#define CFG10_BOFMET (1 << 7)
- unsigned char cfg_ifs;
- unsigned char cfg_slotl;
- unsigned char cfg_byte13;
-#define CFG13_SLOTH(x) (x)
-#define CFG13_RETRY(x) (x << 4)
- unsigned char cfg_byte14;
-#define CFG14_PROMISC (1 << 0)
-#define CFG14_DISBRD (1 << 1)
-#define CFG14_MANCH (1 << 2)
-#define CFG14_TNCRS (1 << 3)
-#define CFG14_NOCRC (1 << 4)
-#define CFG14_CRC16 (1 << 5)
-#define CFG14_BTSTF (1 << 6)
-#define CFG14_FLGPAD (1 << 7)
- unsigned char cfg_byte15;
-#define CFG15_CSTF(x) (x)
-#define CFG15_ICSS (1 << 3)
-#define CFG15_CDTF(x) (x << 4)
-#define CFG15_ICDS (1 << 7)
- unsigned short cfg_minfrmlen;
-} cfg_t;
-
-typedef struct { /* scb */
- unsigned short scb_status; /* status of 82586 */
-#define SCB_STRXMASK (7 << 4) /* Receive unit status */
-#define SCB_STRXIDLE (0 << 4) /* Idle */
-#define SCB_STRXSUSP (1 << 4) /* Suspended */
-#define SCB_STRXNRES (2 << 4) /* No resources */
-#define SCB_STRXRDY (4 << 4) /* Ready */
-#define SCB_STCUMASK (7 << 8) /* Command unit status */
-#define SCB_STCUIDLE (0 << 8) /* Idle */
-#define SCB_STCUSUSP (1 << 8) /* Suspended */
-#define SCB_STCUACTV (2 << 8) /* Active */
-#define SCB_STRNR (1 << 12) /* Receive unit not ready */
-#define SCB_STCNA (1 << 13) /* Command unit not ready */
-#define SCB_STFR (1 << 14) /* Frame received */
-#define SCB_STCX (1 << 15) /* Command completed */
- unsigned short scb_command; /* Next command */
-#define SCB_CMDRXSTART (1 << 4) /* Start (at rfa_offset) */
-#define SCB_CMDRXRESUME (2 << 4) /* Resume reception */
-#define SCB_CMDRXSUSPEND (3 << 4) /* Suspend reception */
-#define SCB_CMDRXABORT (4 << 4) /* Abort reception */
-#define SCB_CMDCUCSTART (1 << 8) /* Start (at cbl_offset) */
-#define SCB_CMDCUCRESUME (2 << 8) /* Resume execution */
-#define SCB_CMDCUCSUSPEND (3 << 8) /* Suspend execution */
-#define SCB_CMDCUCABORT (4 << 8) /* Abort execution */
-#define SCB_CMDACKRNR (1 << 12) /* Ack RU not ready */
-#define SCB_CMDACKCNA (1 << 13) /* Ack CU not ready */
-#define SCB_CMDACKFR (1 << 14) /* Ack Frame received */
-#define SCB_CMDACKCX (1 << 15) /* Ack Command complete */
- unsigned short scb_cbl_offset; /* Offset of first command unit */
- unsigned short scb_rfa_offset; /* Offset of first receive frame area */
- unsigned short scb_crc_errors; /* Properly aligned frame with CRC error*/
- unsigned short scb_aln_errors; /* Misaligned frames */
- unsigned short scb_rsc_errors; /* Frames lost due to no space */
- unsigned short scb_ovn_errors; /* Frames lost due to slow bus */
-} scb_t;
-
-typedef struct { /* iscp */
- unsigned short iscp_busy; /* set by CPU before CA */
- unsigned short iscp_offset; /* offset of SCB */
- unsigned short iscp_basel; /* base of SCB */
- unsigned short iscp_baseh;
-} iscp_t;
-
- /* this address must be 0xfff6 */
-typedef struct { /* scp */
- unsigned short scp_sysbus; /* bus size */
-#define SCP_SY_16BBUS 0x00
-#define SCP_SY_8BBUS 0x01
- unsigned short scp_junk[2]; /* junk */
- unsigned short scp_iscpl; /* lower 16 bits of iscp */
- unsigned short scp_iscph; /* upper 16 bits of iscp */
-} scp_t;
-
-/* commands */
-#define CMD_NOP 0
-#define CMD_SETADDRESS 1
-#define CMD_CONFIG 2
-#define CMD_SETMULTICAST 3
-#define CMD_TX 4
-#define CMD_TDR 5
-#define CMD_DUMP 6
-#define CMD_DIAGNOSE 7
-
-#define CMD_MASK 7
-
-#define CMD_INTR (1 << 13)
-#define CMD_SUSP (1 << 14)
-#define CMD_EOL (1 << 15)
-
-#define STAT_COLLISIONS (15)
-#define STAT_COLLEXCESSIVE (1 << 5)
-#define STAT_COLLAFTERTX (1 << 6)
-#define STAT_TXDEFERRED (1 << 7)
-#define STAT_TXSLOWDMA (1 << 8)
-#define STAT_TXLOSTCTS (1 << 9)
-#define STAT_NOCARRIER (1 << 10)
-#define STAT_FAIL (1 << 11)
-#define STAT_ABORTED (1 << 12)
-#define STAT_OK (1 << 13)
-#define STAT_BUSY (1 << 14)
-#define STAT_COMPLETE (1 << 15)
-#endif
-#endif
-
-/*
- * Ether1 card definitions:
- *
- * FAST accesses:
- * +0 Page register
- * 16 pages
- * +4 Control
- * '1' = reset
- * '2' = loopback
- * '4' = CA
- * '8' = int ack
- *
- * RAM at address + 0x2000
- * Pod. Prod id = 3
- * Words after ID block [base + 8 words]
- * +0 pcb issue (0x0c and 0xf3 invalid)
- * +1 - +6 eth hw address
- */
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
deleted file mode 100644
index 1cc53abc3a3..00000000000
--- a/drivers/net/arm/ether3.c
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- * linux/drivers/acorn/net/ether3.c
- *
- * Copyright (C) 1995-2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * SEEQ nq8005 ethernet driver for Acorn/ANT Ether3 card
- * for Acorn machines
- *
- * By Russell King, with some suggestions from borris@ant.co.uk
- *
- * Changelog:
- * 1.04 RMK 29/02/1996 Won't pass packets that are from our ethernet
- * address up to the higher levels - they're
- * silently ignored. I/F can now be put into
- * multicast mode. Receiver routine optimised.
- * 1.05 RMK 30/02/1996 Now claims interrupt at open when part of
- * the kernel rather than when a module.
- * 1.06 RMK 02/03/1996 Various code cleanups
- * 1.07 RMK 13/10/1996 Optimised interrupt routine and transmit
- * routines.
- * 1.08 RMK 14/10/1996 Fixed problem with too many packets,
- * prevented the kernel message about dropped
- * packets appearing too many times a second.
- * Now does not disable all IRQs, only the IRQ
- * used by this card.
- * 1.09 RMK 10/11/1996 Only enables TX irq when buffer space is low,
- * but we still service the TX queue if we get a
- * RX interrupt.
- * 1.10 RMK 15/07/1997 Fixed autoprobing of NQ8004.
- * 1.11 RMK 16/11/1997 Fixed autoprobing of NQ8005A.
- * 1.12 RMK 31/12/1997 Removed reference to dev_tint for Linux 2.1.
- * RMK 27/06/1998 Changed asm/delay.h to linux/delay.h.
- * 1.13 RMK 29/06/1998 Fixed problem with transmission of packets.
- * Chip seems to have a bug in, whereby if the
- * packet starts two bytes from the end of the
- * buffer, it corrupts the receiver chain, and
- * never updates the transmit status correctly.
- * 1.14 RMK 07/01/1998 Added initial code for ETHERB addressing.
- * 1.15 RMK 30/04/1999 More fixes to the transmit routine for buggy
- * hardware.
- * 1.16 RMK 10/02/2000 Updated for 2.3.43
- * 1.17 RMK 13/05/2000 Updated for 2.3.99-pre8
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/ecard.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-static char version[] __initdata = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n";
-
-#include "ether3.h"
-
-static unsigned int net_debug = NET_DEBUG;
-
-static void ether3_setmulticastlist(struct net_device *dev);
-static int ether3_rx(struct net_device *dev, unsigned int maxcnt);
-static void ether3_tx(struct net_device *dev);
-static int ether3_open (struct net_device *dev);
-static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t ether3_interrupt (int irq, void *dev_id, struct pt_regs *regs);
-static int ether3_close (struct net_device *dev);
-static struct net_device_stats *ether3_getstats (struct net_device *dev);
-static void ether3_setmulticastlist (struct net_device *dev);
-static void ether3_timeout(struct net_device *dev);
-
-#define BUS_16 2
-#define BUS_8 1
-#define BUS_UNKNOWN 0
-
-/* --------------------------------------------------------------------------- */
-
-typedef enum {
- buffer_write,
- buffer_read
-} buffer_rw_t;
-
-/*
- * ether3 read/write. Slow things down a bit...
- * The SEEQ8005 doesn't like us writing to its registers
- * too quickly.
- */
-static inline void ether3_outb(int v, const void __iomem *r)
-{
- writeb(v, r);
- udelay(1);
-}
-
-static inline void ether3_outw(int v, const void __iomem *r)
-{
- writew(v, r);
- udelay(1);
-}
-#define ether3_inb(r) ({ unsigned int __v = readb((r)); udelay(1); __v; })
-#define ether3_inw(r) ({ unsigned int __v = readw((r)); udelay(1); __v; })
-
-static int
-ether3_setbuffer(struct net_device *dev, buffer_rw_t read, int start)
-{
- int timeout = 1000;
-
- ether3_outw(priv(dev)->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1);
- ether3_outw(priv(dev)->regs.command | CMD_FIFOWRITE, REG_COMMAND);
-
- while ((ether3_inw(REG_STATUS) & STAT_FIFOEMPTY) == 0) {
- if (!timeout--) {
- printk("%s: setbuffer broken\n", dev->name);
- priv(dev)->broken = 1;
- return 1;
- }
- udelay(1);
- }
-
- if (read == buffer_read) {
- ether3_outw(start, REG_DMAADDR);
- ether3_outw(priv(dev)->regs.command | CMD_FIFOREAD, REG_COMMAND);
- } else {
- ether3_outw(priv(dev)->regs.command | CMD_FIFOWRITE, REG_COMMAND);
- ether3_outw(start, REG_DMAADDR);
- }
- return 0;
-}
-
-/*
- * write data to the buffer memory
- */
-#define ether3_writebuffer(dev,data,length) \
- writesw(REG_BUFWIN, (data), (length) >> 1)
-
-#define ether3_writeword(dev,data) \
- writew((data), REG_BUFWIN)
-
-#define ether3_writelong(dev,data) { \
- void __iomem *reg_bufwin = REG_BUFWIN; \
- writew((data), reg_bufwin); \
- writew((data) >> 16, reg_bufwin); \
-}
-
-/*
- * read data from the buffer memory
- */
-#define ether3_readbuffer(dev,data,length) \
- readsw(REG_BUFWIN, (data), (length) >> 1)
-
-#define ether3_readword(dev) \
- readw(REG_BUFWIN)
-
-#define ether3_readlong(dev) \
- readw(REG_BUFWIN) | (readw(REG_BUFWIN) << 16)
-
-/*
- * Switch LED off...
- */
-static void ether3_ledoff(unsigned long data)
-{
- struct net_device *dev = (struct net_device *)data;
- ether3_outw(priv(dev)->regs.config2 |= CFG2_CTRLO, REG_CONFIG2);
-}
-
-/*
- * switch LED on...
- */
-static inline void ether3_ledon(struct net_device *dev)
-{
- del_timer(&priv(dev)->timer);
- priv(dev)->timer.expires = jiffies + HZ / 50; /* leave on for 1/50th second */
- priv(dev)->timer.data = (unsigned long)dev;
- priv(dev)->timer.function = ether3_ledoff;
- add_timer(&priv(dev)->timer);
- if (priv(dev)->regs.config2 & CFG2_CTRLO)
- ether3_outw(priv(dev)->regs.config2 &= ~CFG2_CTRLO, REG_CONFIG2);
-}
-
-/*
- * Read the ethernet address string from the on board rom.
- * This is an ascii string!!!
- */
-static int __init
-ether3_addr(char *addr, struct expansion_card *ec)
-{
- struct in_chunk_dir cd;
- char *s;
-
- if (ecard_readchunk(&cd, ec, 0xf5, 0) && (s = strchr(cd.d.string, '('))) {
- int i;
- for (i = 0; i<6; i++) {
- addr[i] = simple_strtoul(s + 1, &s, 0x10);
- if (*s != (i==5?')' : ':' ))
- break;
- }
- if (i == 6)
- return 0;
- }
- /* I wonder if we should even let the user continue in this case
- * - no, it would be better to disable the device
- */
- printk(KERN_ERR "ether3: Couldn't read a valid MAC address from card.\n");
- return -ENODEV;
-}
-
-/* --------------------------------------------------------------------------- */
-
-static int __init
-ether3_ramtest(struct net_device *dev, unsigned char byte)
-{
- unsigned char *buffer = kmalloc(RX_END, GFP_KERNEL);
- int i,ret = 0;
- int max_errors = 4;
- int bad = -1;
-
- if (!buffer)
- return 1;
-
- memset(buffer, byte, RX_END);
- ether3_setbuffer(dev, buffer_write, 0);
- ether3_writebuffer(dev, buffer, TX_END);
- ether3_setbuffer(dev, buffer_write, RX_START);
- ether3_writebuffer(dev, buffer + RX_START, RX_LEN);
- memset(buffer, byte ^ 0xff, RX_END);
- ether3_setbuffer(dev, buffer_read, 0);
- ether3_readbuffer(dev, buffer, TX_END);
- ether3_setbuffer(dev, buffer_read, RX_START);
- ether3_readbuffer(dev, buffer + RX_START, RX_LEN);
-
- for (i = 0; i < RX_END; i++) {
- if (buffer[i] != byte) {
- if (max_errors > 0 && bad != buffer[i]) {
- printk("%s: RAM failed with (%02X instead of %02X) at 0x%04X",
- dev->name, buffer[i], byte, i);
- ret = 2;
- max_errors--;
- bad = i;
- }
- } else {
- if (bad != -1) {
- if (bad != i - 1)
- printk(" - 0x%04X\n", i - 1);
- printk("\n");
- bad = -1;
- }
- }
- }
- if (bad != -1)
- printk(" - 0xffff\n");
- kfree(buffer);
-
- return ret;
-}
-
-/* ------------------------------------------------------------------------------- */
-
-static int __init ether3_init_2(struct net_device *dev)
-{
- int i;
-
- priv(dev)->regs.config1 = CFG1_RECVCOMPSTAT0|CFG1_DMABURST8;
- priv(dev)->regs.config2 = CFG2_CTRLO|CFG2_RECVCRC|CFG2_ERRENCRC;
- priv(dev)->regs.command = 0;
-
- /*
- * Set up our hardware address
- */
- ether3_outw(priv(dev)->regs.config1 | CFG1_BUFSELSTAT0, REG_CONFIG1);
- for (i = 0; i < 6; i++)
- ether3_outb(dev->dev_addr[i], REG_BUFWIN);
-
- if (dev->flags & IFF_PROMISC)
- priv(dev)->regs.config1 |= CFG1_RECVPROMISC;
- else if (dev->flags & IFF_MULTICAST)
- priv(dev)->regs.config1 |= CFG1_RECVSPECBRMULTI;
- else
- priv(dev)->regs.config1 |= CFG1_RECVSPECBROAD;
-
- /*
- * There is a problem with the NQ8005 in that it occasionally loses the
- * last two bytes. To get round this problem, we receive the CRC as
- * well. That way, if we do lose the last two, then it doesn't matter.
- */
- ether3_outw(priv(dev)->regs.config1 | CFG1_TRANSEND, REG_CONFIG1);
- ether3_outw((TX_END>>8) - 1, REG_BUFWIN);
- ether3_outw(priv(dev)->rx_head, REG_RECVPTR);
- ether3_outw(0, REG_TRANSMITPTR);
- ether3_outw(priv(dev)->rx_head >> 8, REG_RECVEND);
- ether3_outw(priv(dev)->regs.config2, REG_CONFIG2);
- ether3_outw(priv(dev)->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1);
- ether3_outw(priv(dev)->regs.command, REG_COMMAND);
-
- i = ether3_ramtest(dev, 0x5A);
- if(i)
- return i;
- i = ether3_ramtest(dev, 0x1E);
- if(i)
- return i;
-
- ether3_setbuffer(dev, buffer_write, 0);
- ether3_writelong(dev, 0);
- return 0;
-}
-
-static void
-ether3_init_for_open(struct net_device *dev)
-{
- int i;
-
- memset(&priv(dev)->stats, 0, sizeof(struct net_device_stats));
-
- /* Reset the chip */
- ether3_outw(CFG2_RESET, REG_CONFIG2);
- udelay(4);
-
- priv(dev)->regs.command = 0;
- ether3_outw(CMD_RXOFF|CMD_TXOFF, REG_COMMAND);
- while (ether3_inw(REG_STATUS) & (STAT_RXON|STAT_TXON))
- barrier();
-
- ether3_outw(priv(dev)->regs.config1 | CFG1_BUFSELSTAT0, REG_CONFIG1);
- for (i = 0; i < 6; i++)
- ether3_outb(dev->dev_addr[i], REG_BUFWIN);
-
- priv(dev)->tx_head = 0;
- priv(dev)->tx_tail = 0;
- priv(dev)->regs.config2 |= CFG2_CTRLO;
- priv(dev)->rx_head = RX_START;
-
- ether3_outw(priv(dev)->regs.config1 | CFG1_TRANSEND, REG_CONFIG1);
- ether3_outw((TX_END>>8) - 1, REG_BUFWIN);
- ether3_outw(priv(dev)->rx_head, REG_RECVPTR);
- ether3_outw(priv(dev)->rx_head >> 8, REG_RECVEND);
- ether3_outw(0, REG_TRANSMITPTR);
- ether3_outw(priv(dev)->regs.config2, REG_CONFIG2);
- ether3_outw(priv(dev)->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1);
-
- ether3_setbuffer(dev, buffer_write, 0);
- ether3_writelong(dev, 0);
-
- priv(dev)->regs.command = CMD_ENINTRX | CMD_ENINTTX;
- ether3_outw(priv(dev)->regs.command | CMD_RXON, REG_COMMAND);
-}
-
-static inline int
-ether3_probe_bus_8(struct net_device *dev, int val)
-{
- int write_low, write_high, read_low, read_high;
-
- write_low = val & 255;
- write_high = val >> 8;
-
- printk(KERN_DEBUG "ether3_probe: write8 [%02X:%02X]", write_high, write_low);
-
- ether3_outb(write_low, REG_RECVPTR);
- ether3_outb(write_high, REG_RECVPTR + 4);
-
- read_low = ether3_inb(REG_RECVPTR);
- read_high = ether3_inb(REG_RECVPTR + 4);
-
- printk(", read8 [%02X:%02X]\n", read_high, read_low);
-
- return read_low == write_low && read_high == write_high;
-}
-
-static inline int
-ether3_probe_bus_16(struct net_device *dev, int val)
-{
- int read_val;
-
- ether3_outw(val, REG_RECVPTR);
- read_val = ether3_inw(REG_RECVPTR);
-
- printk(KERN_DEBUG "ether3_probe: write16 [%04X], read16 [%04X]\n", val, read_val);
-
- return read_val == val;
-}
-
-/*
- * Open/initialize the board. This is called (in the current kernel)
- * sometime after booting when the 'ifconfig' program is run.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is non-reboot way to recover if something goes wrong.
- */
-static int
-ether3_open(struct net_device *dev)
-{
- if (!is_valid_ether_addr(dev->dev_addr)) {
- printk(KERN_WARNING "%s: invalid ethernet MAC address\n",
- dev->name);
- return -EINVAL;
- }
-
- if (request_irq(dev->irq, ether3_interrupt, 0, "ether3", dev))
- return -EAGAIN;
-
- ether3_init_for_open(dev);
-
- netif_start_queue(dev);
-
- return 0;
-}
-
-/*
- * The inverse routine to ether3_open().
- */
-static int
-ether3_close(struct net_device *dev)
-{
- netif_stop_queue(dev);
-
- disable_irq(dev->irq);
-
- ether3_outw(CMD_RXOFF|CMD_TXOFF, REG_COMMAND);
- priv(dev)->regs.command = 0;
- while (ether3_inw(REG_STATUS) & (STAT_RXON|STAT_TXON))
- barrier();
- ether3_outb(0x80, REG_CONFIG2 + 4);
- ether3_outw(0, REG_COMMAND);
-
- free_irq(dev->irq, dev);
-
- return 0;
-}
-
-/*
- * Get the current statistics. This may be called with the card open or
- * closed.
- */
-static struct net_device_stats *ether3_getstats(struct net_device *dev)
-{
- return &priv(dev)->stats;
-}
-
-/*
- * Set or clear promiscuous/multicast mode filter for this adaptor.
- *
- * We don't attempt any packet filtering. The card may have a SEEQ 8004
- * in which does not have the other ethernet address registers present...
- */
-static void ether3_setmulticastlist(struct net_device *dev)
-{
- priv(dev)->regs.config1 &= ~CFG1_RECVPROMISC;
-
- if (dev->flags & IFF_PROMISC) {
- /* promiscuous mode */
- priv(dev)->regs.config1 |= CFG1_RECVPROMISC;
- } else if (dev->flags & IFF_ALLMULTI) {
- priv(dev)->regs.config1 |= CFG1_RECVSPECBRMULTI;
- } else
- priv(dev)->regs.config1 |= CFG1_RECVSPECBROAD;
-
- ether3_outw(priv(dev)->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1);
-}
-
-static void ether3_timeout(struct net_device *dev)
-{
- unsigned long flags;
-
- del_timer(&priv(dev)->timer);
-
- local_irq_save(flags);
- printk(KERN_ERR "%s: transmit timed out, network cable problem?\n", dev->name);
- printk(KERN_ERR "%s: state: { status=%04X cfg1=%04X cfg2=%04X }\n", dev->name,
- ether3_inw(REG_STATUS), ether3_inw(REG_CONFIG1), ether3_inw(REG_CONFIG2));
- printk(KERN_ERR "%s: { rpr=%04X rea=%04X tpr=%04X }\n", dev->name,
- ether3_inw(REG_RECVPTR), ether3_inw(REG_RECVEND), ether3_inw(REG_TRANSMITPTR));
- printk(KERN_ERR "%s: tx head=%X tx tail=%X\n", dev->name,
- priv(dev)->tx_head, priv(dev)->tx_tail);
- ether3_setbuffer(dev, buffer_read, priv(dev)->tx_tail);
- printk(KERN_ERR "%s: packet status = %08X\n", dev->name, ether3_readlong(dev));
- local_irq_restore(flags);
-
- priv(dev)->regs.config2 |= CFG2_CTRLO;
- priv(dev)->stats.tx_errors += 1;
- ether3_outw(priv(dev)->regs.config2, REG_CONFIG2);
- priv(dev)->tx_head = priv(dev)->tx_tail = 0;
-
- netif_wake_queue(dev);
-}
-
-/*
- * Transmit a packet
- */
-static int
-ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
-{
- unsigned long flags;
- unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- unsigned int ptr, next_ptr;
-
- if (priv(dev)->broken) {
- dev_kfree_skb(skb);
- priv(dev)->stats.tx_dropped ++;
- netif_start_queue(dev);
- return 0;
- }
-
- length = (length + 1) & ~1;
- if (length != skb->len) {
- skb = skb_padto(skb, length);
- if (skb == NULL)
- goto out;
- }
-
- next_ptr = (priv(dev)->tx_head + 1) & 15;
-
- local_irq_save(flags);
-
- if (priv(dev)->tx_tail == next_ptr) {
- local_irq_restore(flags);
- return 1; /* unable to queue */
- }
-
- dev->trans_start = jiffies;
- ptr = 0x600 * priv(dev)->tx_head;
- priv(dev)->tx_head = next_ptr;
- next_ptr *= 0x600;
-
-#define TXHDR_FLAGS (TXHDR_TRANSMIT|TXHDR_CHAINCONTINUE|TXHDR_DATAFOLLOWS|TXHDR_ENSUCCESS)
-
- ether3_setbuffer(dev, buffer_write, next_ptr);
- ether3_writelong(dev, 0);
- ether3_setbuffer(dev, buffer_write, ptr);
- ether3_writelong(dev, 0);
- ether3_writebuffer(dev, skb->data, length);
- ether3_writeword(dev, htons(next_ptr));
- ether3_writeword(dev, TXHDR_CHAINCONTINUE >> 16);
- ether3_setbuffer(dev, buffer_write, ptr);
- ether3_writeword(dev, htons((ptr + length + 4)));
- ether3_writeword(dev, TXHDR_FLAGS >> 16);
- ether3_ledon(dev);
-
- if (!(ether3_inw(REG_STATUS) & STAT_TXON)) {
- ether3_outw(ptr, REG_TRANSMITPTR);
- ether3_outw(priv(dev)->regs.command | CMD_TXON, REG_COMMAND);
- }
-
- next_ptr = (priv(dev)->tx_head + 1) & 15;
- local_irq_restore(flags);
-
- dev_kfree_skb(skb);
-
- if (priv(dev)->tx_tail == next_ptr)
- netif_stop_queue(dev);
-
- out:
- return 0;
-}
-
-static irqreturn_t
-ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct net_device *dev = (struct net_device *)dev_id;
- unsigned int status, handled = IRQ_NONE;
-
-#if NET_DEBUG > 1
- if(net_debug & DEBUG_INT)
- printk("eth3irq: %d ", irq);
-#endif
-
- status = ether3_inw(REG_STATUS);
-
- if (status & STAT_INTRX) {
- ether3_outw(CMD_ACKINTRX | priv(dev)->regs.command, REG_COMMAND);
- ether3_rx(dev, 12);
- handled = IRQ_HANDLED;
- }
-
- if (status & STAT_INTTX) {
- ether3_outw(CMD_ACKINTTX | priv(dev)->regs.command, REG_COMMAND);
- ether3_tx(dev);
- handled = IRQ_HANDLED;
- }
-
-#if NET_DEBUG > 1
- if(net_debug & DEBUG_INT)
- printk("done\n");
-#endif
- return handled;
-}
-
-/*
- * If we have a good packet(s), get it/them out of the buffers.
- */
-static int ether3_rx(struct net_device *dev, unsigned int maxcnt)
-{
- unsigned int next_ptr = priv(dev)->rx_head, received = 0;
-
- ether3_ledon(dev);
-
- do {
- unsigned int this_ptr, status;
- unsigned char addrs[16];
-
- /*
- * read the first 16 bytes from the buffer.
- * This contains the status bytes etc and ethernet addresses,
- * and we also check the source ethernet address to see if
- * it originated from us.
- */
- {
- unsigned int temp_ptr;
- ether3_setbuffer(dev, buffer_read, next_ptr);
- temp_ptr = ether3_readword(dev);
- status = ether3_readword(dev);
- if ((status & (RXSTAT_DONE | RXHDR_CHAINCONTINUE | RXHDR_RECEIVE)) !=
- (RXSTAT_DONE | RXHDR_CHAINCONTINUE) || !temp_ptr)
- break;
-
- this_ptr = next_ptr + 4;
- next_ptr = ntohs(temp_ptr);
- }
- ether3_setbuffer(dev, buffer_read, this_ptr);
- ether3_readbuffer(dev, addrs+2, 12);
-
-if (next_ptr < RX_START || next_ptr >= RX_END) {
- int i;
- printk("%s: bad next pointer @%04X: ", dev->name, priv(dev)->rx_head);
- printk("%02X %02X %02X %02X ", next_ptr >> 8, next_ptr & 255, status & 255, status >> 8);
- for (i = 2; i < 14; i++)
- printk("%02X ", addrs[i]);
- printk("\n");
- next_ptr = priv(dev)->rx_head;
- break;
-}
- /*
- * ignore our own packets...
- */
- if (!(*(unsigned long *)&dev->dev_addr[0] ^ *(unsigned long *)&addrs[2+6]) &&
- !(*(unsigned short *)&dev->dev_addr[4] ^ *(unsigned short *)&addrs[2+10])) {
- maxcnt ++; /* compensate for loopedback packet */
- ether3_outw(next_ptr >> 8, REG_RECVEND);
- } else
- if (!(status & (RXSTAT_OVERSIZE|RXSTAT_CRCERROR|RXSTAT_DRIBBLEERROR|RXSTAT_SHORTPACKET))) {
- unsigned int length = next_ptr - this_ptr;
- struct sk_buff *skb;
-
- if (next_ptr <= this_ptr)
- length += RX_END - RX_START;
-
- skb = dev_alloc_skb(length + 2);
- if (skb) {
- unsigned char *buf;
-
- skb->dev = dev;
- skb_reserve(skb, 2);
- buf = skb_put(skb, length);
- ether3_readbuffer(dev, buf + 12, length - 12);
- ether3_outw(next_ptr >> 8, REG_RECVEND);
- *(unsigned short *)(buf + 0) = *(unsigned short *)(addrs + 2);
- *(unsigned long *)(buf + 2) = *(unsigned long *)(addrs + 4);
- *(unsigned long *)(buf + 6) = *(unsigned long *)(addrs + 8);
- *(unsigned short *)(buf + 10) = *(unsigned short *)(addrs + 12);
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
- received ++;
- } else
- goto dropping;
- } else {
- struct net_device_stats *stats = &priv(dev)->stats;
- ether3_outw(next_ptr >> 8, REG_RECVEND);
- if (status & RXSTAT_OVERSIZE) stats->rx_over_errors ++;
- if (status & RXSTAT_CRCERROR) stats->rx_crc_errors ++;
- if (status & RXSTAT_DRIBBLEERROR) stats->rx_fifo_errors ++;
- if (status & RXSTAT_SHORTPACKET) stats->rx_length_errors ++;
- stats->rx_errors++;
- }
- }
- while (-- maxcnt);
-
-done:
- priv(dev)->stats.rx_packets += received;
- priv(dev)->rx_head = next_ptr;
- /*
- * If rx went off line, then that means that the buffer may be full. We
- * have dropped at least one packet.
- */
- if (!(ether3_inw(REG_STATUS) & STAT_RXON)) {
- priv(dev)->stats.rx_dropped ++;
- ether3_outw(next_ptr, REG_RECVPTR);
- ether3_outw(priv(dev)->regs.command | CMD_RXON, REG_COMMAND);
- }
-
- return maxcnt;
-
-dropping:{
- static unsigned long last_warned;
-
- ether3_outw(next_ptr >> 8, REG_RECVEND);
- /*
- * Don't print this message too many times...
- */
- if (time_after(jiffies, last_warned + 10 * HZ)) {
- last_warned = jiffies;
- printk("%s: memory squeeze, dropping packet.\n", dev->name);
- }
- priv(dev)->stats.rx_dropped ++;
- goto done;
- }
-}
-
-/*
- * Update stats for the transmitted packet(s)
- */
-static void ether3_tx(struct net_device *dev)
-{
- unsigned int tx_tail = priv(dev)->tx_tail;
- int max_work = 14;
-
- do {
- unsigned long status;
-
- /*
- * Read the packet header
- */
- ether3_setbuffer(dev, buffer_read, tx_tail * 0x600);
- status = ether3_readlong(dev);
-
- /*
- * Check to see if this packet has been transmitted
- */
- if ((status & (TXSTAT_DONE | TXHDR_TRANSMIT)) !=
- (TXSTAT_DONE | TXHDR_TRANSMIT))
- break;
-
- /*
- * Update errors
- */
- if (!(status & (TXSTAT_BABBLED | TXSTAT_16COLLISIONS)))
- priv(dev)->stats.tx_packets++;
- else {
- priv(dev)->stats.tx_errors ++;
- if (status & TXSTAT_16COLLISIONS)
- priv(dev)->stats.collisions += 16;
- if (status & TXSTAT_BABBLED)
- priv(dev)->stats.tx_fifo_errors ++;
- }
-
- tx_tail = (tx_tail + 1) & 15;
- } while (--max_work);
-
- if (priv(dev)->tx_tail != tx_tail) {
- priv(dev)->tx_tail = tx_tail;
- netif_wake_queue(dev);
- }
-}
-
-static void __init ether3_banner(void)
-{
- static unsigned version_printed = 0;
-
- if (net_debug && version_printed++ == 0)
- printk(KERN_INFO "%s", version);
-}
-
-static int __devinit
-ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
-{
- const struct ether3_data *data = id->data;
- struct net_device *dev;
- int i, bus_type, ret;
-
- ether3_banner();
-
- ret = ecard_request_resources(ec);
- if (ret)
- goto out;
-
- dev = alloc_etherdev(sizeof(struct dev_priv));
- if (!dev) {
- ret = -ENOMEM;
- goto release;
- }
-
- SET_MODULE_OWNER(dev);
- SET_NETDEV_DEV(dev, &ec->dev);
-
- priv(dev)->base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
- ecard_resource_len(ec, ECARD_RES_MEMC));
- if (!priv(dev)->base) {
- ret = -ENOMEM;
- goto free;
- }
-
- ec->irqaddr = priv(dev)->base + data->base_offset;
- ec->irqmask = 0xf0;
-
- priv(dev)->seeq = priv(dev)->base + data->base_offset;
- dev->irq = ec->irq;
-
- ether3_addr(dev->dev_addr, ec);
-
- init_timer(&priv(dev)->timer);
-
- /* Reset card...
- */
- ether3_outb(0x80, REG_CONFIG2 + 4);
- bus_type = BUS_UNKNOWN;
- udelay(4);
-
- /* Test using Receive Pointer (16-bit register) to find out
- * how the ether3 is connected to the bus...
- */
- if (ether3_probe_bus_8(dev, 0x100) &&
- ether3_probe_bus_8(dev, 0x201))
- bus_type = BUS_8;
-
- if (bus_type == BUS_UNKNOWN &&
- ether3_probe_bus_16(dev, 0x101) &&
- ether3_probe_bus_16(dev, 0x201))
- bus_type = BUS_16;
-
- switch (bus_type) {
- case BUS_UNKNOWN:
- printk(KERN_ERR "%s: unable to identify bus width\n", dev->name);
- ret = -ENODEV;
- goto free;
-
- case BUS_8:
- printk(KERN_ERR "%s: %s found, but is an unsupported "
- "8-bit card\n", dev->name, data->name);
- ret = -ENODEV;
- goto free;
-
- default:
- break;
- }
-
- if (ether3_init_2(dev)) {
- ret = -ENODEV;
- goto free;
- }
-
- dev->open = ether3_open;
- dev->stop = ether3_close;
- dev->hard_start_xmit = ether3_sendpacket;
- dev->get_stats = ether3_getstats;
- dev->set_multicast_list = ether3_setmulticastlist;
- dev->tx_timeout = ether3_timeout;
- dev->watchdog_timeo = 5 * HZ / 100;
-
- ret = register_netdev(dev);
- if (ret)
- goto free;
-
- printk("%s: %s in slot %d, ", dev->name, data->name, ec->slot_no);
- for (i = 0; i < 6; i++)
- printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
-
- ecard_set_drvdata(ec, dev);
- return 0;
-
- free:
- if (priv(dev)->base)
- iounmap(priv(dev)->base);
- free_netdev(dev);
- release:
- ecard_release_resources(ec);
- out:
- return ret;
-}
-
-static void __devexit ether3_remove(struct expansion_card *ec)
-{
- struct net_device *dev = ecard_get_drvdata(ec);
-
- ecard_set_drvdata(ec, NULL);
-
- unregister_netdev(dev);
- iounmap(priv(dev)->base);
- free_netdev(dev);
- ecard_release_resources(ec);
-}
-
-static struct ether3_data ether3 = {
- .name = "ether3",
- .base_offset = 0,
-};
-
-static struct ether3_data etherb = {
- .name = "etherb",
- .base_offset = 0x800,
-};
-
-static const struct ecard_id ether3_ids[] = {
- { MANU_ANT2, PROD_ANT_ETHER3, &ether3 },
- { MANU_ANT, PROD_ANT_ETHER3, &ether3 },
- { MANU_ANT, PROD_ANT_ETHERB, &etherb },
- { 0xffff, 0xffff }
-};
-
-static struct ecard_driver ether3_driver = {
- .probe = ether3_probe,
- .remove = __devexit_p(ether3_remove),
- .id_table = ether3_ids,
- .drv = {
- .name = "ether3",
- },
-};
-
-static int __init ether3_init(void)
-{
- return ecard_register_driver(&ether3_driver);
-}
-
-static void __exit ether3_exit(void)
-{
- ecard_remove_driver(&ether3_driver);
-}
-
-module_init(ether3_init);
-module_exit(ether3_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/arm/ether3.h b/drivers/net/arm/ether3.h
deleted file mode 100644
index 1921a3a07da..00000000000
--- a/drivers/net/arm/ether3.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * linux/drivers/acorn/net/ether3.h
- *
- * Copyright (C) 1995-2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * network driver for Acorn/ANT Ether3 cards
- */
-
-#ifndef _LINUX_ether3_H
-#define _LINUX_ether3_H
-
-/* use 0 for production, 1 for verification, >2 for debug. debug flags: */
-#define DEBUG_TX 2
-#define DEBUG_RX 4
-#define DEBUG_INT 8
-#define DEBUG_IC 16
-#ifndef NET_DEBUG
-#define NET_DEBUG 0
-#endif
-
-#define priv(dev) ((struct dev_priv *)netdev_priv(dev))
-
-/* Command register definitions & bits */
-#define REG_COMMAND (priv(dev)->seeq + 0x0000)
-#define CMD_ENINTDMA 0x0001
-#define CMD_ENINTRX 0x0002
-#define CMD_ENINTTX 0x0004
-#define CMD_ENINTBUFWIN 0x0008
-#define CMD_ACKINTDMA 0x0010
-#define CMD_ACKINTRX 0x0020
-#define CMD_ACKINTTX 0x0040
-#define CMD_ACKINTBUFWIN 0x0080
-#define CMD_DMAON 0x0100
-#define CMD_RXON 0x0200
-#define CMD_TXON 0x0400
-#define CMD_DMAOFF 0x0800
-#define CMD_RXOFF 0x1000
-#define CMD_TXOFF 0x2000
-#define CMD_FIFOREAD 0x4000
-#define CMD_FIFOWRITE 0x8000
-
-/* status register */
-#define REG_STATUS (priv(dev)->seeq + 0x0000)
-#define STAT_ENINTSTAT 0x0001
-#define STAT_ENINTRX 0x0002
-#define STAT_ENINTTX 0x0004
-#define STAT_ENINTBUFWIN 0x0008
-#define STAT_INTDMA 0x0010
-#define STAT_INTRX 0x0020
-#define STAT_INTTX 0x0040
-#define STAT_INTBUFWIN 0x0080
-#define STAT_DMAON 0x0100
-#define STAT_RXON 0x0200
-#define STAT_TXON 0x0400
-#define STAT_FIFOFULL 0x2000
-#define STAT_FIFOEMPTY 0x4000
-#define STAT_FIFODIR 0x8000
-
-/* configuration register 1 */
-#define REG_CONFIG1 (priv(dev)->seeq + 0x0040)
-#define CFG1_BUFSELSTAT0 0x0000
-#define CFG1_BUFSELSTAT1 0x0001
-#define CFG1_BUFSELSTAT2 0x0002
-#define CFG1_BUFSELSTAT3 0x0003
-#define CFG1_BUFSELSTAT4 0x0004
-#define CFG1_BUFSELSTAT5 0x0005
-#define CFG1_ADDRPROM 0x0006
-#define CFG1_TRANSEND 0x0007
-#define CFG1_LOCBUFMEM 0x0008
-#define CFG1_INTVECTOR 0x0009
-#define CFG1_RECVSPECONLY 0x0000
-#define CFG1_RECVSPECBROAD 0x4000
-#define CFG1_RECVSPECBRMULTI 0x8000
-#define CFG1_RECVPROMISC 0xC000
-
-/* The following aren't in 8004 */
-#define CFG1_DMABURSTCONT 0x0000
-#define CFG1_DMABURST800NS 0x0010
-#define CFG1_DMABURST1600NS 0x0020
-#define CFG1_DMABURST3200NS 0x0030
-#define CFG1_DMABURST1 0x0000
-#define CFG1_DMABURST4 0x0040
-#define CFG1_DMABURST8 0x0080
-#define CFG1_DMABURST16 0x00C0
-#define CFG1_RECVCOMPSTAT0 0x0100
-#define CFG1_RECVCOMPSTAT1 0x0200
-#define CFG1_RECVCOMPSTAT2 0x0400
-#define CFG1_RECVCOMPSTAT3 0x0800
-#define CFG1_RECVCOMPSTAT4 0x1000
-#define CFG1_RECVCOMPSTAT5 0x2000
-
-/* configuration register 2 */
-#define REG_CONFIG2 (priv(dev)->seeq + 0x0080)
-#define CFG2_BYTESWAP 0x0001
-#define CFG2_ERRENCRC 0x0008
-#define CFG2_ERRENDRIBBLE 0x0010
-#define CFG2_ERRSHORTFRAME 0x0020
-#define CFG2_SLOTSELECT 0x0040
-#define CFG2_PREAMSELECT 0x0080
-#define CFG2_ADDRLENGTH 0x0100
-#define CFG2_RECVCRC 0x0200
-#define CFG2_XMITNOCRC 0x0400
-#define CFG2_LOOPBACK 0x0800
-#define CFG2_CTRLO 0x1000
-#define CFG2_RESET 0x8000
-
-#define REG_RECVEND (priv(dev)->seeq + 0x00c0)
-
-#define REG_BUFWIN (priv(dev)->seeq + 0x0100)
-
-#define REG_RECVPTR (priv(dev)->seeq + 0x0140)
-
-#define REG_TRANSMITPTR (priv(dev)->seeq + 0x0180)
-
-#define REG_DMAADDR (priv(dev)->seeq + 0x01c0)
-
-/*
- * Cards transmit/receive headers
- */
-#define TX_NEXT (0xffff)
-#define TXHDR_ENBABBLEINT (1 << 16)
-#define TXHDR_ENCOLLISIONINT (1 << 17)
-#define TXHDR_EN16COLLISION (1 << 18)
-#define TXHDR_ENSUCCESS (1 << 19)
-#define TXHDR_DATAFOLLOWS (1 << 21)
-#define TXHDR_CHAINCONTINUE (1 << 22)
-#define TXHDR_TRANSMIT (1 << 23)
-#define TXSTAT_BABBLED (1 << 24)
-#define TXSTAT_COLLISION (1 << 25)
-#define TXSTAT_16COLLISIONS (1 << 26)
-#define TXSTAT_DONE (1 << 31)
-
-#define RX_NEXT (0xffff)
-#define RXHDR_CHAINCONTINUE (1 << 6)
-#define RXHDR_RECEIVE (1 << 7)
-#define RXSTAT_OVERSIZE (1 << 8)
-#define RXSTAT_CRCERROR (1 << 9)
-#define RXSTAT_DRIBBLEERROR (1 << 10)
-#define RXSTAT_SHORTPACKET (1 << 11)
-#define RXSTAT_DONE (1 << 15)
-
-
-#define TX_START 0x0000
-#define TX_END 0x6000
-#define RX_START 0x6000
-#define RX_LEN 0xA000
-#define RX_END 0x10000
-/* must be a power of 2 and greater than MAX_TX_BUFFERED */
-#define MAX_TXED 16
-#define MAX_TX_BUFFERED 10
-
-struct dev_priv {
- void __iomem *base;
- void __iomem *seeq;
- struct {
- unsigned int command;
- unsigned int config1;
- unsigned int config2;
- } regs;
- unsigned char tx_head; /* buffer nr to insert next packet */
- unsigned char tx_tail; /* buffer nr of transmitting packet */
- unsigned int rx_head; /* address to fetch next packet from */
- struct net_device_stats stats;
- struct timer_list timer;
- int broken; /* 0 = ok, 1 = something went wrong */
-};
-
-struct ether3_data {
- const char name[8];
- unsigned long base_offset;
-};
-
-#endif
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
deleted file mode 100644
index 942a2819576..00000000000
--- a/drivers/net/arm/etherh.c
+++ /dev/null
@@ -1,862 +0,0 @@
-/*
- * linux/drivers/acorn/net/etherh.c
- *
- * Copyright (C) 2000-2002 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * NS8390 I-cubed EtherH and ANT EtherM specific driver
- * Thanks to I-Cubed for information on their cards.
- * EtherM conversion (C) 1999 Chris Kemp and Tim Watterton
- * EtherM integration (C) 2000 Aleph One Ltd (Tak-Shing Chan)
- * EtherM integration re-engineered by Russell King.
- *
- * Changelog:
- * 08-12-1996 RMK 1.00 Created
- * RMK 1.03 Added support for EtherLan500 cards
- * 23-11-1997 RMK 1.04 Added media autodetection
- * 16-04-1998 RMK 1.05 Improved media autodetection
- * 10-02-2000 RMK 1.06 Updated for 2.3.43
- * 13-05-2000 RMK 1.07 Updated for 2.3.99-pre8
- * 12-10-1999 CK/TEW EtherM driver first release
- * 21-12-2000 TTC EtherH/EtherM integration
- * 25-12-2000 RMK 1.08 Clean integration of EtherM into this driver.
- * 03-01-2002 RMK 1.09 Always enable IRQs if we're in the nic slot.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/ecard.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include "../8390.h"
-
-#define NET_DEBUG 0
-#define DEBUG_INIT 2
-
-#define DRV_NAME "etherh"
-#define DRV_VERSION "1.11"
-
-static unsigned int net_debug = NET_DEBUG;
-
-struct etherh_priv {
- void __iomem *ioc_fast;
- void __iomem *memc;
- void __iomem *dma_base;
- unsigned int id;
- void __iomem *ctrl_port;
- unsigned char ctrl;
- u32 supported;
-};
-
-struct etherh_data {
- unsigned long ns8390_offset;
- unsigned long dataport_offset;
- unsigned long ctrlport_offset;
- int ctrl_ioc;
- const char name[16];
- u32 supported;
- unsigned char tx_start_page;
- unsigned char stop_page;
-};
-
-MODULE_AUTHOR("Russell King");
-MODULE_DESCRIPTION("EtherH/EtherM driver");
-MODULE_LICENSE("GPL");
-
-static char version[] __initdata =
- "EtherH/EtherM Driver (c) 2002-2004 Russell King " DRV_VERSION "\n";
-
-#define ETHERH500_DATAPORT 0x800 /* MEMC */
-#define ETHERH500_NS8390 0x000 /* MEMC */
-#define ETHERH500_CTRLPORT 0x800 /* IOC */
-
-#define ETHERH600_DATAPORT 0x040 /* MEMC */
-#define ETHERH600_NS8390 0x800 /* MEMC */
-#define ETHERH600_CTRLPORT 0x200 /* MEMC */
-
-#define ETHERH_CP_IE 1
-#define ETHERH_CP_IF 2
-#define ETHERH_CP_HEARTBEAT 2
-
-#define ETHERH_TX_START_PAGE 1
-#define ETHERH_STOP_PAGE 127
-
-/*
- * These came from CK/TEW
- */
-#define ETHERM_DATAPORT 0x200 /* MEMC */
-#define ETHERM_NS8390 0x800 /* MEMC */
-#define ETHERM_CTRLPORT 0x23c /* MEMC */
-
-#define ETHERM_TX_START_PAGE 64
-#define ETHERM_STOP_PAGE 127
-
-/* ------------------------------------------------------------------------ */
-
-#define etherh_priv(dev) \
- ((struct etherh_priv *)(((char *)netdev_priv(dev)) + sizeof(struct ei_device)))
-
-static inline void etherh_set_ctrl(struct etherh_priv *eh, unsigned char mask)
-{
- unsigned char ctrl = eh->ctrl | mask;
- eh->ctrl = ctrl;
- writeb(ctrl, eh->ctrl_port);
-}
-
-static inline void etherh_clr_ctrl(struct etherh_priv *eh, unsigned char mask)
-{
- unsigned char ctrl = eh->ctrl & ~mask;
- eh->ctrl = ctrl;
- writeb(ctrl, eh->ctrl_port);
-}
-
-static inline unsigned int etherh_get_stat(struct etherh_priv *eh)
-{
- return readb(eh->ctrl_port);
-}
-
-
-
-
-static void etherh_irq_enable(ecard_t *ec, int irqnr)
-{
- struct etherh_priv *eh = ec->irq_data;
-
- etherh_set_ctrl(eh, ETHERH_CP_IE);
-}
-
-static void etherh_irq_disable(ecard_t *ec, int irqnr)
-{
- struct etherh_priv *eh = ec->irq_data;
-
- etherh_clr_ctrl(eh, ETHERH_CP_IE);
-}
-
-static expansioncard_ops_t etherh_ops = {
- .irqenable = etherh_irq_enable,
- .irqdisable = etherh_irq_disable,
-};
-
-
-
-
-static void
-etherh_setif(struct net_device *dev)
-{
- struct ei_device *ei_local = netdev_priv(dev);
- unsigned long flags;
- void __iomem *addr;
-
- local_irq_save(flags);
-
- /* set the interface type */
- switch (etherh_priv(dev)->id) {
- case PROD_I3_ETHERLAN600:
- case PROD_I3_ETHERLAN600A:
- addr = (void *)dev->base_addr + EN0_RCNTHI;
-
- switch (dev->if_port) {
- case IF_PORT_10BASE2:
- writeb((readb(addr) & 0xf8) | 1, addr);
- break;
- case IF_PORT_10BASET:
- writeb((readb(addr) & 0xf8), addr);
- break;
- }
- break;
-
- case PROD_I3_ETHERLAN500:
- switch (dev->if_port) {
- case IF_PORT_10BASE2:
- etherh_clr_ctrl(etherh_priv(dev), ETHERH_CP_IF);
- break;
-
- case IF_PORT_10BASET:
- etherh_set_ctrl(etherh_priv(dev), ETHERH_CP_IF);
- break;
- }
- break;
-
- default:
- break;
- }
-
- local_irq_restore(flags);
-}
-
-static int
-etherh_getifstat(struct net_device *dev)
-{
- struct ei_device *ei_local = netdev_priv(dev);
- void __iomem *addr;
- int stat = 0;
-
- switch (etherh_priv(dev)->id) {
- case PROD_I3_ETHERLAN600:
- case PROD_I3_ETHERLAN600A:
- addr = (void *)dev->base_addr + EN0_RCNTHI;
- switch (dev->if_port) {
- case IF_PORT_10BASE2:
- stat = 1;
- break;
- case IF_PORT_10BASET:
- stat = readb(addr) & 4;
- break;
- }
- break;
-
- case PROD_I3_ETHERLAN500:
- switch (dev->if_port) {
- case IF_PORT_10BASE2:
- stat = 1;
- break;
- case IF_PORT_10BASET:
- stat = etherh_get_stat(etherh_priv(dev)) & ETHERH_CP_HEARTBEAT;
- break;
- }
- break;
-
- default:
- stat = 0;
- break;
- }
-
- return stat != 0;
-}
-
-/*
- * Configure the interface. Note that we ignore the other
- * parts of ifmap, since its mostly meaningless for this driver.
- */
-static int etherh_set_config(struct net_device *dev, struct ifmap *map)
-{
- switch (map->port) {
- case IF_PORT_10BASE2:
- case IF_PORT_10BASET:
- /*
- * If the user explicitly sets the interface
- * media type, turn off automedia detection.
- */
- dev->flags &= ~IFF_AUTOMEDIA;
- dev->if_port = map->port;
- break;
-
- default:
- return -EINVAL;
- }
-
- etherh_setif(dev);
-
- return 0;
-}
-
-/*
- * Reset the 8390 (hard reset). Note that we can't actually do this.
- */
-static void
-etherh_reset(struct net_device *dev)
-{
- struct ei_device *ei_local = netdev_priv(dev);
- void __iomem *addr = (void *)dev->base_addr;
-
- writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, addr);
-
- /*
- * See if we need to change the interface type.
- * Note that we use 'interface_num' as a flag
- * to indicate that we need to change the media.
- */
- if (dev->flags & IFF_AUTOMEDIA && ei_local->interface_num) {
- ei_local->interface_num = 0;
-
- if (dev->if_port == IF_PORT_10BASET)
- dev->if_port = IF_PORT_10BASE2;
- else
- dev->if_port = IF_PORT_10BASET;
-
- etherh_setif(dev);
- }
-}
-
-/*
- * Write a block of data out to the 8390
- */
-static void
-etherh_block_output (struct net_device *dev, int count, const unsigned char *buf, int start_page)
-{
- struct ei_device *ei_local = netdev_priv(dev);
- unsigned long dma_start;
- void __iomem *dma_base, *addr;
-
- if (ei_local->dmaing) {
- printk(KERN_ERR "%s: DMAing conflict in etherh_block_input: "
- " DMAstat %d irqlock %d\n", dev->name,
- ei_local->dmaing, ei_local->irqlock);
- return;
- }
-
- /*
- * Make sure we have a round number of bytes if we're in word mode.
- */
- if (count & 1 && ei_local->word16)
- count++;
-
- ei_local->dmaing = 1;
-
- addr = (void *)dev->base_addr;
- dma_base = etherh_priv(dev)->dma_base;
-
- count = (count + 1) & ~1;
- writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD);
-
- writeb (0x42, addr + EN0_RCNTLO);
- writeb (0x00, addr + EN0_RCNTHI);
- writeb (0x42, addr + EN0_RSARLO);
- writeb (0x00, addr + EN0_RSARHI);
- writeb (E8390_RREAD | E8390_START, addr + E8390_CMD);
-
- udelay (1);
-
- writeb (ENISR_RDC, addr + EN0_ISR);
- writeb (count, addr + EN0_RCNTLO);
- writeb (count >> 8, addr + EN0_RCNTHI);
- writeb (0, addr + EN0_RSARLO);
- writeb (start_page, addr + EN0_RSARHI);
- writeb (E8390_RWRITE | E8390_START, addr + E8390_CMD);
-
- if (ei_local->word16)
- writesw (dma_base, buf, count >> 1);
- else
- writesb (dma_base, buf, count);
-
- dma_start = jiffies;
-
- while ((readb (addr + EN0_ISR) & ENISR_RDC) == 0)
- if (jiffies - dma_start > 2*HZ/100) { /* 20ms */
- printk(KERN_ERR "%s: timeout waiting for TX RDC\n",
- dev->name);
- etherh_reset (dev);
- NS8390_init (dev, 1);
- break;
- }
-
- writeb (ENISR_RDC, addr + EN0_ISR);
- ei_local->dmaing = 0;
-}
-
-/*
- * Read a block of data from the 8390
- */
-static void
-etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- struct ei_device *ei_local = netdev_priv(dev);
- unsigned char *buf;
- void __iomem *dma_base, *addr;
-
- if (ei_local->dmaing) {
- printk(KERN_ERR "%s: DMAing conflict in etherh_block_input: "
- " DMAstat %d irqlock %d\n", dev->name,
- ei_local->dmaing, ei_local->irqlock);
- return;
- }
-
- ei_local->dmaing = 1;
-
- addr = (void *)dev->base_addr;
- dma_base = etherh_priv(dev)->dma_base;
-
- buf = skb->data;
- writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD);
- writeb (count, addr + EN0_RCNTLO);
- writeb (count >> 8, addr + EN0_RCNTHI);
- writeb (ring_offset, addr + EN0_RSARLO);
- writeb (ring_offset >> 8, addr + EN0_RSARHI);
- writeb (E8390_RREAD | E8390_START, addr + E8390_CMD);
-
- if (ei_local->word16) {
- readsw (dma_base, buf, count >> 1);
- if (count & 1)
- buf[count - 1] = readb (dma_base);
- } else
- readsb (dma_base, buf, count);
-
- writeb (ENISR_RDC, addr + EN0_ISR);
- ei_local->dmaing = 0;
-}
-
-/*
- * Read a header from the 8390
- */
-static void
-etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- struct ei_device *ei_local = netdev_priv(dev);
- void __iomem *dma_base, *addr;
-
- if (ei_local->dmaing) {
- printk(KERN_ERR "%s: DMAing conflict in etherh_get_header: "
- " DMAstat %d irqlock %d\n", dev->name,
- ei_local->dmaing, ei_local->irqlock);
- return;
- }
-
- ei_local->dmaing = 1;
-
- addr = (void *)dev->base_addr;
- dma_base = etherh_priv(dev)->dma_base;
-
- writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD);
- writeb (sizeof (*hdr), addr + EN0_RCNTLO);
- writeb (0, addr + EN0_RCNTHI);
- writeb (0, addr + EN0_RSARLO);
- writeb (ring_page, addr + EN0_RSARHI);
- writeb (E8390_RREAD | E8390_START, addr + E8390_CMD);
-
- if (ei_local->word16)
- readsw (dma_base, hdr, sizeof (*hdr) >> 1);
- else
- readsb (dma_base, hdr, sizeof (*hdr));
-
- writeb (ENISR_RDC, addr + EN0_ISR);
- ei_local->dmaing = 0;
-}
-
-/*
- * Open/initialize the board. This is called (in the current kernel)
- * sometime after booting when the 'ifconfig' program is run.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is non-reboot way to recover if something goes wrong.
- */
-static int
-etherh_open(struct net_device *dev)
-{
- struct ei_device *ei_local = netdev_priv(dev);
-
- if (!is_valid_ether_addr(dev->dev_addr)) {
- printk(KERN_WARNING "%s: invalid ethernet MAC address\n",
- dev->name);
- return -EINVAL;
- }
-
- if (request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))
- return -EAGAIN;
-
- /*
- * Make sure that we aren't going to change the
- * media type on the next reset - we are about to
- * do automedia manually now.
- */
- ei_local->interface_num = 0;
-
- /*
- * If we are doing automedia detection, do it now.
- * This is more reliable than the 8390's detection.
- */
- if (dev->flags & IFF_AUTOMEDIA) {
- dev->if_port = IF_PORT_10BASET;
- etherh_setif(dev);
- mdelay(1);
- if (!etherh_getifstat(dev)) {
- dev->if_port = IF_PORT_10BASE2;
- etherh_setif(dev);
- }
- } else
- etherh_setif(dev);
-
- etherh_reset(dev);
- ei_open(dev);
-
- return 0;
-}
-
-/*
- * The inverse routine to etherh_open().
- */
-static int
-etherh_close(struct net_device *dev)
-{
- ei_close (dev);
- free_irq (dev->irq, dev);
- return 0;
-}
-
-/*
- * Initialisation
- */
-
-static void __init etherh_banner(void)
-{
- static int version_printed;
-
- if (net_debug && version_printed++ == 0)
- printk(KERN_INFO "%s", version);
-}
-
-/*
- * Read the ethernet address string from the on board rom.
- * This is an ascii string...
- */
-static int __init etherh_addr(char *addr, struct expansion_card *ec)
-{
- struct in_chunk_dir cd;
- char *s;
-
- if (!ecard_readchunk(&cd, ec, 0xf5, 0)) {
- printk(KERN_ERR "%s: unable to read podule description string\n",
- ec->dev.bus_id);
- goto no_addr;
- }
-
- s = strchr(cd.d.string, '(');
- if (s) {
- int i;
-
- for (i = 0; i < 6; i++) {
- addr[i] = simple_strtoul(s + 1, &s, 0x10);
- if (*s != (i == 5? ')' : ':'))
- break;
- }
-
- if (i == 6)
- return 0;
- }
-
- printk(KERN_ERR "%s: unable to parse MAC address: %s\n",
- ec->dev.bus_id, cd.d.string);
-
- no_addr:
- return -ENODEV;
-}
-
-/*
- * Create an ethernet address from the system serial number.
- */
-static int __init etherm_addr(char *addr)
-{
- unsigned int serial;
-
- if (system_serial_low == 0 && system_serial_high == 0)
- return -ENODEV;
-
- serial = system_serial_low | system_serial_high;
-
- addr[0] = 0;
- addr[1] = 0;
- addr[2] = 0xa4;
- addr[3] = 0x10 + (serial >> 24);
- addr[4] = serial >> 16;
- addr[5] = serial >> 8;
- return 0;
-}
-
-static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, DRV_VERSION, sizeof(info->version));
- strlcpy(info->bus_info, dev->class_dev.dev->bus_id,
- sizeof(info->bus_info));
-}
-
-static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- cmd->supported = etherh_priv(dev)->supported;
- cmd->speed = SPEED_10;
- cmd->duplex = DUPLEX_HALF;
- cmd->port = dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC;
- cmd->autoneg = dev->flags & IFF_AUTOMEDIA ? AUTONEG_ENABLE : AUTONEG_DISABLE;
- return 0;
-}
-
-static int etherh_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- switch (cmd->autoneg) {
- case AUTONEG_ENABLE:
- dev->flags |= IFF_AUTOMEDIA;
- break;
-
- case AUTONEG_DISABLE:
- switch (cmd->port) {
- case PORT_TP:
- dev->if_port = IF_PORT_10BASET;
- break;
-
- case PORT_BNC:
- dev->if_port = IF_PORT_10BASE2;
- break;
-
- default:
- return -EINVAL;
- }
- dev->flags &= ~IFF_AUTOMEDIA;
- break;
-
- default:
- return -EINVAL;
- }
-
- etherh_setif(dev);
-
- return 0;
-}
-
-static struct ethtool_ops etherh_ethtool_ops = {
- .get_settings = etherh_get_settings,
- .set_settings = etherh_set_settings,
- .get_drvinfo = etherh_get_drvinfo,
-};
-
-static u32 etherh_regoffsets[16];
-static u32 etherm_regoffsets[16];
-
-static int __init
-etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
-{
- const struct etherh_data *data = id->data;
- struct ei_device *ei_local;
- struct net_device *dev;
- struct etherh_priv *eh;
- int i, ret;
-
- etherh_banner();
-
- ret = ecard_request_resources(ec);
- if (ret)
- goto out;
-
- dev = __alloc_ei_netdev(sizeof(struct etherh_priv));
- if (!dev) {
- ret = -ENOMEM;
- goto release;
- }
-
- SET_MODULE_OWNER(dev);
- SET_NETDEV_DEV(dev, &ec->dev);
-
- dev->open = etherh_open;
- dev->stop = etherh_close;
- dev->set_config = etherh_set_config;
- dev->irq = ec->irq;
- dev->ethtool_ops = &etherh_ethtool_ops;
-
- if (data->supported & SUPPORTED_Autoneg)
- dev->flags |= IFF_AUTOMEDIA;
- if (data->supported & SUPPORTED_TP) {
- dev->flags |= IFF_PORTSEL;
- dev->if_port = IF_PORT_10BASET;
- } else if (data->supported & SUPPORTED_BNC) {
- dev->flags |= IFF_PORTSEL;
- dev->if_port = IF_PORT_10BASE2;
- } else
- dev->if_port = IF_PORT_UNKNOWN;
-
- eh = etherh_priv(dev);
- eh->supported = data->supported;
- eh->ctrl = 0;
- eh->id = ec->cid.product;
- eh->memc = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), PAGE_SIZE);
- if (!eh->memc) {
- ret = -ENOMEM;
- goto free;
- }
-
- eh->ctrl_port = eh->memc;
- if (data->ctrl_ioc) {
- eh->ioc_fast = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST), PAGE_SIZE);
- if (!eh->ioc_fast) {
- ret = -ENOMEM;
- goto free;
- }
- eh->ctrl_port = eh->ioc_fast;
- }
-
- dev->base_addr = (unsigned long)eh->memc + data->ns8390_offset;
- eh->dma_base = eh->memc + data->dataport_offset;
- eh->ctrl_port += data->ctrlport_offset;
-
- /*
- * IRQ and control port handling - only for non-NIC slot cards.
- */
- if (ec->slot_no != 8) {
- ec->ops = &etherh_ops;
- ec->irq_data = eh;
- } else {
- /*
- * If we're in the NIC slot, make sure the IRQ is enabled
- */
- etherh_set_ctrl(eh, ETHERH_CP_IE);
- }
-
- ei_local = netdev_priv(dev);
- spin_lock_init(&ei_local->page_lock);
-
- if (ec->cid.product == PROD_ANT_ETHERM) {
- etherm_addr(dev->dev_addr);
- ei_local->reg_offset = etherm_regoffsets;
- } else {
- etherh_addr(dev->dev_addr, ec);
- ei_local->reg_offset = etherh_regoffsets;
- }
-
- ei_local->name = dev->name;
- ei_local->word16 = 1;
- ei_local->tx_start_page = data->tx_start_page;
- ei_local->rx_start_page = ei_local->tx_start_page + TX_PAGES;
- ei_local->stop_page = data->stop_page;
- ei_local->reset_8390 = etherh_reset;
- ei_local->block_input = etherh_block_input;
- ei_local->block_output = etherh_block_output;
- ei_local->get_8390_hdr = etherh_get_header;
- ei_local->interface_num = 0;
-
- etherh_reset(dev);
- NS8390_init(dev, 0);
-
- ret = register_netdev(dev);
- if (ret)
- goto free;
-
- printk(KERN_INFO "%s: %s in slot %d, ",
- dev->name, data->name, ec->slot_no);
-
- for (i = 0; i < 6; i++)
- printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
-
- ecard_set_drvdata(ec, dev);
-
- return 0;
-
- free:
- if (eh->ioc_fast)
- iounmap(eh->ioc_fast);
- if (eh->memc)
- iounmap(eh->memc);
- free_netdev(dev);
- release:
- ecard_release_resources(ec);
- out:
- return ret;
-}
-
-static void __devexit etherh_remove(struct expansion_card *ec)
-{
- struct net_device *dev = ecard_get_drvdata(ec);
- struct etherh_priv *eh = etherh_priv(dev);
-
- ecard_set_drvdata(ec, NULL);
-
- unregister_netdev(dev);
- ec->ops = NULL;
-
- if (eh->ioc_fast)
- iounmap(eh->ioc_fast);
- iounmap(eh->memc);
-
- free_netdev(dev);
-
- ecard_release_resources(ec);
-}
-
-static struct etherh_data etherm_data = {
- .ns8390_offset = ETHERM_NS8390,
- .dataport_offset = ETHERM_NS8390 + ETHERM_DATAPORT,
- .ctrlport_offset = ETHERM_NS8390 + ETHERM_CTRLPORT,
- .name = "ANT EtherM",
- .supported = SUPPORTED_10baseT_Half,
- .tx_start_page = ETHERM_TX_START_PAGE,
- .stop_page = ETHERM_STOP_PAGE,
-};
-
-static struct etherh_data etherlan500_data = {
- .ns8390_offset = ETHERH500_NS8390,
- .dataport_offset = ETHERH500_NS8390 + ETHERH500_DATAPORT,
- .ctrlport_offset = ETHERH500_CTRLPORT,
- .ctrl_ioc = 1,
- .name = "i3 EtherH 500",
- .supported = SUPPORTED_10baseT_Half,
- .tx_start_page = ETHERH_TX_START_PAGE,
- .stop_page = ETHERH_STOP_PAGE,
-};
-
-static struct etherh_data etherlan600_data = {
- .ns8390_offset = ETHERH600_NS8390,
- .dataport_offset = ETHERH600_NS8390 + ETHERH600_DATAPORT,
- .ctrlport_offset = ETHERH600_NS8390 + ETHERH600_CTRLPORT,
- .name = "i3 EtherH 600",
- .supported = SUPPORTED_10baseT_Half | SUPPORTED_TP | SUPPORTED_BNC | SUPPORTED_Autoneg,
- .tx_start_page = ETHERH_TX_START_PAGE,
- .stop_page = ETHERH_STOP_PAGE,
-};
-
-static struct etherh_data etherlan600a_data = {
- .ns8390_offset = ETHERH600_NS8390,
- .dataport_offset = ETHERH600_NS8390 + ETHERH600_DATAPORT,
- .ctrlport_offset = ETHERH600_NS8390 + ETHERH600_CTRLPORT,
- .name = "i3 EtherH 600A",
- .supported = SUPPORTED_10baseT_Half | SUPPORTED_TP | SUPPORTED_BNC | SUPPORTED_Autoneg,
- .tx_start_page = ETHERH_TX_START_PAGE,
- .stop_page = ETHERH_STOP_PAGE,
-};
-
-static const struct ecard_id etherh_ids[] = {
- { MANU_ANT, PROD_ANT_ETHERM, &etherm_data },
- { MANU_I3, PROD_I3_ETHERLAN500, &etherlan500_data },
- { MANU_I3, PROD_I3_ETHERLAN600, &etherlan600_data },
- { MANU_I3, PROD_I3_ETHERLAN600A, &etherlan600a_data },
- { 0xffff, 0xffff }
-};
-
-static struct ecard_driver etherh_driver = {
- .probe = etherh_probe,
- .remove = __devexit_p(etherh_remove),
- .id_table = etherh_ids,
- .drv = {
- .name = DRV_NAME,
- },
-};
-
-static int __init etherh_init(void)
-{
- int i;
-
- for (i = 0; i < 16; i++) {
- etherh_regoffsets[i] = i << 2;
- etherm_regoffsets[i] = i << 5;
- }
-
- return ecard_register_driver(&etherh_driver);
-}
-
-static void __exit etherh_exit(void)
-{
- ecard_remove_driver(&etherh_driver);
-}
-
-module_init(etherh_init);
-module_exit(etherh_exit);