|
@@ -1,7 +1,7 @@
|
|
/* eth16i.c An ICL EtherTeam 16i and 32 EISA ethernet driver for Linux
|
|
/* eth16i.c An ICL EtherTeam 16i and 32 EISA ethernet driver for Linux
|
|
-
|
|
|
|
|
|
+
|
|
Written 1994-1999 by Mika Kuoppala
|
|
Written 1994-1999 by Mika Kuoppala
|
|
-
|
|
|
|
|
|
+
|
|
Copyright (C) 1994-1999 by Mika Kuoppala
|
|
Copyright (C) 1994-1999 by Mika Kuoppala
|
|
Based on skeleton.c and heavily on at1700.c by Donald Becker
|
|
Based on skeleton.c and heavily on at1700.c by Donald Becker
|
|
|
|
|
|
@@ -12,7 +12,7 @@
|
|
|
|
|
|
This driver supports following cards :
|
|
This driver supports following cards :
|
|
- ICL EtherTeam 16i
|
|
- ICL EtherTeam 16i
|
|
- - ICL EtherTeam 32 EISA
|
|
|
|
|
|
+ - ICL EtherTeam 32 EISA
|
|
(Uses true 32 bit transfers rather than 16i compability mode)
|
|
(Uses true 32 bit transfers rather than 16i compability mode)
|
|
|
|
|
|
Example Module usage:
|
|
Example Module usage:
|
|
@@ -25,26 +25,26 @@
|
|
|
|
|
|
I have benchmarked driver with PII/300Mhz as a ftp client
|
|
I have benchmarked driver with PII/300Mhz as a ftp client
|
|
and 486/33Mhz as a ftp server. Top speed was 1128.37 kilobytes/sec.
|
|
and 486/33Mhz as a ftp server. Top speed was 1128.37 kilobytes/sec.
|
|
-
|
|
|
|
|
|
+
|
|
Sources:
|
|
Sources:
|
|
- skeleton.c a sample network driver core for linux,
|
|
- skeleton.c a sample network driver core for linux,
|
|
written by Donald Becker <becker@scyld.com>
|
|
written by Donald Becker <becker@scyld.com>
|
|
- - at1700.c a driver for Allied Telesis AT1700, written
|
|
|
|
|
|
+ - at1700.c a driver for Allied Telesis AT1700, written
|
|
by Donald Becker.
|
|
by Donald Becker.
|
|
- e16iSRV.asm a Netware 3.X Server Driver for ICL EtherTeam16i
|
|
- e16iSRV.asm a Netware 3.X Server Driver for ICL EtherTeam16i
|
|
written by Markku Viima
|
|
written by Markku Viima
|
|
- The Fujitsu MB86965 databook.
|
|
- The Fujitsu MB86965 databook.
|
|
-
|
|
|
|
- Author thanks following persons due to their valueble assistance:
|
|
|
|
|
|
+
|
|
|
|
+ Author thanks following persons due to their valueble assistance:
|
|
Markku Viima (ICL)
|
|
Markku Viima (ICL)
|
|
- Ari Valve (ICL)
|
|
|
|
|
|
+ Ari Valve (ICL)
|
|
Donald Becker
|
|
Donald Becker
|
|
Kurt Huwig <kurt@huwig.de>
|
|
Kurt Huwig <kurt@huwig.de>
|
|
|
|
|
|
Revision history:
|
|
Revision history:
|
|
|
|
|
|
Version Date Description
|
|
Version Date Description
|
|
-
|
|
|
|
|
|
+
|
|
0.01 15.12-94 Initial version (card detection)
|
|
0.01 15.12-94 Initial version (card detection)
|
|
0.02 23.01-95 Interrupt is now hooked correctly
|
|
0.02 23.01-95 Interrupt is now hooked correctly
|
|
0.03 01.02-95 Rewrote initialization part
|
|
0.03 01.02-95 Rewrote initialization part
|
|
@@ -58,7 +58,7 @@
|
|
0.05 08.02-95 If there were more than one packet to send,
|
|
0.05 08.02-95 If there were more than one packet to send,
|
|
transmit was jammed due to invalid
|
|
transmit was jammed due to invalid
|
|
register write...now fixed
|
|
register write...now fixed
|
|
- 0.06 19.02-95 Rewrote interrupt handling
|
|
|
|
|
|
+ 0.06 19.02-95 Rewrote interrupt handling
|
|
0.07 13.04-95 Wrote EEPROM read routines
|
|
0.07 13.04-95 Wrote EEPROM read routines
|
|
Card configuration now set according to
|
|
Card configuration now set according to
|
|
data read from EEPROM
|
|
data read from EEPROM
|
|
@@ -66,34 +66,34 @@
|
|
port if AUTO is selected
|
|
port if AUTO is selected
|
|
|
|
|
|
0.09 01.09-95 Added module support
|
|
0.09 01.09-95 Added module support
|
|
-
|
|
|
|
|
|
+
|
|
0.10 04.09-95 Fixed receive packet allocation to work
|
|
0.10 04.09-95 Fixed receive packet allocation to work
|
|
with kernels > 1.3.x
|
|
with kernels > 1.3.x
|
|
-
|
|
|
|
- 0.20 20.09-95 Added support for EtherTeam32 EISA
|
|
|
|
|
|
|
|
- 0.21 17.10-95 Removed the unnecessary extern
|
|
|
|
|
|
+ 0.20 20.09-95 Added support for EtherTeam32 EISA
|
|
|
|
+
|
|
|
|
+ 0.21 17.10-95 Removed the unnecessary extern
|
|
init_etherdev() declaration. Some
|
|
init_etherdev() declaration. Some
|
|
other cleanups.
|
|
other cleanups.
|
|
-
|
|
|
|
|
|
+
|
|
0.22 22.02-96 Receive buffer was not flushed
|
|
0.22 22.02-96 Receive buffer was not flushed
|
|
correctly when faulty packet was
|
|
correctly when faulty packet was
|
|
received. Now fixed.
|
|
received. Now fixed.
|
|
|
|
|
|
- 0.23 26.02-96 Made resetting the adapter
|
|
|
|
|
|
+ 0.23 26.02-96 Made resetting the adapter
|
|
more reliable.
|
|
more reliable.
|
|
-
|
|
|
|
|
|
+
|
|
0.24 27.02-96 Rewrote faulty packet handling in eth16i_rx
|
|
0.24 27.02-96 Rewrote faulty packet handling in eth16i_rx
|
|
|
|
|
|
0.25 22.05-96 kfree() was missing from cleanup_module.
|
|
0.25 22.05-96 kfree() was missing from cleanup_module.
|
|
|
|
|
|
- 0.26 11.06-96 Sometimes card was not found by
|
|
|
|
|
|
+ 0.26 11.06-96 Sometimes card was not found by
|
|
check_signature(). Now made more reliable.
|
|
check_signature(). Now made more reliable.
|
|
-
|
|
|
|
- 0.27 23.06-96 Oops. 16 consecutive collisions halted
|
|
|
|
- adapter. Now will try to retransmit
|
|
|
|
|
|
+
|
|
|
|
+ 0.27 23.06-96 Oops. 16 consecutive collisions halted
|
|
|
|
+ adapter. Now will try to retransmit
|
|
MAX_COL_16 times before finally giving up.
|
|
MAX_COL_16 times before finally giving up.
|
|
-
|
|
|
|
|
|
+
|
|
0.28 28.10-97 Added dev_id parameter (NULL) for free_irq
|
|
0.28 28.10-97 Added dev_id parameter (NULL) for free_irq
|
|
|
|
|
|
0.29 29.10-97 Multiple card support for module users
|
|
0.29 29.10-97 Multiple card support for module users
|
|
@@ -103,16 +103,16 @@
|
|
|
|
|
|
0.30a 21.08-98 Card detection made more relaxed. Driver
|
|
0.30a 21.08-98 Card detection made more relaxed. Driver
|
|
had problems with some TCP/IP-PROM boots
|
|
had problems with some TCP/IP-PROM boots
|
|
- to find the card. Suggested by
|
|
|
|
|
|
+ to find the card. Suggested by
|
|
Kurt Huwig <kurt@huwig.de>
|
|
Kurt Huwig <kurt@huwig.de>
|
|
|
|
|
|
0.31 28.08-98 Media interface port can now be selected
|
|
0.31 28.08-98 Media interface port can now be selected
|
|
with module parameters or kernel
|
|
with module parameters or kernel
|
|
- boot parameters.
|
|
|
|
|
|
+ boot parameters.
|
|
|
|
|
|
- 0.32 31.08-98 IRQ was never freed if open/close
|
|
|
|
|
|
+ 0.32 31.08-98 IRQ was never freed if open/close
|
|
pair wasn't called. Now fixed.
|
|
pair wasn't called. Now fixed.
|
|
-
|
|
|
|
|
|
+
|
|
0.33 10.09-98 When eth16i_open() was called after
|
|
0.33 10.09-98 When eth16i_open() was called after
|
|
eth16i_close() chip never recovered.
|
|
eth16i_close() chip never recovered.
|
|
Now more shallow reset is made on
|
|
Now more shallow reset is made on
|
|
@@ -122,15 +122,15 @@
|
|
Changed ioaddr -> io for consistency
|
|
Changed ioaddr -> io for consistency
|
|
|
|
|
|
0.35 01.07-99 transmit,-receive bytes were never
|
|
0.35 01.07-99 transmit,-receive bytes were never
|
|
- updated in stats.
|
|
|
|
|
|
+ updated in stats.
|
|
|
|
|
|
Bugs:
|
|
Bugs:
|
|
- In some cases the media interface autoprobing code doesn't find
|
|
|
|
- the correct interface type. In this case you can
|
|
|
|
- manually choose the interface type in DOS with E16IC.EXE which is
|
|
|
|
|
|
+ In some cases the media interface autoprobing code doesn't find
|
|
|
|
+ the correct interface type. In this case you can
|
|
|
|
+ manually choose the interface type in DOS with E16IC.EXE which is
|
|
configuration software for EtherTeam16i and EtherTeam32 cards.
|
|
configuration software for EtherTeam16i and EtherTeam32 cards.
|
|
This is also true for IRQ setting. You cannot use module
|
|
This is also true for IRQ setting. You cannot use module
|
|
- parameter to configure IRQ of the card (yet).
|
|
|
|
|
|
+ parameter to configure IRQ of the card (yet).
|
|
|
|
|
|
To do:
|
|
To do:
|
|
- Real multicast support
|
|
- Real multicast support
|
|
@@ -142,18 +142,18 @@
|
|
irq without configuration utility.
|
|
irq without configuration utility.
|
|
*/
|
|
*/
|
|
|
|
|
|
-static char *version =
|
|
|
|
|
|
+static char *version =
|
|
"eth16i.c: v0.35 01-Jul-1999 Mika Kuoppala (miku@iki.fi)\n";
|
|
"eth16i.c: v0.35 01-Jul-1999 Mika Kuoppala (miku@iki.fi)\n";
|
|
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/kernel.h>
|
|
-#include <linux/types.h>
|
|
|
|
-#include <linux/fcntl.h>
|
|
|
|
-#include <linux/interrupt.h>
|
|
|
|
-#include <linux/ioport.h>
|
|
|
|
-#include <linux/in.h>
|
|
|
|
-#include <linux/slab.h>
|
|
|
|
-#include <linux/string.h>
|
|
|
|
|
|
+#include <linux/types.h>
|
|
|
|
+#include <linux/fcntl.h>
|
|
|
|
+#include <linux/interrupt.h>
|
|
|
|
+#include <linux/ioport.h>
|
|
|
|
+#include <linux/in.h>
|
|
|
|
+#include <linux/slab.h>
|
|
|
|
+#include <linux/string.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/init.h>
|
|
#include <linux/init.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/spinlock.h>
|
|
@@ -163,15 +163,15 @@ static char *version =
|
|
#include <linux/bitops.h>
|
|
#include <linux/bitops.h>
|
|
#include <linux/jiffies.h>
|
|
#include <linux/jiffies.h>
|
|
|
|
|
|
-#include <asm/system.h>
|
|
|
|
-#include <asm/io.h>
|
|
|
|
|
|
+#include <asm/system.h>
|
|
|
|
+#include <asm/io.h>
|
|
#include <asm/dma.h>
|
|
#include <asm/dma.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Few macros */
|
|
/* Few macros */
|
|
-#define BIT(a) ( (1 << (a)) )
|
|
|
|
-#define BITSET(ioaddr, bnum) ((outb(((inb(ioaddr)) | (bnum)), ioaddr)))
|
|
|
|
|
|
+#define BIT(a) ( (1 << (a)) )
|
|
|
|
+#define BITSET(ioaddr, bnum) ((outb(((inb(ioaddr)) | (bnum)), ioaddr)))
|
|
#define BITCLR(ioaddr, bnum) ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
|
|
#define BITCLR(ioaddr, bnum) ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
|
|
|
|
|
|
/* This is the I/O address space for Etherteam 16i adapter. */
|
|
/* This is the I/O address space for Etherteam 16i adapter. */
|
|
@@ -186,7 +186,7 @@ static char *version =
|
|
/* Some interrupt masks */
|
|
/* Some interrupt masks */
|
|
#define ETH16I_INTR_ON 0xef8a /* Higher is receive mask */
|
|
#define ETH16I_INTR_ON 0xef8a /* Higher is receive mask */
|
|
#define ETH16I_INTR_OFF 0x0000
|
|
#define ETH16I_INTR_OFF 0x0000
|
|
-
|
|
|
|
|
|
+
|
|
/* Buffers header status byte meanings */
|
|
/* Buffers header status byte meanings */
|
|
#define PKT_GOOD BIT(5)
|
|
#define PKT_GOOD BIT(5)
|
|
#define PKT_GOOD_RMT BIT(4)
|
|
#define PKT_GOOD_RMT BIT(4)
|
|
@@ -213,7 +213,7 @@ static char *version =
|
|
#define ALIGN_ERR BIT(2)
|
|
#define ALIGN_ERR BIT(2)
|
|
#define CRC_ERR BIT(1)
|
|
#define CRC_ERR BIT(1)
|
|
#define RX_BUF_OVERFLOW BIT(0)
|
|
#define RX_BUF_OVERFLOW BIT(0)
|
|
-
|
|
|
|
|
|
+
|
|
/* Transmit Interrupt Enable Register (DLCR2) */
|
|
/* Transmit Interrupt Enable Register (DLCR2) */
|
|
#define TX_INTR_REG 2
|
|
#define TX_INTR_REG 2
|
|
#define TX_INTR_DONE BIT(7)
|
|
#define TX_INTR_DONE BIT(7)
|
|
@@ -252,14 +252,14 @@ static char *version =
|
|
#define SRAM_CYCLE_TIME_100NS BIT(6)
|
|
#define SRAM_CYCLE_TIME_100NS BIT(6)
|
|
#define SYSTEM_BUS_WIDTH_8 BIT(5) /* 1 = 8bit, 0 = 16bit */
|
|
#define SYSTEM_BUS_WIDTH_8 BIT(5) /* 1 = 8bit, 0 = 16bit */
|
|
#define BUFFER_WIDTH_8 BIT(4) /* 1 = 8bit, 0 = 16bit */
|
|
#define BUFFER_WIDTH_8 BIT(4) /* 1 = 8bit, 0 = 16bit */
|
|
-#define TBS1 BIT(3)
|
|
|
|
|
|
+#define TBS1 BIT(3)
|
|
#define TBS0 BIT(2)
|
|
#define TBS0 BIT(2)
|
|
#define SRAM_BS1 BIT(1) /* 00=8kb, 01=16kb */
|
|
#define SRAM_BS1 BIT(1) /* 00=8kb, 01=16kb */
|
|
#define SRAM_BS0 BIT(0) /* 10=32kb, 11=64kb */
|
|
#define SRAM_BS0 BIT(0) /* 10=32kb, 11=64kb */
|
|
|
|
|
|
-#ifndef ETH16I_TX_BUF_SIZE /* 0 = 2kb, 1 = 4kb */
|
|
|
|
|
|
+#ifndef ETH16I_TX_BUF_SIZE /* 0 = 2kb, 1 = 4kb */
|
|
#define ETH16I_TX_BUF_SIZE 3 /* 2 = 8kb, 3 = 16kb */
|
|
#define ETH16I_TX_BUF_SIZE 3 /* 2 = 8kb, 3 = 16kb */
|
|
-#endif
|
|
|
|
|
|
+#endif
|
|
#define TX_BUF_1x2048 0
|
|
#define TX_BUF_1x2048 0
|
|
#define TX_BUF_2x2048 1
|
|
#define TX_BUF_2x2048 1
|
|
#define TX_BUF_2x4098 2
|
|
#define TX_BUF_2x4098 2
|
|
@@ -297,7 +297,7 @@ static char *version =
|
|
|
|
|
|
/* DMA Burst and Transceiver Mode Register (BMPR13) */
|
|
/* DMA Burst and Transceiver Mode Register (BMPR13) */
|
|
#define TRANSCEIVER_MODE_REG 13
|
|
#define TRANSCEIVER_MODE_REG 13
|
|
-#define TRANSCEIVER_MODE_RB 2
|
|
|
|
|
|
+#define TRANSCEIVER_MODE_RB 2
|
|
#define IO_BASE_UNLOCK BIT(7)
|
|
#define IO_BASE_UNLOCK BIT(7)
|
|
#define LOWER_SQUELCH_TRESH BIT(6)
|
|
#define LOWER_SQUELCH_TRESH BIT(6)
|
|
#define LINK_TEST_DISABLE BIT(5)
|
|
#define LINK_TEST_DISABLE BIT(5)
|
|
@@ -337,7 +337,7 @@ static char *version =
|
|
#define E_PORT_AUTO 0x03
|
|
#define E_PORT_AUTO 0x03
|
|
#define E_PORT_FROM_EPROM 0x04
|
|
#define E_PORT_FROM_EPROM 0x04
|
|
#define E_PRODUCT_CFG 0x30
|
|
#define E_PRODUCT_CFG 0x30
|
|
-
|
|
|
|
|
|
+
|
|
|
|
|
|
/* Macro to slow down io between EEPROM clock transitions */
|
|
/* Macro to slow down io between EEPROM clock transitions */
|
|
#define eeprom_slow_io() do { int _i = 40; while(--_i > 0) { inb(0x80); }}while(0)
|
|
#define eeprom_slow_io() do { int _i = 40; while(--_i > 0) { inb(0x80); }}while(0)
|
|
@@ -352,12 +352,12 @@ static char *version =
|
|
|
|
|
|
/* This is the I/O address list to be probed when seeking the card */
|
|
/* This is the I/O address list to be probed when seeking the card */
|
|
static unsigned int eth16i_portlist[] __initdata = {
|
|
static unsigned int eth16i_portlist[] __initdata = {
|
|
- 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
|
|
|
|
|
|
+ 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
|
|
};
|
|
};
|
|
|
|
|
|
-static unsigned int eth32i_portlist[] __initdata = {
|
|
|
|
|
|
+static unsigned int eth32i_portlist[] __initdata = {
|
|
0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000,
|
|
0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000,
|
|
- 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0
|
|
|
|
|
|
+ 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0
|
|
};
|
|
};
|
|
|
|
|
|
/* This is the Interrupt lookup table for Eth16i card */
|
|
/* This is the Interrupt lookup table for Eth16i card */
|
|
@@ -365,7 +365,7 @@ static unsigned int eth16i_irqmap[] __initdata = { 9, 10, 5, 15, 0 };
|
|
#define NUM_OF_ISA_IRQS 4
|
|
#define NUM_OF_ISA_IRQS 4
|
|
|
|
|
|
/* This is the Interrupt lookup table for Eth32i card */
|
|
/* This is the Interrupt lookup table for Eth32i card */
|
|
-static unsigned int eth32i_irqmap[] __initdata = { 3, 5, 7, 9, 10, 11, 12, 15, 0 };
|
|
|
|
|
|
+static unsigned int eth32i_irqmap[] __initdata = { 3, 5, 7, 9, 10, 11, 12, 15, 0 };
|
|
#define EISA_IRQ_REG 0xc89
|
|
#define EISA_IRQ_REG 0xc89
|
|
#define NUM_OF_EISA_IRQS 8
|
|
#define NUM_OF_EISA_IRQS 8
|
|
|
|
|
|
@@ -384,7 +384,7 @@ struct eth16i_local {
|
|
unsigned char tx_started;
|
|
unsigned char tx_started;
|
|
unsigned char tx_buf_busy;
|
|
unsigned char tx_buf_busy;
|
|
unsigned short tx_queue; /* Number of packets in transmit buffer */
|
|
unsigned short tx_queue; /* Number of packets in transmit buffer */
|
|
- unsigned short tx_queue_len;
|
|
|
|
|
|
+ unsigned short tx_queue_len;
|
|
unsigned int tx_buf_size;
|
|
unsigned int tx_buf_size;
|
|
unsigned long open_time;
|
|
unsigned long open_time;
|
|
unsigned long tx_buffered_packets;
|
|
unsigned long tx_buffered_packets;
|
|
@@ -414,7 +414,7 @@ static irqreturn_t eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
|
static void eth16i_reset(struct net_device *dev);
|
|
static void eth16i_reset(struct net_device *dev);
|
|
static void eth16i_timeout(struct net_device *dev);
|
|
static void eth16i_timeout(struct net_device *dev);
|
|
static void eth16i_skip_packet(struct net_device *dev);
|
|
static void eth16i_skip_packet(struct net_device *dev);
|
|
-static void eth16i_multicast(struct net_device *dev);
|
|
|
|
|
|
+static void eth16i_multicast(struct net_device *dev);
|
|
static void eth16i_select_regbank(unsigned char regbank, int ioaddr);
|
|
static void eth16i_select_regbank(unsigned char regbank, int ioaddr);
|
|
static void eth16i_initialize(struct net_device *dev, int boot);
|
|
static void eth16i_initialize(struct net_device *dev, int boot);
|
|
|
|
|
|
@@ -435,10 +435,10 @@ static int __init do_eth16i_probe(struct net_device *dev)
|
|
int i;
|
|
int i;
|
|
int ioaddr;
|
|
int ioaddr;
|
|
int base_addr = dev->base_addr;
|
|
int base_addr = dev->base_addr;
|
|
-
|
|
|
|
|
|
+
|
|
SET_MODULE_OWNER(dev);
|
|
SET_MODULE_OWNER(dev);
|
|
|
|
|
|
- if(eth16i_debug > 4)
|
|
|
|
|
|
+ if(eth16i_debug > 4)
|
|
printk(KERN_DEBUG "Probing started for %s\n", cardname);
|
|
printk(KERN_DEBUG "Probing started for %s\n", cardname);
|
|
|
|
|
|
if(base_addr > 0x1ff) /* Check only single location */
|
|
if(base_addr > 0x1ff) /* Check only single location */
|
|
@@ -492,14 +492,14 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
|
|
return -EBUSY;
|
|
return -EBUSY;
|
|
|
|
|
|
/*
|
|
/*
|
|
- The MB86985 chip has on register which holds information in which
|
|
|
|
|
|
+ The MB86985 chip has on register which holds information in which
|
|
io address the chip lies. First read this register and compare
|
|
io address the chip lies. First read this register and compare
|
|
it to our current io address and if match then this could
|
|
it to our current io address and if match then this could
|
|
be our chip.
|
|
be our chip.
|
|
*/
|
|
*/
|
|
|
|
|
|
if(ioaddr < 0x1000) {
|
|
if(ioaddr < 0x1000) {
|
|
- if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)]
|
|
|
|
|
|
+ if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)]
|
|
!= ioaddr) {
|
|
!= ioaddr) {
|
|
retval = -ENODEV;
|
|
retval = -ENODEV;
|
|
goto out;
|
|
goto out;
|
|
@@ -513,9 +513,9 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
- /*
|
|
|
|
|
|
+ /*
|
|
Now it seems that we have found a ethernet chip in this particular
|
|
Now it seems that we have found a ethernet chip in this particular
|
|
- ioaddr. The MB86985 chip has this feature, that when you read a
|
|
|
|
|
|
+ ioaddr. The MB86985 chip has this feature, that when you read a
|
|
certain register it will increase it's io base address to next
|
|
certain register it will increase it's io base address to next
|
|
configurable slot. Now when we have found the chip, first thing is
|
|
configurable slot. Now when we have found the chip, first thing is
|
|
to make sure that the chip's ioaddr will hold still here.
|
|
to make sure that the chip's ioaddr will hold still here.
|
|
@@ -536,7 +536,7 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
|
|
/* Try to obtain interrupt vector */
|
|
/* Try to obtain interrupt vector */
|
|
|
|
|
|
if ((retval = request_irq(dev->irq, (void *)ð16i_interrupt, 0, cardname, dev))) {
|
|
if ((retval = request_irq(dev->irq, (void *)ð16i_interrupt, 0, cardname, dev))) {
|
|
- printk(KERN_WARNING "%s at %#3x, but is unusable due to conflicting IRQ %d.\n",
|
|
|
|
|
|
+ printk(KERN_WARNING "%s at %#3x, but is unusable due to conflicting IRQ %d.\n",
|
|
cardname, ioaddr, dev->irq);
|
|
cardname, ioaddr, dev->irq);
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
@@ -547,7 +547,7 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
|
|
|
|
|
|
/* Now we will have to lock the chip's io address */
|
|
/* Now we will have to lock the chip's io address */
|
|
eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
|
|
eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
|
|
- outb(0x38, ioaddr + TRANSCEIVER_MODE_REG);
|
|
|
|
|
|
+ outb(0x38, ioaddr + TRANSCEIVER_MODE_REG);
|
|
|
|
|
|
eth16i_initialize(dev, 1); /* Initialize rest of the chip's registers */
|
|
eth16i_initialize(dev, 1); /* Initialize rest of the chip's registers */
|
|
|
|
|
|
@@ -590,7 +590,7 @@ static void eth16i_initialize(struct net_device *dev, int boot)
|
|
((unsigned short *)dev->dev_addr)[i] = ntohs(node_val);
|
|
((unsigned short *)dev->dev_addr)[i] = ntohs(node_val);
|
|
}
|
|
}
|
|
|
|
|
|
- for(i = 0; i < 6; i++) {
|
|
|
|
|
|
+ for(i = 0; i < 6; i++) {
|
|
outb( ((unsigned char *)dev->dev_addr)[i], ioaddr + NODE_ID_0 + i);
|
|
outb( ((unsigned char *)dev->dev_addr)[i], ioaddr + NODE_ID_0 + i);
|
|
if(boot) {
|
|
if(boot) {
|
|
printk("%02x", inb(ioaddr + NODE_ID_0 + i));
|
|
printk("%02x", inb(ioaddr + NODE_ID_0 + i));
|
|
@@ -601,11 +601,11 @@ static void eth16i_initialize(struct net_device *dev, int boot)
|
|
|
|
|
|
/* Now we will set multicast addresses to accept none */
|
|
/* Now we will set multicast addresses to accept none */
|
|
eth16i_select_regbank(HASH_TABLE_RB, ioaddr);
|
|
eth16i_select_regbank(HASH_TABLE_RB, ioaddr);
|
|
- for(i = 0; i < 8; i++)
|
|
|
|
|
|
+ for(i = 0; i < 8; i++)
|
|
outb(0x00, ioaddr + HASH_TABLE_0 + i);
|
|
outb(0x00, ioaddr + HASH_TABLE_0 + i);
|
|
|
|
|
|
/*
|
|
/*
|
|
- Now let's disable the transmitter and receiver, set the buffer ram
|
|
|
|
|
|
+ Now let's disable the transmitter and receiver, set the buffer ram
|
|
cycle time, bus width and buffer data path width. Also we shall
|
|
cycle time, bus width and buffer data path width. Also we shall
|
|
set transmit buffer size and total buffer size.
|
|
set transmit buffer size and total buffer size.
|
|
*/
|
|
*/
|
|
@@ -633,7 +633,7 @@ static void eth16i_initialize(struct net_device *dev, int boot)
|
|
#ifdef MODULE
|
|
#ifdef MODULE
|
|
/* if_port already set by init_module() */
|
|
/* if_port already set by init_module() */
|
|
#else
|
|
#else
|
|
- dev->if_port = (dev->mem_start < E_PORT_FROM_EPROM) ?
|
|
|
|
|
|
+ dev->if_port = (dev->mem_start < E_PORT_FROM_EPROM) ?
|
|
dev->mem_start : E_PORT_FROM_EPROM;
|
|
dev->mem_start : E_PORT_FROM_EPROM;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
@@ -651,7 +651,7 @@ static void eth16i_initialize(struct net_device *dev, int boot)
|
|
case E_PORT_AUTO:
|
|
case E_PORT_AUTO:
|
|
dev->if_port = eth16i_probe_port(ioaddr);
|
|
dev->if_port = eth16i_probe_port(ioaddr);
|
|
break;
|
|
break;
|
|
-
|
|
|
|
|
|
+
|
|
case E_PORT_BNC:
|
|
case E_PORT_BNC:
|
|
case E_PORT_TP:
|
|
case E_PORT_TP:
|
|
case E_PORT_DIX:
|
|
case E_PORT_DIX:
|
|
@@ -721,7 +721,7 @@ static int eth16i_probe_port(int ioaddr)
|
|
}
|
|
}
|
|
|
|
|
|
static void eth16i_set_port(int ioaddr, int porttype)
|
|
static void eth16i_set_port(int ioaddr, int porttype)
|
|
-{
|
|
|
|
|
|
+{
|
|
unsigned short temp = 0;
|
|
unsigned short temp = 0;
|
|
|
|
|
|
eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
|
|
eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
|
|
@@ -742,13 +742,13 @@ static void eth16i_set_port(int ioaddr, int porttype)
|
|
temp |= AUI_SELECT;
|
|
temp |= AUI_SELECT;
|
|
BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT);
|
|
BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT);
|
|
break;
|
|
break;
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
outb(temp, ioaddr + TRANSCEIVER_MODE_REG);
|
|
outb(temp, ioaddr + TRANSCEIVER_MODE_REG);
|
|
|
|
|
|
if(eth16i_debug > 1) {
|
|
if(eth16i_debug > 1) {
|
|
printk(KERN_DEBUG "TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG));
|
|
printk(KERN_DEBUG "TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG));
|
|
- printk(KERN_DEBUG "TRANSCEIVER_MODE_REG = %x\n",
|
|
|
|
|
|
+ printk(KERN_DEBUG "TRANSCEIVER_MODE_REG = %x\n",
|
|
inb(ioaddr+TRANSCEIVER_MODE_REG));
|
|
inb(ioaddr+TRANSCEIVER_MODE_REG));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -760,10 +760,10 @@ static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l)
|
|
outb(0xff, ioaddr + TX_STATUS_REG);
|
|
outb(0xff, ioaddr + TX_STATUS_REG);
|
|
|
|
|
|
outw(l, ioaddr + DATAPORT);
|
|
outw(l, ioaddr + DATAPORT);
|
|
- outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);
|
|
|
|
|
|
+ outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);
|
|
|
|
|
|
starttime = jiffies;
|
|
starttime = jiffies;
|
|
- outb(TX_START | 1, ioaddr + TRANSMIT_START_REG);
|
|
|
|
|
|
+ outb(TX_START | 1, ioaddr + TRANSMIT_START_REG);
|
|
|
|
|
|
while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) {
|
|
while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) {
|
|
if( time_after(jiffies, starttime + TX_TIMEOUT)) {
|
|
if( time_after(jiffies, starttime + TX_TIMEOUT)) {
|
|
@@ -815,10 +815,10 @@ static int eth16i_set_irq(struct net_device* dev)
|
|
const int irq = dev->irq;
|
|
const int irq = dev->irq;
|
|
int i = 0;
|
|
int i = 0;
|
|
|
|
|
|
- if(ioaddr < 0x1000) {
|
|
|
|
|
|
+ if(ioaddr < 0x1000) {
|
|
while(eth16i_irqmap[i] && eth16i_irqmap[i] != irq)
|
|
while(eth16i_irqmap[i] && eth16i_irqmap[i] != irq)
|
|
i++;
|
|
i++;
|
|
-
|
|
|
|
|
|
+
|
|
if(i < NUM_OF_ISA_IRQS) {
|
|
if(i < NUM_OF_ISA_IRQS) {
|
|
u8 cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
|
|
u8 cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
|
|
cbyte = (cbyte & 0x3F) | (i << 6);
|
|
cbyte = (cbyte & 0x3F) | (i << 6);
|
|
@@ -829,7 +829,7 @@ static int eth16i_set_irq(struct net_device* dev)
|
|
else {
|
|
else {
|
|
printk(KERN_NOTICE "%s: EISA Interrupt cannot be set. Use EISA Configuration utility.\n", dev->name);
|
|
printk(KERN_NOTICE "%s: EISA Interrupt cannot be set. Use EISA Configuration utility.\n", dev->name);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
}
|
|
}
|
|
@@ -863,7 +863,7 @@ static int __init eth16i_check_signature(int ioaddr)
|
|
creg[i] = inb(ioaddr + TRANSMIT_MODE_REG + i);
|
|
creg[i] = inb(ioaddr + TRANSMIT_MODE_REG + i);
|
|
|
|
|
|
if(eth16i_debug > 1)
|
|
if(eth16i_debug > 1)
|
|
- printk("eth16i: read signature byte %x at %x\n",
|
|
|
|
|
|
+ printk("eth16i: read signature byte %x at %x\n",
|
|
creg[i],
|
|
creg[i],
|
|
ioaddr + TRANSMIT_MODE_REG + i);
|
|
ioaddr + TRANSMIT_MODE_REG + i);
|
|
}
|
|
}
|
|
@@ -872,7 +872,7 @@ static int __init eth16i_check_signature(int ioaddr)
|
|
creg[2] &= 0x7F; /* Mask DCLEN bit */
|
|
creg[2] &= 0x7F; /* Mask DCLEN bit */
|
|
|
|
|
|
#if 0
|
|
#if 0
|
|
- /*
|
|
|
|
|
|
+ /*
|
|
This was removed because the card was sometimes left to state
|
|
This was removed because the card was sometimes left to state
|
|
from which it couldn't be find anymore. If there is need
|
|
from which it couldn't be find anymore. If there is need
|
|
to more strict check still this have to be fixed.
|
|
to more strict check still this have to be fixed.
|
|
@@ -886,14 +886,14 @@ static int __init eth16i_check_signature(int ioaddr)
|
|
if( !((creg[2] == 0x36) && (creg[3] == 0xE0)) ) {
|
|
if( !((creg[2] == 0x36) && (creg[3] == 0xE0)) ) {
|
|
creg[2] &= 0x40;
|
|
creg[2] &= 0x40;
|
|
creg[3] &= 0x03;
|
|
creg[3] &= 0x03;
|
|
-
|
|
|
|
|
|
+
|
|
if( !((creg[2] == 0x40) && (creg[3] == 0x00)) )
|
|
if( !((creg[2] == 0x40) && (creg[3] == 0x00)) )
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if(eth16i_read_eeprom(ioaddr, E_NODEID_0) != 0)
|
|
if(eth16i_read_eeprom(ioaddr, E_NODEID_0) != 0)
|
|
return -1;
|
|
return -1;
|
|
-
|
|
|
|
|
|
+
|
|
if((eth16i_read_eeprom(ioaddr, E_NODEID_1) & 0xFF00) != 0x4B00)
|
|
if((eth16i_read_eeprom(ioaddr, E_NODEID_1) & 0xFF00) != 0x4B00)
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
@@ -909,22 +909,22 @@ static int eth16i_read_eeprom(int ioaddr, int offset)
|
|
data = eth16i_read_eeprom_word(ioaddr);
|
|
data = eth16i_read_eeprom_word(ioaddr);
|
|
outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
|
|
outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
|
|
|
|
|
|
- return(data);
|
|
|
|
|
|
+ return(data);
|
|
}
|
|
}
|
|
|
|
|
|
static int eth16i_read_eeprom_word(int ioaddr)
|
|
static int eth16i_read_eeprom_word(int ioaddr)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|
|
int data = 0;
|
|
int data = 0;
|
|
-
|
|
|
|
|
|
+
|
|
for(i = 16; i > 0; i--) {
|
|
for(i = 16; i > 0; i--) {
|
|
outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
|
|
outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
|
|
eeprom_slow_io();
|
|
eeprom_slow_io();
|
|
outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
|
|
outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
|
|
eeprom_slow_io();
|
|
eeprom_slow_io();
|
|
- data = (data << 1) |
|
|
|
|
|
|
+ data = (data << 1) |
|
|
((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0);
|
|
((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0);
|
|
-
|
|
|
|
|
|
+
|
|
eeprom_slow_io();
|
|
eeprom_slow_io();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -948,25 +948,25 @@ static void eth16i_eeprom_cmd(int ioaddr, unsigned char command)
|
|
eeprom_slow_io();
|
|
eeprom_slow_io();
|
|
outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
|
|
outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
|
|
eeprom_slow_io();
|
|
eeprom_slow_io();
|
|
- }
|
|
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
static int eth16i_open(struct net_device *dev)
|
|
static int eth16i_open(struct net_device *dev)
|
|
{
|
|
{
|
|
struct eth16i_local *lp = netdev_priv(dev);
|
|
struct eth16i_local *lp = netdev_priv(dev);
|
|
int ioaddr = dev->base_addr;
|
|
int ioaddr = dev->base_addr;
|
|
-
|
|
|
|
|
|
+
|
|
/* Powerup the chip */
|
|
/* Powerup the chip */
|
|
outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
|
|
outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
|
|
|
|
|
|
/* Initialize the chip */
|
|
/* Initialize the chip */
|
|
- eth16i_initialize(dev, 0);
|
|
|
|
|
|
+ eth16i_initialize(dev, 0);
|
|
|
|
|
|
/* Set the transmit buffer size */
|
|
/* Set the transmit buffer size */
|
|
lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
|
|
lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
|
|
|
|
|
|
if(eth16i_debug > 0)
|
|
if(eth16i_debug > 0)
|
|
- printk(KERN_DEBUG "%s: transmit buffer size %d\n",
|
|
|
|
|
|
+ printk(KERN_DEBUG "%s: transmit buffer size %d\n",
|
|
dev->name, lp->tx_buf_size);
|
|
dev->name, lp->tx_buf_size);
|
|
|
|
|
|
/* Now enable Transmitter and Receiver sections */
|
|
/* Now enable Transmitter and Receiver sections */
|
|
@@ -981,7 +981,7 @@ static int eth16i_open(struct net_device *dev)
|
|
lp->tx_queue_len = 0;
|
|
lp->tx_queue_len = 0;
|
|
|
|
|
|
/* Turn on interrupts*/
|
|
/* Turn on interrupts*/
|
|
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
|
|
|
|
|
|
+ outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
|
|
|
|
|
|
netif_start_queue(dev);
|
|
netif_start_queue(dev);
|
|
return 0;
|
|
return 0;
|
|
@@ -995,10 +995,10 @@ static int eth16i_close(struct net_device *dev)
|
|
eth16i_reset(dev);
|
|
eth16i_reset(dev);
|
|
|
|
|
|
/* Turn off interrupts*/
|
|
/* Turn off interrupts*/
|
|
- outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
|
|
|
|
|
|
+ outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
|
|
|
|
|
|
netif_stop_queue(dev);
|
|
netif_stop_queue(dev);
|
|
-
|
|
|
|
|
|
+
|
|
lp->open_time = 0;
|
|
lp->open_time = 0;
|
|
|
|
|
|
/* Disable transmit and receive */
|
|
/* Disable transmit and receive */
|
|
@@ -1007,7 +1007,7 @@ static int eth16i_close(struct net_device *dev)
|
|
/* Reset the chip */
|
|
/* Reset the chip */
|
|
/* outb(0xff, ioaddr + RESET); */
|
|
/* outb(0xff, ioaddr + RESET); */
|
|
/* outw(0xffff, ioaddr + TX_STATUS_REG); */
|
|
/* outw(0xffff, ioaddr + TX_STATUS_REG); */
|
|
-
|
|
|
|
|
|
+
|
|
outb(0x00, ioaddr + CONFIG_REG_1);
|
|
outb(0x00, ioaddr + CONFIG_REG_1);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -1017,26 +1017,26 @@ static void eth16i_timeout(struct net_device *dev)
|
|
{
|
|
{
|
|
struct eth16i_local *lp = netdev_priv(dev);
|
|
struct eth16i_local *lp = netdev_priv(dev);
|
|
int ioaddr = dev->base_addr;
|
|
int ioaddr = dev->base_addr;
|
|
- /*
|
|
|
|
- If we get here, some higher level has decided that
|
|
|
|
- we are broken. There should really be a "kick me"
|
|
|
|
- function call instead.
|
|
|
|
|
|
+ /*
|
|
|
|
+ If we get here, some higher level has decided that
|
|
|
|
+ we are broken. There should really be a "kick me"
|
|
|
|
+ function call instead.
|
|
*/
|
|
*/
|
|
|
|
|
|
outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
|
|
outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
|
|
- printk(KERN_WARNING "%s: transmit timed out with status %04x, %s ?\n",
|
|
|
|
|
|
+ printk(KERN_WARNING "%s: transmit timed out with status %04x, %s ?\n",
|
|
dev->name,
|
|
dev->name,
|
|
- inw(ioaddr + TX_STATUS_REG), (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ?
|
|
|
|
|
|
+ inw(ioaddr + TX_STATUS_REG), (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ?
|
|
"IRQ conflict" : "network cable problem");
|
|
"IRQ conflict" : "network cable problem");
|
|
|
|
|
|
dev->trans_start = jiffies;
|
|
dev->trans_start = jiffies;
|
|
|
|
|
|
/* Let's dump all registers */
|
|
/* Let's dump all registers */
|
|
- if(eth16i_debug > 0) {
|
|
|
|
|
|
+ if(eth16i_debug > 0) {
|
|
printk(KERN_DEBUG "%s: timeout: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
|
|
printk(KERN_DEBUG "%s: timeout: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
|
|
- dev->name, inb(ioaddr + 0),
|
|
|
|
- inb(ioaddr + 1), inb(ioaddr + 2),
|
|
|
|
- inb(ioaddr + 3), inb(ioaddr + 4),
|
|
|
|
|
|
+ dev->name, inb(ioaddr + 0),
|
|
|
|
+ inb(ioaddr + 1), inb(ioaddr + 2),
|
|
|
|
+ inb(ioaddr + 3), inb(ioaddr + 4),
|
|
inb(ioaddr + 5),
|
|
inb(ioaddr + 5),
|
|
inb(ioaddr + 6), inb(ioaddr + 7));
|
|
inb(ioaddr + 6), inb(ioaddr + 7));
|
|
|
|
|
|
@@ -1071,31 +1071,31 @@ static int eth16i_tx(struct sk_buff *skb, struct net_device *dev)
|
|
buf = skb->data;
|
|
buf = skb->data;
|
|
|
|
|
|
netif_stop_queue(dev);
|
|
netif_stop_queue(dev);
|
|
-
|
|
|
|
|
|
+
|
|
/* Turn off TX interrupts */
|
|
/* Turn off TX interrupts */
|
|
outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
|
|
outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
|
|
-
|
|
|
|
|
|
+
|
|
/* We would be better doing the disable_irq tricks the 3c509 does,
|
|
/* We would be better doing the disable_irq tricks the 3c509 does,
|
|
that would make this suck a lot less */
|
|
that would make this suck a lot less */
|
|
-
|
|
|
|
|
|
+
|
|
spin_lock_irqsave(&lp->lock, flags);
|
|
spin_lock_irqsave(&lp->lock, flags);
|
|
|
|
|
|
if( (length + 2) > (lp->tx_buf_size - lp->tx_queue_len)) {
|
|
if( (length + 2) > (lp->tx_buf_size - lp->tx_queue_len)) {
|
|
- if(eth16i_debug > 0)
|
|
|
|
- printk(KERN_WARNING "%s: Transmit buffer full.\n", dev->name);
|
|
|
|
- }
|
|
|
|
|
|
+ if(eth16i_debug > 0)
|
|
|
|
+ printk(KERN_WARNING "%s: Transmit buffer full.\n", dev->name);
|
|
|
|
+ }
|
|
else {
|
|
else {
|
|
outw(length, ioaddr + DATAPORT);
|
|
outw(length, ioaddr + DATAPORT);
|
|
|
|
|
|
- if( ioaddr < 0x1000 )
|
|
|
|
|
|
+ if( ioaddr < 0x1000 )
|
|
outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
|
|
outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
|
|
else {
|
|
else {
|
|
unsigned char frag = length % 4;
|
|
unsigned char frag = length % 4;
|
|
outsl(ioaddr + DATAPORT, buf, length >> 2);
|
|
outsl(ioaddr + DATAPORT, buf, length >> 2);
|
|
if( frag != 0 ) {
|
|
if( frag != 0 ) {
|
|
outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1);
|
|
outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1);
|
|
- if( frag == 3 )
|
|
|
|
- outsw(ioaddr + DATAPORT,
|
|
|
|
|
|
+ if( frag == 3 )
|
|
|
|
+ outsw(ioaddr + DATAPORT,
|
|
(buf + (length & 0xFFFC) + 2), 1);
|
|
(buf + (length & 0xFFFC) + 2), 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1119,9 +1119,9 @@ static int eth16i_tx(struct sk_buff *skb, struct net_device *dev)
|
|
/* There is still more room for one more packet in tx buffer */
|
|
/* There is still more room for one more packet in tx buffer */
|
|
netif_wake_queue(dev);
|
|
netif_wake_queue(dev);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
spin_unlock_irqrestore(&lp->lock, flags);
|
|
spin_unlock_irqrestore(&lp->lock, flags);
|
|
-
|
|
|
|
|
|
+
|
|
outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
|
|
outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
|
|
/* Turn TX interrupts back on */
|
|
/* Turn TX interrupts back on */
|
|
/* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */
|
|
/* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */
|
|
@@ -1139,36 +1139,36 @@ static void eth16i_rx(struct net_device *dev)
|
|
/* Loop until all packets have been read */
|
|
/* Loop until all packets have been read */
|
|
while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) {
|
|
while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) {
|
|
|
|
|
|
- /* Read status byte from receive buffer */
|
|
|
|
|
|
+ /* Read status byte from receive buffer */
|
|
ushort status = inw(ioaddr + DATAPORT);
|
|
ushort status = inw(ioaddr + DATAPORT);
|
|
|
|
|
|
/* Get the size of the packet from receive buffer */
|
|
/* Get the size of the packet from receive buffer */
|
|
ushort pkt_len = inw(ioaddr + DATAPORT);
|
|
ushort pkt_len = inw(ioaddr + DATAPORT);
|
|
|
|
|
|
if(eth16i_debug > 4)
|
|
if(eth16i_debug > 4)
|
|
- printk(KERN_DEBUG "%s: Receiving packet mode %02x status %04x.\n",
|
|
|
|
- dev->name,
|
|
|
|
|
|
+ printk(KERN_DEBUG "%s: Receiving packet mode %02x status %04x.\n",
|
|
|
|
+ dev->name,
|
|
inb(ioaddr + RECEIVE_MODE_REG), status);
|
|
inb(ioaddr + RECEIVE_MODE_REG), status);
|
|
-
|
|
|
|
|
|
+
|
|
if( !(status & PKT_GOOD) ) {
|
|
if( !(status & PKT_GOOD) ) {
|
|
lp->stats.rx_errors++;
|
|
lp->stats.rx_errors++;
|
|
|
|
|
|
if( (pkt_len < ETH_ZLEN) || (pkt_len > ETH_FRAME_LEN) ) {
|
|
if( (pkt_len < ETH_ZLEN) || (pkt_len > ETH_FRAME_LEN) ) {
|
|
lp->stats.rx_length_errors++;
|
|
lp->stats.rx_length_errors++;
|
|
eth16i_reset(dev);
|
|
eth16i_reset(dev);
|
|
- return;
|
|
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
- else {
|
|
|
|
|
|
+ else {
|
|
eth16i_skip_packet(dev);
|
|
eth16i_skip_packet(dev);
|
|
lp->stats.rx_dropped++;
|
|
lp->stats.rx_dropped++;
|
|
- }
|
|
|
|
|
|
+ }
|
|
}
|
|
}
|
|
else { /* Ok so now we should have a good packet */
|
|
else { /* Ok so now we should have a good packet */
|
|
struct sk_buff *skb;
|
|
struct sk_buff *skb;
|
|
|
|
|
|
skb = dev_alloc_skb(pkt_len + 3);
|
|
skb = dev_alloc_skb(pkt_len + 3);
|
|
if( skb == NULL ) {
|
|
if( skb == NULL ) {
|
|
- printk(KERN_WARNING "%s: Could'n allocate memory for packet (len %d)\n",
|
|
|
|
|
|
+ printk(KERN_WARNING "%s: Could'n allocate memory for packet (len %d)\n",
|
|
dev->name, pkt_len);
|
|
dev->name, pkt_len);
|
|
eth16i_skip_packet(dev);
|
|
eth16i_skip_packet(dev);
|
|
lp->stats.rx_dropped++;
|
|
lp->stats.rx_dropped++;
|
|
@@ -1177,17 +1177,17 @@ static void eth16i_rx(struct net_device *dev)
|
|
|
|
|
|
skb->dev = dev;
|
|
skb->dev = dev;
|
|
skb_reserve(skb,2);
|
|
skb_reserve(skb,2);
|
|
-
|
|
|
|
- /*
|
|
|
|
|
|
+
|
|
|
|
+ /*
|
|
Now let's get the packet out of buffer.
|
|
Now let's get the packet out of buffer.
|
|
size is (pkt_len + 1) >> 1, cause we are now reading words
|
|
size is (pkt_len + 1) >> 1, cause we are now reading words
|
|
and it have to be even aligned.
|
|
and it have to be even aligned.
|
|
- */
|
|
|
|
-
|
|
|
|
- if(ioaddr < 0x1000)
|
|
|
|
- insw(ioaddr + DATAPORT, skb_put(skb, pkt_len),
|
|
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ if(ioaddr < 0x1000)
|
|
|
|
+ insw(ioaddr + DATAPORT, skb_put(skb, pkt_len),
|
|
(pkt_len + 1) >> 1);
|
|
(pkt_len + 1) >> 1);
|
|
- else {
|
|
|
|
|
|
+ else {
|
|
unsigned char *buf = skb_put(skb, pkt_len);
|
|
unsigned char *buf = skb_put(skb, pkt_len);
|
|
unsigned char frag = pkt_len % 4;
|
|
unsigned char frag = pkt_len % 4;
|
|
|
|
|
|
@@ -1207,9 +1207,9 @@ static void eth16i_rx(struct net_device *dev)
|
|
|
|
|
|
if( eth16i_debug > 5 ) {
|
|
if( eth16i_debug > 5 ) {
|
|
int i;
|
|
int i;
|
|
- printk(KERN_DEBUG "%s: Received packet of length %d.\n",
|
|
|
|
|
|
+ printk(KERN_DEBUG "%s: Received packet of length %d.\n",
|
|
dev->name, pkt_len);
|
|
dev->name, pkt_len);
|
|
- for(i = 0; i < 14; i++)
|
|
|
|
|
|
+ for(i = 0; i < 14; i++)
|
|
printk(KERN_DEBUG " %02x", skb->data[i]);
|
|
printk(KERN_DEBUG " %02x", skb->data[i]);
|
|
printk(KERN_DEBUG ".\n");
|
|
printk(KERN_DEBUG ".\n");
|
|
}
|
|
}
|
|
@@ -1255,7 +1255,7 @@ static irqreturn_t eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
|
|
|
|
|
lp->stats.rx_errors++;
|
|
lp->stats.rx_errors++;
|
|
|
|
|
|
- if(status & (BUS_RD_ERR << 8) )
|
|
|
|
|
|
+ if(status & (BUS_RD_ERR << 8) )
|
|
printk(KERN_WARNING "%s: Bus read error.\n",dev->name);
|
|
printk(KERN_WARNING "%s: Bus read error.\n",dev->name);
|
|
if(status & (SHORT_PKT_ERR << 8) ) lp->stats.rx_length_errors++;
|
|
if(status & (SHORT_PKT_ERR << 8) ) lp->stats.rx_length_errors++;
|
|
if(status & (ALIGN_ERR << 8) ) lp->stats.rx_frame_errors++;
|
|
if(status & (ALIGN_ERR << 8) ) lp->stats.rx_frame_errors++;
|
|
@@ -1269,14 +1269,14 @@ static irqreturn_t eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
|
if(status & CR_LOST) lp->stats.tx_carrier_errors++;
|
|
if(status & CR_LOST) lp->stats.tx_carrier_errors++;
|
|
if(status & TX_JABBER_ERR) lp->stats.tx_window_errors++;
|
|
if(status & TX_JABBER_ERR) lp->stats.tx_window_errors++;
|
|
|
|
|
|
-#if 0
|
|
|
|
|
|
+#if 0
|
|
if(status & COLLISION) {
|
|
if(status & COLLISION) {
|
|
- lp->stats.collisions +=
|
|
|
|
|
|
+ lp->stats.collisions +=
|
|
((inb(ioaddr+TRANSMIT_MODE_REG) & 0xF0) >> 4);
|
|
((inb(ioaddr+TRANSMIT_MODE_REG) & 0xF0) >> 4);
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
if(status & COLLISIONS_16) {
|
|
if(status & COLLISIONS_16) {
|
|
- if(lp->col_16 < MAX_COL_16) {
|
|
|
|
|
|
+ if(lp->col_16 < MAX_COL_16) {
|
|
lp->col_16++;
|
|
lp->col_16++;
|
|
lp->stats.collisions++;
|
|
lp->stats.collisions++;
|
|
/* Resume transmitting, skip failed packet */
|
|
/* Resume transmitting, skip failed packet */
|
|
@@ -1293,7 +1293,7 @@ static irqreturn_t eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
|
if(status & TX_DONE) { /* The transmit has been done */
|
|
if(status & TX_DONE) { /* The transmit has been done */
|
|
lp->stats.tx_packets = lp->tx_buffered_packets;
|
|
lp->stats.tx_packets = lp->tx_buffered_packets;
|
|
lp->stats.tx_bytes += lp->tx_buffered_bytes;
|
|
lp->stats.tx_bytes += lp->tx_buffered_bytes;
|
|
- lp->col_16 = 0;
|
|
|
|
|
|
+ lp->col_16 = 0;
|
|
|
|
|
|
if(lp->tx_queue) { /* Is there still packets ? */
|
|
if(lp->tx_queue) { /* Is there still packets ? */
|
|
/* There was packet(s) so start transmitting and write also
|
|
/* There was packet(s) so start transmitting and write also
|
|
@@ -1310,26 +1310,26 @@ static irqreturn_t eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if( ( status & 0x8000 ) ||
|
|
|
|
|
|
+ if( ( status & 0x8000 ) ||
|
|
( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) {
|
|
( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) {
|
|
eth16i_rx(dev); /* We have packet in receive buffer */
|
|
eth16i_rx(dev); /* We have packet in receive buffer */
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
/* Turn interrupts back on */
|
|
/* Turn interrupts back on */
|
|
outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
|
|
outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
|
|
-
|
|
|
|
|
|
+
|
|
if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) {
|
|
if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) {
|
|
/* There is still more room for one more packet in tx buffer */
|
|
/* There is still more room for one more packet in tx buffer */
|
|
netif_wake_queue(dev);
|
|
netif_wake_queue(dev);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
spin_unlock(&lp->lock);
|
|
spin_unlock(&lp->lock);
|
|
-
|
|
|
|
|
|
+
|
|
return IRQ_RETVAL(handled);
|
|
return IRQ_RETVAL(handled);
|
|
}
|
|
}
|
|
|
|
|
|
static void eth16i_skip_packet(struct net_device *dev)
|
|
static void eth16i_skip_packet(struct net_device *dev)
|
|
-{
|
|
|
|
|
|
+{
|
|
int ioaddr = dev->base_addr;
|
|
int ioaddr = dev->base_addr;
|
|
|
|
|
|
inw(ioaddr + DATAPORT);
|
|
inw(ioaddr + DATAPORT);
|
|
@@ -1345,28 +1345,28 @@ static void eth16i_reset(struct net_device *dev)
|
|
struct eth16i_local *lp = netdev_priv(dev);
|
|
struct eth16i_local *lp = netdev_priv(dev);
|
|
int ioaddr = dev->base_addr;
|
|
int ioaddr = dev->base_addr;
|
|
|
|
|
|
- if(eth16i_debug > 1)
|
|
|
|
|
|
+ if(eth16i_debug > 1)
|
|
printk(KERN_DEBUG "%s: Resetting device.\n", dev->name);
|
|
printk(KERN_DEBUG "%s: Resetting device.\n", dev->name);
|
|
|
|
|
|
BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
|
|
BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
|
|
- outw(0xffff, ioaddr + TX_STATUS_REG);
|
|
|
|
|
|
+ outw(0xffff, ioaddr + TX_STATUS_REG);
|
|
eth16i_select_regbank(2, ioaddr);
|
|
eth16i_select_regbank(2, ioaddr);
|
|
|
|
|
|
lp->tx_started = 0;
|
|
lp->tx_started = 0;
|
|
lp->tx_buf_busy = 0;
|
|
lp->tx_buf_busy = 0;
|
|
lp->tx_queue = 0;
|
|
lp->tx_queue = 0;
|
|
- lp->tx_queue_len = 0;
|
|
|
|
|
|
+ lp->tx_queue_len = 0;
|
|
BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
|
|
BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
|
|
}
|
|
}
|
|
|
|
|
|
static void eth16i_multicast(struct net_device *dev)
|
|
static void eth16i_multicast(struct net_device *dev)
|
|
{
|
|
{
|
|
int ioaddr = dev->base_addr;
|
|
int ioaddr = dev->base_addr;
|
|
-
|
|
|
|
- if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
|
|
|
|
|
|
+
|
|
|
|
+ if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
|
|
{
|
|
{
|
|
dev->flags|=IFF_PROMISC; /* Must do this */
|
|
dev->flags|=IFF_PROMISC; /* Must do this */
|
|
- outb(3, ioaddr + RECEIVE_MODE_REG);
|
|
|
|
|
|
+ outb(3, ioaddr + RECEIVE_MODE_REG);
|
|
} else {
|
|
} else {
|
|
outb(2, ioaddr + RECEIVE_MODE_REG);
|
|
outb(2, ioaddr + RECEIVE_MODE_REG);
|
|
}
|
|
}
|
|
@@ -1383,7 +1383,7 @@ static void eth16i_select_regbank(unsigned char banknbr, int ioaddr)
|
|
unsigned char data;
|
|
unsigned char data;
|
|
|
|
|
|
data = inb(ioaddr + CONFIG_REG_1);
|
|
data = inb(ioaddr + CONFIG_REG_1);
|
|
- outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1);
|
|
|
|
|
|
+ outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1);
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef MODULE
|
|
#ifdef MODULE
|
|
@@ -1392,7 +1392,7 @@ static ushort eth16i_parse_mediatype(const char* s)
|
|
{
|
|
{
|
|
if(!s)
|
|
if(!s)
|
|
return E_PORT_FROM_EPROM;
|
|
return E_PORT_FROM_EPROM;
|
|
-
|
|
|
|
|
|
+
|
|
if (!strncmp(s, "bnc", 3))
|
|
if (!strncmp(s, "bnc", 3))
|
|
return E_PORT_BNC;
|
|
return E_PORT_BNC;
|
|
else if (!strncmp(s, "tp", 2))
|
|
else if (!strncmp(s, "tp", 2))
|
|
@@ -1474,14 +1474,14 @@ int __init init_module(void)
|
|
return 0;
|
|
return 0;
|
|
return -ENXIO;
|
|
return -ENXIO;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
void cleanup_module(void)
|
|
void cleanup_module(void)
|
|
{
|
|
{
|
|
int this_dev;
|
|
int this_dev;
|
|
|
|
|
|
for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) {
|
|
for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) {
|
|
struct net_device *dev = dev_eth16i[this_dev];
|
|
struct net_device *dev = dev_eth16i[this_dev];
|
|
-
|
|
|
|
|
|
+
|
|
if(dev->priv) {
|
|
if(dev->priv) {
|
|
unregister_netdev(dev);
|
|
unregister_netdev(dev);
|
|
free_irq(dev->irq, dev);
|
|
free_irq(dev->irq, dev);
|