summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/if_ze.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1995-05-02 04:03:07 +0000
committerphk <phk@FreeBSD.org>1995-05-02 04:03:07 +0000
commit93bec984db221d82ad3fda54d4c16d3105f28030 (patch)
tree929a5298470ce6508ef9424e8c087b930b9196c4 /sys/i386/isa/if_ze.c
parentdce343626d3a734bead42b3f25abb96e0fbec43c (diff)
downloadFreeBSD-src-93bec984db221d82ad3fda54d4c16d3105f28030.zip
FreeBSD-src-93bec984db221d82ad3fda54d4c16d3105f28030.tar.gz
Do the obvious thing: when the interface is downed, power off the card.
When up'ed again: reapply power. This means that you can leave your card in, you don't need to reboot to avoid the power drain.
Diffstat (limited to 'sys/i386/isa/if_ze.c')
-rw-r--r--sys/i386/isa/if_ze.c226
1 files changed, 78 insertions, 148 deletions
diff --git a/sys/i386/isa/if_ze.c b/sys/i386/isa/if_ze.c
index 7c8719e..72417e9 100644
--- a/sys/i386/isa/if_ze.c
+++ b/sys/i386/isa/if_ze.c
@@ -47,7 +47,7 @@
*/
/*
- * $Id: if_ze.c,v 1.12 1995/02/26 05:14:48 bde Exp $
+ * $Id: if_ze.c,v 1.13 1995/03/28 07:55:35 bde Exp $
*/
#include "ze.h"
@@ -106,18 +106,14 @@
* ze_softc: per line info and status
*/
struct ze_softc {
+
+ caddr_t maddr;
+ u_long iobase, irq;
+
struct arpcom arpcom; /* ethernet common */
char *type_str; /* pointer to type string */
char *mau; /* type of media access unit */
-#if 0
- u_char vendor; /* interface vendor */
- u_char type; /* interface type code */
-#endif
-
-#if 0
- u_short vector; /* interrupt vector */
-#endif
u_short nic_addr; /* NIC (DS8390) I/O bus address */
caddr_t smem_start; /* shared memory start address */
@@ -151,6 +147,7 @@ int ze_attach(), ze_ioctl(), ze_probe();
void ze_init(), ze_start(), ze_stop(), ze_intr();
void ze_reset(), ze_watchdog(), ze_get_packet();
+void ze_setup __P((struct ze_softc *sc));
static inline void ze_rint();
static inline void ze_xmit();
static inline char *ze_ring_copy();
@@ -325,6 +322,7 @@ ze_find_adapter (unsigned char *scratch, int reconfig)
* on exit:
* NULL if device not found
* or # of i/o addresses used (if found)
+ pcic(
*/
int
ze_probe(isa_dev)
@@ -372,7 +370,55 @@ ze_probe(isa_dev)
enet_addr[5] = PEEK(isa_dev->id_maddr+0xffa);
pcic_unmap_memory (slot, 0);
- re_init_flag = 0;
+ sc->maddr = isa_dev->id_maddr;
+ sc->irq = isa_dev->id_irq;
+ sc->iobase = isa_dev->id_iobase;
+ sc->slot = slot;
+ /*
+ * Setup i/o addresses
+ */
+ sc->nic_addr = sc->iobase;
+ sc->smem_start = (caddr_t)sc->maddr;
+
+ ze_setup(sc);
+
+ tmp = inb (sc->iobase + ZE_RESET);
+ sc->mau = tmp & 0x09 ? "10base2" : "10baseT";
+
+ /* set width/size */
+ sc->type_str = "IBM PCMCIA";
+ memsize = 16*1024;
+ sc->memwidth = 16;
+
+ /* allocate 1 xmit buffer */
+ sc->smem_ring = sc->smem_start + (ZE_PAGE_SIZE * ZE_TXBUF_SIZE);
+ sc->txb_cnt = 1;
+ sc->rec_page_start = ZE_TXBUF_SIZE + ZE_PAGE_OFFSET;
+ sc->smem_size = memsize;
+ sc->smem_end = sc->smem_start + memsize;
+ sc->rec_page_stop = memsize / ZE_PAGE_SIZE + ZE_PAGE_OFFSET;
+ sc->tx_page_start = ZE_PAGE_OFFSET;
+
+ /* get station address */
+ for (i = 0; i < ETHER_ADDR_LEN; ++i)
+ sc->arpcom.ac_enaddr[i] = enet_addr[i];
+
+ isa_dev->id_msize = memsize;
+
+
+ /* information for reconfiguration */
+ sc->last_alive = 0;
+ sc->last_up = 0;
+
+ return 32;
+}
+
+
+void
+ze_setup(struct ze_softc *sc)
+{
+ int re_init_flag = 0,tmp,slot = sc->slot;
+
re_init:
/*
* (2) map card configuration registers. these are offset
@@ -385,9 +431,9 @@ re_init:
* 0x20000 in the next statement. Oh yes, also change the
* card id string that we probe for.
*/
- pcic_map_memory (slot, 0, kvtop (isa_dev->id_maddr), 0x20000, 8L,
+ pcic_map_memory (slot, 0, kvtop (sc->maddr), 0x20000, 8L,
ATTRIBUTE, 1);
- POKE(isa_dev->id_maddr, 0x80); /* reset the card (how long?) */
+ POKE(sc->maddr, 0x80); /* reset the card (how long?) */
DELAY (40000);
/*
* Set the configuration index. According to [1], the adapter won't
@@ -398,7 +444,7 @@ re_init:
* XXX probably should init the socket and copy register also,
* so that we can deal with multiple instances of the same card.
*/
- POKE(isa_dev->id_maddr, 0x41);
+ POKE(sc->maddr, 0x41);
pcic_unmap_memory (slot, 0);
/*
@@ -408,7 +454,7 @@ re_init:
* looking at the PCIC registers; it's not documented in IBM's
* tech ref manual ([1]).
*/
- pcic_map_memory (slot, 0, kvtop (isa_dev->id_maddr), 0x4000L, 0x4000L,
+ pcic_map_memory (slot, 0, kvtop (sc->maddr), 0x4000L, 0x4000L,
COMMON, 2);
/*
@@ -424,10 +470,10 @@ re_init:
* we have an extra window anyway...
*/
#ifdef SHARED_MEMORY
- pcic_map_io (slot, 0, isa_dev->id_iobase, 32, 1);
+ pcic_map_io (slot, 0, sc->iobase, 32, 1);
#else
- pcic_map_io (slot, 0, isa_dev->id_iobase, 16, 1);
- pcic_map_io (slot, 1, isa_dev->id_iobase+16, 16, 2);
+ pcic_map_io (slot, 0, sc->iobase, 16, 1);
+ pcic_map_io (slot, 1, sc->iobase+16, 16, 2);
#endif /* SHARED_MEMORY */
/*
@@ -435,7 +481,7 @@ re_init:
*
* XXX is it possible that the config file leaves this unspecified?
*/
- pcic_map_irq (slot, ffs (isa_dev->id_irq) - 1);
+ pcic_map_irq (slot, ffs (sc->irq) - 1);
/* tell the PCIC that this is an I/O card (not memory) */
pcic_putb (slot, PCIC_INT_GEN,
@@ -451,34 +497,21 @@ re_init:
#if 0
pcic_print_regs (slot);
#endif
- /*
- * Setup i/o addresses
- */
- sc->nic_addr = isa_dev->id_iobase;
-#if 0
- sc->vector = isa_dev->id_irq;
-#endif
- sc->smem_start = (caddr_t)isa_dev->id_maddr;
-
-#if 0
- sc->vendor = ZE_VENDOR_IBM;
- sc->type = xxx;
-#endif
/* reset card to force it into a known state */
- tmp = inb (isa_dev->id_iobase + ZE_RESET);
+ tmp = inb (sc->iobase + ZE_RESET);
DELAY(20000);
- outb (isa_dev->id_iobase + ZE_RESET, tmp);
+ outb (sc->iobase + ZE_RESET, tmp);
DELAY(20000);
#if 0
- tmp = inb(isa_dev->id_iobase);
+ tmp = inb(sc->iobase);
printf("CR = 0x%x\n", tmp);
#endif
/*
* query MAM bit in misc register for 10base2
*/
- tmp = inb (isa_dev->id_iobase + ZE_MISC);
+ tmp = inb (sc->iobase + ZE_MISC);
/*
* Some Intel-compatible PCICs of Cirrus Logic fails in
@@ -490,36 +523,6 @@ re_init:
re_init_flag++;
goto re_init;
}
-
- sc->mau = tmp & 0x09 ? "10base2" : "10baseT";
-
- /* set width/size */
- sc->type_str = "IBM PCMCIA";
- memsize = 16*1024;
- sc->memwidth = 16;
-
- /* allocate 1 xmit buffer */
- sc->smem_ring = sc->smem_start + (ZE_PAGE_SIZE * ZE_TXBUF_SIZE);
- sc->txb_cnt = 1;
- sc->rec_page_start = ZE_TXBUF_SIZE + ZE_PAGE_OFFSET;
- sc->smem_size = memsize;
- sc->smem_end = sc->smem_start + memsize;
- sc->rec_page_stop = memsize / ZE_PAGE_SIZE + ZE_PAGE_OFFSET;
- sc->tx_page_start = ZE_PAGE_OFFSET;
-
- /* get station address */
- for (i = 0; i < ETHER_ADDR_LEN; ++i)
- sc->arpcom.ac_enaddr[i] = enet_addr[i];
-
- isa_dev->id_msize = memsize;
-
-
- /* information for reconfiguration */
- sc->last_alive = 0;
- sc->last_up = 0;
- sc->slot = slot;
-
- return 32;
}
#if NAPM > 0
@@ -714,6 +717,7 @@ ze_stop(unit)
* DS8390's, but just in case it's an old one.
*/
while (((inb(sc->nic_addr + ZE_P0_ISR) & ZE_ISR_RST) == 0) && --n);
+ pcic_power_off(0);
}
@@ -730,6 +734,8 @@ ze_watchdog(unit)
u_char isr, imr;
u_short imask;
+ if(!(sc->arpcom.ac_if.if_flags & IFF_UP))
+ return;
/* select page zero */
outb (sc->nic_addr + ZE_P0_CR,
(inb (sc->nic_addr + ZE_P0_CR) & 0x3f) | ZE_CR_PAGE_0);
@@ -768,6 +774,11 @@ ze_init(unit)
u_char command;
+ pcic_power_on(sc->slot);
+ pcic_reset(sc->slot);
+ if(!(sc->arpcom.ac_if.if_flags & IFF_UP))
+ Debugger("here!!");
+ ze_setup(sc);
/* address not known */
if (ifp->if_addrlist == (struct ifaddr *)0) return;
@@ -885,20 +896,6 @@ ze_init(unit)
*/
outb(sc->nic_addr + ZE_P0_TCR, 0);
-#if 0
- /*
- * If this is a 3Com board, the tranceiver must be software enabled
- * (there is no settable hardware default).
- */
- if (sc->vendor == ZE_VENDOR_3COM) {
- if (ifp->if_flags & IFF_LINK0) {
- outb(sc->asic_addr + ZE_3COM_CR, 0);
- } else {
- outb(sc->asic_addr + ZE_3COM_CR, ZE_3COM_CR_XSEL);
- }
- }
-#endif
-
/*
* Set 'running' flag, and clear output active flag.
*/
@@ -1024,16 +1021,6 @@ outloop:
/*
* Copy the mbuf chain into the transmit buffer
*/
-#if 0
- /*
- * Enable 16bit access to shared memory on WD/SMC boards
- */
- if (sc->memwidth == 16)
- if (sc->vendor == ZE_VENDOR_WD_SMC) {
- laar_tmp = inb(sc->asic_addr + ZE_WD_LAAR);
- outb(sc->asic_addr + ZE_WD_LAAR, laar_tmp | ZE_WD_LAAR_M16EN);
- }
-#endif
buffer = sc->smem_start + (sc->txb_next * ZE_TXBUF_SIZE * ZE_PAGE_SIZE);
len = 0;
@@ -1043,16 +1030,6 @@ outloop:
len += m->m_len;
}
-#if 0
- /*
- * Restore previous shared mem access type
- */
- if (sc->memwidth == 16)
- if (sc->vendor == ZE_VENDOR_WD_SMC) {
- outb(sc->asic_addr + ZE_WD_LAAR, laar_tmp);
- }
-#endif
-
sc->txb_next_len = max(len, ETHER_MIN_LEN);
if (sc->txb_cnt > 1)
@@ -1181,6 +1158,8 @@ zeintr(unit)
struct ze_softc *sc = &ze_softc[unit];
u_char isr;
+ if(!(sc->arpcom.ac_if.if_flags & IFF_UP))
+ return;
/*
* Set NIC to page 0 registers
*/
@@ -1247,15 +1226,10 @@ zeintr(unit)
if (isr & ZE_ISR_RXE) {
++sc->arpcom.ac_if.if_ierrors;
#ifdef ZE_DEBUG
-#if 0
- printf("ze%d: receive error %x\n", unit,
- inb(sc->nic_addr + ZE_P0_RSR));
-#else
printf("ze%d: receive error %b\n", unit,
inb(sc->nic_addr + ZE_P0_RSR),
"\20\8DEF\7REC DISAB\6PHY/MC\5MISSED\4OVR\3ALIGN\2FCS\1RCVD");
#endif
-#endif
}
/*
@@ -1269,12 +1243,6 @@ zeintr(unit)
*/
if (isr & ZE_ISR_OVW) {
++sc->arpcom.ac_if.if_ierrors;
-#if 0
- /* sigh. this happens too often on our net */
- log(LOG_WARNING,
- "ze%d: warning - receiver ring buffer overrun\n",
- unit);
-#endif
/*
* Stop/reset/re-init NIC
*/
@@ -1318,30 +1286,7 @@ zeintr(unit)
* interface to not accept packets with errors).
*/
if (isr & (ZE_ISR_PRX|ZE_ISR_RXE)) {
-#if 0
- /*
- * Enable access to shared memory on WD/SMC boards
- */
- if (sc->memwidth == 16)
- if (sc->vendor == ZE_VENDOR_WD_SMC) {
- outb(sc->asic_addr + ZE_WD_LAAR,
- inb(sc->asic_addr + ZE_WD_LAAR)
- | ZE_WD_LAAR_M16EN);
- }
-#endif
ze_rint (unit);
-
-#if 0
- /*
- * Disable access to shared memory
- */
- if (sc->memwidth == 16)
- if (sc->vendor == ZE_VENDOR_WD_SMC) {
- outb(sc->asic_addr + ZE_WD_LAAR,
- inb(sc->asic_addr + ZE_WD_LAAR)
- & ~ZE_WD_LAAR_M16EN);
- }
-#endif
}
/*
@@ -1485,21 +1430,6 @@ ze_ioctl(ifp, command, data)
outb(sc->nic_addr + ZE_P0_RCR, ZE_RCR_AB);
}
#endif
-#if 0
- /*
- * An unfortunate hack to provide the (required) software control
- * of the tranceiver for 3Com boards. The LLC0 flag disables
- * the tranceiver if set.
- */
- if (sc->vendor == ZE_VENDOR_3COM) {
- if (ifp->if_flags & IFF_LINK0) {
- outb(sc->asic_addr + ZE_3COM_CR, 0);
- } else {
- outb(sc->asic_addr + ZE_3COM_CR, ZE_3COM_CR_XSEL);
- }
- }
-#endif
-
break;
default:
OpenPOWER on IntegriCloud