Commit 1cf65f54 authored by Jeff Garzik's avatar Jeff Garzik

Merge pobox.com:/garz/repo/netdev-2.6/eepro

into pobox.com:/garz/repo/net-drivers-2.6
parents 2afb4304 d32c83bf
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
This is a compatibility hardware problem. This is a compatibility hardware problem.
Versions: Versions:
0.13b basic ethtool support (aris, 09/13/2004)
0.13a in memory shortage, drop packets also in board 0.13a in memory shortage, drop packets also in board
(Michael Westermann <mw@microdata-pos.de>, 07/30/2002) (Michael Westermann <mw@microdata-pos.de>, 07/30/2002)
0.13 irq sharing, rewrote probe function, fixed a nasty bug in 0.13 irq sharing, rewrote probe function, fixed a nasty bug in
...@@ -104,7 +105,7 @@ ...@@ -104,7 +105,7 @@
*/ */
static const char version[] = static const char version[] =
"eepro.c: v0.13 11/08/2001 aris@cathedrallabs.org\n"; "eepro.c: v0.13b 09/13/2004 aris@cathedrallabs.org\n";
#include <linux/module.h> #include <linux/module.h>
...@@ -146,19 +147,21 @@ static const char version[] = ...@@ -146,19 +147,21 @@ static const char version[] =
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/ethtool.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/dma.h> #include <asm/dma.h>
#define DRV_NAME "eepro" #define DRV_NAME "eepro"
#define DRV_VERSION "0.13b"
#define compat_dev_kfree_skb( skb, mode ) dev_kfree_skb( (skb) ) #define compat_dev_kfree_skb( skb, mode ) dev_kfree_skb( (skb) )
/* I had reports of looong delays with SLOW_DOWN defined as udelay(2) */ /* I had reports of looong delays with SLOW_DOWN defined as udelay(2) */
#define SLOW_DOWN inb(0x80) #define SLOW_DOWN inb(0x80)
/* udelay(2) */ /* udelay(2) */
#define compat_init_data __initdata #define compat_init_data __initdata
enum iftype { AUI=0, BNC=1, TPE=2 };
/* First, a few definitions that the brave might change. */ /* First, a few definitions that the brave might change. */
/* A zero-terminated list of I/O addresses to be probed. */ /* A zero-terminated list of I/O addresses to be probed. */
...@@ -214,6 +217,7 @@ struct eepro_local { ...@@ -214,6 +217,7 @@ struct eepro_local {
short rcv_lower_limit; short rcv_lower_limit;
short rcv_upper_limit; short rcv_upper_limit;
unsigned char eeprom_reg; unsigned char eeprom_reg;
unsigned short word[8];
}; };
/* The station (ethernet) address prefix, used for IDing the board. */ /* The station (ethernet) address prefix, used for IDing the board. */
...@@ -608,16 +612,22 @@ struct net_device * __init eepro_probe(int unit) ...@@ -608,16 +612,22 @@ struct net_device * __init eepro_probe(int unit)
} }
#endif #endif
static void __init printEEPROMInfo(short ioaddr, struct net_device *dev) static void __init printEEPROMInfo(struct net_device *dev)
{ {
struct eepro_local *lp = (struct eepro_local *)dev->priv;
int ioaddr = dev->base_addr;
unsigned short Word; unsigned short Word;
int i,j; int i,j;
for (i=0, j=ee_Checksum; i<ee_SIZE; i++) j = ee_Checksum;
j+=read_eeprom(ioaddr,i,dev); for (i = 0; i < 8; i++)
j += lp->word[i];
for ( ; i < ee_SIZE; i++)
j += read_eeprom(ioaddr, i, dev);
printk(KERN_DEBUG "Checksum: %#x\n",j&0xffff); printk(KERN_DEBUG "Checksum: %#x\n",j&0xffff);
Word=read_eeprom(ioaddr, 0, dev); Word = lp->word[0];
printk(KERN_DEBUG "Word0:\n"); printk(KERN_DEBUG "Word0:\n");
printk(KERN_DEBUG " Plug 'n Pray: %d\n",GetBit(Word,ee_PnP)); printk(KERN_DEBUG " Plug 'n Pray: %d\n",GetBit(Word,ee_PnP));
printk(KERN_DEBUG " Buswidth: %d\n",(GetBit(Word,ee_BusWidth)+1)*8 ); printk(KERN_DEBUG " Buswidth: %d\n",(GetBit(Word,ee_BusWidth)+1)*8 );
...@@ -625,7 +635,7 @@ static void __init printEEPROMInfo(short ioaddr, struct net_device *dev) ...@@ -625,7 +635,7 @@ static void __init printEEPROMInfo(short ioaddr, struct net_device *dev)
printk(KERN_DEBUG " IO Address: %#x\n", (Word>>ee_IO0)<<4); printk(KERN_DEBUG " IO Address: %#x\n", (Word>>ee_IO0)<<4);
if (net_debug>4) { if (net_debug>4) {
Word=read_eeprom(ioaddr, 1, dev); Word = lp->word[1];
printk(KERN_DEBUG "Word1:\n"); printk(KERN_DEBUG "Word1:\n");
printk(KERN_DEBUG " INT: %d\n", Word & ee_IntMask); printk(KERN_DEBUG " INT: %d\n", Word & ee_IntMask);
printk(KERN_DEBUG " LI: %d\n", GetBit(Word,ee_LI)); printk(KERN_DEBUG " LI: %d\n", GetBit(Word,ee_LI));
...@@ -636,7 +646,7 @@ static void __init printEEPROMInfo(short ioaddr, struct net_device *dev) ...@@ -636,7 +646,7 @@ static void __init printEEPROMInfo(short ioaddr, struct net_device *dev)
printk(KERN_DEBUG " Duplex: %d\n", GetBit(Word,ee_Duplex)); printk(KERN_DEBUG " Duplex: %d\n", GetBit(Word,ee_Duplex));
} }
Word=read_eeprom(ioaddr, 5, dev); Word = lp->word[5];
printk(KERN_DEBUG "Word5:\n"); printk(KERN_DEBUG "Word5:\n");
printk(KERN_DEBUG " BNC: %d\n",GetBit(Word,ee_BNC_TPE)); printk(KERN_DEBUG " BNC: %d\n",GetBit(Word,ee_BNC_TPE));
printk(KERN_DEBUG " NumConnectors: %d\n",GetBit(Word,ee_NumConn)); printk(KERN_DEBUG " NumConnectors: %d\n",GetBit(Word,ee_NumConn));
...@@ -646,12 +656,12 @@ static void __init printEEPROMInfo(short ioaddr, struct net_device *dev) ...@@ -646,12 +656,12 @@ static void __init printEEPROMInfo(short ioaddr, struct net_device *dev)
if (GetBit(Word,ee_PortAUI)) printk(KERN_DEBUG "AUI "); if (GetBit(Word,ee_PortAUI)) printk(KERN_DEBUG "AUI ");
printk(KERN_DEBUG "port(s) \n"); printk(KERN_DEBUG "port(s) \n");
Word=read_eeprom(ioaddr, 6, dev); Word = lp->word[6];
printk(KERN_DEBUG "Word6:\n"); printk(KERN_DEBUG "Word6:\n");
printk(KERN_DEBUG " Stepping: %d\n",Word & ee_StepMask); printk(KERN_DEBUG " Stepping: %d\n",Word & ee_StepMask);
printk(KERN_DEBUG " BoardID: %d\n",Word>>ee_BoardID); printk(KERN_DEBUG " BoardID: %d\n",Word>>ee_BoardID);
Word=read_eeprom(ioaddr, 7, dev); Word = lp->word[7];
printk(KERN_DEBUG "Word7:\n"); printk(KERN_DEBUG "Word7:\n");
printk(KERN_DEBUG " INT to IRQ:\n"); printk(KERN_DEBUG " INT to IRQ:\n");
...@@ -725,7 +735,7 @@ static void __init eepro_print_info (struct net_device *dev) ...@@ -725,7 +735,7 @@ static void __init eepro_print_info (struct net_device *dev)
printk(", %s.\n", ifmap[dev->if_port]); printk(", %s.\n", ifmap[dev->if_port]);
if (net_debug > 3) { if (net_debug > 3) {
i = read_eeprom(dev->base_addr, 5, dev); i = lp->word[5];
if (i & 0x2000) /* bit 13 of EEPROM word 5 */ if (i & 0x2000) /* bit 13 of EEPROM word 5 */
printk(KERN_DEBUG "%s: Concurrent Processing is " printk(KERN_DEBUG "%s: Concurrent Processing is "
"enabled but not used!\n", dev->name); "enabled but not used!\n", dev->name);
...@@ -733,19 +743,20 @@ static void __init eepro_print_info (struct net_device *dev) ...@@ -733,19 +743,20 @@ static void __init eepro_print_info (struct net_device *dev)
/* Check the station address for the manufacturer's code */ /* Check the station address for the manufacturer's code */
if (net_debug>3) if (net_debug>3)
printEEPROMInfo(dev->base_addr, dev); printEEPROMInfo(dev);
} }
static struct ethtool_ops eepro_ethtool_ops;
/* This is the real probe routine. Linux has a history of friendly device /* This is the real probe routine. Linux has a history of friendly device
probes on the ISA bus. A good device probe avoids doing writes, and probes on the ISA bus. A good device probe avoids doing writes, and
verifies that the correct device exists and functions. */ verifies that the correct device exists and functions. */
static int __init eepro_probe1(struct net_device *dev, int autoprobe) static int __init eepro_probe1(struct net_device *dev, int autoprobe)
{ {
unsigned short station_addr[6], id, counter; unsigned short station_addr[3], id, counter;
int i; int i;
struct eepro_local *lp; struct eepro_local *lp;
enum iftype { AUI=0, BNC=1, TPE=2 };
int ioaddr = dev->base_addr; int ioaddr = dev->base_addr;
/* Grab the region so we can find another board if autoIRQ fails. */ /* Grab the region so we can find another board if autoIRQ fails. */
...@@ -796,11 +807,16 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe) ...@@ -796,11 +807,16 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
lp->xmt_bar = XMT_BAR_10; lp->xmt_bar = XMT_BAR_10;
station_addr[0] = read_eeprom(ioaddr, 2, dev); station_addr[0] = read_eeprom(ioaddr, 2, dev);
} }
station_addr[1] = read_eeprom(ioaddr, 3, dev);
station_addr[2] = read_eeprom(ioaddr, 4, dev); /* get all words at once. will be used here and for ethtool */
for (i = 0; i < 8; i++) {
lp->word[i] = read_eeprom(ioaddr, i, dev);
}
station_addr[1] = lp->word[3];
station_addr[2] = lp->word[4];
if (!lp->eepro) { if (!lp->eepro) {
if (read_eeprom(ioaddr,7,dev)== ee_FX_INT2IRQ) if (lp->word[7] == ee_FX_INT2IRQ)
lp->eepro = 2; lp->eepro = 2;
else if (station_addr[2] == SA_ADDR1) else if (station_addr[2] == SA_ADDR1)
lp->eepro = 1; lp->eepro = 1;
...@@ -817,15 +833,15 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe) ...@@ -817,15 +833,15 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
/* calculate {xmt,rcv}_{lower,upper}_limit */ /* calculate {xmt,rcv}_{lower,upper}_limit */
eepro_recalc(dev); eepro_recalc(dev);
if (GetBit( read_eeprom(ioaddr, 5, dev),ee_BNC_TPE)) if (GetBit(lp->word[5], ee_BNC_TPE))
dev->if_port = BNC; dev->if_port = BNC;
else else
dev->if_port = TPE; dev->if_port = TPE;
if (dev->irq < 2 && lp->eepro != 0) { if (dev->irq < 2 && lp->eepro != 0) {
/* Mask off INT number */ /* Mask off INT number */
int count = read_eeprom(ioaddr, 1, dev) & 7; int count = lp->word[1] & 7;
unsigned irqMask = read_eeprom(ioaddr, 7, dev); unsigned irqMask = lp->word[7];
while (count--) while (count--)
irqMask &= irqMask - 1; irqMask &= irqMask - 1;
...@@ -850,6 +866,7 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe) ...@@ -850,6 +866,7 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
dev->set_multicast_list = &set_multicast_list; dev->set_multicast_list = &set_multicast_list;
dev->tx_timeout = eepro_tx_timeout; dev->tx_timeout = eepro_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
dev->ethtool_ops = &eepro_ethtool_ops;
/* print boot time info */ /* print boot time info */
eepro_print_info(dev); eepro_print_info(dev);
...@@ -941,7 +958,7 @@ static int eepro_open(struct net_device *dev) ...@@ -941,7 +958,7 @@ static int eepro_open(struct net_device *dev)
if (net_debug > 3) if (net_debug > 3)
printk(KERN_DEBUG "%s: entering eepro_open routine.\n", dev->name); printk(KERN_DEBUG "%s: entering eepro_open routine.\n", dev->name);
irqMask = read_eeprom(ioaddr,7,dev); irqMask = lp->word[7];
if (lp->eepro == LAN595FX_10ISA) { if (lp->eepro == LAN595FX_10ISA) {
if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 3;\n"); if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 3;\n");
...@@ -1070,8 +1087,6 @@ static int eepro_open(struct net_device *dev) ...@@ -1070,8 +1087,6 @@ static int eepro_open(struct net_device *dev)
old9 = inb(ioaddr + 9); old9 = inb(ioaddr + 9);
if (irqMask==ee_FX_INT2IRQ) { if (irqMask==ee_FX_INT2IRQ) {
enum iftype { AUI=0, BNC=1, TPE=2 };
if (net_debug > 3) { if (net_debug > 3) {
printk(KERN_DEBUG "IrqMask: %#x\n",irqMask); printk(KERN_DEBUG "IrqMask: %#x\n",irqMask);
printk(KERN_DEBUG "i82595FX detected!\n"); printk(KERN_DEBUG "i82595FX detected!\n");
...@@ -1701,12 +1716,72 @@ eepro_transmit_interrupt(struct net_device *dev) ...@@ -1701,12 +1716,72 @@ eepro_transmit_interrupt(struct net_device *dev)
} }
} }
static int eepro_ethtool_get_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
struct eepro_local *lp = (struct eepro_local *)dev->priv;
cmd->supported = SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_Autoneg;
cmd->advertising = ADVERTISED_10baseT_Half |
ADVERTISED_10baseT_Full |
ADVERTISED_Autoneg;
if (GetBit(lp->word[5], ee_PortTPE)) {
cmd->supported |= SUPPORTED_TP;
cmd->advertising |= ADVERTISED_TP;
}
if (GetBit(lp->word[5], ee_PortBNC)) {
cmd->supported |= SUPPORTED_BNC;
cmd->advertising |= ADVERTISED_BNC;
}
if (GetBit(lp->word[5], ee_PortAUI)) {
cmd->supported |= SUPPORTED_AUI;
cmd->advertising |= ADVERTISED_AUI;
}
cmd->speed = SPEED_10;
if (dev->if_port == TPE && lp->word[1] & ee_Duplex) {
cmd->duplex = DUPLEX_FULL;
}
else {
cmd->duplex = DUPLEX_HALF;
}
cmd->port = dev->if_port;
cmd->phy_address = dev->base_addr;
cmd->transceiver = XCVR_INTERNAL;
if (lp->word[0] & ee_AutoNeg) {
cmd->autoneg = 1;
}
return 0;
}
static void eepro_ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *drvinfo)
{
strcpy(drvinfo->driver, DRV_NAME);
strcpy(drvinfo->version, DRV_VERSION);
sprintf(drvinfo->bus_info, "ISA 0x%lx", dev->base_addr);
}
static struct ethtool_ops eepro_ethtool_ops = {
.get_settings = eepro_ethtool_get_settings,
.get_drvinfo = eepro_ethtool_get_drvinfo,
};
#ifdef MODULE #ifdef MODULE
#define MAX_EEPRO 8 #define MAX_EEPRO 8
static struct net_device *dev_eepro[MAX_EEPRO]; static struct net_device *dev_eepro[MAX_EEPRO];
static int io[MAX_EEPRO]; static int io[MAX_EEPRO] = {
[0 ... MAX_EEPRO-1] = -1
};
static int irq[MAX_EEPRO]; static int irq[MAX_EEPRO];
static int mem[MAX_EEPRO] = { /* Size of the rx buffer in KB */ static int mem[MAX_EEPRO] = { /* Size of the rx buffer in KB */
[0 ... MAX_EEPRO-1] = RCV_DEFAULT_RAM/1024 [0 ... MAX_EEPRO-1] = RCV_DEFAULT_RAM/1024
...@@ -1716,14 +1791,15 @@ static int autodetect; ...@@ -1716,14 +1791,15 @@ static int autodetect;
static int n_eepro; static int n_eepro;
/* For linux 2.1.xx */ /* For linux 2.1.xx */
MODULE_AUTHOR("Pascal Dupuis, and aris@cathedrallabs.org"); MODULE_AUTHOR("Pascal Dupuis and others");
MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver"); MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EEPRO) "i"); static int num_params;
MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EEPRO) "i"); module_param_array(io, int, num_params, 0);
MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_EEPRO) "i"); module_param_array(irq, int, num_params, 0);
MODULE_PARM(autodetect, "1-" __MODULE_STRING(1) "i"); module_param_array(mem, int, num_params, 0);
module_param(autodetect, int, 0);
MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)"); MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)");
MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)"); MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)");
MODULE_PARM_DESC(mem, "EtherExpress Pro/10 Rx buffer size(es) in kB (3-29)"); MODULE_PARM_DESC(mem, "EtherExpress Pro/10 Rx buffer size(es) in kB (3-29)");
...@@ -1734,19 +1810,21 @@ init_module(void) ...@@ -1734,19 +1810,21 @@ init_module(void)
{ {
struct net_device *dev; struct net_device *dev;
int i; int i;
if (io[0] == 0 && autodetect == 0) { if (io[0] == -1 && autodetect == 0) {
printk(KERN_WARNING "eepro_init_module: Probe is very dangerous in ISA boards!\n"); printk(KERN_WARNING "eepro_init_module: Probe is very dangerous in ISA boards!\n");
printk(KERN_WARNING "eepro_init_module: Please add \"autodetect=1\" to force probe\n"); printk(KERN_WARNING "eepro_init_module: Please add \"autodetect=1\" to force probe\n");
return 1; return -ENODEV;
} }
else if (autodetect) { else if (autodetect) {
/* if autodetect is set then we must force detection */ /* if autodetect is set then we must force detection */
io[0] = 0; for (i = 0; i < MAX_EEPRO; i++) {
io[i] = 0;
}
printk(KERN_INFO "eepro_init_module: Auto-detecting boards (May God protect us...)\n"); printk(KERN_INFO "eepro_init_module: Auto-detecting boards (May God protect us...)\n");
} }
for (i = 0; i < MAX_EEPRO; i++) { for (i = 0; io[i] != -1 && i < MAX_EEPRO; i++) {
dev = alloc_etherdev(sizeof(struct eepro_local)); dev = alloc_etherdev(sizeof(struct eepro_local));
if (!dev) if (!dev)
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment