root/dev/ic/malo.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. malo_intr
  2. malo_attach
  3. malo_detach
  4. malo_alloc_cmd
  5. malo_free_cmd
  6. malo_send_cmd
  7. malo_send_cmd_dma
  8. malo_alloc_rx_ring
  9. malo_reset_rx_ring
  10. malo_free_rx_ring
  11. malo_alloc_tx_ring
  12. malo_reset_tx_ring
  13. malo_free_tx_ring
  14. malo_init
  15. malo_ioctl
  16. malo_start
  17. malo_stop
  18. malo_watchdog
  19. malo_newstate
  20. malo_newassoc
  21. malo_node_alloc
  22. malo_media_change
  23. malo_media_status
  24. malo_chip2rate
  25. malo_fix2rate
  26. malo_next_scan
  27. malo_tx_intr
  28. malo_tx_mgt
  29. malo_tx_data
  30. malo_tx_setup_desc
  31. malo_rx_intr
  32. malo_load_bootimg
  33. malo_load_firmware
  34. malo_set_wepkey
  35. malo_set_slot
  36. malo_update_slot
  37. malo_hexdump
  38. malo_cmd_string
  39. malo_cmd_string_result
  40. malo_cmd_get_spec
  41. malo_cmd_set_wepkey
  42. malo_cmd_set_prescan
  43. malo_cmd_set_postscan
  44. malo_cmd_set_channel
  45. malo_cmd_set_antenna
  46. malo_cmd_set_radio
  47. malo_cmd_set_aid
  48. malo_cmd_set_txpower
  49. malo_cmd_set_rts
  50. malo_cmd_set_slot
  51. malo_cmd_set_rate

    1 /*      $OpenBSD: malo.c,v 1.72 2007/07/18 18:10:31 damien Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
    5  * Copyright (c) 2006 Marcus Glocker <mglocker@openbsd.org>
    6  *
    7  * Permission to use, copy, modify, and distribute this software for any
    8  * purpose with or without fee is hereby granted, provided that the above
    9  * copyright notice and this permission notice appear in all copies.
   10  *
   11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   18  */
   19 
   20 #include "bpfilter.h"
   21 
   22 #include <sys/cdefs.h>
   23 #include <sys/param.h>
   24 #include <sys/types.h>
   25 
   26 #include <sys/device.h>
   27 #include <sys/kernel.h>
   28 #include <sys/malloc.h>
   29 #include <sys/mbuf.h>
   30 #include <sys/proc.h>
   31 #include <sys/socket.h>
   32 #include <sys/sockio.h>
   33 #include <sys/systm.h>
   34 
   35 #include <machine/bus.h>
   36 #include <machine/endian.h>
   37 #include <machine/intr.h>
   38 
   39 #include <net/if.h>
   40 #include <net/if_media.h>
   41 
   42 #if NBPFILTER > 0
   43 #include <net/bpf.h>
   44 #endif
   45 
   46 #include <netinet/in.h>
   47 #include <netinet/in_systm.h>
   48 #include <netinet/if_ether.h>
   49 
   50 #include <net80211/ieee80211_var.h>
   51 #include <net80211/ieee80211_radiotap.h>
   52 
   53 #include <dev/ic/malo.h>
   54 
   55 #ifdef MALO_DEBUG
   56 #define DPRINTF(x)      do { if (malo_debug > 0) printf x; } while (0)
   57 #define DPRINTFN(n, x)  do { if (malo_debug >= (n)) printf x; } while (0)
   58 int malo_debug = 1;
   59 #else
   60 #define DPRINTF(x)
   61 #define DPRINTFN(n, x)
   62 #endif
   63 
   64 /* internal structures and defines */
   65 struct malo_node {
   66         struct ieee80211_node           ni;
   67 };
   68 
   69 struct malo_rx_data {
   70         bus_dmamap_t    map;
   71         struct mbuf     *m;
   72 };
   73 
   74 struct malo_tx_data {
   75         bus_dmamap_t            map;
   76         struct mbuf             *m;
   77         uint32_t                softstat;
   78         struct ieee80211_node   *ni;
   79 };
   80 
   81 /* RX descriptor used by HW */
   82 struct malo_rx_desc {
   83         uint8_t         rxctrl;
   84         uint8_t         rssi;
   85         uint8_t         status;
   86         uint8_t         channel;
   87         uint16_t        len;
   88         uint8_t         reserved1;      /* actually unused */
   89         uint8_t         datarate;
   90         uint32_t        physdata;       /* DMA address of data */
   91         uint32_t        physnext;       /* DMA address of next control block */
   92         uint16_t        qosctrl;
   93         uint16_t        reserved2;
   94 } __packed;
   95 
   96 /* TX descriptor used by HW */
   97 struct malo_tx_desc {
   98         uint32_t        status;
   99         uint8_t         datarate;
  100         uint8_t         txpriority;
  101         uint16_t        qosctrl;
  102         uint32_t        physdata;       /* DMA address of data */
  103         uint16_t        len;
  104         uint8_t         destaddr[6];
  105         uint32_t        physnext;       /* DMA address of next control block */
  106         uint32_t        reserved1;      /* SAP packet info ??? */
  107         uint32_t        reserved2;
  108 } __packed;
  109 
  110 #define MALO_RX_RING_COUNT      256
  111 #define MALO_TX_RING_COUNT      256
  112 #define MALO_MAX_SCATTER        8       /* XXX unknown, wild guess */
  113 
  114 /*
  115  * Firmware commands
  116  */
  117 #define MALO_CMD_GET_HW_SPEC            0x0003
  118 #define MALO_CMD_SET_WEPKEY             0x0013
  119 #define MALO_CMD_SET_RADIO              0x001c
  120 #define MALO_CMD_SET_AID                0x010d
  121 #define MALO_CMD_SET_TXPOWER            0x001e
  122 #define MALO_CMD_SET_ANTENNA            0x0020
  123 #define MALO_CMD_SET_PRESCAN            0x0107
  124 #define MALO_CMD_SET_POSTSCAN           0x0108
  125 #define MALO_CMD_SET_RATE               0x0110
  126 #define MALO_CMD_SET_CHANNEL            0x010a
  127 #define MALO_CMD_SET_RTS                0x0113
  128 #define MALO_CMD_SET_SLOT               0x0114
  129 #define MALO_CMD_RESPONSE               0x8000
  130 
  131 #define MALO_CMD_RESULT_OK              0x0000  /* everything is fine */
  132 #define MALO_CMD_RESULT_ERROR           0x0001  /* general error */
  133 #define MALO_CMD_RESULT_NOSUPPORT       0x0002  /* command not valid */
  134 #define MALO_CMD_RESULT_PENDING         0x0003  /* will be processed */
  135 #define MALO_CMD_RESULT_BUSY            0x0004  /* command ignored */
  136 #define MALO_CMD_RESULT_PARTIALDATA     0x0005  /* buffer too small */
  137 
  138 struct malo_cmdheader {
  139         uint16_t        cmd;
  140         uint16_t        size;           /* size of the command, incl. header */
  141         uint16_t        seqnum;         /* seems not to matter that much */
  142         uint16_t        result;         /* set to 0 on request */
  143         /* following the data payload, up to 256 bytes */
  144 };
  145 
  146 struct malo_hw_spec {
  147         uint16_t        HwVersion;
  148         uint16_t        NumOfWCB;
  149         uint16_t        NumOfMCastAdr;
  150         uint8_t         PermanentAddress[6];
  151         uint16_t        RegionCode;
  152         uint16_t        NumberOfAntenna;
  153         uint32_t        FWReleaseNumber;
  154         uint32_t        WcbBase0;
  155         uint32_t        RxPdWrPtr;
  156         uint32_t        RxPdRdPtr;
  157         uint32_t        CookiePtr;
  158         uint32_t        WcbBase1;
  159         uint32_t        WcbBase2;
  160         uint32_t        WcbBase3;
  161 } __packed;
  162 
  163 struct malo_cmd_wepkey {
  164         uint16_t        action;
  165         uint8_t         len;
  166         uint8_t         flags;
  167         uint16_t        index;
  168         uint8_t         value[IEEE80211_KEYBUF_SIZE];
  169         uint8_t         txmickey[IEEE80211_WEP_MICLEN];
  170         uint8_t         rxmickey[IEEE80211_WEP_MICLEN];
  171         uint64_t        rxseqctr;
  172         uint64_t        txseqctr;
  173 } __packed;
  174 
  175 struct malo_cmd_radio {
  176         uint16_t        action;
  177         uint16_t        preamble_mode;
  178         uint16_t        enable;
  179 } __packed;
  180 
  181 struct malo_cmd_aid {
  182         uint16_t        associd;
  183         uint8_t         macaddr[6];
  184         uint32_t        gprotection;
  185         uint8_t         aprates[14];
  186 } __packed;
  187 
  188 struct malo_cmd_txpower {
  189         uint16_t        action;
  190         uint16_t        supportpowerlvl;
  191         uint16_t        currentpowerlvl;
  192         uint16_t        reserved;
  193         uint16_t        powerlvllist[8];
  194 } __packed;
  195 
  196 struct malo_cmd_antenna {
  197         uint16_t        action;
  198         uint16_t        mode;
  199 } __packed;
  200 
  201 struct malo_cmd_postscan {
  202         uint32_t        isibss;
  203         uint8_t         bssid[6];
  204 } __packed;
  205 
  206 struct malo_cmd_channel {
  207         uint16_t        action;
  208         uint8_t         channel;
  209 } __packed;
  210 
  211 struct malo_cmd_rate {
  212         uint8_t         dataratetype;
  213         uint8_t         rateindex;
  214         uint8_t         aprates[14];
  215 } __packed;
  216 
  217 struct malo_cmd_slot {
  218         uint16_t        action;
  219         uint8_t         slot;
  220 } __packed;
  221 
  222 #define malo_mem_write4(sc, off, x) \
  223         bus_space_write_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x))
  224 #define malo_mem_write2(sc, off, x) \
  225         bus_space_write_2((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x))
  226 #define malo_mem_write1(sc, off, x) \
  227         bus_space_write_1((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x))
  228 
  229 #define malo_mem_read4(sc, off) \
  230         bus_space_read_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off))
  231 #define malo_mem_read1(sc, off) \
  232         bus_space_read_1((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off))
  233 
  234 #define malo_ctl_write4(sc, off, x) \
  235         bus_space_write_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off), (x))
  236 #define malo_ctl_read4(sc, off) \
  237         bus_space_read_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off))
  238 #define malo_ctl_read1(sc, off) \
  239         bus_space_read_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off))
  240 
  241 #define malo_ctl_barrier(sc, t) \
  242         bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00, 0xff, (t))
  243 
  244 struct cfdriver malo_cd = {
  245         NULL, "malo", DV_IFNET
  246 };
  247 
  248 int     malo_alloc_cmd(struct malo_softc *sc);
  249 void    malo_free_cmd(struct malo_softc *sc);
  250 void    malo_send_cmd(struct malo_softc *sc, bus_addr_t addr);
  251 int     malo_send_cmd_dma(struct malo_softc *sc, bus_addr_t addr);
  252 int     malo_alloc_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring,
  253             int count);
  254 void    malo_reset_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring);
  255 void    malo_free_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring);
  256 int     malo_alloc_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring,
  257             int count);
  258 void    malo_reset_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring);
  259 void    malo_free_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring);
  260 int     malo_init(struct ifnet *ifp);
  261 int     malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
  262 void    malo_start(struct ifnet *ifp);
  263 void    malo_stop(struct malo_softc *sc);
  264 void    malo_watchdog(struct ifnet *ifp);
  265 int     malo_newstate(struct ieee80211com *ic, enum ieee80211_state nstate,
  266             int arg);
  267 void    malo_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni,
  268             int isnew);
  269 struct ieee80211_node *
  270         malo_node_alloc(struct ieee80211com *ic);
  271 int     malo_media_change(struct ifnet *ifp);
  272 void    malo_media_status(struct ifnet *ifp, struct ifmediareq *imr);
  273 int     malo_chip2rate(int chip_rate);
  274 int     malo_fix2rate(int fix_rate);
  275 void    malo_next_scan(void *arg);
  276 void    malo_tx_intr(struct malo_softc *sc);
  277 int     malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0,
  278             struct ieee80211_node *ni);
  279 int     malo_tx_data(struct malo_softc *sc, struct mbuf *m0,
  280             struct ieee80211_node *ni);
  281 void    malo_tx_setup_desc(struct malo_softc *sc, struct malo_tx_desc *desc,
  282             int len, int rate, const bus_dma_segment_t *segs, int nsegs);
  283 void    malo_rx_intr(struct malo_softc *sc);
  284 int     malo_load_bootimg(struct malo_softc *sc);
  285 int     malo_load_firmware(struct malo_softc *sc);
  286 
  287 int     malo_set_wepkey(struct malo_softc *sc);
  288 int     malo_set_slot(struct malo_softc *sc);
  289 void    malo_update_slot(struct ieee80211com *ic);
  290 #ifdef MALO_DEBUG
  291 void    malo_hexdump(void *buf, int len);
  292 #endif
  293 static char *
  294         malo_cmd_string(uint16_t cmd);
  295 static char *
  296         malo_cmd_string_result(uint16_t result);
  297 int     malo_cmd_get_spec(struct malo_softc *sc);
  298 int     malo_cmd_set_wepkey(struct malo_softc *sc, struct ieee80211_key *k,
  299             uint16_t k_index);
  300 int     malo_cmd_set_prescan(struct malo_softc *sc);
  301 int     malo_cmd_set_postscan(struct malo_softc *sc, uint8_t *macaddr,
  302             uint8_t ibsson);
  303 int     malo_cmd_set_channel(struct malo_softc *sc, uint8_t channel);
  304 int     malo_cmd_set_antenna(struct malo_softc *sc, uint16_t antenna_type);
  305 int     malo_cmd_set_radio(struct malo_softc *sc, uint16_t mode,
  306             uint16_t preamble);
  307 int     malo_cmd_set_aid(struct malo_softc *sc, uint8_t *bssid,
  308             uint16_t associd);
  309 int     malo_cmd_set_txpower(struct malo_softc *sc, unsigned int powerlevel);
  310 int     malo_cmd_set_rts(struct malo_softc *sc, uint32_t threshold);
  311 int     malo_cmd_set_slot(struct malo_softc *sc, uint8_t slot);
  312 int     malo_cmd_set_rate(struct malo_softc *sc, uint8_t rate);
  313 
  314 int
  315 malo_intr(void *arg)
  316 {
  317         struct malo_softc *sc = arg;
  318         uint32_t status;
  319 
  320         status = malo_ctl_read4(sc, 0x0c30);
  321         if (status == 0xffffffff || status == 0)
  322                 /* not for us */
  323                 return (0);
  324 
  325         if (status & 0x1)
  326                 malo_tx_intr(sc);
  327         if (status & 0x2)
  328                 malo_rx_intr(sc);
  329         if (status & 0x4) {
  330                 struct malo_cmdheader *hdr = sc->sc_cmd_mem;
  331 
  332                 if (letoh16(hdr->result) != MALO_CMD_RESULT_OK) {
  333                         printf("%s: firmware cmd %s failed with %s\n",
  334                             sc->sc_dev.dv_xname,
  335                             malo_cmd_string(hdr->cmd),
  336                             malo_cmd_string_result(hdr->result));
  337                 }
  338 #ifdef MALO_DEBUG
  339                 printf("%s: cmd answer for %s=%s\n",
  340                     sc->sc_dev.dv_xname,
  341                     malo_cmd_string(hdr->cmd),
  342                     malo_cmd_string_result(hdr->result));
  343                 if (malo_debug > 2)
  344                         malo_hexdump(hdr, letoh16(hdr->size));
  345 #endif
  346         }
  347 
  348         if (status & ~0x7)
  349                 DPRINTF(("%s: unkown interrupt %x\n", sc->sc_dev.dv_xname,
  350                     status));
  351 
  352         /* just ack the interrupt */
  353         malo_ctl_write4(sc, 0x0c30, 0);
  354 
  355         return (1);
  356 }
  357 
  358 int
  359 malo_attach(struct malo_softc *sc)
  360 {
  361         struct ieee80211com *ic = &sc->sc_ic;
  362         struct ifnet *ifp = &sc->sc_ic.ic_if;
  363         int i;
  364 
  365         /* initialize channel scanning timer */
  366         timeout_set(&sc->sc_scan_to, malo_next_scan, sc);
  367 
  368         /* allocate DMA structures */
  369         malo_alloc_cmd(sc);
  370         malo_alloc_rx_ring(sc, &sc->sc_rxring, MALO_RX_RING_COUNT);
  371         malo_alloc_tx_ring(sc, &sc->sc_txring, MALO_TX_RING_COUNT);
  372 
  373         /* setup interface */
  374         ifp->if_softc = sc;
  375         ifp->if_init = malo_init;
  376         ifp->if_ioctl = malo_ioctl;
  377         ifp->if_start = malo_start;
  378         ifp->if_watchdog = malo_watchdog;
  379         ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
  380         strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
  381         IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
  382         IFQ_SET_READY(&ifp->if_snd);
  383 
  384         /* set supported rates */
  385         ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
  386         ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
  387         sc->sc_last_txrate = -1;
  388 
  389         /* set channels */
  390         for (i = 1; i <= 14; i++) {
  391                 ic->ic_channels[i].ic_freq =
  392                     ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
  393                 ic->ic_channels[i].ic_flags =
  394                     IEEE80211_CHAN_PUREG |
  395                     IEEE80211_CHAN_B |
  396                     IEEE80211_CHAN_G;
  397         }
  398 
  399         /* set the rest */
  400         ic->ic_caps =
  401             IEEE80211_C_IBSS |
  402             IEEE80211_C_MONITOR |
  403             IEEE80211_C_SHPREAMBLE |
  404             IEEE80211_C_SHSLOT |
  405             IEEE80211_C_WEP;
  406         ic->ic_opmode = IEEE80211_M_STA;
  407         ic->ic_state = IEEE80211_S_INIT;
  408         ic->ic_max_rssi = 75;
  409         for (i = 0; i < 6; i++)
  410                 ic->ic_myaddr[i] = malo_ctl_read1(sc, 0xa528 + i);
  411 
  412         /* show our mac address */
  413         printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
  414 
  415         /* attach interface */
  416         if_attach(ifp);
  417         ieee80211_ifattach(ifp);
  418 
  419         /* post attach vector functions */
  420         sc->sc_newstate = ic->ic_newstate;
  421         ic->ic_newstate = malo_newstate;
  422         ic->ic_newassoc = malo_newassoc;
  423         ic->ic_node_alloc = malo_node_alloc;
  424         ic->ic_updateslot = malo_update_slot;
  425 
  426         ieee80211_media_init(ifp, malo_media_change, malo_media_status);
  427 
  428 #if NBPFILTER > 0
  429         bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
  430             sizeof(struct ieee80211_frame) + 64);
  431 
  432         sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
  433         sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
  434         sc->sc_rxtap.wr_ihdr.it_present = htole32(MALO_RX_RADIOTAP_PRESENT);
  435 
  436         sc->sc_txtap_len = sizeof(sc->sc_txtapu);
  437         sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
  438         sc->sc_txtap.wt_ihdr.it_present = htole32(MALO_TX_RADIOTAP_PRESENT);
  439 #endif
  440 
  441         return (0);
  442 }
  443 
  444 int
  445 malo_detach(void *arg)
  446 {
  447         struct malo_softc *sc = arg;
  448         struct ieee80211com *ic = &sc->sc_ic;
  449         struct ifnet *ifp = &ic->ic_if;
  450 
  451         /* remove channel scanning timer */
  452         timeout_del(&sc->sc_scan_to);
  453 
  454         malo_stop(sc);
  455         ieee80211_ifdetach(ifp);
  456         if_detach(ifp);
  457         malo_free_cmd(sc);
  458         malo_free_rx_ring(sc, &sc->sc_rxring);
  459         malo_free_tx_ring(sc, &sc->sc_txring);
  460 
  461         return (0);
  462 }
  463 
  464 int
  465 malo_alloc_cmd(struct malo_softc *sc)
  466 {
  467         int error, nsegs;
  468 
  469         error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1,
  470             PAGE_SIZE, 0, BUS_DMA_ALLOCNOW, &sc->sc_cmd_dmam);
  471         if (error != 0) {
  472                 printf("%s: can not create DMA tag\n", sc->sc_dev.dv_xname);
  473                 return (-1);
  474         }
  475 
  476         error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE,
  477             0, &sc->sc_cmd_dmas, 1, &nsegs, BUS_DMA_WAITOK);
  478         if (error != 0) {
  479                 printf("%s: error alloc dma memory\n", sc->sc_dev.dv_xname);
  480                 return (-1);
  481         }
  482 
  483         error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cmd_dmas, nsegs,
  484             PAGE_SIZE, (caddr_t *)&sc->sc_cmd_mem, BUS_DMA_WAITOK);
  485         if (error != 0) {
  486                 printf("%s: error map dma memory\n", sc->sc_dev.dv_xname);
  487                 return (-1);
  488         }
  489 
  490         error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmd_dmam,
  491             sc->sc_cmd_mem, PAGE_SIZE, NULL, BUS_DMA_NOWAIT);
  492         if (error != 0) {
  493                 printf("%s: error load dma memory\n", sc->sc_dev.dv_xname);
  494                 bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_dmas, nsegs);
  495                 return (-1);
  496         }
  497 
  498         sc->sc_cookie = sc->sc_cmd_mem;
  499         *sc->sc_cookie = htole32(0xaa55aa55);
  500         sc->sc_cmd_mem = sc->sc_cmd_mem + sizeof(uint32_t);
  501         sc->sc_cookie_dmaaddr = sc->sc_cmd_dmam->dm_segs[0].ds_addr;
  502         sc->sc_cmd_dmaaddr = sc->sc_cmd_dmam->dm_segs[0].ds_addr +
  503             sizeof(uint32_t);
  504 
  505         return (0);
  506 }
  507 
  508 void
  509 malo_free_cmd(struct malo_softc *sc)
  510 {
  511         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
  512             BUS_DMASYNC_POSTWRITE);
  513         bus_dmamap_unload(sc->sc_dmat, sc->sc_cmd_dmam);
  514         bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_cookie, PAGE_SIZE);
  515         bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_dmas, 1);
  516 }
  517 
  518 void
  519 malo_send_cmd(struct malo_softc *sc, bus_addr_t addr)
  520 {
  521         malo_ctl_write4(sc, 0x0c10, (uint32_t)addr);
  522         malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
  523         malo_ctl_write4(sc, 0x0c18, 2); /* CPU_TRANSFER_CMD */
  524         malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
  525 }
  526 
  527 int
  528 malo_send_cmd_dma(struct malo_softc *sc, bus_addr_t addr)
  529 {
  530         int i;
  531         struct malo_cmdheader *hdr = sc->sc_cmd_mem;
  532 
  533         malo_ctl_write4(sc, 0x0c10, (uint32_t)addr);
  534         malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
  535         malo_ctl_write4(sc, 0x0c18, 2); /* CPU_TRANSFER_CMD */
  536         malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
  537 
  538         for (i = 0; i < 10; i++) {
  539                 delay(100);
  540                 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
  541                     BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
  542                 if (hdr->cmd & htole16(0x8000))
  543                         break;
  544         }
  545 
  546         if (i == 10)
  547                 return (ETIMEDOUT);
  548 
  549         return (0);
  550 }
  551 
  552 int
  553 malo_alloc_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring, int count)
  554 {
  555         struct malo_rx_desc *desc;
  556         struct malo_rx_data *data;
  557         int i, nsegs, error;
  558 
  559         ring->count = count;
  560         ring->cur = ring->next = 0;
  561 
  562         error = bus_dmamap_create(sc->sc_dmat,
  563             count * sizeof(struct malo_rx_desc), 1,
  564             count * sizeof(struct malo_rx_desc), 0,
  565             BUS_DMA_NOWAIT, &ring->map);
  566         if (error != 0) {
  567                 printf("%s: could not create desc DMA map\n",
  568                     sc->sc_dev.dv_xname);
  569                 goto fail;
  570         }
  571 
  572         error = bus_dmamem_alloc(sc->sc_dmat,
  573             count * sizeof(struct malo_rx_desc),
  574             PAGE_SIZE, 0, &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT);
  575         if (error != 0) {
  576                 printf("%s: could not allocate DMA memory\n",
  577                     sc->sc_dev.dv_xname);
  578                 goto fail;
  579         }
  580 
  581         error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
  582             count * sizeof(struct malo_rx_desc), (caddr_t *)&ring->desc,
  583             BUS_DMA_NOWAIT);
  584         if (error != 0) {
  585                 printf("%s: could not map desc DMA memory\n",
  586                     sc->sc_dev.dv_xname);
  587                 goto fail;
  588         }
  589 
  590         error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
  591             count * sizeof(struct malo_rx_desc), NULL, BUS_DMA_NOWAIT);
  592         if (error != 0) {
  593                 printf("%s: could not load desc DMA map\n",
  594                     sc->sc_dev.dv_xname);
  595                 goto fail;
  596         }
  597 
  598         bzero(ring->desc, count * sizeof(struct malo_rx_desc));
  599         ring->physaddr = ring->map->dm_segs->ds_addr;
  600 
  601         ring->data = malloc(count * sizeof (struct malo_rx_data), M_DEVBUF,
  602             M_NOWAIT);
  603         if (ring->data == NULL) {
  604                 printf("%s: could not allocate soft data\n",
  605                     sc->sc_dev.dv_xname);
  606                 error = ENOMEM;
  607                 goto fail;
  608         }
  609 
  610         /*
  611          * Pre-allocate Rx buffers and populate Rx ring.
  612          */
  613         bzero(ring->data, count * sizeof (struct malo_rx_data));
  614         for (i = 0; i < count; i++) {
  615                 desc = &ring->desc[i];
  616                 data = &ring->data[i];
  617 
  618                 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
  619                     0, BUS_DMA_NOWAIT, &data->map);
  620                 if (error != 0) {
  621                         printf("%s: could not create DMA map\n",
  622                             sc->sc_dev.dv_xname);
  623                         goto fail;
  624                 }
  625 
  626                 MGETHDR(data->m, M_DONTWAIT, MT_DATA);
  627                 if (data->m == NULL) {
  628                         printf("%s: could not allocate rx mbuf\n",
  629                             sc->sc_dev.dv_xname);
  630                         error = ENOMEM;
  631                         goto fail;
  632                 }
  633 
  634                 MCLGET(data->m, M_DONTWAIT);
  635                 if (!(data->m->m_flags & M_EXT)) {
  636                         printf("%s: could not allocate rx mbuf cluster\n",
  637                             sc->sc_dev.dv_xname);
  638                         error = ENOMEM;
  639                         goto fail;
  640                 }
  641 
  642                 error = bus_dmamap_load(sc->sc_dmat, data->map,
  643                     mtod(data->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
  644                 if (error != 0) {
  645                         printf("%s: could not load rx buf DMA map",
  646                             sc->sc_dev.dv_xname);
  647                         goto fail;
  648                 }
  649 
  650                 desc->status = htole16(1);
  651                 desc->physdata = htole32(data->map->dm_segs->ds_addr);
  652                 desc->physnext = htole32(ring->physaddr +
  653                     (i + 1) % count * sizeof(struct malo_rx_desc));
  654         }
  655 
  656         bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
  657             BUS_DMASYNC_PREWRITE);
  658 
  659         return (0);
  660 
  661 fail:   malo_free_rx_ring(sc, ring);
  662         return (error);
  663 }
  664 
  665 void
  666 malo_reset_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring)
  667 {
  668         int i;
  669 
  670         for (i = 0; i < ring->count; i++)
  671                 ring->desc[i].status = 0;
  672 
  673         bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
  674             BUS_DMASYNC_PREWRITE);
  675 
  676         ring->cur = ring->next = 0;
  677 }
  678 
  679 void
  680 malo_free_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring)
  681 {
  682         struct malo_rx_data *data;
  683         int i;
  684 
  685         if (ring->desc != NULL) {
  686                 bus_dmamap_sync(sc->sc_dmat, ring->map, 0,
  687                     ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
  688                 bus_dmamap_unload(sc->sc_dmat, ring->map);
  689                 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
  690                     ring->count * sizeof(struct malo_rx_desc));
  691                 bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
  692         }
  693 
  694         if (ring->data != NULL) {
  695                 for (i = 0; i < ring->count; i++) {
  696                         data = &ring->data[i];
  697 
  698                         if (data->m != NULL) {
  699                                 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
  700                                     data->map->dm_mapsize,
  701                                     BUS_DMASYNC_POSTREAD);
  702                                 bus_dmamap_unload(sc->sc_dmat, data->map);
  703                                 m_freem(data->m);
  704                         }
  705 
  706                         if (data->map != NULL)
  707                                 bus_dmamap_destroy(sc->sc_dmat, data->map);
  708                 }
  709                 free(ring->data, M_DEVBUF);
  710         }
  711 }
  712 
  713 int
  714 malo_alloc_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring,
  715     int count)
  716 {
  717         int i, nsegs, error;
  718 
  719         ring->count = count;
  720         ring->queued = 0;
  721         ring->cur = ring->next = ring->stat = 0;
  722 
  723         error = bus_dmamap_create(sc->sc_dmat,
  724             count * sizeof(struct malo_tx_desc), 1,
  725             count * sizeof(struct malo_tx_desc), 0, BUS_DMA_NOWAIT, &ring->map);
  726         if (error != 0) {
  727                 printf("%s: could not create desc DMA map\n",
  728                     sc->sc_dev.dv_xname);
  729                 goto fail;
  730         }
  731 
  732         error = bus_dmamem_alloc(sc->sc_dmat,
  733             count * sizeof(struct malo_tx_desc),
  734             PAGE_SIZE, 0, &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT);
  735         if (error != 0) {
  736                 printf("%s: could not allocate DMA memory\n",
  737                     sc->sc_dev.dv_xname);
  738                 goto fail;
  739         }
  740 
  741         error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
  742             count * sizeof(struct malo_tx_desc), (caddr_t *)&ring->desc,
  743             BUS_DMA_NOWAIT);
  744         if (error != 0) {
  745                 printf("%s: could not map desc DMA memory\n",
  746                     sc->sc_dev.dv_xname);
  747                 goto fail;
  748         }
  749 
  750         error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
  751             count * sizeof(struct malo_tx_desc), NULL, BUS_DMA_NOWAIT);
  752         if (error != 0) {
  753                 printf("%s: could not load desc DMA map\n",
  754                     sc->sc_dev.dv_xname);
  755                 goto fail;
  756         }
  757 
  758         memset(ring->desc, 0, count * sizeof(struct malo_tx_desc));
  759         ring->physaddr = ring->map->dm_segs->ds_addr;
  760 
  761         ring->data = malloc(count * sizeof(struct malo_tx_data), M_DEVBUF,
  762             M_NOWAIT);
  763         if (ring->data == NULL) {
  764                 printf("%s: could not allocate soft data\n",
  765                     sc->sc_dev.dv_xname);
  766                 error = ENOMEM;
  767                 goto fail;
  768         }
  769 
  770         memset(ring->data, 0, count * sizeof(struct malo_tx_data));
  771         for (i = 0; i < count; i++) {
  772                 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
  773                     MALO_MAX_SCATTER, MCLBYTES, 0, BUS_DMA_NOWAIT,
  774                     &ring->data[i].map);
  775                 if (error != 0) {
  776                         printf("%s: could not create DMA map\n",
  777                             sc->sc_dev.dv_xname);
  778                         goto fail;
  779                 }
  780                 ring->desc[i].physnext = htole32(ring->physaddr +
  781                     (i + 1) % count * sizeof(struct malo_tx_desc));
  782         }
  783 
  784         return (0);
  785 
  786 fail:   malo_free_tx_ring(sc, ring);
  787         return (error);
  788 }
  789 
  790 void
  791 malo_reset_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring)
  792 {
  793         struct malo_tx_desc *desc;
  794         struct malo_tx_data *data;
  795         int i;
  796 
  797         for (i = 0; i < ring->count; i++) {
  798                 desc = &ring->desc[i];
  799                 data = &ring->data[i];
  800 
  801                 if (data->m != NULL) {
  802                         bus_dmamap_sync(sc->sc_dmat, data->map, 0,
  803                             data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
  804                         bus_dmamap_unload(sc->sc_dmat, data->map);
  805                         m_freem(data->m);
  806                         data->m = NULL;
  807                 }
  808 
  809                 /*
  810                  * The node has already been freed at that point so don't call
  811                  * ieee80211_release_node() here.
  812                  */
  813                 data->ni = NULL;
  814 
  815                 desc->status = 0;
  816         }
  817 
  818         bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
  819             BUS_DMASYNC_PREWRITE);
  820 
  821         ring->queued = 0;
  822         ring->cur = ring->next = ring->stat = 0;
  823 }
  824 
  825 void
  826 malo_free_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring)
  827 {
  828         struct malo_tx_data *data;
  829         int i;
  830 
  831         if (ring->desc != NULL) {
  832                 bus_dmamap_sync(sc->sc_dmat, ring->map, 0,
  833                     ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
  834                 bus_dmamap_unload(sc->sc_dmat, ring->map);
  835                 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
  836                     ring->count * sizeof(struct malo_tx_desc));
  837                 bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
  838         }
  839 
  840         if (ring->data != NULL) {
  841                 for (i = 0; i < ring->count; i++) {
  842                         data = &ring->data[i];
  843 
  844                         if (data->m != NULL) {
  845                                 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
  846                                     data->map->dm_mapsize,
  847                                     BUS_DMASYNC_POSTWRITE);
  848                                 bus_dmamap_unload(sc->sc_dmat, data->map);
  849                                 m_freem(data->m);
  850                         }
  851 
  852                         /*
  853                          * The node has already been freed at that point so
  854                          * don't call ieee80211_release_node() here.
  855                          */
  856                         data->ni = NULL;
  857 
  858                         if (data->map != NULL)
  859                                 bus_dmamap_destroy(sc->sc_dmat, data->map);
  860                 }
  861                 free(ring->data, M_DEVBUF);
  862         }
  863 }
  864 
  865 int
  866 malo_init(struct ifnet *ifp)
  867 {
  868         struct malo_softc *sc = ifp->if_softc;
  869         struct ieee80211com *ic = &sc->sc_ic;
  870         uint8_t chan;
  871         int error;
  872 
  873         DPRINTF(("%s: %s\n", ifp->if_xname, __func__));
  874 
  875         /* if interface already runs stop it first */
  876         if (ifp->if_flags & IFF_RUNNING)
  877                 malo_stop(sc);
  878 
  879         /* power on cardbus socket */
  880         if (sc->sc_enable)
  881                 sc->sc_enable(sc);
  882 
  883         /* disable interrupts */
  884         malo_ctl_read4(sc, 0x0c30);
  885         malo_ctl_write4(sc, 0x0c30, 0);
  886         malo_ctl_write4(sc, 0x0c34, 0);
  887         malo_ctl_write4(sc, 0x0c3c, 0);
  888 
  889         /* load firmware */
  890         if ((error = malo_load_bootimg(sc)))
  891                 goto fail;
  892         if ((error = malo_load_firmware(sc)))
  893                 goto fail;
  894 
  895         /* enable interrupts */
  896         malo_ctl_write4(sc, 0x0c34, 0x1f);
  897         malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
  898         malo_ctl_write4(sc, 0x0c3c, 0x1f);
  899         malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
  900 
  901         if ((error = malo_cmd_get_spec(sc)))
  902                 goto fail;
  903 
  904         /* select default channel */
  905         ic->ic_bss->ni_chan = ic->ic_ibss_chan;
  906         chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
  907 
  908         /* initialize hardware */
  909         if ((error = malo_cmd_set_channel(sc, chan))) {
  910                 printf("%s: setting channel failed!\n",
  911                     sc->sc_dev.dv_xname);
  912                 goto fail;
  913         }
  914         if ((error = malo_cmd_set_antenna(sc, 1))) {
  915                 printf("%s: setting RX antenna failed!\n",
  916                     sc->sc_dev.dv_xname);
  917                 goto fail;
  918         }
  919         if ((error = malo_cmd_set_antenna(sc, 2))) {
  920                 printf("%s: setting TX antenna failed!\n",
  921                     sc->sc_dev.dv_xname);
  922                 goto fail;
  923         }
  924         if ((error = malo_cmd_set_radio(sc, 1, 5))) {
  925                 printf("%s: turn radio on failed!\n",
  926                     sc->sc_dev.dv_xname);
  927                 goto fail;
  928         }
  929         if ((error = malo_cmd_set_txpower(sc, 100))) {
  930                 printf("%s: setting TX power failed!\n",
  931                     sc->sc_dev.dv_xname);
  932                 goto fail;
  933         }
  934         if ((error = malo_cmd_set_rts(sc, IEEE80211_RTS_MAX))) {
  935                 printf("%s: setting RTS failed!\n",
  936                     sc->sc_dev.dv_xname);
  937                 goto fail;
  938         }
  939 
  940         /* WEP */
  941         if (sc->sc_ic.ic_flags & IEEE80211_F_WEPON) {
  942                 /* set key */
  943                 if (malo_set_wepkey(sc)) {
  944                         printf("%s: setting WEP key failed!\n",
  945                             sc->sc_dev.dv_xname);
  946                         goto fail;
  947                 }
  948         }
  949 
  950         ifp->if_flags |= IFF_RUNNING;
  951 
  952         if (ic->ic_opmode != IEEE80211_M_MONITOR)
  953                 /* start background scanning */
  954                 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
  955         else
  956                 /* in monitor mode change directly into run state */
  957                 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
  958 
  959         return (0);
  960 
  961 fail:
  962         /* reset adapter */
  963         DPRINTF(("%s: malo_init failed, reseting card\n",
  964             sc->sc_dev.dv_xname));
  965         malo_ctl_write4(sc, 0x0c18, (1 << 15));
  966         return (error);
  967 }
  968 
  969 int
  970 malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  971 {
  972         struct malo_softc *sc = ifp->if_softc;
  973         struct ieee80211com *ic = &sc->sc_ic;
  974         struct ifaddr *ifa;
  975         struct ifreq *ifr;
  976         int s, error = 0;
  977         uint8_t chan;
  978 
  979         s = splnet();
  980 
  981         switch (cmd) {
  982         case SIOCSIFADDR:
  983                 ifa = (struct ifaddr *)data;
  984                 ifp->if_flags |= IFF_UP;
  985 #ifdef INET
  986                 if (ifa->ifa_addr->sa_family == AF_INET)
  987                         arp_ifinit(&ic->ic_ac, ifa);
  988 #endif
  989                 /* FALLTHROUGH */
  990         case SIOCSIFFLAGS:
  991                 if (ifp->if_flags & IFF_UP) {
  992                         if ((ifp->if_flags & IFF_RUNNING) == 0)
  993                                 malo_init(ifp);
  994                 } else {
  995                         if (ifp->if_flags & IFF_RUNNING)
  996                                 malo_stop(sc);
  997                 }
  998                 break;
  999         case SIOCADDMULTI:
 1000         case SIOCDELMULTI:
 1001                 ifr = (struct ifreq *)data;
 1002                 error = (cmd == SIOCADDMULTI) ?
 1003                     ether_addmulti(ifr, &ic->ic_ac) :
 1004                     ether_delmulti(ifr, &ic->ic_ac);
 1005 
 1006                 if (error == ENETRESET)
 1007                         error = 0;
 1008                 break;
 1009         case SIOCS80211CHANNEL:
 1010                 /* allow fast channel switching in monitor mode */
 1011                 error = ieee80211_ioctl(ifp, cmd, data);
 1012                 if (error == ENETRESET &&
 1013                     ic->ic_opmode == IEEE80211_M_MONITOR) {
 1014                         if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
 1015                             (IFF_UP | IFF_RUNNING)) {
 1016                                 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
 1017                                 chan = ieee80211_chan2ieee(ic,
 1018                                     ic->ic_bss->ni_chan);
 1019                                 malo_cmd_set_channel(sc, chan);
 1020                         }
 1021                         error = 0;
 1022                 }
 1023                 break;
 1024         default:
 1025                 error = ieee80211_ioctl(ifp, cmd, data);
 1026                 break;
 1027         }
 1028 
 1029         if (error == ENETRESET) {
 1030                 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
 1031                     (IFF_UP | IFF_RUNNING))
 1032                         malo_init(ifp);
 1033                 error = 0;
 1034         }
 1035 
 1036         splx(s);
 1037 
 1038         return (error);
 1039 }
 1040 
 1041 void
 1042 malo_start(struct ifnet *ifp)
 1043 {
 1044         struct malo_softc *sc = ifp->if_softc;
 1045         struct ieee80211com *ic = &sc->sc_ic;
 1046         struct mbuf *m0;
 1047         struct ieee80211_node *ni;
 1048 
 1049         DPRINTFN(2, ("%s: %s\n", sc->sc_dev.dv_xname, __func__));
 1050 
 1051         if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
 1052                 return;
 1053 
 1054         for (;;) {
 1055                 IF_POLL(&ic->ic_mgtq, m0);
 1056                 if (m0 != NULL) {
 1057                         if (sc->sc_txring.queued >= MALO_TX_RING_COUNT) {
 1058                                 ifp->if_flags |= IFF_OACTIVE;
 1059                                 break;
 1060                         }
 1061                         IF_DEQUEUE(&ic->ic_mgtq, m0);
 1062 
 1063                         ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
 1064                         m0->m_pkthdr.rcvif = NULL;
 1065 #if NBPFILTER > 0
 1066                         if (ic->ic_rawbpf != NULL)
 1067                                 bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
 1068 #endif
 1069                         if (malo_tx_mgt(sc, m0, ni) != 0)
 1070                                 break;
 1071                 } else {
 1072                         if (ic->ic_state != IEEE80211_S_RUN)
 1073                                 break;
 1074                         IFQ_POLL(&ifp->if_snd, m0);
 1075                         if (m0 == NULL)
 1076                                 break;
 1077                         if (sc->sc_txring.queued >= MALO_TX_RING_COUNT - 1) {
 1078                                 ifp->if_flags |= IFF_OACTIVE;
 1079                                 break;
 1080                         }
 1081                         IFQ_DEQUEUE(&ifp->if_snd, m0);
 1082 #if NBPFILTER > 0
 1083                         if (ifp->if_bpf != NULL)
 1084                                 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
 1085 #endif
 1086                         m0 = ieee80211_encap(ifp, m0, &ni);
 1087                         if (m0 == NULL)
 1088                                 continue;
 1089 #if NBPFILTER > 0
 1090                         if (ic->ic_rawbpf != NULL)
 1091                                 bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
 1092 #endif
 1093                         if (malo_tx_data(sc, m0, ni) != 0) {
 1094                                 if (ni != NULL)
 1095                                         ieee80211_release_node(ic, ni);
 1096                                 ifp->if_oerrors++;
 1097                                 break;
 1098                         }
 1099                 }
 1100         }
 1101 }
 1102 
 1103 void
 1104 malo_stop(struct malo_softc *sc)
 1105 {
 1106         struct ieee80211com *ic = &sc->sc_ic;
 1107         struct ifnet *ifp = &ic->ic_if;
 1108 
 1109         DPRINTF(("%s: %s\n", ifp->if_xname, __func__));
 1110 
 1111         /* reset adapter */
 1112         if (ifp->if_flags & IFF_RUNNING)
 1113                 malo_ctl_write4(sc, 0x0c18, (1 << 15));
 1114 
 1115         /* device is not running anymore */
 1116         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
 1117 
 1118         /* change back to initial state */
 1119         ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 1120 
 1121         /* reset RX / TX rings */
 1122         malo_reset_tx_ring(sc, &sc->sc_txring);
 1123         malo_reset_rx_ring(sc, &sc->sc_rxring);
 1124 
 1125         /* set initial rate */
 1126         sc->sc_last_txrate = -1;
 1127 
 1128         /* power off cardbus socket */
 1129         if (sc->sc_disable)
 1130                 sc->sc_disable(sc);
 1131 }
 1132 
 1133 void
 1134 malo_watchdog(struct ifnet *ifp)
 1135 {
 1136 
 1137 }
 1138 
 1139 int
 1140 malo_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
 1141 {
 1142         struct malo_softc *sc = ic->ic_if.if_softc;
 1143         enum ieee80211_state ostate;
 1144         uint8_t chan;
 1145         int rate;
 1146 
 1147         DPRINTFN(2, ("%s: %s\n", sc->sc_dev.dv_xname, __func__));
 1148 
 1149         ostate = ic->ic_state;
 1150         timeout_del(&sc->sc_scan_to);
 1151 
 1152         switch (nstate) {
 1153         case IEEE80211_S_INIT:
 1154                 break;
 1155         case IEEE80211_S_SCAN:
 1156                 if (ostate == IEEE80211_S_INIT) {
 1157                         if (malo_cmd_set_prescan(sc) != 0)
 1158                                 DPRINTF(("%s: can't set prescan\n",
 1159                                     sc->sc_dev.dv_xname));
 1160                 } else {
 1161                         chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
 1162 
 1163                         malo_cmd_set_channel(sc, chan);
 1164                 }
 1165                 timeout_add(&sc->sc_scan_to, hz / 2);
 1166                 break;
 1167         case IEEE80211_S_AUTH:
 1168                 DPRINTF(("newstate AUTH\n"));
 1169                 malo_cmd_set_postscan(sc, ic->ic_myaddr, 1);
 1170                 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
 1171                 malo_cmd_set_channel(sc, chan);
 1172                 break;
 1173         case IEEE80211_S_ASSOC:
 1174                 DPRINTF(("newstate ASSOC\n"));
 1175                 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
 1176                         malo_cmd_set_radio(sc, 1, 3); /* short preamble */
 1177                 else
 1178                         malo_cmd_set_radio(sc, 1, 1); /* long preamble */
 1179 
 1180                 malo_cmd_set_aid(sc, ic->ic_bss->ni_bssid,
 1181                     ic->ic_bss->ni_associd);
 1182 
 1183                 if (ic->ic_fixed_rate == -1)
 1184                         /* automatic rate adaption */
 1185                         malo_cmd_set_rate(sc, 0);
 1186                 else {
 1187                         /* fixed rate */
 1188                         rate = malo_fix2rate(ic->ic_fixed_rate);
 1189                         malo_cmd_set_rate(sc, rate);
 1190                 }
 1191 
 1192                 malo_set_slot(sc);
 1193                 break;
 1194         case IEEE80211_S_RUN:
 1195                 DPRINTF(("newstate RUN\n"));
 1196                 break;
 1197         default:
 1198                 break;
 1199         }
 1200 
 1201         return (sc->sc_newstate(ic, nstate, arg));
 1202 }
 1203 
 1204 void
 1205 malo_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
 1206 {
 1207 
 1208 }
 1209 
 1210 struct ieee80211_node *
 1211 malo_node_alloc(struct ieee80211com *ic)
 1212 {
 1213         struct malo_node *wn;
 1214 
 1215         wn = malloc(sizeof(struct malo_node), M_DEVBUF, M_NOWAIT);
 1216         if (wn == NULL)
 1217                 return (NULL);
 1218 
 1219         bzero(wn, sizeof(struct malo_node));
 1220 
 1221         return ((struct ieee80211_node *)wn);
 1222 }
 1223 
 1224 int
 1225 malo_media_change(struct ifnet *ifp)
 1226 {
 1227         int error;
 1228 
 1229         DPRINTF(("%s: %s\n", ifp->if_xname, __func__));
 1230 
 1231         error = ieee80211_media_change(ifp);
 1232         if (error != ENETRESET)
 1233                 return (error);
 1234 
 1235         if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
 1236                 malo_init(ifp);
 1237 
 1238         return (0);
 1239 }
 1240 
 1241 void
 1242 malo_media_status(struct ifnet *ifp, struct ifmediareq *imr)
 1243 {
 1244         struct malo_softc *sc = ifp->if_softc;
 1245         struct ieee80211com *ic = &sc->sc_ic;
 1246 
 1247         imr->ifm_status = IFM_AVALID;
 1248         imr->ifm_active = IFM_IEEE80211;
 1249         if (ic->ic_state == IEEE80211_S_RUN)
 1250                 imr->ifm_status |= IFM_ACTIVE;
 1251 
 1252         /* report last TX rate used by chip */
 1253         imr->ifm_active |= ieee80211_rate2media(ic, sc->sc_last_txrate,
 1254             ic->ic_curmode);
 1255 
 1256         switch (ic->ic_opmode) {
 1257         case IEEE80211_M_STA:
 1258                 break;
 1259         case IEEE80211_M_IBSS:
 1260                 imr->ifm_active |= IFM_IEEE80211_ADHOC;
 1261                 break;
 1262         case IEEE80211_M_MONITOR:
 1263                 imr->ifm_active |= IFM_IEEE80211_MONITOR;
 1264                 break;
 1265         case IEEE80211_M_AHDEMO:
 1266                 break;
 1267         case IEEE80211_M_HOSTAP:
 1268                 break;
 1269         }
 1270 
 1271         switch (ic->ic_curmode) {
 1272                 case IEEE80211_MODE_11B:
 1273                         imr->ifm_active |= IFM_IEEE80211_11B;
 1274                         break;
 1275                 case IEEE80211_MODE_11G:
 1276                         imr->ifm_active |= IFM_IEEE80211_11G;
 1277                         break;
 1278         }
 1279 }
 1280 
 1281 int
 1282 malo_chip2rate(int chip_rate)
 1283 {
 1284         switch (chip_rate) {
 1285         /* CCK rates */
 1286         case  0:        return (2);
 1287         case  1:        return (4);
 1288         case  2:        return (11);
 1289         case  3:        return (22);
 1290 
 1291         /* OFDM rates */
 1292         case  4:        return (0); /* reserved */
 1293         case  5:        return (12);
 1294         case  6:        return (18);
 1295         case  7:        return (24);
 1296         case  8:        return (36);
 1297         case  9:        return (48);
 1298         case 10:        return (72);
 1299         case 11:        return (96);
 1300         case 12:        return (108);
 1301 
 1302         /* no rate select yet or unknown rate */
 1303         default:        return (-1);
 1304         }
 1305 }
 1306 
 1307 int
 1308 malo_fix2rate(int fix_rate)
 1309 {
 1310         switch (fix_rate) {
 1311         /* CCK rates */
 1312         case  0:        return (2);
 1313         case  1:        return (4);
 1314         case  2:        return (11);
 1315         case  3:        return (22);
 1316 
 1317         /* OFDM rates */
 1318         case  4:        return (12);
 1319         case  5:        return (18);
 1320         case  6:        return (24);
 1321         case  7:        return (36);
 1322         case  8:        return (48);
 1323         case  9:        return (72);
 1324         case 10:        return (96);
 1325         case 11:        return (108);
 1326 
 1327         /* unknown rate: should not happen */
 1328         default:        return (0);
 1329         }
 1330 }
 1331 
 1332 void
 1333 malo_next_scan(void *arg)
 1334 {
 1335         struct malo_softc *sc = arg;
 1336         struct ieee80211com *ic = &sc->sc_ic;
 1337         struct ifnet *ifp = &ic->ic_if;
 1338         int s;
 1339 
 1340         DPRINTF(("%s: %s\n", ifp->if_xname, __func__));
 1341 
 1342         s = splnet();
 1343 
 1344         if (ic->ic_state == IEEE80211_S_SCAN)
 1345                 ieee80211_next_scan(ifp);
 1346 
 1347         splx(s);
 1348 }
 1349 
 1350 void
 1351 malo_tx_intr(struct malo_softc *sc)
 1352 {
 1353         struct ieee80211com *ic = &sc->sc_ic;
 1354         struct ifnet *ifp = &ic->ic_if;
 1355         struct malo_tx_desc *desc;
 1356         struct malo_tx_data *data;
 1357         struct malo_node *rn;
 1358         int stat;
 1359 
 1360         DPRINTFN(2, ("%s: %s\n", sc->sc_dev.dv_xname, __func__));
 1361 
 1362         stat = sc->sc_txring.stat;
 1363         for (;;) {
 1364                 desc = &sc->sc_txring.desc[sc->sc_txring.stat];
 1365                 data = &sc->sc_txring.data[sc->sc_txring.stat];
 1366                 rn = (struct malo_node *)data->ni;
 1367 
 1368                 /* check if TX descriptor is not owned by FW anymore */
 1369                 if ((letoh32(desc->status) & 0x80000000) ||
 1370                     !(letoh32(data->softstat) & 0x80))
 1371                         break;
 1372 
 1373                 /* if no frame has been sent, ignore */
 1374                 if (rn == NULL)
 1375                         goto next;
 1376 
 1377                 /* check TX state */
 1378                 switch (letoh32(desc->status) & 0x1) {
 1379                 case 0x1:
 1380                         DPRINTFN(2, ("data frame was sent successfully\n"));
 1381                         ifp->if_opackets++;
 1382                         break;
 1383                 default:
 1384                         DPRINTF(("data frame sending error\n"));
 1385                         ifp->if_oerrors++;
 1386                         break;
 1387                 }
 1388 
 1389                 /* save last used TX rate */
 1390                 sc->sc_last_txrate = malo_chip2rate(desc->datarate);
 1391 
 1392                 /* cleanup TX data and TX descritpor */
 1393                 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
 1394                     data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
 1395                 bus_dmamap_unload(sc->sc_dmat, data->map);
 1396                 m_freem(data->m);
 1397                 ieee80211_release_node(ic, data->ni);
 1398                 data->m = NULL;
 1399                 data->ni = NULL;
 1400                 data->softstat &= htole32(~0x80);
 1401                 desc->status = 0;
 1402                 desc->len = 0;
 1403 
 1404                 DPRINTFN(2, ("tx done idx=%u\n", sc->sc_txring.stat));
 1405 
 1406                 sc->sc_txring.queued--;
 1407 next:
 1408                 if (++sc->sc_txring.stat >= sc->sc_txring.count)
 1409                         sc->sc_txring.stat = 0;
 1410                 if (sc->sc_txring.stat == stat)
 1411                         break;
 1412         }
 1413 
 1414         sc->sc_tx_timer = 0;
 1415         ifp->if_flags &= ~IFF_OACTIVE;
 1416         malo_start(ifp);
 1417 }
 1418 
 1419 int
 1420 malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
 1421 {
 1422         struct ieee80211com *ic = &sc->sc_ic;
 1423         struct ifnet *ifp = &ic->ic_if;
 1424         struct malo_tx_desc *desc;
 1425         struct malo_tx_data *data;
 1426         struct ieee80211_frame *wh;
 1427         int error;
 1428 
 1429         DPRINTFN(2, ("%s: %s\n", sc->sc_dev.dv_xname, __func__));
 1430 
 1431         desc = &sc->sc_txring.desc[sc->sc_txring.cur];
 1432         data = &sc->sc_txring.data[sc->sc_txring.cur];
 1433 
 1434         if (m0->m_len < sizeof(struct ieee80211_frame)) {
 1435                 m0 = m_pullup(m0, sizeof(struct ieee80211_frame));
 1436                 if (m0 == NULL) {
 1437                         ifp->if_ierrors++;
 1438                         return (ENOBUFS);
 1439                 }
 1440         }
 1441         wh = mtod(m0, struct ieee80211_frame *);
 1442 
 1443         if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
 1444                 m0 = ieee80211_wep_crypt(ifp, m0, 1);
 1445                 if (m0 == NULL)
 1446                         return (ENOBUFS);
 1447 
 1448                 /* packet header may have moved, reset our local pointer */
 1449                 wh = mtod(m0, struct ieee80211_frame *);
 1450         }
 1451 
 1452 #if NBPFILTER > 0
 1453         if (sc->sc_drvbpf != NULL) {
 1454                 struct mbuf mb;
 1455                 struct malo_tx_radiotap_hdr *tap = &sc->sc_txtap;
 1456 
 1457                 tap->wt_flags = 0;
 1458                 tap->wt_rate = sc->sc_last_txrate;
 1459                 tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
 1460                 tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
 1461 
 1462                 mb.m_data = (caddr_t)tap;
 1463                 mb.m_len = sc->sc_txtap_len;
 1464                 mb.m_next = m0;
 1465                 mb.m_nextpkt = NULL;
 1466                 mb.m_type = 0;
 1467                 mb.m_flags = 0;
 1468                 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
 1469         }
 1470 #endif
 1471         /*
 1472          * inject FW specific fields into the 802.11 frame
 1473          *
 1474          *  2 bytes FW len (inject)
 1475          * 24 bytes 802.11 frame header
 1476          *  6 bytes addr4 (inject)
 1477          *  n bytes 802.11 frame body
 1478          */
 1479         if (M_LEADINGSPACE(m0) < 8) {
 1480                 if (M_TRAILINGSPACE(m0) < 8)
 1481                         panic("%s: not enough space for mbuf dance",
 1482                             sc->sc_dev.dv_xname);
 1483                 bcopy(m0->m_data, m0->m_data + 8, m0->m_len);
 1484                 m0->m_data += 8;
 1485         }
 1486 
 1487         /* move frame header */
 1488         bcopy(m0->m_data, m0->m_data - 6, sizeof(*wh));
 1489         m0->m_data -= 8;
 1490         m0->m_len += 8;
 1491         m0->m_pkthdr.len += 8;
 1492         *mtod(m0, uint16_t *) = htole16(m0->m_len - 32); /* FW len */
 1493 
 1494         error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
 1495             BUS_DMA_NOWAIT);
 1496         if (error != 0) {
 1497                 printf("%s: could not map mbuf (error %d)\n",
 1498                     sc->sc_dev.dv_xname, error);
 1499                 m_freem(m0);
 1500                 return (error);
 1501         }
 1502 
 1503         data->m = m0;
 1504         data->ni = ni;
 1505         data->softstat |= htole32(0x80);
 1506 
 1507         malo_tx_setup_desc(sc, desc, m0->m_pkthdr.len, 0,
 1508             data->map->dm_segs, data->map->dm_nsegs);
 1509 
 1510         bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
 1511             BUS_DMASYNC_PREWRITE);
 1512         bus_dmamap_sync(sc->sc_dmat, sc->sc_txring.map,
 1513             sc->sc_txring.cur * sizeof(struct malo_tx_desc),
 1514             sizeof(struct malo_tx_desc), BUS_DMASYNC_PREWRITE);
 1515 
 1516         DPRINTFN(2, ("%s: sending mgmt frame, pktlen=%u, idx=%u\n",
 1517             sc->sc_dev.dv_xname, m0->m_pkthdr.len, sc->sc_txring.cur));
 1518 
 1519         sc->sc_txring.queued++;
 1520         sc->sc_txring.cur = (sc->sc_txring.cur + 1) % MALO_TX_RING_COUNT;
 1521 
 1522         /* kick mgmt TX */
 1523         malo_ctl_write4(sc, 0x0c18, 1);
 1524         malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
 1525 
 1526         return (0);
 1527 }
 1528 
 1529 int
 1530 malo_tx_data(struct malo_softc *sc, struct mbuf *m0,
 1531     struct ieee80211_node *ni)
 1532 {
 1533         struct ieee80211com *ic = &sc->sc_ic;
 1534         struct ifnet *ifp = &ic->ic_if;
 1535         struct malo_tx_desc *desc;
 1536         struct malo_tx_data *data;
 1537         struct ieee80211_frame *wh;
 1538         struct mbuf *mnew;
 1539         int error;
 1540 
 1541         DPRINTFN(2, ("%s: %s\n", sc->sc_dev.dv_xname, __func__));
 1542 
 1543         desc = &sc->sc_txring.desc[sc->sc_txring.cur];
 1544         data = &sc->sc_txring.data[sc->sc_txring.cur];
 1545 
 1546         if (m0->m_len < sizeof(struct ieee80211_frame)) {
 1547                 m0 = m_pullup(m0, sizeof(struct ieee80211_frame));
 1548                 if (m0 == NULL) {
 1549                         ifp->if_ierrors++;
 1550                         return (ENOBUFS);
 1551                 }
 1552         }
 1553         wh = mtod(m0, struct ieee80211_frame *);
 1554 
 1555         if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
 1556                 m0 = ieee80211_wep_crypt(ifp, m0, 1);
 1557                 if (m0 == NULL)
 1558                         return (ENOBUFS);
 1559 
 1560                 /* packet header may have moved, reset our local pointer */
 1561                 wh = mtod(m0, struct ieee80211_frame *);
 1562         }
 1563 
 1564 #if NBPFILTER > 0
 1565         if (sc->sc_drvbpf != NULL) {
 1566                 struct mbuf mb;
 1567                 struct malo_tx_radiotap_hdr *tap = &sc->sc_txtap;
 1568 
 1569                 tap->wt_flags = 0;
 1570                 tap->wt_rate = sc->sc_last_txrate;
 1571                 tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
 1572                 tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
 1573 
 1574                 mb.m_data = (caddr_t)tap;
 1575                 mb.m_len = sc->sc_txtap_len;
 1576                 mb.m_next = m0;
 1577                 mb.m_nextpkt = NULL;
 1578                 mb.m_type = 0;
 1579                 mb.m_flags = 0;
 1580                 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
 1581         }
 1582 #endif
 1583 
 1584         /*
 1585          * inject FW specific fields into the 802.11 frame
 1586          *
 1587          *  2 bytes FW len (inject)
 1588          * 24 bytes 802.11 frame header
 1589          *  6 bytes addr4 (inject)
 1590          *  n bytes 802.11 frame body
 1591          *
 1592          * For now copy all into a new mcluster.
 1593          */
 1594         MGETHDR(mnew, M_DONTWAIT, MT_DATA);
 1595         if (mnew == NULL)
 1596                 return (ENOBUFS);
 1597         MCLGET(mnew, M_DONTWAIT);
 1598         if (!(mnew->m_flags & M_EXT)) {
 1599                 m_free(mnew);
 1600                 return (ENOBUFS);
 1601         }
 1602 
 1603         *mtod(mnew, uint16_t *) = htole16(m0->m_pkthdr.len - 24); /* FW len */
 1604         bcopy(wh, mtod(mnew, caddr_t) + 2, sizeof(*wh));
 1605         bzero(mtod(mnew, caddr_t) + 26, 6);
 1606         m_copydata(m0, sizeof(*wh), m0->m_pkthdr.len - sizeof(*wh),
 1607             mtod(mnew, caddr_t) + 32);
 1608         mnew->m_pkthdr.len = mnew->m_len = m0->m_pkthdr.len + 8;
 1609         m_freem(m0);
 1610         m0 = mnew;
 1611 
 1612         error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
 1613             BUS_DMA_NOWAIT);
 1614         if (error != 0) {
 1615                 printf("%s: could not map mbuf (error %d)\n",
 1616                     sc->sc_dev.dv_xname, error);
 1617                 m_freem(m0);
 1618                 return (error);
 1619         }
 1620 
 1621         data->m = m0;
 1622         data->ni = ni;
 1623         data->softstat |= htole32(0x80);
 1624 
 1625         malo_tx_setup_desc(sc, desc, m0->m_pkthdr.len, 1,
 1626             data->map->dm_segs, data->map->dm_nsegs);
 1627 
 1628         bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
 1629             BUS_DMASYNC_PREWRITE);
 1630         bus_dmamap_sync(sc->sc_dmat, sc->sc_txring.map,
 1631             sc->sc_txring.cur * sizeof(struct malo_tx_desc),
 1632             sizeof(struct malo_tx_desc), BUS_DMASYNC_PREWRITE);
 1633 
 1634         DPRINTFN(2, ("%s: sending data frame, pktlen=%u, idx=%u\n",
 1635             sc->sc_dev.dv_xname, m0->m_pkthdr.len, sc->sc_txring.cur));
 1636 
 1637         sc->sc_txring.queued++;
 1638         sc->sc_txring.cur = (sc->sc_txring.cur + 1) % MALO_TX_RING_COUNT;
 1639 
 1640         /* kick data TX */
 1641         malo_ctl_write4(sc, 0x0c18, 1);
 1642         malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
 1643 
 1644         return (0);
 1645 }
 1646 
 1647 void
 1648 malo_tx_setup_desc(struct malo_softc *sc, struct malo_tx_desc *desc,
 1649     int len, int rate, const bus_dma_segment_t *segs, int nsegs)
 1650 {
 1651         desc->len = htole16(segs[0].ds_len);
 1652         desc->datarate = rate; /* 0 = mgmt frame, 1 = data frame */
 1653         desc->physdata = htole32(segs[0].ds_addr);
 1654         desc->status = htole32(0x00000001 | 0x80000000);
 1655 }
 1656 
 1657 void
 1658 malo_rx_intr(struct malo_softc *sc)
 1659 {
 1660         struct ieee80211com *ic = &sc->sc_ic;
 1661         struct ifnet *ifp = &ic->ic_if;
 1662         struct malo_rx_desc *desc;
 1663         struct malo_rx_data *data;
 1664         struct ieee80211_frame *wh;
 1665         struct ieee80211_node *ni;
 1666         struct mbuf *mnew, *m;
 1667         uint32_t rxRdPtr, rxWrPtr;
 1668         int error, i;
 1669 
 1670         rxRdPtr = malo_mem_read4(sc, sc->sc_RxPdRdPtr);
 1671         rxWrPtr = malo_mem_read4(sc, sc->sc_RxPdWrPtr);
 1672 
 1673         for (i = 0; i < MALO_RX_RING_COUNT && rxRdPtr != rxWrPtr; i++) {
 1674                 desc = &sc->sc_rxring.desc[sc->sc_rxring.cur];
 1675                 data = &sc->sc_rxring.data[sc->sc_rxring.cur];
 1676 
 1677                 bus_dmamap_sync(sc->sc_dmat, sc->sc_rxring.map,
 1678                     sc->sc_rxring.cur * sizeof(struct malo_rx_desc),
 1679                     sizeof(struct malo_rx_desc), BUS_DMASYNC_POSTREAD);
 1680 
 1681                 DPRINTFN(3, ("rx intr idx=%d, rxctrl=0x%02x, rssi=%d, "
 1682                     "status=0x%02x, channel=%d, len=%d, res1=%02x, rate=%d, "
 1683                     "physdata=0x%04x, physnext=0x%04x, qosctrl=%02x, res2=%d\n",
 1684                     sc->sc_rxring.cur, desc->rxctrl, desc->rssi, desc->status,
 1685                     desc->channel, letoh16(desc->len), desc->reserved1,
 1686                     desc->datarate, letoh32(desc->physdata),
 1687                     letoh32(desc->physnext), desc->qosctrl, desc->reserved2));
 1688 
 1689                 if ((desc->rxctrl & 0x80) == 0)
 1690                         break;
 1691 
 1692                 MGETHDR(mnew, M_DONTWAIT, MT_DATA);
 1693                 if (mnew == NULL) {
 1694                         ifp->if_ierrors++;
 1695                         goto skip;
 1696                 }
 1697 
 1698                 MCLGET(mnew, M_DONTWAIT);
 1699                 if (!(mnew->m_flags & M_EXT)) {
 1700                         m_freem(mnew);
 1701                         ifp->if_ierrors++;
 1702                         goto skip;
 1703                 }
 1704 
 1705                 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
 1706                     data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
 1707                 bus_dmamap_unload(sc->sc_dmat, data->map);
 1708 
 1709                 error = bus_dmamap_load(sc->sc_dmat, data->map,
 1710                     mtod(mnew, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
 1711                 if (error != 0) {
 1712                         m_freem(mnew);
 1713 
 1714                         error = bus_dmamap_load(sc->sc_dmat, data->map,
 1715                             mtod(data->m, void *), MCLBYTES, NULL,
 1716                             BUS_DMA_NOWAIT);
 1717                         if (error != 0) {
 1718                                 panic("%s: could not load old rx mbuf",
 1719                                     sc->sc_dev.dv_xname);
 1720                         }
 1721                         ifp->if_ierrors++;
 1722                         goto skip;
 1723                 }
 1724 
 1725                 /*
 1726                  * New mbuf mbuf successfully loaded
 1727                  */
 1728                 m = data->m;
 1729                 data->m = mnew;
 1730                 desc->physdata = htole32(data->map->dm_segs->ds_addr);
 1731 
 1732                 /* finalize mbuf */
 1733                 m->m_pkthdr.rcvif = ifp;
 1734                 m->m_pkthdr.len = m->m_len = letoh16(desc->len);
 1735 
 1736                 /*
 1737                  * cut out FW specific fields from the 802.11 frame
 1738                  *
 1739                  *  2 bytes FW len (cut out)
 1740                  * 24 bytes 802.11 frame header
 1741                  *  6 bytes addr4 (cut out)
 1742                  *  n bytes 802.11 frame data
 1743                  */
 1744                 bcopy(m->m_data, m->m_data + 6, 26);
 1745                 m_adj(m, 8);
 1746 
 1747 #if NBPFILTER > 0
 1748                 if (sc->sc_drvbpf != NULL) {
 1749                         struct mbuf mb;
 1750                         struct malo_rx_radiotap_hdr *tap = &sc->sc_rxtap;
 1751 
 1752                         tap->wr_flags = 0;
 1753                         tap->wr_chan_freq =
 1754                             htole16(ic->ic_bss->ni_chan->ic_freq);
 1755                         tap->wr_chan_flags =
 1756                             htole16(ic->ic_bss->ni_chan->ic_flags);
 1757                         tap->wr_rssi = desc->rssi;
 1758                         tap->wr_max_rssi = ic->ic_max_rssi;
 1759 
 1760                         mb.m_data = (caddr_t)tap;
 1761                         mb.m_len = sc->sc_rxtap_len;
 1762                         mb.m_next = m;
 1763                         mb.m_nextpkt = NULL;
 1764                         mb.m_type = 0;
 1765                         mb.m_flags = 0;
 1766                         bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
 1767                 }
 1768 #endif
 1769 
 1770                 wh = mtod(m, struct ieee80211_frame *);
 1771                 ni = ieee80211_find_rxnode(ic, wh);
 1772 
 1773                 /* send the frame to the 802.11 layer */
 1774                 ieee80211_input(ifp, m, ni, desc->rssi, 0);
 1775 
 1776                 /* node is no longer needed */
 1777                 ieee80211_release_node(ic, ni);
 1778 
 1779 skip:
 1780                 desc->rxctrl = 0;
 1781                 rxRdPtr = letoh32(desc->physnext);
 1782 
 1783                 bus_dmamap_sync(sc->sc_dmat, sc->sc_rxring.map,
 1784                     sc->sc_rxring.cur * sizeof(struct malo_rx_desc),
 1785                     sizeof(struct malo_rx_desc), BUS_DMASYNC_PREWRITE);
 1786 
 1787                 sc->sc_rxring.cur = (sc->sc_rxring.cur + 1) %
 1788                     MALO_RX_RING_COUNT;
 1789         }
 1790 
 1791         malo_mem_write4(sc, sc->sc_RxPdRdPtr, rxRdPtr);
 1792 
 1793         /*
 1794          * In HostAP mode, ieee80211_input() will enqueue packets in if_snd
 1795          * without calling if_start().
 1796          */
 1797         if (!IFQ_IS_EMPTY(&ifp->if_snd) && !(ifp->if_flags & IFF_OACTIVE))
 1798                 (*ifp->if_start)(ifp);
 1799 }
 1800 
 1801 int
 1802 malo_load_bootimg(struct malo_softc *sc)
 1803 {
 1804         char *name = "malo8335-h";
 1805         uint8_t *ucode;
 1806         size_t size;
 1807         int error, i;
 1808 
 1809         /* load boot firmware */
 1810         if ((error = loadfirmware(name, &ucode, &size)) != 0) {
 1811                 printf("%s: error %d, could not read microcode %s!\n",
 1812                     sc->sc_dev.dv_xname, error, name);
 1813                 return (EIO);
 1814         }
 1815 
 1816         /*
 1817          * It seems we are putting this code directly onto the stack of
 1818          * the ARM cpu. I don't know why we need to instruct the DMA
 1819          * engine to move the code. This is a big riddle without docu.
 1820          */
 1821         DPRINTF(("%s: loading boot firmware\n", sc->sc_dev.dv_xname));
 1822         malo_mem_write2(sc, 0xbef8, 0x001);
 1823         malo_mem_write2(sc, 0xbefa, size);
 1824         malo_mem_write4(sc, 0xbefc, 0);
 1825 
 1826         bus_space_write_region_1(sc->sc_mem1_bt, sc->sc_mem1_bh, 0xbf00,
 1827             ucode, size);
 1828 
 1829         /*
 1830          * we loaded the firmware into card memory now tell the CPU
 1831          * to fetch the code and execute it. The memory mapped via the
 1832          * first bar is internaly mapped to 0xc0000000.
 1833          */
 1834         malo_send_cmd(sc, 0xc000bef8);
 1835 
 1836         /* wait for the device to go into FW loading mode */
 1837         for (i = 0; i < 10; i++) {
 1838                 delay(50);
 1839                 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_READ);
 1840                 if (malo_ctl_read4(sc, 0x0c14) == 0x5)
 1841                         break;
 1842         }
 1843         if (i == 10) {
 1844                 printf("%s: timeout at boot firmware load!\n",
 1845                     sc->sc_dev.dv_xname);
 1846                 free(ucode, M_DEVBUF);
 1847                 return (ETIMEDOUT);
 1848         }
 1849         free(ucode, M_DEVBUF);
 1850 
 1851         /* tell the card we're done and... */
 1852         malo_mem_write2(sc, 0xbef8, 0x001);
 1853         malo_mem_write2(sc, 0xbefa, 0);
 1854         malo_mem_write4(sc, 0xbefc, 0);
 1855         malo_send_cmd(sc, 0xc000bef8);
 1856 
 1857         DPRINTF(("%s: boot firmware loaded\n", sc->sc_dev.dv_xname));
 1858 
 1859         return (0);
 1860 }
 1861 
 1862 int
 1863 malo_load_firmware(struct malo_softc *sc)
 1864 {
 1865         struct malo_cmdheader *hdr;
 1866         char *name = "malo8335-m";
 1867         void *data;
 1868         uint8_t *ucode;
 1869         size_t size, count, bsize;
 1870         int i, sn, error;
 1871 
 1872         /* load real firmware now */
 1873         if ((error = loadfirmware(name, &ucode, &size)) != 0) {
 1874                 printf("%s: error %d, could not read microcode %s!\n",
 1875                     sc->sc_dev.dv_xname, error, name);
 1876                 return (EIO);
 1877         }
 1878 
 1879         DPRINTF(("%s: uploading firmware\n", sc->sc_dev.dv_xname));
 1880 
 1881         hdr = sc->sc_cmd_mem;
 1882         data = hdr + 1;
 1883         sn = 1;
 1884         for (count = 0; count < size; count += bsize) {
 1885                 bsize = MIN(256, size - count);
 1886 
 1887                 hdr->cmd = htole16(0x0001);
 1888                 hdr->size = htole16(bsize);
 1889                 hdr->seqnum = htole16(sn++);
 1890                 hdr->result = 0;
 1891 
 1892                 bcopy(ucode + count, data, bsize);
 1893 
 1894                 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 1895                     BUS_DMASYNC_PREWRITE);
 1896                 malo_send_cmd(sc, sc->sc_cmd_dmaaddr);
 1897                 bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 1898                     BUS_DMASYNC_POSTWRITE);
 1899                 delay(500);
 1900         }
 1901         free(ucode, M_DEVBUF);
 1902 
 1903         DPRINTF(("%s: firmware upload finished\n", sc->sc_dev.dv_xname));
 1904 
 1905         /*
 1906          * send a command with size 0 to tell that the firmware has been
 1907          * uploaded
 1908          */
 1909         hdr->cmd = htole16(0x0001);
 1910         hdr->size = 0;
 1911         hdr->seqnum = htole16(sn++);
 1912         hdr->result = 0;
 1913 
 1914         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 1915             BUS_DMASYNC_PREWRITE);
 1916         malo_send_cmd(sc, sc->sc_cmd_dmaaddr);
 1917         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 1918             BUS_DMASYNC_POSTWRITE);
 1919         delay(100);
 1920 
 1921         DPRINTF(("%s: loading firmware\n", sc->sc_dev.dv_xname));
 1922 
 1923         /* wait until firmware has been loaded */
 1924         for (i = 0; i < 200; i++) {
 1925                 malo_ctl_write4(sc, 0x0c10, 0x5a);
 1926                 delay(500);
 1927                 malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE |
 1928                      BUS_SPACE_BARRIER_READ);
 1929                 if (malo_ctl_read4(sc, 0x0c14) == 0xf0f1f2f4)
 1930                         break;
 1931         }
 1932         if (i == 200) {
 1933                 printf("%s: timeout at firmware load!\n", sc->sc_dev.dv_xname);
 1934                 return (ETIMEDOUT);
 1935         }
 1936 
 1937         DPRINTF(("%s: firmware loaded\n", sc->sc_dev.dv_xname));
 1938 
 1939         return (0);
 1940 }
 1941 
 1942 int
 1943 malo_set_wepkey(struct malo_softc *sc)
 1944 {
 1945         struct ieee80211com *ic = &sc->sc_ic;
 1946         int i;
 1947 
 1948         for (i = 0; i < IEEE80211_WEP_NKID; i++) {
 1949                 struct ieee80211_key *k = &ic->ic_nw_keys[i];
 1950 
 1951                 if (k->k_len == 0)
 1952                         continue;
 1953 
 1954                 if (malo_cmd_set_wepkey(sc, k, i))
 1955                         return (ENXIO);
 1956         }
 1957 
 1958         return (0);
 1959 }
 1960 
 1961 int
 1962 malo_set_slot(struct malo_softc *sc)
 1963 {
 1964         struct ieee80211com *ic = &sc->sc_ic;
 1965 
 1966         if (ic->ic_flags & IEEE80211_F_SHSLOT) {
 1967                 /* set short slot */
 1968                 if (malo_cmd_set_slot(sc, 1)) {
 1969                         printf("%s: setting short slot failed\n",
 1970                             sc->sc_dev.dv_xname);
 1971                         return (ENXIO);
 1972                 }
 1973         } else {
 1974                 /* set long slot */
 1975                 if (malo_cmd_set_slot(sc, 0)) {
 1976                         printf("%s: setting long slot failed\n",
 1977                             sc->sc_dev.dv_xname);
 1978                         return (ENXIO);
 1979                 }
 1980         }
 1981 
 1982         return (0);
 1983 }
 1984 
 1985 void
 1986 malo_update_slot(struct ieee80211com *ic)
 1987 {
 1988         struct malo_softc *sc = ic->ic_if.if_softc;
 1989 
 1990         malo_set_slot(sc);
 1991 
 1992         if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
 1993                 /* TODO */
 1994         }
 1995 }
 1996 
 1997 #ifdef MALO_DEBUG
 1998 void
 1999 malo_hexdump(void *buf, int len)
 2000 {
 2001         u_char b[16];
 2002         int i, j, l;
 2003 
 2004         for (i = 0; i < len; i += l) {
 2005                 printf("%4i:", i);
 2006                 l = min(sizeof(b), len - i);
 2007                 bcopy(buf + i, b, l);
 2008                 
 2009                 for (j = 0; j < sizeof(b); j++) {
 2010                         if (j % 2 == 0)
 2011                                 printf(" ");
 2012                         if (j % 8 == 0)
 2013                                 printf(" ");
 2014                         if (j < l)
 2015                                 printf("%02x", (int)b[j]);
 2016                         else
 2017                                 printf("  ");
 2018                 }
 2019                 printf("  |");
 2020                 for (j = 0; j < l; j++) {
 2021                         if (b[j] >= 0x20 && b[j] <= 0x7e)
 2022                                 printf("%c", b[j]);
 2023                         else
 2024                                 printf(".");
 2025                 }
 2026                 printf("|\n");
 2027         }
 2028 }
 2029 #endif
 2030 
 2031 static char *
 2032 malo_cmd_string(uint16_t cmd)
 2033 {
 2034         int i;
 2035         static char cmd_buf[16];
 2036         static const struct {
 2037                 uint16_t         cmd_code;
 2038                 char            *cmd_string;
 2039         } cmds[] = {
 2040                 { MALO_CMD_GET_HW_SPEC,         "GetHwSpecifications"   },
 2041                 { MALO_CMD_SET_RADIO,           "SetRadio"              },
 2042                 { MALO_CMD_SET_TXPOWER,         "SetTxPower"            },
 2043                 { MALO_CMD_SET_ANTENNA,         "SetAntenna"            },
 2044                 { MALO_CMD_SET_PRESCAN,         "SetPrescan"            },
 2045                 { MALO_CMD_SET_POSTSCAN,        "SetPostscan"           },
 2046                 { MALO_CMD_SET_CHANNEL,         "SetChannel"            },
 2047                 { MALO_CMD_SET_RTS,             "SetRTS"                },
 2048         };
 2049 
 2050         for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++)
 2051                 if ((letoh16(cmd) & 0x7fff) == cmds[i].cmd_code)
 2052                         return (cmds[i].cmd_string);
 2053 
 2054         snprintf(cmd_buf, sizeof(cmd_buf), "unknown %#x", cmd);
 2055         return (cmd_buf);
 2056 }
 2057 
 2058 static char *
 2059 malo_cmd_string_result(uint16_t result)
 2060 {
 2061         int i;
 2062         static const struct {
 2063                 uint16_t         result_code;
 2064                 char            *result_string;
 2065         } results[] = {
 2066                 { MALO_CMD_RESULT_OK,           "OK"            },
 2067                 { MALO_CMD_RESULT_ERROR,        "general error" },
 2068                 { MALO_CMD_RESULT_NOSUPPORT,    "not supported" },
 2069                 { MALO_CMD_RESULT_PENDING,      "pending"       },
 2070                 { MALO_CMD_RESULT_BUSY,         "ignored"       },
 2071                 { MALO_CMD_RESULT_PARTIALDATA,  "incomplete"    },
 2072         };
 2073 
 2074         for (i = 0; i < sizeof(results) / sizeof(results[0]); i++)
 2075                 if (letoh16(result) == results[i].result_code)
 2076                         return (results[i].result_string);
 2077 
 2078         return ("unknown");
 2079 }
 2080 
 2081 int
 2082 malo_cmd_get_spec(struct malo_softc *sc)
 2083 {
 2084         struct malo_cmdheader *hdr = sc->sc_cmd_mem;
 2085         struct malo_hw_spec *spec;
 2086 
 2087         hdr->cmd = htole16(MALO_CMD_GET_HW_SPEC);
 2088         hdr->size = htole16(sizeof(*hdr) + sizeof(*spec));
 2089         hdr->seqnum = htole16(42);      /* the one and only */
 2090         hdr->result = 0;
 2091         spec = (struct malo_hw_spec *)(hdr + 1);
 2092 
 2093         bzero(spec, sizeof(*spec));
 2094         memset(spec->PermanentAddress, 0xff, ETHER_ADDR_LEN);
 2095         spec->CookiePtr = htole32(sc->sc_cookie_dmaaddr);
 2096 
 2097         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 2098             BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
 2099 
 2100         if (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr) != 0)
 2101                 return (ETIMEDOUT);
 2102 
 2103         /* XXX get the data from the buffer and feed it to ieee80211 */
 2104         DPRINTF(("%s: get_hw_spec: V%x R%x, #WCB %d, #Mcast %d, Regcode %d, "
 2105             "#Ant %d\n", sc->sc_dev.dv_xname, htole16(spec->HwVersion),
 2106             htole32(spec->FWReleaseNumber), htole16(spec->NumOfWCB),
 2107             htole16(spec->NumOfMCastAdr), htole16(spec->RegionCode),
 2108             htole16(spec->NumberOfAntenna)));
 2109 
 2110         /* tell the DMA engine where our rings are */
 2111         malo_mem_write4(sc, letoh32(spec->RxPdRdPtr) & 0xffff,
 2112             sc->sc_rxring.physaddr);
 2113         malo_mem_write4(sc, letoh32(spec->RxPdWrPtr) & 0xffff,
 2114             sc->sc_rxring.physaddr);
 2115         malo_mem_write4(sc, letoh32(spec->WcbBase0) & 0xffff,
 2116             sc->sc_txring.physaddr);
 2117 
 2118         /* save DMA RX pointers for later use */
 2119         sc->sc_RxPdRdPtr = letoh32(spec->RxPdRdPtr) & 0xffff;
 2120         sc->sc_RxPdWrPtr = letoh32(spec->RxPdWrPtr) & 0xffff;
 2121 
 2122         return (0);
 2123 }
 2124 
 2125 int
 2126 malo_cmd_set_wepkey(struct malo_softc *sc, struct ieee80211_key *k,
 2127     uint16_t k_index)
 2128 {
 2129         struct malo_cmdheader *hdr = sc->sc_cmd_mem;
 2130         struct malo_cmd_wepkey *body;
 2131 
 2132         hdr->cmd = htole16(MALO_CMD_SET_WEPKEY);
 2133         hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
 2134         hdr->seqnum = 1;
 2135         hdr->result = 0;
 2136         body = (struct malo_cmd_wepkey *)(hdr + 1);
 2137 
 2138         bzero(body, sizeof(*body));
 2139         body->action = htole16(1);
 2140         body->flags = 0;
 2141         body->index = k_index;
 2142         body->len = k->k_len;
 2143         memcpy(body->value, k->k_key, k->k_len);
 2144 
 2145         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 2146             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 2147 
 2148         return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
 2149 }
 2150 
 2151 int
 2152 malo_cmd_set_prescan(struct malo_softc *sc)
 2153 {
 2154         struct malo_cmdheader *hdr = sc->sc_cmd_mem;
 2155 
 2156         hdr->cmd = htole16(MALO_CMD_SET_PRESCAN);
 2157         hdr->size = htole16(sizeof(*hdr));
 2158         hdr->seqnum = 1;
 2159         hdr->result = 0;
 2160 
 2161         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 2162             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 2163 
 2164         return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
 2165 }
 2166 
 2167 int
 2168 malo_cmd_set_postscan(struct malo_softc *sc, uint8_t *macaddr, uint8_t ibsson)
 2169 {
 2170         struct malo_cmdheader *hdr = sc->sc_cmd_mem;
 2171         struct malo_cmd_postscan *body;
 2172 
 2173         hdr->cmd = htole16(MALO_CMD_SET_POSTSCAN);
 2174         hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
 2175         hdr->seqnum = 1;
 2176         hdr->result = 0;
 2177         body = (struct malo_cmd_postscan *)(hdr + 1);
 2178 
 2179         bzero(body, sizeof(*body));
 2180         memcpy(&body->bssid, macaddr, ETHER_ADDR_LEN);
 2181         body->isibss = htole32(ibsson);
 2182 
 2183         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 2184             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 2185 
 2186         return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
 2187 }
 2188 
 2189 int
 2190 malo_cmd_set_channel(struct malo_softc *sc, uint8_t channel)
 2191 {
 2192         struct malo_cmdheader *hdr = sc->sc_cmd_mem;
 2193         struct malo_cmd_channel *body;
 2194 
 2195         hdr->cmd = htole16(MALO_CMD_SET_CHANNEL);
 2196         hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
 2197         hdr->seqnum = 1;
 2198         hdr->result = 0;
 2199         body = (struct malo_cmd_channel *)(hdr + 1);
 2200 
 2201         bzero(body, sizeof(*body));
 2202         body->action = htole16(1);
 2203         body->channel = channel;
 2204 
 2205         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 2206             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 2207 
 2208         return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
 2209 }
 2210 
 2211 int
 2212 malo_cmd_set_antenna(struct malo_softc *sc, uint16_t antenna)
 2213 {
 2214         struct malo_cmdheader *hdr = sc->sc_cmd_mem;
 2215         struct malo_cmd_antenna *body;
 2216 
 2217         hdr->cmd = htole16(MALO_CMD_SET_ANTENNA);
 2218         hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
 2219         hdr->seqnum = 1;
 2220         hdr->result = 0;
 2221         body = (struct malo_cmd_antenna *)(hdr + 1);
 2222 
 2223         bzero(body, sizeof(*body));
 2224         body->action = htole16(antenna);
 2225         if (antenna == 1)
 2226                 body->mode = htole16(0xffff);
 2227         else
 2228                 body->mode = htole16(2);
 2229 
 2230         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 2231             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 2232 
 2233         return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
 2234 }
 2235 
 2236 int
 2237 malo_cmd_set_radio(struct malo_softc *sc, uint16_t enable,
 2238     uint16_t preamble_mode)
 2239 {
 2240         struct malo_cmdheader *hdr = sc->sc_cmd_mem;
 2241         struct malo_cmd_radio *body;
 2242 
 2243         hdr->cmd = htole16(MALO_CMD_SET_RADIO);
 2244         hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
 2245         hdr->seqnum = 1;
 2246         hdr->result = 0;
 2247         body = (struct malo_cmd_radio *)(hdr + 1);
 2248 
 2249         bzero(body, sizeof(*body));
 2250         body->action = htole16(1);
 2251         body->preamble_mode = htole16(preamble_mode);
 2252         body->enable = htole16(enable);
 2253 
 2254         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 2255             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 2256 
 2257         return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
 2258 }
 2259 
 2260 int
 2261 malo_cmd_set_aid(struct malo_softc *sc, uint8_t *bssid, uint16_t associd)
 2262 {
 2263         struct malo_cmdheader *hdr = sc->sc_cmd_mem;
 2264         struct malo_cmd_aid *body;
 2265 
 2266         hdr->cmd = htole16(MALO_CMD_SET_AID);
 2267         hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
 2268         hdr->seqnum = 1;
 2269         hdr->result = 0;
 2270         body = (struct malo_cmd_aid *)(hdr + 1);
 2271 
 2272         bzero(body, sizeof(*body));
 2273         body->associd = htole16(associd);
 2274         memcpy(&body->macaddr[0], bssid, IEEE80211_ADDR_LEN);
 2275 
 2276         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 2277             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 2278 
 2279         return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
 2280 }
 2281 
 2282 int
 2283 malo_cmd_set_txpower(struct malo_softc *sc, unsigned int powerlevel)
 2284 {
 2285         struct malo_cmdheader *hdr = sc->sc_cmd_mem;
 2286         struct malo_cmd_txpower *body;
 2287 
 2288         hdr->cmd = htole16(MALO_CMD_SET_TXPOWER);
 2289         hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
 2290         hdr->seqnum = 1;
 2291         hdr->result = 0;
 2292         body = (struct malo_cmd_txpower *)(hdr + 1);
 2293 
 2294         bzero(body, sizeof(*body));
 2295         body->action = htole16(1);
 2296         if (powerlevel >= 0 && powerlevel < 30)
 2297                 body->supportpowerlvl = htole16(5);     /* LOW */
 2298         else if (powerlevel >= 30 && powerlevel < 60)
 2299                 body->supportpowerlvl = htole16(10);    /* MEDIUM */
 2300         else
 2301                 body->supportpowerlvl = htole16(15);    /* HIGH */
 2302 
 2303         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 2304             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 2305 
 2306         return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
 2307 }
 2308 
 2309 int
 2310 malo_cmd_set_rts(struct malo_softc *sc, uint32_t threshold)
 2311 {
 2312         struct malo_cmdheader *hdr = sc->sc_cmd_mem;
 2313 
 2314         hdr->cmd = htole16(MALO_CMD_SET_RTS);
 2315         hdr->size = htole16(sizeof(*hdr) + sizeof(threshold));
 2316         hdr->seqnum = 1;
 2317         hdr->result = 0;
 2318 
 2319         *(uint32_t *)(hdr + 1) = htole32(threshold);
 2320 
 2321         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 2322             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 2323 
 2324         return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
 2325 }
 2326 
 2327 int
 2328 malo_cmd_set_slot(struct malo_softc *sc, uint8_t slot)
 2329 {
 2330         struct malo_cmdheader *hdr = sc->sc_cmd_mem;
 2331         struct malo_cmd_slot *body;
 2332 
 2333         hdr->cmd = htole16(MALO_CMD_SET_SLOT);
 2334         hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
 2335         hdr->seqnum = 1;
 2336         hdr->result = 0;
 2337         body = (struct malo_cmd_slot *)(hdr + 1);
 2338 
 2339         bzero(body, sizeof(*body));
 2340         body->action = htole16(1);
 2341         body->slot = slot;
 2342 
 2343         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 2344             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 2345 
 2346         return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
 2347 }
 2348 
 2349 int
 2350 malo_cmd_set_rate(struct malo_softc *sc, uint8_t rate)
 2351 {
 2352         struct ieee80211com *ic = &sc->sc_ic;
 2353         struct malo_cmdheader *hdr = sc->sc_cmd_mem;
 2354         struct malo_cmd_rate *body;
 2355         int i;
 2356 
 2357         hdr->cmd = htole16(MALO_CMD_SET_RATE);
 2358         hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
 2359         hdr->seqnum = 1;
 2360         hdr->result = 0;
 2361         body = (struct malo_cmd_rate *)(hdr + 1);
 2362 
 2363         bzero(body, sizeof(*body));
 2364 
 2365         if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
 2366                 /* TODO */
 2367         } else {
 2368                 body->aprates[0] = 2;
 2369                 body->aprates[1] = 4;
 2370                 body->aprates[2] = 11;
 2371                 body->aprates[3] = 22;
 2372                 if (ic->ic_curmode == IEEE80211_MODE_11G) {
 2373                         body->aprates[4] = 0;
 2374                         body->aprates[5] = 12;
 2375                         body->aprates[6] = 18;
 2376                         body->aprates[7] = 24;
 2377                         body->aprates[8] = 36;
 2378                         body->aprates[9] = 48;
 2379                         body->aprates[10] = 72;
 2380                         body->aprates[11] = 96;
 2381                         body->aprates[12] = 108;
 2382                 }
 2383         }
 2384 
 2385         if (rate != 0) {
 2386                 /* fixed rate */
 2387                 for (i = 0; i < 13; i++) {
 2388                         if (body->aprates[i] == rate) {
 2389                                 body->rateindex = i;
 2390                                 body->dataratetype = 1;
 2391                                 break;
 2392                         }
 2393                 }
 2394         }
 2395 
 2396         bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
 2397             BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 2398 
 2399         return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
 2400 }

/* [<][>][^][v][top][bottom][index][help] */