diff options
author | phk <phk@FreeBSD.org> | 1995-05-02 04:03:07 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1995-05-02 04:03:07 +0000 |
commit | 93bec984db221d82ad3fda54d4c16d3105f28030 (patch) | |
tree | 929a5298470ce6508ef9424e8c087b930b9196c4 /sys/i386/isa/if_ze.c | |
parent | dce343626d3a734bead42b3f25abb96e0fbec43c (diff) | |
download | FreeBSD-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.c | 226 |
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: |