1 1.63 thorpej /* $NetBSD: if_le.c,v 1.63 2024/01/16 05:48:28 thorpej Exp $ */ 2 1.44 thorpej 3 1.44 thorpej /*- 4 1.44 thorpej * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 1.44 thorpej * All rights reserved. 6 1.44 thorpej * 7 1.44 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.47 mycroft * by Charles M. Hannum and by Jason R. Thorpe. 9 1.44 thorpej * 10 1.44 thorpej * Redistribution and use in source and binary forms, with or without 11 1.44 thorpej * modification, are permitted provided that the following conditions 12 1.44 thorpej * are met: 13 1.44 thorpej * 1. Redistributions of source code must retain the above copyright 14 1.44 thorpej * notice, this list of conditions and the following disclaimer. 15 1.44 thorpej * 2. Redistributions in binary form must reproduce the above copyright 16 1.44 thorpej * notice, this list of conditions and the following disclaimer in the 17 1.44 thorpej * documentation and/or other materials provided with the distribution. 18 1.44 thorpej * 19 1.44 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.44 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.44 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.44 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.44 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.44 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.44 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.44 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.44 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.44 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.44 thorpej * POSSIBILITY OF SUCH DAMAGE. 30 1.44 thorpej */ 31 1.20 cgd 32 1.24 mycroft /*- 33 1.24 mycroft * Copyright (c) 1992, 1993 34 1.24 mycroft * The Regents of the University of California. All rights reserved. 35 1.24 mycroft * 36 1.24 mycroft * This code is derived from software contributed to Berkeley by 37 1.24 mycroft * Ralph Campbell and Rick Macklem. 38 1.1 cgd * 39 1.1 cgd * Redistribution and use in source and binary forms, with or without 40 1.1 cgd * modification, are permitted provided that the following conditions 41 1.1 cgd * are met: 42 1.1 cgd * 1. Redistributions of source code must retain the above copyright 43 1.1 cgd * notice, this list of conditions and the following disclaimer. 44 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 45 1.1 cgd * notice, this list of conditions and the following disclaimer in the 46 1.1 cgd * documentation and/or other materials provided with the distribution. 47 1.54 agc * 3. Neither the name of the University nor the names of its contributors 48 1.1 cgd * may be used to endorse or promote products derived from this software 49 1.1 cgd * without specific prior written permission. 50 1.1 cgd * 51 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 52 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 55 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 1.1 cgd * SUCH DAMAGE. 62 1.1 cgd * 63 1.24 mycroft * @(#)if_le.c 8.2 (Berkeley) 11/16/93 64 1.1 cgd */ 65 1.49 gmcgarry 66 1.49 gmcgarry #include <sys/cdefs.h> 67 1.63 thorpej __KERNEL_RCSID(0, "$NetBSD: if_le.c,v 1.63 2024/01/16 05:48:28 thorpej Exp $"); 68 1.1 cgd 69 1.45 jonathan #include "opt_inet.h" 70 1.1 cgd 71 1.5 mycroft #include <sys/param.h> 72 1.5 mycroft #include <sys/systm.h> 73 1.24 mycroft #include <sys/device.h> 74 1.5 mycroft 75 1.5 mycroft #include <net/if.h> 76 1.38 is #include <net/if_ether.h> 77 1.39 thorpej #include <net/if_media.h> 78 1.1 cgd 79 1.46 drochner #include <dev/ic/lancereg.h> 80 1.46 drochner #include <dev/ic/lancevar.h> 81 1.30 thorpej #include <dev/ic/am7990var.h> 82 1.30 thorpej 83 1.36 thorpej #include <hp300/dev/diovar.h> 84 1.36 thorpej #include <hp300/dev/diodevs.h> 85 1.5 mycroft #include <hp300/dev/if_lereg.h> 86 1.1 cgd 87 1.43 thorpej #include "opt_useleds.h" 88 1.43 thorpej 89 1.43 thorpej #ifdef USELEDS 90 1.43 thorpej #include <hp300/hp300/leds.h> 91 1.43 thorpej #endif 92 1.43 thorpej 93 1.52 gmcgarry struct le_softc { 94 1.52 gmcgarry struct am7990_softc sc_am7990; /* glue to MI code */ 95 1.55 tsutsui 96 1.55 tsutsui bus_space_tag_t sc_bst; 97 1.55 tsutsui 98 1.52 gmcgarry bus_space_handle_t sc_bsh0; /* DIO registers */ 99 1.52 gmcgarry bus_space_handle_t sc_bsh1; /* LANCE registers */ 100 1.52 gmcgarry bus_space_handle_t sc_bsh2; /* buffer area */ 101 1.55 tsutsui }; 102 1.52 gmcgarry 103 1.60 tsutsui static int lematch(device_t, cfdata_t, void *); 104 1.60 tsutsui static void leattach(device_t, device_t, void *); 105 1.36 thorpej 106 1.60 tsutsui CFATTACH_DECL_NEW(le, sizeof(struct le_softc), 107 1.51 thorpej lematch, leattach, NULL, NULL); 108 1.36 thorpej 109 1.56 thorpej static int leintr(void *); 110 1.13 mycroft 111 1.48 mrg #if defined(_KERNEL_OPT) 112 1.46 drochner #include "opt_ddb.h" 113 1.46 drochner #endif 114 1.46 drochner 115 1.56 thorpej static void le_copytobuf(struct lance_softc *, void *, int, int); 116 1.56 thorpej static void le_copyfrombuf(struct lance_softc *, void *, int, int); 117 1.56 thorpej static void le_zerobuf(struct lance_softc *, int, int); 118 1.44 thorpej 119 1.1 cgd /* offsets for: ID, REGS, MEM, NVRAM */ 120 1.56 thorpej static const int lestd[] = { 0, 0x4000, 0x8000, 0xC008 }; 121 1.1 cgd 122 1.56 thorpej static void 123 1.57 tsutsui lewrcsr(struct lance_softc *sc, uint16_t port, uint16_t val) 124 1.13 mycroft { 125 1.44 thorpej struct le_softc *lesc = (struct le_softc *)sc; 126 1.44 thorpej bus_space_tag_t bst = lesc->sc_bst; 127 1.44 thorpej bus_space_handle_t bsh0 = lesc->sc_bsh0; 128 1.44 thorpej bus_space_handle_t bsh1 = lesc->sc_bsh1; 129 1.13 mycroft 130 1.13 mycroft do { 131 1.44 thorpej bus_space_write_2(bst, bsh1, LER1_RAP, port); 132 1.44 thorpej } while ((bus_space_read_1(bst, bsh0, LER0_STATUS) & LE_ACK) == 0); 133 1.13 mycroft do { 134 1.44 thorpej bus_space_write_2(bst, bsh1, LER1_RDP, val); 135 1.44 thorpej } while ((bus_space_read_1(bst, bsh0, LER0_STATUS) & LE_ACK) == 0); 136 1.13 mycroft } 137 1.13 mycroft 138 1.57 tsutsui static uint16_t 139 1.57 tsutsui lerdcsr(struct lance_softc *sc, uint16_t port) 140 1.13 mycroft { 141 1.44 thorpej struct le_softc *lesc = (struct le_softc *)sc; 142 1.44 thorpej bus_space_tag_t bst = lesc->sc_bst; 143 1.44 thorpej bus_space_handle_t bsh0 = lesc->sc_bsh0; 144 1.44 thorpej bus_space_handle_t bsh1 = lesc->sc_bsh1; 145 1.57 tsutsui uint16_t val; 146 1.13 mycroft 147 1.13 mycroft do { 148 1.44 thorpej bus_space_write_2(bst, bsh1, LER1_RAP, port); 149 1.44 thorpej } while ((bus_space_read_1(bst, bsh0, LER0_STATUS) & LE_ACK) == 0); 150 1.13 mycroft do { 151 1.44 thorpej val = bus_space_read_2(bst, bsh1, LER1_RDP); 152 1.44 thorpej } while ((bus_space_read_1(bst, bsh0, LER0_STATUS) & LE_ACK) == 0); 153 1.44 thorpej 154 1.59 tsutsui return val; 155 1.13 mycroft } 156 1.13 mycroft 157 1.56 thorpej static int 158 1.60 tsutsui lematch(device_t parent, cfdata_t cf, void *aux) 159 1.36 thorpej { 160 1.36 thorpej struct dio_attach_args *da = aux; 161 1.36 thorpej 162 1.36 thorpej if (da->da_id == DIO_DEVICE_ID_LAN) 163 1.59 tsutsui return 1; 164 1.59 tsutsui return 0; 165 1.36 thorpej } 166 1.23 thorpej 167 1.1 cgd /* 168 1.1 cgd * Interface exists: make available by filling in network interface 169 1.1 cgd * record. System will initialize the interface when it is ready 170 1.1 cgd * to accept packets. 171 1.1 cgd */ 172 1.56 thorpej static void 173 1.60 tsutsui leattach(device_t parent, device_t self, void *aux) 174 1.1 cgd { 175 1.60 tsutsui struct le_softc *lesc = device_private(self); 176 1.60 tsutsui struct lance_softc *sc = &lesc->sc_am7990.lsc; 177 1.36 thorpej struct dio_attach_args *da = aux; 178 1.44 thorpej bus_space_tag_t bst = da->da_bst; 179 1.44 thorpej bus_space_handle_t bsh0, bsh1, bsh2; 180 1.44 thorpej bus_size_t offset; 181 1.53 gmcgarry int i; 182 1.36 thorpej 183 1.60 tsutsui sc->sc_dev = self; 184 1.60 tsutsui 185 1.44 thorpej if (bus_space_map(bst, (bus_addr_t)dio_scodetopa(da->da_scode), 186 1.44 thorpej da->da_size, 0, &bsh0)) { 187 1.60 tsutsui aprint_error(": can't map LANCE registers\n"); 188 1.36 thorpej return; 189 1.36 thorpej } 190 1.1 cgd 191 1.44 thorpej if (bus_space_subregion(bst, bsh0, lestd[1], LER1_SIZE, &bsh1)) { 192 1.60 tsutsui aprint_error(": can't subregion LANCE space\n"); 193 1.44 thorpej return; 194 1.44 thorpej } 195 1.44 thorpej 196 1.44 thorpej if (bus_space_subregion(bst, bsh0, lestd[2], LE_BUFSIZE, &bsh2)) { 197 1.60 tsutsui aprint_error(": can't subregion buffer space\n"); 198 1.44 thorpej return; 199 1.44 thorpej } 200 1.44 thorpej 201 1.44 thorpej lesc->sc_bst = bst; 202 1.44 thorpej lesc->sc_bsh0 = bsh0; 203 1.44 thorpej lesc->sc_bsh1 = bsh1; 204 1.44 thorpej lesc->sc_bsh2 = bsh2; 205 1.44 thorpej 206 1.44 thorpej bus_space_write_1(bst, bsh0, LER0_ID, 0xff); 207 1.24 mycroft DELAY(100); 208 1.24 mycroft 209 1.24 mycroft sc->sc_conf3 = LE_C3_BSWP; 210 1.24 mycroft sc->sc_addr = 0; 211 1.44 thorpej sc->sc_memsize = LE_BUFSIZE; 212 1.1 cgd 213 1.1 cgd /* 214 1.1 cgd * Read the ethernet address off the board, one nibble at a time. 215 1.1 cgd */ 216 1.44 thorpej offset = lestd[3]; 217 1.38 is for (i = 0; i < sizeof(sc->sc_enaddr); i++) { 218 1.44 thorpej sc->sc_enaddr[i] = 219 1.44 thorpej (bus_space_read_1(bst, bsh0, ++offset) & 0xf) << 4; 220 1.44 thorpej offset++; 221 1.44 thorpej sc->sc_enaddr[i] |= 222 1.44 thorpej (bus_space_read_1(bst, bsh0, ++offset) & 0xf); 223 1.44 thorpej offset++; 224 1.1 cgd } 225 1.1 cgd 226 1.44 thorpej sc->sc_copytodesc = le_copytobuf; 227 1.44 thorpej sc->sc_copyfromdesc = le_copyfrombuf; 228 1.44 thorpej sc->sc_copytobuf = le_copytobuf; 229 1.44 thorpej sc->sc_copyfrombuf = le_copyfrombuf; 230 1.44 thorpej sc->sc_zerobuf = le_zerobuf; 231 1.25 thorpej 232 1.30 thorpej sc->sc_rdcsr = lerdcsr; 233 1.30 thorpej sc->sc_wrcsr = lewrcsr; 234 1.30 thorpej sc->sc_hwinit = NULL; 235 1.30 thorpej 236 1.46 drochner am7990_config(&lesc->sc_am7990); 237 1.24 mycroft 238 1.27 thorpej /* Establish the interrupt handler. */ 239 1.63 thorpej (void) dio_intr_establish(leintr, sc, da->da_ipl, ISRPRI_NET); 240 1.44 thorpej bus_space_write_1(bst, bsh0, LER0_STATUS, LE_IE); 241 1.1 cgd } 242 1.14 mycroft 243 1.56 thorpej static int 244 1.52 gmcgarry leintr(void *arg) 245 1.26 thorpej { 246 1.46 drochner struct lance_softc *sc = arg; 247 1.42 mycroft #ifdef USELEDS 248 1.57 tsutsui uint16_t isr; 249 1.26 thorpej 250 1.26 thorpej isr = lerdcsr(sc, LE_CSR0); 251 1.26 thorpej 252 1.26 thorpej if ((isr & LE_C0_INTR) == 0) 253 1.59 tsutsui return 0; 254 1.26 thorpej 255 1.26 thorpej if (isr & LE_C0_RINT) 256 1.43 thorpej ledcontrol(0, 0, LED_LANRCV); 257 1.26 thorpej 258 1.26 thorpej if (isr & LE_C0_TINT) 259 1.43 thorpej ledcontrol(0, 0, LED_LANXMT); 260 1.26 thorpej #endif /* USELEDS */ 261 1.26 thorpej 262 1.59 tsutsui return am7990_intr(sc); 263 1.44 thorpej } 264 1.44 thorpej 265 1.56 thorpej static void 266 1.52 gmcgarry le_copytobuf(struct lance_softc *sc, void *from, int boff, int len) 267 1.44 thorpej { 268 1.44 thorpej struct le_softc *lesc = (struct le_softc *)sc; 269 1.44 thorpej 270 1.44 thorpej bus_space_write_region_1(lesc->sc_bst, lesc->sc_bsh2, boff, from, len); 271 1.44 thorpej } 272 1.44 thorpej 273 1.56 thorpej static void 274 1.52 gmcgarry le_copyfrombuf(struct lance_softc *sc, void *to, int boff, int len) 275 1.44 thorpej { 276 1.44 thorpej struct le_softc *lesc = (struct le_softc *)sc; 277 1.44 thorpej 278 1.44 thorpej bus_space_read_region_1(lesc->sc_bst, lesc->sc_bsh2, boff, to, len); 279 1.44 thorpej } 280 1.44 thorpej 281 1.56 thorpej static void 282 1.52 gmcgarry le_zerobuf(struct lance_softc *sc, int boff, int len) 283 1.44 thorpej { 284 1.44 thorpej struct le_softc *lesc = (struct le_softc *)sc; 285 1.44 thorpej 286 1.44 thorpej bus_space_set_region_1(lesc->sc_bst, lesc->sc_bsh2, boff, 0, len); 287 1.26 thorpej } 288