[BACK]Return to if_malo.c CVS log [TXT][DIR] Up to [local] / sys / dev / pcmcia

Annotation of sys/dev/pcmcia/if_malo.c, Revision 1.1

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

CVSweb