patch-1.3.7 linux/drivers/net/wavelan.c
Next file: linux/drivers/net/wavelan.h
Previous file: linux/drivers/net/tulip.c
Back to the patch index
Back to the overall index
- Lines: 204
- Date:
Wed Jul 5 12:53:22 1995
- Orig file:
v1.3.6/linux/drivers/net/wavelan.c
- Orig date:
Fri Jun 30 16:22:29 1995
diff -u --recursive --new-file v1.3.6/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c
@@ -6,7 +6,6 @@
#include <linux/config.h>
-#if defined(CONFIG_WAVELAN)
#if defined(MODULE)
#include <linux/module.h>
#include <linux/version.h>
@@ -26,7 +25,7 @@
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
-#include <errno.h>
+#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
@@ -40,9 +39,10 @@
#define WAVELAN_DEBUG 0
#endif /* WAVELAN_DEBUG */
-#define nels(a) (sizeof(a) / sizeof(a[0]))
-
#define WATCHDOG_JIFFIES 512 /* TODO: express in HZ. */
+#define ENABLE_FULL_PROMISCUOUS 0x10000
+
+#define nels(a) (sizeof(a) / sizeof(a[0]))
typedef struct device device;
typedef struct enet_statistics en_stats;
@@ -63,6 +63,7 @@
unsigned int correct_nwid;
unsigned int wrong_nwid;
unsigned int promiscuous;
+ unsigned int full_promiscuous;
timer_list watchdog;
device *dev;
net_local *prev;
@@ -242,6 +243,28 @@
wavelan_16_on(ioaddr, hacr);
}
+#if defined(IRQ_SET_WORKS)
+/*
+ * Write bytes to the PSA.
+ */
+static
+void
+psa_write(unsigned short ioaddr, unsigned short hacr, int o, unsigned char *b, int n)
+{
+ wavelan_16_off(ioaddr, hacr);
+
+ while (n-- > 0)
+ {
+ outw(o, PIOR2(ioaddr));
+ o++;
+ outb(*b, PIOP2(ioaddr));
+ b++;
+ }
+
+ wavelan_16_on(ioaddr, hacr);
+}
+#endif /* defined(IRQ_SET_WORKS) */
+
/*
* Read bytes from the on-board RAM.
*/
@@ -310,21 +333,36 @@
}
}
+static int irqvals[] =
+{
+ 0, 0, 0, 0x01,
+ 0x02, 0x04, 0, 0x08,
+ 0, 0, 0x10, 0x20,
+ 0x40, 0, 0, 0x80,
+};
+
+#if defined(IRQ_SET_WORKS)
+static
+int
+wavelan_unmap_irq(int irq, unsigned char *irqval)
+{
+ if (irq < 0 || irq >= nels(irqvals) || irqvals[irq] == 0)
+ return -1;
+
+ *irqval = (unsigned char)irqvals[irq];
+
+ return 0;
+}
+#endif /* defined(IRQ_SET_WORKS) */
+
/*
* Map values from the irq parameter register to irq numbers.
*/
static
int
-wavelan_map_irq(unsigned short ioaddr, unsigned char irqval)
+wavelan_map_irq(unsigned char irqval)
{
- int irq;
- static int irqvals[] =
- {
- 0, 0, 0, 0x01,
- 0x02, 0x04, 0, 0x08,
- 0, 0, 0x10, 0x20,
- 0x40, 0, 0, 0x80,
- };
+ int irq;
for (irq = 0; irq < nels(irqvals); irq++)
{
@@ -392,7 +430,7 @@
}
else
{
- if (lp->promiscuous)
+ if (lp->promiscuous && lp->full_promiscuous)
m.mmw_loopt_sel = MMW_LOOPT_SEL_UNDEFINED;
else
m.mmw_loopt_sel = 0x00;
@@ -816,6 +854,7 @@
int irq;
int i;
net_local *lp;
+ int enable_full_promiscuous;
if (wavelan_debug > 0)
printk("%s: ->wavelan_probe1(dev=0x%x, ioaddr=0x%x)\n", dev->name, (unsigned int)dev, ioaddr);
@@ -844,9 +883,27 @@
printk("%s: WaveLAN at %#x,", dev->name, ioaddr);
- if ((irq = wavelan_map_irq(ioaddr, psa.psa_int_req_no)) == -1)
+ if (dev->irq != 0)
{
- printk(" could not wavelan_map_irq(0x%x, %d).\n", ioaddr, psa.psa_int_req_no);
+ printk("[WARNING: explicit IRQ value %d ignored: using PSA value instead]", dev->irq);
+#if defined(IRQ_SET_WORKS)
+Leave this out until I can get it to work -- BJ.
+ if (wavelan_unmap_irq(dev->irq, &psa.psa_int_req_no) == -1)
+ {
+ printk(" could not wavelan_unmap_irq(%d, ..) -- ignored.\n", dev->irq);
+ dev->irq = 0;
+ }
+ else
+ {
+ psa_write(ioaddr, HACR_DEFAULT, (char *)&psa.psa_int_req_no - (char *)&psa, (unsigned char *)&psa.psa_int_req_no, sizeof(psa.psa_int_req_no));
+ wavelan_reset(ioaddr);
+ }
+#endif /* defined(IRQ_SET_WORKS) */
+ }
+
+ if ((irq = wavelan_map_irq(psa.psa_int_req_no)) == -1)
+ {
+ printk(" could not wavelan_map_irq(%d).\n", psa.psa_int_req_no);
if (wavelan_debug > 0)
printk("%s: <-wavelan_probe1(): EAGAIN\n", dev->name);
return EAGAIN;
@@ -858,10 +915,19 @@
dev->base_addr = ioaddr;
/*
- * Apparently the third numeric argument to LILO's
+ * The third numeric argument to LILO's
* `ether=' control line arrives here as `dev->mem_start'.
- * If it is non-zero we use it instead of the PSA NWID.
+ *
+ * If bit 16 of dev->mem_start is non-zero we enable
+ * full promiscuity.
+ *
+ * If either of the least significant two bytes of
+ * dev->mem_start are non-zero we use them instead
+ * of the PSA NWID.
*/
+ enable_full_promiscuous = (dev->mem_start & ENABLE_FULL_PROMISCUOUS) == ENABLE_FULL_PROMISCUOUS;
+ dev->mem_start &= ~ENABLE_FULL_PROMISCUOUS;
+
if (dev->mem_start != 0)
{
psa.psa_nwid[0] = (dev->mem_start >> 8) & 0xFF;
@@ -878,6 +944,8 @@
printk("%s%02x", (i == 0) ? " " : ":", dev->dev_addr[i]);
printk(", IRQ %d", dev->irq);
+ if (enable_full_promiscuous)
+ printk(", promisc");
printk(", nwid 0x%02x%02x", psa.psa_nwid[0], psa.psa_nwid[1]);
printk(", PC");
@@ -957,6 +1025,7 @@
lp->hacr = HACR_DEFAULT;
+ lp->full_promiscuous = enable_full_promiscuous;
lp->nwid[0] = psa.psa_nwid[0];
lp->nwid[1] = psa.psa_nwid[1];
@@ -2444,4 +2513,3 @@
* Basser Department of Computer Science Phone: +61-2-351-3423
* University of Sydney, N.S.W., 2006, AUSTRALIA Fax: +61-2-351-3838
*/
-#endif /* defined(CONFIG_WAVELAN) */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this