|
From: Jan-Benedict G. <jb...@us...> - 2004-10-08 19:26:28
|
Update of /cvsroot/linux-vax/kernel-2.5/drivers/vax/net In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19008/drivers/vax/net Modified Files: sgec.c Log Message: - First round on the SGEC: port over to Kenn's new vsbus API. - Corrected strange MAC address reading from ESAR. - Still doesn't work, of course... Upon bootp, nothing comes out of it:-( - I found an old email (http://solar.physics.montana.edu/hypermail/linux-vax/1673.html) which I'll go through. I guess it may still contain a lot of unapplied chunks (wrt. 2.6.x). - Dumb question: isn't this basically a Tulip without PCI interface? Index: sgec.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.5/drivers/vax/net/sgec.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- sgec.c 4 Oct 2003 17:47:47 -0000 1.1 +++ sgec.c 8 Oct 2004 19:26:13 -0000 1.2 @@ -23,7 +23,8 @@ #include <linux/ioport.h> /* for autoirq_setup/_report */ #include <asm/pgalloc.h> /* for __flush_tlb_one */ -#include <asm/vsa.h> +#include <asm/bus/vsbus.h> +#include <asm/mv.h> /* use #undef to turn these off */ #define VAX_SGEC_DEBUG @@ -212,14 +213,22 @@ /* * Adresses. */ -#define SGECADDR 0x20008000 -/*defines for the network card address in ROM */ -#define NISA_ROM 0x20084000 /* QBUS address - 3100/85 */ -/* #define NISA_ROM 0x27800000 * vsbus address */ -#define SGECVEC 0x108 - -/* register offsets */ +#define NISA_ROM ( \ + { \ + unsigned long __addr; \ + if (is_ka49 ()) \ + /* VS 4000m90 */ \ + __addr = 0x27800000; \ + else \ + /* QBUS 3100/85 */ \ + __addr = 0x20084000; \ + \ + __addr; \ + }) +/* + * Register offsets + */ #define SG_CSR0 0 #define SG_CSR1 4 #define SG_CSR2 8 @@ -537,7 +546,6 @@ volatile struct sgec_regs *ll = lp->ll; volatile struct sgec_tx_desc *td; int i, j; - int status; j = lp->tx_old; spin_lock(&lp->lock); @@ -602,7 +610,7 @@ spin_unlock(&lp->lock); } -static void sgec_interrupt(const int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t sgec_interrupt(const int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; struct sgec_private *lp = (struct sgec_private *) dev->priv; @@ -613,12 +621,10 @@ if ((csr5 & SG_NICSR5_IS) == 0) { /* Hmmm, not for us... */ - return; + return IRQ_NONE; } writereg(&ll->sg_nicsr5, csr5); /* reset interrupt */ - vsbus_clear_int(lp->vsbus_int); - /* if ((csr0 & LE_C0_ERR)) { * Clear the error condition writecsr0(ll, LE_C0_BABL | LE_C0_ERR | LE_C0_MISS | @@ -644,28 +650,26 @@ netif_wake_queue(dev); } */ + + return IRQ_HANDLED; } -struct net_device *last_dev = 0; +extern struct net_device *last_dev; static int sgec_open(struct net_device *dev) { struct sgec_private *lp = (struct sgec_private *) dev->priv; volatile struct sgec_init_block *ib = lp->init_block; volatile struct sgec_regs *ll = lp->ll; - int status = 0; last_dev = dev; /* Associate IRQ with sgec_interrupt */ - if (request_irq(dev->irq, &sgec_interrupt, 0, lp->name, dev)) { + if (vsbus_request_irq (lp->vsbus_int, &sgec_interrupt, 0, lp->name, dev)) { printk("SGEC: Can't get irq %d\n", dev->irq); return -EAGAIN; } - /* this is just a hack for now */ - vsbus_enable_int(lp->vsbus_int); - sgec_stop(ll); /* Clear the multicast filter */ @@ -680,14 +684,7 @@ netif_start_queue(dev); - status = init_restart_sgec(lp); - - /* - * if (!status) - * MOD_INC_USE_COUNT; - */ - - return status; + return init_restart_sgec(lp); } static int sgec_close(struct net_device *dev) @@ -879,36 +876,23 @@ sgec_set_multicast(dev); } -volatile void *base_addr=NULL; - -static int __init vax_sgec_init(struct net_device *dev) +static int __init vax_sgec_init(struct net_device *dev, + struct vsbus_device *vsbus_dev) { static unsigned version_printed = 0; struct sgec_private *lp; volatile struct sgec_regs *ll; int i, ret; - unsigned char *esar; + volatile unsigned long *esar; /* Could these base addresses be different on other CPUs? */ - unsigned long sgec_phys_addr=SGECADDR; - unsigned long esar_phys_addr=NISA_ROM; + unsigned long sgec_phys_addr = vsbus_dev->phys_base; + unsigned long esar_phys_addr = NISA_ROM; + printk (KERN_INFO "esar_phys_addr = 0x%08x\n", esar_phys_addr); if (version_printed++ == 0) printk(version); - if (dev == NULL) { - dev = init_etherdev(0, sizeof(struct sgec_private) + 8); - } else { - dev->priv = kmalloc(sizeof(struct sgec_private) + 8, - GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; - memset(dev->priv, 0, sizeof(struct sgec_private) + 8); - - } - /* Make certain the data structures used by the SGEC are aligned. */ - dev->priv = (void *) (((unsigned long) dev->priv + 7) & ~7); - lp = (struct sgec_private *) dev->priv; spin_lock_init(&lp->lock); @@ -924,21 +908,18 @@ dev->mem_end = dev->mem_start + 65536; - /* FIXME: check this for NULL */ - base_addr=ioremap(sgec_phys_addr, 0x8); - - dev->base_addr=(unsigned long)base_addr; + dev->base_addr = (unsigned long) ioremap (sgec_phys_addr, 0x8); + dev->irq = vsbus_irqindex_to_irq (vsbus_dev->vsbus_irq); lp->sgec_mem = (volatile struct sgec_shared_mem *)(dev->mem_start); lp->init_block = &(lp->sgec_mem->init_block); - /* need something meaningful in here */ - dev->irq = 0; + lp->vsbus_int = vsbus_dev->vsbus_irq; - ll = (struct sgec_regs *) base_addr; + ll = (struct sgec_regs *) dev->base_addr; /* FIXME: deal with failure here */ - esar=ioremap(esar_phys_addr, 0x80); + esar = ioremap (esar_phys_addr, 0x80); /* 3rd byte contains address part in 3100/85 -RB */ /* Note that 660 board types use a different position */ @@ -948,67 +929,15 @@ */ printk("Ethernet address in ROM: "); for (i = 0; i < 6; i++) { - dev->dev_addr[i] = esar[(i * 4) - 2]; + dev->dev_addr[i] = esar[i] & 0xff; printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); } /* Don't need this any more */ - iounmap(esar); - -#ifdef CONFIG_VSBUS -#ifndef CONFIG_VAX_4000HC - { - int num, irq; - autoirq_setup(0); - vsbus_probe_irq_on(); - writereg(&ll->sg_nicsr6, SG_NICSR6_RE); /* reset status register */ - writereg(&ll->sg_nicsr6, SG_NICSR6_IE); /* enable interrupts */ - udelay(1000); - num=vsbus_probe_irq_report(); - irq=autoirq_report(0); - if (num) - lp->vsbus_int=num; - } -#else - lp->vsbus_int=1; -#endif - -#endif - -#ifdef VAX_SGEC_AUTOPROBE_IRQ -#ifndef CONFIG_VAX_4000HC - printk("Autoprobing SGEC interrupt vector..."); - - autoirq_setup(0); - vsbus_enable_int(lp->vsbus_int); - sgec_stop(ll); - - writereg(&ll->sg_nicsr6, SG_NICSR6_RE|SG_NICSR6_IE); -#ifdef CONFIG_VSBUS - /*lp->vsbus_int=vsbus_probe_irq_report();*/ -#endif - - dev->irq = autoirq_report(100); - vsbus_clear_int(lp->vsbus_int); -#else - dev->irq=SGECVEC; -#endif - if (dev->irq) - printk(" probed IRQ %d, vsbus %d\n", dev->irq, lp->vsbus_int); - else - { - dev->irq=SGECVEC; - printk(" failed to detect IRQ line - assuming 0x108.\n"); - } - /* Fill the dev fields */ + iounmap (esar); -#else - dev->irq=SGECVEC; - printk("Using SGEC interrupt vector %d\n", dev->irq); -#endif - /* tmp atp*/ - dev->irq=SGECVEC; - printk("Using SGEC interrupt vector %d\n", dev->irq); + printk (KERN_INFO "Using LANCE interrupt vector %d, vsbus irq %d\n", + dev->irq, lp->vsbus_int); dev->open = &sgec_open; dev->stop = &sgec_close; @@ -1041,14 +970,7 @@ lp->multicast_timer.data = (unsigned long) dev; lp->multicast_timer.function = &sgec_set_multicast_retry; -#ifdef MODULE - /* - dev->ifindex = dev_new_index(); - lp->next_module = root_sgec_dev; - root_sgec_dev = lp; - #endif - */ -#endif + SET_NETDEV_DEV(dev, &vsbus_dev->dev); return 0; @@ -1060,44 +982,45 @@ /* Find all the SGEC cards on the system and initialize them */ -int __init vax_sgec_probe(void) +int __init vax_sgec_probe(struct vsbus_device *vsbus_dev) { - struct net_device *dev = NULL; - static int called = 0; + struct net_device *netdev; + int retval; + + printk("vax_sgec_probe: name = %s, base = 0x%08x, irqindex = %d\n", + vsbus_dev->dev.bus_id, vsbus_dev->phys_base, vsbus_dev->vsbus_irq); + + netdev = alloc_etherdev (sizeof (struct sgec_private)); + if (!netdev) + return -ENOMEM; + + retval = vax_sgec_init (netdev, vsbus_dev); + if (retval == 0) { + retval = register_netdev (netdev); + if (retval) + free_netdev (netdev); + } - if (!called) - { - called=1; - return vax_sgec_init(dev); - } - else - return -ENODEV; + return 0; } -__initcall(vax_sgec_probe); - -#ifdef MODULE +static struct vsbus_driver vax_sgec_driver = { + .probe = vax_sgec_probe, + .drv = { + .name = "sgec", + }, +}; -int init_module(void) +int __init sgec_init_module (void) { - root_sgec_dev = NULL; - return vax_sgec_probe(NULL); + return vsbus_register_driver (&vax_sgec_driver); } -void cleanup_module(void) +void __exit sgec_exit_module (void) { - struct sgec_private *lp; - - while (root_sgec_dev) { - lp = root_sgec_dev->next_module; - - unregister_netdev(root_sgec_dev->dev); - kfree(root_sgec_dev->dev); - root_sgec_dev = lp; - } + printk (KERN_ERR "vax_sgec_exit: What to do???\n"); } -#endif - - +module_init (sgec_init_module); +module_exit (sgec_exit_module); |