📄 if_wlp_ir.c
字号:
/* * Copyright (c) 1997 Carnegie Mellon University. All Rights Reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation is hereby granted (including for commercial or for-profit * use), provided that both the copyright notice and this permission notice * appear in all copies of the software, derivative works, or modified * versions, and any portions thereof, and that both notices appear in * supporting documentation, and that credit is given to Carnegie Mellon * University in all publications reporting on direct or indirect use of this * code or its derivatives. * * THIS IMPLEMENTATION IS EXPERIMENTAL AND MAY HAVE BUGS, SOME OF WHICH MAY HAVE * SERIOUS CONSEQUENCES. CARNEGIE MELLON PROVIDES THIS SOFTWARE IN ITS "AS * IS" CONDITION, AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON * UNIVERSITY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Carnegie Mellon encourages (but does not require) users of this software to * return any improvements or extensions that they make, and to grant * Carnegie Mellon the rights to redistribute these changes without * encumbrance. * * */#include "card.h"#include <sys/param.h>#include <sys/systm.h>#include <sys/kernel.h>#include <sys/conf.h>#include <sys/errno.h>#include <sys/ioctl.h>#include <sys/mbuf.h>#include <sys/socket.h>#include <sys/syslog.h>#include <sys/time.h>#include <net/if.h>#include <net/if_dl.h>#include <net/if_types.h>#ifdef INET#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/in_var.h>#include <netinet/ip.h>#include <netinet/if_ether.h>#endif#include <machine/clock.h>#include <i386/isa/isa_device.h>#include <i386/isa/ic/i82593.h>#include <i386/isa/if_wlp_ir.h>#include <i386/isa/if_wlp_wavelan.h>#include <i386/isa/if_wlp.h>extern struct wlp_softc wlp_softc[];/* * ====================================================================== * Infrared (rw) Specific Routines * ====================================================================== */intrwprobe(is) struct isa_device *is;{ struct wlp_softc *sc = &wlp_softc[is->id_unit]; u_int32_t cksum; u_int8_t *enaddr; if (sc->sc_maddr == 0) goto bad; /* * Fix for ASIC Problem ??? */ IOWrite1(0x0C, P12_SERIAL_CLOCK); DELAY(200); IOWrite1(0x0C, 0x00); DELAY(200); /* * Reset the Intel 82593 */ IOWrite1(0x00, P0_RESET); DELAY(200); /* * Perform a general reset of the card. */ IOWrite1(0x08, IORead1(0x08) | P8_RESET); DELAY(200); IOWrite1(0x08, IORead1(0x08) & ~P8_RESET); DELAY(200); /* * Defect 38 */ IOWrite1(0x0C, IORead1(0x0C) | P12_TRANSCEIVER_ENABLE); DELAY(200); /* * (1) Set ROM/RAM ENABLE bit to 1 (RAM selected) * (2) Test the onboard RAM */ IOWrite1(0x08, IORead1(0x08) | P8_RAM_ROM); if (TestRAM(sc)) { goto bad; } if (ProbeIntel82593(is, IFTYPE_REDWING)) { goto bad; } /* * (1) Set ROM/RAM ENABLE bit to 0 (ROM selected) * (2) Write 0xC0 to the Page Control Port */ IOWrite1(0x08, IORead1(0x08) & ~P8_RAM_ROM); IOWrite1(0x09, 0xC0); /* * Access the hardware address starting at offset 0x1FF0. Then * compute the checksum of the address to verify that no errors * exist. Checksum bytes are at 0x1FF6 (LSB) and 0x1FF7 (MSB). */ enaddr = sc->sc_ac.ac_enaddr; MEMRead(enaddr, 0x1FF0, ETHER_ADDR_LEN); cksum = enaddr[0] + enaddr[1] + enaddr[2] + enaddr[3] + enaddr[4] + enaddr[5]; cksum = (~(cksum) + 1) & 0xFFFF; if ((cksum & 0xFF) != MEMRead1(0x1FF7) || ((cksum >> 8) & 0xFF) != MEMRead1(0x1FF6)) { printf("wlp%d: Ethernet address checksum failed.\n", sc->sc_unit); goto bad; }#ifdef WLP_STATS i82593_reset_stats(sc);#endif return RW_IOSIZE;bad: return 0; /* ERROR */}intrwconfig(sc) struct wlp_softc *sc;{ struct ifnet *ifp = &(sc->sc_ac.ac_if); u_int8_t status; /* * Reset the 82593. */ IOWrite1(0x00, P0_RESET); DELAY(200); status = IORead1(0x00); if (status != P0_S0_CHNL) { printf("wlp%d: Reset of the Intel 82593 failed (status = %x)\n", ifp->if_unit, status); goto bad; } /* * (1) Set ROM/RAM ENABLE bit to 1 (RAM selected) * (2) Set Page Control Port to 0x00 */ IOWrite1(0x08, IORead1(0x08) | P8_RAM_ROM); IOWrite1(0x09, 0x00); /* * (1) Load 82593 Configuration data into the Transmit Buffer * (2) Reset the Transmit DMA Counter to zero * (3) Issue the Config command to the 82593 * (4) Make sure we get a Configure-Done Interrupt */ { char tmpbuf[20]; tmpbuf[0] = 0x10; tmpbuf[1] = 0x00; tmpbuf[2] = 0x2A; /* AA */ tmpbuf[3] = 0x80; /* 88 */ tmpbuf[4] = 0x0E; /* 2E */ tmpbuf[5] = 0x00; tmpbuf[6] = 0x60; tmpbuf[7] = 0x00; /* 20 */ tmpbuf[8] = 0x02; tmpbuf[9] = 0x00; if (ifp->if_flags & IFF_PROMISC) tmpbuf[9] |= 0x01; tmpbuf[10] = 0x00; tmpbuf[11] = 0x40; tmpbuf[12] = 0x7E; tmpbuf[13] = 0x00; tmpbuf[14] = 0x3F; tmpbuf[15] = 0x07; tmpbuf[16] = 0x30; tmpbuf[17] = 0x08; RW_ResetTXDMA(); MEMWrite(tmpbuf, RW_RXWINDOW, 18); /* Load the Transmit * Buffer */ IOWrite1(0x00, P0_CONFIGURE); } status = I82593_wait(sc, P0_CONFIGURE); if (status != (P0_CONFIGURE | P0_S0_INT | P0_S0_EXEC)) { printf("wlp%d: Configure of the Intel 82593 failed (status = %x)\n", ifp->if_unit, status); goto bad; }#ifdef WLP_DEBUG else { IOWrite1(0x00, P0_NOP | P0_STATUS1); printf("wlp%d: Intel 82593 configured successfully, Chip Signature: %x\n", ifp->if_unit, IORead1(0x00)); }#endif /* * (1) Load the Ethernet address into the Transmit Buffer * (2) Reset the Transmit DMA Counter to zero * (3) Issue the IA-SETUP command to the 82593 * (4) Make sure that we get an IA-SETUP-DONE interrupt. */ RW_ResetTXDMA(); MEMWrite1(RW_RXWINDOW, ETHER_ADDR_LEN); MEMWrite1(RW_RXWINDOW + 1, 0x00); MEMWrite(sc->sc_ac.ac_enaddr, RW_RXWINDOW + 2, ETHER_ADDR_LEN); IOWrite1(0x00, P0_IA_SETUP); status = I82593_wait(sc, P0_IA_SETUP); if (status != (P0_IA_SETUP | P0_S0_INT | P0_S0_EXEC)) { printf("wlp%d: IA-SETUP of the Intel 82593 failed (status = %x)\n", ifp->if_unit, status); goto bad; }#ifdef WLP_DEBUG else { printf("wlp%d: IA-SETUP of the Intel 82593 successful\n", ifp->if_unit); }#endif /* * Reload the multicast address list */ if (sc->sc_ac.ac_multiaddrs) { wlpsetrcr(sc); status = I82593_wait(sc, P0_MC_SETUP); if (status != (P0_MC_SETUP | P0_S0_INT | P0_S0_EXEC)) { printf("wlp%d: MC_SETUP of the Intel 82593 failed (status = %x)\n", ifp->if_unit, status); goto bad; } } /* * (1) Set Serial Data Drive = 0 * (2) Check Transceiver Detect. * (3) If a transceiver is detected, then set the Transceiver * Enable bit to 1. */ IOWrite1(0x0C, IORead1(0x0C) & ~P12_SERIAL_DATA_DRIVE); DELAY(200); status = IORead1(0x0C); if (!(status & P12_TRANSCEIVER_DETECT)) { printf("wlp%d: No optical transceiver detected.\n", ifp->if_unit); } else { IOWrite1(0x0C, status | P12_TRANSCEIVER_ENABLE); } return 0;bad: return 1;}intTestRAM(sc) struct wlp_softc *sc;{ caddr_t tststr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; char tmpbuf[64]; int len = sc->sc_msize; int unit = sc->sc_unit; int i; /* * Copy the test string to memory and read it back. */ bzero(tmpbuf, sizeof(tmpbuf)); MEMWrite(tststr, 0, 20); MEMRead(tmpbuf, 0, 20); if (bcmp(tststr, tmpbuf, 20)) { printf("wlp%d: Unable to read/write onboard RAM\n", unit); goto bad; } /* * Write 0xff to each byte and read it back. */ for (i = 0; i < len; i++) MEMWrite1(i, 0xff); for (i = 0; i < len; i++) if (MEMRead1(i) != 0xff) { printf("wlp%d: Unable to initialize onboard RAM at address %p\n", unit, sc->sc_maddr + i); goto bad; } /* * Write 0x00 to each byte and read it back. */ for (i = 0; i < len; i++) MEMWrite1(i, 0x00); for (i = 0; i < len; i++) if (MEMRead1(i) != 0x00) { printf("wlp%d: Unable to initialize onboard RAM at address %p\n", unit, sc->sc_maddr + i); goto bad; } return 0;bad: return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -