summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/drivers/net/ethernet/dlink
diff options
context:
space:
mode:
authorSrikant Patnaik2015-01-11 12:28:04 +0530
committerSrikant Patnaik2015-01-11 12:28:04 +0530
commit871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch)
tree8718f573808810c2a1e8cb8fb6ac469093ca2784 /ANDROID_3.4.5/drivers/net/ethernet/dlink
parent9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff)
downloadFOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure.
Diffstat (limited to 'ANDROID_3.4.5/drivers/net/ethernet/dlink')
-rw-r--r--ANDROID_3.4.5/drivers/net/ethernet/dlink/Kconfig86
-rw-r--r--ANDROID_3.4.5/drivers/net/ethernet/dlink/Makefile8
-rw-r--r--ANDROID_3.4.5/drivers/net/ethernet/dlink/de600.c529
-rw-r--r--ANDROID_3.4.5/drivers/net/ethernet/dlink/de600.h168
-rw-r--r--ANDROID_3.4.5/drivers/net/ethernet/dlink/de620.c987
-rw-r--r--ANDROID_3.4.5/drivers/net/ethernet/dlink/de620.h117
-rw-r--r--ANDROID_3.4.5/drivers/net/ethernet/dlink/dl2k.c1787
-rw-r--r--ANDROID_3.4.5/drivers/net/ethernet/dlink/dl2k.h441
-rw-r--r--ANDROID_3.4.5/drivers/net/ethernet/dlink/sundance.c1939
9 files changed, 0 insertions, 6062 deletions
diff --git a/ANDROID_3.4.5/drivers/net/ethernet/dlink/Kconfig b/ANDROID_3.4.5/drivers/net/ethernet/dlink/Kconfig
deleted file mode 100644
index b5afe218..00000000
--- a/ANDROID_3.4.5/drivers/net/ethernet/dlink/Kconfig
+++ /dev/null
@@ -1,86 +0,0 @@
-#
-# D-Link device configuration
-#
-
-config NET_VENDOR_DLINK
- bool "D-Link devices"
- default y
- depends on PCI || PARPORT
- ---help---
- If you have a network (Ethernet) card belonging to this class, say Y
- and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- Note that the answer to this question doesn't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about D-Link devices. If you say Y, you will be asked for
- your specific card in the following questions.
-
-if NET_VENDOR_DLINK
-
-config DE600
- tristate "D-Link DE600 pocket adapter support"
- depends on PARPORT
- ---help---
- This is a network (Ethernet) device which attaches to your parallel
- port. Read <file:Documentation/networking/DLINK.txt> as well as the
- Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>, if you want to use
- this. It is possible to have several devices share a single parallel
- port and it is safe to compile the corresponding drivers into the
- kernel.
-
- To compile this driver as a module, choose M here: the module
- will be called de600.
-
-config DE620
- tristate "D-Link DE620 pocket adapter support"
- depends on PARPORT
- ---help---
- This is a network (Ethernet) device which attaches to your parallel
- port. Read <file:Documentation/networking/DLINK.txt> as well as the
- Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>, if you want to use
- this. It is possible to have several devices share a single parallel
- port and it is safe to compile the corresponding drivers into the
- kernel.
-
- To compile this driver as a module, choose M here: the module
- will be called de620.
-
-config DL2K
- tristate "DL2000/TC902x-based Gigabit Ethernet support"
- depends on PCI
- select CRC32
- ---help---
- This driver supports DL2000/TC902x-based Gigabit ethernet cards,
- which includes
- D-Link DGE-550T Gigabit Ethernet Adapter.
- D-Link DL2000-based Gigabit Ethernet Adapter.
- Sundance/Tamarack TC902x Gigabit Ethernet Adapter.
-
- To compile this driver as a module, choose M here: the
- module will be called dl2k.
-
-config SUNDANCE
- tristate "Sundance Alta support"
- depends on PCI
- select CRC32
- select NET_CORE
- select MII
- ---help---
- This driver is for the Sundance "Alta" chip.
- More specific information and updates are available from
- <http://www.scyld.com/network/sundance.html>.
-
-config SUNDANCE_MMIO
- bool "Use MMIO instead of PIO"
- depends on SUNDANCE
- ---help---
- Enable memory-mapped I/O for interaction with Sundance NIC registers.
- Do NOT enable this by default, PIO (enabled when MMIO is disabled)
- is known to solve bugs on certain chips.
-
- If unsure, say N.
-
-endif # NET_VENDOR_DLINK
diff --git a/ANDROID_3.4.5/drivers/net/ethernet/dlink/Makefile b/ANDROID_3.4.5/drivers/net/ethernet/dlink/Makefile
deleted file mode 100644
index c705eaa4..00000000
--- a/ANDROID_3.4.5/drivers/net/ethernet/dlink/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for the D-Link network device drivers.
-#
-
-obj-$(CONFIG_DE600) += de600.o
-obj-$(CONFIG_DE620) += de620.o
-obj-$(CONFIG_DL2K) += dl2k.o
-obj-$(CONFIG_SUNDANCE) += sundance.o
diff --git a/ANDROID_3.4.5/drivers/net/ethernet/dlink/de600.c b/ANDROID_3.4.5/drivers/net/ethernet/dlink/de600.c
deleted file mode 100644
index 414f0eea..00000000
--- a/ANDROID_3.4.5/drivers/net/ethernet/dlink/de600.c
+++ /dev/null
@@ -1,529 +0,0 @@
-static const char version[] = "de600.c: $Revision: 1.41-2.5 $, Bjorn Ekwall (bj0rn@blox.se)\n";
-/*
- * de600.c
- *
- * Linux driver for the D-Link DE-600 Ethernet pocket adapter.
- *
- * Portions (C) Copyright 1993, 1994 by Bjorn Ekwall
- * The Author may be reached as bj0rn@blox.se
- *
- * Based on adapter information gathered from DE600.ASM by D-Link Inc.,
- * as included on disk C in the v.2.11 of PC/TCP from FTP Software.
- * For DE600.asm:
- * Portions (C) Copyright 1990 D-Link, Inc.
- * Copyright, 1988-1992, Russell Nelson, Crynwr Software
- *
- * Adapted to the sample network driver core for linux,
- * written by: Donald Becker <becker@super.org>
- * (Now at <becker@scyld.com>)
- *
- **************************************************************/
-/*
- * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- **************************************************************/
-
-/* Add more time here if your adapter won't work OK: */
-#define DE600_SLOW_DOWN udelay(delay_time)
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <asm/io.h>
-
-#include "de600.h"
-
-static bool check_lost = true;
-module_param(check_lost, bool, 0);
-MODULE_PARM_DESC(check_lost, "If set then check for unplugged de600");
-
-static unsigned int delay_time = 10;
-module_param(delay_time, int, 0);
-MODULE_PARM_DESC(delay_time, "DE-600 deley on I/O in microseconds");
-
-
-/*
- * D-Link driver variables:
- */
-
-static volatile int rx_page;
-
-#define TX_PAGES 2
-static volatile int tx_fifo[TX_PAGES];
-static volatile int tx_fifo_in;
-static volatile int tx_fifo_out;
-static volatile int free_tx_pages = TX_PAGES;
-static int was_down;
-static DEFINE_SPINLOCK(de600_lock);
-
-static inline u8 de600_read_status(struct net_device *dev)
-{
- u8 status;
-
- outb_p(STATUS, DATA_PORT);
- status = inb(STATUS_PORT);
- outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT);
-
- return status;
-}
-
-static inline u8 de600_read_byte(unsigned char type, struct net_device *dev)
-{
- /* dev used by macros */
- u8 lo;
- outb_p((type), DATA_PORT);
- lo = ((unsigned char)inb(STATUS_PORT)) >> 4;
- outb_p((type) | HI_NIBBLE, DATA_PORT);
- return ((unsigned char)inb(STATUS_PORT) & (unsigned char)0xf0) | lo;
-}
-
-/*
- * Open/initialize the board. This is called (in the current kernel)
- * after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1).
- *
- * 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 a non-reboot way to recover if something goes wrong.
- */
-
-static int de600_open(struct net_device *dev)
-{
- unsigned long flags;
- int ret = request_irq(DE600_IRQ, de600_interrupt, 0, dev->name, dev);
- if (ret) {
- printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name, DE600_IRQ);
- return ret;
- }
- spin_lock_irqsave(&de600_lock, flags);
- ret = adapter_init(dev);
- spin_unlock_irqrestore(&de600_lock, flags);
- return ret;
-}
-
-/*
- * The inverse routine to de600_open().
- */
-
-static int de600_close(struct net_device *dev)
-{
- select_nic();
- rx_page = 0;
- de600_put_command(RESET);
- de600_put_command(STOP_RESET);
- de600_put_command(0);
- select_prn();
- free_irq(DE600_IRQ, dev);
- return 0;
-}
-
-static inline void trigger_interrupt(struct net_device *dev)
-{
- de600_put_command(FLIP_IRQ);
- select_prn();
- DE600_SLOW_DOWN;
- select_nic();
- de600_put_command(0);
-}
-
-/*
- * Copy a buffer to the adapter transmit page memory.
- * Start sending.
- */
-
-static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- unsigned long flags;
- int transmit_from;
- int len;
- int tickssofar;
- u8 *buffer = skb->data;
- int i;
-
- if (free_tx_pages <= 0) { /* Do timeouts, to avoid hangs. */
- tickssofar = jiffies - dev_trans_start(dev);
- if (tickssofar < HZ/20)
- return NETDEV_TX_BUSY;
- /* else */
- printk(KERN_WARNING "%s: transmit timed out (%d), %s?\n", dev->name, tickssofar, "network cable problem");
- /* Restart the adapter. */
- spin_lock_irqsave(&de600_lock, flags);
- if (adapter_init(dev)) {
- spin_unlock_irqrestore(&de600_lock, flags);
- return NETDEV_TX_BUSY;
- }
- spin_unlock_irqrestore(&de600_lock, flags);
- }
-
- /* Start real output */
- pr_debug("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages);
-
- if ((len = skb->len) < RUNT)
- len = RUNT;
-
- spin_lock_irqsave(&de600_lock, flags);
- select_nic();
- tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len;
- tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */
-
- if(check_lost)
- {
- /* This costs about 40 instructions per packet... */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- de600_read_byte(READ_DATA, dev);
- if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
- if (adapter_init(dev)) {
- spin_unlock_irqrestore(&de600_lock, flags);
- return NETDEV_TX_BUSY;
- }
- }
- }
-
- de600_setup_address(transmit_from, RW_ADDR);
- for (i = 0; i < skb->len ; ++i, ++buffer)
- de600_put_byte(*buffer);
- for (; i < len; ++i)
- de600_put_byte(0);
-
- if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */
- dev->trans_start = jiffies;
- netif_start_queue(dev); /* allow more packets into adapter */
- /* Send page and generate a faked interrupt */
- de600_setup_address(transmit_from, TX_ADDR);
- de600_put_command(TX_ENABLE);
- }
- else {
- if (free_tx_pages)
- netif_start_queue(dev);
- else
- netif_stop_queue(dev);
- select_prn();
- }
- spin_unlock_irqrestore(&de600_lock, flags);
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
-}
-
-/*
- * The typical workload of the driver:
- * Handle the network interface interrupts.
- */
-
-static irqreturn_t de600_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- u8 irq_status;
- int retrig = 0;
- int boguscount = 0;
-
- spin_lock(&de600_lock);
-
- select_nic();
- irq_status = de600_read_status(dev);
-
- do {
- pr_debug("de600_interrupt (%02X)\n", irq_status);
-
- if (irq_status & RX_GOOD)
- de600_rx_intr(dev);
- else if (!(irq_status & RX_BUSY))
- de600_put_command(RX_ENABLE);
-
- /* Any transmission in progress? */
- if (free_tx_pages < TX_PAGES)
- retrig = de600_tx_intr(dev, irq_status);
- else
- retrig = 0;
-
- irq_status = de600_read_status(dev);
- } while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
- /*
- * Yeah, it _looks_ like busy waiting, smells like busy waiting
- * and I know it's not PC, but please, it will only occur once
- * in a while and then only for a loop or so (< 1ms for sure!)
- */
-
- /* Enable adapter interrupts */
- select_prn();
- if (retrig)
- trigger_interrupt(dev);
- spin_unlock(&de600_lock);
- return IRQ_HANDLED;
-}
-
-static int de600_tx_intr(struct net_device *dev, int irq_status)
-{
- /*
- * Returns 1 if tx still not done
- */
-
- /* Check if current transmission is done yet */
- if (irq_status & TX_BUSY)
- return 1; /* tx not done, try again */
-
- /* else */
- /* If last transmission OK then bump fifo index */
- if (!(irq_status & TX_FAILED16)) {
- tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES;
- ++free_tx_pages;
- dev->stats.tx_packets++;
- netif_wake_queue(dev);
- }
-
- /* More to send, or resend last packet? */
- if ((free_tx_pages < TX_PAGES) || (irq_status & TX_FAILED16)) {
- dev->trans_start = jiffies;
- de600_setup_address(tx_fifo[tx_fifo_out], TX_ADDR);
- de600_put_command(TX_ENABLE);
- return 1;
- }
- /* else */
-
- return 0;
-}
-
-/*
- * We have a good packet, get it out of the adapter.
- */
-static void de600_rx_intr(struct net_device *dev)
-{
- struct sk_buff *skb;
- int i;
- int read_from;
- int size;
- unsigned char *buffer;
-
- /* Get size of received packet */
- size = de600_read_byte(RX_LEN, dev); /* low byte */
- size += (de600_read_byte(RX_LEN, dev) << 8); /* high byte */
- size -= 4; /* Ignore trailing 4 CRC-bytes */
-
- /* Tell adapter where to store next incoming packet, enable receiver */
- read_from = rx_page_adr();
- next_rx_page();
- de600_put_command(RX_ENABLE);
-
- if ((size < 32) || (size > 1535)) {
- printk(KERN_WARNING "%s: Bogus packet size %d.\n", dev->name, size);
- if (size > 10000)
- adapter_init(dev);
- return;
- }
-
- skb = netdev_alloc_skb(dev, size + 2);
- if (skb == NULL) {
- printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
- return;
- }
- /* else */
-
- skb_reserve(skb,2); /* Align */
-
- /* 'skb->data' points to the start of sk_buff data area. */
- buffer = skb_put(skb,size);
-
- /* copy the packet into the buffer */
- de600_setup_address(read_from, RW_ADDR);
- for (i = size; i > 0; --i, ++buffer)
- *buffer = de600_read_byte(READ_DATA, dev);
-
- skb->protocol=eth_type_trans(skb,dev);
-
- netif_rx(skb);
-
- /* update stats */
- dev->stats.rx_packets++; /* count all receives */
- dev->stats.rx_bytes += size; /* count all received bytes */
-
- /*
- * If any worth-while packets have been received, netif_rx()
- * will work on them when we get to the tasklets.
- */
-}
-
-static const struct net_device_ops de600_netdev_ops = {
- .ndo_open = de600_open,
- .ndo_stop = de600_close,
- .ndo_start_xmit = de600_start_xmit,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-
-static struct net_device * __init de600_probe(void)
-{
- int i;
- struct net_device *dev;
- int err;
-
- dev = alloc_etherdev(0);
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
-
- if (!request_region(DE600_IO, 3, "de600")) {
- printk(KERN_WARNING "DE600: port 0x%x busy\n", DE600_IO);
- err = -EBUSY;
- goto out;
- }
-
- printk(KERN_INFO "%s: D-Link DE-600 pocket adapter", dev->name);
- /* Alpha testers must have the version number to report bugs. */
- pr_debug("%s", version);
-
- /* probe for adapter */
- err = -ENODEV;
- rx_page = 0;
- select_nic();
- (void)de600_read_status(dev);
- de600_put_command(RESET);
- de600_put_command(STOP_RESET);
- if (de600_read_status(dev) & 0xf0) {
- printk(": not at I/O %#3x.\n", DATA_PORT);
- goto out1;
- }
-
- /*
- * Maybe we found one,
- * have to check if it is a D-Link DE-600 adapter...
- */
-
- /* Get the adapter ethernet address from the ROM */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- for (i = 0; i < ETH_ALEN; i++) {
- dev->dev_addr[i] = de600_read_byte(READ_DATA, dev);
- dev->broadcast[i] = 0xff;
- }
-
- /* Check magic code */
- if ((dev->dev_addr[1] == 0xde) && (dev->dev_addr[2] == 0x15)) {
- /* OK, install real address */
- dev->dev_addr[0] = 0x00;
- dev->dev_addr[1] = 0x80;
- dev->dev_addr[2] = 0xc8;
- dev->dev_addr[3] &= 0x0f;
- dev->dev_addr[3] |= 0x70;
- } else {
- printk(" not identified in the printer port\n");
- goto out1;
- }
-
- printk(", Ethernet Address: %pM\n", dev->dev_addr);
-
- dev->netdev_ops = &de600_netdev_ops;
-
- dev->flags&=~IFF_MULTICAST;
-
- select_prn();
-
- err = register_netdev(dev);
- if (err)
- goto out1;
-
- return dev;
-
-out1:
- release_region(DE600_IO, 3);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-static int adapter_init(struct net_device *dev)
-{
- int i;
-
- select_nic();
- rx_page = 0; /* used by RESET */
- de600_put_command(RESET);
- de600_put_command(STOP_RESET);
-
- /* Check if it is still there... */
- /* Get the some bytes of the adapter ethernet address from the ROM */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- de600_read_byte(READ_DATA, dev);
- if ((de600_read_byte(READ_DATA, dev) != 0xde) ||
- (de600_read_byte(READ_DATA, dev) != 0x15)) {
- /* was: if (de600_read_status(dev) & 0xf0) { */
- printk("Something has happened to the DE-600! Please check it and do a new ifconfig!\n");
- /* Goodbye, cruel world... */
- dev->flags &= ~IFF_UP;
- de600_close(dev);
- was_down = 1;
- netif_stop_queue(dev); /* Transmit busy... */
- return 1; /* failed */
- }
-
- if (was_down) {
- printk(KERN_INFO "%s: Thanks, I feel much better now!\n", dev->name);
- was_down = 0;
- }
-
- tx_fifo_in = 0;
- tx_fifo_out = 0;
- free_tx_pages = TX_PAGES;
-
-
- /* set the ether address. */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- for (i = 0; i < ETH_ALEN; i++)
- de600_put_byte(dev->dev_addr[i]);
-
- /* where to start saving incoming packets */
- rx_page = RX_BP | RX_BASE_PAGE;
- de600_setup_address(MEM_4K, RW_ADDR);
- /* Enable receiver */
- de600_put_command(RX_ENABLE);
- select_prn();
-
- netif_start_queue(dev);
-
- return 0; /* OK */
-}
-
-static struct net_device *de600_dev;
-
-static int __init de600_init(void)
-{
- de600_dev = de600_probe();
- if (IS_ERR(de600_dev))
- return PTR_ERR(de600_dev);
- return 0;
-}
-
-static void __exit de600_exit(void)
-{
- unregister_netdev(de600_dev);
- release_region(DE600_IO, 3);
- free_netdev(de600_dev);
-}
-
-module_init(de600_init);
-module_exit(de600_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/ethernet/dlink/de600.h b/ANDROID_3.4.5/drivers/net/ethernet/dlink/de600.h
deleted file mode 100644
index e80ecbab..00000000
--- a/ANDROID_3.4.5/drivers/net/ethernet/dlink/de600.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/**************************************************
- * *
- * Definition of D-Link Ethernet Pocket adapter *
- * *
- **************************************************/
-/*
- * D-Link Ethernet pocket adapter ports
- */
-/*
- * OK, so I'm cheating, but there are an awful lot of
- * reads and writes in order to get anything in and out
- * of the DE-600 with 4 bits at a time in the parallel port,
- * so every saved instruction really helps :-)
- */
-
-#ifndef DE600_IO
-#define DE600_IO 0x378
-#endif
-
-#define DATA_PORT (DE600_IO)
-#define STATUS_PORT (DE600_IO + 1)
-#define COMMAND_PORT (DE600_IO + 2)
-
-#ifndef DE600_IRQ
-#define DE600_IRQ 7
-#endif
-/*
- * It really should look like this, and autoprobing as well...
- *
-#define DATA_PORT (dev->base_addr + 0)
-#define STATUS_PORT (dev->base_addr + 1)
-#define COMMAND_PORT (dev->base_addr + 2)
-#define DE600_IRQ dev->irq
- */
-
-/*
- * D-Link COMMAND_PORT commands
- */
-#define SELECT_NIC 0x04 /* select Network Interface Card */
-#define SELECT_PRN 0x1c /* select Printer */
-#define NML_PRN 0xec /* normal Printer situation */
-#define IRQEN 0x10 /* enable IRQ line */
-
-/*
- * D-Link STATUS_PORT
- */
-#define RX_BUSY 0x80
-#define RX_GOOD 0x40
-#define TX_FAILED16 0x10
-#define TX_BUSY 0x08
-
-/*
- * D-Link DATA_PORT commands
- * command in low 4 bits
- * data in high 4 bits
- * select current data nibble with HI_NIBBLE bit
- */
-#define WRITE_DATA 0x00 /* write memory */
-#define READ_DATA 0x01 /* read memory */
-#define STATUS 0x02 /* read status register */
-#define COMMAND 0x03 /* write command register (see COMMAND below) */
-#define NULL_COMMAND 0x04 /* null command */
-#define RX_LEN 0x05 /* read received packet length */
-#define TX_ADDR 0x06 /* set adapter transmit memory address */
-#define RW_ADDR 0x07 /* set adapter read/write memory address */
-#define HI_NIBBLE 0x08 /* read/write the high nibble of data,
- or-ed with rest of command */
-
-/*
- * command register, accessed through DATA_PORT with low bits = COMMAND
- */
-#define RX_ALL 0x01 /* PROMISCUOUS */
-#define RX_BP 0x02 /* default: BROADCAST & PHYSICAL ADDRESS */
-#define RX_MBP 0x03 /* MULTICAST, BROADCAST & PHYSICAL ADDRESS */
-
-#define TX_ENABLE 0x04 /* bit 2 */
-#define RX_ENABLE 0x08 /* bit 3 */
-
-#define RESET 0x80 /* set bit 7 high */
-#define STOP_RESET 0x00 /* set bit 7 low */
-
-/*
- * data to command register
- * (high 4 bits in write to DATA_PORT)
- */
-#define RX_PAGE2_SELECT 0x10 /* bit 4, only 2 pages to select */
-#define RX_BASE_PAGE 0x20 /* bit 5, always set when specifying RX_ADDR */
-#define FLIP_IRQ 0x40 /* bit 6 */
-
-/*
- * D-Link adapter internal memory:
- *
- * 0-2K 1:st transmit page (send from pointer up to 2K)
- * 2-4K 2:nd transmit page (send from pointer up to 4K)
- *
- * 4-6K 1:st receive page (data from 4K upwards)
- * 6-8K 2:nd receive page (data from 6K upwards)
- *
- * 8K+ Adapter ROM (contains magic code and last 3 bytes of Ethernet address)
- */
-#define MEM_2K 0x0800 /* 2048 */
-#define MEM_4K 0x1000 /* 4096 */
-#define MEM_6K 0x1800 /* 6144 */
-#define NODE_ADDRESS 0x2000 /* 8192 */
-
-#define RUNT 60 /* Too small Ethernet packet */
-
-/**************************************************
- * *
- * End of definition *
- * *
- **************************************************/
-
-/*
- * Index to functions, as function prototypes.
- */
-/* Routines used internally. (See "convenience macros") */
-static u8 de600_read_status(struct net_device *dev);
-static u8 de600_read_byte(unsigned char type, struct net_device *dev);
-
-/* Put in the device structure. */
-static int de600_open(struct net_device *dev);
-static int de600_close(struct net_device *dev);
-static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev);
-
-/* Dispatch from interrupts. */
-static irqreturn_t de600_interrupt(int irq, void *dev_id);
-static int de600_tx_intr(struct net_device *dev, int irq_status);
-static void de600_rx_intr(struct net_device *dev);
-
-/* Initialization */
-static void trigger_interrupt(struct net_device *dev);
-static int adapter_init(struct net_device *dev);
-
-/*
- * Convenience macros/functions for D-Link adapter
- */
-
-#define select_prn() outb_p(SELECT_PRN, COMMAND_PORT); DE600_SLOW_DOWN
-#define select_nic() outb_p(SELECT_NIC, COMMAND_PORT); DE600_SLOW_DOWN
-
-/* Thanks for hints from Mark Burton <markb@ordern.demon.co.uk> */
-#define de600_put_byte(data) ( \
- outb_p(((data) << 4) | WRITE_DATA , DATA_PORT), \
- outb_p(((data) & 0xf0) | WRITE_DATA | HI_NIBBLE, DATA_PORT))
-
-/*
- * The first two outb_p()'s below could perhaps be deleted if there
- * would be more delay in the last two. Not certain about it yet...
- */
-#define de600_put_command(cmd) ( \
- outb_p(( rx_page << 4) | COMMAND , DATA_PORT), \
- outb_p(( rx_page & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT), \
- outb_p(((rx_page | cmd) << 4) | COMMAND , DATA_PORT), \
- outb_p(((rx_page | cmd) & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT))
-
-#define de600_setup_address(addr,type) ( \
- outb_p((((addr) << 4) & 0xf0) | type , DATA_PORT), \
- outb_p(( (addr) & 0xf0) | type | HI_NIBBLE, DATA_PORT), \
- outb_p((((addr) >> 4) & 0xf0) | type , DATA_PORT), \
- outb_p((((addr) >> 8) & 0xf0) | type | HI_NIBBLE, DATA_PORT))
-
-#define rx_page_adr() ((rx_page & RX_PAGE2_SELECT)?(MEM_6K):(MEM_4K))
-
-/* Flip bit, only 2 pages */
-#define next_rx_page() (rx_page ^= RX_PAGE2_SELECT)
-
-#define tx_page_adr(a) (((a) + 1) * MEM_2K)
diff --git a/ANDROID_3.4.5/drivers/net/ethernet/dlink/de620.c b/ANDROID_3.4.5/drivers/net/ethernet/dlink/de620.c
deleted file mode 100644
index 2e2bc60e..00000000
--- a/ANDROID_3.4.5/drivers/net/ethernet/dlink/de620.c
+++ /dev/null
@@ -1,987 +0,0 @@
-/*
- * de620.c $Revision: 1.40 $ BETA
- *
- *
- * Linux driver for the D-Link DE-620 Ethernet pocket adapter.
- *
- * Portions (C) Copyright 1993, 1994 by Bjorn Ekwall <bj0rn@blox.se>
- *
- * Based on adapter information gathered from DOS packetdriver
- * sources from D-Link Inc: (Special thanks to Henry Ngai of D-Link.)
- * Portions (C) Copyright D-Link SYSTEM Inc. 1991, 1992
- * Copyright, 1988, Russell Nelson, Crynwr Software
- *
- * Adapted to the sample network driver core for linux,
- * written by: Donald Becker <becker@super.org>
- * (Now at <becker@scyld.com>)
- *
- * Valuable assistance from:
- * J. Joshua Kopper <kopper@rtsg.mot.com>
- * Olav Kvittem <Olav.Kvittem@uninett.no>
- * Germano Caronni <caronni@nessie.cs.id.ethz.ch>
- * Jeremy Fitzhardinge <jeremy@suite.sw.oz.au>
- *
- *****************************************************************************/
-/*
- * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *****************************************************************************/
-static const char version[] =
- "de620.c: $Revision: 1.40 $, Bjorn Ekwall <bj0rn@blox.se>\n";
-
-/***********************************************************************
- *
- * "Tuning" section.
- *
- * Compile-time options: (see below for descriptions)
- * -DDE620_IO=0x378 (lpt1)
- * -DDE620_IRQ=7 (lpt1)
- * -DSHUTDOWN_WHEN_LOST
- * -DCOUNT_LOOPS
- * -DLOWSPEED
- * -DREAD_DELAY
- * -DWRITE_DELAY
- */
-
-/*
- * This driver assumes that the printer port is a "normal",
- * dumb, uni-directional port!
- * If your port is "fancy" in any way, please try to set it to "normal"
- * with your BIOS setup. I have no access to machines with bi-directional
- * ports, so I can't test such a driver :-(
- * (Yes, I _know_ it is possible to use DE620 with bidirectional ports...)
- *
- * There are some clones of DE620 out there, with different names.
- * If the current driver does not recognize a clone, try to change
- * the following #define to:
- *
- * #define DE620_CLONE 1
- */
-#define DE620_CLONE 0
-
-/*
- * If the adapter has problems with high speeds, enable this #define
- * otherwise full printerport speed will be attempted.
- *
- * You can tune the READ_DELAY/WRITE_DELAY below if you enable LOWSPEED
- *
-#define LOWSPEED
- */
-
-#ifndef READ_DELAY
-#define READ_DELAY 100 /* adapter internal read delay in 100ns units */
-#endif
-
-#ifndef WRITE_DELAY
-#define WRITE_DELAY 100 /* adapter internal write delay in 100ns units */
-#endif
-
-/*
- * Enable this #define if you want the adapter to do a "ifconfig down" on
- * itself when we have detected that something is possibly wrong with it.
- * The default behaviour is to retry with "adapter_init()" until success.
- * This should be used for debugging purposes only.
- *
-#define SHUTDOWN_WHEN_LOST
- */
-
-#ifdef LOWSPEED
-/*
- * Enable this #define if you want to see debugging output that show how long
- * we have to wait before the DE-620 is ready for the next read/write/command.
- *
-#define COUNT_LOOPS
- */
-#endif
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <asm/io.h>
-
-/* Constant definitions for the DE-620 registers, commands and bits */
-#include "de620.h"
-
-typedef unsigned char byte;
-
-/*******************************************************
- * *
- * Definition of D-Link DE-620 Ethernet Pocket adapter *
- * See also "de620.h" *
- * *
- *******************************************************/
-#ifndef DE620_IO /* Compile-time configurable */
-#define DE620_IO 0x378
-#endif
-
-#ifndef DE620_IRQ /* Compile-time configurable */
-#define DE620_IRQ 7
-#endif
-
-#define DATA_PORT (dev->base_addr)
-#define STATUS_PORT (dev->base_addr + 1)
-#define COMMAND_PORT (dev->base_addr + 2)
-
-#define RUNT 60 /* Too small Ethernet packet */
-#define GIANT 1514 /* largest legal size packet, no fcs */
-
-/*
- * Force media with insmod:
- * insmod de620.o bnc=1
- * or
- * insmod de620.o utp=1
- *
- * Force io and/or irq with insmod:
- * insmod de620.o io=0x378 irq=7
- *
- * Make a clone skip the Ethernet-address range check:
- * insmod de620.o clone=1
- */
-static int bnc;
-static int utp;
-static int io = DE620_IO;
-static int irq = DE620_IRQ;
-static int clone = DE620_CLONE;
-
-static spinlock_t de620_lock;
-
-module_param(bnc, int, 0);
-module_param(utp, int, 0);
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(clone, int, 0);
-MODULE_PARM_DESC(bnc, "DE-620 set BNC medium (0-1)");
-MODULE_PARM_DESC(utp, "DE-620 set UTP medium (0-1)");
-MODULE_PARM_DESC(io, "DE-620 I/O base address,required");
-MODULE_PARM_DESC(irq, "DE-620 IRQ number,required");
-MODULE_PARM_DESC(clone, "Check also for non-D-Link DE-620 clones (0-1)");
-
-/***********************************************
- * *
- * Index to functions, as function prototypes. *
- * *
- ***********************************************/
-
-/*
- * Routines used internally. (See also "convenience macros.. below")
- */
-
-/* Put in the device structure. */
-static int de620_open(struct net_device *);
-static int de620_close(struct net_device *);
-static void de620_set_multicast_list(struct net_device *);
-static int de620_start_xmit(struct sk_buff *, struct net_device *);
-
-/* Dispatch from interrupts. */
-static irqreturn_t de620_interrupt(int, void *);
-static int de620_rx_intr(struct net_device *);
-
-/* Initialization */
-static int adapter_init(struct net_device *);
-static int read_eeprom(struct net_device *);
-
-
-/*
- * D-Link driver variables:
- */
-#define SCR_DEF NIBBLEMODE |INTON | SLEEP | AUTOTX
-#define TCR_DEF RXPB /* not used: | TXSUCINT | T16INT */
-#define DE620_RX_START_PAGE 12 /* 12 pages (=3k) reserved for tx */
-#define DEF_NIC_CMD IRQEN | ICEN | DS1
-
-static volatile byte NIC_Cmd;
-static volatile byte next_rx_page;
-static byte first_rx_page;
-static byte last_rx_page;
-static byte EIPRegister;
-
-static struct nic {
- byte NodeID[6];
- byte RAM_Size;
- byte Model;
- byte Media;
- byte SCR;
-} nic_data;
-
-/**********************************************************
- * *
- * Convenience macros/functions for D-Link DE-620 adapter *
- * *
- **********************************************************/
-#define de620_tx_buffs(dd) (inb(STATUS_PORT) & (TXBF0 | TXBF1))
-#define de620_flip_ds(dd) NIC_Cmd ^= DS0 | DS1; outb(NIC_Cmd, COMMAND_PORT);
-
-/* Check for ready-status, and return a nibble (high 4 bits) for data input */
-#ifdef COUNT_LOOPS
-static int tot_cnt;
-#endif
-static inline byte
-de620_ready(struct net_device *dev)
-{
- byte value;
- register short int cnt = 0;
-
- while ((((value = inb(STATUS_PORT)) & READY) == 0) && (cnt <= 1000))
- ++cnt;
-
-#ifdef COUNT_LOOPS
- tot_cnt += cnt;
-#endif
- return value & 0xf0; /* nibble */
-}
-
-static inline void
-de620_send_command(struct net_device *dev, byte cmd)
-{
- de620_ready(dev);
- if (cmd == W_DUMMY)
- outb(NIC_Cmd, COMMAND_PORT);
-
- outb(cmd, DATA_PORT);
-
- outb(NIC_Cmd ^ CS0, COMMAND_PORT);
- de620_ready(dev);
- outb(NIC_Cmd, COMMAND_PORT);
-}
-
-static inline void
-de620_put_byte(struct net_device *dev, byte value)
-{
- /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
- de620_ready(dev);
- outb(value, DATA_PORT);
- de620_flip_ds(dev);
-}
-
-static inline byte
-de620_read_byte(struct net_device *dev)
-{
- byte value;
-
- /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
- value = de620_ready(dev); /* High nibble */
- de620_flip_ds(dev);
- value |= de620_ready(dev) >> 4; /* Low nibble */
- return value;
-}
-
-static inline void
-de620_write_block(struct net_device *dev, byte *buffer, int count, int pad)
-{
-#ifndef LOWSPEED
- byte uflip = NIC_Cmd ^ (DS0 | DS1);
- byte dflip = NIC_Cmd;
-#else /* LOWSPEED */
-#ifdef COUNT_LOOPS
- int bytes = count;
-#endif /* COUNT_LOOPS */
-#endif /* LOWSPEED */
-
-#ifdef LOWSPEED
-#ifdef COUNT_LOOPS
- tot_cnt = 0;
-#endif /* COUNT_LOOPS */
- /* No further optimization useful, the limit is in the adapter. */
- for ( ; count > 0; --count, ++buffer) {
- de620_put_byte(dev,*buffer);
- }
- for ( count = pad ; count > 0; --count, ++buffer) {
- de620_put_byte(dev, 0);
- }
- de620_send_command(dev,W_DUMMY);
-#ifdef COUNT_LOOPS
- /* trial debug output: loops per byte in de620_ready() */
- printk("WRITE(%d)\n", tot_cnt/((bytes?bytes:1)));
-#endif /* COUNT_LOOPS */
-#else /* not LOWSPEED */
- for ( ; count > 0; count -=2) {
- outb(*buffer++, DATA_PORT);
- outb(uflip, COMMAND_PORT);
- outb(*buffer++, DATA_PORT);
- outb(dflip, COMMAND_PORT);
- }
- de620_send_command(dev,W_DUMMY);
-#endif /* LOWSPEED */
-}
-
-static inline void
-de620_read_block(struct net_device *dev, byte *data, int count)
-{
-#ifndef LOWSPEED
- byte value;
- byte uflip = NIC_Cmd ^ (DS0 | DS1);
- byte dflip = NIC_Cmd;
-#else /* LOWSPEED */
-#ifdef COUNT_LOOPS
- int bytes = count;
-
- tot_cnt = 0;
-#endif /* COUNT_LOOPS */
-#endif /* LOWSPEED */
-
-#ifdef LOWSPEED
- /* No further optimization useful, the limit is in the adapter. */
- while (count-- > 0) {
- *data++ = de620_read_byte(dev);
- de620_flip_ds(dev);
- }
-#ifdef COUNT_LOOPS
- /* trial debug output: loops per byte in de620_ready() */
- printk("READ(%d)\n", tot_cnt/(2*(bytes?bytes:1)));
-#endif /* COUNT_LOOPS */
-#else /* not LOWSPEED */
- while (count-- > 0) {
- value = inb(STATUS_PORT) & 0xf0; /* High nibble */
- outb(uflip, COMMAND_PORT);
- *data++ = value | inb(STATUS_PORT) >> 4; /* Low nibble */
- outb(dflip , COMMAND_PORT);
- }
-#endif /* LOWSPEED */
-}
-
-static inline void
-de620_set_delay(struct net_device *dev)
-{
- de620_ready(dev);
- outb(W_DFR, DATA_PORT);
- outb(NIC_Cmd ^ CS0, COMMAND_PORT);
-
- de620_ready(dev);
-#ifdef LOWSPEED
- outb(WRITE_DELAY, DATA_PORT);
-#else
- outb(0, DATA_PORT);
-#endif
- de620_flip_ds(dev);
-
- de620_ready(dev);
-#ifdef LOWSPEED
- outb(READ_DELAY, DATA_PORT);
-#else
- outb(0, DATA_PORT);
-#endif
- de620_flip_ds(dev);
-}
-
-static inline void
-de620_set_register(struct net_device *dev, byte reg, byte value)
-{
- de620_ready(dev);
- outb(reg, DATA_PORT);
- outb(NIC_Cmd ^ CS0, COMMAND_PORT);
-
- de620_put_byte(dev, value);
-}
-
-static inline byte
-de620_get_register(struct net_device *dev, byte reg)
-{
- byte value;
-
- de620_send_command(dev,reg);
- value = de620_read_byte(dev);
- de620_send_command(dev,W_DUMMY);
-
- return value;
-}
-
-/*********************************************************************
- *
- * Open/initialize the board.
- *
- * 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 a non-reboot way to recover if something goes wrong.
- *
- */
-static int de620_open(struct net_device *dev)
-{
- int ret = request_irq(dev->irq, de620_interrupt, 0, dev->name, dev);
- if (ret) {
- printk (KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq);
- return ret;
- }
-
- if (adapter_init(dev)) {
- ret = -EIO;
- goto out_free_irq;
- }
-
- netif_start_queue(dev);
- return 0;
-
-out_free_irq:
- free_irq(dev->irq, dev);
- return ret;
-}
-
-/************************************************
- *
- * The inverse routine to de620_open().
- *
- */
-
-static int de620_close(struct net_device *dev)
-{
- netif_stop_queue(dev);
- /* disable recv */
- de620_set_register(dev, W_TCR, RXOFF);
- free_irq(dev->irq, dev);
- return 0;
-}
-
-/*********************************************
- *
- * Set or clear the multicast filter for this adaptor.
- * (no real multicast implemented for the DE-620, but she can be promiscuous...)
- *
- */
-
-static void de620_set_multicast_list(struct net_device *dev)
-{
- if (!netdev_mc_empty(dev) || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
- { /* Enable promiscuous mode */
- de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
- }
- else
- { /* Disable promiscuous mode, use normal mode */
- de620_set_register(dev, W_TCR, TCR_DEF);
- }
-}
-
-/*******************************************************
- *
- * Handle timeouts on transmit
- */
-
-static void de620_timeout(struct net_device *dev)
-{
- printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, "network cable problem");
- /* Restart the adapter. */
- if (!adapter_init(dev)) /* maybe close it */
- netif_wake_queue(dev);
-}
-
-/*******************************************************
- *
- * Copy a buffer to the adapter transmit page memory.
- * Start sending.
- */
-static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- unsigned long flags;
- int len;
- byte *buffer = skb->data;
- byte using_txbuf;
-
- using_txbuf = de620_tx_buffs(dev); /* Peek at the adapter */
-
- netif_stop_queue(dev);
-
-
- if ((len = skb->len) < RUNT)
- len = RUNT;
- if (len & 1) /* send an even number of bytes */
- ++len;
-
- /* Start real output */
-
- spin_lock_irqsave(&de620_lock, flags);
- pr_debug("de620_start_xmit: len=%d, bufs 0x%02x\n",
- (int)skb->len, using_txbuf);
-
- /* select a free tx buffer. if there is one... */
- switch (using_txbuf) {
- default: /* both are free: use TXBF0 */
- case TXBF1: /* use TXBF0 */
- de620_send_command(dev,W_CR | RW0);
- using_txbuf |= TXBF0;
- break;
-
- case TXBF0: /* use TXBF1 */
- de620_send_command(dev,W_CR | RW1);
- using_txbuf |= TXBF1;
- break;
-
- case (TXBF0 | TXBF1): /* NONE!!! */
- printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name);
- spin_unlock_irqrestore(&de620_lock, flags);
- return NETDEV_TX_BUSY;
- }
- de620_write_block(dev, buffer, skb->len, len-skb->len);
-
- if(!(using_txbuf == (TXBF0 | TXBF1)))
- netif_wake_queue(dev);
-
- dev->stats.tx_packets++;
- spin_unlock_irqrestore(&de620_lock, flags);
- dev_kfree_skb (skb);
- return NETDEV_TX_OK;
-}
-
-/*****************************************************
- *
- * Handle the network interface interrupts.
- *
- */
-static irqreturn_t
-de620_interrupt(int irq_in, void *dev_id)
-{
- struct net_device *dev = dev_id;
- byte irq_status;
- int bogus_count = 0;
- int again = 0;
-
- spin_lock(&de620_lock);
-
- /* Read the status register (_not_ the status port) */
- irq_status = de620_get_register(dev, R_STS);
-
- pr_debug("de620_interrupt (%2.2X)\n", irq_status);
-
- if (irq_status & RXGOOD) {
- do {
- again = de620_rx_intr(dev);
- pr_debug("again=%d\n", again);
- }
- while (again && (++bogus_count < 100));
- }
-
- if(de620_tx_buffs(dev) != (TXBF0 | TXBF1))
- netif_wake_queue(dev);
-
- spin_unlock(&de620_lock);
- return IRQ_HANDLED;
-}
-
-/**************************************
- *
- * Get a packet from the adapter
- *
- * Send it "upstairs"
- *
- */
-static int de620_rx_intr(struct net_device *dev)
-{
- struct header_buf {
- byte status;
- byte Rx_NextPage;
- unsigned short Rx_ByteCount;
- } header_buf;
- struct sk_buff *skb;
- int size;
- byte *buffer;
- byte pagelink;
- byte curr_page;
-
- pr_debug("de620_rx_intr: next_rx_page = %d\n", next_rx_page);
-
- /* Tell the adapter that we are going to read data, and from where */
- de620_send_command(dev, W_CR | RRN);
- de620_set_register(dev, W_RSA1, next_rx_page);
- de620_set_register(dev, W_RSA0, 0);
-
- /* Deep breath, and away we goooooo */
- de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf));
- pr_debug("page status=0x%02x, nextpage=%d, packetsize=%d\n",
- header_buf.status, header_buf.Rx_NextPage,
- header_buf.Rx_ByteCount);
-
- /* Plausible page header? */
- pagelink = header_buf.Rx_NextPage;
- if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) {
- /* Ouch... Forget it! Skip all and start afresh... */
- printk(KERN_WARNING "%s: Ring overrun? Restoring...\n", dev->name);
- /* You win some, you lose some. And sometimes plenty... */
- adapter_init(dev);
- netif_wake_queue(dev);
- dev->stats.rx_over_errors++;
- return 0;
- }
-
- /* OK, this look good, so far. Let's see if it's consistent... */
- /* Let's compute the start of the next packet, based on where we are */
- pagelink = next_rx_page +
- ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8);
-
- /* Are we going to wrap around the page counter? */
- if (pagelink > last_rx_page)
- pagelink -= (last_rx_page - first_rx_page + 1);
-
- /* Is the _computed_ next page number equal to what the adapter says? */
- if (pagelink != header_buf.Rx_NextPage) {
- /* Naah, we'll skip this packet. Probably bogus data as well */
- printk(KERN_WARNING "%s: Page link out of sync! Restoring...\n", dev->name);
- next_rx_page = header_buf.Rx_NextPage; /* at least a try... */
- de620_send_command(dev, W_DUMMY);
- de620_set_register(dev, W_NPRF, next_rx_page);
- dev->stats.rx_over_errors++;
- return 0;
- }
- next_rx_page = pagelink;
-
- size = header_buf.Rx_ByteCount - 4;
- if ((size < RUNT) || (GIANT < size)) {
- printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size);
- }
- else { /* Good packet? */
- skb = netdev_alloc_skb(dev, size + 2);
- if (skb == NULL) { /* Yeah, but no place to put it... */
- printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
- dev->stats.rx_dropped++;
- }
- else { /* Yep! Go get it! */
- skb_reserve(skb,2); /* Align */
- /* skb->data points to the start of sk_buff data area */
- buffer = skb_put(skb,size);
- /* copy the packet into the buffer */
- de620_read_block(dev, buffer, size);
- pr_debug("Read %d bytes\n", size);
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb); /* deliver it "upstairs" */
- /* count all receives */
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += size;
- }
- }
-
- /* Let's peek ahead to see if we have read the last current packet */
- /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */
- curr_page = de620_get_register(dev, R_CPR);
- de620_set_register(dev, W_NPRF, next_rx_page);
- pr_debug("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page);
-
- return next_rx_page != curr_page; /* That was slightly tricky... */
-}
-
-/*********************************************
- *
- * Reset the adapter to a known state
- *
- */
-static int adapter_init(struct net_device *dev)
-{
- int i;
- static int was_down;
-
- if ((nic_data.Model == 3) || (nic_data.Model == 0)) { /* CT */
- EIPRegister = NCTL0;
- if (nic_data.Media != 1)
- EIPRegister |= NIS0; /* not BNC */
- }
- else if (nic_data.Model == 2) { /* UTP */
- EIPRegister = NCTL0 | NIS0;
- }
-
- if (utp)
- EIPRegister = NCTL0 | NIS0;
- if (bnc)
- EIPRegister = NCTL0;
-
- de620_send_command(dev, W_CR | RNOP | CLEAR);
- de620_send_command(dev, W_CR | RNOP);
-
- de620_set_register(dev, W_SCR, SCR_DEF);
- /* disable recv to wait init */
- de620_set_register(dev, W_TCR, RXOFF);
-
- /* Set the node ID in the adapter */
- for (i = 0; i < 6; ++i) { /* W_PARn = 0xaa + n */
- de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]);
- }
-
- de620_set_register(dev, W_EIP, EIPRegister);
-
- next_rx_page = first_rx_page = DE620_RX_START_PAGE;
- if (nic_data.RAM_Size)
- last_rx_page = nic_data.RAM_Size - 1;
- else /* 64k RAM */
- last_rx_page = 255;
-
- de620_set_register(dev, W_SPR, first_rx_page); /* Start Page Register*/
- de620_set_register(dev, W_EPR, last_rx_page); /* End Page Register */
- de620_set_register(dev, W_CPR, first_rx_page);/*Current Page Register*/
- de620_send_command(dev, W_NPR | first_rx_page); /* Next Page Register*/
- de620_send_command(dev, W_DUMMY);
- de620_set_delay(dev);
-
- /* Final sanity check: Anybody out there? */
- /* Let's hope some bits from the statusregister make a good check */
-#define CHECK_MASK ( 0 | TXSUC | T16 | 0 | RXCRC | RXSHORT | 0 | 0 )
-#define CHECK_OK ( 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 )
- /* success: X 0 0 X 0 0 X X */
- /* ignore: EEDI RXGOOD COLS LNKS*/
-
- if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) {
- printk(KERN_ERR "%s: Something has happened to the DE-620! Please check it"
-#ifdef SHUTDOWN_WHEN_LOST
- " and do a new ifconfig"
-#endif
- "! (%02x)\n", dev->name, i);
-#ifdef SHUTDOWN_WHEN_LOST
- /* Goodbye, cruel world... */
- dev->flags &= ~IFF_UP;
- de620_close(dev);
-#endif
- was_down = 1;
- return 1; /* failed */
- }
- if (was_down) {
- printk(KERN_WARNING "%s: Thanks, I feel much better now!\n", dev->name);
- was_down = 0;
- }
-
- /* All OK, go ahead... */
- de620_set_register(dev, W_TCR, TCR_DEF);
-
- return 0; /* all ok */
-}
-
-static const struct net_device_ops de620_netdev_ops = {
- .ndo_open = de620_open,
- .ndo_stop = de620_close,
- .ndo_start_xmit = de620_start_xmit,
- .ndo_tx_timeout = de620_timeout,
- .ndo_set_rx_mode = de620_set_multicast_list,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/******************************************************************************
- *
- * Only start-up code below
- *
- */
-/****************************************
- *
- * Check if there is a DE-620 connected
- */
-struct net_device * __init de620_probe(int unit)
-{
- byte checkbyte = 0xa5;
- struct net_device *dev;
- int err = -ENOMEM;
- int i;
-
- dev = alloc_etherdev(0);
- if (!dev)
- goto out;
-
- spin_lock_init(&de620_lock);
-
- /*
- * This is where the base_addr and irq gets set.
- * Tunable at compile-time and insmod-time
- */
- dev->base_addr = io;
- dev->irq = irq;
-
- /* allow overriding parameters on command line */
- if (unit >= 0) {
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- }
-
- pr_debug("%s", version);
-
- printk(KERN_INFO "D-Link DE-620 pocket adapter");
-
- if (!request_region(dev->base_addr, 3, "de620")) {
- printk(" io 0x%3lX, which is busy.\n", dev->base_addr);
- err = -EBUSY;
- goto out1;
- }
-
- /* Initially, configure basic nibble mode, so we can read the EEPROM */
- NIC_Cmd = DEF_NIC_CMD;
- de620_set_register(dev, W_EIP, EIPRegister);
-
- /* Anybody out there? */
- de620_set_register(dev, W_CPR, checkbyte);
- checkbyte = de620_get_register(dev, R_CPR);
-
- if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) {
- printk(" not identified in the printer port\n");
- err = -ENODEV;
- goto out2;
- }
-
- /* else, got it! */
- dev->dev_addr[0] = nic_data.NodeID[0];
- for (i = 1; i < ETH_ALEN; i++) {
- dev->dev_addr[i] = nic_data.NodeID[i];
- dev->broadcast[i] = 0xff;
- }
-
- printk(", Ethernet Address: %pM", dev->dev_addr);
-
- printk(" (%dk RAM,",
- (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64);
-
- if (nic_data.Media == 1)
- printk(" BNC)\n");
- else
- printk(" UTP)\n");
-
- dev->netdev_ops = &de620_netdev_ops;
- dev->watchdog_timeo = HZ*2;
-
- /* base_addr and irq are already set, see above! */
-
- /* dump eeprom */
- pr_debug("\nEEPROM contents:\n"
- "RAM_Size = 0x%02X\n"
- "NodeID = %pM\n"
- "Model = %d\n"
- "Media = %d\n"
- "SCR = 0x%02x\n", nic_data.RAM_Size, nic_data.NodeID,
- nic_data.Model, nic_data.Media, nic_data.SCR);
-
- err = register_netdev(dev);
- if (err)
- goto out2;
- return dev;
-
-out2:
- release_region(dev->base_addr, 3);
-out1:
- free_netdev(dev);
-out:
- return ERR_PTR(err);
-}
-
-/**********************************
- *
- * Read info from on-board EEPROM
- *
- * Note: Bitwise serial I/O to/from the EEPROM vi the status _register_!
- */
-#define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister);
-
-static unsigned short __init ReadAWord(struct net_device *dev, int from)
-{
- unsigned short data;
- int nbits;
-
- /* cs [__~~] SET SEND STATE */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4);
-
- /* Send the 9-bit address from where we want to read the 16-bit word */
- for (nbits = 9; nbits > 0; --nbits, from <<= 1) {
- if (from & 0x0100) { /* bit set? */
- /* cs [~~~~] SEND 1 */
- /* di [~~~~] */
- /* sck [_~~_] */
- sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6);
- }
- else {
- /* cs [~~~~] SEND 0 */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
- }
- }
-
- /* Shift in the 16-bit word. The bits appear serially in EEDI (=0x80) */
- for (data = 0, nbits = 16; nbits > 0; --nbits) {
- /* cs [~~~~] SEND 0 */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
- data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7);
- }
- /* cs [____] RESET SEND STATE */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0);
-
- return data;
-}
-
-static int __init read_eeprom(struct net_device *dev)
-{
- unsigned short wrd;
-
- /* D-Link Ethernet addresses are in the series 00:80:c8:7X:XX:XX:XX */
- wrd = ReadAWord(dev, 0x1aa); /* bytes 0 + 1 of NodeID */
- if (!clone && (wrd != htons(0x0080))) /* Valid D-Link ether sequence? */
- return -1; /* Nope, not a DE-620 */
- nic_data.NodeID[0] = wrd & 0xff;
- nic_data.NodeID[1] = wrd >> 8;
-
- wrd = ReadAWord(dev, 0x1ab); /* bytes 2 + 3 of NodeID */
- if (!clone && ((wrd & 0xff) != 0xc8)) /* Valid D-Link ether sequence? */
- return -1; /* Nope, not a DE-620 */
- nic_data.NodeID[2] = wrd & 0xff;
- nic_data.NodeID[3] = wrd >> 8;
-
- wrd = ReadAWord(dev, 0x1ac); /* bytes 4 + 5 of NodeID */
- nic_data.NodeID[4] = wrd & 0xff;
- nic_data.NodeID[5] = wrd >> 8;
-
- wrd = ReadAWord(dev, 0x1ad); /* RAM size in pages (256 bytes). 0 = 64k */
- nic_data.RAM_Size = (wrd >> 8);
-
- wrd = ReadAWord(dev, 0x1ae); /* hardware model (CT = 3) */
- nic_data.Model = (wrd & 0xff);
-
- wrd = ReadAWord(dev, 0x1af); /* media (indicates BNC/UTP) */
- nic_data.Media = (wrd & 0xff);
-
- wrd = ReadAWord(dev, 0x1a8); /* System Configuration Register */
- nic_data.SCR = (wrd >> 8);
-
- return 0; /* no errors */
-}
-
-/******************************************************************************
- *
- * Loadable module skeleton
- *
- */
-#ifdef MODULE
-static struct net_device *de620_dev;
-
-int __init init_module(void)
-{
- de620_dev = de620_probe(-1);
- if (IS_ERR(de620_dev))
- return PTR_ERR(de620_dev);
- return 0;
-}
-
-void cleanup_module(void)
-{
- unregister_netdev(de620_dev);
- release_region(de620_dev->base_addr, 3);
- free_netdev(de620_dev);
-}
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/net/ethernet/dlink/de620.h b/ANDROID_3.4.5/drivers/net/ethernet/dlink/de620.h
deleted file mode 100644
index e8d9a88f..00000000
--- a/ANDROID_3.4.5/drivers/net/ethernet/dlink/de620.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*********************************************************
- * *
- * Definition of D-Link DE-620 Ethernet Pocket adapter *
- * *
- *********************************************************/
-
-/* DE-620's CMD port Command */
-#define CS0 0x08 /* 1->0 command strobe */
-#define ICEN 0x04 /* 0=enable DL3520 host interface */
-#define DS0 0x02 /* 1->0 data strobe 0 */
-#define DS1 0x01 /* 1->0 data strobe 1 */
-
-#define WDIR 0x20 /* general 0=read 1=write */
-#define RDIR 0x00 /* (not 100% confirm ) */
-#define PS2WDIR 0x00 /* ps/2 mode 1=read, 0=write */
-#define PS2RDIR 0x20
-
-#define IRQEN 0x10 /* 1 = enable printer IRQ line */
-#define SELECTIN 0x08 /* 1 = select printer */
-#define INITP 0x04 /* 0 = initial printer */
-#define AUTOFEED 0x02 /* 1 = printer auto form feed */
-#define STROBE 0x01 /* 0->1 data strobe */
-
-#define RESET 0x08
-#define NIS0 0x20 /* 0 = BNC, 1 = UTP */
-#define NCTL0 0x10
-
-/* DE-620 DIC Command */
-#define W_DUMMY 0x00 /* DIC reserved command */
-#define W_CR 0x20 /* DIC write command register */
-#define W_NPR 0x40 /* DIC write Next Page Register */
-#define W_TBR 0x60 /* DIC write Tx Byte Count 1 reg */
-#define W_RSA 0x80 /* DIC write Remote Start Addr 1 */
-
-/* DE-620's STAT port bits 7-4 */
-#define EMPTY 0x80 /* 1 = receive buffer empty */
-#define INTLEVEL 0x40 /* 1 = interrupt level is high */
-#define TXBF1 0x20 /* 1 = transmit buffer 1 is in use */
-#define TXBF0 0x10 /* 1 = transmit buffer 0 is in use */
-#define READY 0x08 /* 1 = h/w ready to accept cmd/data */
-
-/* IDC 1 Command */
-#define W_RSA1 0xa0 /* write remote start address 1 */
-#define W_RSA0 0xa1 /* write remote start address 0 */
-#define W_NPRF 0xa2 /* write next page register NPR15-NPR8 */
-#define W_DFR 0xa3 /* write delay factor register */
-#define W_CPR 0xa4 /* write current page register */
-#define W_SPR 0xa5 /* write start page register */
-#define W_EPR 0xa6 /* write end page register */
-#define W_SCR 0xa7 /* write system configuration register */
-#define W_TCR 0xa8 /* write Transceiver Configuration reg */
-#define W_EIP 0xa9 /* write EEPM Interface port */
-#define W_PAR0 0xaa /* write physical address register 0 */
-#define W_PAR1 0xab /* write physical address register 1 */
-#define W_PAR2 0xac /* write physical address register 2 */
-#define W_PAR3 0xad /* write physical address register 3 */
-#define W_PAR4 0xae /* write physical address register 4 */
-#define W_PAR5 0xaf /* write physical address register 5 */
-
-/* IDC 2 Command */
-#define R_STS 0xc0 /* read status register */
-#define R_CPR 0xc1 /* read current page register */
-#define R_BPR 0xc2 /* read boundary page register */
-#define R_TDR 0xc3 /* read time domain reflectometry reg */
-
-/* STATUS Register */
-#define EEDI 0x80 /* EEPM DO pin */
-#define TXSUC 0x40 /* tx success */
-#define T16 0x20 /* tx fail 16 times */
-#define TS1 0x40 /* 0=Tx success, 1=T16 */
-#define TS0 0x20 /* 0=Tx success, 1=T16 */
-#define RXGOOD 0x10 /* rx a good packet */
-#define RXCRC 0x08 /* rx a CRC error packet */
-#define RXSHORT 0x04 /* rx a short packet */
-#define COLS 0x02 /* coaxial collision status */
-#define LNKS 0x01 /* UTP link status */
-
-/* Command Register */
-#define CLEAR 0x10 /* reset part of hardware */
-#define NOPER 0x08 /* No Operation */
-#define RNOP 0x08
-#define RRA 0x06 /* After RR then auto-advance NPR & BPR(=NPR-1) */
-#define RRN 0x04 /* Normal Remote Read mode */
-#define RW1 0x02 /* Remote Write tx buffer 1 ( page 6 - 11 ) */
-#define RW0 0x00 /* Remote Write tx buffer 0 ( page 0 - 5 ) */
-#define TXEN 0x01 /* 0->1 tx enable */
-
-/* System Configuration Register */
-#define TESTON 0x80 /* test host data transfer reliability */
-#define SLEEP 0x40 /* sleep mode */
-#if 0
-#define FASTMODE 0x04 /* fast mode for intel 82360SL fast mode */
-#define BYTEMODE 0x02 /* byte mode */
-#else
-#define FASTMODE 0x20 /* fast mode for intel 82360SL fast mode */
-#define BYTEMODE 0x10 /* byte mode */
-#endif
-#define NIBBLEMODE 0x00 /* nibble mode */
-#define IRQINV 0x08 /* turn off IRQ line inverter */
-#define IRQNML 0x00 /* turn on IRQ line inverter */
-#define INTON 0x04
-#define AUTOFFSET 0x02 /* auto shift address to TPR+12 */
-#define AUTOTX 0x01 /* auto tx when leave RW mode */
-
-/* Transceiver Configuration Register */
-#define JABBER 0x80 /* generate jabber condition */
-#define TXSUCINT 0x40 /* enable tx success interrupt */
-#define T16INT 0x20 /* enable T16 interrupt */
-#define RXERRPKT 0x10 /* accept CRC error or short packet */
-#define EXTERNALB2 0x0C /* external loopback 2 */
-#define EXTERNALB1 0x08 /* external loopback 1 */
-#define INTERNALB 0x04 /* internal loopback */
-#define NMLOPERATE 0x00 /* normal operation */
-#define RXPBM 0x03 /* rx physical, broadcast, multicast */
-#define RXPB 0x02 /* rx physical, broadcast */
-#define RXALL 0x01 /* rx all packet */
-#define RXOFF 0x00 /* rx disable */
diff --git a/ANDROID_3.4.5/drivers/net/ethernet/dlink/dl2k.c b/ANDROID_3.4.5/drivers/net/ethernet/dlink/dl2k.c
deleted file mode 100644
index 2e09edb9..00000000
--- a/ANDROID_3.4.5/drivers/net/ethernet/dlink/dl2k.c
+++ /dev/null
@@ -1,1787 +0,0 @@
-/* D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */
-/*
- Copyright (c) 2001, 2002 by D-Link Corporation
- Written by Edward Peng.<edward_peng@dlink.com.tw>
- Created 03-May-2001, base on Linux' sundance.c.
-
- 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.
-*/
-
-#define DRV_NAME "DL2000/TC902x-based linux driver"
-#define DRV_VERSION "v1.19"
-#define DRV_RELDATE "2007/08/12"
-#include "dl2k.h"
-#include <linux/dma-mapping.h>
-
-static char version[] __devinitdata =
- KERN_INFO DRV_NAME " " DRV_VERSION " " DRV_RELDATE "\n";
-#define MAX_UNITS 8
-static int mtu[MAX_UNITS];
-static int vlan[MAX_UNITS];
-static int jumbo[MAX_UNITS];
-static char *media[MAX_UNITS];
-static int tx_flow=-1;
-static int rx_flow=-1;
-static int copy_thresh;
-static int rx_coalesce=10; /* Rx frame count each interrupt */
-static int rx_timeout=200; /* Rx DMA wait time in 640ns increments */
-static int tx_coalesce=16; /* HW xmit count each TxDMAComplete */
-
-
-MODULE_AUTHOR ("Edward Peng");
-MODULE_DESCRIPTION ("D-Link DL2000-based Gigabit Ethernet Adapter");
-MODULE_LICENSE("GPL");
-module_param_array(mtu, int, NULL, 0);
-module_param_array(media, charp, NULL, 0);
-module_param_array(vlan, int, NULL, 0);
-module_param_array(jumbo, int, NULL, 0);
-module_param(tx_flow, int, 0);
-module_param(rx_flow, int, 0);
-module_param(copy_thresh, int, 0);
-module_param(rx_coalesce, int, 0); /* Rx frame count each interrupt */
-module_param(rx_timeout, int, 0); /* Rx DMA wait time in 64ns increments */
-module_param(tx_coalesce, int, 0); /* HW xmit count each TxDMAComplete */
-
-
-/* Enable the default interrupts */
-#define DEFAULT_INTR (RxDMAComplete | HostError | IntRequested | TxDMAComplete| \
- UpdateStats | LinkEvent)
-#define EnableInt() \
-writew(DEFAULT_INTR, ioaddr + IntEnable)
-
-static const int max_intrloop = 50;
-static const int multicast_filter_limit = 0x40;
-
-static int rio_open (struct net_device *dev);
-static void rio_timer (unsigned long data);
-static void rio_tx_timeout (struct net_device *dev);
-static void alloc_list (struct net_device *dev);
-static netdev_tx_t start_xmit (struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t rio_interrupt (int irq, void *dev_instance);
-static void rio_free_tx (struct net_device *dev, int irq);
-static void tx_error (struct net_device *dev, int tx_status);
-static int receive_packet (struct net_device *dev);
-static void rio_error (struct net_device *dev, int int_status);
-static int change_mtu (struct net_device *dev, int new_mtu);
-static void set_multicast (struct net_device *dev);
-static struct net_device_stats *get_stats (struct net_device *dev);
-static int clear_stats (struct net_device *dev);
-static int rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
-static int rio_close (struct net_device *dev);
-static int find_miiphy (struct net_device *dev);
-static int parse_eeprom (struct net_device *dev);
-static int read_eeprom (long ioaddr, int eep_addr);
-static int mii_wait_link (struct net_device *dev, int wait);
-static int mii_set_media (struct net_device *dev);
-static int mii_get_media (struct net_device *dev);
-static int mii_set_media_pcs (struct net_device *dev);
-static int mii_get_media_pcs (struct net_device *dev);
-static int mii_read (struct net_device *dev, int phy_addr, int reg_num);
-static int mii_write (struct net_device *dev, int phy_addr, int reg_num,
- u16 data);
-
-static const struct ethtool_ops ethtool_ops;
-
-static const struct net_device_ops netdev_ops = {
- .ndo_open = rio_open,
- .ndo_start_xmit = start_xmit,
- .ndo_stop = rio_close,
- .ndo_get_stats = get_stats,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_set_rx_mode = set_multicast,
- .ndo_do_ioctl = rio_ioctl,
- .ndo_tx_timeout = rio_tx_timeout,
- .ndo_change_mtu = change_mtu,
-};
-
-static int __devinit
-rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- struct net_device *dev;
- struct netdev_private *np;
- static int card_idx;
- int chip_idx = ent->driver_data;
- int err, irq;
- long ioaddr;
- static int version_printed;
- void *ring_space;
- dma_addr_t ring_dma;
-
- if (!version_printed++)
- printk ("%s", version);
-
- err = pci_enable_device (pdev);
- if (err)
- return err;
-
- irq = pdev->irq;
- err = pci_request_regions (pdev, "dl2k");
- if (err)
- goto err_out_disable;
-
- pci_set_master (pdev);
- dev = alloc_etherdev (sizeof (*np));
- if (!dev) {
- err = -ENOMEM;
- goto err_out_res;
- }
- SET_NETDEV_DEV(dev, &pdev->dev);
-
-#ifdef MEM_MAPPING
- ioaddr = pci_resource_start (pdev, 1);
- ioaddr = (long) ioremap (ioaddr, RIO_IO_SIZE);
- if (!ioaddr) {
- err = -ENOMEM;
- goto err_out_dev;
- }
-#else
- ioaddr = pci_resource_start (pdev, 0);
-#endif
- dev->base_addr = ioaddr;
- dev->irq = irq;
- np = netdev_priv(dev);
- np->chip_id = chip_idx;
- np->pdev = pdev;
- spin_lock_init (&np->tx_lock);
- spin_lock_init (&np->rx_lock);
-
- /* Parse manual configuration */
- np->an_enable = 1;
- np->tx_coalesce = 1;
- if (card_idx < MAX_UNITS) {
- if (media[card_idx] != NULL) {
- np->an_enable = 0;
- if (strcmp (media[card_idx], "auto") == 0 ||
- strcmp (media[card_idx], "autosense") == 0 ||
- strcmp (media[card_idx], "0") == 0 ) {
- np->an_enable = 2;
- } else if (strcmp (media[card_idx], "100mbps_fd") == 0 ||
- strcmp (media[card_idx], "4") == 0) {
- np->speed = 100;
- np->full_duplex = 1;
- } else if (strcmp (media[card_idx], "100mbps_hd") == 0 ||
- strcmp (media[card_idx], "3") == 0) {
- np->speed = 100;
- np->full_duplex = 0;
- } else if (strcmp (media[card_idx], "10mbps_fd") == 0 ||
- strcmp (media[card_idx], "2") == 0) {
- np->speed = 10;
- np->full_duplex = 1;
- } else if (strcmp (media[card_idx], "10mbps_hd") == 0 ||
- strcmp (media[card_idx], "1") == 0) {
- np->speed = 10;
- np->full_duplex = 0;
- } else if (strcmp (media[card_idx], "1000mbps_fd") == 0 ||
- strcmp (media[card_idx], "6") == 0) {
- np->speed=1000;
- np->full_duplex=1;
- } else if (strcmp (media[card_idx], "1000mbps_hd") == 0 ||
- strcmp (media[card_idx], "5") == 0) {
- np->speed = 1000;
- np->full_duplex = 0;
- } else {
- np->an_enable = 1;
- }
- }
- if (jumbo[card_idx] != 0) {
- np->jumbo = 1;
- dev->mtu = MAX_JUMBO;
- } else {
- np->jumbo = 0;
- if (mtu[card_idx] > 0 && mtu[card_idx] < PACKET_SIZE)
- dev->mtu = mtu[card_idx];
- }
- np->vlan = (vlan[card_idx] > 0 && vlan[card_idx] < 4096) ?
- vlan[card_idx] : 0;
- if (rx_coalesce > 0 && rx_timeout > 0) {
- np->rx_coalesce = rx_coalesce;
- np->rx_timeout = rx_timeout;
- np->coalesce = 1;
- }
- np->tx_flow = (tx_flow == 0) ? 0 : 1;
- np->rx_flow = (rx_flow == 0) ? 0 : 1;
-
- if (tx_coalesce < 1)
- tx_coalesce = 1;
- else if (tx_coalesce > TX_RING_SIZE-1)
- tx_coalesce = TX_RING_SIZE - 1;
- }
- dev->netdev_ops = &netdev_ops;
- dev->watchdog_timeo = TX_TIMEOUT;
- SET_ETHTOOL_OPS(dev, &ethtool_ops);
-#if 0
- dev->features = NETIF_F_IP_CSUM;
-#endif
- pci_set_drvdata (pdev, dev);
-
- ring_space = pci_alloc_consistent (pdev, TX_TOTAL_SIZE, &ring_dma);
- if (!ring_space)
- goto err_out_iounmap;
- np->tx_ring = ring_space;
- np->tx_ring_dma = ring_dma;
-
- ring_space = pci_alloc_consistent (pdev, RX_TOTAL_SIZE, &ring_dma);
- if (!ring_space)
- goto err_out_unmap_tx;
- np->rx_ring = ring_space;
- np->rx_ring_dma = ring_dma;
-
- /* Parse eeprom data */
- parse_eeprom (dev);
-
- /* Find PHY address */
- err = find_miiphy (dev);
- if (err)
- goto err_out_unmap_rx;
-
- /* Fiber device? */
- np->phy_media = (readw(ioaddr + ASICCtrl) & PhyMedia) ? 1 : 0;
- np->link_status = 0;
- /* Set media and reset PHY */
- if (np->phy_media) {
- /* default Auto-Negotiation for fiber deivices */
- if (np->an_enable == 2) {
- np->an_enable = 1;
- }
- mii_set_media_pcs (dev);
- } else {
- /* Auto-Negotiation is mandatory for 1000BASE-T,
- IEEE 802.3ab Annex 28D page 14 */
- if (np->speed == 1000)
- np->an_enable = 1;
- mii_set_media (dev);
- }
-
- err = register_netdev (dev);
- if (err)
- goto err_out_unmap_rx;
-
- card_idx++;
-
- printk (KERN_INFO "%s: %s, %pM, IRQ %d\n",
- dev->name, np->name, dev->dev_addr, irq);
- if (tx_coalesce > 1)
- printk(KERN_INFO "tx_coalesce:\t%d packets\n",
- tx_coalesce);
- if (np->coalesce)
- printk(KERN_INFO
- "rx_coalesce:\t%d packets\n"
- "rx_timeout: \t%d ns\n",
- np->rx_coalesce, np->rx_timeout*640);
- if (np->vlan)
- printk(KERN_INFO "vlan(id):\t%d\n", np->vlan);
- return 0;
-
- err_out_unmap_rx:
- pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);
- err_out_unmap_tx:
- pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
- err_out_iounmap:
-#ifdef MEM_MAPPING
- iounmap ((void *) ioaddr);
-
- err_out_dev:
-#endif
- free_netdev (dev);
-
- err_out_res:
- pci_release_regions (pdev);
-
- err_out_disable:
- pci_disable_device (pdev);
- return err;
-}
-
-static int
-find_miiphy (struct net_device *dev)
-{
- int i, phy_found = 0;
- struct netdev_private *np;
- long ioaddr;
- np = netdev_priv(dev);
- ioaddr = dev->base_addr;
- np->phy_addr = 1;
-
- for (i = 31; i >= 0; i--) {
- int mii_status = mii_read (dev, i, 1);
- if (mii_status != 0xffff && mii_status != 0x0000) {
- np->phy_addr = i;
- phy_found++;
- }
- }
- if (!phy_found) {
- printk (KERN_ERR "%s: No MII PHY found!\n", dev->name);
- return -ENODEV;
- }
- return 0;
-}
-
-static int
-parse_eeprom (struct net_device *dev)
-{
- int i, j;
- long ioaddr = dev->base_addr;
- u8 sromdata[256];
- u8 *psib;
- u32 crc;
- PSROM_t psrom = (PSROM_t) sromdata;
- struct netdev_private *np = netdev_priv(dev);
-
- int cid, next;
-
-#ifdef MEM_MAPPING
- ioaddr = pci_resource_start (np->pdev, 0);
-#endif
- /* Read eeprom */
- for (i = 0; i < 128; i++) {
- ((__le16 *) sromdata)[i] = cpu_to_le16(read_eeprom (ioaddr, i));
- }
-#ifdef MEM_MAPPING
- ioaddr = dev->base_addr;
-#endif
- if (np->pdev->vendor == PCI_VENDOR_ID_DLINK) { /* D-Link Only */
- /* Check CRC */
- crc = ~ether_crc_le (256 - 4, sromdata);
- if (psrom->crc != cpu_to_le32(crc)) {
- printk (KERN_ERR "%s: EEPROM data CRC error.\n",
- dev->name);
- return -1;
- }
- }
-
- /* Set MAC address */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = psrom->mac_addr[i];
-
- if (np->pdev->vendor != PCI_VENDOR_ID_DLINK) {
- return 0;
- }
-
- /* Parse Software Information Block */
- i = 0x30;
- psib = (u8 *) sromdata;
- do {
- cid = psib[i++];
- next = psib[i++];
- if ((cid == 0 && next == 0) || (cid == 0xff && next == 0xff)) {
- printk (KERN_ERR "Cell data error\n");
- return -1;
- }
- switch (cid) {
- case 0: /* Format version */
- break;
- case 1: /* End of cell */
- return 0;
- case 2: /* Duplex Polarity */
- np->duplex_polarity = psib[i];
- writeb (readb (ioaddr + PhyCtrl) | psib[i],
- ioaddr + PhyCtrl);
- break;
- case 3: /* Wake Polarity */
- np->wake_polarity = psib[i];
- break;
- case 9: /* Adapter description */
- j = (next - i > 255) ? 255 : next - i;
- memcpy (np->name, &(psib[i]), j);
- break;
- case 4:
- case 5:
- case 6:
- case 7:
- case 8: /* Reversed */
- break;
- default: /* Unknown cell */
- return -1;
- }
- i = next;
- } while (1);
-
- return 0;
-}
-
-static int
-rio_open (struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- long ioaddr = dev->base_addr;
- int i;
- u16 macctrl;
-
- i = request_irq (dev->irq, rio_interrupt, IRQF_SHARED, dev->name, dev);
- if (i)
- return i;
-
- /* Reset all logic functions */
- writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
- ioaddr + ASICCtrl + 2);
- mdelay(10);
-
- /* DebugCtrl bit 4, 5, 9 must set */
- writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl);
-
- /* Jumbo frame */
- if (np->jumbo != 0)
- writew (MAX_JUMBO+14, ioaddr + MaxFrameSize);
-
- alloc_list (dev);
-
- /* Get station address */
- for (i = 0; i < 6; i++)
- writeb (dev->dev_addr[i], ioaddr + StationAddr0 + i);
-
- set_multicast (dev);
- if (np->coalesce) {
- writel (np->rx_coalesce | np->rx_timeout << 16,
- ioaddr + RxDMAIntCtrl);
- }
- /* Set RIO to poll every N*320nsec. */
- writeb (0x20, ioaddr + RxDMAPollPeriod);
- writeb (0xff, ioaddr + TxDMAPollPeriod);
- writeb (0x30, ioaddr + RxDMABurstThresh);
- writeb (0x30, ioaddr + RxDMAUrgentThresh);
- writel (0x0007ffff, ioaddr + RmonStatMask);
- /* clear statistics */
- clear_stats (dev);
-
- /* VLAN supported */
- if (np->vlan) {
- /* priority field in RxDMAIntCtrl */
- writel (readl(ioaddr + RxDMAIntCtrl) | 0x7 << 10,
- ioaddr + RxDMAIntCtrl);
- /* VLANId */
- writew (np->vlan, ioaddr + VLANId);
- /* Length/Type should be 0x8100 */
- writel (0x8100 << 16 | np->vlan, ioaddr + VLANTag);
- /* Enable AutoVLANuntagging, but disable AutoVLANtagging.
- VLAN information tagged by TFC' VID, CFI fields. */
- writel (readl (ioaddr + MACCtrl) | AutoVLANuntagging,
- ioaddr + MACCtrl);
- }
-
- init_timer (&np->timer);
- np->timer.expires = jiffies + 1*HZ;
- np->timer.data = (unsigned long) dev;
- np->timer.function = rio_timer;
- add_timer (&np->timer);
-
- /* Start Tx/Rx */
- writel (readl (ioaddr + MACCtrl) | StatsEnable | RxEnable | TxEnable,
- ioaddr + MACCtrl);
-
- macctrl = 0;
- macctrl |= (np->vlan) ? AutoVLANuntagging : 0;
- macctrl |= (np->full_duplex) ? DuplexSelect : 0;
- macctrl |= (np->tx_flow) ? TxFlowControlEnable : 0;
- macctrl |= (np->rx_flow) ? RxFlowControlEnable : 0;
- writew(macctrl, ioaddr + MACCtrl);
-
- netif_start_queue (dev);
-
- /* Enable default interrupts */
- EnableInt ();
- return 0;
-}
-
-static void
-rio_timer (unsigned long data)
-{
- struct net_device *dev = (struct net_device *)data;
- struct netdev_private *np = netdev_priv(dev);
- unsigned int entry;
- int next_tick = 1*HZ;
- unsigned long flags;
-
- spin_lock_irqsave(&np->rx_lock, flags);
- /* Recover rx ring exhausted error */
- if (np->cur_rx - np->old_rx >= RX_RING_SIZE) {
- printk(KERN_INFO "Try to recover rx ring exhausted...\n");
- /* Re-allocate skbuffs to fill the descriptor ring */
- for (; np->cur_rx - np->old_rx > 0; np->old_rx++) {
- struct sk_buff *skb;
- entry = np->old_rx % RX_RING_SIZE;
- /* Dropped packets don't need to re-allocate */
- if (np->rx_skbuff[entry] == NULL) {
- skb = netdev_alloc_skb_ip_align(dev,
- np->rx_buf_sz);
- if (skb == NULL) {
- np->rx_ring[entry].fraginfo = 0;
- printk (KERN_INFO
- "%s: Still unable to re-allocate Rx skbuff.#%d\n",
- dev->name, entry);
- break;
- }
- np->rx_skbuff[entry] = skb;
- np->rx_ring[entry].fraginfo =
- cpu_to_le64 (pci_map_single
- (np->pdev, skb->data, np->rx_buf_sz,
- PCI_DMA_FROMDEVICE));
- }
- np->rx_ring[entry].fraginfo |=
- cpu_to_le64((u64)np->rx_buf_sz << 48);
- np->rx_ring[entry].status = 0;
- } /* end for */
- } /* end if */
- spin_unlock_irqrestore (&np->rx_lock, flags);
- np->timer.expires = jiffies + next_tick;
- add_timer(&np->timer);
-}
-
-static void
-rio_tx_timeout (struct net_device *dev)
-{
- long ioaddr = dev->base_addr;
-
- printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
- dev->name, readl (ioaddr + TxStatus));
- rio_free_tx(dev, 0);
- dev->if_port = 0;
- dev->trans_start = jiffies; /* prevent tx timeout */
-}
-
- /* allocate and initialize Tx and Rx descriptors */
-static void
-alloc_list (struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- int i;
-
- np->cur_rx = np->cur_tx = 0;
- np->old_rx = np->old_tx = 0;
- np->rx_buf_sz = (dev->mtu <= 1500 ? PACKET_SIZE : dev->mtu + 32);
-
- /* Initialize Tx descriptors, TFDListPtr leaves in start_xmit(). */
- for (i = 0; i < TX_RING_SIZE; i++) {
- np->tx_skbuff[i] = NULL;
- np->tx_ring[i].status = cpu_to_le64 (TFDDone);
- np->tx_ring[i].next_desc = cpu_to_le64 (np->tx_ring_dma +
- ((i+1)%TX_RING_SIZE) *
- sizeof (struct netdev_desc));
- }
-
- /* Initialize Rx descriptors */
- for (i = 0; i < RX_RING_SIZE; i++) {
- np->rx_ring[i].next_desc = cpu_to_le64 (np->rx_ring_dma +
- ((i + 1) % RX_RING_SIZE) *
- sizeof (struct netdev_desc));
- np->rx_ring[i].status = 0;
- np->rx_ring[i].fraginfo = 0;
- np->rx_skbuff[i] = NULL;
- }
-
- /* Allocate the rx buffers */
- for (i = 0; i < RX_RING_SIZE; i++) {
- /* Allocated fixed size of skbuff */
- struct sk_buff *skb;
-
- skb = netdev_alloc_skb_ip_align(dev, np->rx_buf_sz);
- np->rx_skbuff[i] = skb;
- if (skb == NULL) {
- printk (KERN_ERR
- "%s: alloc_list: allocate Rx buffer error! ",
- dev->name);
- break;
- }
- /* Rubicon now supports 40 bits of addressing space. */
- np->rx_ring[i].fraginfo =
- cpu_to_le64 ( pci_map_single (
- np->pdev, skb->data, np->rx_buf_sz,
- PCI_DMA_FROMDEVICE));
- np->rx_ring[i].fraginfo |= cpu_to_le64((u64)np->rx_buf_sz << 48);
- }
-
- /* Set RFDListPtr */
- writel (np->rx_ring_dma, dev->base_addr + RFDListPtr0);
- writel (0, dev->base_addr + RFDListPtr1);
-}
-
-static netdev_tx_t
-start_xmit (struct sk_buff *skb, struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- struct netdev_desc *txdesc;
- unsigned entry;
- u32 ioaddr;
- u64 tfc_vlan_tag = 0;
-
- if (np->link_status == 0) { /* Link Down */
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
- }
- ioaddr = dev->base_addr;
- entry = np->cur_tx % TX_RING_SIZE;
- np->tx_skbuff[entry] = skb;
- txdesc = &np->tx_ring[entry];
-
-#if 0
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
- txdesc->status |=
- cpu_to_le64 (TCPChecksumEnable | UDPChecksumEnable |
- IPChecksumEnable);
- }
-#endif
- if (np->vlan) {
- tfc_vlan_tag = VLANTagInsert |
- ((u64)np->vlan << 32) |
- ((u64)skb->priority << 45);
- }
- txdesc->fraginfo = cpu_to_le64 (pci_map_single (np->pdev, skb->data,
- skb->len,
- PCI_DMA_TODEVICE));
- txdesc->fraginfo |= cpu_to_le64((u64)skb->len << 48);
-
- /* DL2K bug: DMA fails to get next descriptor ptr in 10Mbps mode
- * Work around: Always use 1 descriptor in 10Mbps mode */
- if (entry % np->tx_coalesce == 0 || np->speed == 10)
- txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag |
- WordAlignDisable |
- TxDMAIndicate |
- (1 << FragCountShift));
- else
- txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag |
- WordAlignDisable |
- (1 << FragCountShift));
-
- /* TxDMAPollNow */
- writel (readl (ioaddr + DMACtrl) | 0x00001000, ioaddr + DMACtrl);
- /* Schedule ISR */
- writel(10000, ioaddr + CountDown);
- np->cur_tx = (np->cur_tx + 1) % TX_RING_SIZE;
- if ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE
- < TX_QUEUE_LEN - 1 && np->speed != 10) {
- /* do nothing */
- } else if (!netif_queue_stopped(dev)) {
- netif_stop_queue (dev);
- }
-
- /* The first TFDListPtr */
- if (readl (dev->base_addr + TFDListPtr0) == 0) {
- writel (np->tx_ring_dma + entry * sizeof (struct netdev_desc),
- dev->base_addr + TFDListPtr0);
- writel (0, dev->base_addr + TFDListPtr1);
- }
-
- return NETDEV_TX_OK;
-}
-
-static irqreturn_t
-rio_interrupt (int irq, void *dev_instance)
-{
- struct net_device *dev = dev_instance;
- struct netdev_private *np;
- unsigned int_status;
- long ioaddr;
- int cnt = max_intrloop;
- int handled = 0;
-
- ioaddr = dev->base_addr;
- np = netdev_priv(dev);
- while (1) {
- int_status = readw (ioaddr + IntStatus);
- writew (int_status, ioaddr + IntStatus);
- int_status &= DEFAULT_INTR;
- if (int_status == 0 || --cnt < 0)
- break;
- handled = 1;
- /* Processing received packets */
- if (int_status & RxDMAComplete)
- receive_packet (dev);
- /* TxDMAComplete interrupt */
- if ((int_status & (TxDMAComplete|IntRequested))) {
- int tx_status;
- tx_status = readl (ioaddr + TxStatus);
- if (tx_status & 0x01)
- tx_error (dev, tx_status);
- /* Free used tx skbuffs */
- rio_free_tx (dev, 1);
- }
-
- /* Handle uncommon events */
- if (int_status &
- (HostError | LinkEvent | UpdateStats))
- rio_error (dev, int_status);
- }
- if (np->cur_tx != np->old_tx)
- writel (100, ioaddr + CountDown);
- return IRQ_RETVAL(handled);
-}
-
-static inline dma_addr_t desc_to_dma(struct netdev_desc *desc)
-{
- return le64_to_cpu(desc->fraginfo) & DMA_BIT_MASK(48);
-}
-
-static void
-rio_free_tx (struct net_device *dev, int irq)
-{
- struct netdev_private *np = netdev_priv(dev);
- int entry = np->old_tx % TX_RING_SIZE;
- int tx_use = 0;
- unsigned long flag = 0;
-
- if (irq)
- spin_lock(&np->tx_lock);
- else
- spin_lock_irqsave(&np->tx_lock, flag);
-
- /* Free used tx skbuffs */
- while (entry != np->cur_tx) {
- struct sk_buff *skb;
-
- if (!(np->tx_ring[entry].status & cpu_to_le64(TFDDone)))
- break;
- skb = np->tx_skbuff[entry];
- pci_unmap_single (np->pdev,
- desc_to_dma(&np->tx_ring[entry]),
- skb->len, PCI_DMA_TODEVICE);
- if (irq)
- dev_kfree_skb_irq (skb);
- else
- dev_kfree_skb (skb);
-
- np->tx_skbuff[entry] = NULL;
- entry = (entry + 1) % TX_RING_SIZE;
- tx_use++;
- }
- if (irq)
- spin_unlock(&np->tx_lock);
- else
- spin_unlock_irqrestore(&np->tx_lock, flag);
- np->old_tx = entry;
-
- /* If the ring is no longer full, clear tx_full and
- call netif_wake_queue() */
-
- if (netif_queue_stopped(dev) &&
- ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE
- < TX_QUEUE_LEN - 1 || np->speed == 10)) {
- netif_wake_queue (dev);
- }
-}
-
-static void
-tx_error (struct net_device *dev, int tx_status)
-{
- struct netdev_private *np;
- long ioaddr = dev->base_addr;
- int frame_id;
- int i;
-
- np = netdev_priv(dev);
-
- frame_id = (tx_status & 0xffff0000);
- printk (KERN_ERR "%s: Transmit error, TxStatus %4.4x, FrameId %d.\n",
- dev->name, tx_status, frame_id);
- np->stats.tx_errors++;
- /* Ttransmit Underrun */
- if (tx_status & 0x10) {
- np->stats.tx_fifo_errors++;
- writew (readw (ioaddr + TxStartThresh) + 0x10,
- ioaddr + TxStartThresh);
- /* Transmit Underrun need to set TxReset, DMARest, FIFOReset */
- writew (TxReset | DMAReset | FIFOReset | NetworkReset,
- ioaddr + ASICCtrl + 2);
- /* Wait for ResetBusy bit clear */
- for (i = 50; i > 0; i--) {
- if ((readw (ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
- break;
- mdelay (1);
- }
- rio_free_tx (dev, 1);
- /* Reset TFDListPtr */
- writel (np->tx_ring_dma +
- np->old_tx * sizeof (struct netdev_desc),
- dev->base_addr + TFDListPtr0);
- writel (0, dev->base_addr + TFDListPtr1);
-
- /* Let TxStartThresh stay default value */
- }
- /* Late Collision */
- if (tx_status & 0x04) {
- np->stats.tx_fifo_errors++;
- /* TxReset and clear FIFO */
- writew (TxReset | FIFOReset, ioaddr + ASICCtrl + 2);
- /* Wait reset done */
- for (i = 50; i > 0; i--) {
- if ((readw (ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
- break;
- mdelay (1);
- }
- /* Let TxStartThresh stay default value */
- }
- /* Maximum Collisions */
-#ifdef ETHER_STATS
- if (tx_status & 0x08)
- np->stats.collisions16++;
-#else
- if (tx_status & 0x08)
- np->stats.collisions++;
-#endif
- /* Restart the Tx */
- writel (readw (dev->base_addr + MACCtrl) | TxEnable, ioaddr + MACCtrl);
-}
-
-static int
-receive_packet (struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- int entry = np->cur_rx % RX_RING_SIZE;
- int cnt = 30;
-
- /* If RFDDone, FrameStart and FrameEnd set, there is a new packet in. */
- while (1) {
- struct netdev_desc *desc = &np->rx_ring[entry];
- int pkt_len;
- u64 frame_status;
-
- if (!(desc->status & cpu_to_le64(RFDDone)) ||
- !(desc->status & cpu_to_le64(FrameStart)) ||
- !(desc->status & cpu_to_le64(FrameEnd)))
- break;
-
- /* Chip omits the CRC. */
- frame_status = le64_to_cpu(desc->status);
- pkt_len = frame_status & 0xffff;
- if (--cnt < 0)
- break;
- /* Update rx error statistics, drop packet. */
- if (frame_status & RFS_Errors) {
- np->stats.rx_errors++;
- if (frame_status & (RxRuntFrame | RxLengthError))
- np->stats.rx_length_errors++;
- if (frame_status & RxFCSError)
- np->stats.rx_crc_errors++;
- if (frame_status & RxAlignmentError && np->speed != 1000)
- np->stats.rx_frame_errors++;
- if (frame_status & RxFIFOOverrun)
- np->stats.rx_fifo_errors++;
- } else {
- struct sk_buff *skb;
-
- /* Small skbuffs for short packets */
- if (pkt_len > copy_thresh) {
- pci_unmap_single (np->pdev,
- desc_to_dma(desc),
- np->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
- skb_put (skb = np->rx_skbuff[entry], pkt_len);
- np->rx_skbuff[entry] = NULL;
- } else if ((skb = netdev_alloc_skb_ip_align(dev, pkt_len))) {
- pci_dma_sync_single_for_cpu(np->pdev,
- desc_to_dma(desc),
- np->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
- skb_copy_to_linear_data (skb,
- np->rx_skbuff[entry]->data,
- pkt_len);
- skb_put (skb, pkt_len);
- pci_dma_sync_single_for_device(np->pdev,
- desc_to_dma(desc),
- np->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
- }
- skb->protocol = eth_type_trans (skb, dev);
-#if 0
- /* Checksum done by hw, but csum value unavailable. */
- if (np->pdev->pci_rev_id >= 0x0c &&
- !(frame_status & (TCPError | UDPError | IPError))) {
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- }
-#endif
- netif_rx (skb);
- }
- entry = (entry + 1) % RX_RING_SIZE;
- }
- spin_lock(&np->rx_lock);
- np->cur_rx = entry;
- /* Re-allocate skbuffs to fill the descriptor ring */
- entry = np->old_rx;
- while (entry != np->cur_rx) {
- struct sk_buff *skb;
- /* Dropped packets don't need to re-allocate */
- if (np->rx_skbuff[entry] == NULL) {
- skb = netdev_alloc_skb_ip_align(dev, np->rx_buf_sz);
- if (skb == NULL) {
- np->rx_ring[entry].fraginfo = 0;
- printk (KERN_INFO
- "%s: receive_packet: "
- "Unable to re-allocate Rx skbuff.#%d\n",
- dev->name, entry);
- break;
- }
- np->rx_skbuff[entry] = skb;
- np->rx_ring[entry].fraginfo =
- cpu_to_le64 (pci_map_single
- (np->pdev, skb->data, np->rx_buf_sz,
- PCI_DMA_FROMDEVICE));
- }
- np->rx_ring[entry].fraginfo |=
- cpu_to_le64((u64)np->rx_buf_sz << 48);
- np->rx_ring[entry].status = 0;
- entry = (entry + 1) % RX_RING_SIZE;
- }
- np->old_rx = entry;
- spin_unlock(&np->rx_lock);
- return 0;
-}
-
-static void
-rio_error (struct net_device *dev, int int_status)
-{
- long ioaddr = dev->base_addr;
- struct netdev_private *np = netdev_priv(dev);
- u16 macctrl;
-
- /* Link change event */
- if (int_status & LinkEvent) {
- if (mii_wait_link (dev, 10) == 0) {
- printk (KERN_INFO "%s: Link up\n", dev->name);
- if (np->phy_media)
- mii_get_media_pcs (dev);
- else
- mii_get_media (dev);
- if (np->speed == 1000)
- np->tx_coalesce = tx_coalesce;
- else
- np->tx_coalesce = 1;
- macctrl = 0;
- macctrl |= (np->vlan) ? AutoVLANuntagging : 0;
- macctrl |= (np->full_duplex) ? DuplexSelect : 0;
- macctrl |= (np->tx_flow) ?
- TxFlowControlEnable : 0;
- macctrl |= (np->rx_flow) ?
- RxFlowControlEnable : 0;
- writew(macctrl, ioaddr + MACCtrl);
- np->link_status = 1;
- netif_carrier_on(dev);
- } else {
- printk (KERN_INFO "%s: Link off\n", dev->name);
- np->link_status = 0;
- netif_carrier_off(dev);
- }
- }
-
- /* UpdateStats statistics registers */
- if (int_status & UpdateStats) {
- get_stats (dev);
- }
-
- /* PCI Error, a catastronphic error related to the bus interface
- occurs, set GlobalReset and HostReset to reset. */
- if (int_status & HostError) {
- printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
- dev->name, int_status);
- writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
- mdelay (500);
- }
-}
-
-static struct net_device_stats *
-get_stats (struct net_device *dev)
-{
- long ioaddr = dev->base_addr;
- struct netdev_private *np = netdev_priv(dev);
-#ifdef MEM_MAPPING
- int i;
-#endif
- unsigned int stat_reg;
-
- /* All statistics registers need to be acknowledged,
- else statistic overflow could cause problems */
-
- np->stats.rx_packets += readl (ioaddr + FramesRcvOk);
- np->stats.tx_packets += readl (ioaddr + FramesXmtOk);
- np->stats.rx_bytes += readl (ioaddr + OctetRcvOk);
- np->stats.tx_bytes += readl (ioaddr + OctetXmtOk);
-
- np->stats.multicast = readl (ioaddr + McstFramesRcvdOk);
- np->stats.collisions += readl (ioaddr + SingleColFrames)
- + readl (ioaddr + MultiColFrames);
-
- /* detailed tx errors */
- stat_reg = readw (ioaddr + FramesAbortXSColls);
- np->stats.tx_aborted_errors += stat_reg;
- np->stats.tx_errors += stat_reg;
-
- stat_reg = readw (ioaddr + CarrierSenseErrors);
- np->stats.tx_carrier_errors += stat_reg;
- np->stats.tx_errors += stat_reg;
-
- /* Clear all other statistic register. */
- readl (ioaddr + McstOctetXmtOk);
- readw (ioaddr + BcstFramesXmtdOk);
- readl (ioaddr + McstFramesXmtdOk);
- readw (ioaddr + BcstFramesRcvdOk);
- readw (ioaddr + MacControlFramesRcvd);
- readw (ioaddr + FrameTooLongErrors);
- readw (ioaddr + InRangeLengthErrors);
- readw (ioaddr + FramesCheckSeqErrors);
- readw (ioaddr + FramesLostRxErrors);
- readl (ioaddr + McstOctetXmtOk);
- readl (ioaddr + BcstOctetXmtOk);
- readl (ioaddr + McstFramesXmtdOk);
- readl (ioaddr + FramesWDeferredXmt);
- readl (ioaddr + LateCollisions);
- readw (ioaddr + BcstFramesXmtdOk);
- readw (ioaddr + MacControlFramesXmtd);
- readw (ioaddr + FramesWEXDeferal);
-
-#ifdef MEM_MAPPING
- for (i = 0x100; i <= 0x150; i += 4)
- readl (ioaddr + i);
-#endif
- readw (ioaddr + TxJumboFrames);
- readw (ioaddr + RxJumboFrames);
- readw (ioaddr + TCPCheckSumErrors);
- readw (ioaddr + UDPCheckSumErrors);
- readw (ioaddr + IPCheckSumErrors);
- return &np->stats;
-}
-
-static int
-clear_stats (struct net_device *dev)
-{
- long ioaddr = dev->base_addr;
-#ifdef MEM_MAPPING
- int i;
-#endif
-
- /* All statistics registers need to be acknowledged,
- else statistic overflow could cause problems */
- readl (ioaddr + FramesRcvOk);
- readl (ioaddr + FramesXmtOk);
- readl (ioaddr + OctetRcvOk);
- readl (ioaddr + OctetXmtOk);
-
- readl (ioaddr + McstFramesRcvdOk);
- readl (ioaddr + SingleColFrames);
- readl (ioaddr + MultiColFrames);
- readl (ioaddr + LateCollisions);
- /* detailed rx errors */
- readw (ioaddr + FrameTooLongErrors);
- readw (ioaddr + InRangeLengthErrors);
- readw (ioaddr + FramesCheckSeqErrors);
- readw (ioaddr + FramesLostRxErrors);
-
- /* detailed tx errors */
- readw (ioaddr + FramesAbortXSColls);
- readw (ioaddr + CarrierSenseErrors);
-
- /* Clear all other statistic register. */
- readl (ioaddr + McstOctetXmtOk);
- readw (ioaddr + BcstFramesXmtdOk);
- readl (ioaddr + McstFramesXmtdOk);
- readw (ioaddr + BcstFramesRcvdOk);
- readw (ioaddr + MacControlFramesRcvd);
- readl (ioaddr + McstOctetXmtOk);
- readl (ioaddr + BcstOctetXmtOk);
- readl (ioaddr + McstFramesXmtdOk);
- readl (ioaddr + FramesWDeferredXmt);
- readw (ioaddr + BcstFramesXmtdOk);
- readw (ioaddr + MacControlFramesXmtd);
- readw (ioaddr + FramesWEXDeferal);
-#ifdef MEM_MAPPING
- for (i = 0x100; i <= 0x150; i += 4)
- readl (ioaddr + i);
-#endif
- readw (ioaddr + TxJumboFrames);
- readw (ioaddr + RxJumboFrames);
- readw (ioaddr + TCPCheckSumErrors);
- readw (ioaddr + UDPCheckSumErrors);
- readw (ioaddr + IPCheckSumErrors);
- return 0;
-}
-
-
-static int
-change_mtu (struct net_device *dev, int new_mtu)
-{
- struct netdev_private *np = netdev_priv(dev);
- int max = (np->jumbo) ? MAX_JUMBO : 1536;
-
- if ((new_mtu < 68) || (new_mtu > max)) {
- return -EINVAL;
- }
-
- dev->mtu = new_mtu;
-
- return 0;
-}
-
-static void
-set_multicast (struct net_device *dev)
-{
- long ioaddr = dev->base_addr;
- u32 hash_table[2];
- u16 rx_mode = 0;
- struct netdev_private *np = netdev_priv(dev);
-
- hash_table[0] = hash_table[1] = 0;
- /* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */
- hash_table[1] |= 0x02000000;
- if (dev->flags & IFF_PROMISC) {
- /* Receive all frames promiscuously. */
- rx_mode = ReceiveAllFrames;
- } else if ((dev->flags & IFF_ALLMULTI) ||
- (netdev_mc_count(dev) > multicast_filter_limit)) {
- /* Receive broadcast and multicast frames */
- rx_mode = ReceiveBroadcast | ReceiveMulticast | ReceiveUnicast;
- } else if (!netdev_mc_empty(dev)) {
- struct netdev_hw_addr *ha;
- /* Receive broadcast frames and multicast frames filtering
- by Hashtable */
- rx_mode =
- ReceiveBroadcast | ReceiveMulticastHash | ReceiveUnicast;
- netdev_for_each_mc_addr(ha, dev) {
- int bit, index = 0;
- int crc = ether_crc_le(ETH_ALEN, ha->addr);
- /* The inverted high significant 6 bits of CRC are
- used as an index to hashtable */
- for (bit = 0; bit < 6; bit++)
- if (crc & (1 << (31 - bit)))
- index |= (1 << bit);
- hash_table[index / 32] |= (1 << (index % 32));
- }
- } else {
- rx_mode = ReceiveBroadcast | ReceiveUnicast;
- }
- if (np->vlan) {
- /* ReceiveVLANMatch field in ReceiveMode */
- rx_mode |= ReceiveVLANMatch;
- }
-
- writel (hash_table[0], ioaddr + HashTable0);
- writel (hash_table[1], ioaddr + HashTable1);
- writew (rx_mode, ioaddr + ReceiveMode);
-}
-
-static void rio_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- struct netdev_private *np = netdev_priv(dev);
- strcpy(info->driver, "dl2k");
- strcpy(info->version, DRV_VERSION);
- strcpy(info->bus_info, pci_name(np->pdev));
-}
-
-static int rio_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct netdev_private *np = netdev_priv(dev);
- if (np->phy_media) {
- /* fiber device */
- cmd->supported = SUPPORTED_Autoneg | SUPPORTED_FIBRE;
- cmd->advertising= ADVERTISED_Autoneg | ADVERTISED_FIBRE;
- cmd->port = PORT_FIBRE;
- cmd->transceiver = XCVR_INTERNAL;
- } else {
- /* copper device */
- cmd->supported = SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half
- | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full |
- SUPPORTED_Autoneg | SUPPORTED_MII;
- cmd->advertising = ADVERTISED_10baseT_Half |
- ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Half |
- ADVERTISED_100baseT_Full | ADVERTISED_1000baseT_Full|
- ADVERTISED_Autoneg | ADVERTISED_MII;
- cmd->port = PORT_MII;
- cmd->transceiver = XCVR_INTERNAL;
- }
- if ( np->link_status ) {
- ethtool_cmd_speed_set(cmd, np->speed);
- cmd->duplex = np->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
- } else {
- ethtool_cmd_speed_set(cmd, -1);
- cmd->duplex = -1;
- }
- if ( np->an_enable)
- cmd->autoneg = AUTONEG_ENABLE;
- else
- cmd->autoneg = AUTONEG_DISABLE;
-
- cmd->phy_address = np->phy_addr;
- return 0;
-}
-
-static int rio_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct netdev_private *np = netdev_priv(dev);
- netif_carrier_off(dev);
- if (cmd->autoneg == AUTONEG_ENABLE) {
- if (np->an_enable)
- return 0;
- else {
- np->an_enable = 1;
- mii_set_media(dev);
- return 0;
- }
- } else {
- np->an_enable = 0;
- if (np->speed == 1000) {
- ethtool_cmd_speed_set(cmd, SPEED_100);
- cmd->duplex = DUPLEX_FULL;
- printk("Warning!! Can't disable Auto negotiation in 1000Mbps, change to Manual 100Mbps, Full duplex.\n");
- }
- switch (ethtool_cmd_speed(cmd)) {
- case SPEED_10:
- np->speed = 10;
- np->full_duplex = (cmd->duplex == DUPLEX_FULL);
- break;
- case SPEED_100:
- np->speed = 100;
- np->full_duplex = (cmd->duplex == DUPLEX_FULL);
- break;
- case SPEED_1000: /* not supported */
- default:
- return -EINVAL;
- }
- mii_set_media(dev);
- }
- return 0;
-}
-
-static u32 rio_get_link(struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- return np->link_status;
-}
-
-static const struct ethtool_ops ethtool_ops = {
- .get_drvinfo = rio_get_drvinfo,
- .get_settings = rio_get_settings,
- .set_settings = rio_set_settings,
- .get_link = rio_get_link,
-};
-
-static int
-rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
-{
- int phy_addr;
- struct netdev_private *np = netdev_priv(dev);
- struct mii_ioctl_data *miidata = if_mii(rq);
-
- phy_addr = np->phy_addr;
- switch (cmd) {
- case SIOCGMIIPHY:
- miidata->phy_id = phy_addr;
- break;
- case SIOCGMIIREG:
- miidata->val_out = mii_read (dev, phy_addr, miidata->reg_num);
- break;
- case SIOCSMIIREG:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- mii_write (dev, phy_addr, miidata->reg_num, miidata->val_in);
- break;
- default:
- return -EOPNOTSUPP;
- }
- return 0;
-}
-
-#define EEP_READ 0x0200
-#define EEP_BUSY 0x8000
-/* Read the EEPROM word */
-/* We use I/O instruction to read/write eeprom to avoid fail on some machines */
-static int
-read_eeprom (long ioaddr, int eep_addr)
-{
- int i = 1000;
- outw (EEP_READ | (eep_addr & 0xff), ioaddr + EepromCtrl);
- while (i-- > 0) {
- if (!(inw (ioaddr + EepromCtrl) & EEP_BUSY)) {
- return inw (ioaddr + EepromData);
- }
- }
- return 0;
-}
-
-enum phy_ctrl_bits {
- MII_READ = 0x00, MII_CLK = 0x01, MII_DATA1 = 0x02, MII_WRITE = 0x04,
- MII_DUPLEX = 0x08,
-};
-
-#define mii_delay() readb(ioaddr)
-static void
-mii_sendbit (struct net_device *dev, u32 data)
-{
- long ioaddr = dev->base_addr + PhyCtrl;
- data = (data) ? MII_DATA1 : 0;
- data |= MII_WRITE;
- data |= (readb (ioaddr) & 0xf8) | MII_WRITE;
- writeb (data, ioaddr);
- mii_delay ();
- writeb (data | MII_CLK, ioaddr);
- mii_delay ();
-}
-
-static int
-mii_getbit (struct net_device *dev)
-{
- long ioaddr = dev->base_addr + PhyCtrl;
- u8 data;
-
- data = (readb (ioaddr) & 0xf8) | MII_READ;
- writeb (data, ioaddr);
- mii_delay ();
- writeb (data | MII_CLK, ioaddr);
- mii_delay ();
- return ((readb (ioaddr) >> 1) & 1);
-}
-
-static void
-mii_send_bits (struct net_device *dev, u32 data, int len)
-{
- int i;
- for (i = len - 1; i >= 0; i--) {
- mii_sendbit (dev, data & (1 << i));
- }
-}
-
-static int
-mii_read (struct net_device *dev, int phy_addr, int reg_num)
-{
- u32 cmd;
- int i;
- u32 retval = 0;
-
- /* Preamble */
- mii_send_bits (dev, 0xffffffff, 32);
- /* ST(2), OP(2), ADDR(5), REG#(5), TA(2), Data(16) total 32 bits */
- /* ST,OP = 0110'b for read operation */
- cmd = (0x06 << 10 | phy_addr << 5 | reg_num);
- mii_send_bits (dev, cmd, 14);
- /* Turnaround */
- if (mii_getbit (dev))
- goto err_out;
- /* Read data */
- for (i = 0; i < 16; i++) {
- retval |= mii_getbit (dev);
- retval <<= 1;
- }
- /* End cycle */
- mii_getbit (dev);
- return (retval >> 1) & 0xffff;
-
- err_out:
- return 0;
-}
-static int
-mii_write (struct net_device *dev, int phy_addr, int reg_num, u16 data)
-{
- u32 cmd;
-
- /* Preamble */
- mii_send_bits (dev, 0xffffffff, 32);
- /* ST(2), OP(2), ADDR(5), REG#(5), TA(2), Data(16) total 32 bits */
- /* ST,OP,AAAAA,RRRRR,TA = 0101xxxxxxxxxx10'b = 0x5002 for write */
- cmd = (0x5002 << 16) | (phy_addr << 23) | (reg_num << 18) | data;
- mii_send_bits (dev, cmd, 32);
- /* End cycle */
- mii_getbit (dev);
- return 0;
-}
-static int
-mii_wait_link (struct net_device *dev, int wait)
-{
- __u16 bmsr;
- int phy_addr;
- struct netdev_private *np;
-
- np = netdev_priv(dev);
- phy_addr = np->phy_addr;
-
- do {
- bmsr = mii_read (dev, phy_addr, MII_BMSR);
- if (bmsr & BMSR_LSTATUS)
- return 0;
- mdelay (1);
- } while (--wait > 0);
- return -1;
-}
-static int
-mii_get_media (struct net_device *dev)
-{
- __u16 negotiate;
- __u16 bmsr;
- __u16 mscr;
- __u16 mssr;
- int phy_addr;
- struct netdev_private *np;
-
- np = netdev_priv(dev);
- phy_addr = np->phy_addr;
-
- bmsr = mii_read (dev, phy_addr, MII_BMSR);
- if (np->an_enable) {
- if (!(bmsr & BMSR_ANEGCOMPLETE)) {
- /* Auto-Negotiation not completed */
- return -1;
- }
- negotiate = mii_read (dev, phy_addr, MII_ADVERTISE) &
- mii_read (dev, phy_addr, MII_LPA);
- mscr = mii_read (dev, phy_addr, MII_CTRL1000);
- mssr = mii_read (dev, phy_addr, MII_STAT1000);
- if (mscr & ADVERTISE_1000FULL && mssr & LPA_1000FULL) {
- np->speed = 1000;
- np->full_duplex = 1;
- printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n");
- } else if (mscr & ADVERTISE_1000HALF && mssr & LPA_1000HALF) {
- np->speed = 1000;
- np->full_duplex = 0;
- printk (KERN_INFO "Auto 1000 Mbps, Half duplex\n");
- } else if (negotiate & ADVERTISE_100FULL) {
- np->speed = 100;
- np->full_duplex = 1;
- printk (KERN_INFO "Auto 100 Mbps, Full duplex\n");
- } else if (negotiate & ADVERTISE_100HALF) {
- np->speed = 100;
- np->full_duplex = 0;
- printk (KERN_INFO "Auto 100 Mbps, Half duplex\n");
- } else if (negotiate & ADVERTISE_10FULL) {
- np->speed = 10;
- np->full_duplex = 1;
- printk (KERN_INFO "Auto 10 Mbps, Full duplex\n");
- } else if (negotiate & ADVERTISE_10HALF) {
- np->speed = 10;
- np->full_duplex = 0;
- printk (KERN_INFO "Auto 10 Mbps, Half duplex\n");
- }
- if (negotiate & ADVERTISE_PAUSE_CAP) {
- np->tx_flow &= 1;
- np->rx_flow &= 1;
- } else if (negotiate & ADVERTISE_PAUSE_ASYM) {
- np->tx_flow = 0;
- np->rx_flow &= 1;
- }
- /* else tx_flow, rx_flow = user select */
- } else {
- __u16 bmcr = mii_read (dev, phy_addr, MII_BMCR);
- switch (bmcr & (BMCR_SPEED100 | BMCR_SPEED1000)) {
- case BMCR_SPEED1000:
- printk (KERN_INFO "Operating at 1000 Mbps, ");
- break;
- case BMCR_SPEED100:
- printk (KERN_INFO "Operating at 100 Mbps, ");
- break;
- case 0:
- printk (KERN_INFO "Operating at 10 Mbps, ");
- }
- if (bmcr & BMCR_FULLDPLX) {
- printk (KERN_CONT "Full duplex\n");
- } else {
- printk (KERN_CONT "Half duplex\n");
- }
- }
- if (np->tx_flow)
- printk(KERN_INFO "Enable Tx Flow Control\n");
- else
- printk(KERN_INFO "Disable Tx Flow Control\n");
- if (np->rx_flow)
- printk(KERN_INFO "Enable Rx Flow Control\n");
- else
- printk(KERN_INFO "Disable Rx Flow Control\n");
-
- return 0;
-}
-
-static int
-mii_set_media (struct net_device *dev)
-{
- __u16 pscr;
- __u16 bmcr;
- __u16 bmsr;
- __u16 anar;
- int phy_addr;
- struct netdev_private *np;
- np = netdev_priv(dev);
- phy_addr = np->phy_addr;
-
- /* Does user set speed? */
- if (np->an_enable) {
- /* Advertise capabilities */
- bmsr = mii_read (dev, phy_addr, MII_BMSR);
- anar = mii_read (dev, phy_addr, MII_ADVERTISE) &
- ~(ADVERTISE_100FULL | ADVERTISE_10FULL |
- ADVERTISE_100HALF | ADVERTISE_10HALF |
- ADVERTISE_100BASE4);
- if (bmsr & BMSR_100FULL)
- anar |= ADVERTISE_100FULL;
- if (bmsr & BMSR_100HALF)
- anar |= ADVERTISE_100HALF;
- if (bmsr & BMSR_100BASE4)
- anar |= ADVERTISE_100BASE4;
- if (bmsr & BMSR_10FULL)
- anar |= ADVERTISE_10FULL;
- if (bmsr & BMSR_10HALF)
- anar |= ADVERTISE_10HALF;
- anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
- mii_write (dev, phy_addr, MII_ADVERTISE, anar);
-
- /* Enable Auto crossover */
- pscr = mii_read (dev, phy_addr, MII_PHY_SCR);
- pscr |= 3 << 5; /* 11'b */
- mii_write (dev, phy_addr, MII_PHY_SCR, pscr);
-
- /* Soft reset PHY */
- mii_write (dev, phy_addr, MII_BMCR, BMCR_RESET);
- bmcr = BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET;
- mii_write (dev, phy_addr, MII_BMCR, bmcr);
- mdelay(1);
- } else {
- /* Force speed setting */
- /* 1) Disable Auto crossover */
- pscr = mii_read (dev, phy_addr, MII_PHY_SCR);
- pscr &= ~(3 << 5);
- mii_write (dev, phy_addr, MII_PHY_SCR, pscr);
-
- /* 2) PHY Reset */
- bmcr = mii_read (dev, phy_addr, MII_BMCR);
- bmcr |= BMCR_RESET;
- mii_write (dev, phy_addr, MII_BMCR, bmcr);
-
- /* 3) Power Down */
- bmcr = 0x1940; /* must be 0x1940 */
- mii_write (dev, phy_addr, MII_BMCR, bmcr);
- mdelay (100); /* wait a certain time */
-
- /* 4) Advertise nothing */
- mii_write (dev, phy_addr, MII_ADVERTISE, 0);
-
- /* 5) Set media and Power Up */
- bmcr = BMCR_PDOWN;
- if (np->speed == 100) {
- bmcr |= BMCR_SPEED100;
- printk (KERN_INFO "Manual 100 Mbps, ");
- } else if (np->speed == 10) {
- printk (KERN_INFO "Manual 10 Mbps, ");
- }
- if (np->full_duplex) {
- bmcr |= BMCR_FULLDPLX;
- printk (KERN_CONT "Full duplex\n");
- } else {
- printk (KERN_CONT "Half duplex\n");
- }
-#if 0
- /* Set 1000BaseT Master/Slave setting */
- mscr = mii_read (dev, phy_addr, MII_CTRL1000);
- mscr |= MII_MSCR_CFG_ENABLE;
- mscr &= ~MII_MSCR_CFG_VALUE = 0;
-#endif
- mii_write (dev, phy_addr, MII_BMCR, bmcr);
- mdelay(10);
- }
- return 0;
-}
-
-static int
-mii_get_media_pcs (struct net_device *dev)
-{
- __u16 negotiate;
- __u16 bmsr;
- int phy_addr;
- struct netdev_private *np;
-
- np = netdev_priv(dev);
- phy_addr = np->phy_addr;
-
- bmsr = mii_read (dev, phy_addr, PCS_BMSR);
- if (np->an_enable) {
- if (!(bmsr & BMSR_ANEGCOMPLETE)) {
- /* Auto-Negotiation not completed */
- return -1;
- }
- negotiate = mii_read (dev, phy_addr, PCS_ANAR) &
- mii_read (dev, phy_addr, PCS_ANLPAR);
- np->speed = 1000;
- if (negotiate & PCS_ANAR_FULL_DUPLEX) {
- printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n");
- np->full_duplex = 1;
- } else {
- printk (KERN_INFO "Auto 1000 Mbps, half duplex\n");
- np->full_duplex = 0;
- }
- if (negotiate & PCS_ANAR_PAUSE) {
- np->tx_flow &= 1;
- np->rx_flow &= 1;
- } else if (negotiate & PCS_ANAR_ASYMMETRIC) {
- np->tx_flow = 0;
- np->rx_flow &= 1;
- }
- /* else tx_flow, rx_flow = user select */
- } else {
- __u16 bmcr = mii_read (dev, phy_addr, PCS_BMCR);
- printk (KERN_INFO "Operating at 1000 Mbps, ");
- if (bmcr & BMCR_FULLDPLX) {
- printk (KERN_CONT "Full duplex\n");
- } else {
- printk (KERN_CONT "Half duplex\n");
- }
- }
- if (np->tx_flow)
- printk(KERN_INFO "Enable Tx Flow Control\n");
- else
- printk(KERN_INFO "Disable Tx Flow Control\n");
- if (np->rx_flow)
- printk(KERN_INFO "Enable Rx Flow Control\n");
- else
- printk(KERN_INFO "Disable Rx Flow Control\n");
-
- return 0;
-}
-
-static int
-mii_set_media_pcs (struct net_device *dev)
-{
- __u16 bmcr;
- __u16 esr;
- __u16 anar;
- int phy_addr;
- struct netdev_private *np;
- np = netdev_priv(dev);
- phy_addr = np->phy_addr;
-
- /* Auto-Negotiation? */
- if (np->an_enable) {
- /* Advertise capabilities */
- esr = mii_read (dev, phy_addr, PCS_ESR);
- anar = mii_read (dev, phy_addr, MII_ADVERTISE) &
- ~PCS_ANAR_HALF_DUPLEX &
- ~PCS_ANAR_FULL_DUPLEX;
- if (esr & (MII_ESR_1000BT_HD | MII_ESR_1000BX_HD))
- anar |= PCS_ANAR_HALF_DUPLEX;
- if (esr & (MII_ESR_1000BT_FD | MII_ESR_1000BX_FD))
- anar |= PCS_ANAR_FULL_DUPLEX;
- anar |= PCS_ANAR_PAUSE | PCS_ANAR_ASYMMETRIC;
- mii_write (dev, phy_addr, MII_ADVERTISE, anar);
-
- /* Soft reset PHY */
- mii_write (dev, phy_addr, MII_BMCR, BMCR_RESET);
- bmcr = BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET;
- mii_write (dev, phy_addr, MII_BMCR, bmcr);
- mdelay(1);
- } else {
- /* Force speed setting */
- /* PHY Reset */
- bmcr = BMCR_RESET;
- mii_write (dev, phy_addr, MII_BMCR, bmcr);
- mdelay(10);
- if (np->full_duplex) {
- bmcr = BMCR_FULLDPLX;
- printk (KERN_INFO "Manual full duplex\n");
- } else {
- bmcr = 0;
- printk (KERN_INFO "Manual half duplex\n");
- }
- mii_write (dev, phy_addr, MII_BMCR, bmcr);
- mdelay(10);
-
- /* Advertise nothing */
- mii_write (dev, phy_addr, MII_ADVERTISE, 0);
- }
- return 0;
-}
-
-
-static int
-rio_close (struct net_device *dev)
-{
- long ioaddr = dev->base_addr;
- struct netdev_private *np = netdev_priv(dev);
- struct sk_buff *skb;
- int i;
-
- netif_stop_queue (dev);
-
- /* Disable interrupts */
- writew (0, ioaddr + IntEnable);
-
- /* Stop Tx and Rx logics */
- writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl);
-
- free_irq (dev->irq, dev);
- del_timer_sync (&np->timer);
-
- /* Free all the skbuffs in the queue. */
- for (i = 0; i < RX_RING_SIZE; i++) {
- skb = np->rx_skbuff[i];
- if (skb) {
- pci_unmap_single(np->pdev,
- desc_to_dma(&np->rx_ring[i]),
- skb->len, PCI_DMA_FROMDEVICE);
- dev_kfree_skb (skb);
- np->rx_skbuff[i] = NULL;
- }
- np->rx_ring[i].status = 0;
- np->rx_ring[i].fraginfo = 0;
- }
- for (i = 0; i < TX_RING_SIZE; i++) {
- skb = np->tx_skbuff[i];
- if (skb) {
- pci_unmap_single(np->pdev,
- desc_to_dma(&np->tx_ring[i]),
- skb->len, PCI_DMA_TODEVICE);
- dev_kfree_skb (skb);
- np->tx_skbuff[i] = NULL;
- }
- }
-
- return 0;
-}
-
-static void __devexit
-rio_remove1 (struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata (pdev);
-
- if (dev) {
- struct netdev_private *np = netdev_priv(dev);
-
- unregister_netdev (dev);
- pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring,
- np->rx_ring_dma);
- pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring,
- np->tx_ring_dma);
-#ifdef MEM_MAPPING
- iounmap ((char *) (dev->base_addr));
-#endif
- free_netdev (dev);
- pci_release_regions (pdev);
- pci_disable_device (pdev);
- }
- pci_set_drvdata (pdev, NULL);
-}
-
-static struct pci_driver rio_driver = {
- .name = "dl2k",
- .id_table = rio_pci_tbl,
- .probe = rio_probe1,
- .remove = __devexit_p(rio_remove1),
-};
-
-static int __init
-rio_init (void)
-{
- return pci_register_driver(&rio_driver);
-}
-
-static void __exit
-rio_exit (void)
-{
- pci_unregister_driver (&rio_driver);
-}
-
-module_init (rio_init);
-module_exit (rio_exit);
-
-/*
-
-Compile command:
-
-gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -c dl2k.c
-
-Read Documentation/networking/dl2k.txt for details.
-
-*/
-
diff --git a/ANDROID_3.4.5/drivers/net/ethernet/dlink/dl2k.h b/ANDROID_3.4.5/drivers/net/ethernet/dlink/dl2k.h
deleted file mode 100644
index 30c2da3d..00000000
--- a/ANDROID_3.4.5/drivers/net/ethernet/dlink/dl2k.h
+++ /dev/null
@@ -1,441 +0,0 @@
-/* D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */
-/*
- Copyright (c) 2001, 2002 by D-Link Corporation
- Written by Edward Peng.<edward_peng@dlink.com.tw>
- Created 03-May-2001, base on Linux' sundance.c.
-
- 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.
-*/
-
-#ifndef __DL2K_H__
-#define __DL2K_H__
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-#include <linux/crc32.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/bitops.h>
-#include <asm/processor.h> /* Processor type for cache alignment. */
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/time.h>
-#define TX_RING_SIZE 256
-#define TX_QUEUE_LEN (TX_RING_SIZE - 1) /* Limit ring entries actually used.*/
-#define RX_RING_SIZE 256
-#define TX_TOTAL_SIZE TX_RING_SIZE*sizeof(struct netdev_desc)
-#define RX_TOTAL_SIZE RX_RING_SIZE*sizeof(struct netdev_desc)
-
-/* This driver was written to use PCI memory space, however x86-oriented
- hardware often uses I/O space accesses. */
-#ifndef MEM_MAPPING
-#undef readb
-#undef readw
-#undef readl
-#undef writeb
-#undef writew
-#undef writel
-#define readb inb
-#define readw inw
-#define readl inl
-#define writeb outb
-#define writew outw
-#define writel outl
-#endif
-
-/* Offsets to the device registers.
- Unlike software-only systems, device drivers interact with complex hardware.
- It's not useful to define symbolic names for every register bit in the
- device. The name can only partially document the semantics and make
- the driver longer and more difficult to read.
- In general, only the important configuration values or bits changed
- multiple times should be defined symbolically.
-*/
-enum dl2x_offsets {
- /* I/O register offsets */
- DMACtrl = 0x00,
- RxDMAStatus = 0x08,
- TFDListPtr0 = 0x10,
- TFDListPtr1 = 0x14,
- TxDMABurstThresh = 0x18,
- TxDMAUrgentThresh = 0x19,
- TxDMAPollPeriod = 0x1a,
- RFDListPtr0 = 0x1c,
- RFDListPtr1 = 0x20,
- RxDMABurstThresh = 0x24,
- RxDMAUrgentThresh = 0x25,
- RxDMAPollPeriod = 0x26,
- RxDMAIntCtrl = 0x28,
- DebugCtrl = 0x2c,
- ASICCtrl = 0x30,
- FifoCtrl = 0x38,
- RxEarlyThresh = 0x3a,
- FlowOffThresh = 0x3c,
- FlowOnThresh = 0x3e,
- TxStartThresh = 0x44,
- EepromData = 0x48,
- EepromCtrl = 0x4a,
- ExpromAddr = 0x4c,
- Exprodata = 0x50,
- WakeEvent = 0x51,
- CountDown = 0x54,
- IntStatusAck = 0x5a,
- IntEnable = 0x5c,
- IntStatus = 0x5e,
- TxStatus = 0x60,
- MACCtrl = 0x6c,
- VLANTag = 0x70,
- PhyCtrl = 0x76,
- StationAddr0 = 0x78,
- StationAddr1 = 0x7a,
- StationAddr2 = 0x7c,
- VLANId = 0x80,
- MaxFrameSize = 0x86,
- ReceiveMode = 0x88,
- HashTable0 = 0x8c,
- HashTable1 = 0x90,
- RmonStatMask = 0x98,
- StatMask = 0x9c,
- RxJumboFrames = 0xbc,
- TCPCheckSumErrors = 0xc0,
- IPCheckSumErrors = 0xc2,
- UDPCheckSumErrors = 0xc4,
- TxJumboFrames = 0xf4,
- /* Ethernet MIB statistic register offsets */
- OctetRcvOk = 0xa8,
- McstOctetRcvOk = 0xac,
- BcstOctetRcvOk = 0xb0,
- FramesRcvOk = 0xb4,
- McstFramesRcvdOk = 0xb8,
- BcstFramesRcvdOk = 0xbe,
- MacControlFramesRcvd = 0xc6,
- FrameTooLongErrors = 0xc8,
- InRangeLengthErrors = 0xca,
- FramesCheckSeqErrors = 0xcc,
- FramesLostRxErrors = 0xce,
- OctetXmtOk = 0xd0,
- McstOctetXmtOk = 0xd4,
- BcstOctetXmtOk = 0xd8,
- FramesXmtOk = 0xdc,
- McstFramesXmtdOk = 0xe0,
- FramesWDeferredXmt = 0xe4,
- LateCollisions = 0xe8,
- MultiColFrames = 0xec,
- SingleColFrames = 0xf0,
- BcstFramesXmtdOk = 0xf6,
- CarrierSenseErrors = 0xf8,
- MacControlFramesXmtd = 0xfa,
- FramesAbortXSColls = 0xfc,
- FramesWEXDeferal = 0xfe,
- /* RMON statistic register offsets */
- EtherStatsCollisions = 0x100,
- EtherStatsOctetsTransmit = 0x104,
- EtherStatsPktsTransmit = 0x108,
- EtherStatsPkts64OctetTransmit = 0x10c,
- EtherStats65to127OctetsTransmit = 0x110,
- EtherStatsPkts128to255OctetsTransmit = 0x114,
- EtherStatsPkts256to511OctetsTransmit = 0x118,
- EtherStatsPkts512to1023OctetsTransmit = 0x11c,
- EtherStatsPkts1024to1518OctetsTransmit = 0x120,
- EtherStatsCRCAlignErrors = 0x124,
- EtherStatsUndersizePkts = 0x128,
- EtherStatsFragments = 0x12c,
- EtherStatsJabbers = 0x130,
- EtherStatsOctets = 0x134,
- EtherStatsPkts = 0x138,
- EtherStats64Octets = 0x13c,
- EtherStatsPkts65to127Octets = 0x140,
- EtherStatsPkts128to255Octets = 0x144,
- EtherStatsPkts256to511Octets = 0x148,
- EtherStatsPkts512to1023Octets = 0x14c,
- EtherStatsPkts1024to1518Octets = 0x150,
-};
-
-/* Bits in the interrupt status/mask registers. */
-enum IntStatus_bits {
- InterruptStatus = 0x0001,
- HostError = 0x0002,
- MACCtrlFrame = 0x0008,
- TxComplete = 0x0004,
- RxComplete = 0x0010,
- RxEarly = 0x0020,
- IntRequested = 0x0040,
- UpdateStats = 0x0080,
- LinkEvent = 0x0100,
- TxDMAComplete = 0x0200,
- RxDMAComplete = 0x0400,
- RFDListEnd = 0x0800,
- RxDMAPriority = 0x1000,
-};
-
-/* Bits in the ReceiveMode register. */
-enum ReceiveMode_bits {
- ReceiveUnicast = 0x0001,
- ReceiveMulticast = 0x0002,
- ReceiveBroadcast = 0x0004,
- ReceiveAllFrames = 0x0008,
- ReceiveMulticastHash = 0x0010,
- ReceiveIPMulticast = 0x0020,
- ReceiveVLANMatch = 0x0100,
- ReceiveVLANHash = 0x0200,
-};
-/* Bits in MACCtrl. */
-enum MACCtrl_bits {
- DuplexSelect = 0x20,
- TxFlowControlEnable = 0x80,
- RxFlowControlEnable = 0x0100,
- RcvFCS = 0x200,
- AutoVLANtagging = 0x1000,
- AutoVLANuntagging = 0x2000,
- StatsEnable = 0x00200000,
- StatsDisable = 0x00400000,
- StatsEnabled = 0x00800000,
- TxEnable = 0x01000000,
- TxDisable = 0x02000000,
- TxEnabled = 0x04000000,
- RxEnable = 0x08000000,
- RxDisable = 0x10000000,
- RxEnabled = 0x20000000,
-};
-
-enum ASICCtrl_LoWord_bits {
- PhyMedia = 0x0080,
-};
-
-enum ASICCtrl_HiWord_bits {
- GlobalReset = 0x0001,
- RxReset = 0x0002,
- TxReset = 0x0004,
- DMAReset = 0x0008,
- FIFOReset = 0x0010,
- NetworkReset = 0x0020,
- HostReset = 0x0040,
- ResetBusy = 0x0400,
-};
-
-/* Transmit Frame Control bits */
-enum TFC_bits {
- DwordAlign = 0x00000000,
- WordAlignDisable = 0x00030000,
- WordAlign = 0x00020000,
- TCPChecksumEnable = 0x00040000,
- UDPChecksumEnable = 0x00080000,
- IPChecksumEnable = 0x00100000,
- FCSAppendDisable = 0x00200000,
- TxIndicate = 0x00400000,
- TxDMAIndicate = 0x00800000,
- FragCountShift = 24,
- VLANTagInsert = 0x0000000010000000,
- TFDDone = 0x80000000,
- VIDShift = 32,
- UsePriorityShift = 48,
-};
-
-/* Receive Frames Status bits */
-enum RFS_bits {
- RxFIFOOverrun = 0x00010000,
- RxRuntFrame = 0x00020000,
- RxAlignmentError = 0x00040000,
- RxFCSError = 0x00080000,
- RxOverSizedFrame = 0x00100000,
- RxLengthError = 0x00200000,
- VLANDetected = 0x00400000,
- TCPDetected = 0x00800000,
- TCPError = 0x01000000,
- UDPDetected = 0x02000000,
- UDPError = 0x04000000,
- IPDetected = 0x08000000,
- IPError = 0x10000000,
- FrameStart = 0x20000000,
- FrameEnd = 0x40000000,
- RFDDone = 0x80000000,
- TCIShift = 32,
- RFS_Errors = 0x003f0000,
-};
-
-#define MII_RESET_TIME_OUT 10000
-/* MII register */
-enum _mii_reg {
- MII_PHY_SCR = 16,
-};
-
-/* PCS register */
-enum _pcs_reg {
- PCS_BMCR = 0,
- PCS_BMSR = 1,
- PCS_ANAR = 4,
- PCS_ANLPAR = 5,
- PCS_ANER = 6,
- PCS_ANNPT = 7,
- PCS_ANLPRNP = 8,
- PCS_ESR = 15,
-};
-
-/* IEEE Extened Status Register */
-enum _mii_esr {
- MII_ESR_1000BX_FD = 0x8000,
- MII_ESR_1000BX_HD = 0x4000,
- MII_ESR_1000BT_FD = 0x2000,
- MII_ESR_1000BT_HD = 0x1000,
-};
-/* PHY Specific Control Register */
-#if 0
-typedef union t_MII_PHY_SCR {
- u16 image;
- struct {
- u16 disable_jabber:1; // bit 0
- u16 polarity_reversal:1; // bit 1
- u16 SEQ_test:1; // bit 2
- u16 _bit_3:1; // bit 3
- u16 disable_CLK125:1; // bit 4
- u16 mdi_crossover_mode:2; // bit 6:5
- u16 enable_ext_dist:1; // bit 7
- u16 _bit_8_9:2; // bit 9:8
- u16 force_link:1; // bit 10
- u16 assert_CRS:1; // bit 11
- u16 rcv_fifo_depth:2; // bit 13:12
- u16 xmit_fifo_depth:2; // bit 15:14
- } bits;
-} PHY_SCR_t, *PPHY_SCR_t;
-#endif
-
-typedef enum t_MII_ADMIN_STATUS {
- adm_reset,
- adm_operational,
- adm_loopback,
- adm_power_down,
- adm_isolate
-} MII_ADMIN_t, *PMII_ADMIN_t;
-
-/* Physical Coding Sublayer Management (PCS) */
-/* PCS control and status registers bitmap as the same as MII */
-/* PCS Extended Status register bitmap as the same as MII */
-/* PCS ANAR */
-enum _pcs_anar {
- PCS_ANAR_NEXT_PAGE = 0x8000,
- PCS_ANAR_REMOTE_FAULT = 0x3000,
- PCS_ANAR_ASYMMETRIC = 0x0100,
- PCS_ANAR_PAUSE = 0x0080,
- PCS_ANAR_HALF_DUPLEX = 0x0040,
- PCS_ANAR_FULL_DUPLEX = 0x0020,
-};
-/* PCS ANLPAR */
-enum _pcs_anlpar {
- PCS_ANLPAR_NEXT_PAGE = PCS_ANAR_NEXT_PAGE,
- PCS_ANLPAR_REMOTE_FAULT = PCS_ANAR_REMOTE_FAULT,
- PCS_ANLPAR_ASYMMETRIC = PCS_ANAR_ASYMMETRIC,
- PCS_ANLPAR_PAUSE = PCS_ANAR_PAUSE,
- PCS_ANLPAR_HALF_DUPLEX = PCS_ANAR_HALF_DUPLEX,
- PCS_ANLPAR_FULL_DUPLEX = PCS_ANAR_FULL_DUPLEX,
-};
-
-typedef struct t_SROM {
- u16 config_param; /* 0x00 */
- u16 asic_ctrl; /* 0x02 */
- u16 sub_vendor_id; /* 0x04 */
- u16 sub_system_id; /* 0x06 */
- u16 reserved1[12]; /* 0x08-0x1f */
- u8 mac_addr[6]; /* 0x20-0x25 */
- u8 reserved2[10]; /* 0x26-0x2f */
- u8 sib[204]; /* 0x30-0xfb */
- u32 crc; /* 0xfc-0xff */
-} SROM_t, *PSROM_t;
-
-/* Ioctl custom data */
-struct ioctl_data {
- char signature[10];
- int cmd;
- int len;
- char *data;
-};
-
-/* The Rx and Tx buffer descriptors. */
-struct netdev_desc {
- __le64 next_desc;
- __le64 status;
- __le64 fraginfo;
-};
-
-#define PRIV_ALIGN 15 /* Required alignment mask */
-/* Use __attribute__((aligned (L1_CACHE_BYTES))) to maintain alignment
- within the structure. */
-struct netdev_private {
- /* Descriptor rings first for alignment. */
- struct netdev_desc *rx_ring;
- struct netdev_desc *tx_ring;
- struct sk_buff *rx_skbuff[RX_RING_SIZE];
- struct sk_buff *tx_skbuff[TX_RING_SIZE];
- dma_addr_t tx_ring_dma;
- dma_addr_t rx_ring_dma;
- struct pci_dev *pdev;
- spinlock_t tx_lock;
- spinlock_t rx_lock;
- struct net_device_stats stats;
- unsigned int rx_buf_sz; /* Based on MTU+slack. */
- unsigned int speed; /* Operating speed */
- unsigned int vlan; /* VLAN Id */
- unsigned int chip_id; /* PCI table chip id */
- unsigned int rx_coalesce; /* Maximum frames each RxDMAComplete intr */
- unsigned int rx_timeout; /* Wait time between RxDMAComplete intr */
- unsigned int tx_coalesce; /* Maximum frames each tx interrupt */
- unsigned int full_duplex:1; /* Full-duplex operation requested. */
- unsigned int an_enable:2; /* Auto-Negotiated Enable */
- unsigned int jumbo:1; /* Jumbo frame enable */
- unsigned int coalesce:1; /* Rx coalescing enable */
- unsigned int tx_flow:1; /* Tx flow control enable */
- unsigned int rx_flow:1; /* Rx flow control enable */
- unsigned int phy_media:1; /* 1: fiber, 0: copper */
- unsigned int link_status:1; /* Current link status */
- struct netdev_desc *last_tx; /* Last Tx descriptor used. */
- unsigned long cur_rx, old_rx; /* Producer/consumer ring indices */
- unsigned long cur_tx, old_tx;
- struct timer_list timer;
- int wake_polarity;
- char name[256]; /* net device description */
- u8 duplex_polarity;
- u16 mcast_filter[4];
- u16 advertising; /* NWay media advertisement */
- u16 negotiate; /* Negotiated media */
- int phy_addr; /* PHY addresses. */
-};
-
-/* The station address location in the EEPROM. */
-/* The struct pci_device_id consist of:
- vendor, device Vendor and device ID to match (or PCI_ANY_ID)
- subvendor, subdevice Subsystem vendor and device ID to match (or PCI_ANY_ID)
- class Device class to match. The class_mask tells which bits
- class_mask of the class are honored during the comparison.
- driver_data Data private to the driver.
-*/
-
-static DEFINE_PCI_DEVICE_TABLE(rio_pci_tbl) = {
- {0x1186, 0x4000, PCI_ANY_ID, PCI_ANY_ID, },
- {0x13f0, 0x1021, PCI_ANY_ID, PCI_ANY_ID, },
- { }
-};
-MODULE_DEVICE_TABLE (pci, rio_pci_tbl);
-#define TX_TIMEOUT (4*HZ)
-#define PACKET_SIZE 1536
-#define MAX_JUMBO 8000
-#define RIO_IO_SIZE 340
-#define DEFAULT_RXC 5
-#define DEFAULT_RXT 750
-#define DEFAULT_TXC 1
-#define MAX_TXC 8
-#endif /* __DL2K_H__ */
diff --git a/ANDROID_3.4.5/drivers/net/ethernet/dlink/sundance.c b/ANDROID_3.4.5/drivers/net/ethernet/dlink/sundance.c
deleted file mode 100644
index d783f4f9..00000000
--- a/ANDROID_3.4.5/drivers/net/ethernet/dlink/sundance.c
+++ /dev/null
@@ -1,1939 +0,0 @@
-/* sundance.c: A Linux device driver for the Sundance ST201 "Alta". */
-/*
- Written 1999-2000 by Donald Becker.
-
- This software may be used and distributed according to the terms of
- the GNU General Public License (GPL), incorporated herein by reference.
- Drivers based on or derived from this code fall under the GPL and must
- retain the authorship, copyright and license notice. This file is not
- a complete program and may only be used when the entire operating
- system is licensed under the GPL.
-
- The author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
- Support and updates available at
- http://www.scyld.com/network/sundance.html
- [link no longer provides useful info -jgarzik]
- Archives of the mailing list are still available at
- http://www.beowulf.org/pipermail/netdrivers/
-
-*/
-
-#define DRV_NAME "sundance"
-#define DRV_VERSION "1.2"
-#define DRV_RELDATE "11-Sep-2006"
-
-
-/* The user-configurable values.
- These may be modified when a driver module is loaded.*/
-static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
-/* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
- Typical is a 64 element hash table based on the Ethernet CRC. */
-static const int multicast_filter_limit = 32;
-
-/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
- Setting to > 1518 effectively disables this feature.
- This chip can receive into offset buffers, so the Alpha does not
- need a copy-align. */
-static int rx_copybreak;
-static int flowctrl=1;
-
-/* media[] specifies the media type the NIC operates at.
- autosense Autosensing active media.
- 10mbps_hd 10Mbps half duplex.
- 10mbps_fd 10Mbps full duplex.
- 100mbps_hd 100Mbps half duplex.
- 100mbps_fd 100Mbps full duplex.
- 0 Autosensing active media.
- 1 10Mbps half duplex.
- 2 10Mbps full duplex.
- 3 100Mbps half duplex.
- 4 100Mbps full duplex.
-*/
-#define MAX_UNITS 8
-static char *media[MAX_UNITS];
-
-
-/* Operational parameters that are set at compile time. */
-
-/* Keep the ring sizes a power of two for compile efficiency.
- The compiler will convert <unsigned>'%'<2^N> into a bit mask.
- Making the Tx ring too large decreases the effectiveness of channel
- bonding and packet priority, and more than 128 requires modifying the
- Tx error recovery.
- Large receive rings merely waste memory. */
-#define TX_RING_SIZE 32
-#define TX_QUEUE_LEN (TX_RING_SIZE - 1) /* Limit ring entries actually used. */
-#define RX_RING_SIZE 64
-#define RX_BUDGET 32
-#define TX_TOTAL_SIZE TX_RING_SIZE*sizeof(struct netdev_desc)
-#define RX_TOTAL_SIZE RX_RING_SIZE*sizeof(struct netdev_desc)
-
-/* Operational parameters that usually are not changed. */
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT (4*HZ)
-#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
-
-/* Include files, designed to support most kernel versions 2.0.0 and later. */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h> /* Processor type for cache alignment. */
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/dma-mapping.h>
-#include <linux/crc32.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-
-/* These identify the driver base version and may not be removed. */
-static const char version[] __devinitconst =
- KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE
- " Written by Donald Becker\n";
-
-MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
-MODULE_DESCRIPTION("Sundance Alta Ethernet driver");
-MODULE_LICENSE("GPL");
-
-module_param(debug, int, 0);
-module_param(rx_copybreak, int, 0);
-module_param_array(media, charp, NULL, 0);
-module_param(flowctrl, int, 0);
-MODULE_PARM_DESC(debug, "Sundance Alta debug level (0-5)");
-MODULE_PARM_DESC(rx_copybreak, "Sundance Alta copy breakpoint for copy-only-tiny-frames");
-MODULE_PARM_DESC(flowctrl, "Sundance Alta flow control [0|1]");
-
-/*
- Theory of Operation
-
-I. Board Compatibility
-
-This driver is designed for the Sundance Technologies "Alta" ST201 chip.
-
-II. Board-specific settings
-
-III. Driver operation
-
-IIIa. Ring buffers
-
-This driver uses two statically allocated fixed-size descriptor lists
-formed into rings by a branch from the final descriptor to the beginning of
-the list. The ring sizes are set at compile time by RX/TX_RING_SIZE.
-Some chips explicitly use only 2^N sized rings, while others use a
-'next descriptor' pointer that the driver forms into rings.
-
-IIIb/c. Transmit/Receive Structure
-
-This driver uses a zero-copy receive and transmit scheme.
-The driver allocates full frame size skbuffs for the Rx ring buffers at
-open() time and passes the skb->data field to the chip as receive data
-buffers. When an incoming frame is less than RX_COPYBREAK bytes long,
-a fresh skbuff is allocated and the frame is copied to the new skbuff.
-When the incoming frame is larger, the skbuff is passed directly up the
-protocol stack. Buffers consumed this way are replaced by newly allocated
-skbuffs in a later phase of receives.
-
-The RX_COPYBREAK value is chosen to trade-off the memory wasted by
-using a full-sized skbuff for small frames vs. the copying costs of larger
-frames. New boards are typically used in generously configured machines
-and the underfilled buffers have negligible impact compared to the benefit of
-a single allocation size, so the default value of zero results in never
-copying packets. When copying is done, the cost is usually mitigated by using
-a combined copy/checksum routine. Copying also preloads the cache, which is
-most useful with small frames.
-
-A subtle aspect of the operation is that the IP header at offset 14 in an
-ethernet frame isn't longword aligned for further processing.
-Unaligned buffers are permitted by the Sundance hardware, so
-frames are received into the skbuff at an offset of "+2", 16-byte aligning
-the IP header.
-
-IIId. Synchronization
-
-The driver runs as two independent, single-threaded flows of control. One
-is the send-packet routine, which enforces single-threaded use by the
-dev->tbusy flag. The other thread is the interrupt handler, which is single
-threaded by the hardware and interrupt handling software.
-
-The send packet thread has partial control over the Tx ring and 'dev->tbusy'
-flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next
-queue slot is empty, it clears the tbusy flag when finished otherwise it sets
-the 'lp->tx_full' flag.
-
-The interrupt handler has exclusive control over the Rx ring and records stats
-from the Tx ring. After reaping the stats, it marks the Tx queue entry as
-empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it
-clears both the tx_full and tbusy flags.
-
-IV. Notes
-
-IVb. References
-
-The Sundance ST201 datasheet, preliminary version.
-The Kendin KS8723 datasheet, preliminary version.
-The ICplus IP100 datasheet, preliminary version.
-http://www.scyld.com/expert/100mbps.html
-http://www.scyld.com/expert/NWay.html
-
-IVc. Errata
-
-*/
-
-/* Work-around for Kendin chip bugs. */
-#ifndef CONFIG_SUNDANCE_MMIO
-#define USE_IO_OPS 1
-#endif
-
-static DEFINE_PCI_DEVICE_TABLE(sundance_pci_tbl) = {
- { 0x1186, 0x1002, 0x1186, 0x1002, 0, 0, 0 },
- { 0x1186, 0x1002, 0x1186, 0x1003, 0, 0, 1 },
- { 0x1186, 0x1002, 0x1186, 0x1012, 0, 0, 2 },
- { 0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3 },
- { 0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
- { 0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
- { 0x13F0, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },
- { }
-};
-MODULE_DEVICE_TABLE(pci, sundance_pci_tbl);
-
-enum {
- netdev_io_size = 128
-};
-
-struct pci_id_info {
- const char *name;
-};
-static const struct pci_id_info pci_id_tbl[] __devinitdata = {
- {"D-Link DFE-550TX FAST Ethernet Adapter"},
- {"D-Link DFE-550FX 100Mbps Fiber-optics Adapter"},
- {"D-Link DFE-580TX 4 port Server Adapter"},
- {"D-Link DFE-530TXS FAST Ethernet Adapter"},
- {"D-Link DL10050-based FAST Ethernet Adapter"},
- {"Sundance Technology Alta"},
- {"IC Plus Corporation IP100A FAST Ethernet Adapter"},
- { } /* terminate list. */
-};
-
-/* This driver was written to use PCI memory space, however x86-oriented
- hardware often uses I/O space accesses. */
-
-/* Offsets to the device registers.
- Unlike software-only systems, device drivers interact with complex hardware.
- It's not useful to define symbolic names for every register bit in the
- device. The name can only partially document the semantics and make
- the driver longer and more difficult to read.
- In general, only the important configuration values or bits changed
- multiple times should be defined symbolically.
-*/
-enum alta_offsets {
- DMACtrl = 0x00,
- TxListPtr = 0x04,
- TxDMABurstThresh = 0x08,
- TxDMAUrgentThresh = 0x09,
- TxDMAPollPeriod = 0x0a,
- RxDMAStatus = 0x0c,
- RxListPtr = 0x10,
- DebugCtrl0 = 0x1a,
- DebugCtrl1 = 0x1c,
- RxDMABurstThresh = 0x14,
- RxDMAUrgentThresh = 0x15,
- RxDMAPollPeriod = 0x16,
- LEDCtrl = 0x1a,
- ASICCtrl = 0x30,
- EEData = 0x34,
- EECtrl = 0x36,
- FlashAddr = 0x40,
- FlashData = 0x44,
- TxStatus = 0x46,
- TxFrameId = 0x47,
- DownCounter = 0x18,
- IntrClear = 0x4a,
- IntrEnable = 0x4c,
- IntrStatus = 0x4e,
- MACCtrl0 = 0x50,
- MACCtrl1 = 0x52,
- StationAddr = 0x54,
- MaxFrameSize = 0x5A,
- RxMode = 0x5c,
- MIICtrl = 0x5e,
- MulticastFilter0 = 0x60,
- MulticastFilter1 = 0x64,
- RxOctetsLow = 0x68,
- RxOctetsHigh = 0x6a,
- TxOctetsLow = 0x6c,
- TxOctetsHigh = 0x6e,
- TxFramesOK = 0x70,
- RxFramesOK = 0x72,
- StatsCarrierError = 0x74,
- StatsLateColl = 0x75,
- StatsMultiColl = 0x76,
- StatsOneColl = 0x77,
- StatsTxDefer = 0x78,
- RxMissed = 0x79,
- StatsTxXSDefer = 0x7a,
- StatsTxAbort = 0x7b,
- StatsBcastTx = 0x7c,
- StatsBcastRx = 0x7d,
- StatsMcastTx = 0x7e,
- StatsMcastRx = 0x7f,
- /* Aliased and bogus values! */
- RxStatus = 0x0c,
-};
-
-#define ASIC_HI_WORD(x) ((x) + 2)
-
-enum ASICCtrl_HiWord_bit {
- GlobalReset = 0x0001,
- RxReset = 0x0002,
- TxReset = 0x0004,
- DMAReset = 0x0008,
- FIFOReset = 0x0010,
- NetworkReset = 0x0020,
- HostReset = 0x0040,
- ResetBusy = 0x0400,
-};
-
-/* Bits in the interrupt status/mask registers. */
-enum intr_status_bits {
- IntrSummary=0x0001, IntrPCIErr=0x0002, IntrMACCtrl=0x0008,
- IntrTxDone=0x0004, IntrRxDone=0x0010, IntrRxStart=0x0020,
- IntrDrvRqst=0x0040,
- StatsMax=0x0080, LinkChange=0x0100,
- IntrTxDMADone=0x0200, IntrRxDMADone=0x0400,
-};
-
-/* Bits in the RxMode register. */
-enum rx_mode_bits {
- AcceptAllIPMulti=0x20, AcceptMultiHash=0x10, AcceptAll=0x08,
- AcceptBroadcast=0x04, AcceptMulticast=0x02, AcceptMyPhys=0x01,
-};
-/* Bits in MACCtrl. */
-enum mac_ctrl0_bits {
- EnbFullDuplex=0x20, EnbRcvLargeFrame=0x40,
- EnbFlowCtrl=0x100, EnbPassRxCRC=0x200,
-};
-enum mac_ctrl1_bits {
- StatsEnable=0x0020, StatsDisable=0x0040, StatsEnabled=0x0080,
- TxEnable=0x0100, TxDisable=0x0200, TxEnabled=0x0400,
- RxEnable=0x0800, RxDisable=0x1000, RxEnabled=0x2000,
-};
-
-/* The Rx and Tx buffer descriptors. */
-/* Note that using only 32 bit fields simplifies conversion to big-endian
- architectures. */
-struct netdev_desc {
- __le32 next_desc;
- __le32 status;
- struct desc_frag { __le32 addr, length; } frag[1];
-};
-
-/* Bits in netdev_desc.status */
-enum desc_status_bits {
- DescOwn=0x8000,
- DescEndPacket=0x4000,
- DescEndRing=0x2000,
- LastFrag=0x80000000,
- DescIntrOnTx=0x8000,
- DescIntrOnDMADone=0x80000000,
- DisableAlign = 0x00000001,
-};
-
-#define PRIV_ALIGN 15 /* Required alignment mask */
-/* Use __attribute__((aligned (L1_CACHE_BYTES))) to maintain alignment
- within the structure. */
-#define MII_CNT 4
-struct netdev_private {
- /* Descriptor rings first for alignment. */
- struct netdev_desc *rx_ring;
- struct netdev_desc *tx_ring;
- struct sk_buff* rx_skbuff[RX_RING_SIZE];
- struct sk_buff* tx_skbuff[TX_RING_SIZE];
- dma_addr_t tx_ring_dma;
- dma_addr_t rx_ring_dma;
- struct timer_list timer; /* Media monitoring timer. */
- /* ethtool extra stats */
- struct {
- u64 tx_multiple_collisions;
- u64 tx_single_collisions;
- u64 tx_late_collisions;
- u64 tx_deferred;
- u64 tx_deferred_excessive;
- u64 tx_aborted;
- u64 tx_bcasts;
- u64 rx_bcasts;
- u64 tx_mcasts;
- u64 rx_mcasts;
- } xstats;
- /* Frequently used values: keep some adjacent for cache effect. */
- spinlock_t lock;
- int msg_enable;
- int chip_id;
- unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */
- unsigned int rx_buf_sz; /* Based on MTU+slack. */
- struct netdev_desc *last_tx; /* Last Tx descriptor used. */
- unsigned int cur_tx, dirty_tx;
- /* These values are keep track of the transceiver/media in use. */
- unsigned int flowctrl:1;
- unsigned int default_port:4; /* Last dev->if_port value. */
- unsigned int an_enable:1;
- unsigned int speed;
- struct tasklet_struct rx_tasklet;
- struct tasklet_struct tx_tasklet;
- int budget;
- int cur_task;
- /* Multicast and receive mode. */
- spinlock_t mcastlock; /* SMP lock multicast updates. */
- u16 mcast_filter[4];
- /* MII transceiver section. */
- struct mii_if_info mii_if;
- int mii_preamble_required;
- unsigned char phys[MII_CNT]; /* MII device addresses, only first one used. */
- struct pci_dev *pci_dev;
- void __iomem *base;
- spinlock_t statlock;
-};
-
-/* The station address location in the EEPROM. */
-#define EEPROM_SA_OFFSET 0x10
-#define DEFAULT_INTR (IntrRxDMADone | IntrPCIErr | \
- IntrDrvRqst | IntrTxDone | StatsMax | \
- LinkChange)
-
-static int change_mtu(struct net_device *dev, int new_mtu);
-static int eeprom_read(void __iomem *ioaddr, int location);
-static int mdio_read(struct net_device *dev, int phy_id, int location);
-static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
-static int mdio_wait_link(struct net_device *dev, int wait);
-static int netdev_open(struct net_device *dev);
-static void check_duplex(struct net_device *dev);
-static void netdev_timer(unsigned long data);
-static void tx_timeout(struct net_device *dev);
-static void init_ring(struct net_device *dev);
-static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev);
-static int reset_tx (struct net_device *dev);
-static irqreturn_t intr_handler(int irq, void *dev_instance);
-static void rx_poll(unsigned long data);
-static void tx_poll(unsigned long data);
-static void refill_rx (struct net_device *dev);
-static void netdev_error(struct net_device *dev, int intr_status);
-static void netdev_error(struct net_device *dev, int intr_status);
-static void set_rx_mode(struct net_device *dev);
-static int __set_mac_addr(struct net_device *dev);
-static int sundance_set_mac_addr(struct net_device *dev, void *data);
-static struct net_device_stats *get_stats(struct net_device *dev);
-static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static int netdev_close(struct net_device *dev);
-static const struct ethtool_ops ethtool_ops;
-
-static void sundance_reset(struct net_device *dev, unsigned long reset_cmd)
-{
- struct netdev_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->base + ASICCtrl;
- int countdown;
-
- /* ST201 documentation states ASICCtrl is a 32bit register */
- iowrite32 (reset_cmd | ioread32 (ioaddr), ioaddr);
- /* ST201 documentation states reset can take up to 1 ms */
- countdown = 10 + 1;
- while (ioread32 (ioaddr) & (ResetBusy << 16)) {
- if (--countdown == 0) {
- printk(KERN_WARNING "%s : reset not completed !!\n", dev->name);
- break;
- }
- udelay(100);
- }
-}
-
-static const struct net_device_ops netdev_ops = {
- .ndo_open = netdev_open,
- .ndo_stop = netdev_close,
- .ndo_start_xmit = start_tx,
- .ndo_get_stats = get_stats,
- .ndo_set_rx_mode = set_rx_mode,
- .ndo_do_ioctl = netdev_ioctl,
- .ndo_tx_timeout = tx_timeout,
- .ndo_change_mtu = change_mtu,
- .ndo_set_mac_address = sundance_set_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-static int __devinit sundance_probe1 (struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- struct net_device *dev;
- struct netdev_private *np;
- static int card_idx;
- int chip_idx = ent->driver_data;
- int irq;
- int i;
- void __iomem *ioaddr;
- u16 mii_ctl;
- void *ring_space;
- dma_addr_t ring_dma;
-#ifdef USE_IO_OPS
- int bar = 0;
-#else
- int bar = 1;
-#endif
- int phy, phy_end, phy_idx = 0;
-
-/* when built into the kernel, we only print version if device is found */
-#ifndef MODULE
- static int printed_version;
- if (!printed_version++)
- printk(version);
-#endif
-
- if (pci_enable_device(pdev))
- return -EIO;
- pci_set_master(pdev);
-
- irq = pdev->irq;
-
- dev = alloc_etherdev(sizeof(*np));
- if (!dev)
- return -ENOMEM;
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- if (pci_request_regions(pdev, DRV_NAME))
- goto err_out_netdev;
-
- ioaddr = pci_iomap(pdev, bar, netdev_io_size);
- if (!ioaddr)
- goto err_out_res;
-
- for (i = 0; i < 3; i++)
- ((__le16 *)dev->dev_addr)[i] =
- cpu_to_le16(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));
- memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-
- dev->base_addr = (unsigned long)ioaddr;
- dev->irq = irq;
-
- np = netdev_priv(dev);
- np->base = ioaddr;
- np->pci_dev = pdev;
- np->chip_id = chip_idx;
- np->msg_enable = (1 << debug) - 1;
- spin_lock_init(&np->lock);
- spin_lock_init(&np->statlock);
- tasklet_init(&np->rx_tasklet, rx_poll, (unsigned long)dev);
- tasklet_init(&np->tx_tasklet, tx_poll, (unsigned long)dev);
-
- ring_space = dma_alloc_coherent(&pdev->dev, TX_TOTAL_SIZE,
- &ring_dma, GFP_KERNEL);
- if (!ring_space)
- goto err_out_cleardev;
- np->tx_ring = (struct netdev_desc *)ring_space;
- np->tx_ring_dma = ring_dma;
-
- ring_space = dma_alloc_coherent(&pdev->dev, RX_TOTAL_SIZE,
- &ring_dma, GFP_KERNEL);
- if (!ring_space)
- goto err_out_unmap_tx;
- np->rx_ring = (struct netdev_desc *)ring_space;
- np->rx_ring_dma = ring_dma;
-
- np->mii_if.dev = dev;
- np->mii_if.mdio_read = mdio_read;
- np->mii_if.mdio_write = mdio_write;
- np->mii_if.phy_id_mask = 0x1f;
- np->mii_if.reg_num_mask = 0x1f;
-
- /* The chip-specific entries in the device structure. */
- dev->netdev_ops = &netdev_ops;
- SET_ETHTOOL_OPS(dev, &ethtool_ops);
- dev->watchdog_timeo = TX_TIMEOUT;
-
- pci_set_drvdata(pdev, dev);
-
- i = register_netdev(dev);
- if (i)
- goto err_out_unmap_rx;
-
- printk(KERN_INFO "%s: %s at %p, %pM, IRQ %d.\n",
- dev->name, pci_id_tbl[chip_idx].name, ioaddr,
- dev->dev_addr, irq);
-
- np->phys[0] = 1; /* Default setting */
- np->mii_preamble_required++;
-
- /*
- * It seems some phys doesn't deal well with address 0 being accessed
- * first
- */
- if (sundance_pci_tbl[np->chip_id].device == 0x0200) {
- phy = 0;
- phy_end = 31;
- } else {
- phy = 1;
- phy_end = 32; /* wraps to zero, due to 'phy & 0x1f' */
- }
- for (; phy <= phy_end && phy_idx < MII_CNT; phy++) {
- int phyx = phy & 0x1f;
- int mii_status = mdio_read(dev, phyx, MII_BMSR);
- if (mii_status != 0xffff && mii_status != 0x0000) {
- np->phys[phy_idx++] = phyx;
- np->mii_if.advertising = mdio_read(dev, phyx, MII_ADVERTISE);
- if ((mii_status & 0x0040) == 0)
- np->mii_preamble_required++;
- printk(KERN_INFO "%s: MII PHY found at address %d, status "
- "0x%4.4x advertising %4.4x.\n",
- dev->name, phyx, mii_status, np->mii_if.advertising);
- }
- }
- np->mii_preamble_required--;
-
- if (phy_idx == 0) {
- printk(KERN_INFO "%s: No MII transceiver found, aborting. ASIC status %x\n",
- dev->name, ioread32(ioaddr + ASICCtrl));
- goto err_out_unregister;
- }
-
- np->mii_if.phy_id = np->phys[0];
-
- /* Parse override configuration */
- np->an_enable = 1;
- if (card_idx < MAX_UNITS) {
- if (media[card_idx] != NULL) {
- np->an_enable = 0;
- if (strcmp (media[card_idx], "100mbps_fd") == 0 ||
- strcmp (media[card_idx], "4") == 0) {
- np->speed = 100;
- np->mii_if.full_duplex = 1;
- } else if (strcmp (media[card_idx], "100mbps_hd") == 0 ||
- strcmp (media[card_idx], "3") == 0) {
- np->speed = 100;
- np->mii_if.full_duplex = 0;
- } else if (strcmp (media[card_idx], "10mbps_fd") == 0 ||
- strcmp (media[card_idx], "2") == 0) {
- np->speed = 10;
- np->mii_if.full_duplex = 1;
- } else if (strcmp (media[card_idx], "10mbps_hd") == 0 ||
- strcmp (media[card_idx], "1") == 0) {
- np->speed = 10;
- np->mii_if.full_duplex = 0;
- } else {
- np->an_enable = 1;
- }
- }
- if (flowctrl == 1)
- np->flowctrl = 1;
- }
-
- /* Fibre PHY? */
- if (ioread32 (ioaddr + ASICCtrl) & 0x80) {
- /* Default 100Mbps Full */
- if (np->an_enable) {
- np->speed = 100;
- np->mii_if.full_duplex = 1;
- np->an_enable = 0;
- }
- }
- /* Reset PHY */
- mdio_write (dev, np->phys[0], MII_BMCR, BMCR_RESET);
- mdelay (300);
- /* If flow control enabled, we need to advertise it.*/
- if (np->flowctrl)
- mdio_write (dev, np->phys[0], MII_ADVERTISE, np->mii_if.advertising | 0x0400);
- mdio_write (dev, np->phys[0], MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART);
- /* Force media type */
- if (!np->an_enable) {
- mii_ctl = 0;
- mii_ctl |= (np->speed == 100) ? BMCR_SPEED100 : 0;
- mii_ctl |= (np->mii_if.full_duplex) ? BMCR_FULLDPLX : 0;
- mdio_write (dev, np->phys[0], MII_BMCR, mii_ctl);
- printk (KERN_INFO "Override speed=%d, %s duplex\n",
- np->speed, np->mii_if.full_duplex ? "Full" : "Half");
-
- }
-
- /* Perhaps move the reset here? */
- /* Reset the chip to erase previous misconfiguration. */
- if (netif_msg_hw(np))
- printk("ASIC Control is %x.\n", ioread32(ioaddr + ASICCtrl));
- sundance_reset(dev, 0x00ff << 16);
- if (netif_msg_hw(np))
- printk("ASIC Control is now %x.\n", ioread32(ioaddr + ASICCtrl));
-
- card_idx++;
- return 0;
-
-err_out_unregister:
- unregister_netdev(dev);
-err_out_unmap_rx:
- dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE,
- np->rx_ring, np->rx_ring_dma);
-err_out_unmap_tx:
- dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE,
- np->tx_ring, np->tx_ring_dma);
-err_out_cleardev:
- pci_set_drvdata(pdev, NULL);
- pci_iounmap(pdev, ioaddr);
-err_out_res:
- pci_release_regions(pdev);
-err_out_netdev:
- free_netdev (dev);
- return -ENODEV;
-}
-
-static int change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > 8191)) /* Set by RxDMAFrameLen */
- return -EINVAL;
- if (netif_running(dev))
- return -EBUSY;
- dev->mtu = new_mtu;
- return 0;
-}
-
-#define eeprom_delay(ee_addr) ioread32(ee_addr)
-/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. */
-static int __devinit eeprom_read(void __iomem *ioaddr, int location)
-{
- int boguscnt = 10000; /* Typical 1900 ticks. */
- iowrite16(0x0200 | (location & 0xff), ioaddr + EECtrl);
- do {
- eeprom_delay(ioaddr + EECtrl);
- if (! (ioread16(ioaddr + EECtrl) & 0x8000)) {
- return ioread16(ioaddr + EEData);
- }
- } while (--boguscnt > 0);
- return 0;
-}
-
-/* MII transceiver control section.
- Read and write the MII registers using software-generated serial
- MDIO protocol. See the MII specifications or DP83840A data sheet
- for details.
-
- The maximum data clock rate is 2.5 Mhz. The minimum timing is usually
- met by back-to-back 33Mhz PCI cycles. */
-#define mdio_delay() ioread8(mdio_addr)
-
-enum mii_reg_bits {
- MDIO_ShiftClk=0x0001, MDIO_Data=0x0002, MDIO_EnbOutput=0x0004,
-};
-#define MDIO_EnbIn (0)
-#define MDIO_WRITE0 (MDIO_EnbOutput)
-#define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput)
-
-/* Generate the preamble required for initial synchronization and
- a few older transceivers. */
-static void mdio_sync(void __iomem *mdio_addr)
-{
- int bits = 32;
-
- /* Establish sync by sending at least 32 logic ones. */
- while (--bits >= 0) {
- iowrite8(MDIO_WRITE1, mdio_addr);
- mdio_delay();
- iowrite8(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
- mdio_delay();
- }
-}
-
-static int mdio_read(struct net_device *dev, int phy_id, int location)
-{
- struct netdev_private *np = netdev_priv(dev);
- void __iomem *mdio_addr = np->base + MIICtrl;
- int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
- int i, retval = 0;
-
- if (np->mii_preamble_required)
- mdio_sync(mdio_addr);
-
- /* Shift the read command bits out. */
- for (i = 15; i >= 0; i--) {
- int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
-
- iowrite8(dataval, mdio_addr);
- mdio_delay();
- iowrite8(dataval | MDIO_ShiftClk, mdio_addr);
- mdio_delay();
- }
- /* Read the two transition, 16 data, and wire-idle bits. */
- for (i = 19; i > 0; i--) {
- iowrite8(MDIO_EnbIn, mdio_addr);
- mdio_delay();
- retval = (retval << 1) | ((ioread8(mdio_addr) & MDIO_Data) ? 1 : 0);
- iowrite8(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
- mdio_delay();
- }
- return (retval>>1) & 0xffff;
-}
-
-static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
-{
- struct netdev_private *np = netdev_priv(dev);
- void __iomem *mdio_addr = np->base + MIICtrl;
- int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
- int i;
-
- if (np->mii_preamble_required)
- mdio_sync(mdio_addr);
-
- /* Shift the command bits out. */
- for (i = 31; i >= 0; i--) {
- int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
-
- iowrite8(dataval, mdio_addr);
- mdio_delay();
- iowrite8(dataval | MDIO_ShiftClk, mdio_addr);
- mdio_delay();
- }
- /* Clear out extra bits. */
- for (i = 2; i > 0; i--) {
- iowrite8(MDIO_EnbIn, mdio_addr);
- mdio_delay();
- iowrite8(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
- mdio_delay();
- }
-}
-
-static int mdio_wait_link(struct net_device *dev, int wait)
-{
- int bmsr;
- int phy_id;
- struct netdev_private *np;
-
- np = netdev_priv(dev);
- phy_id = np->phys[0];
-
- do {
- bmsr = mdio_read(dev, phy_id, MII_BMSR);
- if (bmsr & 0x0004)
- return 0;
- mdelay(1);
- } while (--wait > 0);
- return -1;
-}
-
-static int netdev_open(struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->base;
- unsigned long flags;
- int i;
-
- /* Do we need to reset the chip??? */
-
- i = request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev);
- if (i)
- return i;
-
- if (netif_msg_ifup(np))
- printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
- dev->name, dev->irq);
- init_ring(dev);
-
- iowrite32(np->rx_ring_dma, ioaddr + RxListPtr);
- /* The Tx list pointer is written as packets are queued. */
-
- /* Initialize other registers. */
- __set_mac_addr(dev);
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
- iowrite16(dev->mtu + 18, ioaddr + MaxFrameSize);
-#else
- iowrite16(dev->mtu + 14, ioaddr + MaxFrameSize);
-#endif
- if (dev->mtu > 2047)
- iowrite32(ioread32(ioaddr + ASICCtrl) | 0x0C, ioaddr + ASICCtrl);
-
- /* Configure the PCI bus bursts and FIFO thresholds. */
-
- if (dev->if_port == 0)
- dev->if_port = np->default_port;
-
- spin_lock_init(&np->mcastlock);
-
- set_rx_mode(dev);
- iowrite16(0, ioaddr + IntrEnable);
- iowrite16(0, ioaddr + DownCounter);
- /* Set the chip to poll every N*320nsec. */
- iowrite8(100, ioaddr + RxDMAPollPeriod);
- iowrite8(127, ioaddr + TxDMAPollPeriod);
- /* Fix DFE-580TX packet drop issue */
- if (np->pci_dev->revision >= 0x14)
- iowrite8(0x01, ioaddr + DebugCtrl1);
- netif_start_queue(dev);
-
- spin_lock_irqsave(&np->lock, flags);
- reset_tx(dev);
- spin_unlock_irqrestore(&np->lock, flags);
-
- iowrite16 (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);
-
- if (netif_msg_ifup(np))
- printk(KERN_DEBUG "%s: Done netdev_open(), status: Rx %x Tx %x "
- "MAC Control %x, %4.4x %4.4x.\n",
- dev->name, ioread32(ioaddr + RxStatus), ioread8(ioaddr + TxStatus),
- ioread32(ioaddr + MACCtrl0),
- ioread16(ioaddr + MACCtrl1), ioread16(ioaddr + MACCtrl0));
-
- /* Set the timer to check for link beat. */
- init_timer(&np->timer);
- np->timer.expires = jiffies + 3*HZ;
- np->timer.data = (unsigned long)dev;
- np->timer.function = netdev_timer; /* timer handler */
- add_timer(&np->timer);
-
- /* Enable interrupts by setting the interrupt mask. */
- iowrite16(DEFAULT_INTR, ioaddr + IntrEnable);
-
- return 0;
-}
-
-static void check_duplex(struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->base;
- int mii_lpa = mdio_read(dev, np->phys[0], MII_LPA);
- int negotiated = mii_lpa & np->mii_if.advertising;
- int duplex;
-
- /* Force media */
- if (!np->an_enable || mii_lpa == 0xffff) {
- if (np->mii_if.full_duplex)
- iowrite16 (ioread16 (ioaddr + MACCtrl0) | EnbFullDuplex,
- ioaddr + MACCtrl0);
- return;
- }
-
- /* Autonegotiation */
- duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
- if (np->mii_if.full_duplex != duplex) {
- np->mii_if.full_duplex = duplex;
- if (netif_msg_link(np))
- printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d "
- "negotiated capability %4.4x.\n", dev->name,
- duplex ? "full" : "half", np->phys[0], negotiated);
- iowrite16(ioread16(ioaddr + MACCtrl0) | (duplex ? 0x20 : 0), ioaddr + MACCtrl0);
- }
-}
-
-static void netdev_timer(unsigned long data)
-{
- struct net_device *dev = (struct net_device *)data;
- struct netdev_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->base;
- int next_tick = 10*HZ;
-
- if (netif_msg_timer(np)) {
- printk(KERN_DEBUG "%s: Media selection timer tick, intr status %4.4x, "
- "Tx %x Rx %x.\n",
- dev->name, ioread16(ioaddr + IntrEnable),
- ioread8(ioaddr + TxStatus), ioread32(ioaddr + RxStatus));
- }
- check_duplex(dev);
- np->timer.expires = jiffies + next_tick;
- add_timer(&np->timer);
-}
-
-static void tx_timeout(struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->base;
- unsigned long flag;
-
- netif_stop_queue(dev);
- tasklet_disable(&np->tx_tasklet);
- iowrite16(0, ioaddr + IntrEnable);
- printk(KERN_WARNING "%s: Transmit timed out, TxStatus %2.2x "
- "TxFrameId %2.2x,"
- " resetting...\n", dev->name, ioread8(ioaddr + TxStatus),
- ioread8(ioaddr + TxFrameId));
-
- {
- int i;
- for (i=0; i<TX_RING_SIZE; i++) {
- printk(KERN_DEBUG "%02x %08llx %08x %08x(%02x) %08x %08x\n", i,
- (unsigned long long)(np->tx_ring_dma + i*sizeof(*np->tx_ring)),
- le32_to_cpu(np->tx_ring[i].next_desc),
- le32_to_cpu(np->tx_ring[i].status),
- (le32_to_cpu(np->tx_ring[i].status) >> 2) & 0xff,
- le32_to_cpu(np->tx_ring[i].frag[0].addr),
- le32_to_cpu(np->tx_ring[i].frag[0].length));
- }
- printk(KERN_DEBUG "TxListPtr=%08x netif_queue_stopped=%d\n",
- ioread32(np->base + TxListPtr),
- netif_queue_stopped(dev));
- printk(KERN_DEBUG "cur_tx=%d(%02x) dirty_tx=%d(%02x)\n",
- np->cur_tx, np->cur_tx % TX_RING_SIZE,
- np->dirty_tx, np->dirty_tx % TX_RING_SIZE);
- printk(KERN_DEBUG "cur_rx=%d dirty_rx=%d\n", np->cur_rx, np->dirty_rx);
- printk(KERN_DEBUG "cur_task=%d\n", np->cur_task);
- }
- spin_lock_irqsave(&np->lock, flag);
-
- /* Stop and restart the chip's Tx processes . */
- reset_tx(dev);
- spin_unlock_irqrestore(&np->lock, flag);
-
- dev->if_port = 0;
-
- dev->trans_start = jiffies; /* prevent tx timeout */
- dev->stats.tx_errors++;
- if (np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
- netif_wake_queue(dev);
- }
- iowrite16(DEFAULT_INTR, ioaddr + IntrEnable);
- tasklet_enable(&np->tx_tasklet);
-}
-
-
-/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void init_ring(struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- int i;
-
- np->cur_rx = np->cur_tx = 0;
- np->dirty_rx = np->dirty_tx = 0;
- np->cur_task = 0;
-
- np->rx_buf_sz = (dev->mtu <= 1520 ? PKT_BUF_SZ : dev->mtu + 16);
-
- /* Initialize all Rx descriptors. */
- for (i = 0; i < RX_RING_SIZE; i++) {
- np->rx_ring[i].next_desc = cpu_to_le32(np->rx_ring_dma +
- ((i+1)%RX_RING_SIZE)*sizeof(*np->rx_ring));
- np->rx_ring[i].status = 0;
- np->rx_ring[i].frag[0].length = 0;
- np->rx_skbuff[i] = NULL;
- }
-
- /* Fill in the Rx buffers. Handle allocation failure gracefully. */
- for (i = 0; i < RX_RING_SIZE; i++) {
- struct sk_buff *skb =
- netdev_alloc_skb(dev, np->rx_buf_sz + 2);
- np->rx_skbuff[i] = skb;
- if (skb == NULL)
- break;
- skb_reserve(skb, 2); /* 16 byte align the IP header. */
- np->rx_ring[i].frag[0].addr = cpu_to_le32(
- dma_map_single(&np->pci_dev->dev, skb->data,
- np->rx_buf_sz, DMA_FROM_DEVICE));
- if (dma_mapping_error(&np->pci_dev->dev,
- np->rx_ring[i].frag[0].addr)) {
- dev_kfree_skb(skb);
- np->rx_skbuff[i] = NULL;
- break;
- }
- np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag);
- }
- np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
-
- for (i = 0; i < TX_RING_SIZE; i++) {
- np->tx_skbuff[i] = NULL;
- np->tx_ring[i].status = 0;
- }
-}
-
-static void tx_poll (unsigned long data)
-{
- struct net_device *dev = (struct net_device *)data;
- struct netdev_private *np = netdev_priv(dev);
- unsigned head = np->cur_task % TX_RING_SIZE;
- struct netdev_desc *txdesc =
- &np->tx_ring[(np->cur_tx - 1) % TX_RING_SIZE];
-
- /* Chain the next pointer */
- for (; np->cur_tx - np->cur_task > 0; np->cur_task++) {
- int entry = np->cur_task % TX_RING_SIZE;
- txdesc = &np->tx_ring[entry];
- if (np->last_tx) {
- np->last_tx->next_desc = cpu_to_le32(np->tx_ring_dma +
- entry*sizeof(struct netdev_desc));
- }
- np->last_tx = txdesc;
- }
- /* Indicate the latest descriptor of tx ring */
- txdesc->status |= cpu_to_le32(DescIntrOnTx);
-
- if (ioread32 (np->base + TxListPtr) == 0)
- iowrite32 (np->tx_ring_dma + head * sizeof(struct netdev_desc),
- np->base + TxListPtr);
-}
-
-static netdev_tx_t
-start_tx (struct sk_buff *skb, struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- struct netdev_desc *txdesc;
- unsigned entry;
-
- /* Calculate the next Tx descriptor entry. */
- entry = np->cur_tx % TX_RING_SIZE;
- np->tx_skbuff[entry] = skb;
- txdesc = &np->tx_ring[entry];
-
- txdesc->next_desc = 0;
- txdesc->status = cpu_to_le32 ((entry << 2) | DisableAlign);
- txdesc->frag[0].addr = cpu_to_le32(dma_map_single(&np->pci_dev->dev,
- skb->data, skb->len, DMA_TO_DEVICE));
- if (dma_mapping_error(&np->pci_dev->dev,
- txdesc->frag[0].addr))
- goto drop_frame;
- txdesc->frag[0].length = cpu_to_le32 (skb->len | LastFrag);
-
- /* Increment cur_tx before tasklet_schedule() */
- np->cur_tx++;
- mb();
- /* Schedule a tx_poll() task */
- tasklet_schedule(&np->tx_tasklet);
-
- /* On some architectures: explicitly flush cache lines here. */
- if (np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 1 &&
- !netif_queue_stopped(dev)) {
- /* do nothing */
- } else {
- netif_stop_queue (dev);
- }
- if (netif_msg_tx_queued(np)) {
- printk (KERN_DEBUG
- "%s: Transmit frame #%d queued in slot %d.\n",
- dev->name, np->cur_tx, entry);
- }
- return NETDEV_TX_OK;
-
-drop_frame:
- dev_kfree_skb(skb);
- np->tx_skbuff[entry] = NULL;
- dev->stats.tx_dropped++;
- return NETDEV_TX_OK;
-}
-
-/* Reset hardware tx and free all of tx buffers */
-static int
-reset_tx (struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->base;
- struct sk_buff *skb;
- int i;
-
- /* Reset tx logic, TxListPtr will be cleaned */
- iowrite16 (TxDisable, ioaddr + MACCtrl1);
- sundance_reset(dev, (NetworkReset|FIFOReset|DMAReset|TxReset) << 16);
-
- /* free all tx skbuff */
- for (i = 0; i < TX_RING_SIZE; i++) {
- np->tx_ring[i].next_desc = 0;
-
- skb = np->tx_skbuff[i];
- if (skb) {
- dma_unmap_single(&np->pci_dev->dev,
- le32_to_cpu(np->tx_ring[i].frag[0].addr),
- skb->len, DMA_TO_DEVICE);
- dev_kfree_skb_any(skb);
- np->tx_skbuff[i] = NULL;
- dev->stats.tx_dropped++;
- }
- }
- np->cur_tx = np->dirty_tx = 0;
- np->cur_task = 0;
-
- np->last_tx = NULL;
- iowrite8(127, ioaddr + TxDMAPollPeriod);
-
- iowrite16 (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);
- return 0;
-}
-
-/* The interrupt handler cleans up after the Tx thread,
- and schedule a Rx thread work */
-static irqreturn_t intr_handler(int irq, void *dev_instance)
-{
- struct net_device *dev = (struct net_device *)dev_instance;
- struct netdev_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->base;
- int hw_frame_id;
- int tx_cnt;
- int tx_status;
- int handled = 0;
- int i;
-
-
- do {
- int intr_status = ioread16(ioaddr + IntrStatus);
- iowrite16(intr_status, ioaddr + IntrStatus);
-
- if (netif_msg_intr(np))
- printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n",
- dev->name, intr_status);
-
- if (!(intr_status & DEFAULT_INTR))
- break;
-
- handled = 1;
-
- if (intr_status & (IntrRxDMADone)) {
- iowrite16(DEFAULT_INTR & ~(IntrRxDone|IntrRxDMADone),
- ioaddr + IntrEnable);
- if (np->budget < 0)
- np->budget = RX_BUDGET;
- tasklet_schedule(&np->rx_tasklet);
- }
- if (intr_status & (IntrTxDone | IntrDrvRqst)) {
- tx_status = ioread16 (ioaddr + TxStatus);
- for (tx_cnt=32; tx_status & 0x80; --tx_cnt) {
- if (netif_msg_tx_done(np))
- printk
- ("%s: Transmit status is %2.2x.\n",
- dev->name, tx_status);
- if (tx_status & 0x1e) {
- if (netif_msg_tx_err(np))
- printk("%s: Transmit error status %4.4x.\n",
- dev->name, tx_status);
- dev->stats.tx_errors++;
- if (tx_status & 0x10)
- dev->stats.tx_fifo_errors++;
- if (tx_status & 0x08)
- dev->stats.collisions++;
- if (tx_status & 0x04)
- dev->stats.tx_fifo_errors++;
- if (tx_status & 0x02)
- dev->stats.tx_window_errors++;
-
- /*
- ** This reset has been verified on
- ** DFE-580TX boards ! phdm@macqel.be.
- */
- if (tx_status & 0x10) { /* TxUnderrun */
- /* Restart Tx FIFO and transmitter */
- sundance_reset(dev, (NetworkReset|FIFOReset|TxReset) << 16);
- /* No need to reset the Tx pointer here */
- }
- /* Restart the Tx. Need to make sure tx enabled */
- i = 10;
- do {
- iowrite16(ioread16(ioaddr + MACCtrl1) | TxEnable, ioaddr + MACCtrl1);
- if (ioread16(ioaddr + MACCtrl1) & TxEnabled)
- break;
- mdelay(1);
- } while (--i);
- }
- /* Yup, this is a documentation bug. It cost me *hours*. */
- iowrite16 (0, ioaddr + TxStatus);
- if (tx_cnt < 0) {
- iowrite32(5000, ioaddr + DownCounter);
- break;
- }
- tx_status = ioread16 (ioaddr + TxStatus);
- }
- hw_frame_id = (tx_status >> 8) & 0xff;
- } else {
- hw_frame_id = ioread8(ioaddr + TxFrameId);
- }
-
- if (np->pci_dev->revision >= 0x14) {
- spin_lock(&np->lock);
- for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
- int entry = np->dirty_tx % TX_RING_SIZE;
- struct sk_buff *skb;
- int sw_frame_id;
- sw_frame_id = (le32_to_cpu(
- np->tx_ring[entry].status) >> 2) & 0xff;
- if (sw_frame_id == hw_frame_id &&
- !(le32_to_cpu(np->tx_ring[entry].status)
- & 0x00010000))
- break;
- if (sw_frame_id == (hw_frame_id + 1) %
- TX_RING_SIZE)
- break;
- skb = np->tx_skbuff[entry];
- /* Free the original skb. */
- dma_unmap_single(&np->pci_dev->dev,
- le32_to_cpu(np->tx_ring[entry].frag[0].addr),
- skb->len, DMA_TO_DEVICE);
- dev_kfree_skb_irq (np->tx_skbuff[entry]);
- np->tx_skbuff[entry] = NULL;
- np->tx_ring[entry].frag[0].addr = 0;
- np->tx_ring[entry].frag[0].length = 0;
- }
- spin_unlock(&np->lock);
- } else {
- spin_lock(&np->lock);
- for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
- int entry = np->dirty_tx % TX_RING_SIZE;
- struct sk_buff *skb;
- if (!(le32_to_cpu(np->tx_ring[entry].status)
- & 0x00010000))
- break;
- skb = np->tx_skbuff[entry];
- /* Free the original skb. */
- dma_unmap_single(&np->pci_dev->dev,
- le32_to_cpu(np->tx_ring[entry].frag[0].addr),
- skb->len, DMA_TO_DEVICE);
- dev_kfree_skb_irq (np->tx_skbuff[entry]);
- np->tx_skbuff[entry] = NULL;
- np->tx_ring[entry].frag[0].addr = 0;
- np->tx_ring[entry].frag[0].length = 0;
- }
- spin_unlock(&np->lock);
- }
-
- if (netif_queue_stopped(dev) &&
- np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
- /* The ring is no longer full, clear busy flag. */
- netif_wake_queue (dev);
- }
- /* Abnormal error summary/uncommon events handlers. */
- if (intr_status & (IntrPCIErr | LinkChange | StatsMax))
- netdev_error(dev, intr_status);
- } while (0);
- if (netif_msg_intr(np))
- printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
- dev->name, ioread16(ioaddr + IntrStatus));
- return IRQ_RETVAL(handled);
-}
-
-static void rx_poll(unsigned long data)
-{
- struct net_device *dev = (struct net_device *)data;
- struct netdev_private *np = netdev_priv(dev);
- int entry = np->cur_rx % RX_RING_SIZE;
- int boguscnt = np->budget;
- void __iomem *ioaddr = np->base;
- int received = 0;
-
- /* If EOP is set on the next entry, it's a new packet. Send it up. */
- while (1) {
- struct netdev_desc *desc = &(np->rx_ring[entry]);
- u32 frame_status = le32_to_cpu(desc->status);
- int pkt_len;
-
- if (--boguscnt < 0) {
- goto not_done;
- }
- if (!(frame_status & DescOwn))
- break;
- pkt_len = frame_status & 0x1fff; /* Chip omits the CRC. */
- if (netif_msg_rx_status(np))
- printk(KERN_DEBUG " netdev_rx() status was %8.8x.\n",
- frame_status);
- if (frame_status & 0x001f4000) {
- /* There was a error. */
- if (netif_msg_rx_err(np))
- printk(KERN_DEBUG " netdev_rx() Rx error was %8.8x.\n",
- frame_status);
- dev->stats.rx_errors++;
- if (frame_status & 0x00100000)
- dev->stats.rx_length_errors++;
- if (frame_status & 0x00010000)
- dev->stats.rx_fifo_errors++;
- if (frame_status & 0x00060000)
- dev->stats.rx_frame_errors++;
- if (frame_status & 0x00080000)
- dev->stats.rx_crc_errors++;
- if (frame_status & 0x00100000) {
- printk(KERN_WARNING "%s: Oversized Ethernet frame,"
- " status %8.8x.\n",
- dev->name, frame_status);
- }
- } else {
- struct sk_buff *skb;
-#ifndef final_version
- if (netif_msg_rx_status(np))
- printk(KERN_DEBUG " netdev_rx() normal Rx pkt length %d"
- ", bogus_cnt %d.\n",
- pkt_len, boguscnt);
-#endif
- /* Check if the packet is long enough to accept without copying
- to a minimally-sized skbuff. */
- if (pkt_len < rx_copybreak &&
- (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
- skb_reserve(skb, 2); /* 16 byte align the IP header */
- dma_sync_single_for_cpu(&np->pci_dev->dev,
- le32_to_cpu(desc->frag[0].addr),
- np->rx_buf_sz, DMA_FROM_DEVICE);
- skb_copy_to_linear_data(skb, np->rx_skbuff[entry]->data, pkt_len);
- dma_sync_single_for_device(&np->pci_dev->dev,
- le32_to_cpu(desc->frag[0].addr),
- np->rx_buf_sz, DMA_FROM_DEVICE);
- skb_put(skb, pkt_len);
- } else {
- dma_unmap_single(&np->pci_dev->dev,
- le32_to_cpu(desc->frag[0].addr),
- np->rx_buf_sz, DMA_FROM_DEVICE);
- skb_put(skb = np->rx_skbuff[entry], pkt_len);
- np->rx_skbuff[entry] = NULL;
- }
- skb->protocol = eth_type_trans(skb, dev);
- /* Note: checksum -> skb->ip_summed = CHECKSUM_UNNECESSARY; */
- netif_rx(skb);
- }
- entry = (entry + 1) % RX_RING_SIZE;
- received++;
- }
- np->cur_rx = entry;
- refill_rx (dev);
- np->budget -= received;
- iowrite16(DEFAULT_INTR, ioaddr + IntrEnable);
- return;
-
-not_done:
- np->cur_rx = entry;
- refill_rx (dev);
- if (!received)
- received = 1;
- np->budget -= received;
- if (np->budget <= 0)
- np->budget = RX_BUDGET;
- tasklet_schedule(&np->rx_tasklet);
-}
-
-static void refill_rx (struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- int entry;
- int cnt = 0;
-
- /* Refill the Rx ring buffers. */
- for (;(np->cur_rx - np->dirty_rx + RX_RING_SIZE) % RX_RING_SIZE > 0;
- np->dirty_rx = (np->dirty_rx + 1) % RX_RING_SIZE) {
- struct sk_buff *skb;
- entry = np->dirty_rx % RX_RING_SIZE;
- if (np->rx_skbuff[entry] == NULL) {
- skb = netdev_alloc_skb(dev, np->rx_buf_sz + 2);
- np->rx_skbuff[entry] = skb;
- if (skb == NULL)
- break; /* Better luck next round. */
- skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
- np->rx_ring[entry].frag[0].addr = cpu_to_le32(
- dma_map_single(&np->pci_dev->dev, skb->data,
- np->rx_buf_sz, DMA_FROM_DEVICE));
- if (dma_mapping_error(&np->pci_dev->dev,
- np->rx_ring[entry].frag[0].addr)) {
- dev_kfree_skb_irq(skb);
- np->rx_skbuff[entry] = NULL;
- break;
- }
- }
- /* Perhaps we need not reset this field. */
- np->rx_ring[entry].frag[0].length =
- cpu_to_le32(np->rx_buf_sz | LastFrag);
- np->rx_ring[entry].status = 0;
- cnt++;
- }
-}
-static void netdev_error(struct net_device *dev, int intr_status)
-{
- struct netdev_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->base;
- u16 mii_ctl, mii_advertise, mii_lpa;
- int speed;
-
- if (intr_status & LinkChange) {
- if (mdio_wait_link(dev, 10) == 0) {
- printk(KERN_INFO "%s: Link up\n", dev->name);
- if (np->an_enable) {
- mii_advertise = mdio_read(dev, np->phys[0],
- MII_ADVERTISE);
- mii_lpa = mdio_read(dev, np->phys[0], MII_LPA);
- mii_advertise &= mii_lpa;
- printk(KERN_INFO "%s: Link changed: ",
- dev->name);
- if (mii_advertise & ADVERTISE_100FULL) {
- np->speed = 100;
- printk("100Mbps, full duplex\n");
- } else if (mii_advertise & ADVERTISE_100HALF) {
- np->speed = 100;
- printk("100Mbps, half duplex\n");
- } else if (mii_advertise & ADVERTISE_10FULL) {
- np->speed = 10;
- printk("10Mbps, full duplex\n");
- } else if (mii_advertise & ADVERTISE_10HALF) {
- np->speed = 10;
- printk("10Mbps, half duplex\n");
- } else
- printk("\n");
-
- } else {
- mii_ctl = mdio_read(dev, np->phys[0], MII_BMCR);
- speed = (mii_ctl & BMCR_SPEED100) ? 100 : 10;
- np->speed = speed;
- printk(KERN_INFO "%s: Link changed: %dMbps ,",
- dev->name, speed);
- printk("%s duplex.\n",
- (mii_ctl & BMCR_FULLDPLX) ?
- "full" : "half");
- }
- check_duplex(dev);
- if (np->flowctrl && np->mii_if.full_duplex) {
- iowrite16(ioread16(ioaddr + MulticastFilter1+2) | 0x0200,
- ioaddr + MulticastFilter1+2);
- iowrite16(ioread16(ioaddr + MACCtrl0) | EnbFlowCtrl,
- ioaddr + MACCtrl0);
- }
- netif_carrier_on(dev);
- } else {
- printk(KERN_INFO "%s: Link down\n", dev->name);
- netif_carrier_off(dev);
- }
- }
- if (intr_status & StatsMax) {
- get_stats(dev);
- }
- if (intr_status & IntrPCIErr) {
- printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
- dev->name, intr_status);
- /* We must do a global reset of DMA to continue. */
- }
-}
-
-static struct net_device_stats *get_stats(struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->base;
- unsigned long flags;
- u8 late_coll, single_coll, mult_coll;
-
- spin_lock_irqsave(&np->statlock, flags);
- /* The chip only need report frame silently dropped. */
- dev->stats.rx_missed_errors += ioread8(ioaddr + RxMissed);
- dev->stats.tx_packets += ioread16(ioaddr + TxFramesOK);
- dev->stats.rx_packets += ioread16(ioaddr + RxFramesOK);
- dev->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError);
-
- mult_coll = ioread8(ioaddr + StatsMultiColl);
- np->xstats.tx_multiple_collisions += mult_coll;
- single_coll = ioread8(ioaddr + StatsOneColl);
- np->xstats.tx_single_collisions += single_coll;
- late_coll = ioread8(ioaddr + StatsLateColl);
- np->xstats.tx_late_collisions += late_coll;
- dev->stats.collisions += mult_coll
- + single_coll
- + late_coll;
-
- np->xstats.tx_deferred += ioread8(ioaddr + StatsTxDefer);
- np->xstats.tx_deferred_excessive += ioread8(ioaddr + StatsTxXSDefer);
- np->xstats.tx_aborted += ioread8(ioaddr + StatsTxAbort);
- np->xstats.tx_bcasts += ioread8(ioaddr + StatsBcastTx);
- np->xstats.rx_bcasts += ioread8(ioaddr + StatsBcastRx);
- np->xstats.tx_mcasts += ioread8(ioaddr + StatsMcastTx);
- np->xstats.rx_mcasts += ioread8(ioaddr + StatsMcastRx);
-
- dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow);
- dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16;
- dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow);
- dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsHigh) << 16;
-
- spin_unlock_irqrestore(&np->statlock, flags);
-
- return &dev->stats;
-}
-
-static void set_rx_mode(struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->base;
- u16 mc_filter[4]; /* Multicast hash filter */
- u32 rx_mode;
- int i;
-
- if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
- memset(mc_filter, 0xff, sizeof(mc_filter));
- rx_mode = AcceptBroadcast | AcceptMulticast | AcceptAll | AcceptMyPhys;
- } else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
- (dev->flags & IFF_ALLMULTI)) {
- /* Too many to match, or accept all multicasts. */
- memset(mc_filter, 0xff, sizeof(mc_filter));
- rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
- } else if (!netdev_mc_empty(dev)) {
- struct netdev_hw_addr *ha;
- int bit;
- int index;
- int crc;
- memset (mc_filter, 0, sizeof (mc_filter));
- netdev_for_each_mc_addr(ha, dev) {
- crc = ether_crc_le(ETH_ALEN, ha->addr);
- for (index=0, bit=0; bit < 6; bit++, crc <<= 1)
- if (crc & 0x80000000) index |= 1 << bit;
- mc_filter[index/16] |= (1 << (index % 16));
- }
- rx_mode = AcceptBroadcast | AcceptMultiHash | AcceptMyPhys;
- } else {
- iowrite8(AcceptBroadcast | AcceptMyPhys, ioaddr + RxMode);
- return;
- }
- if (np->mii_if.full_duplex && np->flowctrl)
- mc_filter[3] |= 0x0200;
-
- for (i = 0; i < 4; i++)
- iowrite16(mc_filter[i], ioaddr + MulticastFilter0 + i*2);
- iowrite8(rx_mode, ioaddr + RxMode);
-}
-
-static int __set_mac_addr(struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- u16 addr16;
-
- addr16 = (dev->dev_addr[0] | (dev->dev_addr[1] << 8));
- iowrite16(addr16, np->base + StationAddr);
- addr16 = (dev->dev_addr[2] | (dev->dev_addr[3] << 8));
- iowrite16(addr16, np->base + StationAddr+2);
- addr16 = (dev->dev_addr[4] | (dev->dev_addr[5] << 8));
- iowrite16(addr16, np->base + StationAddr+4);
- return 0;
-}
-
-/* Invoked with rtnl_lock held */
-static int sundance_set_mac_addr(struct net_device *dev, void *data)
-{
- const struct sockaddr *addr = data;
-
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
- memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
- __set_mac_addr(dev);
-
- return 0;
-}
-
-static const struct {
- const char name[ETH_GSTRING_LEN];
-} sundance_stats[] = {
- { "tx_multiple_collisions" },
- { "tx_single_collisions" },
- { "tx_late_collisions" },
- { "tx_deferred" },
- { "tx_deferred_excessive" },
- { "tx_aborted" },
- { "tx_bcasts" },
- { "rx_bcasts" },
- { "tx_mcasts" },
- { "rx_mcasts" },
-};
-
-static int check_if_running(struct net_device *dev)
-{
- if (!netif_running(dev))
- return -EINVAL;
- return 0;
-}
-
-static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- struct netdev_private *np = netdev_priv(dev);
- strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, DRV_VERSION, sizeof(info->version));
- strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info));
-}
-
-static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
- struct netdev_private *np = netdev_priv(dev);
- spin_lock_irq(&np->lock);
- mii_ethtool_gset(&np->mii_if, ecmd);
- spin_unlock_irq(&np->lock);
- return 0;
-}
-
-static int set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
- struct netdev_private *np = netdev_priv(dev);
- int res;
- spin_lock_irq(&np->lock);
- res = mii_ethtool_sset(&np->mii_if, ecmd);
- spin_unlock_irq(&np->lock);
- return res;
-}
-
-static int nway_reset(struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- return mii_nway_restart(&np->mii_if);
-}
-
-static u32 get_link(struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- return mii_link_ok(&np->mii_if);
-}
-
-static u32 get_msglevel(struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- return np->msg_enable;
-}
-
-static void set_msglevel(struct net_device *dev, u32 val)
-{
- struct netdev_private *np = netdev_priv(dev);
- np->msg_enable = val;
-}
-
-static void get_strings(struct net_device *dev, u32 stringset,
- u8 *data)
-{
- if (stringset == ETH_SS_STATS)
- memcpy(data, sundance_stats, sizeof(sundance_stats));
-}
-
-static int get_sset_count(struct net_device *dev, int sset)
-{
- switch (sset) {
- case ETH_SS_STATS:
- return ARRAY_SIZE(sundance_stats);
- default:
- return -EOPNOTSUPP;
- }
-}
-
-static void get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *stats, u64 *data)
-{
- struct netdev_private *np = netdev_priv(dev);
- int i = 0;
-
- get_stats(dev);
- data[i++] = np->xstats.tx_multiple_collisions;
- data[i++] = np->xstats.tx_single_collisions;
- data[i++] = np->xstats.tx_late_collisions;
- data[i++] = np->xstats.tx_deferred;
- data[i++] = np->xstats.tx_deferred_excessive;
- data[i++] = np->xstats.tx_aborted;
- data[i++] = np->xstats.tx_bcasts;
- data[i++] = np->xstats.rx_bcasts;
- data[i++] = np->xstats.tx_mcasts;
- data[i++] = np->xstats.rx_mcasts;
-}
-
-static const struct ethtool_ops ethtool_ops = {
- .begin = check_if_running,
- .get_drvinfo = get_drvinfo,
- .get_settings = get_settings,
- .set_settings = set_settings,
- .nway_reset = nway_reset,
- .get_link = get_link,
- .get_msglevel = get_msglevel,
- .set_msglevel = set_msglevel,
- .get_strings = get_strings,
- .get_sset_count = get_sset_count,
- .get_ethtool_stats = get_ethtool_stats,
-};
-
-static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
- struct netdev_private *np = netdev_priv(dev);
- int rc;
-
- if (!netif_running(dev))
- return -EINVAL;
-
- spin_lock_irq(&np->lock);
- rc = generic_mii_ioctl(&np->mii_if, if_mii(rq), cmd, NULL);
- spin_unlock_irq(&np->lock);
-
- return rc;
-}
-
-static int netdev_close(struct net_device *dev)
-{
- struct netdev_private *np = netdev_priv(dev);
- void __iomem *ioaddr = np->base;
- struct sk_buff *skb;
- int i;
-
- /* Wait and kill tasklet */
- tasklet_kill(&np->rx_tasklet);
- tasklet_kill(&np->tx_tasklet);
- np->cur_tx = 0;
- np->dirty_tx = 0;
- np->cur_task = 0;
- np->last_tx = NULL;
-
- netif_stop_queue(dev);
-
- if (netif_msg_ifdown(np)) {
- printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %2.2x "
- "Rx %4.4x Int %2.2x.\n",
- dev->name, ioread8(ioaddr + TxStatus),
- ioread32(ioaddr + RxStatus), ioread16(ioaddr + IntrStatus));
- printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n",
- dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx);
- }
-
- /* Disable interrupts by clearing the interrupt mask. */
- iowrite16(0x0000, ioaddr + IntrEnable);
-
- /* Disable Rx and Tx DMA for safely release resource */
- iowrite32(0x500, ioaddr + DMACtrl);
-
- /* Stop the chip's Tx and Rx processes. */
- iowrite16(TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl1);
-
- for (i = 2000; i > 0; i--) {
- if ((ioread32(ioaddr + DMACtrl) & 0xc000) == 0)
- break;
- mdelay(1);
- }
-
- iowrite16(GlobalReset | DMAReset | FIFOReset | NetworkReset,
- ioaddr + ASIC_HI_WORD(ASICCtrl));
-
- for (i = 2000; i > 0; i--) {
- if ((ioread16(ioaddr + ASIC_HI_WORD(ASICCtrl)) & ResetBusy) == 0)
- break;
- mdelay(1);
- }
-
-#ifdef __i386__
- if (netif_msg_hw(np)) {
- printk(KERN_DEBUG " Tx ring at %8.8x:\n",
- (int)(np->tx_ring_dma));
- for (i = 0; i < TX_RING_SIZE; i++)
- printk(KERN_DEBUG " #%d desc. %4.4x %8.8x %8.8x.\n",
- i, np->tx_ring[i].status, np->tx_ring[i].frag[0].addr,
- np->tx_ring[i].frag[0].length);
- printk(KERN_DEBUG " Rx ring %8.8x:\n",
- (int)(np->rx_ring_dma));
- for (i = 0; i < /*RX_RING_SIZE*/4 ; i++) {
- printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x\n",
- i, np->rx_ring[i].status, np->rx_ring[i].frag[0].addr,
- np->rx_ring[i].frag[0].length);
- }
- }
-#endif /* __i386__ debugging only */
-
- free_irq(dev->irq, dev);
-
- del_timer_sync(&np->timer);
-
- /* Free all the skbuffs in the Rx queue. */
- for (i = 0; i < RX_RING_SIZE; i++) {
- np->rx_ring[i].status = 0;
- skb = np->rx_skbuff[i];
- if (skb) {
- dma_unmap_single(&np->pci_dev->dev,
- le32_to_cpu(np->rx_ring[i].frag[0].addr),
- np->rx_buf_sz, DMA_FROM_DEVICE);
- dev_kfree_skb(skb);
- np->rx_skbuff[i] = NULL;
- }
- np->rx_ring[i].frag[0].addr = cpu_to_le32(0xBADF00D0); /* poison */
- }
- for (i = 0; i < TX_RING_SIZE; i++) {
- np->tx_ring[i].next_desc = 0;
- skb = np->tx_skbuff[i];
- if (skb) {
- dma_unmap_single(&np->pci_dev->dev,
- le32_to_cpu(np->tx_ring[i].frag[0].addr),
- skb->len, DMA_TO_DEVICE);
- dev_kfree_skb(skb);
- np->tx_skbuff[i] = NULL;
- }
- }
-
- return 0;
-}
-
-static void __devexit sundance_remove1 (struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
-
- if (dev) {
- struct netdev_private *np = netdev_priv(dev);
- unregister_netdev(dev);
- dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE,
- np->rx_ring, np->rx_ring_dma);
- dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE,
- np->tx_ring, np->tx_ring_dma);
- pci_iounmap(pdev, np->base);
- pci_release_regions(pdev);
- free_netdev(dev);
- pci_set_drvdata(pdev, NULL);
- }
-}
-
-#ifdef CONFIG_PM
-
-static int sundance_suspend(struct pci_dev *pci_dev, pm_message_t state)
-{
- struct net_device *dev = pci_get_drvdata(pci_dev);
-
- if (!netif_running(dev))
- return 0;
-
- netdev_close(dev);
- netif_device_detach(dev);
-
- pci_save_state(pci_dev);
- pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
-
- return 0;
-}
-
-static int sundance_resume(struct pci_dev *pci_dev)
-{
- struct net_device *dev = pci_get_drvdata(pci_dev);
- int err = 0;
-
- if (!netif_running(dev))
- return 0;
-
- pci_set_power_state(pci_dev, PCI_D0);
- pci_restore_state(pci_dev);
-
- err = netdev_open(dev);
- if (err) {
- printk(KERN_ERR "%s: Can't resume interface!\n",
- dev->name);
- goto out;
- }
-
- netif_device_attach(dev);
-
-out:
- return err;
-}
-
-#endif /* CONFIG_PM */
-
-static struct pci_driver sundance_driver = {
- .name = DRV_NAME,
- .id_table = sundance_pci_tbl,
- .probe = sundance_probe1,
- .remove = __devexit_p(sundance_remove1),
-#ifdef CONFIG_PM
- .suspend = sundance_suspend,
- .resume = sundance_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init sundance_init(void)
-{
-/* when a module, this is printed whether or not devices are found in probe */
-#ifdef MODULE
- printk(version);
-#endif
- return pci_register_driver(&sundance_driver);
-}
-
-static void __exit sundance_exit(void)
-{
- pci_unregister_driver(&sundance_driver);
-}
-
-module_init(sundance_init);
-module_exit(sundance_exit);
-
-