1 1.47 andvar /* $NetBSD: if_le.c,v 1.47 2023/08/01 21:26:27 andvar Exp $ */ 2 1.7 cgd 3 1.15 chopps /*- 4 1.31 mycroft * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 5 1.27 thorpej * All rights reserved. 6 1.27 thorpej * 7 1.27 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.31 mycroft * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace 9 1.31 mycroft * Simulation Facility, NASA Ames Research Center. 10 1.27 thorpej * 11 1.27 thorpej * Redistribution and use in source and binary forms, with or without 12 1.27 thorpej * modification, are permitted provided that the following conditions 13 1.27 thorpej * are met: 14 1.27 thorpej * 1. Redistributions of source code must retain the above copyright 15 1.27 thorpej * notice, this list of conditions and the following disclaimer. 16 1.27 thorpej * 2. Redistributions in binary form must reproduce the above copyright 17 1.27 thorpej * notice, this list of conditions and the following disclaimer in the 18 1.27 thorpej * documentation and/or other materials provided with the distribution. 19 1.27 thorpej * 20 1.27 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.27 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.27 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.27 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.27 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.27 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.27 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.27 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.27 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.27 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.27 thorpej * POSSIBILITY OF SUCH DAMAGE. 31 1.27 thorpej */ 32 1.27 thorpej 33 1.27 thorpej /*- 34 1.27 thorpej * Copyright (c) 1997 Bernd Ernesti. All rights reserved. 35 1.15 chopps * Copyright (c) 1992, 1993 36 1.15 chopps * The Regents of the University of California. All rights reserved. 37 1.15 chopps * 38 1.15 chopps * This code is derived from software contributed to Berkeley by 39 1.15 chopps * Ralph Campbell and Rick Macklem. 40 1.1 mw * 41 1.1 mw * Redistribution and use in source and binary forms, with or without 42 1.1 mw * modification, are permitted provided that the following conditions 43 1.1 mw * are met: 44 1.1 mw * 1. Redistributions of source code must retain the above copyright 45 1.1 mw * notice, this list of conditions and the following disclaimer. 46 1.1 mw * 2. Redistributions in binary form must reproduce the above copyright 47 1.1 mw * notice, this list of conditions and the following disclaimer in the 48 1.1 mw * documentation and/or other materials provided with the distribution. 49 1.1 mw * 3. All advertising materials mentioning features or use of this software 50 1.1 mw * must display the following acknowledgement: 51 1.26 veego * This product includes software developed for the NetBSD Project 52 1.27 thorpej * by Bernd Ernesti. 53 1.1 mw * This product includes software developed by the University of 54 1.1 mw * California, Berkeley and its contributors. 55 1.1 mw * 4. Neither the name of the University nor the names of its contributors 56 1.1 mw * may be used to endorse or promote products derived from this software 57 1.1 mw * without specific prior written permission. 58 1.1 mw * 59 1.1 mw * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60 1.1 mw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 1.1 mw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 1.1 mw * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63 1.1 mw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 1.1 mw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 1.1 mw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 1.1 mw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 1.1 mw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 1.1 mw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 1.1 mw * SUCH DAMAGE. 70 1.1 mw * 71 1.15 chopps * @(#)if_le.c 8.2 (Berkeley) 11/16/93 72 1.1 mw */ 73 1.1 mw 74 1.29 jonathan #include "opt_inet.h" 75 1.36 aymeric 76 1.36 aymeric #include <sys/cdefs.h> 77 1.47 andvar __KERNEL_RCSID(0, "$NetBSD: if_le.c,v 1.47 2023/08/01 21:26:27 andvar Exp $"); 78 1.36 aymeric 79 1.1 mw 80 1.5 chopps #include <sys/param.h> 81 1.5 chopps #include <sys/systm.h> 82 1.5 chopps #include <sys/mbuf.h> 83 1.15 chopps #include <sys/syslog.h> 84 1.5 chopps #include <sys/socket.h> 85 1.6 chopps #include <sys/device.h> 86 1.5 chopps 87 1.5 chopps #include <net/if.h> 88 1.23 is #include <net/if_ether.h> 89 1.24 thorpej #include <net/if_media.h> 90 1.1 mw 91 1.1 mw #ifdef INET 92 1.5 chopps #include <netinet/in.h> 93 1.23 is #include <netinet/if_inarp.h> 94 1.1 mw #endif 95 1.1 mw 96 1.5 chopps #include <machine/cpu.h> 97 1.15 chopps 98 1.6 chopps #include <amiga/amiga/device.h> 99 1.10 chopps #include <amiga/amiga/isr.h> 100 1.21 thorpej 101 1.30 drochner #include <dev/ic/lancereg.h> 102 1.30 drochner #include <dev/ic/lancevar.h> 103 1.21 thorpej #include <dev/ic/am7990reg.h> 104 1.21 thorpej #include <dev/ic/am7990var.h> 105 1.21 thorpej 106 1.9 chopps #include <amiga/dev/zbusvar.h> 107 1.15 chopps #include <amiga/dev/if_levar.h> 108 1.6 chopps 109 1.42 tsutsui int le_zbus_match(device_t, cfdata_t, void *); 110 1.42 tsutsui void le_zbus_attach(device_t, device_t, void *); 111 1.6 chopps 112 1.42 tsutsui CFATTACH_DECL_NEW(le_zbus, sizeof(struct le_softc), 113 1.38 thorpej le_zbus_match, le_zbus_attach, NULL, NULL); 114 1.17 thorpej 115 1.33 mrg #if defined(_KERNEL_OPT) 116 1.30 drochner #include "opt_ddb.h" 117 1.30 drochner #endif 118 1.30 drochner 119 1.30 drochner #ifdef DDB 120 1.30 drochner #define integrate 121 1.30 drochner #define hide 122 1.30 drochner #else 123 1.41 perry #define integrate static inline 124 1.30 drochner #define hide static 125 1.30 drochner #endif 126 1.30 drochner 127 1.35 aymeric hide void lepcnet_reset(struct lance_softc *); 128 1.35 aymeric hide void lewrcsr(struct lance_softc *, u_int16_t, u_int16_t); 129 1.35 aymeric hide u_int16_t lerdcsr(struct lance_softc *, u_int16_t); 130 1.35 aymeric 131 1.35 aymeric hide u_int16_t ariadne_swapreg(u_int16_t); 132 1.35 aymeric hide void ariadne_wrcsr(struct lance_softc *, u_int16_t, u_int16_t); 133 1.35 aymeric hide u_int16_t ariadne_rdcsr(struct lance_softc *, u_int16_t); 134 1.35 aymeric hide void ariadne_wribcr(struct lance_softc *, u_int16_t, u_int16_t); 135 1.35 aymeric integrate void ariadne_copytodesc_word(struct lance_softc *, void *, int, int); 136 1.35 aymeric integrate void ariadne_copyfromdesc_word(struct lance_softc *, void *, 137 1.35 aymeric int, int); 138 1.35 aymeric integrate void ariadne_copytobuf_word(struct lance_softc *, void *, int, int); 139 1.35 aymeric integrate void ariadne_copyfrombuf_word(struct lance_softc *, void *, int, int); 140 1.35 aymeric integrate void ariadne_zerobuf_word(struct lance_softc *, int, int); 141 1.35 aymeric void ariadne_autoselect(struct lance_softc *, int); 142 1.35 aymeric int ariadne_mediachange(struct lance_softc *); 143 1.35 aymeric void ariadne_hwinit(struct lance_softc *); 144 1.26 veego 145 1.35 aymeric /* 146 1.26 veego * Media types supported by the Ariadne. 147 1.26 veego */ 148 1.26 veego int lemedia_ariadne[] = { 149 1.26 veego IFM_ETHER | IFM_10_T, 150 1.26 veego IFM_ETHER | IFM_10_2, 151 1.26 veego IFM_ETHER | IFM_AUTO, 152 1.26 veego }; 153 1.42 tsutsui #define NLEMEDIA_ARIADNE __arraycount(lemedia_ariadne) 154 1.26 veego 155 1.26 veego 156 1.26 veego hide u_int16_t 157 1.35 aymeric ariadne_swapreg(u_int16_t val) 158 1.26 veego { 159 1.26 veego 160 1.26 veego return (((val & 0xff) << 8 ) | (( val >> 8) & 0xff)); 161 1.26 veego } 162 1.26 veego 163 1.26 veego hide void 164 1.35 aymeric ariadne_wrcsr(struct lance_softc *sc, u_int16_t port, u_int16_t val) 165 1.26 veego { 166 1.26 veego struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1; 167 1.26 veego 168 1.26 veego ler1->ler1_rap = ariadne_swapreg(port); 169 1.26 veego ler1->ler1_rdp = ariadne_swapreg(val); 170 1.26 veego } 171 1.26 veego 172 1.26 veego hide u_int16_t 173 1.35 aymeric ariadne_rdcsr(struct lance_softc *sc, u_int16_t port) 174 1.26 veego { 175 1.26 veego struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1; 176 1.26 veego u_int16_t val; 177 1.26 veego 178 1.26 veego ler1->ler1_rap = ariadne_swapreg(port); 179 1.26 veego val = ariadne_swapreg(ler1->ler1_rdp); 180 1.26 veego return (val); 181 1.26 veego } 182 1.26 veego 183 1.26 veego hide void 184 1.35 aymeric ariadne_wribcr(struct lance_softc *sc, u_int16_t port, u_int16_t val) 185 1.26 veego { 186 1.26 veego struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1; 187 1.26 veego 188 1.26 veego ler1->ler1_rap = ariadne_swapreg(port); 189 1.26 veego ler1->ler1_idp = ariadne_swapreg(val); 190 1.26 veego } 191 1.26 veego 192 1.21 thorpej hide void 193 1.35 aymeric lewrcsr(struct lance_softc *sc, u_int16_t port, u_int16_t val) 194 1.15 chopps { 195 1.21 thorpej struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1; 196 1.6 chopps 197 1.15 chopps ler1->ler1_rap = port; 198 1.15 chopps ler1->ler1_rdp = val; 199 1.15 chopps } 200 1.6 chopps 201 1.21 thorpej hide u_int16_t 202 1.35 aymeric lerdcsr(struct lance_softc *sc, u_int16_t port) 203 1.6 chopps { 204 1.21 thorpej struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1; 205 1.15 chopps u_int16_t val; 206 1.6 chopps 207 1.15 chopps ler1->ler1_rap = port; 208 1.15 chopps val = ler1->ler1_rdp; 209 1.15 chopps return (val); 210 1.15 chopps } 211 1.6 chopps 212 1.26 veego hide void 213 1.35 aymeric lepcnet_reset(struct lance_softc *sc) 214 1.26 veego { 215 1.26 veego struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1; 216 1.26 veego volatile int dummy; 217 1.26 veego 218 1.26 veego dummy = ler1->ler1_reset; /* Reset PCNet-ISA */ 219 1.46 christos __USE(dummy); 220 1.26 veego } 221 1.26 veego 222 1.26 veego void 223 1.35 aymeric ariadne_autoselect(struct lance_softc *sc, int on) 224 1.26 veego { 225 1.26 veego 226 1.26 veego /* 227 1.26 veego * on = 0: autoselect disabled 228 1.26 veego * on = 1: autoselect enabled 229 1.26 veego */ 230 1.26 veego if (on == 0) 231 1.26 veego ariadne_wribcr(sc, LE_BCR_MC, 0x0000); 232 1.26 veego else 233 1.26 veego ariadne_wribcr(sc, LE_BCR_MC, LE_MC_ASEL); 234 1.26 veego } 235 1.26 veego 236 1.26 veego int 237 1.35 aymeric ariadne_mediachange(struct lance_softc *sc) 238 1.26 veego { 239 1.26 veego struct ifmedia *ifm = &sc->sc_media; 240 1.26 veego 241 1.26 veego if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) 242 1.26 veego return (EINVAL); 243 1.26 veego 244 1.26 veego /* 245 1.26 veego * Switch to the selected media. If autoselect is 246 1.26 veego * set, switch it on otherwise disable it. We'll 247 1.26 veego * switch to the other media when we detect loss of 248 1.26 veego * carrier. 249 1.26 veego */ 250 1.26 veego switch (IFM_SUBTYPE(ifm->ifm_media)) { 251 1.26 veego case IFM_10_T: 252 1.26 veego sc->sc_initmodemedia = 1; 253 1.34 jdolecek lance_init(&sc->sc_ethercom.ec_if); 254 1.26 veego break; 255 1.26 veego 256 1.26 veego case IFM_10_2: 257 1.26 veego sc->sc_initmodemedia = 0; 258 1.34 jdolecek lance_init(&sc->sc_ethercom.ec_if); 259 1.26 veego break; 260 1.26 veego 261 1.26 veego case IFM_AUTO: 262 1.26 veego sc->sc_initmodemedia = 2; 263 1.26 veego ariadne_hwinit(sc); 264 1.26 veego break; 265 1.26 veego 266 1.26 veego default: 267 1.26 veego return (EINVAL); 268 1.26 veego } 269 1.26 veego 270 1.26 veego return (0); 271 1.26 veego } 272 1.26 veego 273 1.26 veego void 274 1.35 aymeric ariadne_hwinit(struct lance_softc *sc) 275 1.26 veego { 276 1.26 veego 277 1.26 veego /* 278 1.26 veego * Re-program LEDs to match meaning used on the Ariadne board. 279 1.26 veego */ 280 1.26 veego ariadne_wribcr(sc, LE_BCR_LED1, 0x0090); 281 1.26 veego ariadne_wribcr(sc, LE_BCR_LED2, 0x0081); 282 1.26 veego ariadne_wribcr(sc, LE_BCR_LED3, 0x0084); 283 1.26 veego 284 1.26 veego /* 285 1.47 andvar * Enable/Disable auto selection 286 1.26 veego */ 287 1.26 veego if (sc->sc_initmodemedia == 2) 288 1.26 veego ariadne_autoselect(sc, 1); 289 1.26 veego else 290 1.26 veego ariadne_autoselect(sc, 0); 291 1.26 veego } 292 1.26 veego 293 1.15 chopps int 294 1.42 tsutsui le_zbus_match(device_t parent, cfdata_t cfp, void *aux) 295 1.15 chopps { 296 1.15 chopps struct zbus_args *zap = aux; 297 1.6 chopps 298 1.6 chopps /* Commodore ethernet card */ 299 1.15 chopps if (zap->manid == 514 && zap->prodid == 112) 300 1.15 chopps return (1); 301 1.6 chopps 302 1.6 chopps /* Ameristar ethernet card */ 303 1.15 chopps if (zap->manid == 1053 && zap->prodid == 1) 304 1.15 chopps return (1); 305 1.6 chopps 306 1.26 veego /* Ariadne ethernet card */ 307 1.26 veego if (zap->manid == 2167 && zap->prodid == 201) 308 1.26 veego return (1); 309 1.26 veego 310 1.6 chopps return (0); 311 1.6 chopps } 312 1.1 mw 313 1.6 chopps void 314 1.42 tsutsui le_zbus_attach(device_t parent, device_t self, void *aux) 315 1.1 mw { 316 1.42 tsutsui struct le_softc *lesc = device_private(self); 317 1.30 drochner struct lance_softc *sc = &lesc->sc_am7990.lsc; 318 1.15 chopps struct zbus_args *zap = aux; 319 1.15 chopps u_long ser; 320 1.1 mw 321 1.42 tsutsui sc->sc_dev = self; 322 1.42 tsutsui 323 1.26 veego /* This has no effect on PCnet-ISA LANCE chips */ 324 1.15 chopps sc->sc_conf3 = LE_C3_BSWP; 325 1.6 chopps 326 1.6 chopps /* 327 1.6 chopps * Manufacturer decides the 3 first bytes, i.e. ethernet vendor ID. 328 1.6 chopps */ 329 1.15 chopps switch (zap->manid) { 330 1.26 veego case 514: 331 1.15 chopps /* Commodore */ 332 1.15 chopps sc->sc_memsize = 32768; 333 1.23 is sc->sc_enaddr[0] = 0x00; 334 1.23 is sc->sc_enaddr[1] = 0x80; 335 1.23 is sc->sc_enaddr[2] = 0x10; 336 1.26 veego lesc->sc_r1 = (struct lereg1 *)(0x4000 + (int)zap->va); 337 1.26 veego sc->sc_mem = (void *)(0x8000 + (int)zap->va); 338 1.26 veego sc->sc_addr = 0x8000; 339 1.30 drochner sc->sc_copytodesc = lance_copytobuf_contig; 340 1.30 drochner sc->sc_copyfromdesc = lance_copyfrombuf_contig; 341 1.30 drochner sc->sc_copytobuf = lance_copytobuf_contig; 342 1.30 drochner sc->sc_copyfrombuf = lance_copyfrombuf_contig; 343 1.30 drochner sc->sc_zerobuf = lance_zerobuf_contig; 344 1.26 veego sc->sc_rdcsr = lerdcsr; 345 1.26 veego sc->sc_wrcsr = lewrcsr; 346 1.26 veego sc->sc_hwreset = NULL; 347 1.26 veego sc->sc_hwinit = NULL; 348 1.15 chopps break; 349 1.6 chopps 350 1.26 veego case 1053: 351 1.15 chopps /* Ameristar */ 352 1.15 chopps sc->sc_memsize = 32768; 353 1.23 is sc->sc_enaddr[0] = 0x00; 354 1.23 is sc->sc_enaddr[1] = 0x00; 355 1.23 is sc->sc_enaddr[2] = 0x9f; 356 1.26 veego lesc->sc_r1 = (struct lereg1 *)(0x4000 + (int)zap->va); 357 1.26 veego sc->sc_mem = (void *)(0x8000 + (int)zap->va); 358 1.26 veego sc->sc_addr = 0x8000; 359 1.30 drochner sc->sc_copytodesc = lance_copytobuf_contig; 360 1.30 drochner sc->sc_copyfromdesc = lance_copyfrombuf_contig; 361 1.30 drochner sc->sc_copytobuf = lance_copytobuf_contig; 362 1.30 drochner sc->sc_copyfrombuf = lance_copyfrombuf_contig; 363 1.30 drochner sc->sc_zerobuf = lance_zerobuf_contig; 364 1.26 veego sc->sc_rdcsr = lerdcsr; 365 1.26 veego sc->sc_wrcsr = lewrcsr; 366 1.26 veego sc->sc_hwreset = NULL; 367 1.26 veego sc->sc_hwinit = NULL; 368 1.15 chopps break; 369 1.6 chopps 370 1.26 veego case 2167: 371 1.26 veego /* Village Tronic */ 372 1.26 veego sc->sc_memsize = 32768; 373 1.26 veego sc->sc_enaddr[0] = 0x00; 374 1.26 veego sc->sc_enaddr[1] = 0x60; 375 1.26 veego sc->sc_enaddr[2] = 0x30; 376 1.26 veego lesc->sc_r1 = (struct lereg1 *)(0x0370 + (int)zap->va); 377 1.26 veego sc->sc_mem = (void *)(0x8000 + (int)zap->va); 378 1.26 veego sc->sc_addr = 0x8000; 379 1.26 veego sc->sc_copytodesc = ariadne_copytodesc_word; 380 1.26 veego sc->sc_copyfromdesc = ariadne_copyfromdesc_word; 381 1.26 veego sc->sc_copytobuf = ariadne_copytobuf_word; 382 1.26 veego sc->sc_copyfrombuf = ariadne_copyfrombuf_word; 383 1.26 veego sc->sc_zerobuf = ariadne_zerobuf_word; 384 1.26 veego sc->sc_rdcsr = ariadne_rdcsr; 385 1.26 veego sc->sc_wrcsr = ariadne_wrcsr; 386 1.26 veego sc->sc_hwreset = lepcnet_reset; 387 1.26 veego sc->sc_hwinit = ariadne_hwinit; 388 1.26 veego sc->sc_mediachange = ariadne_mediachange; 389 1.26 veego sc->sc_supmedia = lemedia_ariadne; 390 1.26 veego sc->sc_nsupmedia = NLEMEDIA_ARIADNE; 391 1.26 veego sc->sc_defaultmedia = IFM_ETHER | IFM_AUTO; 392 1.26 veego sc->sc_initmodemedia = 2; 393 1.26 veego break; 394 1.26 veego 395 1.26 veego default: 396 1.21 thorpej panic("le_zbus_attach: bad manid"); 397 1.1 mw } 398 1.6 chopps 399 1.6 chopps /* 400 1.15 chopps * Serial number for board is used as host ID. 401 1.6 chopps */ 402 1.15 chopps ser = (u_long)zap->serno; 403 1.23 is sc->sc_enaddr[3] = (ser >> 16) & 0xff; 404 1.23 is sc->sc_enaddr[4] = (ser >> 8) & 0xff; 405 1.23 is sc->sc_enaddr[5] = (ser ) & 0xff; 406 1.1 mw 407 1.30 drochner am7990_config(&lesc->sc_am7990); 408 1.6 chopps 409 1.21 thorpej lesc->sc_isr.isr_intr = am7990_intr; 410 1.21 thorpej lesc->sc_isr.isr_arg = sc; 411 1.21 thorpej lesc->sc_isr.isr_ipl = 2; 412 1.21 thorpej add_isr(&lesc->sc_isr); 413 1.26 veego } 414 1.26 veego 415 1.26 veego 416 1.26 veego integrate void 417 1.35 aymeric ariadne_copytodesc_word(struct lance_softc *sc, void *from, int boff, int len) 418 1.26 veego { 419 1.26 veego u_short *b1 = from; 420 1.32 tron volatile u_short *b2 = (u_short *)((u_char *)sc->sc_mem + boff); 421 1.26 veego 422 1.26 veego for (len >>= 1; len > 0; len--) 423 1.26 veego *b2++ = ariadne_swapreg(*b1++); 424 1.26 veego } 425 1.26 veego 426 1.26 veego integrate void 427 1.35 aymeric ariadne_copyfromdesc_word(struct lance_softc *sc, void *to, int boff, int len) 428 1.26 veego { 429 1.32 tron volatile u_short *b1 = (u_short *)((u_char *)sc->sc_mem + boff); 430 1.26 veego u_short *b2 = to; 431 1.26 veego 432 1.26 veego for (len >>= 1; len > 0; len--) 433 1.26 veego *b2++ = ariadne_swapreg(*b1++); 434 1.26 veego } 435 1.26 veego 436 1.26 veego #define isodd(n) ((n) & 1) 437 1.26 veego 438 1.26 veego integrate void 439 1.35 aymeric ariadne_copytobuf_word(struct lance_softc *sc, void *from, int boff, int len) 440 1.26 veego { 441 1.26 veego u_char *a1 = from; 442 1.32 tron volatile u_char *a2 = (u_char *)sc->sc_mem + boff; 443 1.26 veego u_short *b1; 444 1.26 veego volatile u_short *b2; 445 1.26 veego int i; 446 1.26 veego 447 1.26 veego if (len > 0 && isodd(boff)) { 448 1.28 is /* adjust source pointer */ 449 1.26 veego b1 = (u_short *)(a1 + 1); 450 1.28 is /* compute aligned destination pointer */ 451 1.39 jmc b2 = (volatile u_short *)(a2 + 1); 452 1.28 is /* copy first unaligned byte to buf */ 453 1.28 is b2[-1] = (b2[-1] & 0xff00) | *a1; 454 1.26 veego --len; 455 1.26 veego } else { 456 1.28 is /* destination is aligned or length is zero */ 457 1.26 veego b1 = (u_short *)a1; 458 1.39 jmc b2 = (volatile u_short *)a2; 459 1.26 veego } 460 1.26 veego 461 1.28 is /* copy full words with aligned destination */ 462 1.26 veego for (i = len >> 1; i > 0; i--) 463 1.26 veego *b2++ = *b1++; 464 1.26 veego 465 1.28 is /* copy remaining byte */ 466 1.26 veego if (isodd(len)) 467 1.28 is *b2 = (*b2 & 0x00ff) | (*(u_char *)b1) << 8; 468 1.26 veego } 469 1.26 veego 470 1.26 veego integrate void 471 1.35 aymeric ariadne_copyfrombuf_word(struct lance_softc *sc, void *to, int boff, int len) 472 1.26 veego { 473 1.32 tron volatile u_char *a1 = (u_char *)sc->sc_mem + boff; 474 1.26 veego u_char *a2 = to; 475 1.26 veego volatile u_short *b1; 476 1.26 veego u_short *b2; 477 1.26 veego int i; 478 1.26 veego 479 1.26 veego if (len > 0 && isodd(boff)) { 480 1.28 is /* compute aligned source pointer */ 481 1.39 jmc b1 = (volatile u_short *)(a1 + 1); 482 1.28 is /* adjust destination pointer (possibly unaligned) */ 483 1.28 is b2 = (u_short *)(a2 + 1); 484 1.28 is /* copy first unaligned byte from buf */ 485 1.28 is *a2 = b1[-1]; 486 1.26 veego --len; 487 1.26 veego } else { 488 1.28 is /* source is aligned or length is zero */ 489 1.39 jmc b1 = (volatile u_short *)a1; 490 1.26 veego b2 = (u_short *)a2; 491 1.26 veego } 492 1.26 veego 493 1.28 is /* copy full words with aligned source */ 494 1.26 veego for (i = len >> 1; i > 0; i--) 495 1.26 veego *b2++ = *b1++; 496 1.26 veego 497 1.28 is /* copy remaining byte */ 498 1.26 veego if (isodd(len)) 499 1.28 is *(u_char *)b2 = *b1 >> 8; 500 1.26 veego } 501 1.26 veego 502 1.26 veego integrate void 503 1.35 aymeric ariadne_zerobuf_word(struct lance_softc *sc, int boff, int len) 504 1.26 veego { 505 1.32 tron volatile u_char *a1 = (u_char *)sc->sc_mem + boff; 506 1.26 veego volatile u_short *b1; 507 1.26 veego int i; 508 1.26 veego 509 1.26 veego if (len > 0 && isodd(boff)) { 510 1.39 jmc b1 = (volatile u_short *)(a1 + 1); 511 1.26 veego b1[-1] &= 0xff00; 512 1.26 veego --len; 513 1.26 veego } else { 514 1.39 jmc b1 = (volatile u_short *)a1; 515 1.26 veego } 516 1.35 aymeric 517 1.26 veego for (i = len >> 1; i > 0; i--) 518 1.26 veego *b1++ = 0; 519 1.26 veego 520 1.26 veego if (isodd(len)) 521 1.26 veego *b1 &= 0x00ff; 522 1.1 mw } 523