1 /* $NetBSD: if_le.c,v 1.3 1996/10/13 03:34:53 christos Exp $ */ 2 3 #define LEDEBUG 1 /* debug-level: 0 or 1 */ 4 /* #define LE_CHIP_IS_POKEY /* does VS2000 need this ??? */ 5 6 /*- 7 * Copyright (c) 1995 Charles M. Hannum. All rights reserved. 8 * Copyright (c) 1992, 1993 9 * The Regents of the University of California. All rights reserved. 10 * 11 * This code is derived from software contributed to Berkeley by 12 * Ralph Campbell and Rick Macklem. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 3. All advertising materials mentioning features or use of this software 23 * must display the following acknowledgement: 24 * This product includes software developed by the University of 25 * California, Berkeley and its contributors. 26 * 4. Neither the name of the University nor the names of its contributors 27 * may be used to endorse or promote products derived from this software 28 * without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 40 * SUCH DAMAGE. 41 * 42 * @(#)if_le.c 8.2 (Berkeley) 11/16/93 43 */ 44 45 #include "bpfilter.h" 46 47 #include <sys/param.h> 48 #include <sys/syslog.h> 49 #include <sys/socket.h> 50 #include <sys/device.h> 51 52 #include <net/if.h> 53 54 #if INET 55 #include <netinet/in.h> 56 #include <netinet/if_ether.h> 57 #endif 58 59 /* 60 * This would be nice, but it's not yet there... 61 * 62 * #include <machine/autoconf.h> 63 */ 64 65 #include <machine/pte.h> 66 #include <machine/cpu.h> 67 #include <machine/mtpr.h> 68 #include <machine/uvax.h> 69 #include <machine/ka410.h> 70 #include <machine/vsbus.h> 71 72 #include <dev/ic/am7990reg.h> 73 #define LE_NEED_BUF_CONTIG 74 #include <dev/ic/am7990var.h> 75 76 #include <dev/tc/if_levar.h> 77 78 #define xdebug(x) 79 80 #ifdef LE_CHIP_IS_POKEY 81 /* 82 * access LANCE registers and double-check their contents 83 */ 84 #define wbflush() /* do nothing */ 85 void lewritereg(); 86 #define LERDWR(cntl, src, dst) { (dst) = (src); wbflush(); } 87 #define LEWREG(src, dst) lewritereg(&(dst), (src)) 88 #endif 89 90 #define LE_IOSIZE 64*1024 /* 64K of real-mem are reserved and already */ 91 extern void *le_iomem; /* mapped into virt-mem by cpu_steal_pages */ 92 extern u_long le_ioaddr; /* le_iomem is virt, le_ioaddr is phys */ 93 94 #define LE_SOFTC(unit) le_cd.cd_devs[unit] 95 #define LE_DELAY(x) DELAY(x) 96 97 int lematch __P((struct device *, void *, void *)); 98 void leattach __P((struct device *, struct device *, void *)); 99 100 int leintr __P((void *sc)); 101 102 struct cfattach le_ca = { 103 sizeof(struct le_softc), lematch, leattach 104 }; 105 106 integrate void 107 lewrcsr(sc, port, val) 108 struct le_softc *sc; 109 u_int16_t port, val; 110 { 111 struct lereg1 *ler1 = sc->sc_r1; 112 113 #ifdef LE_CHIP_IS_POKEY 114 LEWREG(port, ler1->ler1_rap); 115 LERDWR(port, val, ler1->ler1_rdp); 116 #else 117 ler1->ler1_rap = port; 118 ler1->ler1_rdp = val; 119 #endif 120 } 121 122 integrate u_int16_t 123 lerdcsr(sc, port) 124 struct le_softc *sc; 125 u_int16_t port; 126 { 127 struct lereg1 *ler1 = sc->sc_r1; 128 u_int16_t val; 129 130 #ifdef LE_CHIP_IS_POKEY 131 LEWREG(port, ler1->ler1_rap); 132 LERDWR(0, ler1->ler1_rdp, val); 133 #else 134 ler1->ler1_rap = port; 135 val = ler1->ler1_rdp; 136 #endif 137 return (val); 138 } 139 140 int 141 lematch(parent, match, aux) 142 struct device *parent; 143 void *match, *aux; 144 { 145 struct cfdata *cf = match; 146 struct confargs *ca = aux; 147 148 /* 149 * There could/should be more checks, but for now... 150 */ 151 if (strcmp(ca->ca_name, "le") && 152 strcmp(ca->ca_name, "am7990") && 153 strcmp(ca->ca_name, "AM7990")) 154 return (0); 155 156 return (1); 157 } 158 159 /* 160 * 161 */ 162 void 163 leattach(parent, self, aux) 164 struct device *parent, *self; 165 void *aux; 166 { 167 register struct le_softc *sc = (void *)self; 168 struct confargs *ca = aux; 169 u_char *cp; /* pointer to MAC address */ 170 int i; 171 172 sc->sc_r1 = (void*)uvax_phys2virt(ca->ca_ioaddr); 173 174 sc->sc_am7990.sc_conf3 = 0; 175 sc->sc_am7990.sc_mem = le_iomem; 176 sc->sc_am7990.sc_addr = le_ioaddr; 177 sc->sc_am7990.sc_memsize = LE_IOSIZE; 178 179 xdebug(("leattach: mem=%x, addr=%x, size=%x (%d)\n", 180 sc->sc_am7990.sc_mem, sc->sc_am7990.sc_addr, 181 sc->sc_am7990.sc_memsize, sc->sc_am7990.sc_memsize)); 182 183 sc->sc_am7990.sc_copytodesc = am7990_copytobuf_contig; 184 sc->sc_am7990.sc_copyfromdesc = am7990_copyfrombuf_contig; 185 sc->sc_am7990.sc_copytobuf = am7990_copytobuf_contig; 186 sc->sc_am7990.sc_copyfrombuf = am7990_copyfrombuf_contig; 187 sc->sc_am7990.sc_zerobuf = am7990_zerobuf_contig; 188 189 /* 190 * Get the ethernet address out of rom 191 */ 192 for (i = 0; i < sizeof(sc->sc_am7990.sc_arpcom.ac_enaddr); i++) { 193 int *eaddr = (void*)uvax_phys2virt(ca->ca_enaddr); 194 sc->sc_am7990.sc_arpcom.ac_enaddr[i] = (u_char)eaddr[i]; 195 } 196 197 bcopy(self->dv_xname, sc->sc_am7990.sc_arpcom.ac_if.if_xname, IFNAMSIZ); 198 am7990_config(&sc->sc_am7990); 199 200 #ifdef LEDEBUG 201 sc->sc_am7990.sc_debug = LEDEBUG; 202 #endif 203 204 vsbus_intr_register(ca, am7990_intr, &sc->sc_am7990); 205 vsbus_intr_enable(ca); 206 } 207 208 integrate void 209 lehwinit(sc) 210 struct le_softc *sc; 211 { 212 } 213 214 #ifdef LE_CHIP_IS_POKEY 215 /* 216 * Write a lance register port, reading it back to ensure success. This seems 217 * to be necessary during initialization, since the chip appears to be a bit 218 * pokey sometimes. 219 */ 220 void 221 lewritereg(regptr, val) 222 register volatile u_short *regptr; 223 register u_short val; 224 { 225 register int i = 0; 226 227 while (*regptr != val) { 228 *regptr = val; 229 wbflush(); 230 if (++i > 10000) { 231 printf("le: Reg did not settle (to x%x): x%x\n", val, 232 *regptr); 233 return; 234 } 235 DELAY(100); 236 } 237 } 238 #endif 239