1 /* $OpenBSD: if_wi_obio.c,v 1.22 2024/08/28 03:54:54 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1997, 1998, 1999 5 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Bill Paul. 18 * 4. Neither the name of the author nor the names of any co-contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 32 * THE POSSIBILITY OF SUCH DAMAGE. 33 * 34 * From: if_wi.c,v 1.7 1999/07/04 14:40:22 wpaul Exp $ 35 */ 36 37 /* 38 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for OpenBSD. 39 * 40 * Originally written by Bill Paul <wpaul@ctr.columbia.edu> 41 * Electrical Engineering Department 42 * Columbia University, New York City 43 */ 44 /* 45 * modified for apple obio by Dale Rahn 46 */ 47 48 #include <sys/param.h> 49 #include <sys/systm.h> 50 #include <sys/timeout.h> 51 #include <sys/socket.h> 52 #include <sys/device.h> 53 #include <sys/tree.h> 54 55 #include <net/if.h> 56 #include <net/if_media.h> 57 58 #include <netinet/in.h> 59 #include <netinet/if_ether.h> 60 61 #include <net80211/ieee80211.h> 62 #include <net80211/ieee80211_ioctl.h> 63 #include <net80211/ieee80211_var.h> 64 65 #include <machine/bus.h> 66 #include <machine/autoconf.h> 67 68 #include <dev/ic/if_wireg.h> 69 #include <dev/ic/if_wi_ieee.h> 70 #include <dev/ic/if_wivar.h> 71 72 int wi_obio_match(struct device *, void *, void *); 73 void wi_obio_attach(struct device *, struct device *, void *); 74 int wi_obio_detach(struct device *, int); 75 int wi_obio_activate(struct device *, int); 76 void wi_obio_attach(struct device *, struct device *, void *); 77 int wi_obio_enable(struct wi_softc *sc); 78 void wi_obio_disable(struct wi_softc *sc); 79 80 struct wi_obio_softc { 81 struct wi_softc sc_wi; 82 u_int keywest; 83 }; 84 85 const struct cfattach wi_obio_ca = { 86 sizeof (struct wi_obio_softc), wi_obio_match, wi_obio_attach, 87 wi_obio_detach, wi_obio_activate 88 }; 89 90 91 int 92 wi_obio_match(struct device *parent, void *match, void *aux) 93 { 94 struct confargs *ca = aux; 95 96 if (strcmp(ca->ca_name, "radio") == 0 && 97 ca->ca_nintr >= 4 && ca->ca_nreg >= 8) 98 return (1); 99 return (0); 100 } 101 102 void 103 wi_obio_attach(struct device *parent, struct device *self, void *aux) 104 { 105 struct wi_obio_softc *psc = (struct wi_obio_softc *)self; 106 struct wi_softc *sc = &psc->sc_wi; 107 struct confargs *ca = aux; 108 109 printf(" irq %d:", ca->ca_intr[0]); 110 111 sc->wi_btag = ca->ca_iot; 112 ca->ca_reg[0] += ca->ca_baseaddr; 113 if (bus_space_map(sc->wi_btag, ca->ca_reg[0], ca->ca_reg[1], 0, &sc->wi_bhandle)) { 114 printf("can't map i/o space\n"); 115 } 116 /* FSCKING hackery */ 117 psc->keywest = (u_int) mapiodev(0x80000000, 0x1d000); 118 119 /* Establish the interrupt. */ 120 mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_NET, 121 wi_intr, psc, sc->sc_dev.dv_xname); 122 123 /* Make sure interrupts are disabled. */ 124 CSR_WRITE_2(sc, WI_INT_EN, 0); 125 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xffff); 126 127 wi_obio_enable(sc); 128 129 printf("\n"); 130 wi_attach(sc, &wi_func_io); 131 } 132 133 int 134 wi_obio_detach(struct device *dev, int flags) 135 { 136 struct wi_obio_softc *psc = (struct wi_obio_softc *)dev; 137 struct wi_softc *sc = &psc->sc_wi; 138 struct ifnet *ifp = &sc->sc_ic.ic_if; 139 140 /* 141 obio_io_unmap(psc->sc_pf, psc->sc_io_window); 142 obio_io_free(psc->sc_pf, &psc->sc_pcioh); 143 */ 144 145 wi_obio_disable(sc); 146 ether_ifdetach(ifp); 147 if_detach(ifp); 148 149 return (0); 150 } 151 152 int 153 wi_obio_activate(struct device *dev, int act) 154 { 155 struct wi_obio_softc *psc = (struct wi_obio_softc *)dev; 156 struct wi_softc *sc = &psc->sc_wi; 157 struct ifnet *ifp = &sc->sc_ic.ic_if; 158 159 switch (act) { 160 case DVACT_DEACTIVATE: 161 ifp->if_timer = 0; 162 if (ifp->if_flags & IFF_RUNNING) 163 wi_stop(sc); 164 wi_obio_disable(sc); 165 break; 166 } 167 return (0); 168 } 169 170 /* THIS IS CRAP */ 171 172 int 173 wi_obio_enable(struct wi_softc *sc) 174 { 175 struct wi_obio_softc *psc = (struct wi_obio_softc *)sc; 176 const u_int keywest = psc->keywest; /* XXX */ 177 const u_int fcr2 = keywest + 0x40; 178 const u_int gpio = keywest + 0x6a; 179 const u_int extint_gpio = keywest + 0x58; 180 u_int x; 181 182 x = in32rb(fcr2); 183 x |= 0x4; 184 out32rb(fcr2, x); 185 186 /* Enable card slot. */ 187 out8(gpio + 0x0f, 5); 188 delay(1000); 189 out8(gpio + 0x0f, 4); 190 delay(1000); 191 192 x = in32rb(fcr2); 193 x &= ~0x8000000; 194 195 out32rb(fcr2, x); 196 /* out8(gpio + 0x10, 4); */ 197 198 out8(extint_gpio + 0x0b, 0); 199 out8(extint_gpio + 0x0a, 0x28); 200 out8(extint_gpio + 0x0d, 0x28); 201 out8(gpio + 0x0d, 0x28); 202 out8(gpio + 0x0e, 0x28); 203 out32rb(keywest + 0x1c000, 0); 204 205 /* Initialize the card. */ 206 out32rb(keywest + 0x1a3e0, 0x41); 207 x = in32rb(fcr2); 208 x |= 0x8000000; 209 out32rb(fcr2, x); 210 211 return 0; 212 } 213 214 void 215 wi_obio_disable(struct wi_softc *sc) 216 { 217 struct wi_obio_softc *psc = (struct wi_obio_softc *)sc; 218 const u_int keywest = psc->keywest; /* XXX */ 219 const u_int fcr2 = keywest + 0x40; 220 u_int x; 221 222 x = in32rb(fcr2); 223 x &= ~0x4; 224 out32rb(fcr2, x); 225 /* out8(gpio + 0x10, 0); */ 226 } 227