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