1 /* $NetBSD: if_le.c,v 1.26 2003/08/07 16:30:07 agc Exp $ */ 2 3 /*- 4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace 9 * Simulation Facility, NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /*- 41 * Copyright (c) 1992, 1993 42 * The Regents of the University of California. All rights reserved. 43 * 44 * This code is derived from software contributed to Berkeley by 45 * Ralph Campbell and Rick Macklem. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 1. Redistributions of source code must retain the above copyright 51 * notice, this list of conditions and the following disclaimer. 52 * 2. Redistributions in binary form must reproduce the above copyright 53 * notice, this list of conditions and the following disclaimer in the 54 * documentation and/or other materials provided with the distribution. 55 * 3. Neither the name of the University nor the names of its contributors 56 * may be used to endorse or promote products derived from this software 57 * without specific prior written permission. 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * SUCH DAMAGE. 70 * 71 * @(#)if_le.c 8.2 (Berkeley) 11/16/93 72 */ 73 74 #include <sys/cdefs.h> 75 __KERNEL_RCSID(0, "$NetBSD: if_le.c,v 1.26 2003/08/07 16:30:07 agc Exp $"); 76 77 #include "opt_inet.h" 78 #include "bpfilter.h" 79 80 #include <sys/param.h> 81 #include <sys/syslog.h> 82 #include <sys/socket.h> 83 #include <sys/device.h> 84 #include <sys/reboot.h> 85 86 #include <uvm/uvm_extern.h> 87 88 #include <net/if.h> 89 #include <net/if_ether.h> 90 #include <net/if_media.h> 91 92 #ifdef INET 93 #include <netinet/in.h> 94 #include <netinet/if_inarp.h> 95 #endif 96 97 #include <machine/cpu.h> 98 #include <machine/nexus.h> 99 #include <machine/scb.h> 100 101 #include <dev/ic/lancereg.h> 102 #include <dev/ic/lancevar.h> 103 #include <dev/ic/am7990reg.h> 104 #include <dev/ic/am7990var.h> 105 106 #include "ioconf.h" 107 108 #define LEVEC 0xd4 /* Interrupt vector on 3300/3400 */ 109 110 struct le_softc { 111 struct am7990_softc sc_am7990; /* Must be first */ 112 struct evcnt sc_intrcnt; 113 volatile u_short *sc_rap; 114 volatile u_short *sc_rdp; 115 }; 116 117 int le_ibus_match __P((struct device *, struct cfdata *, void *)); 118 void le_ibus_attach __P((struct device *, struct device *, void *)); 119 void lewrcsr __P((struct lance_softc *, u_int16_t, u_int16_t)); 120 u_int16_t lerdcsr __P((struct lance_softc *, u_int16_t)); 121 void lance_copytobuf_gap2 __P((struct lance_softc *, void *, int, int)); 122 void lance_copyfrombuf_gap2 __P((struct lance_softc *, void *, int, int)); 123 void lance_zerobuf_gap2 __P((struct lance_softc *, int, int)); 124 125 CFATTACH_DECL(le_ibus, sizeof(struct le_softc), 126 le_ibus_match, le_ibus_attach, NULL, NULL); 127 128 void 129 lewrcsr(ls, port, val) 130 struct lance_softc *ls; 131 u_int16_t port, val; 132 { 133 struct le_softc *sc = (void *)ls; 134 135 *sc->sc_rap = port; 136 *sc->sc_rdp = val; 137 } 138 139 u_int16_t 140 lerdcsr(ls, port) 141 struct lance_softc *ls; 142 u_int16_t port; 143 { 144 struct le_softc *sc = (void *)ls; 145 146 *sc->sc_rap = port; 147 return *sc->sc_rdp; 148 } 149 150 int 151 le_ibus_match(parent, cf, aux) 152 struct device *parent; 153 struct cfdata *cf; 154 void *aux; 155 { 156 struct bp_conf *bp = aux; 157 158 if (strcmp("lance", bp->type)) 159 return 0; 160 return 1; 161 } 162 163 void 164 le_ibus_attach(parent, self, aux) 165 struct device *parent, *self; 166 void *aux; 167 { 168 struct le_softc *sc = (void *)self; 169 int *lance_addr; 170 int i, vec, br; 171 172 sc->sc_rdp = (short *)vax_map_physmem(0x20084400, 1); 173 sc->sc_rap = sc->sc_rdp + 2; 174 175 /* 176 * Set interrupt vector, by forcing an interrupt. 177 */ 178 scb_vecref(0, 0); /* Clear vector ref */ 179 *sc->sc_rap = LE_CSR0; 180 *sc->sc_rdp = LE_C0_STOP; 181 DELAY(100); 182 *sc->sc_rdp = LE_C0_INIT|LE_C0_INEA; 183 DELAY(100000); 184 i = scb_vecref(&vec, &br); 185 if (i == 0 || vec == 0) 186 return; 187 scb_vecalloc(vec, (void (*)(void *))am7990_intr, sc, 188 SCB_ISTACK, &sc->sc_intrcnt); 189 evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL, 190 self->dv_xname, "intr"); 191 192 printf(": vec %o ipl %x\n%s", vec, br, self->dv_xname); 193 /* 194 * MD functions. 195 */ 196 sc->sc_am7990.lsc.sc_rdcsr = lerdcsr; 197 sc->sc_am7990.lsc.sc_wrcsr = lewrcsr; 198 sc->sc_am7990.lsc.sc_nocarrier = NULL; 199 200 sc->sc_am7990.lsc.sc_mem = 201 (void *)uvm_km_valloc(kernel_map, (128 * 1024)); 202 if (sc->sc_am7990.lsc.sc_mem == 0) 203 return; 204 205 ioaccess((vaddr_t)sc->sc_am7990.lsc.sc_mem, 0x20120000, 206 (128 * 1024) >> VAX_PGSHIFT); 207 208 209 sc->sc_am7990.lsc.sc_addr = 0; 210 sc->sc_am7990.lsc.sc_memsize = (64 * 1024); 211 212 sc->sc_am7990.lsc.sc_copytodesc = lance_copytobuf_gap2; 213 sc->sc_am7990.lsc.sc_copyfromdesc = lance_copyfrombuf_gap2; 214 sc->sc_am7990.lsc.sc_copytobuf = lance_copytobuf_gap2; 215 sc->sc_am7990.lsc.sc_copyfrombuf = lance_copyfrombuf_gap2; 216 sc->sc_am7990.lsc.sc_zerobuf = lance_zerobuf_gap2; 217 218 /* 219 * Get the ethernet address out of rom 220 */ 221 lance_addr = (int *)vax_map_physmem(0x20084200, 1); 222 for (i = 0; i < 6; i++) 223 sc->sc_am7990.lsc.sc_enaddr[i] = (u_char)lance_addr[i]; 224 vax_unmap_physmem((vaddr_t)lance_addr, 1); 225 226 bcopy(self->dv_xname, sc->sc_am7990.lsc.sc_ethercom.ec_if.if_xname, 227 IFNAMSIZ); 228 am7990_config(&sc->sc_am7990); 229 } 230 231 /* 232 * gap2: two bytes of data followed by two bytes of pad. 233 * 234 * Buffers must be 4-byte aligned. The code doesn't worry about 235 * doing an extra byte. 236 */ 237 238 void 239 lance_copytobuf_gap2(sc, fromv, boff, len) 240 struct lance_softc *sc; 241 void *fromv; 242 int boff; 243 register int len; 244 { 245 volatile caddr_t buf = sc->sc_mem; 246 register caddr_t from = fromv; 247 register volatile u_int16_t *bptr; 248 249 if (boff & 0x1) { 250 /* handle unaligned first byte */ 251 bptr = ((volatile u_int16_t *)buf) + (boff - 1); 252 *bptr = (*from++ << 8) | (*bptr & 0xff); 253 bptr += 2; 254 len--; 255 } else 256 bptr = ((volatile u_int16_t *)buf) + boff; 257 while (len > 1) { 258 *bptr = (from[1] << 8) | (from[0] & 0xff); 259 bptr += 2; 260 from += 2; 261 len -= 2; 262 } 263 if (len == 1) 264 *bptr = (u_int16_t)*from; 265 } 266 267 void 268 lance_copyfrombuf_gap2(sc, tov, boff, len) 269 struct lance_softc *sc; 270 void *tov; 271 int boff, len; 272 { 273 volatile caddr_t buf = sc->sc_mem; 274 register caddr_t to = tov; 275 register volatile u_int16_t *bptr; 276 register u_int16_t tmp; 277 278 if (boff & 0x1) { 279 /* handle unaligned first byte */ 280 bptr = ((volatile u_int16_t *)buf) + (boff - 1); 281 *to++ = (*bptr >> 8) & 0xff; 282 bptr += 2; 283 len--; 284 } else 285 bptr = ((volatile u_int16_t *)buf) + boff; 286 while (len > 1) { 287 tmp = *bptr; 288 *to++ = tmp & 0xff; 289 *to++ = (tmp >> 8) & 0xff; 290 bptr += 2; 291 len -= 2; 292 } 293 if (len == 1) 294 *to = *bptr & 0xff; 295 } 296 297 void 298 lance_zerobuf_gap2(sc, boff, len) 299 struct lance_softc *sc; 300 int boff, len; 301 { 302 volatile caddr_t buf = sc->sc_mem; 303 register volatile u_int16_t *bptr; 304 305 if ((unsigned)boff & 0x1) { 306 bptr = ((volatile u_int16_t *)buf) + (boff - 1); 307 *bptr &= 0xff; 308 bptr += 2; 309 len--; 310 } else 311 bptr = ((volatile u_int16_t *)buf) + boff; 312 while (len > 0) { 313 *bptr = 0; 314 bptr += 2; 315 len -= 2; 316 } 317 } 318