summaryrefslogtreecommitdiffstats
path: root/drivers/net/lance.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-04-29 21:13:14 +0000
committer <ralf@linux-mips.org>1997-04-29 21:13:14 +0000
commit19c9bba94152148523ba0f7ef7cffe3d45656b11 (patch)
tree40b1cb534496a7f1ca0f5c314a523c69f1fee464 /drivers/net/lance.c
parent7206675c40394c78a90e74812bbdbf8cf3cca1be (diff)
Import of Linux/MIPS 2.1.36
Diffstat (limited to 'drivers/net/lance.c')
-rw-r--r--drivers/net/lance.c70
1 files changed, 34 insertions, 36 deletions
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index 0c0f238ef..c1aa556d6 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -46,6 +46,7 @@ static const char *version = "lance.c:v1.09 Aug 20 1996 dplatt@3do.com, becker@c
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/bios32.h>
+#include <linux/init.h>
#include <asm/bitops.h>
#ifdef __mips__
#include <asm/bootinfo.h>
@@ -60,7 +61,7 @@ extern unsigned long port_base;
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-static unsigned int lance_portlist[] = {0x300, 0x320, 0x340, 0x360, 0};
+static unsigned int lance_portlist[] __initdata = {0x300, 0x320, 0x340, 0x360, 0};
void lance_probe1(int ioaddr);
#ifdef HAVE_DEVLIST
@@ -168,11 +169,13 @@ tx_full and tbusy flags.
/*
* Changes:
- * Thomas Bogendoerfer (tsbogend@bigbug.franken.de):
+ * Thomas Bogendoerfer (tsbogend@alpha.franken.de):
* - added support for Linux/Alpha, but removed most of it, because
* it worked only for the PCI chip.
* - added hook for the 32bit lance driver
* - added PCnetPCI II (79C970A) to chip table
+ * - made 32bit driver standalone
+ * - changed setting of autoselect bit
*
* Paul Gortmaker (gpg109@rsphy1.anu.edu.au):
* - hopefully fix above so Linux/Alpha can use ISA cards too.
@@ -240,7 +243,7 @@ struct lance_private {
int cur_rx, cur_tx; /* The next free ring entry */
int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
int dma;
- struct enet_statistics stats;
+ struct net_device_stats stats;
unsigned char chip_version; /* See lance_chip_type. */
char tx_full;
unsigned long lock;
@@ -251,6 +254,7 @@ struct lance_private {
#define LANCE_MUST_REINIT_RING 0x00000004
#define LANCE_MUST_UNRESET 0x00000008
#define LANCE_HAS_MISSED_FRAME 0x00000010
+#define PCNET32_POSSIBLE 0x00000020
/* A mapping from the chip ID number to the part number and features.
These are from the datasheets -- in real life the '970 version
@@ -270,15 +274,15 @@ static struct lance_chip_type {
LANCE_HAS_MISSED_FRAME},
{0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
- LANCE_HAS_MISSED_FRAME},
+ LANCE_HAS_MISSED_FRAME + PCNET32_POSSIBLE},
/* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so just call
it the PCnet32. */
{0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
- LANCE_HAS_MISSED_FRAME},
+ LANCE_HAS_MISSED_FRAME + PCNET32_POSSIBLE},
{0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
- LANCE_HAS_MISSED_FRAME},
+ LANCE_HAS_MISSED_FRAME + PCNET32_POSSIBLE},
{0x0, "PCnet (unknown)",
LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
LANCE_HAS_MISSED_FRAME},
@@ -300,7 +304,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct device *dev);
static int lance_rx(struct device *dev);
static void lance_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static int lance_close(struct device *dev);
-static struct enet_statistics *lance_get_stats(struct device *dev);
+static struct net_device_stats *lance_get_stats(struct device *dev);
static void set_multicast_list(struct device *dev);
@@ -311,14 +315,14 @@ static void set_multicast_list(struct device *dev);
before the memory management system is started, and thus well before the
other probes. */
-int lance_init(void)
+__initfunc(int lance_init(void))
{
int *port;
- if (high_memory <= 16*1024*1024)
+ if (virt_to_bus(high_memory) <= 16*1024*1024)
lance_need_isa_bounce_buffers = 0;
-#if defined(CONFIG_PCI)
+#if defined(CONFIG_PCI) && !defined(CONFIG_PCNET32)
if (pcibios_present()) {
int pci_index;
if (lance_debug > 1)
@@ -392,7 +396,7 @@ int lance_init(void)
return 0;
}
-void lance_probe1(int ioaddr)
+__initfunc(void lance_probe1(int ioaddr))
{
struct device *dev;
struct lance_private *lp;
@@ -451,6 +455,15 @@ void lance_probe1(int ioaddr)
break;
}
}
+
+#ifdef CONFIG_PCNET32
+ /*
+ * if pcnet32 is configured and the chip is capable of 32bit mode
+ * leave the card alone
+ */
+ if (chip_table[lance_version].flags & PCNET32_POSSIBLE)
+ return;
+#endif
dev = init_etherdev(0, 0);
dev->open = lance_open_fail;
@@ -465,15 +478,6 @@ void lance_probe1(int ioaddr)
dev->base_addr = ioaddr;
request_region(ioaddr, LANCE_TOTAL_SIZE, chip_table[lance_version].name);
-#ifdef CONFIG_LANCE32
- /* look if it's a PCI or VLB chip */
- if (lance_version == PCNET_PCI || lance_version == PCNET_VLB || lance_version == PCNET_PCI_II) {
- extern void lance32_probe1 (struct device *dev, const char *chipname, int pci_irq_line);
-
- lance32_probe1 (dev, chipname, pci_irq_line);
- return;
- }
-#endif
/* Make certain the data structures used by the LANCE are aligned and DMAble. */
lp = (struct lance_private *)(((unsigned long)kmalloc(sizeof(*lp)+7,
GFP_DMA | GFP_KERNEL)+7) & ~7);
@@ -630,7 +634,8 @@ void lance_probe1(int ioaddr)
/* Turn on auto-select of media (10baseT or BNC) so that the user
can watch the LEDs even if the board isn't opened. */
outw(0x0002, ioaddr+LANCE_ADDR);
- outw(0x0002, ioaddr+LANCE_BUS_IF);
+ /* set autoselect and clean xmausel */
+ outw(inw(ioaddr+LANCE_BUS_IF) & 0xfffe | 0x0002, ioaddr+LANCE_BUS_IF);
}
if (lance_debug > 0 && did_version++ == 0)
@@ -687,7 +692,8 @@ lance_open(struct device *dev)
if (chip_table[lp->chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
/* This is 79C960-specific: Turn on auto-select of media (AUI, BNC). */
outw(0x0002, ioaddr+LANCE_ADDR);
- outw(0x0002, ioaddr+LANCE_BUS_IF);
+ /* set autoselect and clean xmausel */
+ outw(inw(ioaddr+LANCE_BUS_IF) & 0xfffe | 0x0002, ioaddr+LANCE_BUS_IF);
}
if (lance_debug > 1)
@@ -801,8 +807,7 @@ lance_restart(struct device *dev, unsigned int csr0_bits, int must_reinit)
outw(csr0_bits, dev->base_addr + LANCE_DATA);
}
-static int
-lance_start_xmit(struct sk_buff *skb, struct device *dev)
+static int lance_start_xmit(struct sk_buff *skb, struct device *dev)
{
struct lance_private *lp = (struct lance_private *)dev->priv;
int ioaddr = dev->base_addr;
@@ -844,14 +849,6 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
return 0;
}
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- if (skb->len <= 0)
- return 0;
-
if (lance_debug > 3) {
outw(0x0000, ioaddr+LANCE_ADDR);
printk("%s: lance_start_xmit() called, csr0 %4.4x.\n", dev->name,
@@ -905,7 +902,8 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
lp->tx_ring[entry].base = ((u32)virt_to_bus(skb->data) & 0xffffff) | 0x83000000;
}
lp->cur_tx++;
-
+ lp->stats.tx_bytes+=skb->len;
+
/* Trigger an immediate send poll. */
outw(0x0000, ioaddr+LANCE_ADDR);
outw(0x0048, ioaddr+LANCE_DATA);
@@ -1112,9 +1110,10 @@ lance_rx(struct device *dev)
eth_copy_and_sum(skb,
(unsigned char *)bus_to_virt((lp->rx_ring[entry].base & 0x00ffffff)),
pkt_len,0);
+ lp->stats.rx_bytes+=skb->len;
skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
lp->stats.rx_packets++;
+ netif_rx(skb);
}
}
/* The docs say that the buffer length isn't touched, but Andrew Boyd
@@ -1163,8 +1162,7 @@ lance_close(struct device *dev)
return 0;
}
-static struct enet_statistics *
-lance_get_stats(struct device *dev)
+static struct net_device_stats *lance_get_stats(struct device *dev)
{
struct lance_private *lp = (struct lance_private *)dev->priv;
short ioaddr = dev->base_addr;