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