Commit f0e373dc authored by Ralf Bächle's avatar Ralf Bächle

[netdrvr] sgiseeq update

parent e3e33952
...@@ -1843,7 +1843,7 @@ config DE620 ...@@ -1843,7 +1843,7 @@ config DE620
The module will be called de620. The module will be called de620.
config SGISEEQ config SGISEEQ
bool "SGI Seeq ethernet controller support" tristate "SGI Seeq ethernet controller support"
depends on NET_ETHERNET && SGI_IP22 depends on NET_ETHERNET && SGI_IP22
help help
Say Y here if you have an Seeq based Ethernet network card. This is Say Y here if you have an Seeq based Ethernet network card. This is
......
...@@ -82,7 +82,6 @@ extern int sonic_probe(struct net_device *); ...@@ -82,7 +82,6 @@ extern int sonic_probe(struct net_device *);
extern int SK_init(struct net_device *); extern int SK_init(struct net_device *);
extern int seeq8005_probe(struct net_device *); extern int seeq8005_probe(struct net_device *);
extern int smc_init( struct net_device * ); extern int smc_init( struct net_device * );
extern int sgiseeq_probe(struct net_device *);
extern int atarilance_probe(struct net_device *); extern int atarilance_probe(struct net_device *);
extern int sun3lance_probe(struct net_device *); extern int sun3lance_probe(struct net_device *);
extern int sun3_82586_probe(struct net_device *); extern int sun3_82586_probe(struct net_device *);
...@@ -343,14 +342,6 @@ static struct devprobe m68k_probes[] __initdata = { ...@@ -343,14 +342,6 @@ static struct devprobe m68k_probes[] __initdata = {
{NULL, 0}, {NULL, 0},
}; };
static struct devprobe sgi_probes[] __initdata = {
#ifdef CONFIG_SGISEEQ
{sgiseeq_probe, 0},
#endif
{NULL, 0},
};
static struct devprobe mips_probes[] __initdata = { static struct devprobe mips_probes[] __initdata = {
#ifdef CONFIG_MIPS_JAZZ_SONIC #ifdef CONFIG_MIPS_JAZZ_SONIC
{sonic_probe, 0}, {sonic_probe, 0},
...@@ -385,8 +376,6 @@ static int __init ethif_probe(struct net_device *dev) ...@@ -385,8 +376,6 @@ static int __init ethif_probe(struct net_device *dev)
return 0; return 0;
if (probe_list(dev, mips_probes) == 0) if (probe_list(dev, mips_probes) == 0)
return 0; return 0;
if (probe_list(dev, sgi_probes) == 0)
return 0;
if (probe_list(dev, eisa_probes) == 0) if (probe_list(dev, eisa_probes) == 0)
return 0; return 0;
if (probe_list(dev, mca_probes) == 0) if (probe_list(dev, mca_probes) == 0)
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/ioport.h> #include <linux/ioport.h>
...@@ -25,8 +26,8 @@ ...@@ -25,8 +26,8 @@
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/sgi/sgihpc.h> #include <asm/sgi/hpc3.h>
#include <asm/sgi/sgint23.h> #include <asm/sgi/ip22.h>
#include <asm/sgialib.h> #include <asm/sgialib.h>
#include "sgiseeq.h" #include "sgiseeq.h"
...@@ -90,8 +91,8 @@ struct sgiseeq_init_block { /* Note the name ;-) */ ...@@ -90,8 +91,8 @@ struct sgiseeq_init_block { /* Note the name ;-) */
struct sgiseeq_private { struct sgiseeq_private {
volatile struct sgiseeq_init_block srings; volatile struct sgiseeq_init_block srings;
char *name; char *name;
volatile struct hpc3_ethregs *hregs; struct hpc3_ethregs *hregs;
volatile struct sgiseeq_regs *sregs; struct sgiseeq_regs *sregs;
/* Ring entry counters. */ /* Ring entry counters. */
unsigned int rx_new, tx_new; unsigned int rx_new, tx_new;
...@@ -102,17 +103,22 @@ struct sgiseeq_private { ...@@ -102,17 +103,22 @@ struct sgiseeq_private {
unsigned char mode; unsigned char mode;
struct net_device_stats stats; struct net_device_stats stats;
struct net_device *next_module;
}; };
static inline void hpc3_eth_reset(volatile struct hpc3_ethregs *hregs) /* A list of all installed seeq devices, for removing the driver module. */
static struct net_device *root_sgiseeq_dev;
static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs)
{ {
hregs->rx_reset = (HPC3_ERXRST_CRESET | HPC3_ERXRST_CLRIRQ); hregs->rx_reset = (HPC3_ERXRST_CRESET | HPC3_ERXRST_CLRIRQ);
udelay(20); udelay(20);
hregs->rx_reset = 0; hregs->rx_reset = 0;
} }
static inline void reset_hpc3_and_seeq(volatile struct hpc3_ethregs *hregs, static inline void reset_hpc3_and_seeq(struct hpc3_ethregs *hregs,
volatile struct sgiseeq_regs *sregs) struct sgiseeq_regs *sregs)
{ {
hregs->rx_ctrl = hregs->tx_ctrl = 0; hregs->rx_ctrl = hregs->tx_ctrl = 0;
hpc3_eth_reset(hregs); hpc3_eth_reset(hregs);
...@@ -122,15 +128,15 @@ static inline void reset_hpc3_and_seeq(volatile struct hpc3_ethregs *hregs, ...@@ -122,15 +128,15 @@ static inline void reset_hpc3_and_seeq(volatile struct hpc3_ethregs *hregs,
SEEQ_RCMD_IDRIB | SEEQ_RCMD_ICRC) SEEQ_RCMD_IDRIB | SEEQ_RCMD_ICRC)
static inline void seeq_go(struct sgiseeq_private *sp, static inline void seeq_go(struct sgiseeq_private *sp,
volatile struct hpc3_ethregs *hregs, struct hpc3_ethregs *hregs,
volatile struct sgiseeq_regs *sregs) struct sgiseeq_regs *sregs)
{ {
sregs->rstat = sp->mode | RSTAT_GO_BITS; sregs->rstat = sp->mode | RSTAT_GO_BITS;
hregs->rx_ctrl = HPC3_ERXCTRL_ACTIVE; hregs->rx_ctrl = HPC3_ERXCTRL_ACTIVE;
} }
static inline void seeq_load_eaddr(struct net_device *dev, static inline void seeq_load_eaddr(struct net_device *dev,
volatile struct sgiseeq_regs *sregs) struct sgiseeq_regs *sregs)
{ {
int i; int i;
...@@ -171,7 +177,6 @@ static int seeq_init_ring(struct net_device *dev) ...@@ -171,7 +177,6 @@ static int seeq_init_ring(struct net_device *dev)
return -ENOMEM; return -ENOMEM;
ib->tx_desc[i].buf_vaddr = KSEG1ADDR(buffer); ib->tx_desc[i].buf_vaddr = KSEG1ADDR(buffer);
ib->tx_desc[i].tdma.pbuf = PHYSADDR(buffer); ib->tx_desc[i].tdma.pbuf = PHYSADDR(buffer);
// flush_cache_all();
} }
ib->tx_desc[i].tdma.cntinfo = (TCNTINFO_INIT); ib->tx_desc[i].tdma.cntinfo = (TCNTINFO_INIT);
} }
...@@ -186,7 +191,6 @@ static int seeq_init_ring(struct net_device *dev) ...@@ -186,7 +191,6 @@ static int seeq_init_ring(struct net_device *dev)
return -ENOMEM; return -ENOMEM;
ib->rx_desc[i].buf_vaddr = KSEG1ADDR(buffer); ib->rx_desc[i].buf_vaddr = KSEG1ADDR(buffer);
ib->rx_desc[i].rdma.pbuf = PHYSADDR(buffer); ib->rx_desc[i].rdma.pbuf = PHYSADDR(buffer);
// flush_cache_all();
} }
ib->rx_desc[i].rdma.cntinfo = (RCNTINFO_INIT); ib->rx_desc[i].rdma.cntinfo = (RCNTINFO_INIT);
} }
...@@ -203,7 +207,7 @@ void sgiseeq_dump_rings(void) ...@@ -203,7 +207,7 @@ void sgiseeq_dump_rings(void)
static int once; static int once;
struct sgiseeq_rx_desc *r = gpriv->srings.rx_desc; struct sgiseeq_rx_desc *r = gpriv->srings.rx_desc;
struct sgiseeq_tx_desc *t = gpriv->srings.tx_desc; struct sgiseeq_tx_desc *t = gpriv->srings.tx_desc;
volatile struct hpc3_ethregs *hregs = gpriv->hregs; struct hpc3_ethregs *hregs = gpriv->hregs;
int i; int i;
if(once) if(once)
...@@ -242,9 +246,9 @@ void sgiseeq_dump_rings(void) ...@@ -242,9 +246,9 @@ void sgiseeq_dump_rings(void)
#define RDMACFG_INIT (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ) #define RDMACFG_INIT (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ)
static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp, static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp,
volatile struct sgiseeq_regs *sregs) struct sgiseeq_regs *sregs)
{ {
volatile struct hpc3_ethregs *hregs = sp->hregs; struct hpc3_ethregs *hregs = sp->hregs;
int err; int err;
reset_hpc3_and_seeq(hregs, sregs); reset_hpc3_and_seeq(hregs, sregs);
...@@ -285,8 +289,8 @@ static inline void record_rx_errors(struct sgiseeq_private *sp, ...@@ -285,8 +289,8 @@ static inline void record_rx_errors(struct sgiseeq_private *sp,
} }
static inline void rx_maybe_restart(struct sgiseeq_private *sp, static inline void rx_maybe_restart(struct sgiseeq_private *sp,
volatile struct hpc3_ethregs *hregs, struct hpc3_ethregs *hregs,
volatile struct sgiseeq_regs *sregs) struct sgiseeq_regs *sregs)
{ {
if (!(hregs->rx_ctrl & HPC3_ERXCTRL_ACTIVE)) { if (!(hregs->rx_ctrl & HPC3_ERXCTRL_ACTIVE)) {
hregs->rx_ndptr = PHYSADDR(&sp->srings.rx_desc[sp->rx_new]); hregs->rx_ndptr = PHYSADDR(&sp->srings.rx_desc[sp->rx_new]);
...@@ -299,8 +303,8 @@ static inline void rx_maybe_restart(struct sgiseeq_private *sp, ...@@ -299,8 +303,8 @@ static inline void rx_maybe_restart(struct sgiseeq_private *sp,
(rd) = &(sp)->srings.rx_desc[(sp)->rx_new]) (rd) = &(sp)->srings.rx_desc[(sp)->rx_new])
static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp, static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp,
volatile struct hpc3_ethregs *hregs, struct hpc3_ethregs *hregs,
volatile struct sgiseeq_regs *sregs) struct sgiseeq_regs *sregs)
{ {
struct sgiseeq_rx_desc *rd; struct sgiseeq_rx_desc *rd;
struct sk_buff *skb = 0; struct sk_buff *skb = 0;
...@@ -332,7 +336,7 @@ static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp ...@@ -332,7 +336,7 @@ static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp
sp->stats.rx_packets++; sp->stats.rx_packets++;
sp->stats.rx_bytes += len; sp->stats.rx_bytes += len;
} else { } else {
printk ("%s: Memory squeeze, deferring packet.\n", printk (KERN_NOTICE "%s: Memory squeeze, deferring packet.\n",
dev->name); dev->name);
sp->stats.rx_dropped++; sp->stats.rx_dropped++;
} }
...@@ -350,7 +354,7 @@ static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp ...@@ -350,7 +354,7 @@ static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp
} }
static inline void tx_maybe_reset_collisions(struct sgiseeq_private *sp, static inline void tx_maybe_reset_collisions(struct sgiseeq_private *sp,
volatile struct sgiseeq_regs *sregs) struct sgiseeq_regs *sregs)
{ {
if (sp->is_edlc) { if (sp->is_edlc) {
sregs->rw.wregs.control = sp->control & ~(SEEQ_CTRL_XCNT); sregs->rw.wregs.control = sp->control & ~(SEEQ_CTRL_XCNT);
...@@ -359,7 +363,7 @@ static inline void tx_maybe_reset_collisions(struct sgiseeq_private *sp, ...@@ -359,7 +363,7 @@ static inline void tx_maybe_reset_collisions(struct sgiseeq_private *sp,
} }
static inline void kick_tx(struct sgiseeq_tx_desc *td, static inline void kick_tx(struct sgiseeq_tx_desc *td,
volatile struct hpc3_ethregs *hregs) struct hpc3_ethregs *hregs)
{ {
/* If the HPC aint doin nothin, and there are more packets /* If the HPC aint doin nothin, and there are more packets
* with ETXD cleared and XIU set we must make very certain * with ETXD cleared and XIU set we must make very certain
...@@ -377,8 +381,8 @@ static inline void kick_tx(struct sgiseeq_tx_desc *td, ...@@ -377,8 +381,8 @@ static inline void kick_tx(struct sgiseeq_tx_desc *td,
} }
static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp, static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp,
volatile struct hpc3_ethregs *hregs, struct hpc3_ethregs *hregs,
volatile struct sgiseeq_regs *sregs) struct sgiseeq_regs *sregs)
{ {
struct sgiseeq_tx_desc *td; struct sgiseeq_tx_desc *td;
unsigned long status = hregs->tx_ctrl; unsigned long status = hregs->tx_ctrl;
...@@ -420,8 +424,8 @@ static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs ...@@ -420,8 +424,8 @@ static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs
{ {
struct net_device *dev = (struct net_device *) dev_id; struct net_device *dev = (struct net_device *) dev_id;
struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv;
volatile struct hpc3_ethregs *hregs = sp->hregs; struct hpc3_ethregs *hregs = sp->hregs;
volatile struct sgiseeq_regs *sregs = sp->sregs; struct sgiseeq_regs *sregs = sp->sregs;
/* Ack the IRQ and set software state. */ /* Ack the IRQ and set software state. */
hregs->rx_reset = HPC3_ERXRST_CLRIRQ; hregs->rx_reset = HPC3_ERXRST_CLRIRQ;
...@@ -429,7 +433,7 @@ static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs ...@@ -429,7 +433,7 @@ static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs
/* Always check for received packets. */ /* Always check for received packets. */
sgiseeq_rx(dev, sp, hregs, sregs); sgiseeq_rx(dev, sp, hregs, sregs);
/* Only check for tx acks iff we have something queued. */ /* Only check for tx acks if we have something queued. */
if (sp->tx_old != sp->tx_new) if (sp->tx_old != sp->tx_new)
sgiseeq_tx(dev, sp, hregs, sregs); sgiseeq_tx(dev, sp, hregs, sregs);
...@@ -442,47 +446,34 @@ static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs ...@@ -442,47 +446,34 @@ static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs
static int sgiseeq_open(struct net_device *dev) static int sgiseeq_open(struct net_device *dev)
{ {
struct sgiseeq_private *sp = (struct sgiseeq_private *)dev->priv; struct sgiseeq_private *sp = (struct sgiseeq_private *)dev->priv;
volatile struct sgiseeq_regs *sregs = sp->sregs; struct sgiseeq_regs *sregs = sp->sregs;
unsigned long flags;
int err;
local_irq_save(flags); int err = init_seeq(dev, sp, sregs);
err = -EAGAIN;
if (request_irq(dev->irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) {
printk("Seeq8003: Can't get irq %d\n", dev->irq);
goto out;
}
err = init_seeq(dev, sp, sregs);
if (err) if (err)
goto out; return err;
netif_start_queue(dev); netif_start_queue(dev);
out: return 0;
local_irq_restore(flags);
return err;
} }
static int sgiseeq_close(struct net_device *dev) static int sgiseeq_close(struct net_device *dev)
{ {
struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv;
volatile struct sgiseeq_regs *sregs = sp->sregs; struct sgiseeq_regs *sregs = sp->sregs;
netif_stop_queue(dev); netif_stop_queue(dev);
/* Shutdown the Seeq. */ /* Shutdown the Seeq. */
reset_hpc3_and_seeq(sp->hregs, sregs); reset_hpc3_and_seeq(sp->hregs, sregs);
free_irq(dev->irq, dev);
return 0; return 0;
} }
static inline int sgiseeq_reset(struct net_device *dev) static inline int sgiseeq_reset(struct net_device *dev)
{ {
struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv;
volatile struct sgiseeq_regs *sregs = sp->sregs; struct sgiseeq_regs *sregs = sp->sregs;
int err; int err;
err = init_seeq(dev, sp, sregs); err = init_seeq(dev, sp, sregs);
...@@ -504,12 +495,12 @@ void sgiseeq_my_reset(void) ...@@ -504,12 +495,12 @@ void sgiseeq_my_reset(void)
static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv;
volatile struct hpc3_ethregs *hregs = sp->hregs; struct hpc3_ethregs *hregs = sp->hregs;
unsigned long flags; unsigned long flags;
struct sgiseeq_tx_desc *td; struct sgiseeq_tx_desc *td;
int skblen, len, entry; int skblen, len, entry;
save_and_cli(flags); local_irq_save(flags);
/* Setup... */ /* Setup... */
skblen = skb->len; skblen = skb->len;
...@@ -553,14 +544,14 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -553,14 +544,14 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (!TX_BUFFS_AVAIL(sp)) if (!TX_BUFFS_AVAIL(sp))
netif_stop_queue(dev); netif_stop_queue(dev);
restore_flags(flags); local_irq_restore(flags);
return 0; return 0;
} }
static void timeout(struct net_device *dev) static void timeout(struct net_device *dev)
{ {
printk("%s: transmit timed out, resetting\n", dev->name); printk(KERN_NOTICE "%s: transmit timed out, resetting\n", dev->name);
sgiseeq_reset(dev); sgiseeq_reset(dev);
dev->trans_start = jiffies; dev->trans_start = jiffies;
...@@ -603,41 +594,56 @@ static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs) ...@@ -603,41 +594,56 @@ static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs)
buf[i].rdma.pnext = PHYSADDR(&buf[0]); buf[i].rdma.pnext = PHYSADDR(&buf[0]);
} }
static char onboard_eth_addr[6];
#define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf))
int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs, int sgiseeq_init(struct hpc3_regs* regs, int irq)
struct hpc3_ethregs *hregs, int irq)
{ {
static unsigned version_printed; struct net_device *dev;
int i;
struct sgiseeq_private *sp; struct sgiseeq_private *sp;
int i;
sp = (struct sgiseeq_private *) get_zeroed_page(GFP_KERNEL);
if (!sp) {
printk (KERN_ERR
"Seeq8003: Could not allocate private data.\n");
return -ENOMEM;
}
dev->priv = (struct sgiseeq_private *) get_zeroed_page(GFP_KERNEL); dev = init_etherdev(NULL, 0);
if (dev->priv == NULL) if (!dev) {
printk (KERN_ERR
"Seeq8003: Could not allocate memory for device.\n");
free_page((unsigned long) sp);
return -ENOMEM; return -ENOMEM;
}
if (!version_printed++) if (request_irq(irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) {
printk(version); printk(KERN_ERR "Seeq8003: Can't get irq %d\n", dev->irq);
free_page((unsigned long) sp);
unregister_netdev(dev);
return -EAGAIN;
}
printk("%s: SGI Seeq8003 ", dev->name); printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name);
for (i = 0; i < 6; i++) #define EADDR_NVOFS 250
printk("%2.2x%c", for (i = 0; i < 3; i++) {
dev->dev_addr[i] = onboard_eth_addr[i], unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i);
i == 5 ? ' ': ':');
printk("%2.2x:%2.2x%c",
dev->dev_addr[2 * i] = tmp >> 8,
dev->dev_addr[2 * i + 1] = tmp & 0xff,
i == 2 ? ' ' : ':');
}
printk("\n"); printk("\n");
sp = (struct sgiseeq_private *) dev->priv; dev->priv = sp;
#ifdef DEBUG #ifdef DEBUG
gpriv = sp; gpriv = sp;
gdev = dev; gdev = dev;
#endif #endif
memset((char *)dev->priv, 0, sizeof(struct sgiseeq_private)); sp->sregs = (struct sgiseeq_regs *) &hpc3c0->eth_ext[0];
sp->sregs = sregs; sp->hregs = &hpc3c0->ethregs;
sp->hregs = hregs;
sp->name = sgiseeqstr; sp->name = sgiseeqstr;
sp->srings.rx_desc = (struct sgiseeq_rx_desc *) sp->srings.rx_desc = (struct sgiseeq_rx_desc *)
...@@ -654,14 +660,13 @@ int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs, ...@@ -654,14 +660,13 @@ int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs,
setup_tx_ring(sp->srings.tx_desc, SEEQ_TX_BUFFERS); setup_tx_ring(sp->srings.tx_desc, SEEQ_TX_BUFFERS);
/* Reset the chip. */ /* Reset the chip. */
hpc3_eth_reset((volatile struct hpc3_ethregs *) hregs); hpc3_eth_reset(sp->hregs);
sp->is_edlc = !(sregs->rw.rregs.collision_tx[0] & 0xff); sp->is_edlc = !(sp->sregs->rw.rregs.collision_tx[0] & 0xff);
if (sp->is_edlc) { if (sp->is_edlc)
sp->control = (SEEQ_CTRL_XCNT | SEEQ_CTRL_ACCNT | sp->control = (SEEQ_CTRL_XCNT | SEEQ_CTRL_ACCNT |
SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT | SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT |
SEEQ_CTRL_ENCARR); SEEQ_CTRL_ENCARR);
}
dev->open = sgiseeq_open; dev->open = sgiseeq_open;
dev->stop = sgiseeq_close; dev->stop = sgiseeq_close;
...@@ -674,51 +679,37 @@ int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs, ...@@ -674,51 +679,37 @@ int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs,
dev->dma = 0; dev->dma = 0;
ether_setup(dev); ether_setup(dev);
sp->next_module = root_sgiseeq_dev;
root_sgiseeq_dev = dev;
return 0; return 0;
} }
static inline unsigned char str2hexnum(unsigned char c) static int __init sgiseeq_probe(void)
{ {
if (c >= '0' && c <= '9') printk(version);
return c - '0';
if (c >= 'a' && c <= 'f') /* On board adapter on 1st HPC is always present */
return c - 'a' + 10; return sgiseeq_init(hpc3c0, SGI_ENET_IRQ);
return 0; /* foo */
} }
static inline void str2eaddr(unsigned char *ea, unsigned char *str) static void __exit sgiseeq_exit(void)
{ {
int i; struct sgiseeq_private *sp;
struct net_device *next, *dev = root_sgiseeq_dev;
for (i = 0; i < 6; i++) {
unsigned char num; while (dev) {
sp = (struct sgiseeq_private *) dev->priv;
if(*str == ':') next = sp->next_module;
str++; free_irq(dev->irq, dev);
num = str2hexnum(*str++) << 4; free_page((unsigned long) sp);
num |= (str2hexnum(*str++)); unregister_netdev(dev);
ea[i] = num; kfree(dev);
dev = next;
} }
} }
int sgiseeq_probe(struct net_device *dev) module_init(sgiseeq_probe);
{ module_exit(sgiseeq_exit);
static int initialized;
char *ep;
if (initialized) /* Already initialized? */
return 1;
initialized++;
/* First get the ethernet address of the onboard interface from ARCS.
* This is fragile; PROM doesn't like running from cache.
* On MIPS64 it crashes for some other, yet unknown reason ...
*/
ep = ArcGetEnvironmentVariable("eaddr");
str2eaddr(onboard_eth_addr, ep);
return sgiseeq_init(dev,
(struct sgiseeq_regs *) (KSEG1ADDR(0x1fbd4000)),
&hpc3c0->ethregs, SGI_ENET_IRQ);
}
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
/* $Id: sgiseeq.h,v 1.4 1999/10/09 00:01:24 ralf Exp $ /*
* sgiseeq.h: Defines for the Seeq8003 ethernet controller. * sgiseeq.h: Defines for the Seeq8003 ethernet controller.
* *
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
......
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