The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/malo.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: a1bae743666ecdfb14f62bfade7a7d5b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.