1 1.28 andvar /* $NetBSD: if_malo_pcmcia.c,v 1.28 2024/02/09 22:08:36 andvar Exp $ */ 2 1.1 kiyohara /* $OpenBSD: if_malo.c,v 1.65 2009/03/29 21:53:53 sthen Exp $ */ 3 1.1 kiyohara 4 1.1 kiyohara /* 5 1.1 kiyohara * Copyright (c) 2007 Marcus Glocker <mglocker (at) openbsd.org> 6 1.1 kiyohara * 7 1.1 kiyohara * Permission to use, copy, modify, and distribute this software for any 8 1.1 kiyohara * purpose with or without fee is hereby granted, provided that the above 9 1.1 kiyohara * copyright notice and this permission notice appear in all copies. 10 1.1 kiyohara * 11 1.1 kiyohara * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 1.1 kiyohara * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 1.1 kiyohara * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 1.1 kiyohara * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 1.1 kiyohara * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 1.1 kiyohara * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 1.1 kiyohara * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 1.1 kiyohara */ 19 1.1 kiyohara 20 1.1 kiyohara #include <sys/cdefs.h> 21 1.28 andvar __KERNEL_RCSID(0, "$NetBSD: if_malo_pcmcia.c,v 1.28 2024/02/09 22:08:36 andvar Exp $"); 22 1.1 kiyohara 23 1.1 kiyohara #ifdef _MODULE 24 1.1 kiyohara #include <sys/module.h> 25 1.1 kiyohara #endif 26 1.1 kiyohara 27 1.1 kiyohara #include <sys/param.h> 28 1.1 kiyohara #include <sys/bus.h> 29 1.1 kiyohara #include <sys/condvar.h> 30 1.1 kiyohara #include <sys/device.h> 31 1.1 kiyohara #include <sys/intr.h> 32 1.1 kiyohara #include <sys/kernel.h> 33 1.1 kiyohara #include <sys/malloc.h> 34 1.1 kiyohara #include <sys/mbuf.h> 35 1.1 kiyohara #include <sys/mutex.h> 36 1.1 kiyohara #include <sys/pmf.h> 37 1.1 kiyohara #include <sys/proc.h> 38 1.1 kiyohara #include <sys/socket.h> 39 1.1 kiyohara #include <sys/sockio.h> 40 1.1 kiyohara #include <sys/systm.h> 41 1.1 kiyohara 42 1.1 kiyohara #include <net/bpf.h> 43 1.1 kiyohara #include <net/if.h> 44 1.1 kiyohara #include <net/if_dl.h> 45 1.1 kiyohara #include <net/if_ether.h> 46 1.1 kiyohara #include <net/if_media.h> 47 1.1 kiyohara #include <net/if_llc.h> 48 1.1 kiyohara 49 1.1 kiyohara #include <net80211/ieee80211_var.h> 50 1.1 kiyohara #include <net80211/ieee80211_radiotap.h> 51 1.1 kiyohara 52 1.1 kiyohara #include <dev/firmload.h> 53 1.1 kiyohara 54 1.1 kiyohara #include <dev/pcmcia/pcmciareg.h> 55 1.1 kiyohara #include <dev/pcmcia/pcmciavar.h> 56 1.1 kiyohara #include <dev/pcmcia/pcmciadevs.h> 57 1.1 kiyohara 58 1.1 kiyohara #include <dev/pcmcia/if_malo_pcmciavar.h> 59 1.1 kiyohara #include <dev/pcmcia/if_malo_pcmciareg.h> 60 1.1 kiyohara 61 1.1 kiyohara /* 62 1.1 kiyohara * Driver for the Marvell 88W8385 chip (Compact Flash). 63 1.1 kiyohara */ 64 1.1 kiyohara 65 1.1 kiyohara #ifdef CMALO_DEBUG 66 1.1 kiyohara int cmalo_d = 1; 67 1.1 kiyohara #define DPRINTF(l, x...) do { if ((l) <= cmalo_d) printf(x); } while (0) 68 1.1 kiyohara #else 69 1.6 pgoyette #define DPRINTF(l, x...) do {} while (0) 70 1.1 kiyohara #endif 71 1.1 kiyohara 72 1.1 kiyohara static int malo_pcmcia_match(device_t, cfdata_t, void *); 73 1.1 kiyohara static void malo_pcmcia_attach(device_t, device_t, void *); 74 1.1 kiyohara static int malo_pcmcia_detach(device_t, int); 75 1.1 kiyohara static int malo_pcmcia_activate(device_t, devact_t); 76 1.1 kiyohara 77 1.1 kiyohara static int malo_pcmcia_validate_config(struct pcmcia_config_entry *); 78 1.1 kiyohara 79 1.1 kiyohara static int malo_pcmcia_enable(struct malo_softc *); 80 1.1 kiyohara static void malo_pcmcia_disable(struct malo_softc *); 81 1.1 kiyohara 82 1.1 kiyohara static void cmalo_attach(void *); 83 1.1 kiyohara static void cmalo_detach(void *); 84 1.1 kiyohara static int cmalo_intr(void *); 85 1.13 nonaka static void cmalo_softintr(void *); 86 1.1 kiyohara 87 1.1 kiyohara static void cmalo_start(struct ifnet *); 88 1.1 kiyohara static int cmalo_ioctl(struct ifnet *, u_long, void *); 89 1.1 kiyohara static int cmalo_init(struct ifnet *); 90 1.1 kiyohara static void cmalo_watchdog(struct ifnet *); 91 1.1 kiyohara static int cmalo_media_change(struct ifnet *); 92 1.1 kiyohara static int cmalo_newstate(struct ieee80211com *, enum ieee80211_state, 93 1.1 kiyohara int); 94 1.1 kiyohara 95 1.1 kiyohara static int firmware_load(const char *, const char *, uint8_t **, size_t *); 96 1.1 kiyohara static int cmalo_fw_alloc(struct malo_softc *); 97 1.1 kiyohara static void cmalo_fw_free(struct malo_softc *); 98 1.1 kiyohara static int cmalo_fw_load_helper(struct malo_softc *); 99 1.1 kiyohara static int cmalo_fw_load_main(struct malo_softc *); 100 1.1 kiyohara 101 1.1 kiyohara static void cmalo_stop(struct malo_softc *); 102 1.1 kiyohara static void cmalo_intr_mask(struct malo_softc *, int); 103 1.1 kiyohara static void cmalo_rx(struct malo_softc *); 104 1.1 kiyohara static int cmalo_tx(struct malo_softc *, struct mbuf *); 105 1.1 kiyohara static void cmalo_tx_done(struct malo_softc *); 106 1.1 kiyohara static void cmalo_event(struct malo_softc *); 107 1.1 kiyohara static void cmalo_select_network(struct malo_softc *); 108 1.1 kiyohara static void cmalo_reflect_network(struct malo_softc *); 109 1.1 kiyohara static int cmalo_wep(struct malo_softc *); 110 1.1 kiyohara static int cmalo_rate2bitmap(int); 111 1.1 kiyohara 112 1.1 kiyohara static void cmalo_hexdump(void *, int); 113 1.1 kiyohara static int cmalo_cmd_get_hwspec(struct malo_softc *); 114 1.1 kiyohara static int cmalo_cmd_rsp_hwspec(struct malo_softc *); 115 1.1 kiyohara static int cmalo_cmd_set_reset(struct malo_softc *); 116 1.1 kiyohara static int cmalo_cmd_set_scan(struct malo_softc *); 117 1.1 kiyohara static int cmalo_cmd_rsp_scan(struct malo_softc *); 118 1.1 kiyohara static int cmalo_parse_elements(struct malo_softc *, uint8_t *, int, int); 119 1.1 kiyohara static int cmalo_cmd_set_auth(struct malo_softc *); 120 1.1 kiyohara static int cmalo_cmd_set_wep(struct malo_softc *, uint16_t, 121 1.1 kiyohara struct ieee80211_key *); 122 1.1 kiyohara static int cmalo_cmd_set_snmp(struct malo_softc *, uint16_t); 123 1.1 kiyohara static int cmalo_cmd_set_radio(struct malo_softc *, uint16_t); 124 1.1 kiyohara static int cmalo_cmd_set_channel(struct malo_softc *, uint16_t); 125 1.1 kiyohara static int cmalo_cmd_set_txpower(struct malo_softc *, int16_t); 126 1.1 kiyohara static int cmalo_cmd_set_antenna(struct malo_softc *, uint16_t); 127 1.1 kiyohara static int cmalo_cmd_set_macctrl(struct malo_softc *); 128 1.1 kiyohara static int cmalo_cmd_set_macaddr(struct malo_softc *, uint8_t *); 129 1.1 kiyohara static int cmalo_cmd_set_assoc(struct malo_softc *); 130 1.1 kiyohara static int cmalo_cmd_rsp_assoc(struct malo_softc *); 131 1.1 kiyohara static int cmalo_cmd_set_rate(struct malo_softc *, int); 132 1.1 kiyohara static int cmalo_cmd_request(struct malo_softc *, uint16_t, int); 133 1.1 kiyohara static int cmalo_cmd_response(struct malo_softc *); 134 1.1 kiyohara 135 1.1 kiyohara /* 136 1.1 kiyohara * PCMCIA bus. 137 1.1 kiyohara */ 138 1.1 kiyohara struct malo_pcmcia_softc { 139 1.1 kiyohara struct malo_softc sc_malo; 140 1.1 kiyohara 141 1.1 kiyohara struct pcmcia_function *sc_pf; 142 1.1 kiyohara struct pcmcia_io_handle sc_pcioh; 143 1.1 kiyohara int sc_io_window; 144 1.1 kiyohara void *sc_ih; 145 1.1 kiyohara }; 146 1.1 kiyohara 147 1.1 kiyohara CFATTACH_DECL_NEW(malo_pcmcia, sizeof(struct malo_pcmcia_softc), 148 1.1 kiyohara malo_pcmcia_match, malo_pcmcia_attach, malo_pcmcia_detach, 149 1.1 kiyohara malo_pcmcia_activate); 150 1.1 kiyohara 151 1.1 kiyohara 152 1.1 kiyohara static int 153 1.1 kiyohara malo_pcmcia_match(device_t parent, cfdata_t match, void *aux) 154 1.1 kiyohara { 155 1.1 kiyohara struct pcmcia_attach_args *pa = aux; 156 1.1 kiyohara 157 1.1 kiyohara if (pa->manufacturer == PCMCIA_VENDOR_AMBICOM && 158 1.1 kiyohara pa->product == PCMCIA_PRODUCT_AMBICOM_WL54CF) 159 1.1 kiyohara return 1; 160 1.1 kiyohara 161 1.1 kiyohara return 0; 162 1.1 kiyohara } 163 1.1 kiyohara 164 1.1 kiyohara static void 165 1.1 kiyohara malo_pcmcia_attach(device_t parent, device_t self, void *aux) 166 1.1 kiyohara { 167 1.1 kiyohara struct malo_pcmcia_softc *psc = device_private(self); 168 1.1 kiyohara struct malo_softc *sc = &psc->sc_malo; 169 1.1 kiyohara struct pcmcia_attach_args *pa = aux; 170 1.1 kiyohara struct pcmcia_config_entry *cfe; 171 1.1 kiyohara int error; 172 1.1 kiyohara 173 1.1 kiyohara sc->sc_dev = self; 174 1.1 kiyohara psc->sc_pf = pa->pf; 175 1.1 kiyohara 176 1.20 msaitoh error = pcmcia_function_configure(pa->pf, malo_pcmcia_validate_config); 177 1.1 kiyohara if (error) { 178 1.1 kiyohara aprint_error_dev(self, "configure failed, error=%d\n", error); 179 1.1 kiyohara return; 180 1.1 kiyohara } 181 1.1 kiyohara 182 1.13 nonaka sc->sc_soft_ih = softint_establish(SOFTINT_NET, cmalo_softintr, sc); 183 1.13 nonaka if (sc->sc_soft_ih == NULL) { 184 1.13 nonaka aprint_error_dev(self, "couldn't establish softint\n"); 185 1.13 nonaka return; 186 1.13 nonaka } 187 1.13 nonaka 188 1.1 kiyohara malo_pcmcia_enable(sc); 189 1.1 kiyohara 190 1.1 kiyohara cfe = pa->pf->cfe; 191 1.1 kiyohara sc->sc_iot = cfe->iospace[0].handle.iot; 192 1.1 kiyohara sc->sc_ioh = cfe->iospace[0].handle.ioh; 193 1.1 kiyohara 194 1.1 kiyohara cmalo_attach(sc); 195 1.1 kiyohara if (!(sc->sc_flags & MALO_DEVICE_ATTACHED)) 196 1.1 kiyohara goto fail; 197 1.1 kiyohara 198 1.1 kiyohara if (pmf_device_register(self, NULL, NULL)) 199 1.1 kiyohara pmf_class_network_register(self, &sc->sc_if); 200 1.1 kiyohara else 201 1.1 kiyohara aprint_error_dev(self, "couldn't establish power handler\n"); 202 1.1 kiyohara 203 1.1 kiyohara fail: 204 1.1 kiyohara malo_pcmcia_disable(sc); 205 1.1 kiyohara 206 1.1 kiyohara if (sc->sc_flags & MALO_DEVICE_ATTACHED) 207 1.1 kiyohara return; 208 1.1 kiyohara 209 1.13 nonaka softint_disestablish(sc->sc_soft_ih); 210 1.13 nonaka sc->sc_soft_ih = NULL; 211 1.13 nonaka 212 1.1 kiyohara pcmcia_function_unconfigure(pa->pf); 213 1.1 kiyohara return; 214 1.1 kiyohara } 215 1.1 kiyohara 216 1.1 kiyohara static int 217 1.1 kiyohara malo_pcmcia_detach(device_t dev, int flags) 218 1.1 kiyohara { 219 1.1 kiyohara struct malo_pcmcia_softc *psc = device_private(dev); 220 1.1 kiyohara struct malo_softc *sc = &psc->sc_malo; 221 1.1 kiyohara 222 1.1 kiyohara cmalo_detach(sc); 223 1.1 kiyohara malo_pcmcia_disable(sc); 224 1.13 nonaka softint_disestablish(sc->sc_soft_ih); 225 1.13 nonaka sc->sc_soft_ih = NULL; 226 1.1 kiyohara pcmcia_function_unconfigure(psc->sc_pf); 227 1.1 kiyohara 228 1.1 kiyohara return 0; 229 1.1 kiyohara } 230 1.1 kiyohara 231 1.1 kiyohara static int 232 1.1 kiyohara malo_pcmcia_activate(device_t dev, devact_t act) 233 1.1 kiyohara { 234 1.1 kiyohara struct malo_pcmcia_softc *psc = device_private(dev); 235 1.1 kiyohara struct malo_softc *sc = &psc->sc_malo; 236 1.1 kiyohara struct ifnet *ifp = &sc->sc_if; 237 1.1 kiyohara int s; 238 1.1 kiyohara 239 1.1 kiyohara s = splnet(); 240 1.1 kiyohara switch (act) { 241 1.1 kiyohara case DVACT_DEACTIVATE: 242 1.1 kiyohara if_deactivate(ifp); 243 1.1 kiyohara break; 244 1.1 kiyohara default: 245 1.14 maxv splx(s); 246 1.1 kiyohara return EOPNOTSUPP; 247 1.1 kiyohara } 248 1.1 kiyohara splx(s); 249 1.1 kiyohara 250 1.1 kiyohara return 0; 251 1.1 kiyohara } 252 1.1 kiyohara 253 1.1 kiyohara 254 1.1 kiyohara int 255 1.1 kiyohara malo_pcmcia_validate_config(struct pcmcia_config_entry *cfe) 256 1.1 kiyohara { 257 1.1 kiyohara 258 1.1 kiyohara if (cfe->iftype != PCMCIA_IFTYPE_IO || cfe->num_iospace != 1) 259 1.1 kiyohara return EINVAL; 260 1.1 kiyohara /* Some cards have a memory space, but we don't use it. */ 261 1.1 kiyohara cfe->num_memspace = 0; 262 1.1 kiyohara return 0; 263 1.1 kiyohara } 264 1.1 kiyohara 265 1.1 kiyohara 266 1.1 kiyohara static int 267 1.1 kiyohara malo_pcmcia_enable(struct malo_softc *sc) 268 1.1 kiyohara { 269 1.1 kiyohara struct malo_pcmcia_softc *psc = (struct malo_pcmcia_softc *)sc; 270 1.1 kiyohara 271 1.1 kiyohara /* establish interrupt */ 272 1.1 kiyohara psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET, cmalo_intr, sc); 273 1.1 kiyohara if (psc->sc_ih == NULL) { 274 1.1 kiyohara aprint_error(": can't establish interrupt\n"); 275 1.1 kiyohara return -1; 276 1.1 kiyohara } 277 1.1 kiyohara 278 1.1 kiyohara if (pcmcia_function_enable(psc->sc_pf)) { 279 1.1 kiyohara aprint_error(": can't enable function\n"); 280 1.1 kiyohara pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih); 281 1.1 kiyohara return -1; 282 1.1 kiyohara } 283 1.1 kiyohara sc->sc_flags |= MALO_DEVICE_ENABLED; 284 1.1 kiyohara 285 1.1 kiyohara return 0; 286 1.1 kiyohara } 287 1.1 kiyohara 288 1.1 kiyohara static void 289 1.1 kiyohara malo_pcmcia_disable(struct malo_softc *sc) 290 1.1 kiyohara { 291 1.1 kiyohara struct malo_pcmcia_softc *psc = (struct malo_pcmcia_softc *)sc; 292 1.1 kiyohara 293 1.1 kiyohara pcmcia_function_disable(psc->sc_pf); 294 1.1 kiyohara if (psc->sc_ih) 295 1.1 kiyohara pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih); 296 1.1 kiyohara psc->sc_ih = NULL; 297 1.1 kiyohara sc->sc_flags &= ~MALO_DEVICE_ENABLED; 298 1.1 kiyohara } 299 1.1 kiyohara 300 1.1 kiyohara 301 1.1 kiyohara /* 302 1.1 kiyohara * Driver. 303 1.1 kiyohara */ 304 1.1 kiyohara static void 305 1.1 kiyohara cmalo_attach(void *arg) 306 1.1 kiyohara { 307 1.1 kiyohara struct malo_softc *sc = arg; 308 1.1 kiyohara struct ieee80211com *ic = &sc->sc_ic; 309 1.1 kiyohara struct ifnet *ifp = &sc->sc_if; 310 1.26 riastrad int i; 311 1.1 kiyohara 312 1.1 kiyohara /* disable interrupts */ 313 1.1 kiyohara cmalo_intr_mask(sc, 0); 314 1.1 kiyohara 315 1.1 kiyohara /* load firmware */ 316 1.1 kiyohara if (cmalo_fw_alloc(sc) != 0 || 317 1.1 kiyohara cmalo_fw_load_helper(sc) != 0 || 318 1.1 kiyohara cmalo_fw_load_main(sc) != 0) { 319 1.1 kiyohara /* free firmware */ 320 1.1 kiyohara cmalo_fw_free(sc); 321 1.26 riastrad goto fail; 322 1.1 kiyohara } 323 1.1 kiyohara sc->sc_flags |= MALO_FW_LOADED; 324 1.1 kiyohara 325 1.1 kiyohara /* allocate command buffer */ 326 1.24 chs sc->sc_cmd = malloc(MALO_CMD_BUFFER_SIZE, M_DEVBUF, M_WAITOK); 327 1.1 kiyohara 328 1.1 kiyohara /* allocate data buffer */ 329 1.24 chs sc->sc_data = malloc(MALO_DATA_BUFFER_SIZE, M_DEVBUF, M_WAITOK); 330 1.1 kiyohara 331 1.1 kiyohara /* enable interrupts */ 332 1.1 kiyohara cmalo_intr_mask(sc, 1); 333 1.1 kiyohara 334 1.1 kiyohara /* we are context save here for FW commands */ 335 1.1 kiyohara sc->sc_cmd_ctxsave = 1; 336 1.1 kiyohara 337 1.1 kiyohara mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_VM); 338 1.1 kiyohara cv_init(&sc->sc_cv, "malo"); 339 1.1 kiyohara 340 1.1 kiyohara /* get hardware specs */ 341 1.1 kiyohara cmalo_cmd_get_hwspec(sc); 342 1.1 kiyohara 343 1.1 kiyohara /* setup interface */ 344 1.1 kiyohara ifp->if_softc = sc; 345 1.1 kiyohara ifp->if_start = cmalo_start; 346 1.1 kiyohara ifp->if_ioctl = cmalo_ioctl; 347 1.1 kiyohara ifp->if_init = cmalo_init; 348 1.1 kiyohara ifp->if_watchdog = cmalo_watchdog; 349 1.1 kiyohara ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 350 1.1 kiyohara strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 351 1.1 kiyohara IFQ_SET_READY(&ifp->if_snd); 352 1.1 kiyohara 353 1.1 kiyohara ic->ic_ifp = ifp; 354 1.1 kiyohara ic->ic_phytype = IEEE80211_T_OFDM; 355 1.1 kiyohara ic->ic_opmode = IEEE80211_M_STA; 356 1.1 kiyohara ic->ic_state = IEEE80211_S_INIT; 357 1.1 kiyohara ic->ic_caps = IEEE80211_C_MONITOR | IEEE80211_C_WEP; 358 1.1 kiyohara 359 1.1 kiyohara ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; 360 1.1 kiyohara ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g; 361 1.1 kiyohara 362 1.1 kiyohara for (i = 0; i <= 14; i++) { 363 1.1 kiyohara ic->ic_channels[i].ic_freq = 364 1.1 kiyohara ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 365 1.1 kiyohara ic->ic_channels[i].ic_flags = 366 1.1 kiyohara IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | 367 1.1 kiyohara IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; 368 1.1 kiyohara } 369 1.1 kiyohara 370 1.1 kiyohara /* attach interface */ 371 1.26 riastrad if_initialize(ifp); 372 1.1 kiyohara ieee80211_ifattach(ic); 373 1.13 nonaka /* Use common softint-based if_input */ 374 1.13 nonaka ifp->if_percpuq = if_percpuq_create(ifp); 375 1.13 nonaka if_register(ifp); 376 1.1 kiyohara 377 1.1 kiyohara sc->sc_newstate = ic->ic_newstate; 378 1.1 kiyohara ic->ic_newstate = cmalo_newstate; 379 1.1 kiyohara ieee80211_media_init(ic, cmalo_media_change, ieee80211_media_status); 380 1.1 kiyohara 381 1.1 kiyohara /* second attach line */ 382 1.1 kiyohara aprint_normal_dev(sc->sc_dev, "address %s\n", 383 1.1 kiyohara ether_sprintf(ic->ic_myaddr)); 384 1.1 kiyohara 385 1.1 kiyohara ieee80211_announce(ic); 386 1.1 kiyohara 387 1.1 kiyohara /* device attached */ 388 1.1 kiyohara sc->sc_flags |= MALO_DEVICE_ATTACHED; 389 1.15 msaitoh 390 1.15 msaitoh return; 391 1.15 msaitoh 392 1.26 riastrad fail: 393 1.15 msaitoh cmalo_fw_free(sc); 394 1.1 kiyohara } 395 1.1 kiyohara 396 1.1 kiyohara static void 397 1.1 kiyohara cmalo_detach(void *arg) 398 1.1 kiyohara { 399 1.1 kiyohara struct malo_softc *sc = arg; 400 1.1 kiyohara struct ieee80211com *ic = &sc->sc_ic; 401 1.1 kiyohara struct ifnet *ifp = &sc->sc_if; 402 1.1 kiyohara 403 1.1 kiyohara if (!(sc->sc_flags & MALO_DEVICE_ATTACHED)) { 404 1.1 kiyohara /* free firmware */ 405 1.1 kiyohara cmalo_fw_free(sc); 406 1.1 kiyohara 407 1.1 kiyohara /* device was not properly attached */ 408 1.1 kiyohara return; 409 1.1 kiyohara } 410 1.1 kiyohara 411 1.1 kiyohara if (ifp->if_flags & IFF_RUNNING) 412 1.1 kiyohara cmalo_stop(sc); 413 1.1 kiyohara 414 1.1 kiyohara /* free command buffer */ 415 1.1 kiyohara if (sc->sc_cmd != NULL) 416 1.1 kiyohara free(sc->sc_cmd, M_DEVBUF); 417 1.1 kiyohara 418 1.1 kiyohara /* free data buffer */ 419 1.1 kiyohara if (sc->sc_data != NULL) 420 1.1 kiyohara free(sc->sc_data, M_DEVBUF); 421 1.1 kiyohara 422 1.1 kiyohara /* free firmware */ 423 1.1 kiyohara cmalo_fw_free(sc); 424 1.1 kiyohara 425 1.28 andvar /* detach interface */ 426 1.1 kiyohara ieee80211_ifdetach(ic); 427 1.1 kiyohara if_detach(ifp); 428 1.1 kiyohara 429 1.1 kiyohara mutex_destroy(&sc->sc_mtx); 430 1.1 kiyohara cv_destroy(&sc->sc_cv); 431 1.1 kiyohara } 432 1.1 kiyohara 433 1.1 kiyohara static int 434 1.1 kiyohara cmalo_intr(void *arg) 435 1.1 kiyohara { 436 1.1 kiyohara struct malo_softc *sc = arg; 437 1.13 nonaka uint16_t intr; 438 1.1 kiyohara 439 1.1 kiyohara /* read interrupt reason */ 440 1.1 kiyohara intr = MALO_READ_2(sc, MALO_REG_HOST_INTR_CAUSE); 441 1.1 kiyohara if (intr == 0) 442 1.1 kiyohara /* interrupt not for us */ 443 1.1 kiyohara return 0; 444 1.1 kiyohara if (intr == 0xffff) 445 1.1 kiyohara /* card has been detached */ 446 1.1 kiyohara return 0; 447 1.1 kiyohara 448 1.1 kiyohara /* disable interrupts */ 449 1.1 kiyohara cmalo_intr_mask(sc, 0); 450 1.1 kiyohara 451 1.13 nonaka DPRINTF(2, "%s: interrupt handler called (intr = 0x%04x)\n", 452 1.13 nonaka device_xname(sc->sc_dev), intr); 453 1.13 nonaka 454 1.13 nonaka softint_schedule(sc->sc_soft_ih); 455 1.13 nonaka return 1; 456 1.13 nonaka } 457 1.13 nonaka 458 1.13 nonaka static void 459 1.13 nonaka cmalo_softintr(void *arg) 460 1.13 nonaka { 461 1.13 nonaka struct malo_softc *sc = arg; 462 1.13 nonaka uint16_t intr; 463 1.13 nonaka 464 1.13 nonaka /* read interrupt reason */ 465 1.13 nonaka intr = MALO_READ_2(sc, MALO_REG_HOST_INTR_CAUSE); 466 1.13 nonaka if (intr == 0 || intr == 0xffff) 467 1.13 nonaka goto out; 468 1.13 nonaka 469 1.1 kiyohara /* acknowledge interrupt */ 470 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_HOST_INTR_CAUSE, 471 1.1 kiyohara intr & MALO_VAL_HOST_INTR_MASK_ON); 472 1.1 kiyohara 473 1.1 kiyohara if (intr & MALO_VAL_HOST_INTR_TX) 474 1.1 kiyohara /* TX frame sent */ 475 1.1 kiyohara cmalo_tx_done(sc); 476 1.1 kiyohara if (intr & MALO_VAL_HOST_INTR_RX) 477 1.1 kiyohara /* RX frame received */ 478 1.1 kiyohara cmalo_rx(sc); 479 1.1 kiyohara if (intr & MALO_VAL_HOST_INTR_CMD) { 480 1.1 kiyohara /* command response */ 481 1.1 kiyohara mutex_enter(&sc->sc_mtx); 482 1.1 kiyohara cv_signal(&sc->sc_cv); 483 1.1 kiyohara mutex_exit(&sc->sc_mtx); 484 1.1 kiyohara if (!sc->sc_cmd_ctxsave) 485 1.1 kiyohara cmalo_cmd_response(sc); 486 1.1 kiyohara } 487 1.1 kiyohara if (intr & MALO_VAL_HOST_INTR_EVENT) 488 1.1 kiyohara /* event */ 489 1.1 kiyohara cmalo_event(sc); 490 1.1 kiyohara 491 1.13 nonaka out: 492 1.13 nonaka /* enable interrupts */ 493 1.13 nonaka cmalo_intr_mask(sc, 1); 494 1.1 kiyohara } 495 1.1 kiyohara 496 1.1 kiyohara 497 1.1 kiyohara /* 498 1.1 kiyohara * Network functions 499 1.1 kiyohara */ 500 1.1 kiyohara static void 501 1.1 kiyohara cmalo_start(struct ifnet *ifp) 502 1.1 kiyohara { 503 1.1 kiyohara struct malo_softc *sc = ifp->if_softc; 504 1.1 kiyohara struct mbuf *m; 505 1.1 kiyohara 506 1.1 kiyohara /* don't transmit packets if interface is busy or down */ 507 1.1 kiyohara if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 508 1.1 kiyohara return; 509 1.1 kiyohara 510 1.1 kiyohara IFQ_POLL(&ifp->if_snd, m); 511 1.1 kiyohara if (m == NULL) 512 1.1 kiyohara return; 513 1.1 kiyohara 514 1.1 kiyohara IFQ_DEQUEUE(&ifp->if_snd, m); 515 1.1 kiyohara 516 1.18 msaitoh bpf_mtap(ifp, m, BPF_D_OUT); 517 1.1 kiyohara 518 1.1 kiyohara if (cmalo_tx(sc, m) != 0) 519 1.25 thorpej if_statinc(ifp, if_oerrors); 520 1.1 kiyohara } 521 1.1 kiyohara 522 1.1 kiyohara static int 523 1.1 kiyohara cmalo_ioctl(struct ifnet *ifp, u_long cmd, void *data) 524 1.1 kiyohara { 525 1.1 kiyohara struct malo_softc *sc = ifp->if_softc; 526 1.1 kiyohara struct ieee80211com *ic = &sc->sc_ic; 527 1.1 kiyohara int s, error = 0; 528 1.1 kiyohara 529 1.1 kiyohara s = splnet(); 530 1.1 kiyohara 531 1.1 kiyohara switch (cmd) { 532 1.1 kiyohara case SIOCSIFFLAGS: 533 1.1 kiyohara if ((error = ifioctl_common(ifp, cmd, data)) != 0) 534 1.1 kiyohara break; 535 1.1 kiyohara switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { 536 1.1 kiyohara case IFF_RUNNING: 537 1.1 kiyohara cmalo_stop(sc); 538 1.1 kiyohara break; 539 1.1 kiyohara 540 1.1 kiyohara case IFF_UP: 541 1.1 kiyohara cmalo_init(ifp); 542 1.1 kiyohara break; 543 1.1 kiyohara 544 1.1 kiyohara default: 545 1.1 kiyohara break; 546 1.1 kiyohara } 547 1.1 kiyohara error = 0; 548 1.1 kiyohara break; 549 1.1 kiyohara 550 1.1 kiyohara case SIOCADDMULTI: 551 1.1 kiyohara case SIOCDELMULTI: 552 1.1 kiyohara if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) 553 1.1 kiyohara /* setup multicast filter, etc */ 554 1.1 kiyohara error = 0; 555 1.1 kiyohara break; 556 1.1 kiyohara 557 1.1 kiyohara default: 558 1.1 kiyohara error = ieee80211_ioctl(ic, cmd, data); 559 1.1 kiyohara break; 560 1.1 kiyohara } 561 1.1 kiyohara 562 1.1 kiyohara if (error == ENETRESET) { 563 1.1 kiyohara if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 564 1.1 kiyohara (IFF_UP | IFF_RUNNING)) 565 1.1 kiyohara cmalo_init(ifp); 566 1.1 kiyohara error = 0; 567 1.1 kiyohara } 568 1.1 kiyohara 569 1.1 kiyohara splx(s); 570 1.1 kiyohara 571 1.1 kiyohara return error; 572 1.1 kiyohara } 573 1.1 kiyohara 574 1.1 kiyohara static int 575 1.1 kiyohara cmalo_init(struct ifnet *ifp) 576 1.1 kiyohara { 577 1.1 kiyohara struct malo_softc *sc = ifp->if_softc; 578 1.1 kiyohara struct ieee80211com *ic = &sc->sc_ic; 579 1.1 kiyohara 580 1.1 kiyohara if (!(sc->sc_flags & MALO_DEVICE_ENABLED)) 581 1.1 kiyohara malo_pcmcia_enable(sc); 582 1.1 kiyohara 583 1.1 kiyohara /* reload the firmware if necessary */ 584 1.1 kiyohara if (!(sc->sc_flags & MALO_FW_LOADED)) { 585 1.1 kiyohara /* disable interrupts */ 586 1.1 kiyohara cmalo_intr_mask(sc, 0); 587 1.1 kiyohara 588 1.1 kiyohara /* load firmware */ 589 1.1 kiyohara if (cmalo_fw_load_helper(sc) != 0) 590 1.1 kiyohara return EIO; 591 1.1 kiyohara if (cmalo_fw_load_main(sc) != 0) 592 1.1 kiyohara return EIO; 593 1.1 kiyohara sc->sc_flags |= MALO_FW_LOADED; 594 1.1 kiyohara 595 1.1 kiyohara /* enable interrupts */ 596 1.1 kiyohara cmalo_intr_mask(sc, 1); 597 1.1 kiyohara } 598 1.1 kiyohara 599 1.1 kiyohara if (ifp->if_flags & IFF_RUNNING) 600 1.1 kiyohara cmalo_stop(sc); 601 1.1 kiyohara 602 1.1 kiyohara /* reset association state flag */ 603 1.1 kiyohara sc->sc_flags &= ~MALO_ASSOC_FAILED; 604 1.1 kiyohara 605 1.1 kiyohara /* get current channel */ 606 1.1 kiyohara ic->ic_curchan = ic->ic_ibss_chan; 607 1.1 kiyohara sc->sc_curchan = ieee80211_chan2ieee(ic, ic->ic_curchan); 608 1.1 kiyohara DPRINTF(1, "%s: current channel is %d\n", 609 1.1 kiyohara device_xname(sc->sc_dev), sc->sc_curchan); 610 1.1 kiyohara 611 1.1 kiyohara /* setup device */ 612 1.1 kiyohara if (cmalo_cmd_set_macctrl(sc) != 0) 613 1.1 kiyohara return EIO; 614 1.1 kiyohara if (cmalo_cmd_set_txpower(sc, 15) != 0) 615 1.1 kiyohara return EIO; 616 1.1 kiyohara if (cmalo_cmd_set_antenna(sc, 1) != 0) 617 1.1 kiyohara return EIO; 618 1.1 kiyohara if (cmalo_cmd_set_antenna(sc, 2) != 0) 619 1.1 kiyohara return EIO; 620 1.1 kiyohara if (cmalo_cmd_set_radio(sc, 1) != 0) 621 1.1 kiyohara return EIO; 622 1.1 kiyohara if (cmalo_cmd_set_channel(sc, sc->sc_curchan) != 0) 623 1.1 kiyohara return EIO; 624 1.1 kiyohara if (cmalo_cmd_set_rate(sc, ic->ic_fixed_rate) != 0) 625 1.1 kiyohara return EIO; 626 1.1 kiyohara if (cmalo_cmd_set_snmp(sc, MALO_OID_RTSTRESH) != 0) 627 1.1 kiyohara return EIO; 628 1.1 kiyohara if (cmalo_cmd_set_snmp(sc, MALO_OID_SHORTRETRY) != 0) 629 1.1 kiyohara return EIO; 630 1.1 kiyohara if (cmalo_cmd_set_snmp(sc, MALO_OID_FRAGTRESH) != 0) 631 1.1 kiyohara return EIO; 632 1.1 kiyohara IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); 633 1.1 kiyohara if (cmalo_cmd_set_macaddr(sc, ic->ic_myaddr) != 0) 634 1.1 kiyohara return EIO; 635 1.1 kiyohara if (ic->ic_flags & IEEE80211_F_PRIVACY) 636 1.1 kiyohara if (cmalo_wep(sc) != 0) 637 1.1 kiyohara return EIO; 638 1.1 kiyohara 639 1.1 kiyohara /* device up */ 640 1.1 kiyohara ifp->if_flags |= IFF_RUNNING; 641 1.1 kiyohara ifp->if_flags &= ~IFF_OACTIVE; 642 1.1 kiyohara 643 1.1 kiyohara /* start network */ 644 1.1 kiyohara if (ic->ic_opmode != IEEE80211_M_MONITOR) 645 1.1 kiyohara ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 646 1.1 kiyohara if (sc->sc_flags & MALO_ASSOC_FAILED) 647 1.1 kiyohara ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 648 1.1 kiyohara else 649 1.1 kiyohara ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 650 1.1 kiyohara 651 1.1 kiyohara /* we are not context save anymore for FW commands */ 652 1.1 kiyohara sc->sc_cmd_ctxsave = 0; 653 1.1 kiyohara 654 1.1 kiyohara return 0; 655 1.1 kiyohara } 656 1.1 kiyohara 657 1.1 kiyohara static void 658 1.1 kiyohara cmalo_watchdog(struct ifnet *ifp) 659 1.1 kiyohara { 660 1.1 kiyohara DPRINTF(2, "watchdog timeout\n"); 661 1.1 kiyohara 662 1.1 kiyohara /* accept TX packets again */ 663 1.1 kiyohara ifp->if_flags &= ~IFF_OACTIVE; 664 1.1 kiyohara } 665 1.1 kiyohara 666 1.1 kiyohara static int 667 1.1 kiyohara cmalo_media_change(struct ifnet *ifp) 668 1.1 kiyohara { 669 1.1 kiyohara int error; 670 1.1 kiyohara 671 1.10 macallan if ((error = ieee80211_media_change(ifp)) != ENETRESET) 672 1.1 kiyohara return error; 673 1.1 kiyohara 674 1.1 kiyohara if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) 675 1.1 kiyohara cmalo_init(ifp); 676 1.1 kiyohara 677 1.1 kiyohara return 0; 678 1.1 kiyohara } 679 1.1 kiyohara 680 1.1 kiyohara static int 681 1.1 kiyohara cmalo_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 682 1.1 kiyohara { 683 1.1 kiyohara struct malo_softc *sc = ic->ic_ifp->if_softc; 684 1.1 kiyohara enum ieee80211_state ostate; 685 1.1 kiyohara 686 1.1 kiyohara ostate = ic->ic_state; 687 1.1 kiyohara 688 1.1 kiyohara if (ostate == nstate) 689 1.1 kiyohara goto out; 690 1.1 kiyohara 691 1.1 kiyohara switch (nstate) { 692 1.1 kiyohara case IEEE80211_S_INIT: 693 1.1 kiyohara DPRINTF(1, "%s: newstate is IEEE80211_S_INIT\n", 694 1.1 kiyohara device_xname(sc->sc_dev)); 695 1.1 kiyohara break; 696 1.1 kiyohara case IEEE80211_S_SCAN: 697 1.1 kiyohara DPRINTF(1, "%s: newstate is IEEE80211_S_SCAN\n", 698 1.1 kiyohara device_xname(sc->sc_dev)); 699 1.1 kiyohara cmalo_cmd_set_scan(sc); 700 1.1 kiyohara if (!sc->sc_net_num) { 701 1.1 kiyohara /* no networks found */ 702 1.1 kiyohara DPRINTF(1, "%s: no networks found\n", 703 1.1 kiyohara device_xname(sc->sc_dev)); 704 1.1 kiyohara break; 705 1.1 kiyohara } 706 1.1 kiyohara cmalo_select_network(sc); 707 1.1 kiyohara cmalo_cmd_set_auth(sc); 708 1.1 kiyohara cmalo_cmd_set_assoc(sc); 709 1.1 kiyohara break; 710 1.1 kiyohara case IEEE80211_S_AUTH: 711 1.1 kiyohara DPRINTF(1, "%s: newstate is IEEE80211_S_AUTH\n", 712 1.1 kiyohara device_xname(sc->sc_dev)); 713 1.1 kiyohara break; 714 1.1 kiyohara case IEEE80211_S_ASSOC: 715 1.1 kiyohara DPRINTF(1, "%s: newstate is IEEE80211_S_ASSOC\n", 716 1.1 kiyohara device_xname(sc->sc_dev)); 717 1.1 kiyohara break; 718 1.1 kiyohara case IEEE80211_S_RUN: 719 1.1 kiyohara DPRINTF(1, "%s: newstate is IEEE80211_S_RUN\n", 720 1.1 kiyohara device_xname(sc->sc_dev)); 721 1.1 kiyohara cmalo_reflect_network(sc); 722 1.1 kiyohara break; 723 1.1 kiyohara default: 724 1.1 kiyohara break; 725 1.1 kiyohara } 726 1.1 kiyohara 727 1.1 kiyohara out: 728 1.1 kiyohara return sc->sc_newstate(ic, nstate, arg); 729 1.1 kiyohara } 730 1.1 kiyohara 731 1.1 kiyohara 732 1.1 kiyohara static int 733 1.1 kiyohara firmware_load(const char *dname, const char *iname, uint8_t **ucodep, 734 1.1 kiyohara size_t *sizep) 735 1.1 kiyohara { 736 1.1 kiyohara firmware_handle_t fh; 737 1.1 kiyohara int error; 738 1.1 kiyohara 739 1.1 kiyohara if ((error = firmware_open(dname, iname, &fh)) != 0) 740 1.1 kiyohara return error; 741 1.1 kiyohara *sizep = firmware_get_size(fh); 742 1.1 kiyohara if ((*ucodep = firmware_malloc(*sizep)) == NULL) { 743 1.1 kiyohara firmware_close(fh); 744 1.1 kiyohara return ENOMEM; 745 1.1 kiyohara } 746 1.1 kiyohara if ((error = firmware_read(fh, 0, *ucodep, *sizep)) != 0) 747 1.1 kiyohara firmware_free(*ucodep, *sizep); 748 1.1 kiyohara firmware_close(fh); 749 1.1 kiyohara 750 1.1 kiyohara return error; 751 1.1 kiyohara } 752 1.1 kiyohara 753 1.1 kiyohara static int 754 1.1 kiyohara cmalo_fw_alloc(struct malo_softc *sc) 755 1.1 kiyohara { 756 1.1 kiyohara const char *name_h = "malo8385-h"; 757 1.1 kiyohara const char *name_m = "malo8385-m"; 758 1.1 kiyohara int error; 759 1.1 kiyohara 760 1.1 kiyohara if (sc->sc_fw_h == NULL) { 761 1.1 kiyohara /* read helper firmware image */ 762 1.1 kiyohara error = firmware_load("malo", name_h, &sc->sc_fw_h, 763 1.1 kiyohara &sc->sc_fw_h_size); 764 1.1 kiyohara if (error != 0) { 765 1.1 kiyohara aprint_error_dev(sc->sc_dev, 766 1.1 kiyohara "error %d, could not read firmware %s\n", 767 1.1 kiyohara error, name_h); 768 1.1 kiyohara return EIO; 769 1.1 kiyohara } 770 1.1 kiyohara } 771 1.1 kiyohara 772 1.1 kiyohara if (sc->sc_fw_m == NULL) { 773 1.1 kiyohara /* read main firmware image */ 774 1.1 kiyohara error = firmware_load("malo", name_m, &sc->sc_fw_m, 775 1.1 kiyohara &sc->sc_fw_m_size); 776 1.1 kiyohara if (error != 0) { 777 1.1 kiyohara aprint_error_dev(sc->sc_dev, 778 1.1 kiyohara "error %d, could not read firmware %s\n", 779 1.1 kiyohara error, name_m); 780 1.1 kiyohara return EIO; 781 1.1 kiyohara } 782 1.1 kiyohara } 783 1.1 kiyohara 784 1.1 kiyohara return 0; 785 1.1 kiyohara } 786 1.1 kiyohara 787 1.1 kiyohara static void 788 1.1 kiyohara cmalo_fw_free(struct malo_softc *sc) 789 1.1 kiyohara { 790 1.1 kiyohara 791 1.1 kiyohara if (sc->sc_fw_h != NULL) { 792 1.1 kiyohara firmware_free(sc->sc_fw_h, sc->sc_fw_h_size); 793 1.1 kiyohara sc->sc_fw_h = NULL; 794 1.1 kiyohara } 795 1.1 kiyohara 796 1.1 kiyohara if (sc->sc_fw_m != NULL) { 797 1.1 kiyohara firmware_free(sc->sc_fw_m, sc->sc_fw_m_size); 798 1.1 kiyohara sc->sc_fw_m = NULL; 799 1.1 kiyohara } 800 1.1 kiyohara } 801 1.1 kiyohara 802 1.1 kiyohara static int 803 1.1 kiyohara cmalo_fw_load_helper(struct malo_softc *sc) 804 1.1 kiyohara { 805 1.1 kiyohara uint8_t val8; 806 1.1 kiyohara uint16_t bsize, *uc; 807 1.1 kiyohara int offset, i; 808 1.1 kiyohara 809 1.1 kiyohara /* verify if the card is ready for firmware download */ 810 1.1 kiyohara val8 = MALO_READ_1(sc, MALO_REG_SCRATCH); 811 1.1 kiyohara if (val8 == MALO_VAL_SCRATCH_FW_LOADED) 812 1.1 kiyohara /* firmware already loaded */ 813 1.1 kiyohara return 0; 814 1.1 kiyohara if (val8 != MALO_VAL_SCRATCH_READY) { 815 1.1 kiyohara /* bad register value */ 816 1.1 kiyohara aprint_error_dev(sc->sc_dev, 817 1.1 kiyohara "device not ready for FW download\n"); 818 1.1 kiyohara return EIO; 819 1.1 kiyohara } 820 1.1 kiyohara 821 1.1 kiyohara /* download the helper firmware */ 822 1.1 kiyohara for (offset = 0; offset < sc->sc_fw_h_size; offset += bsize) { 823 1.1 kiyohara if (sc->sc_fw_h_size - offset >= MALO_FW_HELPER_BSIZE) 824 1.1 kiyohara bsize = MALO_FW_HELPER_BSIZE; 825 1.1 kiyohara else 826 1.1 kiyohara bsize = sc->sc_fw_h_size - offset; 827 1.1 kiyohara 828 1.1 kiyohara /* send a block in words and confirm it */ 829 1.1 kiyohara DPRINTF(3, "%s: download helper FW block (%d bytes, %d off)\n", 830 1.1 kiyohara device_xname(sc->sc_dev), bsize, offset); 831 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_CMD_WRITE_LEN, bsize); 832 1.1 kiyohara uc = (uint16_t *)(sc->sc_fw_h + offset); 833 1.1 kiyohara for (i = 0; i < bsize / 2; i++) 834 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_CMD_WRITE, htole16(uc[i])); 835 1.1 kiyohara MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_CMD_DL_OVER); 836 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, 837 1.1 kiyohara MALO_VAL_CMD_DL_OVER); 838 1.1 kiyohara 839 1.1 kiyohara /* poll for an acknowledgement */ 840 1.1 kiyohara for (i = 0; i < 50; i++) { 841 1.1 kiyohara if (MALO_READ_1(sc, MALO_REG_CARD_STATUS) == 842 1.1 kiyohara MALO_VAL_CMD_DL_OVER) 843 1.1 kiyohara break; 844 1.1 kiyohara delay(1000); 845 1.1 kiyohara } 846 1.1 kiyohara if (i == 50) { 847 1.1 kiyohara aprint_error_dev(sc->sc_dev, 848 1.1 kiyohara "timeout while helper FW block download\n"); 849 1.1 kiyohara return EIO; 850 1.1 kiyohara } 851 1.1 kiyohara } 852 1.1 kiyohara 853 1.1 kiyohara /* helper firmware download done */ 854 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_CMD_WRITE_LEN, 0); 855 1.1 kiyohara MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_CMD_DL_OVER); 856 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, MALO_VAL_CMD_DL_OVER); 857 1.1 kiyohara DPRINTF(1, "%s: helper FW downloaded\n", device_xname(sc->sc_dev)); 858 1.1 kiyohara 859 1.1 kiyohara return 0; 860 1.1 kiyohara } 861 1.1 kiyohara 862 1.1 kiyohara static int 863 1.1 kiyohara cmalo_fw_load_main(struct malo_softc *sc) 864 1.1 kiyohara { 865 1.1 kiyohara uint16_t val16, bsize = 0, *uc; 866 1.1 kiyohara int offset, i, retry = 0; 867 1.1 kiyohara 868 1.1 kiyohara /* verify if the helper firmware has been loaded correctly */ 869 1.1 kiyohara for (i = 0; i < 10; i++) { 870 1.1 kiyohara if (MALO_READ_1(sc, MALO_REG_RBAL) == MALO_FW_HELPER_LOADED) 871 1.1 kiyohara break; 872 1.1 kiyohara delay(1000); 873 1.1 kiyohara } 874 1.1 kiyohara if (i == 10) { 875 1.1 kiyohara aprint_error_dev(sc->sc_dev, "helper FW not loaded\n"); 876 1.1 kiyohara return EIO; 877 1.1 kiyohara } 878 1.1 kiyohara DPRINTF(1, "%s: helper FW loaded successfully\n", 879 1.1 kiyohara device_xname(sc->sc_dev)); 880 1.1 kiyohara 881 1.1 kiyohara /* download the main firmware */ 882 1.1 kiyohara for (offset = 0; offset < sc->sc_fw_m_size; offset += bsize) { 883 1.1 kiyohara val16 = MALO_READ_2(sc, MALO_REG_RBAL); 884 1.1 kiyohara /* 885 1.1 kiyohara * If the helper firmware serves us an odd integer then 886 1.1 kiyohara * something went wrong and we retry to download the last 887 1.1 kiyohara * block until we receive a good integer again, or give up. 888 1.1 kiyohara */ 889 1.1 kiyohara if (val16 & 0x0001) { 890 1.1 kiyohara if (retry > MALO_FW_MAIN_MAXRETRY) { 891 1.1 kiyohara aprint_error_dev(sc->sc_dev, 892 1.1 kiyohara "main FW download failed\n"); 893 1.1 kiyohara return EIO; 894 1.1 kiyohara } 895 1.1 kiyohara retry++; 896 1.1 kiyohara offset -= bsize; 897 1.1 kiyohara } else { 898 1.1 kiyohara retry = 0; 899 1.1 kiyohara bsize = val16; 900 1.1 kiyohara } 901 1.1 kiyohara 902 1.1 kiyohara /* send a block in words and confirm it */ 903 1.1 kiyohara DPRINTF(3, "%s: download main FW block (%d bytes, %d off)\n", 904 1.1 kiyohara device_xname(sc->sc_dev), bsize, offset); 905 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_CMD_WRITE_LEN, bsize); 906 1.1 kiyohara uc = (uint16_t *)(sc->sc_fw_m + offset); 907 1.1 kiyohara for (i = 0; i < bsize / 2; i++) 908 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_CMD_WRITE, htole16(uc[i])); 909 1.1 kiyohara MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_CMD_DL_OVER); 910 1.20 msaitoh MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, 911 1.1 kiyohara MALO_VAL_CMD_DL_OVER); 912 1.1 kiyohara 913 1.1 kiyohara /* poll for an acknowledgement */ 914 1.1 kiyohara for (i = 0; i < 5000; i++) { 915 1.1 kiyohara if (MALO_READ_1(sc, MALO_REG_CARD_STATUS) == 916 1.1 kiyohara MALO_VAL_CMD_DL_OVER) 917 1.1 kiyohara break; 918 1.1 kiyohara } 919 1.1 kiyohara if (i == 5000) { 920 1.1 kiyohara aprint_error_dev(sc->sc_dev, 921 1.1 kiyohara "timeout while main FW block download\n"); 922 1.1 kiyohara return EIO; 923 1.1 kiyohara } 924 1.1 kiyohara } 925 1.1 kiyohara 926 1.1 kiyohara DPRINTF(1, "%s: main FW downloaded\n", device_xname(sc->sc_dev)); 927 1.1 kiyohara 928 1.1 kiyohara /* verify if the main firmware has been loaded correctly */ 929 1.1 kiyohara for (i = 0; i < 500; i++) { 930 1.1 kiyohara if (MALO_READ_1(sc, MALO_REG_SCRATCH) == 931 1.1 kiyohara MALO_VAL_SCRATCH_FW_LOADED) 932 1.1 kiyohara break; 933 1.1 kiyohara delay(1000); 934 1.1 kiyohara } 935 1.1 kiyohara if (i == 500) { 936 1.1 kiyohara aprint_error_dev(sc->sc_dev, "main FW not loaded\n"); 937 1.1 kiyohara return EIO; 938 1.1 kiyohara } 939 1.1 kiyohara 940 1.1 kiyohara DPRINTF(1, "%s: main FW loaded successfully\n", 941 1.1 kiyohara device_xname(sc->sc_dev)); 942 1.1 kiyohara 943 1.1 kiyohara return 0; 944 1.1 kiyohara } 945 1.1 kiyohara 946 1.1 kiyohara static void 947 1.1 kiyohara cmalo_stop(struct malo_softc *sc) 948 1.1 kiyohara { 949 1.1 kiyohara struct ieee80211com *ic = &sc->sc_ic; 950 1.13 nonaka struct ifnet *ifp = &sc->sc_if; 951 1.1 kiyohara 952 1.1 kiyohara /* device down */ 953 1.1 kiyohara ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 954 1.1 kiyohara 955 1.1 kiyohara /* change device back to initial state */ 956 1.1 kiyohara ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 957 1.1 kiyohara 958 1.1 kiyohara /* reset device */ 959 1.1 kiyohara cmalo_cmd_set_reset(sc); 960 1.1 kiyohara sc->sc_flags &= ~MALO_FW_LOADED; 961 1.1 kiyohara 962 1.1 kiyohara if (sc->sc_flags & MALO_DEVICE_ENABLED) 963 1.1 kiyohara malo_pcmcia_disable(sc); 964 1.1 kiyohara 965 1.1 kiyohara DPRINTF(1, "%s: device down\n", device_xname(sc->sc_dev)); 966 1.1 kiyohara } 967 1.1 kiyohara 968 1.1 kiyohara static void 969 1.1 kiyohara cmalo_intr_mask(struct malo_softc *sc, int enable) 970 1.1 kiyohara { 971 1.1 kiyohara uint16_t val16; 972 1.1 kiyohara 973 1.1 kiyohara val16 = MALO_READ_2(sc, MALO_REG_HOST_INTR_MASK); 974 1.1 kiyohara 975 1.1 kiyohara DPRINTF(3, "%s: intr mask changed from 0x%04x ", 976 1.1 kiyohara device_xname(sc->sc_dev), val16); 977 1.1 kiyohara 978 1.1 kiyohara if (enable) 979 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_HOST_INTR_MASK, 980 1.1 kiyohara val16 & ~MALO_VAL_HOST_INTR_MASK_ON); 981 1.1 kiyohara else 982 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_HOST_INTR_MASK, 983 1.1 kiyohara val16 | MALO_VAL_HOST_INTR_MASK_ON); 984 1.1 kiyohara 985 1.1 kiyohara val16 = MALO_READ_2(sc, MALO_REG_HOST_INTR_MASK); 986 1.1 kiyohara 987 1.1 kiyohara DPRINTF(3, "to 0x%04x\n", val16); 988 1.1 kiyohara } 989 1.1 kiyohara 990 1.1 kiyohara static void 991 1.1 kiyohara cmalo_rx(struct malo_softc *sc) 992 1.1 kiyohara { 993 1.1 kiyohara struct ieee80211com *ic = &sc->sc_ic; 994 1.1 kiyohara struct ifnet *ifp = &sc->sc_if; 995 1.1 kiyohara struct malo_rx_desc *rxdesc; 996 1.1 kiyohara struct mbuf *m; 997 1.1 kiyohara uint8_t *data; 998 1.1 kiyohara uint16_t psize; 999 1.1 kiyohara int i; 1000 1.1 kiyohara 1001 1.1 kiyohara /* read the whole RX packet which is always 802.3 */ 1002 1.1 kiyohara psize = MALO_READ_2(sc, MALO_REG_DATA_READ_LEN); 1003 1.1 kiyohara if (psize > MALO_DATA_BUFFER_SIZE) { 1004 1.1 kiyohara aprint_error_dev(sc->sc_dev, 1005 1.1 kiyohara "received data too large: %dbyte\n", psize); 1006 1.1 kiyohara return; 1007 1.1 kiyohara } 1008 1.1 kiyohara 1009 1.1 kiyohara MALO_READ_MULTI_2(sc, MALO_REG_DATA_READ, 1010 1.1 kiyohara (uint16_t *)sc->sc_data, psize / sizeof(uint16_t)); 1011 1.1 kiyohara if (psize & 0x0001) 1012 1.1 kiyohara sc->sc_data[psize - 1] = MALO_READ_1(sc, MALO_REG_DATA_READ); 1013 1.1 kiyohara MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_RX_DL_OVER); 1014 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, MALO_VAL_RX_DL_OVER); 1015 1.1 kiyohara 1016 1.1 kiyohara /* access RX packet descriptor */ 1017 1.1 kiyohara rxdesc = (struct malo_rx_desc *)sc->sc_data; 1018 1.1 kiyohara rxdesc->status = le16toh(rxdesc->status); 1019 1.1 kiyohara rxdesc->pkglen = le16toh(rxdesc->pkglen); 1020 1.1 kiyohara rxdesc->pkgoffset = le32toh(rxdesc->pkgoffset); 1021 1.1 kiyohara 1022 1.1 kiyohara DPRINTF(2, "RX status=%d, pkglen=%d, pkgoffset=%d\n", 1023 1.1 kiyohara rxdesc->status, rxdesc->pkglen, rxdesc->pkgoffset); 1024 1.1 kiyohara 1025 1.1 kiyohara if (rxdesc->status != MALO_RX_STATUS_OK) 1026 1.1 kiyohara /* RX packet is not OK */ 1027 1.1 kiyohara return; 1028 1.1 kiyohara 1029 1.1 kiyohara /* remove the LLC / SNAP header */ 1030 1.1 kiyohara data = sc->sc_data + rxdesc->pkgoffset; 1031 1.1 kiyohara i = (ETHER_ADDR_LEN * 2) + sizeof(struct llc); 1032 1.1 kiyohara memcpy(data + (ETHER_ADDR_LEN * 2), data + i, rxdesc->pkglen - i); 1033 1.1 kiyohara rxdesc->pkglen -= sizeof(struct llc); 1034 1.1 kiyohara 1035 1.1 kiyohara /* prepare mbuf */ 1036 1.1 kiyohara m = m_devget(sc->sc_data + rxdesc->pkgoffset, 1037 1.19 maxv rxdesc->pkglen, ETHER_ALIGN, ifp); 1038 1.1 kiyohara if (m == NULL) { 1039 1.1 kiyohara DPRINTF(1, "RX m_devget failed\n"); 1040 1.25 thorpej if_statinc(ifp, if_ierrors); 1041 1.1 kiyohara return; 1042 1.1 kiyohara } 1043 1.1 kiyohara 1044 1.1 kiyohara /* push the frame up to the network stack if not in monitor mode */ 1045 1.16 maxv if (ic->ic_opmode != IEEE80211_M_MONITOR) { 1046 1.8 ozaki if_percpuq_enqueue(ifp->if_percpuq, m); 1047 1.16 maxv } else { 1048 1.16 maxv /* XXX: we don't do anything with it? */ 1049 1.16 maxv m_freem(m); 1050 1.16 maxv } 1051 1.1 kiyohara } 1052 1.1 kiyohara 1053 1.1 kiyohara static int 1054 1.1 kiyohara cmalo_tx(struct malo_softc *sc, struct mbuf *m) 1055 1.1 kiyohara { 1056 1.1 kiyohara struct ifnet *ifp = &sc->sc_if; 1057 1.1 kiyohara struct malo_tx_desc *txdesc = (struct malo_tx_desc *)sc->sc_data; 1058 1.1 kiyohara uint8_t *data; 1059 1.1 kiyohara uint16_t psize; 1060 1.1 kiyohara 1061 1.1 kiyohara memset(sc->sc_data, 0, sizeof(*txdesc)); 1062 1.1 kiyohara psize = sizeof(*txdesc) + m->m_pkthdr.len; 1063 1.1 kiyohara data = mtod(m, uint8_t *); 1064 1.1 kiyohara 1065 1.1 kiyohara /* prepare TX descriptor */ 1066 1.1 kiyohara txdesc->pkgoffset = htole32(sizeof(*txdesc)); 1067 1.1 kiyohara txdesc->pkglen = htole16(m->m_pkthdr.len); 1068 1.7 christos memcpy(txdesc->dstaddr, data, ETHER_ADDR_LEN); 1069 1.1 kiyohara 1070 1.1 kiyohara /* copy mbuf data to the buffer */ 1071 1.1 kiyohara m_copydata(m, 0, m->m_pkthdr.len, sc->sc_data + sizeof(*txdesc)); 1072 1.1 kiyohara m_freem(m); 1073 1.1 kiyohara 1074 1.1 kiyohara /* send TX packet to the device */ 1075 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_DATA_WRITE_LEN, psize); 1076 1.1 kiyohara MALO_WRITE_MULTI_2(sc, MALO_REG_DATA_WRITE, 1077 1.1 kiyohara (uint16_t *)sc->sc_data, psize / sizeof(uint16_t)); 1078 1.1 kiyohara if (psize & 0x0001) { 1079 1.1 kiyohara data = sc->sc_data; 1080 1.1 kiyohara MALO_WRITE_1(sc, MALO_REG_DATA_WRITE, data[psize - 1]); 1081 1.1 kiyohara } 1082 1.1 kiyohara MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_TX_DL_OVER); 1083 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, MALO_VAL_TX_DL_OVER); 1084 1.1 kiyohara 1085 1.1 kiyohara ifp->if_flags |= IFF_OACTIVE; 1086 1.1 kiyohara ifp->if_timer = 5; 1087 1.1 kiyohara 1088 1.1 kiyohara DPRINTF(2, "%s: TX status=%d, pkglen=%d, pkgoffset=%zd\n", 1089 1.1 kiyohara device_xname(sc->sc_dev), txdesc->status, le16toh(txdesc->pkglen), 1090 1.1 kiyohara sizeof(*txdesc)); 1091 1.1 kiyohara 1092 1.1 kiyohara return 0; 1093 1.1 kiyohara } 1094 1.1 kiyohara 1095 1.1 kiyohara static void 1096 1.1 kiyohara cmalo_tx_done(struct malo_softc *sc) 1097 1.1 kiyohara { 1098 1.1 kiyohara struct ifnet *ifp = &sc->sc_if; 1099 1.13 nonaka int s; 1100 1.1 kiyohara 1101 1.1 kiyohara DPRINTF(2, "%s: TX done\n", device_xname(sc->sc_dev)); 1102 1.1 kiyohara 1103 1.13 nonaka s = splnet(); 1104 1.25 thorpej if_statinc(ifp, if_opackets); 1105 1.1 kiyohara ifp->if_flags &= ~IFF_OACTIVE; 1106 1.1 kiyohara ifp->if_timer = 0; 1107 1.13 nonaka cmalo_start(ifp); 1108 1.13 nonaka splx(s); 1109 1.1 kiyohara } 1110 1.1 kiyohara 1111 1.1 kiyohara static void 1112 1.1 kiyohara cmalo_event(struct malo_softc *sc) 1113 1.1 kiyohara { 1114 1.1 kiyohara uint16_t event; 1115 1.1 kiyohara 1116 1.1 kiyohara /* read event reason */ 1117 1.1 kiyohara event = MALO_READ_2(sc, MALO_REG_CARD_STATUS); 1118 1.1 kiyohara event &= MALO_VAL_CARD_STATUS_MASK; 1119 1.1 kiyohara event = event >> 8; 1120 1.1 kiyohara 1121 1.1 kiyohara switch (event) { 1122 1.1 kiyohara case MALO_EVENT_DEAUTH: 1123 1.1 kiyohara DPRINTF(1, "%s: got deauthentication event (0x%04x)\n", 1124 1.1 kiyohara device_xname(sc->sc_dev), event); 1125 1.1 kiyohara /* try to associate again */ 1126 1.1 kiyohara cmalo_cmd_set_assoc(sc); 1127 1.1 kiyohara break; 1128 1.1 kiyohara case MALO_EVENT_DISASSOC: 1129 1.1 kiyohara DPRINTF(1, "%s: got disassociation event (0x%04x)\n", 1130 1.1 kiyohara device_xname(sc->sc_dev), event); 1131 1.1 kiyohara /* try to associate again */ 1132 1.1 kiyohara cmalo_cmd_set_assoc(sc); 1133 1.1 kiyohara break; 1134 1.1 kiyohara default: 1135 1.1 kiyohara DPRINTF(1, "%s: got unknown event (0x%04x)\n", 1136 1.1 kiyohara device_xname(sc->sc_dev), event); 1137 1.1 kiyohara break; 1138 1.1 kiyohara } 1139 1.1 kiyohara 1140 1.1 kiyohara /* acknowledge event */ 1141 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, MALO_VAL_HOST_INTR_EVENT); 1142 1.1 kiyohara } 1143 1.1 kiyohara 1144 1.1 kiyohara static void 1145 1.1 kiyohara cmalo_select_network(struct malo_softc *sc) 1146 1.1 kiyohara { 1147 1.1 kiyohara struct ieee80211com *ic = &sc->sc_ic; 1148 1.1 kiyohara int i, best_rssi; 1149 1.1 kiyohara 1150 1.1 kiyohara /* reset last selected network */ 1151 1.1 kiyohara sc->sc_net_cur = 0; 1152 1.1 kiyohara 1153 1.1 kiyohara /* get desired network */ 1154 1.1 kiyohara if (ic->ic_des_esslen) { 1155 1.1 kiyohara for (i = 0; i < sc->sc_net_num; i++) { 1156 1.1 kiyohara if (!strcmp(ic->ic_des_essid, sc->sc_net[i].ssid)) { 1157 1.1 kiyohara sc->sc_net_cur = i; 1158 1.1 kiyohara DPRINTF(1, "%s: desired network found (%s)\n", 1159 1.1 kiyohara device_xname(sc->sc_dev), 1160 1.1 kiyohara ic->ic_des_essid); 1161 1.1 kiyohara return; 1162 1.1 kiyohara } 1163 1.1 kiyohara } 1164 1.1 kiyohara DPRINTF(1, "%s: desired network not found in scan results " 1165 1.1 kiyohara "(%s)\n", 1166 1.1 kiyohara device_xname(sc->sc_dev), ic->ic_des_essid); 1167 1.1 kiyohara } 1168 1.1 kiyohara 1169 1.1 kiyohara /* get network with best signal strength */ 1170 1.1 kiyohara best_rssi = sc->sc_net[0].rssi; 1171 1.1 kiyohara for (i = 0; i < sc->sc_net_num; i++) { 1172 1.1 kiyohara if (best_rssi < sc->sc_net[i].rssi) { 1173 1.1 kiyohara best_rssi = sc->sc_net[i].rssi; 1174 1.1 kiyohara sc->sc_net_cur = i; 1175 1.1 kiyohara } 1176 1.1 kiyohara } 1177 1.1 kiyohara DPRINTF(1, "%s: best network found (%s)\n", 1178 1.1 kiyohara device_xname(sc->sc_dev), sc->sc_net[sc->sc_net_cur].ssid); 1179 1.1 kiyohara } 1180 1.1 kiyohara 1181 1.1 kiyohara static void 1182 1.1 kiyohara cmalo_reflect_network(struct malo_softc *sc) 1183 1.1 kiyohara { 1184 1.1 kiyohara struct ieee80211com *ic = &sc->sc_ic; 1185 1.1 kiyohara uint8_t chan; 1186 1.1 kiyohara 1187 1.1 kiyohara /* reflect active network to our 80211 stack */ 1188 1.1 kiyohara 1189 1.1 kiyohara /* BSSID */ 1190 1.1 kiyohara IEEE80211_ADDR_COPY(ic->ic_bss->ni_bssid, 1191 1.1 kiyohara sc->sc_net[sc->sc_net_cur].bssid); 1192 1.1 kiyohara 1193 1.1 kiyohara /* SSID */ 1194 1.1 kiyohara ic->ic_bss->ni_esslen = strlen(sc->sc_net[sc->sc_net_cur].ssid); 1195 1.1 kiyohara memcpy(ic->ic_bss->ni_essid, sc->sc_net[sc->sc_net_cur].ssid, 1196 1.1 kiyohara ic->ic_bss->ni_esslen); 1197 1.1 kiyohara 1198 1.1 kiyohara /* channel */ 1199 1.1 kiyohara chan = sc->sc_net[sc->sc_net_cur].channel; 1200 1.1 kiyohara ic->ic_curchan = &ic->ic_channels[chan]; 1201 1.1 kiyohara } 1202 1.1 kiyohara 1203 1.1 kiyohara static int 1204 1.1 kiyohara cmalo_wep(struct malo_softc *sc) 1205 1.1 kiyohara { 1206 1.1 kiyohara struct ieee80211com *ic = &sc->sc_ic; 1207 1.1 kiyohara int i; 1208 1.1 kiyohara 1209 1.1 kiyohara for (i = 0; i < IEEE80211_WEP_NKID; i++) { 1210 1.1 kiyohara struct ieee80211_key *key = &ic->ic_crypto.cs_nw_keys[i]; 1211 1.1 kiyohara 1212 1.1 kiyohara if (!key->wk_keylen) 1213 1.1 kiyohara continue; 1214 1.1 kiyohara 1215 1.1 kiyohara DPRINTF(1, "%s: setting wep key for index %d\n", 1216 1.1 kiyohara device_xname(sc->sc_dev), i); 1217 1.1 kiyohara 1218 1.1 kiyohara cmalo_cmd_set_wep(sc, i, key); 1219 1.1 kiyohara } 1220 1.1 kiyohara 1221 1.1 kiyohara return 0; 1222 1.1 kiyohara } 1223 1.1 kiyohara 1224 1.1 kiyohara static int 1225 1.1 kiyohara cmalo_rate2bitmap(int rate) 1226 1.1 kiyohara { 1227 1.1 kiyohara switch (rate) { 1228 1.1 kiyohara /* CCK rates */ 1229 1.1 kiyohara case 0: return MALO_RATE_BITMAP_DS1; 1230 1.1 kiyohara case 1: return MALO_RATE_BITMAP_DS2; 1231 1.1 kiyohara case 2: return MALO_RATE_BITMAP_DS5; 1232 1.1 kiyohara case 3: return MALO_RATE_BITMAP_DS11; 1233 1.1 kiyohara 1234 1.1 kiyohara /* OFDM rates */ 1235 1.1 kiyohara case 4: return MALO_RATE_BITMAP_OFDM6; 1236 1.1 kiyohara case 5: return MALO_RATE_BITMAP_OFDM9; 1237 1.1 kiyohara case 6: return MALO_RATE_BITMAP_OFDM12; 1238 1.1 kiyohara case 7: return MALO_RATE_BITMAP_OFDM18; 1239 1.1 kiyohara case 8: return MALO_RATE_BITMAP_OFDM24; 1240 1.1 kiyohara case 9: return MALO_RATE_BITMAP_OFDM36; 1241 1.1 kiyohara case 10: return MALO_RATE_BITMAP_OFDM48; 1242 1.1 kiyohara case 11: return MALO_RATE_BITMAP_OFDM54; 1243 1.1 kiyohara 1244 1.1 kiyohara /* unknown rate: should not happen */ 1245 1.1 kiyohara default: return 0; 1246 1.1 kiyohara } 1247 1.1 kiyohara } 1248 1.1 kiyohara 1249 1.1 kiyohara static void 1250 1.1 kiyohara cmalo_hexdump(void *buf, int len) 1251 1.1 kiyohara { 1252 1.1 kiyohara #ifdef CMALO_DEBUG 1253 1.1 kiyohara int i; 1254 1.1 kiyohara 1255 1.1 kiyohara if (cmalo_d >= 2) { 1256 1.1 kiyohara for (i = 0; i < len; i++) { 1257 1.1 kiyohara if (i % 16 == 0) 1258 1.1 kiyohara printf("%s%5i:", i ? "\n" : "", i); 1259 1.1 kiyohara if (i % 4 == 0) 1260 1.1 kiyohara printf(" "); 1261 1.1 kiyohara printf("%02x", (int)*((u_char *)buf + i)); 1262 1.1 kiyohara } 1263 1.1 kiyohara printf("\n"); 1264 1.1 kiyohara } 1265 1.1 kiyohara #endif 1266 1.1 kiyohara } 1267 1.1 kiyohara 1268 1.1 kiyohara static int 1269 1.1 kiyohara cmalo_cmd_get_hwspec(struct malo_softc *sc) 1270 1.1 kiyohara { 1271 1.1 kiyohara struct malo_cmd_header *hdr; 1272 1.1 kiyohara struct malo_cmd_body_spec *body; 1273 1.1 kiyohara const uint16_t psize = sizeof(*hdr) + sizeof(*body); 1274 1.1 kiyohara 1275 1.1 kiyohara hdr = (struct malo_cmd_header *)sc->sc_cmd; 1276 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_HWSPEC); 1277 1.1 kiyohara hdr->size = htole16(sizeof(*body)); 1278 1.1 kiyohara hdr->seqnum = htole16(1); 1279 1.1 kiyohara hdr->result = 0; 1280 1.1 kiyohara 1281 1.1 kiyohara body = (struct malo_cmd_body_spec *)(hdr + 1); 1282 1.1 kiyohara memset(body, 0, sizeof(*body)); 1283 1.1 kiyohara /* set all bits for MAC address, otherwise we won't get one back */ 1284 1.1 kiyohara memset(body->macaddr, 0xff, ETHER_ADDR_LEN); 1285 1.1 kiyohara 1286 1.1 kiyohara /* process command request */ 1287 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 0) != 0) 1288 1.1 kiyohara return EIO; 1289 1.1 kiyohara 1290 1.28 andvar /* process command response */ 1291 1.1 kiyohara cmalo_cmd_response(sc); 1292 1.1 kiyohara 1293 1.1 kiyohara return 0; 1294 1.1 kiyohara } 1295 1.1 kiyohara 1296 1.1 kiyohara static int 1297 1.1 kiyohara cmalo_cmd_rsp_hwspec(struct malo_softc *sc) 1298 1.1 kiyohara { 1299 1.1 kiyohara struct ieee80211com *ic = &sc->sc_ic; 1300 1.1 kiyohara struct malo_cmd_header *hdr = (struct malo_cmd_header *)sc->sc_cmd; 1301 1.1 kiyohara struct malo_cmd_body_spec *body; 1302 1.1 kiyohara 1303 1.1 kiyohara body = (struct malo_cmd_body_spec *)(hdr + 1); 1304 1.1 kiyohara 1305 1.1 kiyohara /* get our MAC address */ 1306 1.22 bad memcpy(ic->ic_myaddr, body->macaddr, ETHER_ADDR_LEN); 1307 1.1 kiyohara 1308 1.1 kiyohara return 0; 1309 1.1 kiyohara } 1310 1.1 kiyohara 1311 1.1 kiyohara static int 1312 1.1 kiyohara cmalo_cmd_set_reset(struct malo_softc *sc) 1313 1.1 kiyohara { 1314 1.1 kiyohara struct malo_cmd_header *hdr = (struct malo_cmd_header *)sc->sc_cmd; 1315 1.1 kiyohara const uint16_t psize = sizeof(*hdr); 1316 1.1 kiyohara 1317 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_RESET); 1318 1.1 kiyohara hdr->size = 0; 1319 1.1 kiyohara hdr->seqnum = htole16(1); 1320 1.1 kiyohara hdr->result = 0; 1321 1.1 kiyohara 1322 1.1 kiyohara /* process command request */ 1323 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 1) != 0) 1324 1.1 kiyohara return EIO; 1325 1.1 kiyohara 1326 1.1 kiyohara /* give the device some time to finish the reset */ 1327 1.1 kiyohara delay(100); 1328 1.1 kiyohara 1329 1.1 kiyohara return 0; 1330 1.1 kiyohara } 1331 1.1 kiyohara 1332 1.1 kiyohara static int 1333 1.1 kiyohara cmalo_cmd_set_scan(struct malo_softc *sc) 1334 1.1 kiyohara { 1335 1.1 kiyohara struct ieee80211com *ic = &sc->sc_ic; 1336 1.1 kiyohara struct malo_cmd_header *hdr; 1337 1.1 kiyohara struct malo_cmd_body_scan *body; 1338 1.1 kiyohara struct malo_cmd_tlv_ssid *body_ssid; 1339 1.1 kiyohara struct malo_cmd_tlv_chanlist *body_chanlist; 1340 1.1 kiyohara struct malo_cmd_tlv_rates *body_rates; 1341 1.1 kiyohara uint16_t psize; 1342 1.1 kiyohara int i; 1343 1.1 kiyohara 1344 1.1 kiyohara psize = sizeof(*hdr) + sizeof(*body) + 1345 1.1 kiyohara sizeof(*body_ssid) + sizeof(*body_chanlist) + sizeof(*body_rates); 1346 1.1 kiyohara 1347 1.1 kiyohara hdr = (struct malo_cmd_header *)sc->sc_cmd; 1348 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_SCAN); 1349 1.1 kiyohara hdr->seqnum = htole16(1); 1350 1.1 kiyohara hdr->result = 0; 1351 1.1 kiyohara 1352 1.1 kiyohara body = (struct malo_cmd_body_scan *)(hdr + 1); 1353 1.1 kiyohara body->bsstype = 0x03; /* any BSS */ 1354 1.1 kiyohara memset(body->bssid, 0xff, ETHER_ADDR_LEN); 1355 1.1 kiyohara 1356 1.1 kiyohara body_ssid = (struct malo_cmd_tlv_ssid *)(body + 1); 1357 1.1 kiyohara body_ssid->type = htole16(MALO_TLV_TYPE_SSID); 1358 1.1 kiyohara body_ssid->size = htole16(0); 1359 1.1 kiyohara 1360 1.1 kiyohara body_chanlist = (struct malo_cmd_tlv_chanlist *)(body_ssid + 1); 1361 1.1 kiyohara body_chanlist->type = htole16(MALO_TLV_TYPE_CHANLIST); 1362 1.1 kiyohara body_chanlist->size = htole16(sizeof(body_chanlist->data)); 1363 1.1 kiyohara for (i = 0; i < CHANNELS; i++) { 1364 1.1 kiyohara body_chanlist->data[i].radiotype = 0x00; 1365 1.1 kiyohara body_chanlist->data[i].channumber = (i + 1); 1366 1.1 kiyohara body_chanlist->data[i].scantype = 0x00; /* active */ 1367 1.1 kiyohara body_chanlist->data[i].minscantime = htole16(0); 1368 1.1 kiyohara body_chanlist->data[i].maxscantime = htole16(100); 1369 1.1 kiyohara } 1370 1.1 kiyohara 1371 1.1 kiyohara body_rates = (struct malo_cmd_tlv_rates *)(body_chanlist + 1); 1372 1.1 kiyohara body_rates->type = htole16(MALO_TLV_TYPE_RATES); 1373 1.1 kiyohara body_rates->size = 1374 1.1 kiyohara htole16(ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates); 1375 1.1 kiyohara memcpy(body_rates->data, ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates, 1376 1.1 kiyohara ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates); 1377 1.1 kiyohara psize += le16toh(body_rates->size); 1378 1.1 kiyohara 1379 1.1 kiyohara memset((char *)(body_rates + 1) + le16toh(body_rates->size), 0, 1380 1.1 kiyohara sizeof(struct malo_cmd_tlv_numprobes)); 1381 1.1 kiyohara 1382 1.1 kiyohara hdr->size = htole16(psize - sizeof(*hdr)); 1383 1.1 kiyohara 1384 1.1 kiyohara /* process command request */ 1385 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 0) != 0) 1386 1.1 kiyohara return EIO; 1387 1.1 kiyohara 1388 1.28 andvar /* process command response */ 1389 1.1 kiyohara cmalo_cmd_response(sc); 1390 1.1 kiyohara 1391 1.1 kiyohara return 0; 1392 1.1 kiyohara } 1393 1.1 kiyohara 1394 1.1 kiyohara static int 1395 1.1 kiyohara cmalo_cmd_rsp_scan(struct malo_softc *sc) 1396 1.1 kiyohara { 1397 1.1 kiyohara struct malo_cmd_header *hdr = (struct malo_cmd_header *)sc->sc_cmd; 1398 1.1 kiyohara struct malo_cmd_body_rsp_scan *body; 1399 1.1 kiyohara struct malo_cmd_body_rsp_scan_set *set; 1400 1.1 kiyohara int i; 1401 1.1 kiyohara 1402 1.1 kiyohara memset(sc->sc_net, 0, sizeof(sc->sc_net)); 1403 1.1 kiyohara 1404 1.1 kiyohara body = (struct malo_cmd_body_rsp_scan *)(hdr + 1); 1405 1.1 kiyohara body->bufsize = le16toh(body->bufsize); 1406 1.1 kiyohara 1407 1.1 kiyohara DPRINTF(1, "bufsize=%d, APs=%d\n", body->bufsize, body->numofset); 1408 1.1 kiyohara sc->sc_net_num = body->numofset; 1409 1.1 kiyohara 1410 1.1 kiyohara set = (struct malo_cmd_body_rsp_scan_set *)(body + 1); 1411 1.1 kiyohara 1412 1.1 kiyohara /* cycle through found networks */ 1413 1.1 kiyohara for (i = 0; i < body->numofset; i++) { 1414 1.1 kiyohara set->size = le16toh(set->size); 1415 1.1 kiyohara set->beaconintvl = le16toh(set->beaconintvl); 1416 1.1 kiyohara set->capinfo = le16toh(set->capinfo); 1417 1.1 kiyohara 1418 1.1 kiyohara DPRINTF(1, "size=%d, bssid=%s, rssi=%d, beaconintvl=%d, " 1419 1.1 kiyohara "capinfo=0x%04x\n", 1420 1.1 kiyohara set->size, ether_sprintf(set->bssid), set->rssi, 1421 1.1 kiyohara set->beaconintvl, set->capinfo); 1422 1.1 kiyohara 1423 1.1 kiyohara /* save scan results */ 1424 1.1 kiyohara memcpy(sc->sc_net[i].bssid, set->bssid, sizeof(set->bssid)); 1425 1.1 kiyohara sc->sc_net[i].rssi = set->rssi; 1426 1.1 kiyohara memcpy(sc->sc_net[i].timestamp, set->timestamp, 1427 1.1 kiyohara sizeof(set->timestamp)); 1428 1.1 kiyohara sc->sc_net[i].beaconintvl = set->beaconintvl; 1429 1.1 kiyohara sc->sc_net[i].capinfo = set->capinfo; 1430 1.1 kiyohara 1431 1.1 kiyohara cmalo_parse_elements(sc, set->data, 1432 1.1 kiyohara set->size - (sizeof(*set) - sizeof(set->size)), i); 1433 1.1 kiyohara 1434 1.1 kiyohara set = (struct malo_cmd_body_rsp_scan_set *) 1435 1.1 kiyohara ((char *)set + sizeof(set->size) + set->size); 1436 1.1 kiyohara } 1437 1.1 kiyohara 1438 1.1 kiyohara return 0; 1439 1.1 kiyohara } 1440 1.1 kiyohara 1441 1.1 kiyohara static int 1442 1.1 kiyohara cmalo_parse_elements(struct malo_softc *sc, uint8_t *buf, int size, int pos) 1443 1.1 kiyohara { 1444 1.1 kiyohara uint8_t eid, len; 1445 1.1 kiyohara int i; 1446 1.1 kiyohara 1447 1.1 kiyohara DPRINTF(2, "element_size=%d, element_pos=%d\n", size, pos); 1448 1.1 kiyohara 1449 1.1 kiyohara for (i = 0; i < size; ) { 1450 1.1 kiyohara eid = *(uint8_t *)(buf + i); 1451 1.1 kiyohara i++; 1452 1.1 kiyohara len = *(uint8_t *)(buf + i); 1453 1.1 kiyohara i++; 1454 1.1 kiyohara DPRINTF(2, "eid=%d, len=%d, ", eid, len); 1455 1.1 kiyohara 1456 1.1 kiyohara switch (eid) { 1457 1.1 kiyohara case IEEE80211_ELEMID_SSID: 1458 1.1 kiyohara memcpy(sc->sc_net[pos].ssid, buf + i, len); 1459 1.1 kiyohara DPRINTF(2, "ssid=%s\n", sc->sc_net[pos].ssid); 1460 1.1 kiyohara break; 1461 1.1 kiyohara case IEEE80211_ELEMID_RATES: 1462 1.1 kiyohara memcpy(sc->sc_net[pos].rates, buf + i, len); 1463 1.1 kiyohara DPRINTF(2, "rates\n"); 1464 1.1 kiyohara break; 1465 1.1 kiyohara case IEEE80211_ELEMID_DSPARMS: 1466 1.1 kiyohara sc->sc_net[pos].channel = *(uint8_t *)(buf + i); 1467 1.1 kiyohara DPRINTF(2, "chnl=%d\n", sc->sc_net[pos].channel); 1468 1.1 kiyohara break; 1469 1.1 kiyohara default: 1470 1.1 kiyohara DPRINTF(2, "unknown\n"); 1471 1.1 kiyohara break; 1472 1.1 kiyohara } 1473 1.1 kiyohara 1474 1.1 kiyohara i += len; 1475 1.1 kiyohara } 1476 1.1 kiyohara 1477 1.1 kiyohara return 0; 1478 1.1 kiyohara } 1479 1.1 kiyohara 1480 1.1 kiyohara static int 1481 1.1 kiyohara cmalo_cmd_set_auth(struct malo_softc *sc) 1482 1.1 kiyohara { 1483 1.1 kiyohara struct malo_cmd_header *hdr; 1484 1.1 kiyohara struct malo_cmd_body_auth *body; 1485 1.1 kiyohara const uint16_t psize = sizeof(*hdr) + sizeof(*body); 1486 1.1 kiyohara 1487 1.1 kiyohara hdr = (struct malo_cmd_header *)sc->sc_cmd; 1488 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_AUTH); 1489 1.1 kiyohara hdr->size = htole16(sizeof(*body)); 1490 1.1 kiyohara hdr->seqnum = htole16(1); 1491 1.1 kiyohara hdr->result = 0; 1492 1.1 kiyohara 1493 1.1 kiyohara body = (struct malo_cmd_body_auth *)(hdr + 1); 1494 1.1 kiyohara memcpy(body->peermac, sc->sc_net[sc->sc_net_cur].bssid, ETHER_ADDR_LEN); 1495 1.1 kiyohara body->authtype = 0; 1496 1.1 kiyohara 1497 1.1 kiyohara /* process command request */ 1498 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 0) != 0) 1499 1.1 kiyohara return EIO; 1500 1.1 kiyohara 1501 1.28 andvar /* process command response */ 1502 1.1 kiyohara cmalo_cmd_response(sc); 1503 1.1 kiyohara 1504 1.1 kiyohara return 0; 1505 1.1 kiyohara } 1506 1.1 kiyohara 1507 1.1 kiyohara static int 1508 1.1 kiyohara cmalo_cmd_set_wep(struct malo_softc *sc, uint16_t index, 1509 1.1 kiyohara struct ieee80211_key *key) 1510 1.1 kiyohara { 1511 1.1 kiyohara struct malo_cmd_header *hdr; 1512 1.1 kiyohara struct malo_cmd_body_wep *body; 1513 1.1 kiyohara const uint16_t psize = sizeof(*hdr) + sizeof(*body); 1514 1.1 kiyohara 1515 1.1 kiyohara hdr = (struct malo_cmd_header *)sc->sc_cmd; 1516 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_WEP); 1517 1.1 kiyohara hdr->size = htole16(sizeof(*body)); 1518 1.1 kiyohara hdr->seqnum = htole16(1); 1519 1.1 kiyohara hdr->result = 0; 1520 1.1 kiyohara 1521 1.1 kiyohara body = (struct malo_cmd_body_wep *)(hdr + 1); 1522 1.1 kiyohara memset(body, 0, sizeof(*body)); 1523 1.1 kiyohara body->action = htole16(MALO_WEP_ACTION_TYPE_ADD); 1524 1.1 kiyohara body->key_index = htole16(index); 1525 1.1 kiyohara 1526 1.1 kiyohara if (body->key_index == 0) { 1527 1.1 kiyohara if (key->wk_keylen > 5) 1528 1.1 kiyohara body->key_type_1 = MALO_WEP_KEY_TYPE_104BIT; 1529 1.1 kiyohara else 1530 1.1 kiyohara body->key_type_1 = MALO_WEP_KEY_TYPE_40BIT; 1531 1.1 kiyohara memcpy(body->key_value_1, key->wk_key, key->wk_keylen); 1532 1.1 kiyohara } 1533 1.1 kiyohara if (body->key_index == 1) { 1534 1.1 kiyohara if (key->wk_keylen > 5) 1535 1.1 kiyohara body->key_type_2 = MALO_WEP_KEY_TYPE_104BIT; 1536 1.1 kiyohara else 1537 1.1 kiyohara body->key_type_2 = MALO_WEP_KEY_TYPE_40BIT; 1538 1.1 kiyohara memcpy(body->key_value_2, key->wk_key, key->wk_keylen); 1539 1.1 kiyohara } 1540 1.1 kiyohara if (body->key_index == 2) { 1541 1.1 kiyohara if (key->wk_keylen > 5) 1542 1.1 kiyohara body->key_type_3 = MALO_WEP_KEY_TYPE_104BIT; 1543 1.1 kiyohara else 1544 1.1 kiyohara body->key_type_3 = MALO_WEP_KEY_TYPE_40BIT; 1545 1.1 kiyohara memcpy(body->key_value_3, key->wk_key, key->wk_keylen); 1546 1.1 kiyohara } 1547 1.1 kiyohara if (body->key_index == 3) { 1548 1.1 kiyohara if (key->wk_keylen > 5) 1549 1.1 kiyohara body->key_type_4 = MALO_WEP_KEY_TYPE_104BIT; 1550 1.1 kiyohara else 1551 1.1 kiyohara body->key_type_4 = MALO_WEP_KEY_TYPE_40BIT; 1552 1.1 kiyohara memcpy(body->key_value_4, key->wk_key, key->wk_keylen); 1553 1.1 kiyohara } 1554 1.1 kiyohara 1555 1.1 kiyohara /* process command request */ 1556 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 0) != 0) 1557 1.1 kiyohara return EIO; 1558 1.1 kiyohara 1559 1.28 andvar /* process command response */ 1560 1.1 kiyohara cmalo_cmd_response(sc); 1561 1.1 kiyohara 1562 1.1 kiyohara return 0; 1563 1.1 kiyohara } 1564 1.1 kiyohara 1565 1.1 kiyohara static int 1566 1.1 kiyohara cmalo_cmd_set_snmp(struct malo_softc *sc, uint16_t oid) 1567 1.1 kiyohara { 1568 1.1 kiyohara struct malo_cmd_header *hdr; 1569 1.1 kiyohara struct malo_cmd_body_snmp *body; 1570 1.1 kiyohara const uint16_t psize = sizeof(*hdr) + sizeof(*body); 1571 1.1 kiyohara 1572 1.1 kiyohara hdr = (struct malo_cmd_header *)sc->sc_cmd; 1573 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_SNMP); 1574 1.1 kiyohara hdr->size = htole16(sizeof(*body)); 1575 1.1 kiyohara hdr->seqnum = htole16(1); 1576 1.1 kiyohara hdr->result = 0; 1577 1.1 kiyohara 1578 1.1 kiyohara body = (struct malo_cmd_body_snmp *)(hdr + 1); 1579 1.1 kiyohara memset(body, 0, sizeof(*body)); 1580 1.1 kiyohara body->action = htole16(1); 1581 1.1 kiyohara 1582 1.1 kiyohara switch (oid) { 1583 1.1 kiyohara case MALO_OID_RTSTRESH: 1584 1.1 kiyohara body->oid = htole16(MALO_OID_RTSTRESH); 1585 1.1 kiyohara body->size = htole16(2); 1586 1.1 kiyohara *(uint16_t *)body->data = htole16(2347); 1587 1.1 kiyohara break; 1588 1.1 kiyohara case MALO_OID_SHORTRETRY: 1589 1.1 kiyohara body->oid = htole16(MALO_OID_SHORTRETRY); 1590 1.1 kiyohara body->size = htole16(2); 1591 1.1 kiyohara *(uint16_t *)body->data = htole16(4); 1592 1.1 kiyohara break; 1593 1.1 kiyohara case MALO_OID_FRAGTRESH: 1594 1.1 kiyohara body->oid = htole16(MALO_OID_FRAGTRESH); 1595 1.1 kiyohara body->size = htole16(2); 1596 1.1 kiyohara *(uint16_t *)body->data = htole16(2346); 1597 1.1 kiyohara break; 1598 1.1 kiyohara case MALO_OID_80211D: 1599 1.1 kiyohara body->oid = htole16(MALO_OID_80211D); 1600 1.1 kiyohara body->size = htole16(2); 1601 1.1 kiyohara *(uint16_t *)body->data = htole16(1); 1602 1.1 kiyohara break; 1603 1.1 kiyohara default: 1604 1.1 kiyohara break; 1605 1.1 kiyohara } 1606 1.1 kiyohara 1607 1.1 kiyohara /* process command request */ 1608 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 0) != 0) 1609 1.1 kiyohara return EIO; 1610 1.1 kiyohara 1611 1.28 andvar /* process command response */ 1612 1.1 kiyohara cmalo_cmd_response(sc); 1613 1.1 kiyohara 1614 1.1 kiyohara return 0; 1615 1.1 kiyohara } 1616 1.1 kiyohara 1617 1.1 kiyohara static int 1618 1.1 kiyohara cmalo_cmd_set_radio(struct malo_softc *sc, uint16_t control) 1619 1.1 kiyohara { 1620 1.1 kiyohara struct malo_cmd_header *hdr; 1621 1.1 kiyohara struct malo_cmd_body_radio *body; 1622 1.1 kiyohara const uint16_t psize = sizeof(*hdr) + sizeof(*body); 1623 1.1 kiyohara 1624 1.1 kiyohara hdr = (struct malo_cmd_header *)sc->sc_cmd; 1625 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_RADIO); 1626 1.1 kiyohara hdr->size = htole16(sizeof(*body)); 1627 1.1 kiyohara hdr->seqnum = htole16(1); 1628 1.1 kiyohara hdr->result = 0; 1629 1.1 kiyohara 1630 1.1 kiyohara body = (struct malo_cmd_body_radio *)(hdr + 1); 1631 1.1 kiyohara body->action = htole16(1); 1632 1.1 kiyohara if (control) 1633 1.1 kiyohara body->control = 1634 1.1 kiyohara htole16(MALO_CMD_RADIO_ON | MALO_CMD_RADIO_AUTO_P); 1635 1.1 kiyohara else 1636 1.1 kiyohara body->control = 0; 1637 1.1 kiyohara 1638 1.1 kiyohara /* process command request */ 1639 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 0) != 0) 1640 1.1 kiyohara return EIO; 1641 1.1 kiyohara 1642 1.28 andvar /* process command response */ 1643 1.1 kiyohara cmalo_cmd_response(sc); 1644 1.1 kiyohara 1645 1.1 kiyohara return 0; 1646 1.1 kiyohara } 1647 1.1 kiyohara 1648 1.1 kiyohara static int 1649 1.1 kiyohara cmalo_cmd_set_channel(struct malo_softc *sc, uint16_t channel) 1650 1.1 kiyohara { 1651 1.1 kiyohara struct malo_cmd_header *hdr; 1652 1.1 kiyohara struct malo_cmd_body_channel *body; 1653 1.1 kiyohara const uint16_t psize = sizeof(*hdr) + sizeof(*body); 1654 1.1 kiyohara 1655 1.1 kiyohara hdr = (struct malo_cmd_header *)sc->sc_cmd; 1656 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_CHANNEL); 1657 1.1 kiyohara hdr->size = htole16(sizeof(*body)); 1658 1.1 kiyohara hdr->seqnum = htole16(1); 1659 1.1 kiyohara hdr->result = 0; 1660 1.1 kiyohara 1661 1.1 kiyohara body = (struct malo_cmd_body_channel *)(hdr + 1); 1662 1.1 kiyohara memset(body, 0, sizeof(*body)); 1663 1.1 kiyohara body->action = htole16(1); 1664 1.1 kiyohara body->channel = htole16(channel); 1665 1.1 kiyohara 1666 1.1 kiyohara /* process command request */ 1667 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 0) != 0) 1668 1.1 kiyohara return EIO; 1669 1.1 kiyohara 1670 1.28 andvar /* process command response */ 1671 1.1 kiyohara cmalo_cmd_response(sc); 1672 1.1 kiyohara 1673 1.1 kiyohara return 0; 1674 1.1 kiyohara } 1675 1.1 kiyohara 1676 1.1 kiyohara 1677 1.1 kiyohara static int 1678 1.1 kiyohara cmalo_cmd_set_txpower(struct malo_softc *sc, int16_t txpower) 1679 1.1 kiyohara { 1680 1.1 kiyohara struct malo_cmd_header *hdr; 1681 1.1 kiyohara struct malo_cmd_body_txpower *body; 1682 1.1 kiyohara const uint16_t psize = sizeof(*hdr) + sizeof(*body); 1683 1.1 kiyohara 1684 1.1 kiyohara hdr = (struct malo_cmd_header *)sc->sc_cmd; 1685 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_TXPOWER); 1686 1.1 kiyohara hdr->size = htole16(sizeof(*body)); 1687 1.1 kiyohara hdr->seqnum = htole16(1); 1688 1.1 kiyohara hdr->result = 0; 1689 1.1 kiyohara 1690 1.1 kiyohara body = (struct malo_cmd_body_txpower *)(hdr + 1); 1691 1.1 kiyohara body->action = htole16(1); 1692 1.1 kiyohara body->txpower = htole16(txpower); 1693 1.1 kiyohara 1694 1.1 kiyohara /* process command request */ 1695 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 0) != 0) 1696 1.1 kiyohara return EIO; 1697 1.1 kiyohara 1698 1.28 andvar /* process command response */ 1699 1.1 kiyohara cmalo_cmd_response(sc); 1700 1.1 kiyohara 1701 1.1 kiyohara return 0; 1702 1.1 kiyohara } 1703 1.1 kiyohara 1704 1.1 kiyohara static int 1705 1.1 kiyohara cmalo_cmd_set_antenna(struct malo_softc *sc, uint16_t action) 1706 1.1 kiyohara { 1707 1.1 kiyohara struct malo_cmd_header *hdr; 1708 1.1 kiyohara struct malo_cmd_body_antenna *body; 1709 1.1 kiyohara const uint16_t psize = sizeof(*hdr) + sizeof(*body); 1710 1.1 kiyohara 1711 1.1 kiyohara hdr = (struct malo_cmd_header *)sc->sc_cmd; 1712 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_ANTENNA); 1713 1.1 kiyohara hdr->size = htole16(sizeof(*body)); 1714 1.1 kiyohara hdr->seqnum = htole16(1); 1715 1.1 kiyohara hdr->result = 0; 1716 1.1 kiyohara 1717 1.1 kiyohara body = (struct malo_cmd_body_antenna *)(hdr + 1); 1718 1.1 kiyohara /* 1 = set RX, 2 = set TX */ 1719 1.1 kiyohara body->action = htole16(action); 1720 1.1 kiyohara 1721 1.1 kiyohara switch (action) { 1722 1.1 kiyohara case 1: 1723 1.1 kiyohara /* set RX antenna */ 1724 1.1 kiyohara body->antenna_mode = htole16(0xffff); 1725 1.1 kiyohara break; 1726 1.1 kiyohara 1727 1.1 kiyohara case 2: 1728 1.1 kiyohara /* set TX antenna */ 1729 1.1 kiyohara body->antenna_mode = htole16(2); 1730 1.1 kiyohara break; 1731 1.1 kiyohara 1732 1.1 kiyohara default: 1733 1.1 kiyohara body->antenna_mode = 0; 1734 1.1 kiyohara break; 1735 1.1 kiyohara } 1736 1.1 kiyohara 1737 1.1 kiyohara /* process command request */ 1738 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 0) != 0) 1739 1.1 kiyohara return EIO; 1740 1.1 kiyohara 1741 1.28 andvar /* process command response */ 1742 1.1 kiyohara cmalo_cmd_response(sc); 1743 1.1 kiyohara 1744 1.1 kiyohara return 0; 1745 1.1 kiyohara } 1746 1.1 kiyohara 1747 1.1 kiyohara static int 1748 1.1 kiyohara cmalo_cmd_set_macctrl(struct malo_softc *sc) 1749 1.1 kiyohara { 1750 1.1 kiyohara struct ieee80211com *ic = &sc->sc_ic; 1751 1.1 kiyohara struct malo_cmd_header *hdr; 1752 1.1 kiyohara struct malo_cmd_body_macctrl *body; 1753 1.1 kiyohara uint16_t psize; 1754 1.1 kiyohara 1755 1.1 kiyohara psize = sizeof(*hdr) + sizeof(*body); 1756 1.1 kiyohara 1757 1.1 kiyohara hdr = (struct malo_cmd_header *)sc->sc_cmd; 1758 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_MACCTRL); 1759 1.1 kiyohara hdr->size = htole16(sizeof(*body)); 1760 1.1 kiyohara hdr->seqnum = htole16(1); 1761 1.1 kiyohara hdr->result = 0; 1762 1.1 kiyohara 1763 1.1 kiyohara body = (struct malo_cmd_body_macctrl *)(hdr + 1); 1764 1.1 kiyohara memset(body, 0, sizeof(*body)); 1765 1.1 kiyohara body->action = htole16(MALO_CMD_MACCTRL_RX_ON | MALO_CMD_MACCTRL_TX_ON); 1766 1.1 kiyohara if (ic->ic_opmode == IEEE80211_M_MONITOR) 1767 1.1 kiyohara body->action |= htole16(MALO_CMD_MACCTRL_PROMISC_ON); 1768 1.1 kiyohara 1769 1.1 kiyohara /* process command request */ 1770 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 0) != 0) 1771 1.1 kiyohara return EIO; 1772 1.1 kiyohara 1773 1.28 andvar /* process command response */ 1774 1.1 kiyohara cmalo_cmd_response(sc); 1775 1.1 kiyohara 1776 1.1 kiyohara return 0; 1777 1.1 kiyohara } 1778 1.1 kiyohara 1779 1.1 kiyohara static int 1780 1.1 kiyohara cmalo_cmd_set_macaddr(struct malo_softc *sc, uint8_t *macaddr) 1781 1.1 kiyohara { 1782 1.1 kiyohara struct malo_cmd_header *hdr; 1783 1.1 kiyohara struct malo_cmd_body_macaddr *body; 1784 1.1 kiyohara const uint16_t psize = sizeof(*hdr) + sizeof(*body); 1785 1.1 kiyohara 1786 1.1 kiyohara hdr = (struct malo_cmd_header *)sc->sc_cmd; 1787 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_MACADDR); 1788 1.1 kiyohara hdr->size = htole16(sizeof(*body)); 1789 1.1 kiyohara hdr->seqnum = htole16(1); 1790 1.1 kiyohara hdr->result = 0; 1791 1.1 kiyohara 1792 1.1 kiyohara body = (struct malo_cmd_body_macaddr *)(hdr + 1); 1793 1.1 kiyohara body->action = htole16(1); 1794 1.1 kiyohara memcpy(body->macaddr, macaddr, ETHER_ADDR_LEN); 1795 1.1 kiyohara 1796 1.1 kiyohara /* process command request */ 1797 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 0) != 0) 1798 1.1 kiyohara return EIO; 1799 1.1 kiyohara 1800 1.28 andvar /* process command response */ 1801 1.1 kiyohara cmalo_cmd_response(sc); 1802 1.1 kiyohara 1803 1.1 kiyohara return 0; 1804 1.1 kiyohara } 1805 1.1 kiyohara 1806 1.1 kiyohara static int 1807 1.1 kiyohara cmalo_cmd_set_assoc(struct malo_softc *sc) 1808 1.1 kiyohara { 1809 1.1 kiyohara struct malo_cmd_header *hdr; 1810 1.1 kiyohara struct malo_cmd_body_assoc *body; 1811 1.1 kiyohara struct malo_cmd_tlv_ssid *body_ssid; 1812 1.1 kiyohara struct malo_cmd_tlv_phy *body_phy; 1813 1.1 kiyohara struct malo_cmd_tlv_cf *body_cf; 1814 1.1 kiyohara struct malo_cmd_tlv_rates *body_rates; 1815 1.1 kiyohara struct malo_cmd_tlv_passeid *body_passeid; 1816 1.1 kiyohara uint16_t psize; 1817 1.1 kiyohara 1818 1.1 kiyohara psize = sizeof(*hdr) + sizeof(*body) + sizeof(*body_ssid) + 1819 1.1 kiyohara sizeof(body_phy) + sizeof(*body_cf) + sizeof(*body_rates); 1820 1.1 kiyohara 1821 1.1 kiyohara hdr = (struct malo_cmd_header *)sc->sc_cmd; 1822 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_ASSOC); 1823 1.1 kiyohara hdr->seqnum = htole16(1); 1824 1.1 kiyohara hdr->result = 0; 1825 1.1 kiyohara 1826 1.1 kiyohara body = (struct malo_cmd_body_assoc *)(hdr + 1); 1827 1.2 joerg memset(body, 0, sizeof(*body)); 1828 1.1 kiyohara memcpy(body->peermac, sc->sc_net[sc->sc_net_cur].bssid, ETHER_ADDR_LEN); 1829 1.1 kiyohara body->capinfo = htole16(sc->sc_net[sc->sc_net_cur].capinfo); 1830 1.1 kiyohara body->listenintrv = htole16(10); 1831 1.1 kiyohara 1832 1.1 kiyohara body_ssid = (struct malo_cmd_tlv_ssid *)(body + 1); 1833 1.1 kiyohara body_ssid->type = htole16(MALO_TLV_TYPE_SSID); 1834 1.1 kiyohara body_ssid->size = htole16(strlen(sc->sc_net[sc->sc_net_cur].ssid)); 1835 1.1 kiyohara memcpy(body_ssid->data, sc->sc_net[sc->sc_net_cur].ssid, 1836 1.1 kiyohara le16toh(body_ssid->size)); 1837 1.1 kiyohara psize += le16toh(body_ssid->size); 1838 1.1 kiyohara 1839 1.1 kiyohara body_phy = (struct malo_cmd_tlv_phy *) 1840 1.1 kiyohara ((char *)(body_ssid + 1) + le16toh(body_ssid->size)); 1841 1.1 kiyohara body_phy->type = htole16(MALO_TLV_TYPE_PHY); 1842 1.1 kiyohara body_phy->size = htole16(1); 1843 1.1 kiyohara body_phy->data[0] = sc->sc_net[sc->sc_net_cur].channel; 1844 1.1 kiyohara psize += le16toh(body_phy->size); 1845 1.1 kiyohara 1846 1.1 kiyohara body_cf = (struct malo_cmd_tlv_cf *) 1847 1.1 kiyohara ((char *)(body_phy + 1) + le16toh(body_phy->size)); 1848 1.1 kiyohara body_cf->type = htole16(MALO_TLV_TYPE_CF); 1849 1.1 kiyohara body_cf->size = htole16(0); 1850 1.1 kiyohara 1851 1.1 kiyohara body_rates = (struct malo_cmd_tlv_rates *)(body_cf + 1); 1852 1.1 kiyohara body_rates->type = htole16(MALO_TLV_TYPE_RATES); 1853 1.1 kiyohara body_rates->size = htole16(strlen(sc->sc_net[sc->sc_net_cur].rates)); 1854 1.1 kiyohara memcpy(body_rates->data, sc->sc_net[sc->sc_net_cur].rates, 1855 1.1 kiyohara le16toh(body_rates->size)); 1856 1.1 kiyohara psize += le16toh(body_rates->size); 1857 1.1 kiyohara 1858 1.1 kiyohara /* hack to correct FW's wrong generated rates-element-id */ 1859 1.1 kiyohara body_passeid = (struct malo_cmd_tlv_passeid *) 1860 1.1 kiyohara ((char *)(body_rates + 1) + le16toh(body_rates->size)); 1861 1.1 kiyohara body_passeid->type = htole16(MALO_TLV_TYPE_PASSEID); 1862 1.1 kiyohara body_passeid->size = body_rates->size; 1863 1.1 kiyohara memcpy(body_passeid->data, body_rates->data, le16toh(body_rates->size)); 1864 1.1 kiyohara psize += le16toh(body_passeid->size); 1865 1.1 kiyohara 1866 1.1 kiyohara hdr->size = htole16(psize - sizeof(*hdr)); 1867 1.1 kiyohara 1868 1.1 kiyohara /* process command request */ 1869 1.1 kiyohara if (!sc->sc_cmd_ctxsave) { 1870 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 1) != 0) 1871 1.1 kiyohara return EIO; 1872 1.1 kiyohara return 0; 1873 1.1 kiyohara } 1874 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 0) != 0) 1875 1.1 kiyohara return EIO; 1876 1.1 kiyohara 1877 1.28 andvar /* process command response */ 1878 1.1 kiyohara cmalo_cmd_response(sc); 1879 1.1 kiyohara 1880 1.1 kiyohara return 0; 1881 1.1 kiyohara } 1882 1.1 kiyohara 1883 1.1 kiyohara static int 1884 1.1 kiyohara cmalo_cmd_rsp_assoc(struct malo_softc *sc) 1885 1.1 kiyohara { 1886 1.1 kiyohara struct malo_cmd_header *hdr = (struct malo_cmd_header *)sc->sc_cmd; 1887 1.1 kiyohara struct malo_cmd_body_rsp_assoc *body; 1888 1.1 kiyohara 1889 1.1 kiyohara body = (struct malo_cmd_body_rsp_assoc *)(hdr + 1); 1890 1.1 kiyohara 1891 1.1 kiyohara if (body->status) { 1892 1.1 kiyohara DPRINTF(1, "%s: association failed (status %d)\n", 1893 1.1 kiyohara device_xname(sc->sc_dev), body->status); 1894 1.1 kiyohara sc->sc_flags |= MALO_ASSOC_FAILED; 1895 1.6 pgoyette } else 1896 1.1 kiyohara DPRINTF(1, "%s: association successful\n", 1897 1.1 kiyohara device_xname(sc->sc_dev)); 1898 1.1 kiyohara 1899 1.1 kiyohara return 0; 1900 1.1 kiyohara } 1901 1.1 kiyohara 1902 1.1 kiyohara static int 1903 1.1 kiyohara cmalo_cmd_set_rate(struct malo_softc *sc, int rate) 1904 1.1 kiyohara { 1905 1.1 kiyohara struct malo_cmd_header *hdr; 1906 1.1 kiyohara struct malo_cmd_body_rate *body; 1907 1.1 kiyohara const uint16_t psize = sizeof(*hdr) + sizeof(*body); 1908 1.1 kiyohara 1909 1.1 kiyohara hdr = (struct malo_cmd_header *)sc->sc_cmd; 1910 1.1 kiyohara hdr->cmd = htole16(MALO_CMD_RATE); 1911 1.1 kiyohara hdr->size = htole16(sizeof(*body)); 1912 1.1 kiyohara hdr->seqnum = htole16(1); 1913 1.1 kiyohara hdr->result = 0; 1914 1.1 kiyohara 1915 1.1 kiyohara body = (struct malo_cmd_body_rate *)(hdr + 1); 1916 1.1 kiyohara body->action = htole16(1); 1917 1.1 kiyohara if (rate == IEEE80211_FIXED_RATE_NONE) { 1918 1.1 kiyohara body->hwauto = htole16(1); 1919 1.1 kiyohara body->ratebitmap = htole16(MALO_RATE_BITMAP_AUTO); 1920 1.1 kiyohara } else { 1921 1.1 kiyohara body->hwauto = 0; 1922 1.1 kiyohara body->ratebitmap = htole16(cmalo_rate2bitmap(rate)); 1923 1.1 kiyohara } 1924 1.1 kiyohara 1925 1.1 kiyohara /* process command request */ 1926 1.1 kiyohara if (cmalo_cmd_request(sc, psize, 0) != 0) 1927 1.1 kiyohara return EIO; 1928 1.1 kiyohara 1929 1.28 andvar /* process command response */ 1930 1.1 kiyohara cmalo_cmd_response(sc); 1931 1.1 kiyohara 1932 1.1 kiyohara return 0; 1933 1.1 kiyohara } 1934 1.1 kiyohara 1935 1.1 kiyohara static int 1936 1.1 kiyohara cmalo_cmd_request(struct malo_softc *sc, uint16_t psize, int no_response) 1937 1.1 kiyohara { 1938 1.1 kiyohara uint8_t *cmd; 1939 1.1 kiyohara 1940 1.1 kiyohara mutex_enter(&sc->sc_mtx); 1941 1.1 kiyohara 1942 1.1 kiyohara cmalo_hexdump(sc->sc_cmd, psize); 1943 1.1 kiyohara 1944 1.1 kiyohara /* send command request */ 1945 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_CMD_WRITE_LEN, psize); 1946 1.1 kiyohara MALO_WRITE_MULTI_2(sc, MALO_REG_CMD_WRITE, 1947 1.1 kiyohara (uint16_t *)sc->sc_cmd, psize / sizeof(uint16_t)); 1948 1.1 kiyohara if (psize & 0x0001) { 1949 1.1 kiyohara cmd = sc->sc_cmd; 1950 1.1 kiyohara MALO_WRITE_1(sc, MALO_REG_CMD_WRITE, cmd[psize - 1]); 1951 1.1 kiyohara } 1952 1.1 kiyohara MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_CMD_DL_OVER); 1953 1.1 kiyohara MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE, MALO_VAL_CMD_DL_OVER); 1954 1.1 kiyohara 1955 1.1 kiyohara if (no_response) { 1956 1.1 kiyohara mutex_exit(&sc->sc_mtx); 1957 1.1 kiyohara 1958 1.1 kiyohara /* we don't expect a response */ 1959 1.1 kiyohara return 0; 1960 1.1 kiyohara } 1961 1.1 kiyohara 1962 1.1 kiyohara /* wait for the command response */ 1963 1.1 kiyohara if (cv_timedwait_sig(&sc->sc_cv, &sc->sc_mtx, 500) == EWOULDBLOCK) { 1964 1.1 kiyohara mutex_exit(&sc->sc_mtx); 1965 1.1 kiyohara aprint_error_dev(sc->sc_dev, 1966 1.1 kiyohara "timeout while waiting for cmd response\n"); 1967 1.1 kiyohara return EIO; 1968 1.1 kiyohara } 1969 1.1 kiyohara mutex_exit(&sc->sc_mtx); 1970 1.1 kiyohara 1971 1.1 kiyohara return 0; 1972 1.1 kiyohara } 1973 1.1 kiyohara 1974 1.1 kiyohara static int 1975 1.1 kiyohara cmalo_cmd_response(struct malo_softc *sc) 1976 1.1 kiyohara { 1977 1.1 kiyohara struct malo_cmd_header *hdr = (struct malo_cmd_header *)sc->sc_cmd; 1978 1.1 kiyohara uint16_t psize; 1979 1.1 kiyohara int s; 1980 1.1 kiyohara 1981 1.1 kiyohara s = splnet(); 1982 1.1 kiyohara 1983 1.1 kiyohara #ifdef CMALO_DEBUG 1984 1.1 kiyohara memset(sc->sc_cmd, 0, MALO_CMD_BUFFER_SIZE); 1985 1.1 kiyohara #endif 1986 1.1 kiyohara 1987 1.1 kiyohara /* read the whole command response */ 1988 1.1 kiyohara psize = MALO_READ_2(sc, MALO_REG_CMD_READ_LEN); 1989 1.1 kiyohara if (psize > MALO_CMD_BUFFER_SIZE) { 1990 1.1 kiyohara aprint_error_dev(sc->sc_dev, 1991 1.1 kiyohara "command response too large: %dbyte\n", psize); 1992 1.14 maxv splx(s); 1993 1.1 kiyohara return EIO; 1994 1.1 kiyohara } 1995 1.1 kiyohara 1996 1.1 kiyohara MALO_READ_MULTI_2(sc, MALO_REG_CMD_READ, 1997 1.1 kiyohara (uint16_t *)sc->sc_cmd, psize / sizeof(uint16_t)); 1998 1.1 kiyohara if (psize & 0x0001) 1999 1.1 kiyohara sc->sc_cmd[psize - 1] = MALO_READ_1(sc, MALO_REG_CMD_READ); 2000 1.1 kiyohara 2001 1.1 kiyohara cmalo_hexdump(sc->sc_cmd, psize); 2002 1.1 kiyohara 2003 1.1 kiyohara /* 2004 1.27 msaitoh * We convert the header values into the machines correct endianness, 2005 1.1 kiyohara * so we don't have to le16toh() all over the code. The body is 2006 1.1 kiyohara * kept in the cards order, little endian. We need to take care 2007 1.27 msaitoh * about the body endianness in the corresponding response routines. 2008 1.1 kiyohara */ 2009 1.1 kiyohara hdr->cmd = le16toh(hdr->cmd); 2010 1.1 kiyohara hdr->size = le16toh(hdr->size); 2011 1.1 kiyohara hdr->seqnum = le16toh(hdr->seqnum); 2012 1.1 kiyohara hdr->result = le16toh(hdr->result); 2013 1.1 kiyohara 2014 1.1 kiyohara /* check for a valid command response */ 2015 1.1 kiyohara if (!(hdr->cmd & MALO_CMD_RESP)) { 2016 1.1 kiyohara aprint_error_dev(sc->sc_dev, 2017 1.1 kiyohara "got invalid command response (0x%04x)\n", hdr->cmd); 2018 1.1 kiyohara splx(s); 2019 1.1 kiyohara return EIO; 2020 1.1 kiyohara } 2021 1.1 kiyohara hdr->cmd &= ~MALO_CMD_RESP; 2022 1.1 kiyohara 2023 1.1 kiyohara /* association cmd response is special */ 2024 1.1 kiyohara if (hdr->cmd == 0x0012) 2025 1.1 kiyohara hdr->cmd = MALO_CMD_ASSOC; 2026 1.1 kiyohara 2027 1.1 kiyohara /* to which command does the response belong */ 2028 1.1 kiyohara switch (hdr->cmd) { 2029 1.1 kiyohara case MALO_CMD_HWSPEC: 2030 1.1 kiyohara DPRINTF(1, "%s: got hwspec cmd response\n", 2031 1.1 kiyohara device_xname(sc->sc_dev)); 2032 1.1 kiyohara cmalo_cmd_rsp_hwspec(sc); 2033 1.1 kiyohara break; 2034 1.1 kiyohara case MALO_CMD_RESET: 2035 1.1 kiyohara /* reset will not send back a response */ 2036 1.1 kiyohara break; 2037 1.1 kiyohara case MALO_CMD_SCAN: 2038 1.1 kiyohara DPRINTF(1, "%s: got scan cmd response\n", 2039 1.1 kiyohara device_xname(sc->sc_dev)); 2040 1.1 kiyohara cmalo_cmd_rsp_scan(sc); 2041 1.1 kiyohara break; 2042 1.1 kiyohara case MALO_CMD_AUTH: 2043 1.1 kiyohara /* do nothing */ 2044 1.1 kiyohara DPRINTF(1, "%s: got auth cmd response\n", 2045 1.1 kiyohara device_xname(sc->sc_dev)); 2046 1.1 kiyohara break; 2047 1.1 kiyohara case MALO_CMD_WEP: 2048 1.1 kiyohara /* do nothing */ 2049 1.1 kiyohara DPRINTF(1, "%s: got wep cmd response\n", 2050 1.1 kiyohara device_xname(sc->sc_dev)); 2051 1.1 kiyohara break; 2052 1.1 kiyohara case MALO_CMD_SNMP: 2053 1.1 kiyohara /* do nothing */ 2054 1.1 kiyohara DPRINTF(1, "%s: got snmp cmd response\n", 2055 1.1 kiyohara device_xname(sc->sc_dev)); 2056 1.1 kiyohara break; 2057 1.1 kiyohara case MALO_CMD_RADIO: 2058 1.1 kiyohara /* do nothing */ 2059 1.1 kiyohara DPRINTF(1, "%s: got radio cmd response\n", 2060 1.1 kiyohara device_xname(sc->sc_dev)); 2061 1.1 kiyohara break; 2062 1.1 kiyohara case MALO_CMD_CHANNEL: 2063 1.1 kiyohara /* do nothing */ 2064 1.1 kiyohara DPRINTF(1, "%s: got channel cmd response\n", 2065 1.1 kiyohara device_xname(sc->sc_dev)); 2066 1.1 kiyohara break; 2067 1.1 kiyohara case MALO_CMD_TXPOWER: 2068 1.1 kiyohara /* do nothing */ 2069 1.1 kiyohara DPRINTF(1, "%s: got txpower cmd response\n", 2070 1.1 kiyohara device_xname(sc->sc_dev)); 2071 1.1 kiyohara break; 2072 1.1 kiyohara case MALO_CMD_ANTENNA: 2073 1.1 kiyohara /* do nothing */ 2074 1.1 kiyohara DPRINTF(1, "%s: got antenna cmd response\n", 2075 1.1 kiyohara device_xname(sc->sc_dev)); 2076 1.1 kiyohara break; 2077 1.1 kiyohara case MALO_CMD_MACCTRL: 2078 1.1 kiyohara /* do nothing */ 2079 1.1 kiyohara DPRINTF(1, "%s: got macctrl cmd response\n", 2080 1.1 kiyohara device_xname(sc->sc_dev)); 2081 1.1 kiyohara break; 2082 1.1 kiyohara case MALO_CMD_MACADDR: 2083 1.1 kiyohara /* do nothing */ 2084 1.1 kiyohara DPRINTF(1, "%s: got macaddr cmd response\n", 2085 1.1 kiyohara device_xname(sc->sc_dev)); 2086 1.1 kiyohara break; 2087 1.1 kiyohara case MALO_CMD_ASSOC: 2088 1.1 kiyohara /* do nothing */ 2089 1.1 kiyohara DPRINTF(1, "%s: got assoc cmd response\n", 2090 1.1 kiyohara device_xname(sc->sc_dev)); 2091 1.1 kiyohara cmalo_cmd_rsp_assoc(sc); 2092 1.1 kiyohara break; 2093 1.1 kiyohara case MALO_CMD_80211D: 2094 1.1 kiyohara /* do nothing */ 2095 1.1 kiyohara DPRINTF(1, "%s: got 80211d cmd response\n", 2096 1.1 kiyohara device_xname(sc->sc_dev)); 2097 1.1 kiyohara break; 2098 1.1 kiyohara case MALO_CMD_BGSCAN_CONFIG: 2099 1.1 kiyohara /* do nothing */ 2100 1.1 kiyohara DPRINTF(1, "%s: got bgscan config cmd response\n", 2101 1.1 kiyohara device_xname(sc->sc_dev)); 2102 1.1 kiyohara break; 2103 1.1 kiyohara case MALO_CMD_BGSCAN_QUERY: 2104 1.1 kiyohara /* do nothing */ 2105 1.1 kiyohara DPRINTF(1, "%s: got bgscan query cmd response\n", 2106 1.1 kiyohara device_xname(sc->sc_dev)); 2107 1.1 kiyohara break; 2108 1.1 kiyohara case MALO_CMD_RATE: 2109 1.1 kiyohara /* do nothing */ 2110 1.1 kiyohara DPRINTF(1, "%s: got rate cmd response\n", 2111 1.1 kiyohara device_xname(sc->sc_dev)); 2112 1.1 kiyohara break; 2113 1.1 kiyohara default: 2114 1.1 kiyohara aprint_error_dev(sc->sc_dev, 2115 1.1 kiyohara "got unknown cmd response (0x%04x)\n", hdr->cmd); 2116 1.1 kiyohara break; 2117 1.1 kiyohara } 2118 1.1 kiyohara 2119 1.1 kiyohara splx(s); 2120 1.1 kiyohara 2121 1.1 kiyohara return 0; 2122 1.1 kiyohara } 2123 1.1 kiyohara 2124 1.1 kiyohara #ifdef _MODULE 2125 1.1 kiyohara 2126 1.1 kiyohara MODULE(MODULE_CLASS_DRIVER, malo_pcmcia, NULL); 2127 1.1 kiyohara 2128 1.1 kiyohara CFDRIVER_DECL(malo_pcmcia, DV_IFNET, NULL); 2129 1.1 kiyohara extern struct cfattach malo_pcmcia_ca; 2130 1.1 kiyohara static int malo_pcmcialoc[] = { -1 }; 2131 1.1 kiyohara static struct cfparent pcmciaparent = { 2132 1.1 kiyohara "pcmcia", NULL, DVUNIT_ANY 2133 1.1 kiyohara }; 2134 1.1 kiyohara static struct cfdata malo_pcmcia_cfdata[] = { 2135 1.1 kiyohara { 2136 1.1 kiyohara .cf_name = "malo_pcmcia", 2137 1.1 kiyohara .cf_atname = "malo", 2138 1.1 kiyohara .cf_unit = 0, 2139 1.1 kiyohara .cf_fstate = FSTATE_STAR, 2140 1.1 kiyohara .cf_loc = malo_pcmcialoc, 2141 1.1 kiyohara .cf_flags = 0, 2142 1.1 kiyohara .cf_pspec = &pcmciaparent, 2143 1.1 kiyohara }, 2144 1.1 kiyohara { NULL } 2145 1.1 kiyohara }; 2146 1.1 kiyohara 2147 1.1 kiyohara static int 2148 1.1 kiyohara malo_pcmcia_modcmd(modcmd_t cmd, void *arg) 2149 1.1 kiyohara { 2150 1.1 kiyohara int err; 2151 1.1 kiyohara 2152 1.1 kiyohara switch (cmd) { 2153 1.1 kiyohara case MODULE_CMD_INIT: 2154 1.1 kiyohara err = config_cfdriver_attach(&malo_pcmcia_cd); 2155 1.1 kiyohara if (err) 2156 1.1 kiyohara return err; 2157 1.1 kiyohara err = config_cfattach_attach("malo_pcmcia", &malo_pcmcia_ca); 2158 1.1 kiyohara if (err) { 2159 1.1 kiyohara config_cfdriver_detach(&malo_pcmcia_cd); 2160 1.1 kiyohara return err; 2161 1.1 kiyohara } 2162 1.1 kiyohara err = config_cfdata_attach(malo_pcmcia_cfdata, 1); 2163 1.1 kiyohara if (err) { 2164 1.1 kiyohara config_cfattach_detach("malo_pcmcia", &malo_pcmcia_ca); 2165 1.1 kiyohara config_cfdriver_detach(&malo_pcmcia_cd); 2166 1.1 kiyohara return err; 2167 1.1 kiyohara } 2168 1.1 kiyohara return 0; 2169 1.1 kiyohara case MODULE_CMD_FINI: 2170 1.1 kiyohara err = config_cfdata_detach(malo_pcmcia_cfdata); 2171 1.1 kiyohara if (err) 2172 1.1 kiyohara return err; 2173 1.1 kiyohara config_cfattach_detach("malo_pcmcia", &malo_pcmcia_ca); 2174 1.1 kiyohara config_cfdriver_detach(&malo_pcmcia_cd); 2175 1.1 kiyohara return 0; 2176 1.1 kiyohara default: 2177 1.1 kiyohara return ENOTTY; 2178 1.1 kiyohara } 2179 1.1 kiyohara } 2180 1.1 kiyohara #endif 2181