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/ipw/if_ipw.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 /*      $FreeBSD: releng/8.4/sys/dev/ipw/if_ipw.c 234571 2012-04-22 09:19:19Z bschmidt $        */
    2 
    3 /*-
    4  * Copyright (c) 2004-2006
    5  *      Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
    6  * Copyright (c) 2006 Sam Leffler, Errno Consulting
    7  * Copyright (c) 2007 Andrew Thompson <thompsa@FreeBSD.org>
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice unmodified, this list of conditions, and the following
   14  *    disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD: releng/8.4/sys/dev/ipw/if_ipw.c 234571 2012-04-22 09:19:19Z bschmidt $");
   34 
   35 /*-
   36  * Intel(R) PRO/Wireless 2100 MiniPCI driver
   37  * http://www.intel.com/network/connectivity/products/wireless/prowireless_mobile.htm
   38  */
   39 
   40 #include <sys/param.h>
   41 #include <sys/sysctl.h>
   42 #include <sys/sockio.h>
   43 #include <sys/mbuf.h>
   44 #include <sys/kernel.h>
   45 #include <sys/socket.h>
   46 #include <sys/systm.h>
   47 #include <sys/malloc.h>
   48 #include <sys/queue.h>
   49 #include <sys/taskqueue.h>
   50 #include <sys/module.h>
   51 #include <sys/bus.h>
   52 #include <sys/endian.h>
   53 #include <sys/linker.h>
   54 #include <sys/firmware.h>
   55 
   56 #include <machine/bus.h>
   57 #include <machine/resource.h>
   58 #include <sys/rman.h>
   59 
   60 #include <dev/pci/pcireg.h>
   61 #include <dev/pci/pcivar.h>
   62 
   63 #include <net/bpf.h>
   64 #include <net/if.h>
   65 #include <net/if_arp.h>
   66 #include <net/ethernet.h>
   67 #include <net/if_dl.h>
   68 #include <net/if_media.h>
   69 #include <net/if_types.h>
   70 
   71 #include <net80211/ieee80211_var.h>
   72 #include <net80211/ieee80211_radiotap.h>
   73 
   74 #include <netinet/in.h>
   75 #include <netinet/in_systm.h>
   76 #include <netinet/in_var.h>
   77 #include <netinet/ip.h>
   78 #include <netinet/if_ether.h>
   79 
   80 #include <dev/ipw/if_ipwreg.h>
   81 #include <dev/ipw/if_ipwvar.h>
   82 
   83 #define IPW_DEBUG
   84 #ifdef IPW_DEBUG
   85 #define DPRINTF(x)      do { if (ipw_debug > 0) printf x; } while (0)
   86 #define DPRINTFN(n, x)  do { if (ipw_debug >= (n)) printf x; } while (0)
   87 int ipw_debug = 0;
   88 SYSCTL_INT(_debug, OID_AUTO, ipw, CTLFLAG_RW, &ipw_debug, 0, "ipw debug level");
   89 #else
   90 #define DPRINTF(x)
   91 #define DPRINTFN(n, x)
   92 #endif
   93 
   94 MODULE_DEPEND(ipw, pci,  1, 1, 1);
   95 MODULE_DEPEND(ipw, wlan, 1, 1, 1);
   96 MODULE_DEPEND(ipw, firmware, 1, 1, 1);
   97 
   98 struct ipw_ident {
   99         uint16_t        vendor;
  100         uint16_t        device;
  101         const char      *name;
  102 };
  103 
  104 static const struct ipw_ident ipw_ident_table[] = {
  105         { 0x8086, 0x1043, "Intel(R) PRO/Wireless 2100 MiniPCI" },
  106 
  107         { 0, 0, NULL }
  108 };
  109 
  110 static struct ieee80211vap *ipw_vap_create(struct ieee80211com *,
  111                     const char name[IFNAMSIZ], int unit, int opmode, int flags,
  112                     const uint8_t bssid[IEEE80211_ADDR_LEN],
  113                     const uint8_t mac[IEEE80211_ADDR_LEN]);
  114 static void     ipw_vap_delete(struct ieee80211vap *);
  115 static int      ipw_dma_alloc(struct ipw_softc *);
  116 static void     ipw_release(struct ipw_softc *);
  117 static void     ipw_media_status(struct ifnet *, struct ifmediareq *);
  118 static int      ipw_newstate(struct ieee80211vap *, enum ieee80211_state, int);
  119 static uint16_t ipw_read_prom_word(struct ipw_softc *, uint8_t);
  120 static void     ipw_rx_cmd_intr(struct ipw_softc *, struct ipw_soft_buf *);
  121 static void     ipw_rx_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *);
  122 static void     ipw_rx_data_intr(struct ipw_softc *, struct ipw_status *,
  123                     struct ipw_soft_bd *, struct ipw_soft_buf *);
  124 static void     ipw_rx_intr(struct ipw_softc *);
  125 static void     ipw_release_sbd(struct ipw_softc *, struct ipw_soft_bd *);
  126 static void     ipw_tx_intr(struct ipw_softc *);
  127 static void     ipw_intr(void *);
  128 static void     ipw_dma_map_addr(void *, bus_dma_segment_t *, int, int);
  129 static const char * ipw_cmdname(int);
  130 static int      ipw_cmd(struct ipw_softc *, uint32_t, void *, uint32_t);
  131 static int      ipw_tx_start(struct ifnet *, struct mbuf *,
  132                     struct ieee80211_node *);
  133 static int      ipw_raw_xmit(struct ieee80211_node *, struct mbuf *,
  134                     const struct ieee80211_bpf_params *);
  135 static void     ipw_start(struct ifnet *);
  136 static void     ipw_start_locked(struct ifnet *);
  137 static void     ipw_watchdog(void *);
  138 static int      ipw_ioctl(struct ifnet *, u_long, caddr_t);
  139 static void     ipw_stop_master(struct ipw_softc *);
  140 static int      ipw_enable(struct ipw_softc *);
  141 static int      ipw_disable(struct ipw_softc *);
  142 static int      ipw_reset(struct ipw_softc *);
  143 static int      ipw_load_ucode(struct ipw_softc *, const char *, int);
  144 static int      ipw_load_firmware(struct ipw_softc *, const char *, int);
  145 static int      ipw_config(struct ipw_softc *);
  146 static void     ipw_assoc(struct ieee80211com *, struct ieee80211vap *);
  147 static void     ipw_disassoc(struct ieee80211com *, struct ieee80211vap *);
  148 static void     ipw_init_task(void *, int);
  149 static void     ipw_init(void *);
  150 static void     ipw_init_locked(struct ipw_softc *);
  151 static void     ipw_stop(void *);
  152 static void     ipw_stop_locked(struct ipw_softc *);
  153 static int      ipw_sysctl_stats(SYSCTL_HANDLER_ARGS);
  154 static int      ipw_sysctl_radio(SYSCTL_HANDLER_ARGS);
  155 static uint32_t ipw_read_table1(struct ipw_softc *, uint32_t);
  156 static void     ipw_write_table1(struct ipw_softc *, uint32_t, uint32_t);
  157 #if 0
  158 static int      ipw_read_table2(struct ipw_softc *, uint32_t, void *,
  159                     uint32_t *);
  160 static void     ipw_read_mem_1(struct ipw_softc *, bus_size_t, uint8_t *,
  161                     bus_size_t);
  162 #endif
  163 static void     ipw_write_mem_1(struct ipw_softc *, bus_size_t,
  164                     const uint8_t *, bus_size_t);
  165 static int      ipw_scan(struct ipw_softc *);
  166 static void     ipw_scan_start(struct ieee80211com *);
  167 static void     ipw_scan_end(struct ieee80211com *);
  168 static void     ipw_set_channel(struct ieee80211com *);
  169 static void     ipw_scan_curchan(struct ieee80211_scan_state *,
  170                     unsigned long maxdwell);
  171 static void     ipw_scan_mindwell(struct ieee80211_scan_state *);
  172 
  173 static int ipw_probe(device_t);
  174 static int ipw_attach(device_t);
  175 static int ipw_detach(device_t);
  176 static int ipw_shutdown(device_t);
  177 static int ipw_suspend(device_t);
  178 static int ipw_resume(device_t);
  179 
  180 static device_method_t ipw_methods[] = {
  181         /* Device interface */
  182         DEVMETHOD(device_probe,         ipw_probe),
  183         DEVMETHOD(device_attach,        ipw_attach),
  184         DEVMETHOD(device_detach,        ipw_detach),
  185         DEVMETHOD(device_shutdown,      ipw_shutdown),
  186         DEVMETHOD(device_suspend,       ipw_suspend),
  187         DEVMETHOD(device_resume,        ipw_resume),
  188 
  189         { 0, 0 }
  190 };
  191 
  192 static driver_t ipw_driver = {
  193         "ipw",
  194         ipw_methods,
  195         sizeof (struct ipw_softc)
  196 };
  197 
  198 static devclass_t ipw_devclass;
  199 
  200 DRIVER_MODULE(ipw, pci, ipw_driver, ipw_devclass, 0, 0);
  201 
  202 static int
  203 ipw_probe(device_t dev)
  204 {
  205         const struct ipw_ident *ident;
  206 
  207         for (ident = ipw_ident_table; ident->name != NULL; ident++) {
  208                 if (pci_get_vendor(dev) == ident->vendor &&
  209                     pci_get_device(dev) == ident->device) {
  210                         device_set_desc(dev, ident->name);
  211                         return 0;
  212                 }
  213         }
  214         return ENXIO;
  215 }
  216 
  217 /* Base Address Register */
  218 #define IPW_PCI_BAR0    0x10
  219 
  220 static int
  221 ipw_attach(device_t dev)
  222 {
  223         struct ipw_softc *sc = device_get_softc(dev);
  224         struct ifnet *ifp;
  225         struct ieee80211com *ic;
  226         struct ieee80211_channel *c;
  227         uint16_t val;
  228         int error, i;
  229         uint8_t macaddr[IEEE80211_ADDR_LEN];
  230 
  231         sc->sc_dev = dev;
  232 
  233         mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
  234             MTX_DEF | MTX_RECURSE);
  235 
  236         TASK_INIT(&sc->sc_init_task, 0, ipw_init_task, sc);
  237         callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0);
  238 
  239         if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
  240                 device_printf(dev, "chip is in D%d power mode "
  241                     "-- setting to D0\n", pci_get_powerstate(dev));
  242                 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
  243         }
  244 
  245         pci_write_config(dev, 0x41, 0, 1);
  246 
  247         /* enable bus-mastering */
  248         pci_enable_busmaster(dev);
  249 
  250         sc->mem_rid = IPW_PCI_BAR0;
  251         sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
  252             RF_ACTIVE);
  253         if (sc->mem == NULL) {
  254                 device_printf(dev, "could not allocate memory resource\n");
  255                 goto fail;
  256         }
  257 
  258         sc->sc_st = rman_get_bustag(sc->mem);
  259         sc->sc_sh = rman_get_bushandle(sc->mem);
  260 
  261         sc->irq_rid = 0;
  262         sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
  263             RF_ACTIVE | RF_SHAREABLE);
  264         if (sc->irq == NULL) {
  265                 device_printf(dev, "could not allocate interrupt resource\n");
  266                 goto fail1;
  267         }
  268 
  269         if (ipw_reset(sc) != 0) {
  270                 device_printf(dev, "could not reset adapter\n");
  271                 goto fail2;
  272         }
  273 
  274         if (ipw_dma_alloc(sc) != 0) {
  275                 device_printf(dev, "could not allocate DMA resources\n");
  276                 goto fail2;
  277         }
  278 
  279         ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
  280         if (ifp == NULL) {
  281                 device_printf(dev, "can not if_alloc()\n");
  282                 goto fail3;
  283         }
  284         ic = ifp->if_l2com;
  285 
  286         ifp->if_softc = sc;
  287         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
  288         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  289         ifp->if_init = ipw_init;
  290         ifp->if_ioctl = ipw_ioctl;
  291         ifp->if_start = ipw_start;
  292         IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
  293         ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
  294         IFQ_SET_READY(&ifp->if_snd);
  295 
  296         ic->ic_ifp = ifp;
  297         ic->ic_opmode = IEEE80211_M_STA;
  298         ic->ic_phytype = IEEE80211_T_DS;
  299 
  300         /* set device capabilities */
  301         ic->ic_caps =
  302                   IEEE80211_C_STA               /* station mode supported */
  303                 | IEEE80211_C_IBSS              /* IBSS mode supported */
  304                 | IEEE80211_C_MONITOR           /* monitor mode supported */
  305                 | IEEE80211_C_PMGT              /* power save supported */
  306                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
  307                 | IEEE80211_C_WPA               /* 802.11i supported */
  308                 ;
  309 
  310         /* read MAC address from EEPROM */
  311         val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 0);
  312         macaddr[0] = val >> 8;
  313         macaddr[1] = val & 0xff;
  314         val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 1);
  315         macaddr[2] = val >> 8;
  316         macaddr[3] = val & 0xff;
  317         val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 2);
  318         macaddr[4] = val >> 8;
  319         macaddr[5] = val & 0xff;
  320 
  321         /* set supported .11b channels (read from EEPROM) */
  322         if ((val = ipw_read_prom_word(sc, IPW_EEPROM_CHANNEL_LIST)) == 0)
  323                 val = 0x7ff; /* default to channels 1-11 */
  324         val <<= 1;
  325         for (i = 1; i < 16; i++) {
  326                 if (val & (1 << i)) {
  327                         c = &ic->ic_channels[ic->ic_nchans++];
  328                         c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
  329                         c->ic_flags = IEEE80211_CHAN_B;
  330                         c->ic_ieee = i;
  331                 }
  332         }
  333 
  334         /* check support for radio transmitter switch in EEPROM */
  335         if (!(ipw_read_prom_word(sc, IPW_EEPROM_RADIO) & 8))
  336                 sc->flags |= IPW_FLAG_HAS_RADIO_SWITCH;
  337 
  338         ieee80211_ifattach(ic, macaddr);
  339         ic->ic_scan_start = ipw_scan_start;
  340         ic->ic_scan_end = ipw_scan_end;
  341         ic->ic_set_channel = ipw_set_channel;
  342         ic->ic_scan_curchan = ipw_scan_curchan;
  343         ic->ic_scan_mindwell = ipw_scan_mindwell;
  344         ic->ic_raw_xmit = ipw_raw_xmit;
  345 
  346         ic->ic_vap_create = ipw_vap_create;
  347         ic->ic_vap_delete = ipw_vap_delete;
  348 
  349         ieee80211_radiotap_attach(ic,
  350             &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
  351                 IPW_TX_RADIOTAP_PRESENT,
  352             &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
  353                 IPW_RX_RADIOTAP_PRESENT);
  354 
  355         /*
  356          * Add a few sysctl knobs.
  357          */
  358         SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
  359             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "radio",
  360             CTLTYPE_INT | CTLFLAG_RD, sc, 0, ipw_sysctl_radio, "I",
  361             "radio transmitter switch state (0=off, 1=on)");
  362 
  363         SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
  364             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "stats",
  365             CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, ipw_sysctl_stats, "S",
  366             "statistics");
  367 
  368         /*
  369          * Hook our interrupt after all initialization is complete.
  370          */
  371         error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
  372             NULL, ipw_intr, sc, &sc->sc_ih);
  373         if (error != 0) {
  374                 device_printf(dev, "could not set up interrupt\n");
  375                 goto fail4;
  376         }
  377 
  378         if (bootverbose)
  379                 ieee80211_announce(ic);
  380 
  381         return 0;
  382 fail4:
  383         if_free(ifp);
  384 fail3:
  385         ipw_release(sc);
  386 fail2:
  387         bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
  388 fail1:
  389         bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
  390 fail:
  391         mtx_destroy(&sc->sc_mtx);
  392         return ENXIO;
  393 }
  394 
  395 static int
  396 ipw_detach(device_t dev)
  397 {
  398         struct ipw_softc *sc = device_get_softc(dev);
  399         struct ifnet *ifp = sc->sc_ifp;
  400         struct ieee80211com *ic = ifp->if_l2com;
  401 
  402         ieee80211_draintask(ic, &sc->sc_init_task);
  403         ipw_stop(sc);
  404 
  405         ieee80211_ifdetach(ic);
  406 
  407         callout_drain(&sc->sc_wdtimer);
  408 
  409         ipw_release(sc);
  410 
  411         bus_teardown_intr(dev, sc->irq, sc->sc_ih);
  412         bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
  413 
  414         bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
  415 
  416         if_free(ifp);
  417 
  418         if (sc->sc_firmware != NULL) {
  419                 firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD);
  420                 sc->sc_firmware = NULL;
  421         }
  422 
  423         mtx_destroy(&sc->sc_mtx);
  424 
  425         return 0;
  426 }
  427 
  428 static struct ieee80211vap *
  429 ipw_vap_create(struct ieee80211com *ic,
  430         const char name[IFNAMSIZ], int unit, int opmode, int flags,
  431         const uint8_t bssid[IEEE80211_ADDR_LEN],
  432         const uint8_t mac[IEEE80211_ADDR_LEN])
  433 {
  434         struct ifnet *ifp = ic->ic_ifp;
  435         struct ipw_softc *sc = ifp->if_softc;
  436         struct ipw_vap *ivp;
  437         struct ieee80211vap *vap;
  438         const struct firmware *fp;
  439         const struct ipw_firmware_hdr *hdr;
  440         const char *imagename;
  441 
  442         if (!TAILQ_EMPTY(&ic->ic_vaps))         /* only one at a time */
  443                 return NULL;
  444 
  445         switch (opmode) {
  446         case IEEE80211_M_STA:
  447                 imagename = "ipw_bss";
  448                 break;
  449         case IEEE80211_M_IBSS:
  450                 imagename = "ipw_ibss";
  451                 break;
  452         case IEEE80211_M_MONITOR:
  453                 imagename = "ipw_monitor";
  454                 break;
  455         default:
  456                 return NULL;
  457         }
  458 
  459         /*
  460          * Load firmware image using the firmware(9) subsystem.  Doing
  461          * this unlocked is ok since we're single-threaded by the
  462          * 802.11 layer.
  463          */
  464         if (sc->sc_firmware == NULL ||
  465             strcmp(sc->sc_firmware->name, imagename) != 0) {
  466                 if (sc->sc_firmware != NULL)
  467                         firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD);
  468                 sc->sc_firmware = firmware_get(imagename);
  469         }
  470         if (sc->sc_firmware == NULL) {
  471                 device_printf(sc->sc_dev,
  472                     "could not load firmware image '%s'\n", imagename);
  473                 return NULL;
  474         }
  475         fp = sc->sc_firmware;
  476         if (fp->datasize < sizeof *hdr) {
  477                 device_printf(sc->sc_dev,
  478                     "firmware image too short %zu\n", fp->datasize);
  479                 firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD);
  480                 sc->sc_firmware = NULL;
  481                 return NULL;
  482         }
  483         hdr = (const struct ipw_firmware_hdr *)fp->data;
  484         if (fp->datasize < sizeof *hdr + le32toh(hdr->mainsz) +
  485             le32toh(hdr->ucodesz)) {
  486                 device_printf(sc->sc_dev,
  487                     "firmware image too short %zu\n", fp->datasize);
  488                 firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD);
  489                 sc->sc_firmware = NULL;
  490                 return NULL;
  491         }
  492 
  493         ivp = (struct ipw_vap *) malloc(sizeof(struct ipw_vap),
  494             M_80211_VAP, M_NOWAIT | M_ZERO);
  495         if (ivp == NULL)
  496                 return NULL;
  497         vap = &ivp->vap;
  498 
  499         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
  500         /* override with driver methods */
  501         ivp->newstate = vap->iv_newstate;
  502         vap->iv_newstate = ipw_newstate;
  503 
  504         /* complete setup */
  505         ieee80211_vap_attach(vap, ieee80211_media_change, ipw_media_status);
  506         ic->ic_opmode = opmode;
  507         return vap;
  508 }
  509 
  510 static void
  511 ipw_vap_delete(struct ieee80211vap *vap)
  512 {
  513         struct ipw_vap *ivp = IPW_VAP(vap);
  514 
  515         ieee80211_vap_detach(vap);
  516         free(ivp, M_80211_VAP);
  517 }
  518 
  519 static int
  520 ipw_dma_alloc(struct ipw_softc *sc)
  521 {
  522         struct ipw_soft_bd *sbd;
  523         struct ipw_soft_hdr *shdr;
  524         struct ipw_soft_buf *sbuf;
  525         bus_addr_t physaddr;
  526         int error, i;
  527 
  528         /*
  529          * Allocate parent DMA tag for subsequent allocations.
  530          */
  531         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
  532             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
  533             BUS_SPACE_MAXSIZE_32BIT, BUS_SPACE_UNRESTRICTED,
  534             BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL, &sc->parent_dmat);
  535         if (error != 0) {
  536                 device_printf(sc->sc_dev, "could not create parent DMA tag\n");
  537                 goto fail;
  538         }
  539 
  540         /*
  541          * Allocate and map tx ring.
  542          */
  543         error = bus_dma_tag_create(sc->parent_dmat, 4, 0, BUS_SPACE_MAXADDR_32BIT,
  544             BUS_SPACE_MAXADDR, NULL, NULL, IPW_TBD_SZ, 1, IPW_TBD_SZ, 0, NULL,
  545             NULL, &sc->tbd_dmat);
  546         if (error != 0) {
  547                 device_printf(sc->sc_dev, "could not create tx ring DMA tag\n");
  548                 goto fail;
  549         }
  550 
  551         error = bus_dmamem_alloc(sc->tbd_dmat, (void **)&sc->tbd_list,
  552             BUS_DMA_NOWAIT | BUS_DMA_ZERO, &sc->tbd_map);
  553         if (error != 0) {
  554                 device_printf(sc->sc_dev,
  555                     "could not allocate tx ring DMA memory\n");
  556                 goto fail;
  557         }
  558 
  559         error = bus_dmamap_load(sc->tbd_dmat, sc->tbd_map, sc->tbd_list,
  560             IPW_TBD_SZ, ipw_dma_map_addr, &sc->tbd_phys, 0);
  561         if (error != 0) {
  562                 device_printf(sc->sc_dev, "could not map tx ring DMA memory\n");
  563                 goto fail;
  564         }
  565 
  566         /*
  567          * Allocate and map rx ring.
  568          */
  569         error = bus_dma_tag_create(sc->parent_dmat, 4, 0, BUS_SPACE_MAXADDR_32BIT,
  570             BUS_SPACE_MAXADDR, NULL, NULL, IPW_RBD_SZ, 1, IPW_RBD_SZ, 0, NULL,
  571             NULL, &sc->rbd_dmat);
  572         if (error != 0) {
  573                 device_printf(sc->sc_dev, "could not create rx ring DMA tag\n");
  574                 goto fail;
  575         }
  576 
  577         error = bus_dmamem_alloc(sc->rbd_dmat, (void **)&sc->rbd_list,
  578             BUS_DMA_NOWAIT | BUS_DMA_ZERO, &sc->rbd_map);
  579         if (error != 0) {
  580                 device_printf(sc->sc_dev,
  581                     "could not allocate rx ring DMA memory\n");
  582                 goto fail;
  583         }
  584 
  585         error = bus_dmamap_load(sc->rbd_dmat, sc->rbd_map, sc->rbd_list,
  586             IPW_RBD_SZ, ipw_dma_map_addr, &sc->rbd_phys, 0);
  587         if (error != 0) {
  588                 device_printf(sc->sc_dev, "could not map rx ring DMA memory\n");
  589                 goto fail;
  590         }
  591 
  592         /*
  593          * Allocate and map status ring.
  594          */
  595         error = bus_dma_tag_create(sc->parent_dmat, 4, 0, BUS_SPACE_MAXADDR_32BIT,
  596             BUS_SPACE_MAXADDR, NULL, NULL, IPW_STATUS_SZ, 1, IPW_STATUS_SZ, 0,
  597             NULL, NULL, &sc->status_dmat);
  598         if (error != 0) {
  599                 device_printf(sc->sc_dev,
  600                     "could not create status ring DMA tag\n");
  601                 goto fail;
  602         }
  603 
  604         error = bus_dmamem_alloc(sc->status_dmat, (void **)&sc->status_list,
  605             BUS_DMA_NOWAIT | BUS_DMA_ZERO, &sc->status_map);
  606         if (error != 0) {
  607                 device_printf(sc->sc_dev,
  608                     "could not allocate status ring DMA memory\n");
  609                 goto fail;
  610         }
  611 
  612         error = bus_dmamap_load(sc->status_dmat, sc->status_map,
  613             sc->status_list, IPW_STATUS_SZ, ipw_dma_map_addr, &sc->status_phys,
  614             0);
  615         if (error != 0) {
  616                 device_printf(sc->sc_dev,
  617                     "could not map status ring DMA memory\n");
  618                 goto fail;
  619         }
  620 
  621         /*
  622          * Allocate command DMA map.
  623          */
  624         error = bus_dma_tag_create(sc->parent_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT,
  625             BUS_SPACE_MAXADDR, NULL, NULL, sizeof (struct ipw_cmd), 1,
  626             sizeof (struct ipw_cmd), 0, NULL, NULL, &sc->cmd_dmat);
  627         if (error != 0) {
  628                 device_printf(sc->sc_dev, "could not create command DMA tag\n");
  629                 goto fail;
  630         }
  631 
  632         error = bus_dmamap_create(sc->cmd_dmat, 0, &sc->cmd_map);
  633         if (error != 0) {
  634                 device_printf(sc->sc_dev,
  635                     "could not create command DMA map\n");
  636                 goto fail;
  637         }
  638 
  639         /*
  640          * Allocate headers DMA maps.
  641          */
  642         error = bus_dma_tag_create(sc->parent_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT,
  643             BUS_SPACE_MAXADDR, NULL, NULL, sizeof (struct ipw_hdr), 1,
  644             sizeof (struct ipw_hdr), 0, NULL, NULL, &sc->hdr_dmat);
  645         if (error != 0) {
  646                 device_printf(sc->sc_dev, "could not create header DMA tag\n");
  647                 goto fail;
  648         }
  649 
  650         SLIST_INIT(&sc->free_shdr);
  651         for (i = 0; i < IPW_NDATA; i++) {
  652                 shdr = &sc->shdr_list[i];
  653                 error = bus_dmamap_create(sc->hdr_dmat, 0, &shdr->map);
  654                 if (error != 0) {
  655                         device_printf(sc->sc_dev,
  656                             "could not create header DMA map\n");
  657                         goto fail;
  658                 }
  659                 SLIST_INSERT_HEAD(&sc->free_shdr, shdr, next);
  660         }
  661 
  662         /*
  663          * Allocate tx buffers DMA maps.
  664          */
  665         error = bus_dma_tag_create(sc->parent_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT,
  666             BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, IPW_MAX_NSEG, MCLBYTES, 0,
  667             NULL, NULL, &sc->txbuf_dmat);
  668         if (error != 0) {
  669                 device_printf(sc->sc_dev, "could not create tx DMA tag\n");
  670                 goto fail;
  671         }
  672 
  673         SLIST_INIT(&sc->free_sbuf);
  674         for (i = 0; i < IPW_NDATA; i++) {
  675                 sbuf = &sc->tx_sbuf_list[i];
  676                 error = bus_dmamap_create(sc->txbuf_dmat, 0, &sbuf->map);
  677                 if (error != 0) {
  678                         device_printf(sc->sc_dev,
  679                             "could not create tx DMA map\n");
  680                         goto fail;
  681                 }
  682                 SLIST_INSERT_HEAD(&sc->free_sbuf, sbuf, next);
  683         }
  684 
  685         /*
  686          * Initialize tx ring.
  687          */
  688         for (i = 0; i < IPW_NTBD; i++) {
  689                 sbd = &sc->stbd_list[i];
  690                 sbd->bd = &sc->tbd_list[i];
  691                 sbd->type = IPW_SBD_TYPE_NOASSOC;
  692         }
  693 
  694         /*
  695          * Pre-allocate rx buffers and DMA maps.
  696          */
  697         error = bus_dma_tag_create(sc->parent_dmat, 1, 0, BUS_SPACE_MAXADDR_32BIT,
  698             BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, 1, MCLBYTES, 0, NULL,
  699             NULL, &sc->rxbuf_dmat);
  700         if (error != 0) {
  701                 device_printf(sc->sc_dev, "could not create rx DMA tag\n");
  702                 goto fail;
  703         }
  704 
  705         for (i = 0; i < IPW_NRBD; i++) {
  706                 sbd = &sc->srbd_list[i];
  707                 sbuf = &sc->rx_sbuf_list[i];
  708                 sbd->bd = &sc->rbd_list[i];
  709 
  710                 sbuf->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
  711                 if (sbuf->m == NULL) {
  712                         device_printf(sc->sc_dev,
  713                             "could not allocate rx mbuf\n");
  714                         error = ENOMEM;
  715                         goto fail;
  716                 }
  717 
  718                 error = bus_dmamap_create(sc->rxbuf_dmat, 0, &sbuf->map);
  719                 if (error != 0) {
  720                         device_printf(sc->sc_dev,
  721                             "could not create rx DMA map\n");
  722                         goto fail;
  723                 }
  724 
  725                 error = bus_dmamap_load(sc->rxbuf_dmat, sbuf->map,
  726                     mtod(sbuf->m, void *), MCLBYTES, ipw_dma_map_addr,
  727                     &physaddr, 0);
  728                 if (error != 0) {
  729                         device_printf(sc->sc_dev,
  730                             "could not map rx DMA memory\n");
  731                         goto fail;
  732                 }
  733 
  734                 sbd->type = IPW_SBD_TYPE_DATA;
  735                 sbd->priv = sbuf;
  736                 sbd->bd->physaddr = htole32(physaddr);
  737                 sbd->bd->len = htole32(MCLBYTES);
  738         }
  739 
  740         bus_dmamap_sync(sc->rbd_dmat, sc->rbd_map, BUS_DMASYNC_PREWRITE);
  741 
  742         return 0;
  743 
  744 fail:   ipw_release(sc);
  745         return error;
  746 }
  747 
  748 static void
  749 ipw_release(struct ipw_softc *sc)
  750 {
  751         struct ipw_soft_buf *sbuf;
  752         int i;
  753 
  754         if (sc->parent_dmat != NULL) {
  755                 bus_dma_tag_destroy(sc->parent_dmat);
  756         }
  757 
  758         if (sc->tbd_dmat != NULL) {
  759                 if (sc->stbd_list != NULL) {
  760                         bus_dmamap_unload(sc->tbd_dmat, sc->tbd_map);
  761                         bus_dmamem_free(sc->tbd_dmat, sc->tbd_list,
  762                             sc->tbd_map);
  763                 }
  764                 bus_dma_tag_destroy(sc->tbd_dmat);
  765         }
  766 
  767         if (sc->rbd_dmat != NULL) {
  768                 if (sc->rbd_list != NULL) {
  769                         bus_dmamap_unload(sc->rbd_dmat, sc->rbd_map);
  770                         bus_dmamem_free(sc->rbd_dmat, sc->rbd_list,
  771                             sc->rbd_map);
  772                 }
  773                 bus_dma_tag_destroy(sc->rbd_dmat);
  774         }
  775 
  776         if (sc->status_dmat != NULL) {
  777                 if (sc->status_list != NULL) {
  778                         bus_dmamap_unload(sc->status_dmat, sc->status_map);
  779                         bus_dmamem_free(sc->status_dmat, sc->status_list,
  780                             sc->status_map);
  781                 }
  782                 bus_dma_tag_destroy(sc->status_dmat);
  783         }
  784 
  785         for (i = 0; i < IPW_NTBD; i++)
  786                 ipw_release_sbd(sc, &sc->stbd_list[i]);
  787 
  788         if (sc->cmd_dmat != NULL) {
  789                 bus_dmamap_destroy(sc->cmd_dmat, sc->cmd_map);
  790                 bus_dma_tag_destroy(sc->cmd_dmat);
  791         }
  792 
  793         if (sc->hdr_dmat != NULL) {
  794                 for (i = 0; i < IPW_NDATA; i++)
  795                         bus_dmamap_destroy(sc->hdr_dmat, sc->shdr_list[i].map);
  796                 bus_dma_tag_destroy(sc->hdr_dmat);
  797         }
  798 
  799         if (sc->txbuf_dmat != NULL) {
  800                 for (i = 0; i < IPW_NDATA; i++) {
  801                         bus_dmamap_destroy(sc->txbuf_dmat,
  802                             sc->tx_sbuf_list[i].map);
  803                 }
  804                 bus_dma_tag_destroy(sc->txbuf_dmat);
  805         }
  806 
  807         if (sc->rxbuf_dmat != NULL) {
  808                 for (i = 0; i < IPW_NRBD; i++) {
  809                         sbuf = &sc->rx_sbuf_list[i];
  810                         if (sbuf->m != NULL) {
  811                                 bus_dmamap_sync(sc->rxbuf_dmat, sbuf->map,
  812                                     BUS_DMASYNC_POSTREAD);
  813                                 bus_dmamap_unload(sc->rxbuf_dmat, sbuf->map);
  814                                 m_freem(sbuf->m);
  815                         }
  816                         bus_dmamap_destroy(sc->rxbuf_dmat, sbuf->map);
  817                 }
  818                 bus_dma_tag_destroy(sc->rxbuf_dmat);
  819         }
  820 }
  821 
  822 static int
  823 ipw_shutdown(device_t dev)
  824 {
  825         struct ipw_softc *sc = device_get_softc(dev);
  826 
  827         ipw_stop(sc);
  828 
  829         return 0;
  830 }
  831 
  832 static int
  833 ipw_suspend(device_t dev)
  834 {
  835         struct ipw_softc *sc = device_get_softc(dev);
  836         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
  837 
  838         ieee80211_suspend_all(ic);
  839         return 0;
  840 }
  841 
  842 static int
  843 ipw_resume(device_t dev)
  844 {
  845         struct ipw_softc *sc = device_get_softc(dev);
  846         struct ieee80211com *ic = sc->sc_ifp->if_l2com;
  847 
  848         pci_write_config(dev, 0x41, 0, 1);
  849 
  850         ieee80211_resume_all(ic);
  851         return 0;
  852 }
  853 
  854 static int
  855 ipw_cvtrate(int ipwrate)
  856 {
  857         switch (ipwrate) {
  858         case IPW_RATE_DS1:      return 2;
  859         case IPW_RATE_DS2:      return 4;
  860         case IPW_RATE_DS5:      return 11;
  861         case IPW_RATE_DS11:     return 22;
  862         }
  863         return 0;
  864 }
  865 
  866 /*
  867  * The firmware automatically adapts the transmit speed. We report its current
  868  * value here.
  869  */
  870 static void
  871 ipw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
  872 {
  873         struct ieee80211vap *vap = ifp->if_softc;
  874         struct ieee80211com *ic = vap->iv_ic;
  875         struct ipw_softc *sc = ic->ic_ifp->if_softc;
  876 
  877         /* read current transmission rate from adapter */
  878         vap->iv_bss->ni_txrate = ipw_cvtrate(
  879             ipw_read_table1(sc, IPW_INFO_CURRENT_TX_RATE) & 0xf);
  880         ieee80211_media_status(ifp, imr);
  881 }
  882 
  883 static int
  884 ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
  885 {
  886         struct ipw_vap *ivp = IPW_VAP(vap);
  887         struct ieee80211com *ic = vap->iv_ic;
  888         struct ifnet *ifp = ic->ic_ifp;
  889         struct ipw_softc *sc = ifp->if_softc;
  890         enum ieee80211_state ostate;
  891 
  892         DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__,
  893                 ieee80211_state_name[vap->iv_state],
  894                 ieee80211_state_name[nstate], sc->flags));
  895 
  896         ostate = vap->iv_state;
  897         IEEE80211_UNLOCK(ic);
  898 
  899         switch (nstate) {
  900         case IEEE80211_S_RUN:
  901                 if (ic->ic_opmode == IEEE80211_M_IBSS) {
  902                         /*
  903                          * XXX when joining an ibss network we are called
  904                          * with a SCAN -> RUN transition on scan complete.
  905                          * Use that to call ipw_assoc.  On completing the
  906                          * join we are then called again with an AUTH -> RUN
  907                          * transition and we want to do nothing.  This is
  908                          * all totally bogus and needs to be redone.
  909                          */
  910                         if (ostate == IEEE80211_S_SCAN)
  911                                 ipw_assoc(ic, vap);
  912                 }
  913                 break;
  914 
  915         case IEEE80211_S_INIT:
  916                 if (sc->flags & IPW_FLAG_ASSOCIATED)
  917                         ipw_disassoc(ic, vap);
  918                 break;
  919 
  920         case IEEE80211_S_AUTH:
  921                 /*
  922                  * Move to ASSOC state after the ipw_assoc() call.  Firmware
  923                  * takes care of authentication, after the call we'll receive
  924                  * only an assoc response which would otherwise be discared
  925                  * if we are still in AUTH state.
  926                  */
  927                 nstate = IEEE80211_S_ASSOC;
  928                 ipw_assoc(ic, vap);
  929                 break;
  930 
  931         case IEEE80211_S_ASSOC:
  932                 /*
  933                  * If we are not transitioning from AUTH then resend the
  934                  * association request.
  935                  */
  936                 if (ostate != IEEE80211_S_AUTH)
  937                         ipw_assoc(ic, vap);
  938                 break;
  939 
  940         default:
  941                 break;
  942         }
  943         IEEE80211_LOCK(ic);
  944         return ivp->newstate(vap, nstate, arg);
  945 }
  946 
  947 /*
  948  * Read 16 bits at address 'addr' from the serial EEPROM.
  949  */
  950 static uint16_t
  951 ipw_read_prom_word(struct ipw_softc *sc, uint8_t addr)
  952 {
  953         uint32_t tmp;
  954         uint16_t val;
  955         int n;
  956 
  957         /* clock C once before the first command */
  958         IPW_EEPROM_CTL(sc, 0);
  959         IPW_EEPROM_CTL(sc, IPW_EEPROM_S);
  960         IPW_EEPROM_CTL(sc, IPW_EEPROM_S | IPW_EEPROM_C);
  961         IPW_EEPROM_CTL(sc, IPW_EEPROM_S);
  962 
  963         /* write start bit (1) */
  964         IPW_EEPROM_CTL(sc, IPW_EEPROM_S | IPW_EEPROM_D);
  965         IPW_EEPROM_CTL(sc, IPW_EEPROM_S | IPW_EEPROM_D | IPW_EEPROM_C);
  966 
  967         /* write READ opcode (10) */
  968         IPW_EEPROM_CTL(sc, IPW_EEPROM_S | IPW_EEPROM_D);
  969         IPW_EEPROM_CTL(sc, IPW_EEPROM_S | IPW_EEPROM_D | IPW_EEPROM_C);
  970         IPW_EEPROM_CTL(sc, IPW_EEPROM_S);
  971         IPW_EEPROM_CTL(sc, IPW_EEPROM_S | IPW_EEPROM_C);
  972 
  973         /* write address A7-A0 */
  974         for (n = 7; n >= 0; n--) {
  975                 IPW_EEPROM_CTL(sc, IPW_EEPROM_S |
  976                     (((addr >> n) & 1) << IPW_EEPROM_SHIFT_D));
  977                 IPW_EEPROM_CTL(sc, IPW_EEPROM_S |
  978                     (((addr >> n) & 1) << IPW_EEPROM_SHIFT_D) | IPW_EEPROM_C);
  979         }
  980 
  981         IPW_EEPROM_CTL(sc, IPW_EEPROM_S);
  982 
  983         /* read data Q15-Q0 */
  984         val = 0;
  985         for (n = 15; n >= 0; n--) {
  986                 IPW_EEPROM_CTL(sc, IPW_EEPROM_S | IPW_EEPROM_C);
  987                 IPW_EEPROM_CTL(sc, IPW_EEPROM_S);
  988                 tmp = MEM_READ_4(sc, IPW_MEM_EEPROM_CTL);
  989                 val |= ((tmp & IPW_EEPROM_Q) >> IPW_EEPROM_SHIFT_Q) << n;
  990         }
  991 
  992         IPW_EEPROM_CTL(sc, 0);
  993 
  994         /* clear Chip Select and clock C */
  995         IPW_EEPROM_CTL(sc, IPW_EEPROM_S);
  996         IPW_EEPROM_CTL(sc, 0);
  997         IPW_EEPROM_CTL(sc, IPW_EEPROM_C);
  998 
  999         return le16toh(val);
 1000 }
 1001 
 1002 static void
 1003 ipw_rx_cmd_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
 1004 {
 1005         struct ipw_cmd *cmd;
 1006 
 1007         bus_dmamap_sync(sc->rxbuf_dmat, sbuf->map, BUS_DMASYNC_POSTREAD);
 1008 
 1009         cmd = mtod(sbuf->m, struct ipw_cmd *);
 1010 
 1011         DPRINTFN(9, ("cmd ack'ed %s(%u, %u, %u, %u, %u)\n",
 1012             ipw_cmdname(le32toh(cmd->type)), le32toh(cmd->type),
 1013             le32toh(cmd->subtype), le32toh(cmd->seq), le32toh(cmd->len),
 1014             le32toh(cmd->status)));
 1015 
 1016         sc->flags &= ~IPW_FLAG_BUSY;
 1017         wakeup(sc);
 1018 }
 1019 
 1020 static void
 1021 ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
 1022 {
 1023 #define IEEESTATE(vap)  ieee80211_state_name[vap->iv_state]
 1024         struct ifnet *ifp = sc->sc_ifp;
 1025         struct ieee80211com *ic = ifp->if_l2com;
 1026         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 1027         uint32_t state;
 1028 
 1029         bus_dmamap_sync(sc->rxbuf_dmat, sbuf->map, BUS_DMASYNC_POSTREAD);
 1030 
 1031         state = le32toh(*mtod(sbuf->m, uint32_t *));
 1032 
 1033         switch (state) {
 1034         case IPW_STATE_ASSOCIATED:
 1035                 DPRINTFN(2, ("Association succeeded (%s flags 0x%x)\n",
 1036                         IEEESTATE(vap), sc->flags));
 1037                 /* XXX suppress state change in case the fw auto-associates */
 1038                 if ((sc->flags & IPW_FLAG_ASSOCIATING) == 0) {
 1039                         DPRINTF(("Unexpected association (%s, flags 0x%x)\n",
 1040                                 IEEESTATE(vap), sc->flags));
 1041                         break;
 1042                 }
 1043                 sc->flags &= ~IPW_FLAG_ASSOCIATING;
 1044                 sc->flags |= IPW_FLAG_ASSOCIATED;
 1045                 break;
 1046 
 1047         case IPW_STATE_SCANNING:
 1048                 DPRINTFN(3, ("Scanning (%s flags 0x%x)\n",
 1049                         IEEESTATE(vap), sc->flags));
 1050                 /*
 1051                  * NB: Check driver state for association on assoc
 1052                  * loss as the firmware will immediately start to
 1053                  * scan and we would treat it as a beacon miss if
 1054                  * we checked the 802.11 layer state.
 1055                  */
 1056                 if (sc->flags & IPW_FLAG_ASSOCIATED) {
 1057                         IPW_UNLOCK(sc);
 1058                         /* XXX probably need to issue disassoc to fw */
 1059                         ieee80211_beacon_miss(ic);
 1060                         IPW_LOCK(sc);
 1061                 }
 1062                 break;
 1063 
 1064         case IPW_STATE_SCAN_COMPLETE:
 1065                 /*
 1066                  * XXX For some reason scan requests generate scan
 1067                  * started + scan done events before any traffic is
 1068                  * received (e.g. probe response frames).  We work
 1069                  * around this by marking the HACK flag and skipping
 1070                  * the first scan complete event.
 1071                 */
 1072                 DPRINTFN(3, ("Scan complete (%s flags 0x%x)\n",
 1073                             IEEESTATE(vap), sc->flags));
 1074                 if (sc->flags & IPW_FLAG_HACK) {
 1075                         sc->flags &= ~IPW_FLAG_HACK;
 1076                         break;
 1077                 }
 1078                 if (sc->flags & IPW_FLAG_SCANNING) {
 1079                         IPW_UNLOCK(sc);
 1080                         ieee80211_scan_done(vap);
 1081                         IPW_LOCK(sc);
 1082                         sc->flags &= ~IPW_FLAG_SCANNING;
 1083                         sc->sc_scan_timer = 0;
 1084                 }
 1085                 break;
 1086 
 1087         case IPW_STATE_ASSOCIATION_LOST:
 1088                 DPRINTFN(2, ("Association lost (%s flags 0x%x)\n",
 1089                         IEEESTATE(vap), sc->flags));
 1090                 sc->flags &= ~(IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED);
 1091                 if (vap->iv_state == IEEE80211_S_RUN) {
 1092                         IPW_UNLOCK(sc);
 1093                         ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
 1094                         IPW_LOCK(sc);
 1095                 }
 1096                 break;
 1097 
 1098         case IPW_STATE_DISABLED:
 1099                 /* XXX? is this right? */
 1100                 sc->flags &= ~(IPW_FLAG_HACK | IPW_FLAG_SCANNING |
 1101                     IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED);
 1102                 DPRINTFN(2, ("Firmware disabled (%s flags 0x%x)\n",
 1103                         IEEESTATE(vap), sc->flags));
 1104                 break;
 1105 
 1106         case IPW_STATE_RADIO_DISABLED:
 1107                 device_printf(sc->sc_dev, "radio turned off\n");
 1108                 ieee80211_notify_radio(ic, 0);
 1109                 ipw_stop_locked(sc);
 1110                 /* XXX start polling thread to detect radio on */
 1111                 break;
 1112 
 1113         default:
 1114                 DPRINTFN(2, ("%s: unhandled state %u %s flags 0x%x\n",
 1115                         __func__, state, IEEESTATE(vap), sc->flags));
 1116                 break;
 1117         }
 1118 #undef IEEESTATE
 1119 }
 1120 
 1121 /*
 1122  * Set driver state for current channel.
 1123  */
 1124 static void
 1125 ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan)
 1126 {
 1127         struct ifnet *ifp = sc->sc_ifp;
 1128         struct ieee80211com *ic = ifp->if_l2com;
 1129 
 1130         ic->ic_curchan = chan;
 1131         ieee80211_radiotap_chan_change(ic);
 1132 }
 1133 
 1134 /*
 1135  * XXX: Hack to set the current channel to the value advertised in beacons or
 1136  * probe responses. Only used during AP detection.
 1137  */
 1138 static void
 1139 ipw_fix_channel(struct ipw_softc *sc, struct mbuf *m)
 1140 {
 1141         struct ifnet *ifp = sc->sc_ifp;
 1142         struct ieee80211com *ic = ifp->if_l2com;
 1143         struct ieee80211_channel *c;
 1144         struct ieee80211_frame *wh;
 1145         uint8_t subtype;
 1146         uint8_t *frm, *efrm;
 1147 
 1148         wh = mtod(m, struct ieee80211_frame *);
 1149 
 1150         if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT)
 1151                 return;
 1152 
 1153         subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
 1154 
 1155         if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
 1156             subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP)
 1157                 return;
 1158 
 1159         /* XXX use ieee80211_parse_beacon */
 1160         frm = (uint8_t *)(wh + 1);
 1161         efrm = mtod(m, uint8_t *) + m->m_len;
 1162 
 1163         frm += 12;      /* skip tstamp, bintval and capinfo fields */
 1164         while (frm < efrm) {
 1165                 if (*frm == IEEE80211_ELEMID_DSPARMS)
 1166 #if IEEE80211_CHAN_MAX < 255
 1167                 if (frm[2] <= IEEE80211_CHAN_MAX)
 1168 #endif
 1169                 {
 1170                         DPRINTF(("Fixing channel to %d\n", frm[2]));
 1171                         c = ieee80211_find_channel(ic,
 1172                                 ieee80211_ieee2mhz(frm[2], 0),
 1173                                 IEEE80211_CHAN_B);
 1174                         if (c == NULL)
 1175                                 c = &ic->ic_channels[0];
 1176                         ipw_setcurchan(sc, c);
 1177                 }
 1178 
 1179                 frm += frm[1] + 2;
 1180         }
 1181 }
 1182 
 1183 static void
 1184 ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
 1185     struct ipw_soft_bd *sbd, struct ipw_soft_buf *sbuf)
 1186 {
 1187         struct ifnet *ifp = sc->sc_ifp;
 1188         struct ieee80211com *ic = ifp->if_l2com;
 1189         struct mbuf *mnew, *m;
 1190         struct ieee80211_node *ni;
 1191         bus_addr_t physaddr;
 1192         int error;
 1193         int8_t rssi, nf;
 1194 
 1195         DPRINTFN(5, ("received frame len=%u, rssi=%u\n", le32toh(status->len),
 1196             status->rssi));
 1197 
 1198         if (le32toh(status->len) < sizeof (struct ieee80211_frame_min) ||
 1199             le32toh(status->len) > MCLBYTES)
 1200                 return;
 1201 
 1202         /*
 1203          * Try to allocate a new mbuf for this ring element and load it before
 1204          * processing the current mbuf. If the ring element cannot be loaded,
 1205          * drop the received packet and reuse the old mbuf. In the unlikely
 1206          * case that the old mbuf can't be reloaded either, explicitly panic.
 1207          */
 1208         mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
 1209         if (mnew == NULL) {
 1210                 ifp->if_ierrors++;
 1211                 return;
 1212         }
 1213 
 1214         bus_dmamap_sync(sc->rxbuf_dmat, sbuf->map, BUS_DMASYNC_POSTREAD);
 1215         bus_dmamap_unload(sc->rxbuf_dmat, sbuf->map);
 1216 
 1217         error = bus_dmamap_load(sc->rxbuf_dmat, sbuf->map, mtod(mnew, void *),
 1218             MCLBYTES, ipw_dma_map_addr, &physaddr, 0);
 1219         if (error != 0) {
 1220                 m_freem(mnew);
 1221 
 1222                 /* try to reload the old mbuf */
 1223                 error = bus_dmamap_load(sc->rxbuf_dmat, sbuf->map,
 1224                     mtod(sbuf->m, void *), MCLBYTES, ipw_dma_map_addr,
 1225                     &physaddr, 0);
 1226                 if (error != 0) {
 1227                         /* very unlikely that it will fail... */
 1228                         panic("%s: could not load old rx mbuf",
 1229                             device_get_name(sc->sc_dev));
 1230                 }
 1231                 ifp->if_ierrors++;
 1232                 return;
 1233         }
 1234 
 1235         /*
 1236          * New mbuf successfully loaded, update Rx ring and continue
 1237          * processing.
 1238          */
 1239         m = sbuf->m;
 1240         sbuf->m = mnew;
 1241         sbd->bd->physaddr = htole32(physaddr);
 1242 
 1243         /* finalize mbuf */
 1244         m->m_pkthdr.rcvif = ifp;
 1245         m->m_pkthdr.len = m->m_len = le32toh(status->len);
 1246 
 1247         rssi = status->rssi + IPW_RSSI_TO_DBM;
 1248         nf = -95;
 1249         if (ieee80211_radiotap_active(ic)) {
 1250                 struct ipw_rx_radiotap_header *tap = &sc->sc_rxtap;
 1251 
 1252                 tap->wr_flags = 0;
 1253                 tap->wr_antsignal = rssi;
 1254                 tap->wr_antnoise = nf;
 1255         }
 1256 
 1257         if (sc->flags & IPW_FLAG_SCANNING)
 1258                 ipw_fix_channel(sc, m);
 1259 
 1260         IPW_UNLOCK(sc);
 1261         ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
 1262         if (ni != NULL) {
 1263                 (void) ieee80211_input(ni, m, rssi - nf, nf);
 1264                 ieee80211_free_node(ni);
 1265         } else
 1266                 (void) ieee80211_input_all(ic, m, rssi - nf, nf);
 1267         IPW_LOCK(sc);
 1268 
 1269         bus_dmamap_sync(sc->rbd_dmat, sc->rbd_map, BUS_DMASYNC_PREWRITE);
 1270 }
 1271 
 1272 static void
 1273 ipw_rx_intr(struct ipw_softc *sc)
 1274 {
 1275         struct ipw_status *status;
 1276         struct ipw_soft_bd *sbd;
 1277         struct ipw_soft_buf *sbuf;
 1278         uint32_t r, i;
 1279 
 1280         if (!(sc->flags & IPW_FLAG_FW_INITED))
 1281                 return;
 1282 
 1283         r = CSR_READ_4(sc, IPW_CSR_RX_READ);
 1284 
 1285         bus_dmamap_sync(sc->status_dmat, sc->status_map, BUS_DMASYNC_POSTREAD);
 1286 
 1287         for (i = (sc->rxcur + 1) % IPW_NRBD; i != r; i = (i + 1) % IPW_NRBD) {
 1288                 status = &sc->status_list[i];
 1289                 sbd = &sc->srbd_list[i];
 1290                 sbuf = sbd->priv;
 1291 
 1292                 switch (le16toh(status->code) & 0xf) {
 1293                 case IPW_STATUS_CODE_COMMAND:
 1294                         ipw_rx_cmd_intr(sc, sbuf);
 1295                         break;
 1296 
 1297                 case IPW_STATUS_CODE_NEWSTATE:
 1298                         ipw_rx_newstate_intr(sc, sbuf);
 1299                         break;
 1300 
 1301                 case IPW_STATUS_CODE_DATA_802_3:
 1302                 case IPW_STATUS_CODE_DATA_802_11:
 1303                         ipw_rx_data_intr(sc, status, sbd, sbuf);
 1304                         break;
 1305 
 1306                 case IPW_STATUS_CODE_NOTIFICATION:
 1307                         DPRINTFN(2, ("notification status, len %u flags 0x%x\n",
 1308                             le32toh(status->len), status->flags));
 1309                         /* XXX maybe drive state machine AUTH->ASSOC? */
 1310                         break;
 1311 
 1312                 default:
 1313                         device_printf(sc->sc_dev, "unexpected status code %u\n",
 1314                             le16toh(status->code));
 1315                 }
 1316 
 1317                 /* firmware was killed, stop processing received frames */
 1318                 if (!(sc->flags & IPW_FLAG_FW_INITED))
 1319                         return;
 1320 
 1321                 sbd->bd->flags = 0;
 1322         }
 1323 
 1324         bus_dmamap_sync(sc->rbd_dmat, sc->rbd_map, BUS_DMASYNC_PREWRITE);
 1325 
 1326         /* kick the firmware */
 1327         sc->rxcur = (r == 0) ? IPW_NRBD - 1 : r - 1;
 1328         CSR_WRITE_4(sc, IPW_CSR_RX_WRITE, sc->rxcur);
 1329 }
 1330 
 1331 static void
 1332 ipw_release_sbd(struct ipw_softc *sc, struct ipw_soft_bd *sbd)
 1333 {
 1334         struct ipw_soft_hdr *shdr;
 1335         struct ipw_soft_buf *sbuf;
 1336 
 1337         switch (sbd->type) {
 1338         case IPW_SBD_TYPE_COMMAND:
 1339                 bus_dmamap_sync(sc->cmd_dmat, sc->cmd_map,
 1340                     BUS_DMASYNC_POSTWRITE);
 1341                 bus_dmamap_unload(sc->cmd_dmat, sc->cmd_map);
 1342                 break;
 1343 
 1344         case IPW_SBD_TYPE_HEADER:
 1345                 shdr = sbd->priv;
 1346                 bus_dmamap_sync(sc->hdr_dmat, shdr->map, BUS_DMASYNC_POSTWRITE);
 1347                 bus_dmamap_unload(sc->hdr_dmat, shdr->map);
 1348                 SLIST_INSERT_HEAD(&sc->free_shdr, shdr, next);
 1349                 break;
 1350 
 1351         case IPW_SBD_TYPE_DATA:
 1352                 sbuf = sbd->priv;
 1353                 bus_dmamap_sync(sc->txbuf_dmat, sbuf->map,
 1354                     BUS_DMASYNC_POSTWRITE);
 1355                 bus_dmamap_unload(sc->txbuf_dmat, sbuf->map);
 1356                 SLIST_INSERT_HEAD(&sc->free_sbuf, sbuf, next);
 1357 
 1358                 if (sbuf->m->m_flags & M_TXCB)
 1359                         ieee80211_process_callback(sbuf->ni, sbuf->m, 0/*XXX*/);
 1360                 m_freem(sbuf->m);
 1361                 ieee80211_free_node(sbuf->ni);
 1362 
 1363                 sc->sc_tx_timer = 0;
 1364                 break;
 1365         }
 1366 
 1367         sbd->type = IPW_SBD_TYPE_NOASSOC;
 1368 }
 1369 
 1370 static void
 1371 ipw_tx_intr(struct ipw_softc *sc)
 1372 {
 1373         struct ifnet *ifp = sc->sc_ifp;
 1374         struct ipw_soft_bd *sbd;
 1375         uint32_t r, i;
 1376 
 1377         if (!(sc->flags & IPW_FLAG_FW_INITED))
 1378                 return;
 1379 
 1380         r = CSR_READ_4(sc, IPW_CSR_TX_READ);
 1381 
 1382         for (i = (sc->txold + 1) % IPW_NTBD; i != r; i = (i + 1) % IPW_NTBD) {
 1383                 sbd = &sc->stbd_list[i];
 1384 
 1385                 if (sbd->type == IPW_SBD_TYPE_DATA)
 1386                         ifp->if_opackets++;
 1387 
 1388                 ipw_release_sbd(sc, sbd);
 1389                 sc->txfree++;
 1390         }
 1391 
 1392         /* remember what the firmware has processed */
 1393         sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1;
 1394 
 1395         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 1396         ipw_start_locked(ifp);
 1397 }
 1398 
 1399 static void
 1400 ipw_fatal_error_intr(struct ipw_softc *sc)
 1401 {
 1402         struct ifnet *ifp = sc->sc_ifp;
 1403         struct ieee80211com *ic = ifp->if_l2com;
 1404         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 1405 
 1406         device_printf(sc->sc_dev, "firmware error\n");
 1407         if (vap != NULL) {
 1408                 IPW_UNLOCK(sc);
 1409                 ieee80211_cancel_scan(vap);
 1410                 IPW_LOCK(sc);
 1411         }
 1412         ieee80211_runtask(ic, &sc->sc_init_task);
 1413 }
 1414 
 1415 static void
 1416 ipw_intr(void *arg)
 1417 {
 1418         struct ipw_softc *sc = arg;
 1419         uint32_t r;
 1420 
 1421         IPW_LOCK(sc);
 1422 
 1423         r = CSR_READ_4(sc, IPW_CSR_INTR);
 1424         if (r == 0 || r == 0xffffffff)
 1425                 goto done;
 1426 
 1427         /* disable interrupts */
 1428         CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, 0);
 1429 
 1430         /* acknowledge all interrupts */
 1431         CSR_WRITE_4(sc, IPW_CSR_INTR, r);
 1432 
 1433         if (r & (IPW_INTR_FATAL_ERROR | IPW_INTR_PARITY_ERROR)) {
 1434                 ipw_fatal_error_intr(sc);
 1435                 goto done;
 1436         }
 1437 
 1438         if (r & IPW_INTR_FW_INIT_DONE)
 1439                 wakeup(sc);
 1440 
 1441         if (r & IPW_INTR_RX_TRANSFER)
 1442                 ipw_rx_intr(sc);
 1443 
 1444         if (r & IPW_INTR_TX_TRANSFER)
 1445                 ipw_tx_intr(sc);
 1446 
 1447         /* re-enable interrupts */
 1448         CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, IPW_INTR_MASK);
 1449 done:
 1450         IPW_UNLOCK(sc);
 1451 }
 1452 
 1453 static void
 1454 ipw_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 1455 {
 1456         if (error != 0)
 1457                 return;
 1458 
 1459         KASSERT(nseg == 1, ("too many DMA segments, %d should be 1", nseg));
 1460 
 1461         *(bus_addr_t *)arg = segs[0].ds_addr;
 1462 }
 1463 
 1464 static const char *
 1465 ipw_cmdname(int cmd)
 1466 {
 1467 #define N(a)    (sizeof(a) / sizeof(a[0]))
 1468         static const struct {
 1469                 int     cmd;
 1470                 const char *name;
 1471         } cmds[] = {
 1472                 { IPW_CMD_ADD_MULTICAST,        "ADD_MULTICAST" },
 1473                 { IPW_CMD_BROADCAST_SCAN,       "BROADCAST_SCAN" },
 1474                 { IPW_CMD_DISABLE,              "DISABLE" },
 1475                 { IPW_CMD_DISABLE_PHY,          "DISABLE_PHY" },
 1476                 { IPW_CMD_ENABLE,               "ENABLE" },
 1477                 { IPW_CMD_PREPARE_POWER_DOWN,   "PREPARE_POWER_DOWN" },
 1478                 { IPW_CMD_SET_BASIC_TX_RATES,   "SET_BASIC_TX_RATES" },
 1479                 { IPW_CMD_SET_BEACON_INTERVAL,  "SET_BEACON_INTERVAL" },
 1480                 { IPW_CMD_SET_CHANNEL,          "SET_CHANNEL" },
 1481                 { IPW_CMD_SET_CONFIGURATION,    "SET_CONFIGURATION" },
 1482                 { IPW_CMD_SET_DESIRED_BSSID,    "SET_DESIRED_BSSID" },
 1483                 { IPW_CMD_SET_ESSID,            "SET_ESSID" },
 1484                 { IPW_CMD_SET_FRAG_THRESHOLD,   "SET_FRAG_THRESHOLD" },
 1485                 { IPW_CMD_SET_MAC_ADDRESS,      "SET_MAC_ADDRESS" },
 1486                 { IPW_CMD_SET_MANDATORY_BSSID,  "SET_MANDATORY_BSSID" },
 1487                 { IPW_CMD_SET_MODE,             "SET_MODE" },
 1488                 { IPW_CMD_SET_MSDU_TX_RATES,    "SET_MSDU_TX_RATES" },
 1489                 { IPW_CMD_SET_POWER_MODE,       "SET_POWER_MODE" },
 1490                 { IPW_CMD_SET_RTS_THRESHOLD,    "SET_RTS_THRESHOLD" },
 1491                 { IPW_CMD_SET_SCAN_OPTIONS,     "SET_SCAN_OPTIONS" },
 1492                 { IPW_CMD_SET_SECURITY_INFO,    "SET_SECURITY_INFO" },
 1493                 { IPW_CMD_SET_TX_POWER_INDEX,   "SET_TX_POWER_INDEX" },
 1494                 { IPW_CMD_SET_TX_RATES,         "SET_TX_RATES" },
 1495                 { IPW_CMD_SET_WEP_FLAGS,        "SET_WEP_FLAGS" },
 1496                 { IPW_CMD_SET_WEP_KEY,          "SET_WEP_KEY" },
 1497                 { IPW_CMD_SET_WEP_KEY_INDEX,    "SET_WEP_KEY_INDEX" },
 1498                 { IPW_CMD_SET_WPA_IE,           "SET_WPA_IE" },
 1499 
 1500         };
 1501         static char buf[12];
 1502         int i;
 1503 
 1504         for (i = 0; i < N(cmds); i++)
 1505                 if (cmds[i].cmd == cmd)
 1506                         return cmds[i].name;
 1507         snprintf(buf, sizeof(buf), "%u", cmd);
 1508         return buf;
 1509 #undef N
 1510 }
 1511 
 1512 /*
 1513  * Send a command to the firmware and wait for the acknowledgement.
 1514  */
 1515 static int
 1516 ipw_cmd(struct ipw_softc *sc, uint32_t type, void *data, uint32_t len)
 1517 {
 1518         struct ipw_soft_bd *sbd;
 1519         bus_addr_t physaddr;
 1520         int error;
 1521 
 1522         IPW_LOCK_ASSERT(sc);
 1523 
 1524         if (sc->flags & IPW_FLAG_BUSY) {
 1525                 device_printf(sc->sc_dev, "%s: %s not sent, busy\n",
 1526                         __func__, ipw_cmdname(type));
 1527                 return EAGAIN;
 1528         }
 1529         sc->flags |= IPW_FLAG_BUSY;
 1530 
 1531         sbd = &sc->stbd_list[sc->txcur];
 1532 
 1533         error = bus_dmamap_load(sc->cmd_dmat, sc->cmd_map, &sc->cmd,
 1534             sizeof (struct ipw_cmd), ipw_dma_map_addr, &physaddr, 0);
 1535         if (error != 0) {
 1536                 device_printf(sc->sc_dev, "could not map command DMA memory\n");
 1537                 sc->flags &= ~IPW_FLAG_BUSY;
 1538                 return error;
 1539         }
 1540 
 1541         sc->cmd.type = htole32(type);
 1542         sc->cmd.subtype = 0;
 1543         sc->cmd.len = htole32(len);
 1544         sc->cmd.seq = 0;
 1545         memcpy(sc->cmd.data, data, len);
 1546 
 1547         sbd->type = IPW_SBD_TYPE_COMMAND;
 1548         sbd->bd->physaddr = htole32(physaddr);
 1549         sbd->bd->len = htole32(sizeof (struct ipw_cmd));
 1550         sbd->bd->nfrag = 1;
 1551         sbd->bd->flags = IPW_BD_FLAG_TX_FRAME_COMMAND |
 1552             IPW_BD_FLAG_TX_LAST_FRAGMENT;
 1553 
 1554         bus_dmamap_sync(sc->cmd_dmat, sc->cmd_map, BUS_DMASYNC_PREWRITE);
 1555         bus_dmamap_sync(sc->tbd_dmat, sc->tbd_map, BUS_DMASYNC_PREWRITE);
 1556 
 1557 #ifdef IPW_DEBUG
 1558         if (ipw_debug >= 4) {
 1559                 printf("sending %s(%u, %u, %u, %u)", ipw_cmdname(type), type,
 1560                     0, 0, len);
 1561                 /* Print the data buffer in the higher debug level */
 1562                 if (ipw_debug >= 9 && len > 0) {
 1563                         printf(" data: 0x");
 1564                         for (int i = 1; i <= len; i++)
 1565                                 printf("%1D", (u_char *)data + len - i, "");
 1566                 }
 1567                 printf("\n");
 1568         }
 1569 #endif
 1570 
 1571         /* kick firmware */
 1572         sc->txfree--;
 1573         sc->txcur = (sc->txcur + 1) % IPW_NTBD;
 1574         CSR_WRITE_4(sc, IPW_CSR_TX_WRITE, sc->txcur);
 1575 
 1576         /* wait at most one second for command to complete */
 1577         error = msleep(sc, &sc->sc_mtx, 0, "ipwcmd", hz);
 1578         if (error != 0) {
 1579                 device_printf(sc->sc_dev, "%s: %s failed, timeout (error %u)\n",
 1580                     __func__, ipw_cmdname(type), error);
 1581                 sc->flags &= ~IPW_FLAG_BUSY;
 1582                 return (error);
 1583         }
 1584         return (0);
 1585 }
 1586 
 1587 static int
 1588 ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni)
 1589 {
 1590         struct ipw_softc *sc = ifp->if_softc;
 1591         struct ieee80211com *ic = ifp->if_l2com;
 1592         struct ieee80211vap *vap = ni->ni_vap;
 1593         struct ieee80211_frame *wh;
 1594         struct ipw_soft_bd *sbd;
 1595         struct ipw_soft_hdr *shdr;
 1596         struct ipw_soft_buf *sbuf;
 1597         struct ieee80211_key *k;
 1598         struct mbuf *mnew;
 1599         bus_dma_segment_t segs[IPW_MAX_NSEG];
 1600         bus_addr_t physaddr;
 1601         int nsegs, error, i;
 1602 
 1603         wh = mtod(m0, struct ieee80211_frame *);
 1604 
 1605         if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
 1606                 k = ieee80211_crypto_encap(ni, m0);
 1607                 if (k == NULL) {
 1608                         m_freem(m0);
 1609                         return ENOBUFS;
 1610                 }
 1611                 /* packet header may have moved, reset our local pointer */
 1612                 wh = mtod(m0, struct ieee80211_frame *);
 1613         }
 1614 
 1615         if (ieee80211_radiotap_active_vap(vap)) {
 1616                 struct ipw_tx_radiotap_header *tap = &sc->sc_txtap;
 1617 
 1618                 tap->wt_flags = 0;
 1619 
 1620                 ieee80211_radiotap_tx(vap, m0);
 1621         }
 1622 
 1623         shdr = SLIST_FIRST(&sc->free_shdr);
 1624         sbuf = SLIST_FIRST(&sc->free_sbuf);
 1625         KASSERT(shdr != NULL && sbuf != NULL, ("empty sw hdr/buf pool"));
 1626 
 1627         shdr->hdr.type = htole32(IPW_HDR_TYPE_SEND);
 1628         shdr->hdr.subtype = 0;
 1629         shdr->hdr.encrypted = (wh->i_fc[1] & IEEE80211_FC1_WEP) ? 1 : 0;
 1630         shdr->hdr.encrypt = 0;
 1631         shdr->hdr.keyidx = 0;
 1632         shdr->hdr.keysz = 0;
 1633         shdr->hdr.fragmentsz = 0;
 1634         IEEE80211_ADDR_COPY(shdr->hdr.src_addr, wh->i_addr2);
 1635         if (ic->ic_opmode == IEEE80211_M_STA)
 1636                 IEEE80211_ADDR_COPY(shdr->hdr.dst_addr, wh->i_addr3);
 1637         else
 1638                 IEEE80211_ADDR_COPY(shdr->hdr.dst_addr, wh->i_addr1);
 1639 
 1640         /* trim IEEE802.11 header */
 1641         m_adj(m0, sizeof (struct ieee80211_frame));
 1642 
 1643         error = bus_dmamap_load_mbuf_sg(sc->txbuf_dmat, sbuf->map, m0, segs,
 1644             &nsegs, 0);
 1645         if (error != 0 && error != EFBIG) {
 1646                 device_printf(sc->sc_dev, "could not map mbuf (error %d)\n",
 1647                     error);
 1648                 m_freem(m0);
 1649                 return error;
 1650         }
 1651         if (error != 0) {
 1652                 mnew = m_defrag(m0, M_DONTWAIT);
 1653                 if (mnew == NULL) {
 1654                         device_printf(sc->sc_dev,
 1655                             "could not defragment mbuf\n");
 1656                         m_freem(m0);
 1657                         return ENOBUFS;
 1658                 }
 1659                 m0 = mnew;
 1660 
 1661                 error = bus_dmamap_load_mbuf_sg(sc->txbuf_dmat, sbuf->map, m0,
 1662                     segs, &nsegs, 0);
 1663                 if (error != 0) {
 1664                         device_printf(sc->sc_dev,
 1665                             "could not map mbuf (error %d)\n", error);
 1666                         m_freem(m0);
 1667                         return error;
 1668                 }
 1669         }
 1670 
 1671         error = bus_dmamap_load(sc->hdr_dmat, shdr->map, &shdr->hdr,
 1672             sizeof (struct ipw_hdr), ipw_dma_map_addr, &physaddr, 0);
 1673         if (error != 0) {
 1674                 device_printf(sc->sc_dev, "could not map header DMA memory\n");
 1675                 bus_dmamap_unload(sc->txbuf_dmat, sbuf->map);
 1676                 m_freem(m0);
 1677                 return error;
 1678         }
 1679 
 1680         SLIST_REMOVE_HEAD(&sc->free_sbuf, next);
 1681         SLIST_REMOVE_HEAD(&sc->free_shdr, next);
 1682 
 1683         sbd = &sc->stbd_list[sc->txcur];
 1684         sbd->type = IPW_SBD_TYPE_HEADER;
 1685         sbd->priv = shdr;
 1686         sbd->bd->physaddr = htole32(physaddr);
 1687         sbd->bd->len = htole32(sizeof (struct ipw_hdr));
 1688         sbd->bd->nfrag = 1 + nsegs;
 1689         sbd->bd->flags = IPW_BD_FLAG_TX_FRAME_802_3 |
 1690             IPW_BD_FLAG_TX_NOT_LAST_FRAGMENT;
 1691 
 1692         DPRINTFN(5, ("sending tx hdr (%u, %u, %u, %u, %6D, %6D)\n",
 1693             shdr->hdr.type, shdr->hdr.subtype, shdr->hdr.encrypted,
 1694             shdr->hdr.encrypt, shdr->hdr.src_addr, ":", shdr->hdr.dst_addr,
 1695             ":"));
 1696 
 1697         sc->txfree--;
 1698         sc->txcur = (sc->txcur + 1) % IPW_NTBD;
 1699 
 1700         sbuf->m = m0;
 1701         sbuf->ni = ni;
 1702 
 1703         for (i = 0; i < nsegs; i++) {
 1704                 sbd = &sc->stbd_list[sc->txcur];
 1705 
 1706                 sbd->bd->physaddr = htole32(segs[i].ds_addr);
 1707                 sbd->bd->len = htole32(segs[i].ds_len);
 1708                 sbd->bd->nfrag = 0;
 1709                 sbd->bd->flags = IPW_BD_FLAG_TX_FRAME_802_3;
 1710                 if (i == nsegs - 1) {
 1711                         sbd->type = IPW_SBD_TYPE_DATA;
 1712                         sbd->priv = sbuf;
 1713                         sbd->bd->flags |= IPW_BD_FLAG_TX_LAST_FRAGMENT;
 1714                 } else {
 1715                         sbd->type = IPW_SBD_TYPE_NOASSOC;
 1716                         sbd->bd->flags |= IPW_BD_FLAG_TX_NOT_LAST_FRAGMENT;
 1717                 }
 1718 
 1719                 DPRINTFN(5, ("sending fragment (%d)\n", i));
 1720 
 1721                 sc->txfree--;
 1722                 sc->txcur = (sc->txcur + 1) % IPW_NTBD;
 1723         }
 1724 
 1725         bus_dmamap_sync(sc->hdr_dmat, shdr->map, BUS_DMASYNC_PREWRITE);
 1726         bus_dmamap_sync(sc->txbuf_dmat, sbuf->map, BUS_DMASYNC_PREWRITE);
 1727         bus_dmamap_sync(sc->tbd_dmat, sc->tbd_map, BUS_DMASYNC_PREWRITE);
 1728 
 1729         /* kick firmware */
 1730         CSR_WRITE_4(sc, IPW_CSR_TX_WRITE, sc->txcur);
 1731 
 1732         return 0;
 1733 }
 1734 
 1735 static int
 1736 ipw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
 1737         const struct ieee80211_bpf_params *params)
 1738 {
 1739         /* no support; just discard */
 1740         m_freem(m);
 1741         ieee80211_free_node(ni);
 1742         return 0;
 1743 }
 1744 
 1745 static void
 1746 ipw_start(struct ifnet *ifp)
 1747 {
 1748         struct ipw_softc *sc = ifp->if_softc;
 1749 
 1750         IPW_LOCK(sc);
 1751         ipw_start_locked(ifp);
 1752         IPW_UNLOCK(sc);
 1753 }
 1754 
 1755 static void
 1756 ipw_start_locked(struct ifnet *ifp)
 1757 {
 1758         struct ipw_softc *sc = ifp->if_softc;
 1759         struct ieee80211_node *ni;
 1760         struct mbuf *m;
 1761 
 1762         IPW_LOCK_ASSERT(sc);
 1763 
 1764         for (;;) {
 1765                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
 1766                 if (m == NULL)
 1767                         break;
 1768                 if (sc->txfree < 1 + IPW_MAX_NSEG) {
 1769                         IFQ_DRV_PREPEND(&ifp->if_snd, m);
 1770                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 1771                         break;
 1772                 }
 1773                 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
 1774                 if (ipw_tx_start(ifp, m, ni) != 0) {
 1775                         ieee80211_free_node(ni);
 1776                         ifp->if_oerrors++;
 1777                         break;
 1778                 }
 1779                 /* start watchdog timer */
 1780                 sc->sc_tx_timer = 5;
 1781         }
 1782 }
 1783 
 1784 static void
 1785 ipw_watchdog(void *arg)
 1786 {
 1787         struct ipw_softc *sc = arg;
 1788         struct ifnet *ifp = sc->sc_ifp;
 1789         struct ieee80211com *ic = ifp->if_l2com;
 1790 
 1791         IPW_LOCK_ASSERT(sc);
 1792 
 1793         if (sc->sc_tx_timer > 0) {
 1794                 if (--sc->sc_tx_timer == 0) {
 1795                         if_printf(ifp, "device timeout\n");
 1796                         ifp->if_oerrors++;
 1797                         taskqueue_enqueue(taskqueue_swi, &sc->sc_init_task);
 1798                 }
 1799         }
 1800         if (sc->sc_scan_timer > 0) {
 1801                 if (--sc->sc_scan_timer == 0) {
 1802                         DPRINTFN(3, ("Scan timeout\n"));
 1803                         /* End the scan */
 1804                         if (sc->flags & IPW_FLAG_SCANNING) {
 1805                                 IPW_UNLOCK(sc);
 1806                                 ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps));
 1807                                 IPW_LOCK(sc);
 1808                                 sc->flags &= ~IPW_FLAG_SCANNING;
 1809                         }
 1810                 }
 1811         }
 1812         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 1813                 callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc);
 1814 }
 1815 
 1816 static int
 1817 ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 1818 {
 1819         struct ipw_softc *sc = ifp->if_softc;
 1820         struct ieee80211com *ic = ifp->if_l2com;
 1821         struct ifreq *ifr = (struct ifreq *) data;
 1822         int error = 0, startall = 0;
 1823 
 1824         switch (cmd) {
 1825         case SIOCSIFFLAGS:
 1826                 IPW_LOCK(sc);
 1827                 if (ifp->if_flags & IFF_UP) {
 1828                         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 1829                                 ipw_init_locked(sc);
 1830                                 startall = 1;
 1831                         }
 1832                 } else {
 1833                         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 1834                                 ipw_stop_locked(sc);
 1835                 }
 1836                 IPW_UNLOCK(sc);
 1837                 if (startall)
 1838                         ieee80211_start_all(ic);
 1839                 break;
 1840         case SIOCGIFMEDIA:
 1841                 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
 1842                 break;
 1843         case SIOCGIFADDR:
 1844                 error = ether_ioctl(ifp, cmd, data);
 1845                 break;
 1846         default:
 1847                 error = EINVAL;
 1848                 break;
 1849         }
 1850         return error;
 1851 }
 1852 
 1853 static void
 1854 ipw_stop_master(struct ipw_softc *sc)
 1855 {
 1856         uint32_t tmp;
 1857         int ntries;
 1858 
 1859         /* disable interrupts */
 1860         CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, 0);
 1861 
 1862         CSR_WRITE_4(sc, IPW_CSR_RST, IPW_RST_STOP_MASTER);
 1863         for (ntries = 0; ntries < 50; ntries++) {
 1864                 if (CSR_READ_4(sc, IPW_CSR_RST) & IPW_RST_MASTER_DISABLED)
 1865                         break;
 1866                 DELAY(10);
 1867         }
 1868         if (ntries == 50)
 1869                 device_printf(sc->sc_dev, "timeout waiting for master\n");
 1870 
 1871         tmp = CSR_READ_4(sc, IPW_CSR_RST);
 1872         CSR_WRITE_4(sc, IPW_CSR_RST, tmp | IPW_RST_PRINCETON_RESET);
 1873 
 1874         /* Clear all flags except the following */
 1875         sc->flags &= IPW_FLAG_HAS_RADIO_SWITCH;
 1876 }
 1877 
 1878 static int
 1879 ipw_reset(struct ipw_softc *sc)
 1880 {
 1881         uint32_t tmp;
 1882         int ntries;
 1883 
 1884         ipw_stop_master(sc);
 1885 
 1886         /* move adapter to D0 state */
 1887         tmp = CSR_READ_4(sc, IPW_CSR_CTL);
 1888         CSR_WRITE_4(sc, IPW_CSR_CTL, tmp | IPW_CTL_INIT);
 1889 
 1890         /* wait for clock stabilization */
 1891         for (ntries = 0; ntries < 1000; ntries++) {
 1892                 if (CSR_READ_4(sc, IPW_CSR_CTL) & IPW_CTL_CLOCK_READY)
 1893                         break;
 1894                 DELAY(200);
 1895         }
 1896         if (ntries == 1000)
 1897                 return EIO;
 1898 
 1899         tmp =  CSR_READ_4(sc, IPW_CSR_RST);
 1900         CSR_WRITE_4(sc, IPW_CSR_RST, tmp | IPW_RST_SW_RESET);
 1901 
 1902         DELAY(10);
 1903 
 1904         tmp = CSR_READ_4(sc, IPW_CSR_CTL);
 1905         CSR_WRITE_4(sc, IPW_CSR_CTL, tmp | IPW_CTL_INIT);
 1906 
 1907         return 0;
 1908 }
 1909 
 1910 static int
 1911 ipw_waitfordisable(struct ipw_softc *sc, int waitfor)
 1912 {
 1913         int ms = hz < 1000 ? 1 : hz/10;
 1914         int i, error;
 1915 
 1916         for (i = 0; i < 100; i++) {
 1917                 if (ipw_read_table1(sc, IPW_INFO_CARD_DISABLED) == waitfor)
 1918                         return 0;
 1919                 error = msleep(sc, &sc->sc_mtx, PCATCH, __func__, ms);
 1920                 if (error == 0 || error != EWOULDBLOCK)
 1921                         return 0;
 1922         }
 1923         DPRINTF(("%s: timeout waiting for %s\n",
 1924                 __func__, waitfor ? "disable" : "enable"));
 1925         return ETIMEDOUT;
 1926 }
 1927 
 1928 static int
 1929 ipw_enable(struct ipw_softc *sc)
 1930 {
 1931         int error;
 1932 
 1933         if ((sc->flags & IPW_FLAG_ENABLED) == 0) {
 1934                 DPRINTF(("Enable adapter\n"));
 1935                 error = ipw_cmd(sc, IPW_CMD_ENABLE, NULL, 0);
 1936                 if (error != 0)
 1937                         return error;
 1938                 error = ipw_waitfordisable(sc, 0);
 1939                 if (error != 0)
 1940                         return error;
 1941                 sc->flags |= IPW_FLAG_ENABLED;
 1942         }
 1943         return 0;
 1944 }
 1945 
 1946 static int
 1947 ipw_disable(struct ipw_softc *sc)
 1948 {
 1949         int error;
 1950 
 1951         if (sc->flags & IPW_FLAG_ENABLED) {
 1952                 DPRINTF(("Disable adapter\n"));
 1953                 error = ipw_cmd(sc, IPW_CMD_DISABLE, NULL, 0);
 1954                 if (error != 0)
 1955                         return error;
 1956                 error = ipw_waitfordisable(sc, 1);
 1957                 if (error != 0)
 1958                         return error;
 1959                 sc->flags &= ~IPW_FLAG_ENABLED;
 1960         }
 1961         return 0;
 1962 }
 1963 
 1964 /*
 1965  * Upload the microcode to the device.
 1966  */
 1967 static int
 1968 ipw_load_ucode(struct ipw_softc *sc, const char *uc, int size)
 1969 {
 1970         int ntries;
 1971 
 1972         MEM_WRITE_4(sc, 0x3000e0, 0x80000000);
 1973         CSR_WRITE_4(sc, IPW_CSR_RST, 0);
 1974 
 1975         MEM_WRITE_2(sc, 0x220000, 0x0703);
 1976         MEM_WRITE_2(sc, 0x220000, 0x0707);
 1977 
 1978         MEM_WRITE_1(sc, 0x210014, 0x72);
 1979         MEM_WRITE_1(sc, 0x210014, 0x72);
 1980 
 1981         MEM_WRITE_1(sc, 0x210000, 0x40);
 1982         MEM_WRITE_1(sc, 0x210000, 0x00);
 1983         MEM_WRITE_1(sc, 0x210000, 0x40);
 1984 
 1985         MEM_WRITE_MULTI_1(sc, 0x210010, uc, size);
 1986 
 1987         MEM_WRITE_1(sc, 0x210000, 0x00);
 1988         MEM_WRITE_1(sc, 0x210000, 0x00);
 1989         MEM_WRITE_1(sc, 0x210000, 0x80);
 1990 
 1991         MEM_WRITE_2(sc, 0x220000, 0x0703);
 1992         MEM_WRITE_2(sc, 0x220000, 0x0707);
 1993 
 1994         MEM_WRITE_1(sc, 0x210014, 0x72);
 1995         MEM_WRITE_1(sc, 0x210014, 0x72);
 1996 
 1997         MEM_WRITE_1(sc, 0x210000, 0x00);
 1998         MEM_WRITE_1(sc, 0x210000, 0x80);
 1999 
 2000         for (ntries = 0; ntries < 10; ntries++) {
 2001                 if (MEM_READ_1(sc, 0x210000) & 1)
 2002                         break;
 2003                 DELAY(10);
 2004         }
 2005         if (ntries == 10) {
 2006                 device_printf(sc->sc_dev,
 2007                     "timeout waiting for ucode to initialize\n");
 2008                 return EIO;
 2009         }
 2010 
 2011         MEM_WRITE_4(sc, 0x3000e0, 0);
 2012 
 2013         return 0;
 2014 }
 2015 
 2016 /* set of macros to handle unaligned little endian data in firmware image */
 2017 #define GETLE32(p) ((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3] << 24)
 2018 #define GETLE16(p) ((p)[0] | (p)[1] << 8)
 2019 static int
 2020 ipw_load_firmware(struct ipw_softc *sc, const char *fw, int size)
 2021 {
 2022         const uint8_t *p, *end;
 2023         uint32_t tmp, dst;
 2024         uint16_t len;
 2025         int error;
 2026 
 2027         p = fw;
 2028         end = fw + size;
 2029         while (p < end) {
 2030                 dst = GETLE32(p); p += 4;
 2031                 len = GETLE16(p); p += 2;
 2032 
 2033                 ipw_write_mem_1(sc, dst, p, len);
 2034                 p += len;
 2035         }
 2036 
 2037         CSR_WRITE_4(sc, IPW_CSR_IO, IPW_IO_GPIO1_ENABLE | IPW_IO_GPIO3_MASK |
 2038             IPW_IO_LED_OFF);
 2039 
 2040         /* enable interrupts */
 2041         CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, IPW_INTR_MASK);
 2042 
 2043         /* kick the firmware */
 2044         CSR_WRITE_4(sc, IPW_CSR_RST, 0);
 2045 
 2046         tmp = CSR_READ_4(sc, IPW_CSR_CTL);
 2047         CSR_WRITE_4(sc, IPW_CSR_CTL, tmp | IPW_CTL_ALLOW_STANDBY);
 2048 
 2049         /* wait at most one second for firmware initialization to complete */
 2050         if ((error = msleep(sc, &sc->sc_mtx, 0, "ipwinit", hz)) != 0) {
 2051                 device_printf(sc->sc_dev, "timeout waiting for firmware "
 2052                     "initialization to complete\n");
 2053                 return error;
 2054         }
 2055 
 2056         tmp = CSR_READ_4(sc, IPW_CSR_IO);
 2057         CSR_WRITE_4(sc, IPW_CSR_IO, tmp | IPW_IO_GPIO1_MASK |
 2058             IPW_IO_GPIO3_MASK);
 2059 
 2060         return 0;
 2061 }
 2062 
 2063 static int
 2064 ipw_setwepkeys(struct ipw_softc *sc)
 2065 {
 2066         struct ifnet *ifp = sc->sc_ifp;
 2067         struct ieee80211com *ic = ifp->if_l2com;
 2068         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 2069         struct ipw_wep_key wepkey;
 2070         struct ieee80211_key *wk;
 2071         int error, i;
 2072 
 2073         for (i = 0; i < IEEE80211_WEP_NKID; i++) {
 2074                 wk = &vap->iv_nw_keys[i];
 2075 
 2076                 if (wk->wk_cipher == NULL ||
 2077                     wk->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP)
 2078                         continue;
 2079 
 2080                 wepkey.idx = i;
 2081                 wepkey.len = wk->wk_keylen;
 2082                 memset(wepkey.key, 0, sizeof wepkey.key);
 2083                 memcpy(wepkey.key, wk->wk_key, wk->wk_keylen);
 2084                 DPRINTF(("Setting wep key index %u len %u\n", wepkey.idx,
 2085                     wepkey.len));
 2086                 error = ipw_cmd(sc, IPW_CMD_SET_WEP_KEY, &wepkey,
 2087                     sizeof wepkey);
 2088                 if (error != 0)
 2089                         return error;
 2090         }
 2091         return 0;
 2092 }
 2093 
 2094 static int
 2095 ipw_setwpaie(struct ipw_softc *sc, const void *ie, int ielen)
 2096 {
 2097         struct ipw_wpa_ie wpaie;
 2098 
 2099         memset(&wpaie, 0, sizeof(wpaie));
 2100         wpaie.len = htole32(ielen);
 2101         /* XXX verify length */
 2102         memcpy(&wpaie.ie, ie, ielen);
 2103         DPRINTF(("Setting WPA IE\n"));
 2104         return ipw_cmd(sc, IPW_CMD_SET_WPA_IE, &wpaie, sizeof(wpaie));
 2105 }
 2106 
 2107 static int
 2108 ipw_setbssid(struct ipw_softc *sc, uint8_t *bssid)
 2109 {
 2110         static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
 2111 
 2112         if (bssid == NULL || bcmp(bssid, zerobssid, IEEE80211_ADDR_LEN) == 0) {
 2113                 DPRINTF(("Setting mandatory BSSID to null\n"));
 2114                 return ipw_cmd(sc, IPW_CMD_SET_MANDATORY_BSSID, NULL, 0);
 2115         } else {
 2116                 DPRINTF(("Setting mandatory BSSID to %6D\n", bssid, ":"));
 2117                 return ipw_cmd(sc, IPW_CMD_SET_MANDATORY_BSSID,
 2118                         bssid, IEEE80211_ADDR_LEN);
 2119         }
 2120 }
 2121 
 2122 static int
 2123 ipw_setssid(struct ipw_softc *sc, void *ssid, size_t ssidlen)
 2124 {
 2125         if (ssidlen == 0) {
 2126                 /*
 2127                  * A bug in the firmware breaks the ``don't associate''
 2128                  * bit in the scan options command.  To compensate for
 2129                  * this install a bogus ssid when no ssid is specified
 2130                  * so the firmware won't try to associate.
 2131                  */
 2132                 DPRINTF(("Setting bogus ESSID to WAR firmware bug\n"));
 2133                 return ipw_cmd(sc, IPW_CMD_SET_ESSID,
 2134                         "\x18\x19\x20\x21\x22\x23\x24\x25\x26\x27"
 2135                         "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31"
 2136                         "\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b"
 2137                         "\x3c\x3d", IEEE80211_NWID_LEN);
 2138         } else {
 2139 #ifdef IPW_DEBUG
 2140                 if (ipw_debug > 0) {
 2141                         printf("Setting ESSID to ");
 2142                         ieee80211_print_essid(ssid, ssidlen);
 2143                         printf("\n");
 2144                 }
 2145 #endif
 2146                 return ipw_cmd(sc, IPW_CMD_SET_ESSID, ssid, ssidlen);
 2147         }
 2148 }
 2149 
 2150 static int
 2151 ipw_setscanopts(struct ipw_softc *sc, uint32_t chanmask, uint32_t flags)
 2152 {
 2153         struct ipw_scan_options opts;
 2154 
 2155         DPRINTF(("Scan options: mask 0x%x flags 0x%x\n", chanmask, flags));
 2156         opts.channels = htole32(chanmask);
 2157         opts.flags = htole32(flags);
 2158         return ipw_cmd(sc, IPW_CMD_SET_SCAN_OPTIONS, &opts, sizeof(opts));
 2159 }
 2160 
 2161 static int
 2162 ipw_scan(struct ipw_softc *sc)
 2163 {
 2164         uint32_t params;
 2165         int error;
 2166 
 2167         DPRINTF(("%s: flags 0x%x\n", __func__, sc->flags));
 2168 
 2169         if (sc->flags & IPW_FLAG_SCANNING)
 2170                 return (EBUSY);
 2171         sc->flags |= IPW_FLAG_SCANNING | IPW_FLAG_HACK;
 2172 
 2173         /* NB: IPW_SCAN_DO_NOT_ASSOCIATE does not work (we set it anyway) */
 2174         error = ipw_setscanopts(sc, 0x3fff, IPW_SCAN_DO_NOT_ASSOCIATE);
 2175         if (error != 0)
 2176                 goto done;
 2177 
 2178         /*
 2179          * Setup null/bogus ssid so firmware doesn't use any previous
 2180          * ssid to try and associate.  This is because the ``don't
 2181          * associate'' option bit is broken (sigh).
 2182          */
 2183         error = ipw_setssid(sc, NULL, 0);
 2184         if (error != 0)
 2185                 goto done;
 2186 
 2187         /*
 2188          * NB: the adapter may be disabled on association lost;
 2189          *     if so just re-enable it to kick off scanning.
 2190          */
 2191         DPRINTF(("Starting scan\n"));
 2192         sc->sc_scan_timer = 3;
 2193         if (sc->flags & IPW_FLAG_ENABLED) {
 2194                 params = 0;                             /* XXX? */
 2195                 error = ipw_cmd(sc, IPW_CMD_BROADCAST_SCAN,
 2196                                 &params, sizeof(params));
 2197         } else
 2198                 error = ipw_enable(sc);
 2199 done:
 2200         if (error != 0) {
 2201                 DPRINTF(("Scan failed\n"));
 2202                 sc->flags &= ~(IPW_FLAG_SCANNING | IPW_FLAG_HACK);
 2203         }
 2204         return (error);
 2205 }
 2206 
 2207 static int
 2208 ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan)
 2209 {
 2210         struct ifnet *ifp = sc->sc_ifp;
 2211         struct ieee80211com *ic = ifp->if_l2com;
 2212         uint32_t data;
 2213         int error;
 2214 
 2215         data = htole32(ieee80211_chan2ieee(ic, chan));
 2216         DPRINTF(("Setting channel to %u\n", le32toh(data)));
 2217         error = ipw_cmd(sc, IPW_CMD_SET_CHANNEL, &data, sizeof data);
 2218         if (error == 0)
 2219                 ipw_setcurchan(sc, chan);
 2220         return error;
 2221 }
 2222 
 2223 static void
 2224 ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap)
 2225 {
 2226         struct ifnet *ifp = vap->iv_ic->ic_ifp;
 2227         struct ipw_softc *sc = ifp->if_softc;
 2228         struct ieee80211_node *ni = vap->iv_bss;
 2229         struct ipw_security security;
 2230         uint32_t data;
 2231         int error;
 2232 
 2233         IPW_LOCK(sc);
 2234         error = ipw_disable(sc);
 2235         if (error != 0)
 2236                 goto done;
 2237 
 2238         memset(&security, 0, sizeof security);
 2239         security.authmode = (ni->ni_authmode == IEEE80211_AUTH_SHARED) ?
 2240             IPW_AUTH_SHARED : IPW_AUTH_OPEN;
 2241         security.ciphers = htole32(IPW_CIPHER_NONE);
 2242         DPRINTF(("Setting authmode to %u\n", security.authmode));
 2243         error = ipw_cmd(sc, IPW_CMD_SET_SECURITY_INFO, &security,
 2244             sizeof security);
 2245         if (error != 0)
 2246                 goto done;
 2247 
 2248         data = htole32(vap->iv_rtsthreshold);
 2249         DPRINTF(("Setting RTS threshold to %u\n", le32toh(data)));
 2250         error = ipw_cmd(sc, IPW_CMD_SET_RTS_THRESHOLD, &data, sizeof data);
 2251         if (error != 0)
 2252                 goto done;
 2253 
 2254         data = htole32(vap->iv_fragthreshold);
 2255         DPRINTF(("Setting frag threshold to %u\n", le32toh(data)));
 2256         error = ipw_cmd(sc, IPW_CMD_SET_FRAG_THRESHOLD, &data, sizeof data);
 2257         if (error != 0)
 2258                 goto done;
 2259 
 2260         if (vap->iv_flags & IEEE80211_F_PRIVACY) {
 2261                 error = ipw_setwepkeys(sc);
 2262                 if (error != 0)
 2263                         goto done;
 2264 
 2265                 if (vap->iv_def_txkey != IEEE80211_KEYIX_NONE) {
 2266                         data = htole32(vap->iv_def_txkey);
 2267                         DPRINTF(("Setting wep tx key index to %u\n",
 2268                                 le32toh(data)));
 2269                         error = ipw_cmd(sc, IPW_CMD_SET_WEP_KEY_INDEX, &data,
 2270                             sizeof data);
 2271                         if (error != 0)
 2272                                 goto done;
 2273                 }
 2274         }
 2275 
 2276         data = htole32((vap->iv_flags & IEEE80211_F_PRIVACY) ? IPW_WEPON : 0);
 2277         DPRINTF(("Setting wep flags to 0x%x\n", le32toh(data)));
 2278         error = ipw_cmd(sc, IPW_CMD_SET_WEP_FLAGS, &data, sizeof data);
 2279         if (error != 0)
 2280                 goto done;
 2281 
 2282         error = ipw_setssid(sc, ni->ni_essid, ni->ni_esslen);
 2283         if (error != 0)
 2284                 goto done;
 2285 
 2286         error = ipw_setbssid(sc, ni->ni_bssid);
 2287         if (error != 0)
 2288                 goto done;
 2289 
 2290         if (vap->iv_appie_wpa != NULL) {
 2291                 struct ieee80211_appie *ie = vap->iv_appie_wpa;
 2292                 error = ipw_setwpaie(sc, ie->ie_data, ie->ie_len);
 2293                 if (error != 0)
 2294                         goto done;
 2295         }
 2296         if (ic->ic_opmode == IEEE80211_M_IBSS) {
 2297                 error = ipw_setchannel(sc, ni->ni_chan);
 2298                 if (error != 0)
 2299                         goto done;
 2300         }
 2301 
 2302         /* lock scan to ap's channel and enable associate */
 2303         error = ipw_setscanopts(sc,
 2304             1<<(ieee80211_chan2ieee(ic, ni->ni_chan)-1), 0);
 2305         if (error != 0)
 2306                 goto done;
 2307 
 2308         error = ipw_enable(sc);         /* finally, enable adapter */
 2309         if (error == 0)
 2310                 sc->flags |= IPW_FLAG_ASSOCIATING;
 2311 done:
 2312         IPW_UNLOCK(sc);
 2313 }
 2314 
 2315 static void
 2316 ipw_disassoc(struct ieee80211com *ic, struct ieee80211vap *vap)
 2317 {
 2318         struct ifnet *ifp = vap->iv_ic->ic_ifp;
 2319         struct ieee80211_node *ni = vap->iv_bss;
 2320         struct ipw_softc *sc = ifp->if_softc;
 2321 
 2322         IPW_LOCK(sc);
 2323         DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":"));
 2324         /*
 2325          * NB: don't try to do this if ipw_stop_master has
 2326          *     shutdown the firmware and disabled interrupts.
 2327          */
 2328         if (sc->flags & IPW_FLAG_FW_INITED) {
 2329                 sc->flags &= ~IPW_FLAG_ASSOCIATED;
 2330                 /*
 2331                  * NB: firmware currently ignores bssid parameter, but
 2332                  *     supply it in case this changes (follow linux driver).
 2333                  */
 2334                 (void) ipw_cmd(sc, IPW_CMD_DISASSOCIATE,
 2335                         ni->ni_bssid, IEEE80211_ADDR_LEN);
 2336         }
 2337         IPW_UNLOCK(sc);
 2338 }
 2339 
 2340 /*
 2341  * Handler for sc_init_task.  This is a simple wrapper around ipw_init().
 2342  * It is called on firmware panics or on watchdog timeouts.
 2343  */
 2344 static void
 2345 ipw_init_task(void *context, int pending)
 2346 {
 2347         ipw_init(context);
 2348 }
 2349 
 2350 static void
 2351 ipw_init(void *priv)
 2352 {
 2353         struct ipw_softc *sc = priv;
 2354         struct ifnet *ifp = sc->sc_ifp;
 2355         struct ieee80211com *ic = ifp->if_l2com;
 2356 
 2357         IPW_LOCK(sc);
 2358         ipw_init_locked(sc);
 2359         IPW_UNLOCK(sc);
 2360 
 2361         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 2362                 ieee80211_start_all(ic);                /* start all vap's */
 2363 }
 2364 
 2365 static void
 2366 ipw_init_locked(struct ipw_softc *sc)
 2367 {
 2368         struct ifnet *ifp = sc->sc_ifp;
 2369         struct ieee80211com *ic = ifp->if_l2com;
 2370         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 2371         const struct firmware *fp;
 2372         const struct ipw_firmware_hdr *hdr;
 2373         const char *fw;
 2374 
 2375         IPW_LOCK_ASSERT(sc);
 2376 
 2377         DPRINTF(("%s: state %s flags 0x%x\n", __func__,
 2378                 ieee80211_state_name[vap->iv_state], sc->flags));
 2379 
 2380         /*
 2381          * Avoid re-entrant calls.  We need to release the mutex in ipw_init()
 2382          * when loading the firmware and we don't want to be called during this
 2383          * operation.
 2384          */
 2385         if (sc->flags & IPW_FLAG_INIT_LOCKED)
 2386                 return;
 2387         sc->flags |= IPW_FLAG_INIT_LOCKED;
 2388 
 2389         ipw_stop_locked(sc);
 2390 
 2391         if (ipw_reset(sc) != 0) {
 2392                 device_printf(sc->sc_dev, "could not reset adapter\n");
 2393                 goto fail;
 2394         }
 2395 
 2396         if (sc->sc_firmware == NULL) {
 2397                 device_printf(sc->sc_dev, "no firmware\n");
 2398                 goto fail;
 2399         }
 2400         /* NB: consistency already checked on load */
 2401         fp = sc->sc_firmware;
 2402         hdr = (const struct ipw_firmware_hdr *)fp->data;
 2403 
 2404         DPRINTF(("Loading firmware image '%s'\n", fp->name));
 2405         fw = (const char *)fp->data + sizeof *hdr + le32toh(hdr->mainsz);
 2406         if (ipw_load_ucode(sc, fw, le32toh(hdr->ucodesz)) != 0) {
 2407                 device_printf(sc->sc_dev, "could not load microcode\n");
 2408                 goto fail;
 2409         }
 2410 
 2411         ipw_stop_master(sc);
 2412 
 2413         /*
 2414          * Setup tx, rx and status rings.
 2415          */
 2416         sc->txold = IPW_NTBD - 1;
 2417         sc->txcur = 0;
 2418         sc->txfree = IPW_NTBD - 2;
 2419         sc->rxcur = IPW_NRBD - 1;
 2420 
 2421         CSR_WRITE_4(sc, IPW_CSR_TX_BASE,  sc->tbd_phys);
 2422         CSR_WRITE_4(sc, IPW_CSR_TX_SIZE,  IPW_NTBD);
 2423         CSR_WRITE_4(sc, IPW_CSR_TX_READ,  0);
 2424         CSR_WRITE_4(sc, IPW_CSR_TX_WRITE, sc->txcur);
 2425 
 2426         CSR_WRITE_4(sc, IPW_CSR_RX_BASE,  sc->rbd_phys);
 2427         CSR_WRITE_4(sc, IPW_CSR_RX_SIZE,  IPW_NRBD);
 2428         CSR_WRITE_4(sc, IPW_CSR_RX_READ,  0);
 2429         CSR_WRITE_4(sc, IPW_CSR_RX_WRITE, sc->rxcur);
 2430 
 2431         CSR_WRITE_4(sc, IPW_CSR_STATUS_BASE, sc->status_phys);
 2432 
 2433         fw = (const char *)fp->data + sizeof *hdr;
 2434         if (ipw_load_firmware(sc, fw, le32toh(hdr->mainsz)) != 0) {
 2435                 device_printf(sc->sc_dev, "could not load firmware\n");
 2436                 goto fail;
 2437         }
 2438 
 2439         sc->flags |= IPW_FLAG_FW_INITED;
 2440 
 2441         /* retrieve information tables base addresses */
 2442         sc->table1_base = CSR_READ_4(sc, IPW_CSR_TABLE1_BASE);
 2443         sc->table2_base = CSR_READ_4(sc, IPW_CSR_TABLE2_BASE);
 2444 
 2445         ipw_write_table1(sc, IPW_INFO_LOCK, 0);
 2446 
 2447         if (ipw_config(sc) != 0) {
 2448                 device_printf(sc->sc_dev, "device configuration failed\n");
 2449                 goto fail;
 2450         }
 2451 
 2452         callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc);
 2453         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 2454         ifp->if_drv_flags |= IFF_DRV_RUNNING;
 2455 
 2456         sc->flags &=~ IPW_FLAG_INIT_LOCKED;
 2457         return;
 2458 
 2459 fail:
 2460         ipw_stop_locked(sc);
 2461         sc->flags &=~ IPW_FLAG_INIT_LOCKED;
 2462 }
 2463 
 2464 static int
 2465 ipw_config(struct ipw_softc *sc)
 2466 {
 2467         struct ifnet *ifp = sc->sc_ifp;
 2468         struct ieee80211com *ic = ifp->if_l2com;
 2469         struct ipw_configuration config;
 2470         uint32_t data;
 2471         int error;
 2472 
 2473         error = ipw_disable(sc);
 2474         if (error != 0)
 2475                 return error;
 2476 
 2477         switch (ic->ic_opmode) {
 2478         case IEEE80211_M_STA:
 2479         case IEEE80211_M_HOSTAP:
 2480         case IEEE80211_M_WDS:           /* XXX */
 2481                 data = htole32(IPW_MODE_BSS);
 2482                 break;
 2483         case IEEE80211_M_IBSS:
 2484         case IEEE80211_M_AHDEMO:
 2485                 data = htole32(IPW_MODE_IBSS);
 2486                 break;
 2487         case IEEE80211_M_MONITOR:
 2488                 data = htole32(IPW_MODE_MONITOR);
 2489                 break;
 2490         default:
 2491                 device_printf(sc->sc_dev, "unknown opmode %d\n", ic->ic_opmode);
 2492                 return EINVAL;
 2493         }
 2494         DPRINTF(("Setting mode to %u\n", le32toh(data)));
 2495         error = ipw_cmd(sc, IPW_CMD_SET_MODE, &data, sizeof data);
 2496         if (error != 0)
 2497                 return error;
 2498 
 2499         if (ic->ic_opmode == IEEE80211_M_IBSS ||
 2500             ic->ic_opmode == IEEE80211_M_MONITOR) {
 2501                 error = ipw_setchannel(sc, ic->ic_curchan);
 2502                 if (error != 0)
 2503                         return error;
 2504         }
 2505 
 2506         if (ic->ic_opmode == IEEE80211_M_MONITOR)
 2507                 return ipw_enable(sc);
 2508 
 2509         config.flags = htole32(IPW_CFG_BSS_MASK | IPW_CFG_IBSS_MASK |
 2510             IPW_CFG_PREAMBLE_AUTO | IPW_CFG_802_1x_ENABLE);
 2511         if (ic->ic_opmode == IEEE80211_M_IBSS)
 2512                 config.flags |= htole32(IPW_CFG_IBSS_AUTO_START);
 2513         if (ifp->if_flags & IFF_PROMISC)
 2514                 config.flags |= htole32(IPW_CFG_PROMISCUOUS);
 2515         config.bss_chan = htole32(0x3fff); /* channels 1-14 */
 2516         config.ibss_chan = htole32(0x7ff); /* channels 1-11 */
 2517         DPRINTF(("Setting configuration to 0x%x\n", le32toh(config.flags)));
 2518         error = ipw_cmd(sc, IPW_CMD_SET_CONFIGURATION, &config, sizeof config);
 2519         if (error != 0)
 2520                 return error;
 2521 
 2522         data = htole32(0xf); /* 1, 2, 5.5, 11 */
 2523         DPRINTF(("Setting basic tx rates to 0x%x\n", le32toh(data)));
 2524         error = ipw_cmd(sc, IPW_CMD_SET_BASIC_TX_RATES, &data, sizeof data);
 2525         if (error != 0)
 2526                 return error;
 2527 
 2528         /* Use the same rate set */
 2529         DPRINTF(("Setting msdu tx rates to 0x%x\n", le32toh(data)));
 2530         error = ipw_cmd(sc, IPW_CMD_SET_MSDU_TX_RATES, &data, sizeof data);
 2531         if (error != 0)
 2532                 return error;
 2533 
 2534         /* Use the same rate set */
 2535         DPRINTF(("Setting tx rates to 0x%x\n", le32toh(data)));
 2536         error = ipw_cmd(sc, IPW_CMD_SET_TX_RATES, &data, sizeof data);
 2537         if (error != 0)
 2538                 return error;
 2539 
 2540         data = htole32(IPW_POWER_MODE_CAM);
 2541         DPRINTF(("Setting power mode to %u\n", le32toh(data)));
 2542         error = ipw_cmd(sc, IPW_CMD_SET_POWER_MODE, &data, sizeof data);
 2543         if (error != 0)
 2544                 return error;
 2545 
 2546         if (ic->ic_opmode == IEEE80211_M_IBSS) {
 2547                 data = htole32(32); /* default value */
 2548                 DPRINTF(("Setting tx power index to %u\n", le32toh(data)));
 2549                 error = ipw_cmd(sc, IPW_CMD_SET_TX_POWER_INDEX, &data,
 2550                     sizeof data);
 2551                 if (error != 0)
 2552                         return error;
 2553         }
 2554 
 2555         return 0;
 2556 }
 2557 
 2558 static void
 2559 ipw_stop(void *priv)
 2560 {
 2561         struct ipw_softc *sc = priv;
 2562 
 2563         IPW_LOCK(sc);
 2564         ipw_stop_locked(sc);
 2565         IPW_UNLOCK(sc);
 2566 }
 2567 
 2568 static void
 2569 ipw_stop_locked(struct ipw_softc *sc)
 2570 {
 2571         struct ifnet *ifp = sc->sc_ifp;
 2572         int i;
 2573 
 2574         IPW_LOCK_ASSERT(sc);
 2575 
 2576         callout_stop(&sc->sc_wdtimer);
 2577         ipw_stop_master(sc);
 2578 
 2579         CSR_WRITE_4(sc, IPW_CSR_RST, IPW_RST_SW_RESET);
 2580 
 2581         /*
 2582          * Release tx buffers.
 2583          */
 2584         for (i = 0; i < IPW_NTBD; i++)
 2585                 ipw_release_sbd(sc, &sc->stbd_list[i]);
 2586 
 2587         sc->sc_tx_timer = 0;
 2588         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 2589 }
 2590 
 2591 static int
 2592 ipw_sysctl_stats(SYSCTL_HANDLER_ARGS)
 2593 {
 2594         struct ipw_softc *sc = arg1;
 2595         uint32_t i, size, buf[256];
 2596 
 2597         memset(buf, 0, sizeof buf);
 2598 
 2599         if (!(sc->flags & IPW_FLAG_FW_INITED))
 2600                 return SYSCTL_OUT(req, buf, sizeof buf);
 2601 
 2602         CSR_WRITE_4(sc, IPW_CSR_AUTOINC_ADDR, sc->table1_base);
 2603 
 2604         size = min(CSR_READ_4(sc, IPW_CSR_AUTOINC_DATA), 256);
 2605         for (i = 1; i < size; i++)
 2606                 buf[i] = MEM_READ_4(sc, CSR_READ_4(sc, IPW_CSR_AUTOINC_DATA));
 2607 
 2608         return SYSCTL_OUT(req, buf, size);
 2609 }
 2610 
 2611 static int
 2612 ipw_sysctl_radio(SYSCTL_HANDLER_ARGS)
 2613 {
 2614         struct ipw_softc *sc = arg1;
 2615         int val;
 2616 
 2617         val = !((sc->flags & IPW_FLAG_HAS_RADIO_SWITCH) &&
 2618                 (CSR_READ_4(sc, IPW_CSR_IO) & IPW_IO_RADIO_DISABLED));
 2619 
 2620         return SYSCTL_OUT(req, &val, sizeof val);
 2621 }
 2622 
 2623 static uint32_t
 2624 ipw_read_table1(struct ipw_softc *sc, uint32_t off)
 2625 {
 2626         return MEM_READ_4(sc, MEM_READ_4(sc, sc->table1_base + off));
 2627 }
 2628 
 2629 static void
 2630 ipw_write_table1(struct ipw_softc *sc, uint32_t off, uint32_t info)
 2631 {
 2632         MEM_WRITE_4(sc, MEM_READ_4(sc, sc->table1_base + off), info);
 2633 }
 2634 
 2635 #if 0
 2636 static int
 2637 ipw_read_table2(struct ipw_softc *sc, uint32_t off, void *buf, uint32_t *len)
 2638 {
 2639         uint32_t addr, info;
 2640         uint16_t count, size;
 2641         uint32_t total;
 2642 
 2643         /* addr[4] + count[2] + size[2] */
 2644         addr = MEM_READ_4(sc, sc->table2_base + off);
 2645         info = MEM_READ_4(sc, sc->table2_base + off + 4);
 2646 
 2647         count = info >> 16;
 2648         size = info & 0xffff;
 2649         total = count * size;
 2650 
 2651         if (total > *len) {
 2652                 *len = total;
 2653                 return EINVAL;
 2654         }
 2655 
 2656         *len = total;
 2657         ipw_read_mem_1(sc, addr, buf, total);
 2658 
 2659         return 0;
 2660 }
 2661 
 2662 static void
 2663 ipw_read_mem_1(struct ipw_softc *sc, bus_size_t offset, uint8_t *datap,
 2664     bus_size_t count)
 2665 {
 2666         for (; count > 0; offset++, datap++, count--) {
 2667                 CSR_WRITE_4(sc, IPW_CSR_INDIRECT_ADDR, offset & ~3);
 2668                 *datap = CSR_READ_1(sc, IPW_CSR_INDIRECT_DATA + (offset & 3));
 2669         }
 2670 }
 2671 #endif
 2672 
 2673 static void
 2674 ipw_write_mem_1(struct ipw_softc *sc, bus_size_t offset, const uint8_t *datap,
 2675     bus_size_t count)
 2676 {
 2677         for (; count > 0; offset++, datap++, count--) {
 2678                 CSR_WRITE_4(sc, IPW_CSR_INDIRECT_ADDR, offset & ~3);
 2679                 CSR_WRITE_1(sc, IPW_CSR_INDIRECT_DATA + (offset & 3), *datap);
 2680         }
 2681 }
 2682 
 2683 static void
 2684 ipw_scan_start(struct ieee80211com *ic)
 2685 {
 2686         struct ifnet *ifp = ic->ic_ifp;
 2687         struct ipw_softc *sc = ifp->if_softc;
 2688 
 2689         IPW_LOCK(sc);
 2690         ipw_scan(sc);
 2691         IPW_UNLOCK(sc);
 2692 }
 2693 
 2694 static void
 2695 ipw_set_channel(struct ieee80211com *ic)
 2696 {
 2697         struct ifnet *ifp = ic->ic_ifp;
 2698         struct ipw_softc *sc = ifp->if_softc;
 2699 
 2700         IPW_LOCK(sc);
 2701         if (ic->ic_opmode == IEEE80211_M_MONITOR) {
 2702                 ipw_disable(sc);
 2703                 ipw_setchannel(sc, ic->ic_curchan);
 2704                 ipw_enable(sc);
 2705         }
 2706         IPW_UNLOCK(sc);
 2707 }
 2708 
 2709 static void
 2710 ipw_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
 2711 {
 2712         /* NB: all channels are scanned at once */
 2713 }
 2714 
 2715 static void
 2716 ipw_scan_mindwell(struct ieee80211_scan_state *ss)
 2717 {
 2718         /* NB: don't try to abort scan; wait for firmware to finish */
 2719 }
 2720 
 2721 static void
 2722 ipw_scan_end(struct ieee80211com *ic)
 2723 {
 2724         struct ifnet *ifp = ic->ic_ifp;
 2725         struct ipw_softc *sc = ifp->if_softc;
 2726 
 2727         IPW_LOCK(sc);
 2728         sc->flags &= ~IPW_FLAG_SCANNING;
 2729         IPW_UNLOCK(sc);
 2730 }

Cache object: 62ffd9b2abcb6df9de5b4aa8ea174a63


[ 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.