From: Ladislav Michl <ladis@linux-mips.org>
To: linux-mips@linux-mips.org
Cc: Ralf Baechle <ralf@linux-mips.org>
Subject: [PATCH] SGI Seeq cleanup
Date: Wed, 7 May 2003 22:28:51 +0200 [thread overview]
Message-ID: <20030507202851.GA668@kopretinka> (raw)
read eaddr using NVRAM access fuctions and make various cleanups so driver
can be build as module
diff -Naur linux_2_4/drivers/net/Config.in linux_2_4-fucked/drivers/net/Config.in
--- linux_2_4/drivers/net/Config.in Wed Apr 16 09:11:57 2003
+++ linux_2_4-fucked/drivers/net/Config.in Wed May 7 19:55:30 2003
@@ -217,7 +217,7 @@
dep_tristate ' D-Link DE620 pocket adapter support' CONFIG_DE620 $CONFIG_ISA
fi
if [ "$CONFIG_SGI_IP22" = "y" ]; then
- bool ' SGI Seeq ethernet controller support' CONFIG_SGISEEQ
+ tristate ' SGI Seeq ethernet controller support' CONFIG_SGISEEQ
fi
if [ "$CONFIG_DECSTATION" = "y" ]; then
tristate ' DEC LANCE ethernet controller support' CONFIG_DECLANCE
diff -Naur linux_2_4/drivers/net/Space.c linux_2_4-fucked/drivers/net/Space.c
--- linux_2_4/drivers/net/Space.c Thu Aug 1 21:51:01 2002
+++ linux_2_4-fucked/drivers/net/Space.c Wed May 7 19:55:30 2003
@@ -83,7 +83,6 @@
extern int SK_init(struct net_device *);
extern int seeq8005_probe(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 sun3lance_probe(struct net_device *);
extern int sun3_82586_probe(struct net_device *);
@@ -366,14 +365,6 @@
{NULL, 0},
};
-
-static struct devprobe sgi_probes[] __initdata = {
-#ifdef CONFIG_SGISEEQ
- {sgiseeq_probe, 0},
-#endif
- {NULL, 0},
-};
-
static struct devprobe mips_probes[] __initdata = {
#ifdef CONFIG_MIPS_JAZZ_SONIC
{sonic_probe, 0},
@@ -407,8 +398,6 @@
if (probe_list(dev, m68k_probes) == 0)
return 0;
if (probe_list(dev, mips_probes) == 0)
- return 0;
- if (probe_list(dev, sgi_probes) == 0)
return 0;
if (probe_list(dev, eisa_probes) == 0)
return 0;
diff -Naur linux_2_4/drivers/net/sgiseeq.c linux_2_4-fucked/drivers/net/sgiseeq.c
--- linux_2_4/drivers/net/sgiseeq.c Wed Mar 19 18:33:03 2003
+++ linux_2_4-fucked/drivers/net/sgiseeq.c Wed May 7 19:55:30 2003
@@ -5,6 +5,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/init.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
@@ -96,8 +97,8 @@
struct sgiseeq_private {
volatile struct sgiseeq_init_block srings;
char *name;
- volatile struct hpc3_ethregs *hregs;
- volatile struct sgiseeq_regs *sregs;
+ struct hpc3_ethregs *hregs;
+ struct sgiseeq_regs *sregs;
/* Ring entry counters. */
unsigned int rx_new, tx_new;
@@ -108,17 +109,22 @@
unsigned char mode;
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);
udelay(20);
hregs->rx_reset = 0;
}
-static inline void reset_hpc3_and_seeq(volatile struct hpc3_ethregs *hregs,
- volatile struct sgiseeq_regs *sregs)
+static inline void reset_hpc3_and_seeq(struct hpc3_ethregs *hregs,
+ struct sgiseeq_regs *sregs)
{
hregs->rx_ctrl = hregs->tx_ctrl = 0;
hpc3_eth_reset(hregs);
@@ -128,15 +134,15 @@
SEEQ_RCMD_IDRIB | SEEQ_RCMD_ICRC)
static inline void seeq_go(struct sgiseeq_private *sp,
- volatile struct hpc3_ethregs *hregs,
- volatile struct sgiseeq_regs *sregs)
+ struct hpc3_ethregs *hregs,
+ struct sgiseeq_regs *sregs)
{
sregs->rstat = sp->mode | RSTAT_GO_BITS;
hregs->rx_ctrl = HPC3_ERXCTRL_ACTIVE;
}
static inline void seeq_load_eaddr(struct net_device *dev,
- volatile struct sgiseeq_regs *sregs)
+ struct sgiseeq_regs *sregs)
{
int i;
@@ -177,7 +183,6 @@
return -ENOMEM;
ib->tx_desc[i].buf_vaddr = KSEG1ADDR(buffer);
ib->tx_desc[i].tdma.pbuf = PHYSADDR(buffer);
-// flush_cache_all();
}
ib->tx_desc[i].tdma.cntinfo = (TCNTINFO_INIT);
}
@@ -192,7 +197,6 @@
return -ENOMEM;
ib->rx_desc[i].buf_vaddr = KSEG1ADDR(buffer);
ib->rx_desc[i].rdma.pbuf = PHYSADDR(buffer);
-// flush_cache_all();
}
ib->rx_desc[i].rdma.cntinfo = (RCNTINFO_INIT);
}
@@ -209,7 +213,7 @@
static int once;
struct sgiseeq_rx_desc *r = gpriv->srings.rx_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;
if(once)
@@ -248,9 +252,9 @@
#define RDMACFG_INIT (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ)
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;
reset_hpc3_and_seeq(hregs, sregs);
@@ -291,8 +295,8 @@
}
static inline void rx_maybe_restart(struct sgiseeq_private *sp,
- volatile struct hpc3_ethregs *hregs,
- volatile struct sgiseeq_regs *sregs)
+ struct hpc3_ethregs *hregs,
+ struct sgiseeq_regs *sregs)
{
if (!(hregs->rx_ctrl & HPC3_ERXCTRL_ACTIVE)) {
hregs->rx_ndptr = PHYSADDR(&sp->srings.rx_desc[sp->rx_new]);
@@ -305,8 +309,8 @@
(rd) = &(sp)->srings.rx_desc[(sp)->rx_new])
static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp,
- volatile struct hpc3_ethregs *hregs,
- volatile struct sgiseeq_regs *sregs)
+ struct hpc3_ethregs *hregs,
+ struct sgiseeq_regs *sregs)
{
struct sgiseeq_rx_desc *rd;
struct sk_buff *skb = 0;
@@ -338,7 +342,7 @@
sp->stats.rx_packets++;
sp->stats.rx_bytes += len;
} else {
- printk ("%s: Memory squeeze, deferring packet.\n",
+ printk (KERN_NOTICE "%s: Memory squeeze, deferring packet.\n",
dev->name);
sp->stats.rx_dropped++;
}
@@ -356,7 +360,7 @@
}
static inline void tx_maybe_reset_collisions(struct sgiseeq_private *sp,
- volatile struct sgiseeq_regs *sregs)
+ struct sgiseeq_regs *sregs)
{
if (sp->is_edlc) {
sregs->rw.wregs.control = sp->control & ~(SEEQ_CTRL_XCNT);
@@ -365,7 +369,7 @@
}
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
* with ETXD cleared and XIU set we must make very certain
@@ -383,8 +387,8 @@
}
static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp,
- volatile struct hpc3_ethregs *hregs,
- volatile struct sgiseeq_regs *sregs)
+ struct hpc3_ethregs *hregs,
+ struct sgiseeq_regs *sregs)
{
struct sgiseeq_tx_desc *td;
unsigned long status = hregs->tx_ctrl;
@@ -426,8 +430,8 @@
{
struct net_device *dev = (struct net_device *) dev_id;
struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv;
- volatile struct hpc3_ethregs *hregs = sp->hregs;
- volatile struct sgiseeq_regs *sregs = sp->sregs;
+ struct hpc3_ethregs *hregs = sp->hregs;
+ struct sgiseeq_regs *sregs = sp->sregs;
/* Ack the IRQ and set software state. */
hregs->rx_reset = HPC3_ERXRST_CLRIRQ;
@@ -435,7 +439,7 @@
/* Always check for received packets. */
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)
sgiseeq_tx(dev, sp, hregs, sregs);
@@ -447,47 +451,34 @@
static int sgiseeq_open(struct net_device *dev)
{
struct sgiseeq_private *sp = (struct sgiseeq_private *)dev->priv;
- volatile struct sgiseeq_regs *sregs = sp->sregs;
- unsigned long flags;
- int err;
-
- __save_and_cli(flags);
+ struct sgiseeq_regs *sregs = 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);
+ int err = init_seeq(dev, sp, sregs);
if (err)
- goto out;
+ return err;
netif_start_queue(dev);
-out:
- __restore_flags(flags);
- return err;
+ return 0;
}
static int sgiseeq_close(struct net_device *dev)
{
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);
/* Shutdown the Seeq. */
reset_hpc3_and_seeq(sp->hregs, sregs);
- free_irq(dev->irq, dev);
-
return 0;
}
static inline int sgiseeq_reset(struct net_device *dev)
{
struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv;
- volatile struct sgiseeq_regs *sregs = sp->sregs;
+ struct sgiseeq_regs *sregs = sp->sregs;
int err;
err = init_seeq(dev, sp, sregs);
@@ -509,7 +500,7 @@
static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
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;
struct sgiseeq_tx_desc *td;
int skblen, len, entry;
@@ -565,7 +556,7 @@
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);
dev->trans_start = jiffies;
@@ -608,41 +599,58 @@
buf[i].rdma.pnext = PHYSADDR(&buf[0]);
}
-static char onboard_eth_addr[6];
-
#define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf))
-int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs,
- struct hpc3_ethregs *hregs, int irq)
+int sgiseeq_init(struct hpc3_regs* regs, int irq)
{
- static unsigned version_printed;
- int i;
+ struct net_device *dev;
struct sgiseeq_private *sp;
-
- dev->priv = (struct sgiseeq_private *) get_zeroed_page(GFP_KERNEL);
- if (dev->priv == NULL)
+ 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;
+ }
- if (!version_printed++)
- printk(version);
-
- printk("%s: SGI Seeq8003 ", dev->name);
-
- for (i = 0; i < 6; i++)
- printk("%2.2x%c",
- dev->dev_addr[i] = onboard_eth_addr[i],
- i == 5 ? ' ': ':');
+ dev = init_etherdev(NULL, 0);
+ if (!dev) {
+ printk (KERN_ERR
+ "Seeq8003: Could not allocate memory for device.\n");
+ free_page((unsigned long) sp);
+ return -ENOMEM;
+ }
+ /* let unregister_netdev free memory for us */
+ dev->features |= NETIF_F_DYNALLOC;
+ if (request_irq(irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) {
+ printk(KERN_ERR "Seeq8003: Can't get irq %d\n", dev->irq);
+ free_page((unsigned long) sp);
+ unregister_netdev(dev);
+ return -EAGAIN;
+ }
+
+ printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name);
+
+#define EADDR_NVOFS 250
+ for (i = 0; i < 3; i++) {
+ unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i);
+
+ 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");
- sp = (struct sgiseeq_private *) dev->priv;
+ dev->priv = sp;
#ifdef DEBUG
gpriv = sp;
gdev = dev;
#endif
- memset((char *)dev->priv, 0, sizeof(struct sgiseeq_private));
- sp->sregs = sregs;
- sp->hregs = hregs;
+ sp->sregs = (struct sgiseeq_regs *) &hpc3c0->eth_ext[0];
+ sp->hregs = &hpc3c0->ethregs;
sp->name = sgiseeqstr;
sp->srings.rx_desc = (struct sgiseeq_rx_desc *)
@@ -659,14 +667,13 @@
setup_tx_ring(sp->srings.tx_desc, SEEQ_TX_BUFFERS);
/* 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);
- if (sp->is_edlc) {
+ sp->is_edlc = !(sp->sregs->rw.rregs.collision_tx[0] & 0xff);
+ if (sp->is_edlc)
sp->control = (SEEQ_CTRL_XCNT | SEEQ_CTRL_ACCNT |
SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT |
SEEQ_CTRL_ENCARR);
- }
dev->open = sgiseeq_open;
dev->stop = sgiseeq_close;
@@ -679,58 +686,36 @@
dev->dma = 0;
ether_setup(dev);
+ sp->next_module = root_sgiseeq_dev;
+ root_sgiseeq_dev = dev;
+
return 0;
}
-static inline unsigned char str2hexnum(unsigned char c)
+static int __init sgiseeq_probe(void)
{
- if (c >= '0' && c <= '9')
- return c - '0';
- if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- return 0; /* foo */
+ printk(version);
+
+ /* On board adapter on 1st HPC is always present */
+ return sgiseeq_init(hpc3c0, SGI_ENET_IRQ);
}
-static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+static void __exit sgiseeq_exit(void)
{
- int i;
-
- for (i = 0; i < 6; i++) {
- unsigned char num;
+ struct sgiseeq_private *sp;
+ struct net_device *next, *dev = root_sgiseeq_dev;
- if(*str == ':')
- str++;
- num = str2hexnum(*str++) << 4;
- num |= (str2hexnum(*str++));
- ea[i] = num;
+ while (dev) {
+ sp = (struct sgiseeq_private *) dev->priv;
+ next = sp->next_module;
+ free_irq(dev->irq, dev);
+ free_page((unsigned long) sp);
+ unregister_netdev(dev);
+ dev = next;
}
}
-int sgiseeq_probe(struct net_device *dev)
-{
- 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");
- if (ep == NULL) {
- /*
- * This one is likely to be caused by a broken NVRAM
- */
- printk(KERN_CRIT "Seeq8003: Can't get MAC address!\n");
- return -ENODEV;
- }
- str2eaddr(onboard_eth_addr, ep);
- return sgiseeq_init(dev,
- (struct sgiseeq_regs *) (KSEG1ADDR(0x1fbd4000)),
- &hpc3c0->ethregs, SGI_ENET_IRQ);
-}
+module_init(sgiseeq_probe);
+module_exit(sgiseeq_exit);
MODULE_LICENSE("GPL");
next reply other threads:[~2003-05-07 20:32 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-05-07 20:28 Ladislav Michl [this message]
2003-05-07 22:14 ` [PATCH] SGI Seeq cleanup Juan Quintela
2003-05-08 7:43 ` Ladislav Michl
2003-05-08 12:20 ` Ralf Baechle
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20030507202851.GA668@kopretinka \
--to=ladis@linux-mips.org \
--cc=linux-mips@linux-mips.org \
--cc=ralf@linux-mips.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox