diff options
Diffstat (limited to 'drivers/net/arm')
-rw-r--r-- | drivers/net/arm/Kconfig | 22 | ||||
-rw-r--r-- | drivers/net/arm/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/arm/am79c961a.c | 767 | ||||
-rw-r--r-- | drivers/net/arm/am79c961a.h | 145 | ||||
-rw-r--r-- | drivers/net/arm/ether1.c | 1094 | ||||
-rw-r--r-- | drivers/net/arm/ether1.h | 280 | ||||
-rw-r--r-- | drivers/net/arm/etherh.c | 866 |
7 files changed, 0 insertions, 3177 deletions
diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig index 39e1c0d3947..7848b5f6701 100644 --- a/drivers/net/arm/Kconfig +++ b/drivers/net/arm/Kconfig @@ -2,20 +2,6 @@ # Acorn Network device configuration # These are for Acorn's Expansion card network interfaces # -config ARM_AM79C961A - bool "ARM EBSA110 AM79C961A support" - depends on 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 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" @@ -24,14 +10,6 @@ config ARM_ETHER3 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 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_AT91_ETHER tristate "AT91RM9200 Ethernet support" depends on ARM && ARCH_AT91RM9200 diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile index 303171f589e..6cca728b809 100644 --- a/drivers/net/arm/Makefile +++ b/drivers/net/arm/Makefile @@ -3,10 +3,7 @@ # Makefile for the ARM network device drivers # -obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o -obj-$(CONFIG_ARM_ETHERH) += etherh.o obj-$(CONFIG_ARM_ETHER3) += ether3.o -obj-$(CONFIG_ARM_ETHER1) += ether1.o obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c deleted file mode 100644 index 52fe21e1e2c..00000000000 --- a/drivers/net/arm/am79c961a.c +++ /dev/null @@ -1,767 +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/interrupt.h> -#include <linux/ioport.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/crc32.h> -#include <linux/bitops.h> -#include <linux/platform_device.h> -#include <linux/io.h> - -#include <mach/hardware.h> -#include <asm/system.h> - -#define TX_BUFFERS 15 -#define RX_BUFFERS 25 - -#include "am79c961a.h" - -static irqreturn_t -am79c961_interrupt (int irq, void *dev_id); - -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 volatile( - "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 volatile( - "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 volatile( - "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 volatile( - "str%?h %1, [%2] @ NAT_RAP\n\t" - "ldr%?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 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) { - register unsigned int tmp asm("r2"), tmp2 asm("r3"); - asm volatile( - "ldm%?ia %0!, {%1, %2}" - : "+r" (buf), "=&r" (tmp), "=&r" (tmp2)); - length -= 8; - asm volatile( - "str%?h %1, [%0], #4\n\t" - "mov%? %1, %1, lsr #16\n\t" - "str%?h %1, [%0], #4\n\t" - "str%?h %2, [%0], #4\n\t" - "mov%? %2, %2, lsr #16\n\t" - "str%?h %2, [%0], #4" - : "+r" (offset), "=&r" (tmp), "=&r" (tmp2)); - } - 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 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) { - register unsigned int tmp asm("r2"), tmp2 asm("r3"), tmp3; - asm volatile( - "ldr%?h %2, [%0], #4\n\t" - "ldr%?h %4, [%0], #4\n\t" - "ldr%?h %3, [%0], #4\n\t" - "orr%? %2, %2, %4, lsl #16\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_mc_hash(char *addr, u16 *hash) -{ - int idx, bit; - u32 crc; - - crc = ether_crc_le(ETH_ALEN, addr); - - idx = crc >> 30; - bit = (crc >> 26) & 15; - - hash[idx] |= 1 << bit; -} - -static unsigned int am79c961_get_rx_mode(struct net_device *dev, u16 *hash) -{ - unsigned int mode = MODE_PORT_10BT; - - if (dev->flags & IFF_PROMISC) { - mode |= MODE_PROMISC; - memset(hash, 0xff, 4 * sizeof(*hash)); - } else if (dev->flags & IFF_ALLMULTI) { - memset(hash, 0xff, 4 * sizeof(*hash)); - } else { - struct netdev_hw_addr *ha; - - memset(hash, 0, 4 * sizeof(*hash)); - - netdev_for_each_mc_addr(ha, dev) - am79c961_mc_hash(ha->addr, hash); - } - - return mode; -} - -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; - u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash); - 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, multi_hash[i - LADRL]); - - for (i = PADRL, p = dev->dev_addr; i <= PADRH; i++, p += 2) - write_rreg (dev->base_addr, i, p[0] | (p[1] << 8)); - - write_rreg (dev->base_addr, MODE, mode); - 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); - printk("%s: link up\n", dev->name); - } else if (!lnkstat && carrier) { - netif_carrier_off(dev); - printk("%s: link down\n", dev->name); - } - - mod_timer(&priv->timer, jiffies + msecs_to_jiffies(500)); -} - -/* - * Open/initialize the board. - */ -static int -am79c961_open(struct net_device *dev) -{ - struct dev_priv *priv = netdev_priv(dev); - int ret; - - 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; -} - -/* - * 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; - u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash); - int i, stopped; - - 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 < ARRAY_SIZE(multi_hash); 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); - 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 NETDEV_TX_OK; -} - -/* - * 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); - dev->stats.rx_errors++; - if (status & RMD_ERR) { - if (status & RMD_FRAM) - dev->stats.rx_frame_errors++; - if (status & RMD_CRC) - dev->stats.rx_crc_errors++; - } else if (status & RMD_STP) - dev->stats.rx_length_errors++; - continue; - } - - len = am_readword(dev, hdraddr + 6); - skb = dev_alloc_skb(len + 2); - - if (skb) { - 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->stats.rx_bytes += len; - dev->stats.rx_packets++; - } else { - am_writeword (dev, hdraddr + 2, RMD_OWN); - printk (KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name); - dev->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; - - dev->stats.tx_errors++; - - status2 = am_readword (dev, hdraddr + 6); - - /* - * Clear the error byte - */ - am_writeword (dev, hdraddr + 6, 0); - - if (status2 & TST_RTRY) - dev->stats.collisions += 16; - if (status2 & TST_LCOL) - dev->stats.tx_window_errors++; - if (status2 & TST_LCAR) - dev->stats.tx_carrier_errors++; - if (status2 & TST_UFLO) - dev->stats.tx_fifo_errors++; - continue; - } - dev->stats.tx_packets++; - len = am_readword (dev, hdraddr + 4); - dev->stats.tx_bytes += -len; - } while (priv->txtail != priv->txhead); - - netif_wake_queue(dev); -} - -static irqreturn_t -am79c961_interrupt(int irq, void *dev_id) -{ - 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; - dev->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); - 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 const struct net_device_ops am79c961_netdev_ops = { - .ndo_open = am79c961_open, - .ndo_stop = am79c961_close, - .ndo_start_xmit = am79c961_sendpacket, - .ndo_set_multicast_list = am79c961_setmulticastlist, - .ndo_tx_timeout = am79c961_timeout, - .ndo_validate_addr = eth_validate_addr, - .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = am79c961_poll_controller, -#endif -}; - -static int __devinit am79c961_probe(struct platform_device *pdev) -{ - struct resource *res; - struct net_device *dev; - struct dev_priv *priv; - int i, ret; - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!res) - return -ENODEV; - - dev = alloc_etherdev(sizeof(struct dev_priv)); - ret = -ENOMEM; - if (!dev) - goto out; - - SET_NETDEV_DEV(dev, &pdev->dev); - - 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 = res->start; - ret = platform_get_irq(pdev, 0); - - if (ret < 0) { - ret = -ENODEV; - goto nodev; - } - dev->irq = ret; - - 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; - - for (i = 0; i < 6; i++) - dev->dev_addr[i] = inb(dev->base_addr + i * 2) & 0xff; - - am79c961_banner(); - - 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->netdev_ops = &am79c961_netdev_ops; - - ret = register_netdev(dev); - if (ret == 0) { - printk(KERN_INFO "%s: ether address %pM\n", - dev->name, dev->dev_addr); - return 0; - } - -release: - release_region(dev->base_addr, 0x18); -nodev: - free_netdev(dev); -out: - return ret; -} - -static struct platform_driver am79c961_driver = { - .probe = am79c961_probe, - .driver = { - .name = "am79c961", - }, -}; - -static int __init am79c961_init(void) -{ - return platform_driver_register(&am79c961_driver); -} - -__initcall(am79c961_init); diff --git a/drivers/net/arm/am79c961a.h b/drivers/net/arm/am79c961a.h deleted file mode 100644 index fd634d32756..00000000000 --- a/drivers/net/arm/am79c961a.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * linux/drivers/net/arm/am79c961a.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 { - 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; -}; - -#endif diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c deleted file mode 100644 index b00781c02d5..00000000000 --- a/drivers/net/arm/ether1.c +++ /dev/null @@ -1,1094 +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/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/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); -static int ether1_close(struct net_device *dev); -static void ether1_setmulticastlist(struct net_device *dev); -static void ether1_timeout(struct net_device *dev); - -/* ------------------------------------------------------------------------- */ - -static char version[] __devinitdata = "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 __devinit -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 __devinit -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; - - 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); - - 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) { - if (skb_padto(skb, ETH_ZLEN)) - 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 */ - - /* 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 NETDEV_TX_OK; -} - -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) { - dev->stats.tx_packets++; - dev->stats.collisions += (nop.nop_status & STAT_COLLISIONS); - } else { - dev->stats.tx_errors++; - - if (nop.nop_status & STAT_COLLAFTERTX) - dev->stats.collisions++; - if (nop.nop_status & STAT_NOCARRIER) - 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) - dev->stats.tx_fifo_errors++; - if (nop.nop_status & STAT_COLLEXCESSIVE) - 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_reserve (skb, 2); - - ether1_readbuffer (dev, skb_put (skb, length), rbd.rbd_bufl, length); - - skb->protocol = eth_type_trans (skb, dev); - netif_rx (skb); - dev->stats.rx_packets++; - } else - dev->stats.rx_dropped++; - } else { - printk(KERN_WARNING "%s: %s\n", dev->name, - (rbd.rbd_status & RBD_EOF) ? "oversized packet" : "acnt not valid"); - 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 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); - 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; -} - -/* - * 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 __devinit ether1_banner(void) -{ - static unsigned int version_printed = 0; - - if (net_debug && version_printed++ == 0) - printk(KERN_INFO "%s", version); -} - -static const struct net_device_ops ether1_netdev_ops = { - .ndo_open = ether1_open, - .ndo_stop = ether1_close, - .ndo_start_xmit = ether1_sendpacket, - .ndo_set_multicast_list = ether1_setmulticastlist, - .ndo_tx_timeout = ether1_timeout, - .ndo_validate_addr = eth_validate_addr, - .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, -}; - -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_NETDEV_DEV(dev, &ec->dev); - - dev->irq = ec->irq; - priv(dev)->base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); - 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->netdev_ops = ðer1_netdev_ops; - dev->watchdog_timeo = 5 * HZ / 100; - - ret = register_netdev(dev); - if (ret) - goto free; - - printk(KERN_INFO "%s: ether1 in slot %d, %pM\n", - dev->name, ec->slot_no, dev->dev_addr); - - ecard_set_drvdata(ec, dev); - return 0; - - free: - 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); - 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(ðer1_driver); -} - -static void __exit ether1_exit(void) -{ - ecard_remove_driver(ðer1_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 3a5830ab3dc..00000000000 --- a/drivers/net/arm/ether1.h +++ /dev/null @@ -1,280 +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; - 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/etherh.c b/drivers/net/arm/etherh.c deleted file mode 100644 index 03e217a868d..00000000000 --- a/drivers/net/arm/etherh.c +++ /dev/null @@ -1,866 +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/types.h> -#include <linux/fcntl.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/in.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 <linux/jiffies.h> - -#include <asm/system.h> -#include <asm/ecard.h> -#include <asm/io.h> - -#define EI_SHIFT(x) (ei_local->reg_offset[x]) - -#define ei_inb(_p) readb((void __iomem *)_p) -#define ei_outb(_v,_p) writeb(_v,(void __iomem *)_p) -#define ei_inb_p(_p) readb((void __iomem *)_p) -#define ei_outb_p(_v,_p) writeb(_v,(void __iomem *)_p) - -#define NET_DEBUG 0 -#define DEBUG_INIT 2 - -#define DRV_NAME "etherh" -#define DRV_VERSION "1.11" - -static char version[] __initdata = - "EtherH/EtherM Driver (c) 2002-2004 Russell King " DRV_VERSION "\n"; - -#include "../lib8390.c" - -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"); - -#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 __iomem *)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 __iomem *)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 __iomem *)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 __iomem *)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 (time_after(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 __iomem *)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 __iomem *)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 __devinit 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", - dev_name(&ec->dev)); - 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", - dev_name(&ec->dev), 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_name(dev->dev.parent), - sizeof(info->bus_info)); -} - -static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - cmd->supported = etherh_priv(dev)->supported; - ethtool_cmd_speed_set(cmd, 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 const struct ethtool_ops etherh_ethtool_ops = { - .get_settings = etherh_get_settings, - .set_settings = etherh_set_settings, - .get_drvinfo = etherh_get_drvinfo, -}; - -static const struct net_device_ops etherh_netdev_ops = { - .ndo_open = etherh_open, - .ndo_stop = etherh_close, - .ndo_set_config = etherh_set_config, - .ndo_start_xmit = __ei_start_xmit, - .ndo_tx_timeout = __ei_tx_timeout, - .ndo_get_stats = __ei_get_stats, - .ndo_set_multicast_list = __ei_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, - .ndo_change_mtu = eth_change_mtu, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = __ei_poll, -#endif -}; - -static u32 etherh_regoffsets[16]; -static u32 etherm_regoffsets[16]; - -static int __devinit -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 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_NETDEV_DEV(dev, &ec->dev); - - dev->netdev_ops = ðerh_netdev_ops; - dev->irq = ec->irq; - dev->ethtool_ops = ðerh_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 = ecardm_iomap(ec, ECARD_RES_MEMC, 0, PAGE_SIZE); - if (!eh->memc) { - ret = -ENOMEM; - goto free; - } - - eh->ctrl_port = eh->memc; - if (data->ctrl_ioc) { - eh->ioc_fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 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) { - ecard_setirq(ec, ðerh_ops, 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, %pM\n", - dev->name, data->name, ec->slot_no, dev->dev_addr); - - ecard_set_drvdata(ec, dev); - - return 0; - - free: - 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); - - ecard_set_drvdata(ec, NULL); - - unregister_netdev(dev); - - 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, ðerm_data }, - { MANU_I3, PROD_I3_ETHERLAN500, ðerlan500_data }, - { MANU_I3, PROD_I3_ETHERLAN600, ðerlan600_data }, - { MANU_I3, PROD_I3_ETHERLAN600A, ðerlan600a_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(ðerh_driver); -} - -static void __exit etherh_exit(void) -{ - ecard_remove_driver(ðerh_driver); -} - -module_init(etherh_init); -module_exit(etherh_exit); |