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/netif/iwl/iwl2100.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 /*
    2  * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
    3  * 
    4  * This code is derived from software contributed to The DragonFly Project
    5  * by Sepherosa Ziehau <sepherosa@gmail.com>
    6  * 
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in
   15  *    the documentation and/or other materials provided with the
   16  *    distribution.
   17  * 3. Neither the name of The DragonFly Project nor the names of its
   18  *    contributors may be used to endorse or promote products derived
   19  *    from this software without specific, prior written permission.
   20  * 
   21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
   25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
   27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  */
   34 
   35 #include <sys/param.h>
   36 #include <sys/bus.h>
   37 #include <sys/endian.h>
   38 #include <sys/firmware.h>
   39 #include <sys/kernel.h>
   40 #include <sys/interrupt.h>
   41 #include <sys/mbuf.h>
   42 #include <sys/module.h>
   43 #include <sys/sysctl.h>
   44 #include <sys/socket.h>
   45 #include <sys/sockio.h>
   46 #include <sys/rman.h>
   47 
   48 #include <net/bpf.h>
   49 #include <net/if.h>
   50 #include <net/if_arp.h>
   51 #include <net/ethernet.h>
   52 #include <net/if_dl.h>
   53 #include <net/if_media.h>
   54 #include <net/ifq_var.h>
   55 #include <net/netmsg2.h>
   56 
   57 #include <netproto/802_11/ieee80211_var.h>
   58 #include <netproto/802_11/ieee80211_radiotap.h>
   59 
   60 #include <bus/pci/pcireg.h>
   61 #include <bus/pci/pcivar.h>
   62 
   63 #include "if_iwlvar.h"
   64 #include "iwl2100reg.h"
   65 #include "iwl2100var.h"
   66 
   67 #define IWL2100_INIT_F_ENABLE   0x1
   68 #define IWL2100_INIT_F_IBSSCHAN 0x2
   69 
   70 #define sc_tx_th        sc_u_tx_th.u_tx_th
   71 #define sc_rx_th        sc_u_rx_th.u_rx_th
   72 
   73 static void     iwl2100_init(void *);
   74 static int      iwl2100_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
   75 static void     iwl2100_start(struct ifnet *, struct ifaltq_subque *);
   76 static void     iwl2100_watchdog(struct ifnet *);
   77 static int      iwl2100_newstate(struct ieee80211com *, enum ieee80211_state, int);
   78 static int      iwl2100_media_change(struct ifnet *);
   79 static void     iwl2100_media_status(struct ifnet *, struct ifmediareq *);
   80 static void     iwl2100_stop(struct iwl2100_softc *);
   81 static void     iwl2100_restart(struct iwl2100_softc *);
   82 static void     iwl2100_reinit(struct iwl2100_softc *);
   83 
   84 static void     iwl2100_intr(void *);
   85 static void     iwl2100_txeof(struct iwl2100_softc *);
   86 static void     iwl2100_rxeof(struct iwl2100_softc *);
   87 static void     iwl2100_rxeof_status(struct iwl2100_softc *, int);
   88 static void     iwl2100_rxeof_note(struct iwl2100_softc *, int);
   89 static void     iwl2100_rxeof_cmd(struct iwl2100_softc *, int);
   90 static void     iwl2100_rxeof_data(struct iwl2100_softc *, int);
   91 
   92 static void     iwl2100_init_dispatch(struct netmsg *);
   93 static void     iwl2100_reinit_dispatch(struct netmsg *);
   94 static void     iwl2100_stop_dispatch(struct netmsg *);
   95 static void     iwl2100_newstate_dispatch(struct netmsg *);
   96 static void     iwl2100_scanend_dispatch(struct netmsg *);
   97 static void     iwl2100_restart_dispatch(struct netmsg *);
   98 static void     iwl2100_bmiss_dispatch(struct netmsg *);
   99 
  100 static void     iwl2100_stop_callouts(struct iwl2100_softc *);
  101 static void     iwl2100_restart_bmiss(void *);
  102 static void     iwl2100_ibss_bssid(void *);
  103 static void     iwl2100_reinit_callout(void *);
  104 
  105 static int      iwl2100_dma_alloc(device_t);
  106 static void     iwl2100_dma_free(device_t);
  107 static int      iwl2100_dma_mbuf_create(device_t);
  108 static void     iwl2100_dma_mbuf_destroy(device_t, int, int);
  109 static int      iwl2100_init_tx_ring(struct iwl2100_softc *);
  110 static int      iwl2100_init_rx_ring(struct iwl2100_softc *);
  111 static void     iwl2100_free_tx_ring(struct iwl2100_softc *);
  112 static void     iwl2100_free_rx_ring(struct iwl2100_softc *);
  113 
  114 static int      iwl2100_alloc_cmd(struct iwl2100_softc *);
  115 static void     iwl2100_free_cmd(struct iwl2100_softc *);
  116 static int      iwl2100_wait_cmd(struct iwl2100_softc *);
  117 
  118 static void     iwl2100_rxdesc_setup(struct iwl2100_softc *, int);
  119 static int      iwl2100_newbuf(struct iwl2100_softc *, int, int);
  120 static int      iwl2100_encap(struct iwl2100_softc *, struct mbuf *);
  121 
  122 static void     iwl2100_chan_change(struct iwl2100_softc *,
  123                                     const struct ieee80211_channel *);
  124 
  125 static int      iwl2100_alloc_firmware(struct iwl2100_softc *,
  126                                        enum ieee80211_opmode);
  127 static void     iwl2100_free_firmware(struct iwl2100_softc *);
  128 static int      iwl2100_load_firmware(struct iwl2100_softc *,
  129                                       enum ieee80211_opmode);
  130 static int      iwl2100_load_fw_ucode(struct iwl2100_softc *,
  131                                       const struct iwl2100_firmware *);
  132 static int      iwl2100_load_fw_data(struct iwl2100_softc *,
  133                                      const struct iwl2100_firmware *);
  134 static int      iwl2100_init_firmware(struct iwl2100_softc *);
  135 
  136 static int      iwl2100_read_ord2(struct iwl2100_softc *, uint32_t,
  137                                   void *, int);
  138 static uint32_t iwl2100_read_ord1(struct iwl2100_softc *, uint32_t);
  139 static void     iwl2100_write_ord1(struct iwl2100_softc *, uint32_t, uint32_t);
  140 
  141 static int      iwl2100_reset(struct iwl2100_softc *);
  142 static int      iwl2100_hw_reset(struct iwl2100_softc *);
  143 static int      iwl2100_rfkilled(struct iwl2100_softc *);
  144 
  145 static int      iwl2100_scan(struct iwl2100_softc *);
  146 static int      iwl2100_auth(struct iwl2100_softc *);
  147 static int      iwl2100_ibss(struct iwl2100_softc *);
  148 
  149 static int      iwl2100_hw_init(struct iwl2100_softc *, const uint8_t *,
  150                                 const uint8_t *, uint8_t, uint32_t);
  151 static void     iwl2100_hw_stop(struct iwl2100_softc *);
  152 static int      iwl2100_config(struct iwl2100_softc *, const uint8_t *,
  153                                const uint8_t *, uint8_t, int);
  154 static int      iwl2100_start_scan(struct iwl2100_softc *, uint32_t, uint32_t);
  155 
  156 static int      iwl2100_config_op(struct iwl2100_softc *, uint32_t);
  157 static int      iwl2100_set_addr(struct iwl2100_softc *, const uint8_t *);
  158 static int      iwl2100_set_opmode(struct iwl2100_softc *,
  159                                    enum ieee80211_opmode);
  160 static int      iwl2100_set_80211(struct iwl2100_softc *);
  161 static int      iwl2100_set_basicrates(struct iwl2100_softc *);
  162 static int      iwl2100_set_txrates(struct iwl2100_softc *);
  163 static int      iwl2100_set_powersave(struct iwl2100_softc *, int);
  164 static int      iwl2100_set_rtsthreshold(struct iwl2100_softc *, uint16_t);
  165 static int      iwl2100_set_bssid(struct iwl2100_softc *, const uint8_t *);
  166 static int      iwl2100_set_essid(struct iwl2100_softc *, const uint8_t *, int);
  167 static int      iwl2100_set_auth_ciphers(struct iwl2100_softc *,
  168                                          enum ieee80211_authmode);
  169 static int      iwl2100_set_wepkey(struct iwl2100_softc *,
  170                                    const struct ieee80211_key *);
  171 static int      iwl2100_set_weptxkey(struct iwl2100_softc *, ieee80211_keyix);
  172 static int      iwl2100_set_privacy(struct iwl2100_softc *, int);
  173 static int      iwl2100_set_chan(struct iwl2100_softc *,
  174                                  const struct ieee80211_channel *);
  175 static int      iwl2100_set_scanopt(struct iwl2100_softc *, uint32_t, uint32_t);
  176 static int      iwl2100_set_scan(struct iwl2100_softc *);
  177 static int      iwl2100_set_optie(struct iwl2100_softc *, void *, uint16_t);
  178 static int      iwl2100_set_bintval(struct iwl2100_softc *, uint16_t);
  179 static int      iwl2100_set_txpower(struct iwl2100_softc *, uint16_t);
  180 
  181 static __inline int
  182 iwl2100_config_done(struct iwl2100_softc *sc)
  183 {
  184         return iwl2100_config_op(sc, IWL2100_CMD_CONF_DONE);
  185 }
  186 
  187 static __inline int
  188 iwl2100_config_start(struct iwl2100_softc *sc)
  189 {
  190         return iwl2100_config_op(sc, IWL2100_CMD_CONF_START);
  191 }
  192 
  193 static __inline void
  194 iwl2100_restart_done(struct iwl2100_softc *sc)
  195 {
  196         callout_stop(&sc->sc_restart_bmiss);
  197         sc->sc_flags &= ~IWL2100_F_RESTARTING;
  198 }
  199 
  200 int
  201 iwl2100_attach(device_t dev)
  202 {
  203         struct iwl2100_softc *sc = device_get_softc(dev);
  204         struct ieee80211com *ic = &sc->sc_ic;
  205         struct ifnet *ifp = &ic->ic_if;
  206         uint16_t val;
  207         int error, i;
  208 
  209         /*
  210          * Linux voodoo:
  211          * Clear the retry timeout PCI configuration register to keep
  212          * PCI TX retries from interfering with C3 CPU state.
  213          */
  214         pci_write_config(dev, IWL2100_PCIR_RETRY_TIMEOUT, 0, 1);
  215 
  216         /*
  217          * Allocate DMA stuffs
  218          */
  219         error = iwl2100_dma_alloc(dev);
  220         if (error)
  221                 return error;
  222 
  223         /* Disable interrupts */
  224         CSR_WRITE_4(sc, IWL2100_INTR_MASK, 0);
  225 
  226         /*
  227          * SW reset before reading EEPROM
  228          */
  229         error = iwl2100_reset(sc);
  230         if (error)
  231                 return error;
  232 
  233         ifp->if_softc = sc;
  234         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  235         ifp->if_init = iwl2100_init;
  236         ifp->if_ioctl = iwl2100_ioctl;
  237         ifp->if_start = iwl2100_start;
  238         ifp->if_watchdog = iwl2100_watchdog;
  239         ifq_set_maxlen(&ifp->if_snd, IWL2100_TX_USED_MAX);
  240 #ifdef notyet
  241         ifq_set_ready(&ifp->if_snd);
  242 #endif
  243 
  244 #ifdef DUMP_EEPROM
  245         device_printf(dev, "eeprom\n");
  246         for (i = 0; i < 128; ++i) {
  247                 if (i != 0 && i % 8 == 0)
  248                         kprintf("\n");
  249                 val = iwl_read_eeprom(&sc->iwlcom, i);
  250                 kprintf("%04x ", val);
  251         }
  252         kprintf("\n");
  253 #endif
  254 
  255         /* IBSS channel mask */
  256         sc->sc_ibss_chans = iwl_read_eeprom(&sc->iwlcom,
  257                             IWL2100_EEPROM_IBSS_CHANS) & IWL2100_CFG_CHANMASK;
  258 
  259         /* BSS channel mask */
  260         sc->sc_bss_chans = iwl_read_eeprom(&sc->iwlcom, IWL2100_EEPROM_CHANS);
  261 
  262         /*
  263          * Set MAC address
  264          */
  265         for (i = 0; i < ETHER_ADDR_LEN / 2; ++i) {
  266                 val = iwl_read_eeprom(&sc->iwlcom, IWL2100_EEPROM_MAC + i);
  267                 ic->ic_myaddr[i * 2] = val >> 8;
  268                 ic->ic_myaddr[(i * 2) + 1] = val & 0xff;
  269         }
  270 
  271         /*
  272          * Set supported channels
  273          */
  274         for (i = 0; i < 14; ++i) {
  275                 if (sc->sc_bss_chans & (1 << i)) {
  276                         int chan = i + 1;
  277 
  278                         ic->ic_channels[chan].ic_freq =
  279                                 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
  280                         ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_B;
  281                 }
  282         }
  283 
  284         ic->ic_sup_rates[IEEE80211_MODE_11B] = iwl_rateset_11b;
  285         ic->ic_phytype = IEEE80211_T_DS;
  286         ic->ic_caps = IEEE80211_C_MONITOR |
  287                       IEEE80211_C_IBSS |
  288                       IEEE80211_C_SHPREAMBLE |
  289                       IEEE80211_C_WPA;
  290         ic->ic_caps_ext = IEEE80211_CEXT_AUTOSCAN;
  291         ic->ic_state = IEEE80211_S_INIT;
  292         ic->ic_opmode = IEEE80211_M_STA;
  293 
  294         ieee80211_ifattach(ic);
  295 
  296         /*
  297          * ieee80211_frame will be stripped on TX path, so only
  298          * extra space needs to be reserved.
  299          */
  300         ic->ic_headroom = sizeof(struct iwl2100_tx_hdr) -
  301                           sizeof(struct ieee80211_frame);
  302 
  303         sc->sc_newstate = ic->ic_newstate;
  304         ic->ic_newstate = iwl2100_newstate;
  305 
  306         ieee80211_media_init(ic, iwl2100_media_change, iwl2100_media_status);
  307 
  308         ifq_set_cpuid(&ifp->if_snd, rman_get_cpuid(sc->sc_irq_res));
  309 
  310         error = bus_setup_intr(dev, sc->sc_irq_res, INTR_MPSAFE,
  311                                iwl2100_intr, sc, &sc->sc_irq_handle,
  312                                ifp->if_serializer);
  313         if (error) {
  314                 device_printf(dev, "can't setup intr\n");
  315                 ieee80211_ifdetach(ic);
  316                 return ENXIO;
  317         }
  318 
  319         /*
  320          * Attach radio tap
  321          */
  322         bpfattach_dlt(ifp, DLT_IEEE802_11_RADIO,
  323                       sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th),
  324                       &sc->sc_drvbpf);
  325 
  326         sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(uint32_t));
  327         sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len);
  328         sc->sc_tx_th.wt_ihdr.it_present = htole32(IWL2100_TX_RADIOTAP_PRESENT);
  329 
  330         sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(uint32_t));
  331         sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len);
  332         sc->sc_rx_th.wr_ihdr.it_present = htole32(IWL2100_RX_RADIOTAP_PRESENT);
  333 
  334         sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
  335                 htole16(IEEE80211_CHAN_B);
  336 
  337         /*
  338          * Create worker thread and initialize all necessary messages
  339          */
  340         iwl_create_thread(&sc->iwlcom, device_get_unit(dev));
  341 
  342         iwlmsg_init(&sc->sc_scanend_msg, &netisr_adone_rport,
  343                     iwl2100_scanend_dispatch, sc);
  344         iwlmsg_init(&sc->sc_restart_msg, &netisr_adone_rport,
  345                     iwl2100_restart_dispatch, sc);
  346         iwlmsg_init(&sc->sc_bmiss_msg, &netisr_adone_rport,
  347                     iwl2100_bmiss_dispatch, sc);
  348         iwlmsg_init(&sc->sc_reinit_msg, &netisr_adone_rport,
  349                     iwl2100_reinit_dispatch, sc);
  350 
  351         iwlmsg_init(&sc->sc_assoc_msg, &netisr_adone_rport,
  352                     iwl2100_newstate_dispatch, sc);
  353         sc->sc_assoc_msg.iwlm_nstate = IEEE80211_S_ASSOC;
  354         sc->sc_assoc_msg.iwlm_arg = -1;
  355 
  356         iwlmsg_init(&sc->sc_run_msg, &netisr_adone_rport,
  357                     iwl2100_newstate_dispatch, sc);
  358         sc->sc_run_msg.iwlm_nstate = IEEE80211_S_RUN;
  359         sc->sc_run_msg.iwlm_arg = -1;
  360 
  361         /*
  362          * Initialize callouts
  363          */
  364         callout_init(&sc->sc_restart_bmiss);
  365         callout_init(&sc->sc_ibss);
  366         callout_init(&sc->sc_reinit);
  367 
  368         /* Add sysctl node */
  369         SYSCTL_ADD_UINT(&sc->sc_sysctl_ctx,
  370                         SYSCTL_CHILDREN(sc->sc_sysctl_tree), OID_AUTO,
  371                         "debug", CTLFLAG_RW, &sc->sc_debug, 0, "debug flags");
  372 
  373         if (bootverbose)
  374                 ieee80211_announce(ic);
  375         return 0;
  376 }
  377 
  378 void
  379 iwl2100_detach(device_t dev)
  380 {
  381         struct iwl2100_softc *sc = device_get_softc(dev);
  382 
  383         if (device_is_attached(dev)) {
  384                 struct ifnet *ifp = &sc->sc_ic.ic_if;
  385 
  386                 lwkt_serialize_enter(ifp->if_serializer);
  387 
  388                 sc->sc_flags |= IWL2100_F_DETACH;
  389                 iwl2100_stop(sc);
  390                 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_handle);
  391                 iwl_destroy_thread(&sc->iwlcom);
  392 
  393                 lwkt_serialize_exit(ifp->if_serializer);
  394 
  395                 iwl2100_free_firmware(sc);
  396 
  397                 bpfdetach(ifp);
  398                 ieee80211_ifdetach(&sc->sc_ic);
  399         }
  400         iwl2100_dma_free(dev);
  401 }
  402 
  403 int
  404 iwl2100_shutdown(device_t dev)
  405 {
  406         struct iwl2100_softc *sc = device_get_softc(dev);
  407         struct ifnet *ifp = &sc->sc_ic.ic_if;
  408 
  409         lwkt_serialize_enter(ifp->if_serializer);
  410         iwl2100_stop(sc);
  411         lwkt_serialize_exit(ifp->if_serializer);
  412 
  413         return 0;
  414 }
  415 
  416 static void
  417 iwl2100_stop(struct iwl2100_softc *sc)
  418 {
  419         struct iwlmsg msg;
  420 
  421         ASSERT_SERIALIZED(sc->sc_ic.ic_if.if_serializer);
  422 
  423         iwl2100_stop_callouts(sc);
  424 
  425         iwlmsg_init(&msg, &sc->sc_reply_port, iwl2100_stop_dispatch, sc);
  426         lwkt_domsg(&sc->sc_thread_port, &msg.iwlm_nmsg.nm_lmsg, 0);
  427 }
  428 
  429 static void
  430 iwl2100_stop_dispatch(struct netmsg *nmsg)
  431 {
  432         struct iwlmsg *msg = (struct iwlmsg *)nmsg;
  433         struct iwl2100_softc *sc = msg->iwlm_softc;
  434 
  435         ASSERT_SERIALIZED(sc->sc_ic.ic_if.if_serializer);
  436 
  437         ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
  438         iwl2100_hw_stop(sc);
  439         lwkt_replymsg(&nmsg->nm_lmsg, 0);
  440 }
  441 
  442 static void
  443 iwl2100_hw_stop(struct iwl2100_softc *sc)
  444 {
  445         struct ifnet *ifp = &sc->sc_ic.ic_if;
  446 
  447         ASSERT_SERIALIZED(ifp->if_serializer);
  448         KKASSERT(curthread == &sc->sc_thread);
  449 
  450         callout_stop(&sc->sc_reinit);
  451 
  452         /* Disable interrupts */
  453         CSR_WRITE_4(sc, IWL2100_INTR_MASK, 0);
  454 
  455         /*
  456          * HW and SW reset
  457          */
  458         iwl2100_hw_reset(sc);
  459         iwl2100_reset(sc);
  460 
  461         /*
  462          * Free TX/RX rings
  463          */
  464         iwl2100_free_tx_ring(sc);
  465         iwl2100_free_rx_ring(sc);
  466 
  467         /* NOTE: MUST after iwl2100_free_tx_ring() */
  468         iwl2100_free_cmd(sc);
  469 
  470         ifp->if_timer = 0;
  471         ifp->if_flags &= ~IFF_RUNNING;
  472         ifq_clr_oactive(&ifp->if_snd);
  473 
  474         sc->sc_tx_timer = 0;
  475         sc->sc_flags &= ~(IWL2100_F_WAITCMD |
  476                           IWL2100_F_INITED |
  477                           IWL2100_F_SCANNING |
  478                           IWL2100_F_RESTARTING |
  479                           IWL2100_F_IFSTART |
  480                           IWL2100_F_ERROR |
  481                           IWL2100_F_ZERO_CMD);
  482 }
  483 
  484 static int
  485 iwl2100_reset(struct iwl2100_softc *sc)
  486 {
  487         int i;
  488 
  489         /*
  490          * Software reset
  491          */
  492 #define WAIT_MAX        1000
  493 
  494         CSR_WRITE_4(sc, IWL2100_RESET, IWL2100_RESET_SW);
  495         for (i = 0; i < WAIT_MAX; ++i) {
  496                 DELAY(10);
  497                 if (CSR_READ_4(sc, IWL2100_RESET) & IWL2100_RESET_DONE)
  498                         break;
  499         }
  500         if (i == WAIT_MAX) {
  501                 if_printf(&sc->sc_ic.ic_if, "sw reset timed out\n");
  502                 return ETIMEDOUT;
  503         }
  504 
  505 #undef WAIT_MAX
  506 
  507         /*
  508          * Move to D0 state, wait clock to become stable
  509          */
  510 #define WAIT_MAX        10000
  511 
  512         CSR_WRITE_4(sc, IWL2100_CTRL, IWL2100_CTRL_INITDONE);
  513         for (i = 0; i < WAIT_MAX; ++i) {
  514                 DELAY(200);
  515                 if (CSR_READ_4(sc, IWL2100_CTRL) & IWL2100_CTRL_CLKREADY)
  516                         break;
  517         }
  518         if (i == WAIT_MAX) {
  519                 if_printf(&sc->sc_ic.ic_if, "can't stablize clock\n");
  520                 return ETIMEDOUT;
  521         }
  522 
  523 #undef WAIT_MAX
  524 
  525         /*
  526          * Move to D0 standby
  527          */
  528         CSR_SETBITS_4(sc, IWL2100_CTRL, IWL2100_CTRL_STANDBY);
  529         return 0;
  530 }
  531 
  532 static int
  533 iwl2100_dma_alloc(device_t dev)
  534 {
  535         struct iwl2100_softc *sc = device_get_softc(dev);
  536         struct iwl2100_tx_ring *tr = &sc->sc_txring;
  537         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
  538         int error;
  539 
  540         /*
  541          * Create top level DMA tag
  542          */
  543         error = bus_dma_tag_create(NULL, 1, 0,
  544                                    BUS_SPACE_MAXADDR_32BIT,
  545                                    BUS_SPACE_MAXADDR,
  546                                    NULL, NULL,
  547                                    MAXBSIZE,
  548                                    BUS_SPACE_UNRESTRICTED,
  549                                    BUS_SPACE_MAXSIZE_32BIT,
  550                                    0, &sc->sc_dtag);
  551         if (error) {
  552                 device_printf(dev, "can't create DMA tag\n");
  553                 return error;
  554         }
  555 
  556         /*
  557          * Create DMA stuffs for TX desc ring
  558          */
  559         error = iwl_dma_mem_create(dev, sc->sc_dtag, IWL2100_TXRING_SIZE,
  560                                    &tr->tr_dtag, (void **)&tr->tr_desc,
  561                                    &tr->tr_paddr, &tr->tr_dmap);
  562         if (error) {
  563                 device_printf(dev, "can't create DMA memory for "
  564                               "TX desc ring\n");
  565                 return error;
  566         }
  567 
  568         /*
  569          * Create DMA stuffs for RX desc ring
  570          */
  571         error = iwl_dma_mem_create(dev, sc->sc_dtag, IWL2100_RXRING_SIZE,
  572                                    &rr->rr_dtag, (void **)&rr->rr_desc,
  573                                    &rr->rr_paddr, &rr->rr_dmap);
  574         if (error) {
  575                 device_printf(dev, "can't create DMA memory for "
  576                               "RX desc ring\n");
  577                 return error;
  578         }
  579 
  580         /*
  581          * Create DMA stuffs for RX status ring
  582          */
  583         error = iwl_dma_mem_create(dev, sc->sc_dtag, IWL2100_RXSTATUS_SIZE,
  584                                    &rr->rr_st_dtag, (void **)&rr->rr_status,
  585                                    &rr->rr_st_paddr, &rr->rr_st_dmap);
  586         if (error) {
  587                 device_printf(dev, "can't create DMA memory for "
  588                               "RX status ring\n");
  589                 return error;
  590         }
  591 
  592         /*
  593          * Create mbuf DMA stuffs
  594          */
  595         error = iwl2100_dma_mbuf_create(dev);
  596         if (error)
  597                 return error;
  598 
  599         return 0;
  600 }
  601 
  602 static void
  603 iwl2100_dma_free(device_t dev)
  604 {
  605         struct iwl2100_softc *sc = device_get_softc(dev);
  606         struct iwl2100_tx_ring *tr = &sc->sc_txring;
  607         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
  608 
  609         /* Free DMA stuffs for TX desc ring */
  610         iwl_dma_mem_destroy(tr->tr_dtag, tr->tr_desc, tr->tr_dmap);
  611 
  612         /* Free DMA stuffs for RX desc ring */
  613         iwl_dma_mem_destroy(rr->rr_dtag, rr->rr_desc, rr->rr_dmap);
  614 
  615         /* Free DMA stuffs for RX status ring */
  616         iwl_dma_mem_destroy(rr->rr_st_dtag, rr->rr_status, rr->rr_st_dmap);
  617 
  618         /* Free DMA stuffs for mbufs */
  619         iwl2100_dma_mbuf_destroy(dev, IWL2100_TX_NDESC, IWL2100_RX_NDESC);
  620 
  621         /* Free top level DMA tag */
  622         if (sc->sc_dtag != NULL)
  623                 bus_dma_tag_destroy(sc->sc_dtag);
  624 }
  625 
  626 static int
  627 iwl2100_dma_mbuf_create(device_t dev)
  628 {
  629         struct iwl2100_softc *sc = device_get_softc(dev);
  630         struct iwl2100_tx_ring *tr = &sc->sc_txring;
  631         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
  632         int i, error;
  633 
  634         /*
  635          * Create mbuf DMA tag
  636          */
  637         error = bus_dma_tag_create(sc->sc_dtag, 1, 0,
  638                                    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
  639                                    NULL, NULL,
  640                                    MCLBYTES, IWL2100_NSEG_MAX,
  641                                    BUS_SPACE_MAXSIZE_32BIT,
  642                                    BUS_DMA_ALLOCNOW, &sc->sc_mbuf_dtag);
  643         if (error) {
  644                 device_printf(dev, "can't create mbuf DMA tag\n");
  645                 return error;
  646         }
  647 
  648         /*
  649          * Create spare DMA map for RX mbufs
  650          */
  651         error = bus_dmamap_create(sc->sc_mbuf_dtag, 0, &rr->rr_tmp_dmap);
  652         if (error) {
  653                 device_printf(dev, "can't create spare mbuf DMA map\n");
  654                 bus_dma_tag_destroy(sc->sc_mbuf_dtag);
  655                 sc->sc_mbuf_dtag = NULL;
  656                 return error;
  657         }
  658 
  659         /*
  660          * Create DMA maps for RX mbufs
  661          */
  662         for (i = 0; i < IWL2100_RX_NDESC; ++i) {
  663                 error = bus_dmamap_create(sc->sc_mbuf_dtag, 0,
  664                                           &rr->rr_buf[i].rb_dmap);
  665                 if (error) {
  666                         device_printf(dev, "can't create %d RX mbuf "
  667                                       "for RX ring\n", i);
  668                         iwl2100_dma_mbuf_destroy(dev, 0, i);
  669                         return error;
  670                 }
  671         }
  672 
  673         /*
  674          * Create DMA maps for TX mbufs
  675          */
  676         for (i = 0; i < IWL2100_TX_NDESC; ++i) {
  677                 error = bus_dmamap_create(sc->sc_mbuf_dtag, 0,
  678                                           &tr->tr_buf[i].tb_dmap);
  679                 if (error) {
  680                         device_printf(dev, "can't create %d TX mbuf "
  681                                       "DMA map\n", i);
  682                         iwl2100_dma_mbuf_destroy(dev, i, IWL2100_RX_NDESC);
  683                         return error;
  684                 }
  685         }
  686         return 0;
  687 }
  688 
  689 static void
  690 iwl2100_dma_mbuf_destroy(device_t dev, int tx_done, int rx_done)
  691 {
  692         struct iwl2100_softc *sc = device_get_softc(dev);
  693         struct iwl2100_tx_ring *tr = &sc->sc_txring;
  694         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
  695         int i;
  696 
  697         if (sc->sc_mbuf_dtag == NULL)
  698                 return;
  699 
  700         /*
  701          * Destroy DMA maps for RX mbufs
  702          */
  703         for (i = 0; i < rx_done; ++i) {
  704                 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
  705 
  706                 KASSERT(rb->rb_mbuf == NULL, ("RX mbuf is not freed yet"));
  707                 bus_dmamap_destroy(sc->sc_mbuf_dtag, rb->rb_dmap);
  708         }
  709 
  710         /*
  711          * Destroy DMA maps for TX mbufs
  712          */
  713         for (i = 0; i < tx_done; ++i) {
  714                 struct iwl2100_txbuf *tb = &tr->tr_buf[i];
  715 
  716                 KASSERT(tb->tb_mbuf == NULL, ("TX mbuf is not freed yet"));
  717                 bus_dmamap_destroy(sc->sc_mbuf_dtag, tb->tb_dmap);
  718         }
  719 
  720         /*
  721          * Destroy spare mbuf DMA map
  722          */
  723         bus_dmamap_destroy(sc->sc_mbuf_dtag, rr->rr_tmp_dmap);
  724 
  725         /*
  726          * Destroy mbuf DMA tag
  727          */
  728         bus_dma_tag_destroy(sc->sc_mbuf_dtag);
  729         sc->sc_mbuf_dtag = NULL;
  730 }
  731 
  732 static void
  733 iwl2100_init(void *xsc)
  734 {
  735         struct iwl2100_softc *sc = xsc;
  736         struct iwlmsg msg;
  737 
  738         ASSERT_SERIALIZED(sc->sc_ic.ic_if.if_serializer);
  739 
  740         iwl2100_stop_callouts(sc);
  741 
  742         iwlmsg_init(&msg, &sc->sc_reply_port, iwl2100_init_dispatch, sc);
  743         lwkt_domsg(&sc->sc_thread_port, &msg.iwlm_nmsg.nm_lmsg, 0);
  744 }
  745 
  746 static void
  747 iwl2100_init_dispatch(struct netmsg *nmsg)
  748 {
  749         struct iwlmsg *msg = (struct iwlmsg *)nmsg;
  750         struct iwl2100_softc *sc = msg->iwlm_softc;
  751         struct ieee80211com *ic = &sc->sc_ic;
  752         struct ifnet *ifp = &ic->ic_if;
  753         int error = 0, flags;
  754 
  755         ASSERT_SERIALIZED(ifp->if_serializer);
  756 
  757         if (sc->sc_flags & IWL2100_F_DETACH)
  758                 goto back;
  759 
  760         ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
  761 
  762         if (ic->ic_opmode != IEEE80211_M_MONITOR) {
  763                 /*
  764                  * XXX
  765                  * Workaround for dummy firmware:
  766                  * Don't enable hardware too early, since
  767                  * once it is enabled, it will start scanning.
  768                  */
  769                 flags = 0;
  770         } else {
  771                 flags = IWL2100_INIT_F_ENABLE;
  772         }
  773 
  774         /* Always put the device into a known state */
  775         error = iwl2100_hw_init(sc, NULL,
  776                 ic->ic_des_essid, ic->ic_des_esslen, flags);
  777         if (error)
  778                 goto back;
  779 
  780         if (sc->sc_flags & IWL2100_F_ZERO_CMD) {
  781                 if_printf(ifp, "zero cmd, reinit 1s later\n");
  782                 iwl2100_hw_stop(sc);
  783 
  784                 callout_reset(&sc->sc_reinit, hz, iwl2100_reinit_callout, sc);
  785                 goto back;
  786         }
  787 
  788         if (ic->ic_opmode != IEEE80211_M_MONITOR) {
  789                 if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
  790                         ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
  791         } else {
  792                 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
  793         }
  794 back:
  795         if (error)
  796                 iwl2100_stop(sc);
  797         lwkt_replymsg(&nmsg->nm_lmsg, error);
  798 }
  799 
  800 static int
  801 iwl2100_ioctl(struct ifnet *ifp, u_long cmd, caddr_t req, struct ucred *cr)
  802 {
  803         struct iwl2100_softc *sc = ifp->if_softc;
  804         int error = 0;
  805 
  806         ASSERT_SERIALIZED(ifp->if_serializer);
  807 
  808         if (sc->sc_flags & IWL2100_F_DETACH)
  809                 return 0;
  810 
  811         switch (cmd) {
  812         case SIOCSIFFLAGS:
  813                 if (ifp->if_flags & IFF_UP) {
  814                         if ((ifp->if_flags & IFF_RUNNING) == 0)
  815                                 iwl2100_init(sc);
  816                 } else {
  817                         if (ifp->if_flags & IFF_RUNNING) {
  818                                 iwl2100_stop(sc);
  819                         } else {
  820                                 /*
  821                                  * Stop callouts explicitly, since
  822                                  * if reinitialization is happening,
  823                                  * IFF_RUNNING will not be turned on.
  824                                  */
  825                                 iwl2100_stop_callouts(sc);
  826                         }
  827                 }
  828                 break;
  829         default:
  830                 error = ieee80211_ioctl(&sc->sc_ic, cmd, req, cr);
  831                 break;
  832         }
  833 
  834         if (error == ENETRESET) {
  835                 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
  836                     (IFF_UP | IFF_RUNNING))
  837                         iwl2100_init(sc);
  838                 error = 0;
  839         }
  840         return error;
  841 }
  842 
  843 static void
  844 iwl2100_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
  845 {
  846         struct iwl2100_softc *sc = ifp->if_softc;
  847         struct ieee80211com *ic = &sc->sc_ic;
  848         struct iwl2100_tx_ring *tr = &sc->sc_txring;
  849         int trans = 0;
  850 
  851         ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq);
  852         ASSERT_SERIALIZED(ifp->if_serializer);
  853 
  854         if (sc->sc_flags & IWL2100_F_DETACH) {
  855                 ieee80211_drain_mgtq(&ic->ic_mgtq);
  856                 ifq_purge(&ifp->if_snd);
  857                 return;
  858         }
  859 
  860         if ((ifp->if_flags & IFF_RUNNING) == 0 || ifq_is_oactive(&ifp->if_snd))
  861                 return;
  862 
  863         if ((sc->sc_flags & IWL2100_F_IFSTART) == 0) {
  864                 ifq_purge(&ifp->if_snd);
  865                 goto back;
  866         }
  867 
  868         while (tr->tr_used < IWL2100_TX_USED_MAX) {
  869                 struct ieee80211_frame *wh;
  870                 struct ieee80211_node *ni;
  871                 struct ether_header *eh;
  872                 struct mbuf *m;
  873 
  874                 m = ifq_dequeue(&ifp->if_snd);
  875                 if (m == NULL)
  876                         break;
  877 
  878                 if (m->m_len < sizeof(*eh)) {
  879                         m = m_pullup(m, sizeof(*eh));
  880                         if (m == NULL) {
  881                                 IFNET_STAT_INC(ifp, oerrors, 1);
  882                                 continue;
  883                         }
  884                 }
  885                 eh = mtod(m, struct ether_header *);
  886 
  887                 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
  888                 if (ni == NULL) {
  889                         m_freem(m);
  890                         IFNET_STAT_INC(ifp, oerrors, 1);
  891                         continue;
  892                 }
  893 
  894                 /* TODO: PS */
  895 
  896                 BPF_MTAP(ifp, m);
  897 
  898                 m = ieee80211_encap(ic, m, ni);
  899                 if (m == NULL) {
  900                         ieee80211_free_node(ni);
  901                         IFNET_STAT_INC(ifp, oerrors, 1);
  902                         continue;
  903                 }
  904 
  905                 if (ic->ic_rawbpf != NULL)
  906                         bpf_mtap(ic->ic_rawbpf, m);
  907 
  908                 wh = mtod(m, struct ieee80211_frame *);
  909                 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
  910                         if (ieee80211_crypto_encap(ic, ni, m) == NULL) {
  911                                 ieee80211_free_node(ni);
  912                                 m_freem(m);
  913                                 IFNET_STAT_INC(ifp, oerrors, 1);
  914                                 continue;
  915                         }
  916                 }
  917 
  918                 /*
  919                  * TX radio tap
  920                  */
  921                 if (sc->sc_drvbpf != NULL) {
  922                         if (wh->i_fc[1] & IEEE80211_FC1_WEP)
  923                                 sc->sc_tx_th.wt_flags = IEEE80211_RADIOTAP_F_WEP;
  924                         else
  925                                 sc->sc_tx_th.wt_flags = 0;
  926                         bpf_ptap(sc->sc_drvbpf, m, &sc->sc_tx_th,
  927                                  sc->sc_tx_th_len);
  928                 }
  929                 wh = NULL;      /* Catch any invalid use */
  930 
  931                 ieee80211_free_node(ni);
  932 
  933                 if (iwl2100_encap(sc, m)) {
  934                         IFNET_STAT_INC(ifp, oerrors, 1);
  935                         continue;
  936                 }
  937 
  938                 IFNET_STAT_INC(ifp, opackets, 1);
  939                 trans = 1;
  940         }
  941 
  942         if (tr->tr_used >= IWL2100_TX_USED_MAX)
  943                 ifq_set_oactive(&ifp->if_snd);
  944 
  945         if (trans) {
  946                 bus_dmamap_sync(tr->tr_dtag, tr->tr_dmap, BUS_DMASYNC_PREWRITE);
  947                 CSR_WRITE_4(sc, IWL2100_TXQ_WRITE_IDX, tr->tr_index);
  948                 sc->sc_tx_timer = 5;
  949         }
  950 back:
  951         ieee80211_drain_mgtq(&ic->ic_mgtq);
  952         ifp->if_timer = 1;
  953 }
  954 
  955 static void
  956 iwl2100_watchdog(struct ifnet *ifp)
  957 {
  958         struct iwl2100_softc *sc = ifp->if_softc;
  959 
  960         ASSERT_SERIALIZED(ifp->if_serializer);
  961 
  962         if (sc->sc_flags & IWL2100_F_DETACH)
  963                 return;
  964 
  965         if (sc->sc_tx_timer) {
  966                 if (--sc->sc_tx_timer == 0) {
  967                         if_printf(ifp, "watchdog timeout!\n");
  968                         IFNET_STAT_INC(ifp, oerrors, 1);
  969                         iwl2100_restart(sc);
  970                         return;
  971                 } else {
  972                         ifp->if_timer = 1;
  973                 }
  974         }
  975         ieee80211_watchdog(&sc->sc_ic);
  976 }
  977 
  978 static int
  979 iwl2100_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
  980 {
  981         struct ifnet *ifp = &ic->ic_if;
  982         struct iwl2100_softc *sc = ifp->if_softc;
  983         struct iwlmsg msg;
  984 
  985         ASSERT_SERIALIZED(ifp->if_serializer);
  986 
  987         iwlmsg_init(&msg, &sc->sc_reply_port, iwl2100_newstate_dispatch, sc);
  988         msg.iwlm_nstate = nstate;
  989         msg.iwlm_arg = arg;
  990 
  991         return lwkt_domsg(&sc->sc_thread_port, &msg.iwlm_nmsg.nm_lmsg, 0);
  992 }
  993 
  994 static void
  995 iwl2100_newstate_dispatch(struct netmsg *nmsg)
  996 {
  997         struct iwlmsg *msg = (struct iwlmsg *)nmsg;
  998         struct iwl2100_softc *sc = msg->iwlm_softc;
  999         struct ieee80211com *ic = &sc->sc_ic;
 1000 #ifdef INVARIANTS
 1001         struct ifnet *ifp = &ic->ic_if;
 1002 #endif
 1003         enum ieee80211_state nstate, ostate;
 1004         int arg = msg->iwlm_arg, error = 0;
 1005 
 1006         ASSERT_SERIALIZED(ifp->if_serializer);
 1007 
 1008         nstate = msg->iwlm_nstate;
 1009         ostate = ic->ic_state;
 1010 
 1011         sc->sc_flags &= ~IWL2100_F_IFSTART;
 1012         sc->sc_state_age++;
 1013 
 1014         iwl2100_chan_change(sc, ic->ic_curchan);
 1015 
 1016         callout_stop(&sc->sc_ibss);
 1017         iwl2100_restart_done(sc);
 1018 
 1019         if (nstate == IEEE80211_S_INIT)
 1020                 goto back;
 1021 
 1022         if (sc->sc_flags & IWL2100_F_DETACH) {
 1023                 /*
 1024                  * Except for INIT, we skip rest of the
 1025                  * state changes during detaching
 1026                  */
 1027                 goto reply;
 1028         }
 1029 
 1030         if (ic->ic_opmode == IEEE80211_M_STA) {
 1031                 if (nstate == IEEE80211_S_AUTH)
 1032                         error = iwl2100_auth(sc);
 1033                 else if (nstate == IEEE80211_S_RUN)
 1034                         sc->sc_flags |= IWL2100_F_IFSTART;
 1035         } else if (ic->ic_opmode == IEEE80211_M_IBSS) {
 1036                 if (nstate == IEEE80211_S_RUN) {
 1037                         DPRINTF(sc, IWL2100_DBG_IBSS, "%s",
 1038                                 "start/join ibss\n");
 1039 
 1040                         /*
 1041                          * IWL2100_F_IFSTART can't be turned on
 1042                          * until BSSID generated by the firmware
 1043                          * is extracted.
 1044                          *
 1045                          * XXX only if we started the IBSS
 1046                          */
 1047                         error = iwl2100_ibss(sc);
 1048                 }
 1049         }
 1050 back:
 1051         if (!error)
 1052                 error = sc->sc_newstate(ic, nstate, arg);
 1053 
 1054         if (!error) {
 1055                 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
 1056                         /*
 1057                          * Don't use 'nstate' here, since for IBSS
 1058                          * mode 802.11 layer may enter RUN state in
 1059                          * a recursive manner, i.e. when we reach
 1060                          * here, nstate != ic->ic_state
 1061                          */
 1062                         if (ic->ic_state == IEEE80211_S_SCAN &&
 1063                             ic->ic_state != ostate) {
 1064                                 DPRINTF(sc, IWL2100_DBG_SCAN, "%s",
 1065                                         "start scan\n");
 1066                                 error = iwl2100_scan(sc);
 1067                         }
 1068                 }
 1069         }
 1070 reply:
 1071         lwkt_replymsg(&nmsg->nm_lmsg, error);
 1072 }
 1073 
 1074 static int
 1075 iwl2100_media_change(struct ifnet *ifp)
 1076 {
 1077         int error;
 1078 
 1079         ASSERT_SERIALIZED(ifp->if_serializer);
 1080 
 1081         error = ieee80211_media_change(ifp);
 1082         if (error != ENETRESET)
 1083                 return error;
 1084 
 1085         if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
 1086                 iwl2100_init(ifp->if_softc);
 1087         return 0;
 1088 }
 1089 
 1090 static void
 1091 iwl2100_media_status(struct ifnet *ifp, struct ifmediareq *imr)
 1092 {
 1093         struct iwl2100_softc *sc = ifp->if_softc;
 1094 
 1095         if (sc->sc_flags & IWL2100_F_IFSTART) {
 1096                 struct ieee80211_node *ni = sc->sc_ic.ic_bss;
 1097                 uint32_t txrate;
 1098                 int i, nrates = 4;
 1099 
 1100                 txrate = iwl2100_read_ord1(sc, IWL2100_ORD1_TXRATE) & 0xf;
 1101                 if (ni->ni_rates.rs_nrates < 4)
 1102                         nrates = ni->ni_rates.rs_nrates;
 1103 
 1104                 for (i = 0; i < nrates; ++i) {
 1105                         if ((1 << i) & txrate)
 1106                                 ni->ni_txrate = i;
 1107                 }
 1108         }
 1109         ieee80211_media_status(ifp, imr);
 1110 }
 1111 
 1112 static void
 1113 iwl2100_intr(void *xsc)
 1114 {
 1115         struct iwl2100_softc *sc = xsc;
 1116         struct ifnet *ifp = &sc->sc_ic.ic_if;
 1117         uint32_t intr_status;
 1118 
 1119         ASSERT_SERIALIZED(ifp->if_serializer);
 1120 
 1121         if ((sc->sc_flags & IWL2100_F_INITED) == 0)
 1122                 return;
 1123 
 1124         intr_status = CSR_READ_4(sc, IWL2100_INTR_STATUS);
 1125         if (intr_status == 0xffffffff)  /* not for us */
 1126                 return;
 1127 
 1128         if ((intr_status & IWL2100_INTRS) == 0) /* not interested */
 1129                 return;
 1130 
 1131         sc->sc_flags |= IWL2100_F_IN_INTR;
 1132 
 1133         /* Disable interrupts */
 1134         CSR_WRITE_4(sc, IWL2100_INTR_MASK, 0);
 1135 
 1136         if (intr_status & IWL2100_INTR_EFATAL) {
 1137                 uint32_t error_info;
 1138 
 1139                 if_printf(ifp, "intr fatal error\n");
 1140                 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_EFATAL);
 1141 
 1142                 error_info = IND_READ_4(sc, IWL2100_IND_ERROR_INFO);
 1143                 IND_READ_4(sc, error_info & IWL2100_IND_ERRORADDR_MASK);
 1144 
 1145                 callout_stop(&sc->sc_reinit);
 1146                 iwl2100_reinit(sc);
 1147 
 1148                 /* Leave interrupts disabled */
 1149                 goto back;
 1150         }
 1151 
 1152         if (intr_status & IWL2100_INTR_EPARITY) {
 1153                 if_printf(ifp, "intr parity error\n");
 1154                 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_EPARITY);
 1155         }
 1156 
 1157         if (intr_status & IWL2100_INTR_RX) {
 1158                 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_RX);
 1159                 iwl2100_rxeof(sc);
 1160                 iwl2100_txeof(sc);
 1161         }
 1162 
 1163         if (intr_status & IWL2100_INTR_TX) {
 1164                 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_TX);
 1165                 iwl2100_txeof(sc);
 1166         }
 1167 
 1168         if (intr_status & IWL2100_INTR_FW_INITED)
 1169                 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_FW_INITED);
 1170         if (intr_status & IWL2100_INTR_CMD_DONE)
 1171                 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_CMD_DONE);
 1172 
 1173         /* Enable interrupts */
 1174         CSR_WRITE_4(sc, IWL2100_INTR_MASK, IWL2100_INTRS);
 1175 back:
 1176         sc->sc_flags &= ~IWL2100_F_IN_INTR;
 1177 }
 1178 
 1179 static int
 1180 iwl2100_hw_reset(struct iwl2100_softc *sc)
 1181 {
 1182         int i;
 1183 
 1184         /*
 1185          * Initialize GPIO:
 1186          * - Enable GPIO3
 1187          * - Make GPIO3 firmware writable
 1188          * - Enable GPIO1
 1189          * - Turn off LED
 1190          */
 1191         CSR_WRITE_4(sc, IWL2100_GPIO,
 1192                     IWL2100_GPIO_3_EN | IWL2100_GPIO_3_FWWR |
 1193                     IWL2100_GPIO_1_EN | IWL2100_GPIO_LEDOFF);
 1194 
 1195         /*
 1196          * Stop master
 1197          */
 1198 #define WAIT_MAX        5
 1199 
 1200         CSR_WRITE_4(sc, IWL2100_RESET, IWL2100_RESET_STOP_MASTER);
 1201         for (i = 0; i < WAIT_MAX; ++i) {
 1202                 DELAY(10);
 1203 
 1204                 if (CSR_READ_4(sc, IWL2100_RESET) &
 1205                     IWL2100_RESET_MASTER_STOPPED)
 1206                         break;
 1207         }
 1208         if (i == WAIT_MAX) {
 1209                 if_printf(&sc->sc_ic.ic_if, "can't stop master\n");
 1210                 return ETIMEDOUT;
 1211         }
 1212 
 1213 #undef WAIT_MAX
 1214 
 1215         CSR_WRITE_4(sc, IWL2100_RESET, IWL2100_RESET_SW);
 1216         return 0;
 1217 }
 1218 
 1219 static int
 1220 iwl2100_alloc_firmware(struct iwl2100_softc *sc, enum ieee80211_opmode opmode)
 1221 {
 1222         struct {
 1223                 const char *suffix;
 1224                 uint16_t mode;
 1225                 enum ieee80211_opmode opmode;
 1226                 struct iwl2100_firmware *fw;
 1227         } fw_arr[] = {
 1228                 { "", IWL2100_FW_M_STA, IEEE80211_M_STA,
 1229                   &sc->sc_fw_sta },
 1230                 { "-i", IWL2100_FW_M_IBSS, IEEE80211_M_IBSS,
 1231                   &sc->sc_fw_ibss },
 1232                 { "-p", IWL2100_FW_M_MONITOR, IEEE80211_M_MONITOR,
 1233                   &sc->sc_fw_monitor },
 1234                 { NULL, 0, 0, NULL }
 1235         };
 1236         struct ifnet *ifp = &sc->sc_ic.ic_if;
 1237         const struct iwl2100_fwimg_hdr *hdr;
 1238         struct iwl2100_firmware *fw = NULL;
 1239         struct fw_image *image;
 1240         char filename[128];
 1241         int i, error;
 1242 
 1243         for (i = 0; fw_arr[i].fw != NULL; ++i) {
 1244                 fw = fw_arr[i].fw;
 1245 
 1246                 if (fw_arr[i].opmode == opmode) {
 1247                         if (fw->fw_image != NULL)
 1248                                 return 0;
 1249                         else
 1250                                 break;
 1251                 }
 1252         }
 1253         KASSERT(fw_arr[i].fw != NULL, ("unsupported opmode %u", opmode));
 1254 
 1255         ksnprintf(filename, sizeof(filename), IWL2100_FW_PATH,
 1256                   fw_arr[i].suffix);
 1257 
 1258         /*
 1259          * Release the serializer to avoid possible dead lock
 1260          */
 1261         lwkt_serialize_exit(ifp->if_serializer);
 1262         image = firmware_image_load(filename, NULL);
 1263         lwkt_serialize_enter(ifp->if_serializer);
 1264 
 1265         if (image == NULL)
 1266                 return ENOENT;
 1267         fw->fw_image = image;
 1268 
 1269         /*
 1270          * Verify the image
 1271          */
 1272         error = EINVAL;
 1273 
 1274         hdr = (const struct iwl2100_fwimg_hdr *)image->fw_image;
 1275         if ((hdr->version & 0xff) != 1) {
 1276                 if_printf(ifp, "%s unsupported firmware version %d",
 1277                           image->fw_name, hdr->version & 0xff);
 1278                 goto back;
 1279         }
 1280 
 1281         if (hdr->mode != fw_arr[i].mode) {
 1282                 if_printf(ifp, "%s contains %d mode firmware, should be %d\n",
 1283                           image->fw_name, hdr->mode, fw_arr[i].mode);
 1284                 goto back;
 1285         }
 1286 
 1287         if (hdr->data_size + hdr->ucode_size + sizeof(*hdr) !=
 1288             image->fw_imglen) {
 1289                 if_printf(ifp,
 1290                           "%s size mismatch, %zu/hdr %zu\n",
 1291                           image->fw_name, fw->fw_image->fw_imglen,
 1292                           hdr->data_size + hdr->ucode_size + sizeof(*hdr));
 1293                 goto back;
 1294         }
 1295 
 1296         fw->fw_data = (const uint8_t *)(hdr + 1);
 1297         fw->fw_data_size = hdr->data_size;
 1298         fw->fw_ucode = fw->fw_data + fw->fw_data_size;
 1299         fw->fw_ucode_size = hdr->ucode_size;
 1300         error = 0;
 1301 back:
 1302         if (error) {
 1303                 firmware_image_unload(fw->fw_image);
 1304                 bzero(fw, sizeof(*fw));
 1305         }
 1306         return error;
 1307 }
 1308 
 1309 static void
 1310 iwl2100_free_firmware(struct iwl2100_softc *sc)
 1311 {
 1312         struct iwl2100_firmware *fw_arr[] =
 1313         { &sc->sc_fw_sta, &sc->sc_fw_ibss, &sc->sc_fw_monitor, NULL };
 1314         int i;
 1315 
 1316         for (i = 0; fw_arr[i] != NULL; ++i) {
 1317                 struct iwl2100_firmware *fw = fw_arr[i];
 1318 
 1319                 if (fw->fw_image != NULL) {
 1320                         firmware_image_unload(fw->fw_image);
 1321                         bzero(fw, sizeof(*fw));
 1322                 }
 1323         }
 1324 }
 1325 
 1326 static int
 1327 iwl2100_load_firmware(struct iwl2100_softc *sc, enum ieee80211_opmode opmode)
 1328 {
 1329         static const struct {
 1330                 uint32_t        addr;
 1331                 int             size;
 1332         } share_mem[] = {
 1333                 { IWL2100_SHMEM0, IWL2100_SHMEM0_SIZE },
 1334                 { IWL2100_SHMEM1, IWL2100_SHMEM1_SIZE },
 1335                 { IWL2100_SHMEM2, IWL2100_SHMEM2_SIZE },
 1336                 { IWL2100_SHMEM3, IWL2100_SHMEM3_SIZE },
 1337                 { IWL2100_SHMEM_INTR, IWL2100_SHMEM_INTR_SIZE },
 1338                 { 0, 0 }
 1339         };
 1340         const struct iwl2100_firmware *fw = NULL;
 1341         int i, error;
 1342 
 1343         /*
 1344          * Pick up the firmware image corresponding to
 1345          * the current operation mode
 1346          */
 1347         switch (opmode) {
 1348         case IEEE80211_M_STA:
 1349                 fw = &sc->sc_fw_sta;
 1350                 break;
 1351         case IEEE80211_M_IBSS:
 1352                 fw = &sc->sc_fw_ibss;
 1353                 break;
 1354         case IEEE80211_M_MONITOR:
 1355                 fw = &sc->sc_fw_monitor;
 1356                 break;
 1357         default:
 1358                 panic("unsupported opmode %d", opmode);
 1359                 break;
 1360         }
 1361         KASSERT(fw->fw_image != NULL,
 1362                 ("opmode %d firmware image is not allocated yet\n", opmode));
 1363 
 1364         /* Load ucode */
 1365         error = iwl2100_load_fw_ucode(sc, fw);
 1366         if (error)
 1367                 return error;
 1368 
 1369         /* SW reset */
 1370         error = iwl2100_reset(sc);
 1371         if (error)
 1372                 return error;
 1373 
 1374         /* Load data */
 1375         error = iwl2100_load_fw_data(sc, fw);
 1376         if (error)
 1377                 return error;
 1378 
 1379         /* Clear shared memory */
 1380         for (i = 0; share_mem[i].size != 0; ++i) {
 1381                 uint32_t addr = share_mem[i].addr;
 1382                 int j;
 1383 
 1384                 for (j = 0; j < share_mem[i].size; j += 4)
 1385                         IND_WRITE_4(sc, addr + j, 0);
 1386         }
 1387 
 1388         return 0;
 1389 }
 1390 
 1391 #define IND_WRITE_FLUSH_2(sc, reg, val) \
 1392 do { \
 1393         IND_WRITE_2((sc), (reg), (val)); \
 1394         CSR_READ_4((sc), 0); \
 1395 } while (0)
 1396 
 1397 #define IND_WRITE_FLUSH_1(sc, reg, val) \
 1398 do { \
 1399         IND_WRITE_1((sc), (reg), (val)); \
 1400         CSR_READ_4((sc), 0); \
 1401 } while (0)
 1402 
 1403 /* XXX need more comment */
 1404 static int
 1405 iwl2100_load_fw_ucode(struct iwl2100_softc *sc,
 1406                       const struct iwl2100_firmware *fw)
 1407 {
 1408         struct iwl2100_ucode_resp resp;
 1409         const uint8_t *p;
 1410         int i;
 1411 
 1412         /* Hold ARC */
 1413         IND_WRITE_4(sc, IWL2100_IND_HALT, IWL2100_IND_HALT_HOLD);
 1414 
 1415         /* Allow ARC to run */
 1416         CSR_WRITE_4(sc, IWL2100_RESET, 0);
 1417 
 1418         IND_WRITE_FLUSH_2(sc, IWL2100_IND_CTRL, 0x703);
 1419         IND_WRITE_FLUSH_2(sc, IWL2100_IND_CTRL, 0x707);
 1420 
 1421         IND_WRITE_FLUSH_1(sc, 0x210014, 0x72);
 1422         IND_WRITE_FLUSH_1(sc, 0x210014, 0x72);
 1423 
 1424         IND_WRITE_FLUSH_1(sc, 0x210000, 0x40);
 1425         IND_WRITE_FLUSH_1(sc, 0x210000, 0);
 1426         IND_WRITE_FLUSH_1(sc, 0x210000, 0x40);
 1427 
 1428         p = fw->fw_ucode;
 1429         for (i = 0; i < fw->fw_ucode_size; ++i, ++p)
 1430                 IND_WRITE_1(sc, 0x210010, *p);
 1431 
 1432         IND_WRITE_FLUSH_1(sc, 0x210000, 0);
 1433         IND_WRITE_FLUSH_1(sc, 0x210000, 0);
 1434         IND_WRITE_FLUSH_1(sc, 0x210000, 0x80);
 1435 
 1436 
 1437         IND_WRITE_FLUSH_2(sc, IWL2100_IND_CTRL, 0x703);
 1438         IND_WRITE_FLUSH_2(sc, IWL2100_IND_CTRL, 0x707);
 1439 
 1440         IND_WRITE_FLUSH_1(sc, 0x210014, 0x72);
 1441         IND_WRITE_FLUSH_1(sc, 0x210014, 0x72);
 1442 
 1443         IND_WRITE_FLUSH_1(sc, 0x210000, 0);
 1444         IND_WRITE_1(sc, 0x210000, 0x80);
 1445 
 1446 #define WAIT_MAX        10
 1447         for (i = 0; i < WAIT_MAX; ++i) {
 1448                 DELAY(10);
 1449 
 1450                 if (IND_READ_1(sc, 0x210000) & 0x1)
 1451                         break;
 1452         }
 1453         if (i == WAIT_MAX) {
 1454                 if_printf(&sc->sc_ic.ic_if,
 1455                           "wait ucode symbol init timed out\n");
 1456                 return ETIMEDOUT;
 1457         }
 1458 #undef WAIT_MAX
 1459 
 1460 #define WAIT_MAX        30
 1461         for (i = 0; i < WAIT_MAX; ++i) {
 1462                 uint16_t *r = (uint16_t *)&resp;
 1463                 int j;
 1464 
 1465                 for (j = 0; j < sizeof(resp) / 2; ++j, ++r)
 1466                         *r = IND_READ_2(sc, 0x210004);
 1467 
 1468                 if (resp.cmd_id == 1 && resp.ucode_valid == 1)
 1469                         break;
 1470                 DELAY(10);
 1471         }
 1472         if (i == WAIT_MAX) {
 1473                 if_printf(&sc->sc_ic.ic_if,
 1474                           "wait ucode response timed out\n");
 1475                 return ETIMEDOUT;
 1476         }
 1477 #undef WAIT_MAX
 1478 
 1479         /* Release ARC */
 1480         IND_WRITE_4(sc, IWL2100_IND_HALT, 0);
 1481 
 1482         if (bootverbose) {
 1483                 if_printf(&sc->sc_ic.ic_if, "ucode rev.%d date %d.%d.20%02d "
 1484                           "time %02d:%02d\n", resp.ucode_rev,
 1485                           resp.date_time[0], resp.date_time[1],
 1486                           resp.date_time[2], resp.date_time[3],
 1487                           resp.date_time[4]);
 1488         }
 1489 
 1490         return 0;
 1491 }
 1492 
 1493 #undef IND_WRITE_FLUSH_1
 1494 #undef IND_WRITE_FLUSH_2
 1495 
 1496 static int
 1497 iwl2100_load_fw_data(struct iwl2100_softc *sc,
 1498                      const struct iwl2100_firmware *fw)
 1499 {
 1500         const uint8_t *p = fw->fw_data;
 1501         int w = 0;
 1502 
 1503         while (w < fw->fw_data_size) {
 1504                 const struct iwl2100_fwdata_hdr *h;
 1505                 int hlen, i;
 1506 
 1507                 h = (const struct iwl2100_fwdata_hdr *)p;
 1508                 if (h->len > 32 || h->len == 0) {
 1509                         if_printf(&sc->sc_ic.ic_if,
 1510                                   "firmware image data corrupted\n");
 1511                         return EINVAL;
 1512                 }
 1513                 if ((h->addr & 0x3) || (h->len & 0x3)) {
 1514                         if_printf(&sc->sc_ic.ic_if,
 1515                                   "firmware image data with unaligned "
 1516                                   "address %#x or length %#x\n",
 1517                                   h->addr, h->len);
 1518                         return EOPNOTSUPP;
 1519                 }
 1520 
 1521                 hlen = sizeof(*h) + h->len - 1;
 1522                 if (w + hlen > fw->fw_data_size) {
 1523                         if_printf(&sc->sc_ic.ic_if,
 1524                                   "firmware image data size mismatch\n");
 1525                         return EINVAL;
 1526                 }
 1527 
 1528                 CSR_WRITE_4(sc, IWL2100_AUTOINC_ADDR, h->addr);
 1529                 for (i = 0; i < h->len; i += 4) {
 1530                         CSR_WRITE_4(sc, IWL2100_AUTOINC_DATA,
 1531                                     *(const uint32_t *)&h->data[i]);
 1532                 }
 1533 
 1534                 p += hlen;
 1535                 w += hlen;
 1536         }
 1537         KKASSERT(w == fw->fw_data_size);
 1538 
 1539         return 0;
 1540 }
 1541 
 1542 static void
 1543 iwl2100_free_tx_ring(struct iwl2100_softc *sc)
 1544 {
 1545         struct iwl2100_tx_ring *tr = &sc->sc_txring;
 1546         int i;
 1547 
 1548         for (i = 0; i < IWL2100_TX_NDESC; ++i) {
 1549                 struct iwl2100_txbuf *tb = &tr->tr_buf[i];
 1550 
 1551                 if (tb->tb_mbuf != NULL) {
 1552                         bus_dmamap_unload(sc->sc_mbuf_dtag, tb->tb_dmap);
 1553                         if (tb->tb_flags & IWL2100_TBF_CMDBUF) {
 1554                                 KKASSERT(tb->tb_mbuf == sc->sc_cmd);
 1555                                 tb->tb_flags &= ~IWL2100_TBF_CMDBUF;
 1556                         } else {
 1557                                 m_freem(tb->tb_mbuf);
 1558                         }
 1559                         tb->tb_mbuf = NULL;
 1560                 }
 1561         }
 1562 
 1563         bzero(tr->tr_desc, IWL2100_TXRING_SIZE);
 1564         bus_dmamap_sync(tr->tr_dtag, tr->tr_dmap, BUS_DMASYNC_PREWRITE);
 1565 
 1566         tr->tr_used = 0;
 1567         tr->tr_index = 0;
 1568         tr->tr_coll = 0;
 1569 }
 1570 
 1571 static void
 1572 iwl2100_free_rx_ring(struct iwl2100_softc *sc)
 1573 {
 1574         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
 1575         int i;
 1576 
 1577         for (i = 0; i < IWL2100_RX_NDESC; ++i) {
 1578                 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
 1579 
 1580                 if (rb->rb_mbuf != NULL) {
 1581                         bus_dmamap_unload(sc->sc_mbuf_dtag, rb->rb_dmap);
 1582                         m_freem(rb->rb_mbuf);
 1583                         rb->rb_mbuf = NULL;
 1584                 }
 1585         }
 1586 
 1587         bzero(rr->rr_desc, IWL2100_RXRING_SIZE);
 1588         bus_dmamap_sync(rr->rr_dtag, rr->rr_dmap, BUS_DMASYNC_PREWRITE);
 1589 
 1590         bzero(rr->rr_status, IWL2100_RXSTATUS_SIZE);
 1591         bus_dmamap_sync(rr->rr_st_dtag, rr->rr_st_dmap, BUS_DMASYNC_PREWRITE);
 1592 
 1593         rr->rr_index = 0;
 1594 }
 1595 
 1596 static void
 1597 iwl2100_free_cmd(struct iwl2100_softc *sc)
 1598 {
 1599         if (sc->sc_cmd != NULL) {
 1600                 m_freem(sc->sc_cmd);
 1601                 sc->sc_cmd = NULL;
 1602         }
 1603 }
 1604 
 1605 static int
 1606 iwl2100_init_tx_ring(struct iwl2100_softc *sc)
 1607 {
 1608         struct iwl2100_tx_ring *tr = &sc->sc_txring;
 1609 
 1610         tr->tr_used = 0;
 1611         tr->tr_index = 0;
 1612         tr->tr_coll = 0;
 1613 
 1614         bzero(tr->tr_desc, IWL2100_TXRING_SIZE);
 1615         bus_dmamap_sync(tr->tr_dtag, tr->tr_dmap, BUS_DMASYNC_PREWRITE);
 1616 
 1617         CSR_WRITE_4(sc, IWL2100_TXQ_ADDR, tr->tr_paddr);
 1618         CSR_WRITE_4(sc, IWL2100_TXQ_SIZE, IWL2100_TX_NDESC);
 1619         CSR_WRITE_4(sc, IWL2100_TXQ_READ_IDX, 0);
 1620         CSR_WRITE_4(sc, IWL2100_TXQ_WRITE_IDX, tr->tr_index);
 1621 
 1622         return 0;
 1623 }
 1624 
 1625 static int
 1626 iwl2100_init_rx_ring(struct iwl2100_softc *sc)
 1627 {
 1628         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
 1629         int i, error;
 1630 
 1631         for (i = 0; i < IWL2100_RX_NDESC; ++i) {
 1632                 error = iwl2100_newbuf(sc, i, 1);
 1633                 if (error)
 1634                         return error;
 1635         }
 1636         bus_dmamap_sync(rr->rr_st_dtag, rr->rr_st_dmap, BUS_DMASYNC_PREWRITE);
 1637         bus_dmamap_sync(rr->rr_dtag, rr->rr_dmap, BUS_DMASYNC_PREWRITE);
 1638 
 1639         rr->rr_index = IWL2100_RX_NDESC - 1;
 1640 
 1641         CSR_WRITE_4(sc, IWL2100_RXQ_ADDR, rr->rr_paddr);
 1642         CSR_WRITE_4(sc, IWL2100_RXQ_SIZE, IWL2100_RX_NDESC);
 1643         CSR_WRITE_4(sc, IWL2100_RXQ_READ_IDX, 0);
 1644         CSR_WRITE_4(sc, IWL2100_RXQ_WRITE_IDX, rr->rr_index);
 1645 
 1646         CSR_WRITE_4(sc, IWL2100_RX_STATUS_ADDR, rr->rr_st_paddr);
 1647 
 1648         return 0;
 1649 }
 1650 
 1651 static int
 1652 iwl2100_alloc_cmd(struct iwl2100_softc *sc)
 1653 {
 1654         KKASSERT(sc->sc_cmd == NULL);
 1655 
 1656         sc->sc_cmd = m_getcl(MB_WAIT, MT_DATA, M_PKTHDR);
 1657         if (sc->sc_cmd == NULL)
 1658                 return ENOBUFS;
 1659         return 0;
 1660 }
 1661 
 1662 static int
 1663 iwl2100_newbuf(struct iwl2100_softc *sc, int buf_idx, int init)
 1664 {
 1665         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
 1666         struct iwl2100_rxbuf *rb;
 1667         struct iwl_dmamap_ctx ctx;
 1668         bus_dma_segment_t seg;
 1669         bus_dmamap_t dmap;
 1670         struct mbuf *m;
 1671         int error;
 1672 
 1673         KKASSERT(buf_idx < IWL2100_RX_NDESC);
 1674         rb = &rr->rr_buf[buf_idx];
 1675 
 1676         m = m_getcl(init ? MB_WAIT : MB_DONTWAIT, MT_DATA, M_PKTHDR);
 1677         if (m == NULL) {
 1678                 error = ENOBUFS;
 1679 
 1680                 if (init) {
 1681                         if_printf(&sc->sc_ic.ic_if, "m_getcl failed\n");
 1682                         return error;
 1683                 } else {
 1684                         goto back;
 1685                 }
 1686         }
 1687         m->m_len = m->m_pkthdr.len = MCLBYTES;
 1688 
 1689         /*
 1690          * Try load RX mbuf into temporary DMA map
 1691          */
 1692         ctx.nsegs = 1;
 1693         ctx.segs = &seg;
 1694         error = bus_dmamap_load_mbuf(sc->sc_mbuf_dtag, rr->rr_tmp_dmap, m,
 1695                                      iwl_dma_buf_addr, &ctx,
 1696                                      init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT);
 1697         if (error || ctx.nsegs == 0) {
 1698                 if (!error) {
 1699                         bus_dmamap_unload(sc->sc_mbuf_dtag, rr->rr_tmp_dmap);
 1700                         error = EFBIG;
 1701                         if_printf(&sc->sc_ic.ic_if, "too many segments?!\n");
 1702                 }
 1703                 m_freem(m);
 1704 
 1705                 if (init) {
 1706                         if_printf(&sc->sc_ic.ic_if, "can't load RX mbuf\n");
 1707                         return error;
 1708                 } else {
 1709                         goto back;
 1710                 }
 1711         }
 1712 
 1713         if (!init)
 1714                 bus_dmamap_unload(sc->sc_mbuf_dtag, rb->rb_dmap);
 1715         rb->rb_mbuf = m;
 1716         rb->rb_paddr = seg.ds_addr;
 1717 
 1718         /*
 1719          * Swap RX buf's DMA map with the loaded temporary one
 1720          */
 1721         dmap = rb->rb_dmap;
 1722         rb->rb_dmap = rr->rr_tmp_dmap;
 1723         rr->rr_tmp_dmap = dmap;
 1724 
 1725         error = 0;
 1726 back:
 1727         iwl2100_rxdesc_setup(sc, buf_idx);
 1728         return error;
 1729 }
 1730 
 1731 static void
 1732 iwl2100_rxdesc_setup(struct iwl2100_softc *sc, int buf_idx)
 1733 {
 1734         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
 1735         struct iwl2100_rxbuf *rb;
 1736         struct iwl2100_desc *d;
 1737         struct iwl2100_rx_status *st;
 1738 
 1739         KKASSERT(buf_idx < IWL2100_RX_NDESC);
 1740         rb = &rr->rr_buf[buf_idx];
 1741 
 1742         st = &rr->rr_status[buf_idx];
 1743         bzero(st, sizeof(*st));
 1744 
 1745         d = &rr->rr_desc[buf_idx];
 1746         bzero(d, sizeof(*d));
 1747         d->d_paddr = rb->rb_paddr;
 1748         d->d_len = MCLBYTES;
 1749 }
 1750 
 1751 static int
 1752 iwl2100_init_firmware(struct iwl2100_softc *sc)
 1753 {
 1754 #ifdef INVARIANTS
 1755         struct ifnet *ifp = &sc->sc_ic.ic_if;
 1756 #endif
 1757         uint32_t intr;
 1758         int i;
 1759 
 1760         ASSERT_SERIALIZED(ifp->if_serializer);
 1761 
 1762         CSR_WRITE_4(sc, IWL2100_GPIO,
 1763                     IWL2100_GPIO_3_EN | IWL2100_GPIO_3_FWWR |
 1764                     IWL2100_GPIO_1_EN | IWL2100_GPIO_LEDOFF);
 1765         CSR_WRITE_4(sc, IWL2100_RESET, 0);
 1766 
 1767         /*
 1768          * Wait for firmware to be initialized
 1769          */
 1770 #define WAIT_MAX        5000
 1771 
 1772         for (i = 0; i < WAIT_MAX; ++i) {
 1773                 DELAY(8000);
 1774 
 1775                 intr = CSR_READ_4(sc, IWL2100_INTR_STATUS);
 1776                 if (intr & IWL2100_INTR_FW_INITED) {
 1777                         CSR_WRITE_4(sc, IWL2100_INTR_STATUS,
 1778                                     IWL2100_INTR_FW_INITED);
 1779                         break;
 1780                 }
 1781                 if (intr & (IWL2100_INTR_EFATAL | IWL2100_INTR_EPARITY)) {
 1782                         CSR_WRITE_4(sc, IWL2100_INTR_STATUS,
 1783                                     IWL2100_INTR_EFATAL | IWL2100_INTR_EPARITY);
 1784                 }
 1785         }
 1786 
 1787         intr = CSR_READ_4(sc, IWL2100_INTR_STATUS) & IWL2100_INTRS;
 1788         if (intr & CSR_READ_4(sc, IWL2100_INTR_MASK))
 1789                 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, intr);
 1790 
 1791         if (i == WAIT_MAX) {
 1792                 if_printf(&sc->sc_ic.ic_if,
 1793                           "firmware initialization timed out\n");
 1794                 return ETIMEDOUT;
 1795         }
 1796 
 1797 #undef WAIT_MAX
 1798 
 1799         /* Enable GPIO1/3 and allow firmware to write to them */
 1800         CSR_SETBITS_4(sc, IWL2100_GPIO,
 1801                       IWL2100_GPIO_1_EN | IWL2100_GPIO_1_FWWR |
 1802                       IWL2100_GPIO_3_EN | IWL2100_GPIO_3_FWWR);
 1803         return 0;
 1804 }
 1805 
 1806 static int
 1807 iwl2100_read_ord2(struct iwl2100_softc *sc, uint32_t ofs, void *buf0, int buflen)
 1808 {
 1809         uint8_t *buf = buf0;
 1810         uint32_t addr, info;
 1811         int i, len, ret;
 1812 
 1813 #define IND_ALIGN       4
 1814 #define IND_ALIGN_MASK  0x3
 1815 
 1816         addr = IND_READ_4(sc, sc->sc_ord2 + (ofs << 3));
 1817         info = IND_READ_4(sc, sc->sc_ord2 + (ofs << 3) + sizeof(addr));
 1818 
 1819         len = info & 0xffff;
 1820         i = info >> 16;
 1821 
 1822         if ((len * i) < buflen)
 1823                 buflen = len * i;
 1824         ret = buflen;
 1825 
 1826         i = addr & IND_ALIGN_MASK;
 1827         addr &= ~IND_ALIGN_MASK;
 1828         if (i) {
 1829                 int lim, r;
 1830 
 1831                 KKASSERT(i < IND_ALIGN);
 1832                 if (buflen + i < IND_ALIGN)
 1833                         lim = buflen + i;
 1834                 else
 1835                         lim = IND_ALIGN;
 1836                 r = lim - i;
 1837 
 1838                 CSR_WRITE_4(sc, IWL2100_IND_ADDR, addr);
 1839                 for (; i < lim; ++i, ++buf)
 1840                         *buf = CSR_READ_1(sc, IWL2100_IND_DATA + i);
 1841 
 1842                 KKASSERT(buflen >= r);
 1843                 buflen -= r;
 1844                 if (buflen == 0)
 1845                         goto back;
 1846 
 1847                 addr += IND_ALIGN;
 1848         }
 1849 
 1850         len = buflen & ~IND_ALIGN_MASK;
 1851         buflen &= IND_ALIGN_MASK;
 1852 
 1853         if (len) {
 1854                 CSR_WRITE_4(sc, IWL2100_AUTOINC_ADDR, addr);
 1855                 for (i = 0; i < len; i += 4, addr += 4, buf += 4) {
 1856                         *((uint32_t *)buf) =
 1857                         CSR_READ_4(sc, IWL2100_AUTOINC_DATA);
 1858                 }
 1859         }
 1860         if (buflen) {
 1861                 CSR_WRITE_4(sc, IWL2100_IND_ADDR, addr);
 1862                 for (i = 0; i < buflen; ++i, ++buf)
 1863                         *buf = CSR_READ_1(sc, IWL2100_IND_DATA + i);
 1864         }
 1865 back:
 1866         return ret;
 1867 
 1868 #undef IND_ALIGN
 1869 #undef IND_ALIGN_MASK
 1870 }
 1871 
 1872 static uint32_t
 1873 iwl2100_read_ord1(struct iwl2100_softc *sc, uint32_t ofs)
 1874 {
 1875         uint32_t addr;
 1876 
 1877         addr = IND_READ_4(sc, sc->sc_ord1 + (ofs << 2));
 1878         return IND_READ_4(sc, addr);
 1879 }
 1880 
 1881 static void
 1882 iwl2100_write_ord1(struct iwl2100_softc *sc, uint32_t ofs, uint32_t val)
 1883 {
 1884         uint32_t addr;
 1885 
 1886         addr = IND_READ_4(sc, sc->sc_ord1 + (ofs << 2));
 1887         IND_WRITE_4(sc, addr, val);
 1888 }
 1889 
 1890 static int
 1891 iwl2100_rfkilled(struct iwl2100_softc *sc)
 1892 {
 1893         int i;
 1894 
 1895         if ((sc->sc_caps & IWL2100_C_RFKILL) == 0)
 1896                 return 0;
 1897 
 1898 #define TEST_MAX        5
 1899 
 1900         for (i = 0; i < TEST_MAX; ++i) {
 1901                 DELAY(40);
 1902 
 1903                 if (CSR_READ_4(sc, IWL2100_GPIO) & IWL2100_GPIO_RFKILLED)
 1904                         break;
 1905         }
 1906         if (i != TEST_MAX) {
 1907                 if_printf(&sc->sc_ic.ic_if, "RF killed\n");
 1908                 return 1;
 1909         }
 1910 
 1911 #undef TEST_MAX
 1912 
 1913         return 0;
 1914 }
 1915 
 1916 static int
 1917 iwl2100_set_addr(struct iwl2100_softc *sc, const uint8_t *eaddr)
 1918 {
 1919         struct iwl2100_cmd *cmd;
 1920         int error;
 1921 
 1922         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 1923                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 1924                 return EEXIST;
 1925         }
 1926 
 1927         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 1928         bzero(cmd, sizeof(*cmd));
 1929 
 1930         cmd->c_cmd = IWL2100_CMD_SET_ADDR;
 1931         cmd->c_param_len = IEEE80211_ADDR_LEN;
 1932         IEEE80211_ADDR_COPY(cmd->c_param, eaddr);
 1933 
 1934         error = iwl2100_wait_cmd(sc);
 1935         if (error) {
 1936                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 1937                 return error;
 1938         }
 1939         return 0;
 1940 }
 1941 
 1942 static int
 1943 iwl2100_set_opmode(struct iwl2100_softc *sc, enum ieee80211_opmode opmode)
 1944 {
 1945         struct iwl2100_cmd *cmd;
 1946         int error;
 1947 
 1948         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 1949                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 1950                 return EEXIST;
 1951         }
 1952 
 1953         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 1954         bzero(cmd, sizeof(*cmd));
 1955 
 1956         cmd->c_cmd = IWL2100_CMD_SET_OPMODE;
 1957         cmd->c_param_len = sizeof(cmd->c_param[0]);
 1958         switch (opmode) {
 1959         case IEEE80211_M_STA:
 1960                 cmd->c_param[0] = IWL2100_OPMODE_STA;
 1961                 break;
 1962         case IEEE80211_M_IBSS:
 1963                 cmd->c_param[0] = IWL2100_OPMODE_IBSS;
 1964                 break;
 1965         case IEEE80211_M_MONITOR:
 1966                 /* YYY ipw2100 leave this unset */
 1967                 cmd->c_param[0] = IWL2100_OPMODE_MONITOR;
 1968                 break;
 1969         default:
 1970                 panic("unsupported opmode %d", opmode);
 1971                 break;
 1972         }
 1973 
 1974         error = iwl2100_wait_cmd(sc);
 1975         if (error) {
 1976                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 1977                 return error;
 1978         }
 1979         return 0;
 1980 }
 1981 
 1982 static int
 1983 iwl2100_set_80211(struct iwl2100_softc *sc)
 1984 {
 1985         struct ieee80211com *ic = &sc->sc_ic;
 1986         struct iwl2100_cmd *cmd;
 1987         int error;
 1988 
 1989         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 1990                 if_printf(&ic->ic_if, "there is command pending\n");
 1991                 return EEXIST;
 1992         }
 1993 
 1994         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 1995         bzero(cmd, sizeof(*cmd));
 1996 
 1997         cmd->c_cmd = IWL2100_CMD_SET_80211;
 1998         cmd->c_param_len = sizeof(cmd->c_param[0]) * 3;
 1999         cmd->c_param[0] = IWL2100_CFG_IBSS | IWL2100_CFG_STA |
 2000                           IWL2100_CFG_8021X | IWL2100_CFG_AUTO_PREAMBLE;
 2001         if (ic->ic_opmode == IEEE80211_M_IBSS)
 2002                 cmd->c_param[0] |= IWL2100_CFG_IBSS_AUTO_START;
 2003         else if (ic->ic_opmode == IEEE80211_M_MONITOR) /* YYY not ipw2100 */
 2004                 cmd->c_param[0] |= IWL2100_CFG_MONITOR;
 2005         cmd->c_param[1] = IWL2100_CFG_CHANMASK; /* XXX sc->sc_bss_chans */
 2006         cmd->c_param[2] = IWL2100_CFG_CHANMASK; /* YYY sc->sc_ibss_chans */
 2007 
 2008         error = iwl2100_wait_cmd(sc);
 2009         if (error) {
 2010                 if_printf(&ic->ic_if, "%s failed\n", __func__);
 2011                 return error;
 2012         }
 2013         return 0;
 2014 }
 2015 
 2016 static int
 2017 iwl2100_set_basicrates(struct iwl2100_softc *sc)
 2018 {
 2019         struct iwl2100_cmd *cmd;
 2020         int error;
 2021 
 2022         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2023                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 2024                 return EEXIST;
 2025         }
 2026 
 2027         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2028         bzero(cmd, sizeof(*cmd));
 2029 
 2030         /*
 2031          * This configuration does not seem to have any effects
 2032          * on probe-req and assoc-req frames.
 2033          */
 2034         cmd->c_cmd = IWL2100_CMD_SET_BASICRATES;
 2035         cmd->c_param_len = sizeof(cmd->c_param[0]);
 2036         cmd->c_param[0] = 0x3;  /* 1Mbps and 2Mbps.  XXX from caller */
 2037 
 2038         error = iwl2100_wait_cmd(sc);
 2039         if (error) {
 2040                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 2041                 return error;
 2042         }
 2043         return 0;
 2044 }
 2045 
 2046 static int
 2047 iwl2100_set_txrates(struct iwl2100_softc *sc)
 2048 {
 2049         struct ieee80211com *ic = &sc->sc_ic;
 2050         struct iwl2100_cmd *cmd;
 2051         uint32_t rate_mask;
 2052         int error;
 2053 
 2054         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2055                 if_printf(&ic->ic_if, "there is command pending\n");
 2056                 return EEXIST;
 2057         }
 2058 
 2059         /* Calculate TX rate mask.  XXX let caller do this */
 2060         if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
 2061                 rate_mask = 1 << ic->ic_fixed_rate;
 2062         else
 2063                 rate_mask = 0xf; /* all 11b rates */
 2064         KKASSERT((rate_mask & ~0xf) == 0);
 2065 
 2066         /*
 2067          * Set TX rates
 2068          */
 2069         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2070         bzero(cmd, sizeof(*cmd));
 2071 
 2072         cmd->c_cmd = IWL2100_CMD_SET_TXRATES;
 2073         cmd->c_param_len = sizeof(cmd->c_param[0]);
 2074         cmd->c_param[0] = rate_mask;
 2075 
 2076         error = iwl2100_wait_cmd(sc);
 2077         if (error) {
 2078                 if_printf(&ic->ic_if, "%s failed\n", __func__);
 2079                 return error;
 2080         }
 2081 
 2082         /*
 2083          * Set MSDU TX rates
 2084          */
 2085         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2086         bzero(cmd, sizeof(*cmd));
 2087 
 2088         cmd->c_cmd = IWL2100_CMD_SET_MSDU_TXRATES;
 2089         cmd->c_param_len = sizeof(cmd->c_param[0]);
 2090         cmd->c_param[0] = rate_mask;
 2091 
 2092         error = iwl2100_wait_cmd(sc);
 2093         if (error) {
 2094                 if_printf(&ic->ic_if, "%s failed\n", __func__);
 2095                 return error;
 2096         }
 2097         return 0;
 2098 }
 2099 
 2100 static int
 2101 iwl2100_set_powersave(struct iwl2100_softc *sc, int on)
 2102 {
 2103         struct iwl2100_cmd *cmd;
 2104         int error;
 2105 
 2106         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2107                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 2108                 return EEXIST;
 2109         }
 2110 
 2111         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2112         bzero(cmd, sizeof(*cmd));
 2113 
 2114         cmd->c_cmd = IWL2100_CMD_SET_POWERSAVE;
 2115         cmd->c_param_len = sizeof(cmd->c_param[0]);
 2116         cmd->c_param[0] = on;   /* XXX power level? */
 2117 
 2118         error = iwl2100_wait_cmd(sc);
 2119         if (error) {
 2120                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 2121                 return error;
 2122         }
 2123         return 0;
 2124 }
 2125 
 2126 static int
 2127 iwl2100_set_rtsthreshold(struct iwl2100_softc *sc, uint16_t rtsthreshold)
 2128 {
 2129         struct iwl2100_cmd *cmd;
 2130         int error;
 2131 
 2132         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2133                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 2134                 return EEXIST;
 2135         }
 2136 
 2137         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2138         bzero(cmd, sizeof(*cmd));
 2139 
 2140         cmd->c_cmd = IWL2100_CMD_SET_RTSTHRESHOLD;
 2141         cmd->c_param_len = sizeof(cmd->c_param[0]);
 2142         if (rtsthreshold == IEEE80211_RTS_MAX) {
 2143                 /* Disable RTS threshold */
 2144                 cmd->c_param[0] = IWL2100_RTS_MAX;
 2145         } else {
 2146                 if (rtsthreshold >= IWL2100_RTS_MAX)
 2147                         rtsthreshold = IWL2100_RTS_MAX - 1;
 2148                 cmd->c_param[0] = rtsthreshold;
 2149         }
 2150 
 2151         error = iwl2100_wait_cmd(sc);
 2152         if (error) {
 2153                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 2154                 return error;
 2155         }
 2156         return 0;
 2157 }
 2158 
 2159 static int
 2160 iwl2100_set_bssid(struct iwl2100_softc *sc, const uint8_t *bssid)
 2161 {
 2162         struct iwl2100_cmd *cmd;
 2163         int error;
 2164 
 2165         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2166                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 2167                 return EEXIST;
 2168         }
 2169 
 2170         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2171         bzero(cmd, sizeof(*cmd));
 2172 
 2173         cmd->c_cmd = IWL2100_CMD_SET_BSSID;
 2174         if (bssid != NULL) {
 2175                 cmd->c_param_len = IEEE80211_ADDR_LEN;
 2176                 IEEE80211_ADDR_COPY(cmd->c_param, bssid);
 2177         }
 2178 
 2179         error = iwl2100_wait_cmd(sc);
 2180         if (error) {
 2181                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 2182                 return error;
 2183         }
 2184         return 0;
 2185 }
 2186 
 2187 static int
 2188 iwl2100_set_essid(struct iwl2100_softc *sc, const uint8_t *essid, int essid_len)
 2189 {
 2190         struct iwl2100_cmd *cmd;
 2191         int error;
 2192 
 2193         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2194                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 2195                 return EEXIST;
 2196         }
 2197 
 2198         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2199         bzero(cmd, sizeof(*cmd));
 2200 
 2201         cmd->c_cmd = IWL2100_CMD_SET_ESSID;
 2202         if (essid != NULL) {
 2203                 KKASSERT(essid_len <= sizeof(cmd->c_param));
 2204                 cmd->c_param_len = essid_len;
 2205                 if (essid_len != 0)
 2206                         bcopy(essid, cmd->c_param, essid_len);
 2207         }
 2208 
 2209         error = iwl2100_wait_cmd(sc);
 2210         if (error) {
 2211                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 2212                 return error;
 2213         }
 2214         return 0;
 2215 }
 2216 
 2217 static int
 2218 iwl2100_set_auth_ciphers(struct iwl2100_softc *sc,
 2219                          enum ieee80211_authmode authmode)
 2220 {
 2221         struct iwl2100_cmdparam_sec *sec;
 2222         struct iwl2100_cmd *cmd;
 2223         int error;
 2224 
 2225         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2226                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 2227                 return EEXIST;
 2228         }
 2229 
 2230         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2231         bzero(cmd, sizeof(*cmd));
 2232 
 2233         cmd->c_cmd = IWL2100_CMD_SET_SECURITY;
 2234         cmd->c_param_len = sizeof(*sec);
 2235         sec = (struct iwl2100_cmdparam_sec *)cmd->c_param;
 2236 
 2237         sec->sec_cipher_mask = IWL2100_CIPHER_NONE |
 2238                                IWL2100_CIPHER_WEP40 |
 2239                                IWL2100_CIPHER_TKIP |
 2240                                IWL2100_CIPHER_CCMP |
 2241                                IWL2100_CIPHER_WEP104;
 2242         if (authmode == IEEE80211_AUTH_SHARED)
 2243                 sec->sec_authmode = IWL2100_AUTH_SHARED;
 2244         else
 2245                 sec->sec_authmode = IWL2100_AUTH_OPEN;
 2246 
 2247         error = iwl2100_wait_cmd(sc);
 2248         if (error) {
 2249                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 2250                 return error;
 2251         }
 2252         return 0;
 2253 }
 2254 
 2255 static int
 2256 iwl2100_set_wepkey(struct iwl2100_softc *sc, const struct ieee80211_key *k)
 2257 {
 2258         struct iwl2100_cmdparam_wepkey *key;
 2259         struct iwl2100_cmd *cmd;
 2260         int error;
 2261 
 2262         if (k->wk_keylen > IWL2100_KEYDATA_SIZE)
 2263                 return E2BIG;
 2264 
 2265         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2266                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 2267                 return EEXIST;
 2268         }
 2269 
 2270         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2271         bzero(cmd, sizeof(*cmd));
 2272 
 2273         cmd->c_cmd = IWL2100_CMD_SET_WEPKEY;
 2274         cmd->c_param_len = sizeof(*key);
 2275         key = (struct iwl2100_cmdparam_wepkey *)cmd->c_param;
 2276         key->key_index = k->wk_keyix;
 2277         key->key_len = k->wk_keylen;
 2278         bcopy(k->wk_key, key->key_data, key->key_len);
 2279 
 2280         error = iwl2100_wait_cmd(sc);
 2281         if (error) {
 2282                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 2283                 return error;
 2284         }
 2285         return 0;
 2286 }
 2287 
 2288 static int
 2289 iwl2100_set_weptxkey(struct iwl2100_softc *sc, ieee80211_keyix txkey)
 2290 {
 2291         struct iwl2100_cmd *cmd;
 2292         int error;
 2293 
 2294         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2295                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 2296                 return EEXIST;
 2297         }
 2298 
 2299         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2300         bzero(cmd, sizeof(*cmd));
 2301 
 2302         cmd->c_cmd = IWL2100_CMD_SET_WEPTXKEY;
 2303         cmd->c_param_len = sizeof(cmd->c_param[0]);
 2304         cmd->c_param[0] = txkey;
 2305 
 2306         error = iwl2100_wait_cmd(sc);
 2307         if (error) {
 2308                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 2309                 return error;
 2310         }
 2311         return 0;
 2312 }
 2313 
 2314 static int
 2315 iwl2100_set_privacy(struct iwl2100_softc *sc, int on)
 2316 {
 2317         struct iwl2100_cmd *cmd;
 2318         int error;
 2319 
 2320         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2321                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 2322                 return EEXIST;
 2323         }
 2324 
 2325         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2326         bzero(cmd, sizeof(*cmd));
 2327 
 2328         cmd->c_cmd = IWL2100_CMD_SET_PRIVACY;
 2329         cmd->c_param_len = sizeof(cmd->c_param[0]);
 2330         cmd->c_param[0] = on ? IWL2100_PRIVACY_ENABLE : 0;
 2331 
 2332         error = iwl2100_wait_cmd(sc);
 2333         if (error) {
 2334                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 2335                 return error;
 2336         }
 2337         return 0;
 2338 }
 2339 
 2340 static int
 2341 iwl2100_wait_cmd(struct iwl2100_softc *sc)
 2342 {
 2343         struct ifnet *ifp = &sc->sc_ic.ic_if;
 2344         struct iwl2100_tx_ring *tr = &sc->sc_txring;
 2345         struct mbuf *m = sc->sc_cmd;
 2346         struct iwl_dmamap_ctx ctx;
 2347         bus_dma_segment_t seg;
 2348         struct iwl2100_desc *d;
 2349         struct iwl2100_txbuf *tb;
 2350         int error;
 2351 
 2352         ASSERT_SERIALIZED(ifp->if_serializer);
 2353 
 2354         KKASSERT(tr->tr_index < IWL2100_TX_NDESC);
 2355         tb = &tr->tr_buf[tr->tr_index];
 2356 
 2357         ctx.nsegs = 1;
 2358         ctx.segs = &seg;
 2359         error = bus_dmamap_load_mbuf(sc->sc_mbuf_dtag, tb->tb_dmap, m,
 2360                                      iwl_dma_buf_addr, &ctx, BUS_DMA_WAITOK);
 2361         if (error || ctx.nsegs == 0) {
 2362                 if (!error) {
 2363                         bus_dmamap_unload(sc->sc_mbuf_dtag, tb->tb_dmap);
 2364                         error = EFBIG;
 2365                         if_printf(ifp, "too many segments?!\n");
 2366                 }
 2367 
 2368                 if_printf(ifp, "can't load RX mbuf\n");
 2369                 return error;
 2370         }
 2371         tb->tb_mbuf = sc->sc_cmd;
 2372         tb->tb_flags |= IWL2100_TBF_CMDBUF;
 2373 
 2374         d = &tr->tr_desc[tr->tr_index];
 2375         d->d_paddr = seg.ds_addr;
 2376         d->d_len = sizeof(struct iwl2100_cmd);
 2377         d->d_nfrag = 1;
 2378         d->d_flags = IWL2100_TXD_F_INTR | IWL2100_TXD_F_CMD;
 2379 
 2380         KKASSERT(tr->tr_used < IWL2100_TX_NDESC);
 2381         ++tr->tr_used;
 2382         tr->tr_index = (tr->tr_index + 1) % IWL2100_TX_NDESC;
 2383 
 2384         bus_dmamap_sync(tr->tr_dtag, tr->tr_dmap, BUS_DMASYNC_PREWRITE);
 2385 
 2386         CSR_WRITE_4(sc, IWL2100_TXQ_WRITE_IDX, tr->tr_index);
 2387 
 2388         if (sc->sc_flags & IWL2100_F_IN_INTR)
 2389                 panic("sleep in interrupt thread");
 2390 
 2391         sc->sc_flags |= IWL2100_F_WAITCMD;
 2392         error = zsleep(sc, ifp->if_serializer, 0, "iwlcmd", 2 * hz);
 2393         if (!error) {
 2394                 sc->sc_flags &= ~IWL2100_F_WAITCMD;
 2395                 if (sc->sc_flags & IWL2100_F_ERROR) {
 2396                         if_printf(ifp, "error happened when waiting "
 2397                                   "command to be done\n");
 2398                         error = EIO;
 2399                 }
 2400         }
 2401         return error;
 2402 }
 2403 
 2404 static void
 2405 iwl2100_rxeof(struct iwl2100_softc *sc)
 2406 {
 2407         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
 2408         struct ifnet *ifp = &sc->sc_ic.ic_if;
 2409         int hwidx, i;
 2410 
 2411         hwidx = CSR_READ_4(sc, IWL2100_RXQ_READ_IDX);
 2412         CSR_READ_4(sc, IWL2100_RXQ_WRITE_IDX);
 2413 
 2414         if (hwidx >= IWL2100_RX_NDESC) {
 2415                 if_printf(ifp, "invalid hardware RX index %d\n", hwidx);
 2416                 return;
 2417         }
 2418 
 2419         KKASSERT(rr->rr_index < IWL2100_RX_NDESC);
 2420         i = (rr->rr_index + 1) % IWL2100_RX_NDESC;
 2421         while (hwidx != i) {
 2422                 struct iwl2100_rx_status *st = &rr->rr_status[i];
 2423                 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
 2424                 int frame_type;
 2425 
 2426                 bus_dmamap_sync(rr->rr_st_dtag, rr->rr_st_dmap,
 2427                                 BUS_DMASYNC_POSTREAD);
 2428                 frame_type = st->r_status & IWL2100_RXS_TYPE_MASK;
 2429 
 2430                 bus_dmamap_sync(sc->sc_mbuf_dtag, rb->rb_dmap,
 2431                                 BUS_DMASYNC_POSTREAD);
 2432                 switch (frame_type) {
 2433                 case IWL2100_RXS_TYPE_CMD:
 2434                         iwl2100_rxeof_cmd(sc, i);
 2435                         break;
 2436 
 2437                 case IWL2100_RXS_TYPE_STATUS:
 2438                         iwl2100_rxeof_status(sc, i);
 2439                         break;
 2440 
 2441                 case IWL2100_RXS_TYPE_NOTE:
 2442                         iwl2100_rxeof_note(sc, i);
 2443                         break;
 2444 
 2445                 case IWL2100_RXS_TYPE_DATA:
 2446                 case IWL2100_RXS_TYPE_DATA1:
 2447                         iwl2100_rxeof_data(sc, i);
 2448                         break;
 2449 
 2450                 default:
 2451                         if_printf(ifp, "unknown frame type: %d\n", frame_type);
 2452                         iwl2100_rxdesc_setup(sc, i);
 2453                         break;
 2454                 }
 2455                 i = (i + 1) % IWL2100_RX_NDESC;
 2456         }
 2457         bus_dmamap_sync(rr->rr_st_dtag, rr->rr_st_dmap, BUS_DMASYNC_POSTREAD);
 2458         bus_dmamap_sync(rr->rr_dtag, rr->rr_dmap, BUS_DMASYNC_POSTREAD);
 2459 
 2460         if (i == 0)
 2461                 rr->rr_index = IWL2100_RX_NDESC - 1;
 2462         else
 2463                 rr->rr_index = i - 1;
 2464         CSR_WRITE_4(sc, IWL2100_RXQ_WRITE_IDX, rr->rr_index);
 2465 }
 2466 
 2467 static void
 2468 iwl2100_txeof(struct iwl2100_softc *sc)
 2469 {
 2470         struct iwl2100_tx_ring *tr = &sc->sc_txring;
 2471         struct ifnet *ifp = &sc->sc_ic.ic_if;
 2472         int hwidx;
 2473 
 2474         hwidx = CSR_READ_4(sc, IWL2100_TXQ_READ_IDX);
 2475         CSR_READ_4(sc, IWL2100_TXQ_WRITE_IDX);
 2476         if (hwidx >= IWL2100_TX_NDESC) {
 2477                 if_printf(ifp, "invalid hardware TX index %d\n", hwidx);
 2478                 return;
 2479         }
 2480 
 2481         KKASSERT(tr->tr_coll < IWL2100_TX_NDESC);
 2482         while (tr->tr_used) {
 2483                 struct iwl2100_txbuf *tb;
 2484 
 2485                 if (tr->tr_coll == hwidx)
 2486                         break;
 2487 
 2488                 tb = &tr->tr_buf[tr->tr_coll];
 2489                 if (tb->tb_mbuf == NULL)
 2490                         goto next;
 2491 
 2492                 bus_dmamap_unload(sc->sc_mbuf_dtag, tb->tb_dmap);
 2493                 if (tb->tb_flags & IWL2100_TBF_CMDBUF) {
 2494                         tb->tb_flags &= ~IWL2100_TBF_CMDBUF;
 2495                         KKASSERT(tb->tb_mbuf == sc->sc_cmd);
 2496                 } else {
 2497                         m_freem(tb->tb_mbuf);
 2498                 }
 2499                 tb->tb_mbuf = NULL;
 2500 next:
 2501                 tr->tr_coll = (tr->tr_coll + 1) % IWL2100_TX_NDESC;
 2502 
 2503                 KKASSERT(tr->tr_used > 0);
 2504                 --tr->tr_used;
 2505         }
 2506 
 2507         if (tr->tr_used < IWL2100_TX_USED_MAX) {
 2508                 if (tr->tr_used == 0) {
 2509                         KKASSERT(tr->tr_coll == tr->tr_index);
 2510                         sc->sc_tx_timer = 0;
 2511                 }
 2512 
 2513                 ifq_clr_oactive(&ifp->if_snd);
 2514                 if_devstart(ifp);
 2515         }
 2516 }
 2517 
 2518 static int
 2519 iwl2100_config(struct iwl2100_softc *sc, const uint8_t *bssid,
 2520                const uint8_t *essid, uint8_t esslen, int ibss_chan)
 2521 {
 2522         struct ieee80211com *ic = &sc->sc_ic;
 2523         struct ifnet *ifp = &ic->ic_if;
 2524         int error;
 2525 
 2526         if (ic->ic_opmode == IEEE80211_M_MONITOR) {
 2527                 error = iwl2100_set_chan(sc, ic->ic_curchan);
 2528                 if (error) {
 2529                         if_printf(ifp, "can't set mon channel\n");
 2530                         return error;
 2531                 }
 2532         }
 2533 
 2534         IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
 2535         error = iwl2100_set_addr(sc, ic->ic_myaddr);
 2536         if (error) {
 2537                 if_printf(ifp, "can't set MAC address\n");
 2538                 return error;
 2539         }
 2540 
 2541         error = iwl2100_set_opmode(sc, ic->ic_opmode);
 2542         if (error) {
 2543                 if_printf(ifp, "can't set opmode\n");
 2544                 return error;
 2545         }
 2546 
 2547         if (ibss_chan) {
 2548                 KKASSERT(ic->ic_opmode == IEEE80211_M_IBSS);
 2549                 error = iwl2100_set_chan(sc, ic->ic_curchan);
 2550                 if (error) {
 2551                         if_printf(ifp, "can't set ibss channel\n");
 2552                         return error;
 2553                 }
 2554         }
 2555 
 2556         error = iwl2100_set_80211(sc);
 2557         if (error) {
 2558                 if_printf(ifp, "can't set 802.11 config\n");
 2559                 return error;
 2560         }
 2561 
 2562         error = iwl2100_set_basicrates(sc);
 2563         if (error) {
 2564                 if_printf(ifp, "can't set basicrates\n");
 2565                 return error;
 2566         }
 2567 
 2568         error = iwl2100_set_txrates(sc);
 2569         if (error) {
 2570                 if_printf(ifp, "can't set TX rates\n");
 2571                 return error;
 2572         }
 2573 
 2574         error = iwl2100_set_powersave(sc, ic->ic_flags & IEEE80211_F_PMGTON);
 2575         if (error) {
 2576                 if_printf(ifp, "can't turn off powersave\n");
 2577                 return error;
 2578         }
 2579 
 2580         error = iwl2100_set_rtsthreshold(sc, ic->ic_rtsthreshold);
 2581         if (error) {
 2582                 if_printf(ifp, "can't set RTS threshold\n");
 2583                 return error;
 2584         }
 2585 
 2586         error = iwl2100_set_bssid(sc, bssid);
 2587         if (error) {
 2588                 if_printf(ifp, "can't set bssid\n");
 2589                 return error;
 2590         }
 2591 
 2592         error = iwl2100_set_essid(sc, essid, esslen);
 2593         if (error) {
 2594                 if_printf(ifp, "can't set essid\n");
 2595                 return error;
 2596         }
 2597 
 2598         error = iwl2100_set_auth_ciphers(sc, ic->ic_bss->ni_authmode);
 2599         if (error) {
 2600                 if_printf(ifp, "can't set authmode and ciphers\n");
 2601                 return error;
 2602         }
 2603 
 2604         if (ic->ic_flags & IEEE80211_F_PRIVACY) {
 2605                 ieee80211_keyix txkey = IEEE80211_KEYIX_NONE;
 2606                 int i;
 2607 
 2608                 for (i = 0; i < IEEE80211_WEP_NKID; ++i) {
 2609                         const struct ieee80211_key *k = &ic->ic_nw_keys[i];
 2610 
 2611                         if (k->wk_keyix == IEEE80211_KEYIX_NONE)
 2612                                 continue;
 2613 
 2614                         error = iwl2100_set_wepkey(sc, k);
 2615                         if (error == E2BIG) {
 2616                                 continue;
 2617                         } else if (error) {
 2618                                 if_printf(ifp, "can't set wepkey\n");
 2619                                 return error;
 2620                         }
 2621                         txkey = k->wk_keyix;
 2622                 }
 2623 
 2624                 if (txkey != IEEE80211_KEYIX_NONE) {
 2625                         /*
 2626                          * Found some valid WEP keys.
 2627                          *
 2628                          * If WEP TX key index from 802.11 layer is not
 2629                          * set, then use the first valid WEP key as TX
 2630                          * key.
 2631                          */
 2632                         if (ic->ic_def_txkey != IEEE80211_KEYIX_NONE)
 2633                                 txkey = ic->ic_def_txkey;
 2634 
 2635                         error = iwl2100_set_weptxkey(sc, txkey);
 2636                         if (error) {
 2637                                 if_printf(ifp, "can't set weptxkey\n");
 2638                                 return error;
 2639                         }
 2640                 }
 2641         }
 2642 
 2643         error = iwl2100_set_privacy(sc, ic->ic_flags & IEEE80211_F_PRIVACY);
 2644         if (error) {
 2645                 if_printf(ifp, "can't set privacy\n");
 2646                 return error;
 2647         }
 2648 
 2649         error = iwl2100_set_optie(sc, ic->ic_opt_ie, ic->ic_opt_ie_len);
 2650         if (error) {
 2651                 if (error != E2BIG) {
 2652                         if_printf(ifp, "can't set opt ie\n");
 2653                         return error;
 2654                 }
 2655         }
 2656 
 2657         if (ic->ic_opmode == IEEE80211_M_IBSS) {
 2658                 error = iwl2100_set_bintval(sc, ic->ic_bss->ni_intval);
 2659                 if (error) {
 2660                         if_printf(ifp, "can't set bintval\n");
 2661                         return error;
 2662                 }
 2663 
 2664                 error = iwl2100_set_txpower(sc, 32 /* XXX */);
 2665                 if (error) {
 2666                         if_printf(ifp, "can't set txpwr\n");
 2667                         return error;
 2668                 }
 2669         }
 2670         return 0;
 2671 }
 2672 
 2673 static int
 2674 iwl2100_config_op(struct iwl2100_softc *sc, uint32_t op)
 2675 {
 2676         struct iwl2100_cmd *cmd;
 2677         int error;
 2678 
 2679         KASSERT(op == IWL2100_CMD_CONF_DONE || op == IWL2100_CMD_CONF_START,
 2680                 ("unknown config_op %u", op));
 2681 
 2682         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2683                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 2684                 return EEXIST;
 2685         }
 2686 
 2687         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2688         bzero(cmd, sizeof(*cmd));
 2689         cmd->c_cmd = op;
 2690 
 2691         error = iwl2100_wait_cmd(sc);
 2692         if (error) {
 2693                 if_printf(&sc->sc_ic.ic_if, "%s(%u) failed\n", __func__, op);
 2694                 return error;
 2695         }
 2696 
 2697         iwl2100_read_ord1(sc, IWL2100_ORD1_CONF_START); /* dummy read */
 2698         return 0;
 2699 }
 2700 
 2701 static int
 2702 iwl2100_set_chan(struct iwl2100_softc *sc, const struct ieee80211_channel *c)
 2703 {
 2704         struct ieee80211com *ic = &sc->sc_ic;
 2705         struct iwl2100_cmd *cmd;
 2706         u_int chan;
 2707         int error;
 2708 
 2709         KKASSERT(ic->ic_opmode != IEEE80211_M_STA);
 2710 
 2711         chan = ieee80211_chan2ieee(ic, c);
 2712         if (chan == IEEE80211_CHAN_ANY) {
 2713                 if_printf(&ic->ic_if, "invalid channel!\n");
 2714                 return EINVAL;
 2715         }
 2716 
 2717         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2718                 if_printf(&ic->ic_if, "there is command pending\n");
 2719                 return EEXIST;
 2720         }
 2721 
 2722         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2723         bzero(cmd, sizeof(*cmd));
 2724 
 2725         cmd->c_cmd = IWL2100_CMD_SET_CHAN;
 2726         cmd->c_param_len = sizeof(cmd->c_param[0]);
 2727         cmd->c_param[0] = chan;
 2728 
 2729         error = iwl2100_wait_cmd(sc);
 2730         if (error) {
 2731                 if_printf(&ic->ic_if, "%s failed\n", __func__);
 2732                 return error;
 2733         }
 2734         return 0;
 2735 }
 2736 
 2737 static int
 2738 iwl2100_set_scanopt(struct iwl2100_softc *sc, uint32_t chans, uint32_t flags)
 2739 {
 2740         struct ieee80211com *ic = &sc->sc_ic;
 2741         struct iwl2100_cmd *cmd;
 2742         int error;
 2743 
 2744         KKASSERT(ic->ic_opmode != IEEE80211_M_MONITOR);
 2745 
 2746         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2747                 if_printf(&ic->ic_if, "there is command pending\n");
 2748                 return EEXIST;
 2749         }
 2750 
 2751         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2752         bzero(cmd, sizeof(*cmd));
 2753 
 2754         /*
 2755          * NOTE:
 2756          * 1) IWL2100_SCANOPT_NOASSOC is ignored by firmware, but same
 2757          *    function could be achieved by clearing bssid.
 2758          * 2) Channel mask is ignored by firmware, if NIC is in STA opmode.
 2759          *
 2760          * We leave the correct configuration here just with the hope
 2761          * that one day firmware could do better.
 2762          */
 2763         cmd->c_cmd = IWL2100_CMD_SET_SCANOPT;
 2764         cmd->c_param_len = sizeof(cmd->c_param[0]) * 2;
 2765         cmd->c_param[0] = flags | IWL2100_SCANOPT_MIXED;
 2766         cmd->c_param[1] = chans;
 2767 
 2768         error = iwl2100_wait_cmd(sc);
 2769         if (error) {
 2770                 if_printf(&ic->ic_if, "%s failed\n", __func__);
 2771                 return error;
 2772         }
 2773         return 0;
 2774 }
 2775 
 2776 static int
 2777 iwl2100_set_scan(struct iwl2100_softc *sc)
 2778 {
 2779         struct ieee80211com *ic = &sc->sc_ic;
 2780         struct iwl2100_cmd *cmd;
 2781         int error;
 2782 
 2783         KKASSERT(ic->ic_opmode != IEEE80211_M_MONITOR);
 2784 
 2785         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2786                 if_printf(&ic->ic_if, "there is command pending\n");
 2787                 return EEXIST;
 2788         }
 2789 
 2790         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2791         bzero(cmd, sizeof(*cmd));
 2792 
 2793         cmd->c_cmd = IWL2100_CMD_SCAN;
 2794         cmd->c_param_len = sizeof(cmd->c_param[0]);
 2795 
 2796         error = iwl2100_wait_cmd(sc);
 2797         if (error) {
 2798                 if_printf(&ic->ic_if, "%s failed\n", __func__);
 2799                 return error;
 2800         }
 2801         return 0;
 2802 }
 2803 
 2804 static int
 2805 iwl2100_set_optie(struct iwl2100_softc *sc, void *optie, uint16_t optie_len)
 2806 {
 2807         struct iwl2100_cmd *cmd;
 2808         struct iwl2100_cmdparam_ie *ie;
 2809         int error;
 2810 
 2811         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2812                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 2813                 return EEXIST;
 2814         }
 2815 
 2816         if (optie_len > IWL2100_OPTIE_MAX) {
 2817                 if_printf(&sc->sc_ic.ic_if, "optie too long\n");
 2818                 return E2BIG;
 2819         }
 2820 
 2821         if (optie == NULL || optie_len == 0)
 2822                 return 0;
 2823 
 2824         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2825         bzero(cmd, sizeof(*cmd));
 2826 
 2827         cmd->c_cmd = IWL2100_CMD_SET_IE;
 2828         cmd->c_param_len = sizeof(*ie);
 2829         ie = (struct iwl2100_cmdparam_ie *)cmd->c_param;
 2830         ie->ie_optlen = optie_len;
 2831         bcopy(optie, ie->ie_opt, optie_len);
 2832 
 2833         error = iwl2100_wait_cmd(sc);
 2834         if (error) {
 2835                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 2836                 return error;
 2837         }
 2838         return 0;
 2839 }
 2840 
 2841 static int
 2842 iwl2100_set_bintval(struct iwl2100_softc *sc, uint16_t bintval)
 2843 {
 2844         struct iwl2100_cmd *cmd;
 2845         int error;
 2846 
 2847         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2848                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 2849                 return EEXIST;
 2850         }
 2851 
 2852         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2853         bzero(cmd, sizeof(*cmd));
 2854 
 2855         cmd->c_cmd = IWL2100_CMD_SET_BINTVAL;
 2856         cmd->c_param_len = sizeof(cmd->c_param[0]);
 2857         cmd->c_param[0] = bintval;
 2858 
 2859         error = iwl2100_wait_cmd(sc);
 2860         if (error) {
 2861                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 2862                 return error;
 2863         }
 2864         return 0;
 2865 }
 2866 
 2867 static int
 2868 iwl2100_set_txpower(struct iwl2100_softc *sc, uint16_t txpower)
 2869 {
 2870         struct iwl2100_cmd *cmd;
 2871         int error;
 2872 
 2873         if (sc->sc_flags & IWL2100_F_WAITCMD) {
 2874                 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
 2875                 return EEXIST;
 2876         }
 2877 
 2878         cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
 2879         bzero(cmd, sizeof(*cmd));
 2880 
 2881         cmd->c_cmd = IWL2100_CMD_SET_TXPOWER;
 2882         cmd->c_param_len = sizeof(cmd->c_param[0]);
 2883         cmd->c_param[0] = txpower;
 2884 
 2885         error = iwl2100_wait_cmd(sc);
 2886         if (error) {
 2887                 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
 2888                 return error;
 2889         }
 2890         return 0;
 2891 }
 2892 
 2893 static void
 2894 iwl2100_rxeof_status(struct iwl2100_softc *sc, int i)
 2895 {
 2896         struct ieee80211com *ic = &sc->sc_ic;
 2897         struct ifnet *ifp = &ic->ic_if;
 2898         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
 2899         struct iwl2100_rx_status *st = &rr->rr_status[i];
 2900         struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
 2901         struct mbuf *m = rb->rb_mbuf;
 2902         uint32_t status;
 2903 
 2904         if (st->r_len != sizeof(status)) {
 2905                 if_printf(ifp, "invalid status frame len %u\n", st->r_len);
 2906                 goto back;
 2907         }
 2908 
 2909         if (ic->ic_opmode == IEEE80211_M_MONITOR)
 2910                 goto back;
 2911 
 2912         if ((ic->ic_flags & IEEE80211_F_SCAN) == 0)
 2913                 sc->sc_flags &= ~IWL2100_F_SCANNING;
 2914 
 2915         status = *mtod(m, uint32_t *);
 2916         DPRINTF(sc, IWL2100_DBG_STATUS, "status 0x%08x\n", status);
 2917 
 2918         switch (status) {
 2919         case IWL2100_STATUS_SCANDONE:
 2920                 if (ic->ic_flags & IEEE80211_F_SCAN) {
 2921                         /*
 2922                          * To make sure that firmware has iterated all
 2923                          * of the channels, we wait for the second scan
 2924                          * done status change.
 2925                          */
 2926                         if (sc->sc_flags & IWL2100_F_SCANNING) {
 2927                                 iwlmsg_send(&sc->sc_scanend_msg,
 2928                                             &sc->sc_thread_port);
 2929                         } else {
 2930                                 sc->sc_flags |= IWL2100_F_SCANNING;
 2931                         }
 2932                 }
 2933                 break;
 2934 
 2935         case IWL2100_STATUS_RUNNING:
 2936                 iwl2100_restart_done(sc);
 2937                 if (ic->ic_state == IEEE80211_S_ASSOC) {
 2938                         KKASSERT(ic->ic_opmode == IEEE80211_M_STA);
 2939                         iwlmsg_send(&sc->sc_run_msg, &sc->sc_thread_port);
 2940                 } else if (ic->ic_state == IEEE80211_S_RUN) {
 2941                         if (ic->ic_opmode == IEEE80211_M_STA) {
 2942                                 DPRINTF(sc, IWL2100_DBG_RESTART, "%s",
 2943                                         "restart done\n");
 2944                                 sc->sc_flags |= IWL2100_F_IFSTART;
 2945                                 if_devstart(ifp);
 2946                         } else {
 2947                                 KKASSERT(ic->ic_opmode == IEEE80211_M_IBSS);
 2948                                 callout_reset(&sc->sc_ibss, (100 * hz) / 1000,
 2949                                               iwl2100_ibss_bssid, sc);
 2950                         }
 2951                 }
 2952                 break;
 2953 
 2954         case IWL2100_STATUS_BMISS:
 2955                 if (ic->ic_opmode == IEEE80211_M_STA) {
 2956                         DPRINTF(sc, IWL2100_DBG_SCAN, "%s", "bmiss\n");
 2957                         iwlmsg_send(&sc->sc_bmiss_msg, &sc->sc_thread_port);
 2958                 }
 2959                 break;
 2960 
 2961         case IWL2100_STATUS_SCANNING:
 2962                 if (ic->ic_opmode == IEEE80211_M_STA &&
 2963                     ic->ic_state == IEEE80211_S_RUN) {
 2964                         /* Firmware error happens */
 2965                         iwl2100_restart(sc);
 2966                 }
 2967                 break;
 2968         }
 2969 back:
 2970         iwl2100_rxdesc_setup(sc, i);
 2971 }
 2972 
 2973 static void
 2974 iwl2100_rxeof_note(struct iwl2100_softc *sc, int i)
 2975 {
 2976         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
 2977         struct iwl2100_rx_status *st = &rr->rr_status[i];
 2978         struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
 2979         struct mbuf *m = rb->rb_mbuf;
 2980         struct ieee80211com *ic = &sc->sc_ic;
 2981         struct iwl2100_note *note;
 2982 
 2983         if (st->r_len < sizeof(*note)) {
 2984                 if_printf(&ic->ic_if, "invalid note frame len %u\n", st->r_len);
 2985                 goto back;
 2986         }
 2987 
 2988         if (ic->ic_opmode == IEEE80211_M_MONITOR)
 2989                 goto back;
 2990 
 2991         note = mtod(m, struct iwl2100_note *);
 2992         DPRINTF(sc, IWL2100_DBG_NOTE, "note subtype %u, size %u\n",
 2993                 note->nt_subtype, note->nt_size);
 2994 
 2995         if (note->nt_subtype == 19 /* XXX */ &&
 2996             ic->ic_state == IEEE80211_S_AUTH) {
 2997                 KKASSERT(ic->ic_opmode == IEEE80211_M_STA);
 2998                 iwlmsg_send(&sc->sc_assoc_msg, &sc->sc_thread_port);
 2999         }
 3000 back:
 3001         iwl2100_rxdesc_setup(sc, i);
 3002 }
 3003 
 3004 static void
 3005 iwl2100_rxeof_cmd(struct iwl2100_softc *sc, int i)
 3006 {
 3007         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
 3008         struct iwl2100_rx_status *st = &rr->rr_status[i];
 3009         struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
 3010         struct mbuf *m = rb->rb_mbuf;
 3011         struct iwl2100_cmd *cmd;
 3012 
 3013         if (st->r_len != sizeof(*cmd)) {
 3014                 if_printf(&sc->sc_ic.ic_if,
 3015                           "invalid cmd done frame len %u\n", st->r_len);
 3016                 goto back;
 3017         }
 3018 
 3019         cmd = mtod(m, struct iwl2100_cmd *);
 3020         DPRINTF(sc, IWL2100_DBG_CMD, "cmd %u\n", cmd->c_cmd);
 3021         if (cmd->c_cmd == 0)
 3022                 sc->sc_flags |= IWL2100_F_ZERO_CMD;
 3023         wakeup(sc);
 3024 back:
 3025         iwl2100_rxdesc_setup(sc, i);
 3026 }
 3027 
 3028 static void
 3029 iwl2100_rxeof_data(struct iwl2100_softc *sc, int i)
 3030 {
 3031         struct ieee80211com *ic = &sc->sc_ic;
 3032         struct ifnet *ifp = &ic->ic_if;
 3033         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
 3034         struct iwl2100_rx_status *st = &rr->rr_status[i];
 3035         struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
 3036         struct mbuf *m = rb->rb_mbuf;
 3037         struct ieee80211_frame_min *wh;
 3038         struct ieee80211_node *ni;
 3039         int frame_len, rssi;
 3040         const struct ieee80211_channel *c;
 3041 
 3042         /*
 3043          * Gather all necessary information from status ring _here_,
 3044          * since the following iwl2100_newbuf() will clear them out.
 3045          */
 3046         rssi = st->r_rssi;
 3047         frame_len = st->r_len;
 3048 
 3049         if (iwl2100_newbuf(sc, i, 0)) {
 3050                 IFNET_STAT_INC(ifp, ierrors, 1);
 3051                 return;
 3052         }
 3053 
 3054         c = ic->ic_curchan;
 3055 
 3056         m->m_pkthdr.rcvif = ifp;
 3057         m->m_len = m->m_pkthdr.len = frame_len;
 3058 
 3059         wh = mtod(m, struct ieee80211_frame_min *);
 3060         ni = ieee80211_find_rxnode(ic, wh);
 3061 
 3062         /*
 3063          * RX radio tap
 3064          */
 3065         if (sc->sc_drvbpf != NULL) {
 3066                 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
 3067                         sc->sc_rx_th.wr_flags = IEEE80211_RADIOTAP_F_WEP;
 3068                 else
 3069                         sc->sc_rx_th.wr_flags = 0;
 3070 
 3071                 sc->sc_rx_th.wr_antsignal = rssi + IWL2100_NOISE_FLOOR;
 3072                 sc->sc_rx_th.wr_antnoise = IWL2100_NOISE_FLOOR;
 3073 
 3074                 bpf_ptap(sc->sc_drvbpf, m, &sc->sc_rx_th, sc->sc_rx_th_len);
 3075         }
 3076 
 3077         ieee80211_input(ic, m, ni, rssi, 0);
 3078         ieee80211_free_node(ni);
 3079 
 3080         if (c != ic->ic_curchan)        /* Happen during scanning */
 3081                 iwl2100_chan_change(sc, ic->ic_curchan);
 3082 }
 3083 
 3084 static void
 3085 iwl2100_scanend_dispatch(struct netmsg *nmsg)
 3086 {
 3087         struct iwlmsg *msg = (struct iwlmsg *)nmsg;
 3088         struct iwl2100_softc *sc = msg->iwlm_softc;
 3089         struct ieee80211com *ic = &sc->sc_ic;
 3090         struct ifnet *ifp = &ic->ic_if;
 3091 
 3092         ASSERT_SERIALIZED(ifp->if_serializer);
 3093 
 3094         if (sc->sc_flags & IWL2100_F_DETACH)
 3095                 goto reply;
 3096 
 3097         if (ifp->if_flags & IFF_RUNNING) {
 3098                 ieee80211_end_scan(ic);
 3099                 sc->sc_flags &= ~IWL2100_F_SCANNING;
 3100         }
 3101 reply:
 3102         lwkt_replymsg(&nmsg->nm_lmsg, 0);
 3103 }
 3104 
 3105 static int
 3106 iwl2100_hw_init(struct iwl2100_softc *sc, const uint8_t *bssid,
 3107                 const uint8_t *essid, uint8_t esslen, uint32_t flags)
 3108 {
 3109         struct ieee80211com *ic = &sc->sc_ic;
 3110         struct ifnet *ifp = &ic->ic_if;
 3111         uint32_t db_addr;
 3112         int error;
 3113 
 3114         ASSERT_SERIALIZED(ifp->if_serializer);
 3115         KKASSERT(curthread == &sc->sc_thread);
 3116 
 3117         iwl2100_hw_stop(sc);
 3118 
 3119         error = iwl2100_alloc_firmware(sc, ic->ic_opmode);
 3120         if (error) {
 3121                 if_printf(ifp, "can't allocate firmware\n");
 3122                 goto back;
 3123         }
 3124 
 3125         error = iwl2100_load_firmware(sc, ic->ic_opmode);
 3126         if (error) {
 3127                 if_printf(ifp, "can't load firmware\n");
 3128                 goto back;
 3129         }
 3130 
 3131         error = iwl2100_alloc_cmd(sc);
 3132         if (error) {
 3133                 if_printf(ifp, "can't allocate cmd\n");
 3134                 goto back;
 3135         }
 3136 
 3137         error = iwl2100_init_tx_ring(sc);
 3138         if (error) {
 3139                 if_printf(ifp, "can't init TX ring\n");
 3140                 goto back;
 3141         }
 3142 
 3143         error = iwl2100_init_rx_ring(sc);
 3144         if (error) {
 3145                 if_printf(ifp, "can't init RX ring\n");
 3146                 goto back;
 3147         }
 3148 
 3149         error = iwl2100_init_firmware(sc);
 3150         if (error) {
 3151                 if_printf(ifp, "can't initialize firmware\n");
 3152                 goto back;
 3153         }
 3154 
 3155         sc->sc_ord1 = CSR_READ_4(sc, IWL2100_ORD1_ADDR);
 3156         sc->sc_ord2 = CSR_READ_4(sc, IWL2100_ORD2_ADDR);
 3157 
 3158         db_addr = iwl2100_read_ord1(sc, IWL2100_ORD1_DBADDR);
 3159         if ((IND_READ_4(sc, db_addr + 0x20) >> 24) & 0x1)
 3160                 sc->sc_caps &= ~IWL2100_C_RFKILL;
 3161         else
 3162                 sc->sc_caps |= IWL2100_C_RFKILL;
 3163 
 3164         /* Unlock firmware */
 3165         iwl2100_write_ord1(sc, IWL2100_ORD1_FWLOCK, 0);
 3166 
 3167         if (iwl2100_rfkilled(sc)) {
 3168                 error = ENXIO;
 3169                 goto back;
 3170         }
 3171 
 3172         /* Let interrupt handler run */
 3173         sc->sc_flags |= IWL2100_F_INITED;
 3174 
 3175         /* Enable interrupts */
 3176         CSR_WRITE_4(sc, IWL2100_INTR_MASK, IWL2100_INTRS);
 3177 
 3178         error = iwl2100_config(sc, bssid, essid, esslen,
 3179                                flags & IWL2100_INIT_F_IBSSCHAN);
 3180         if (error)
 3181                 goto back;
 3182 
 3183         if (flags & IWL2100_INIT_F_ENABLE) {
 3184                 error = iwl2100_config_done(sc);
 3185                 if (error) {
 3186                         if_printf(ifp, "can't complete config\n");
 3187                         goto back;
 3188                 }
 3189         }
 3190 
 3191         ifq_clr_oactive(&ifp->if_snd);
 3192         ifp->if_flags |= IFF_RUNNING;
 3193 back:
 3194         if (error)
 3195                 iwl2100_stop(sc);
 3196         return error;
 3197 }
 3198 
 3199 static int
 3200 iwl2100_start_scan(struct iwl2100_softc *sc, uint32_t chans, uint32_t flags)
 3201 {
 3202         int error;
 3203 
 3204         /*
 3205          * XXX
 3206          * Firmware always starts scanning once config is done
 3207          */
 3208         error = iwl2100_set_scanopt(sc, chans, flags);
 3209         if (error) {
 3210                 if_printf(&sc->sc_ic.ic_if, "can't set scan opt\n");
 3211                 return error;
 3212         }
 3213 
 3214         error = iwl2100_set_scan(sc);
 3215         if (error) {
 3216                 if_printf(&sc->sc_ic.ic_if, "can't set bcast scanning\n");
 3217                 return error;
 3218         }
 3219         return 0;
 3220 }
 3221 
 3222 static int
 3223 iwl2100_scan(struct iwl2100_softc *sc)
 3224 {
 3225         struct ieee80211com *ic = &sc->sc_ic;
 3226         uint32_t chans, flags;
 3227         int error;
 3228 
 3229         KKASSERT(ic->ic_opmode != IEEE80211_M_MONITOR);
 3230 
 3231         error = iwl2100_hw_init(sc, NULL,
 3232                 ic->ic_des_essid, ic->ic_des_esslen, IWL2100_INIT_F_ENABLE);
 3233         if (error)
 3234                 return error;
 3235 
 3236         if (ic->ic_opmode == IEEE80211_M_STA) {
 3237                 chans = sc->sc_bss_chans;
 3238                 flags = IWL2100_SCANOPT_NOASSOC;
 3239         } else {
 3240                 /*
 3241                  * Normally # of IBSS channels is less than BSS's
 3242                  * but it seems IBSS mode works on all BSS channels
 3243                  */
 3244 #if 0
 3245                 chans = sc->sc_ibss_chans;
 3246 #else
 3247                 chans = sc->sc_bss_chans;
 3248 #endif
 3249                 /*
 3250                  * Don't set NOASSOC scan option, it seems that
 3251                  * firmware will disable itself after scanning
 3252                  * if this flag is set.  After all, we are in
 3253                  * IBSS mode, which does not have concept of
 3254                  * association.
 3255                  */
 3256                 flags = 0;
 3257         }
 3258 
 3259         /* See NOTE in iwl2100_set_scanopt() */
 3260         error = iwl2100_start_scan(sc, chans, flags);
 3261         if (error)
 3262                 return error;
 3263         return 0;
 3264 }
 3265 
 3266 static int
 3267 iwl2100_auth(struct iwl2100_softc *sc)
 3268 {
 3269         struct ieee80211com *ic = &sc->sc_ic;
 3270         struct ieee80211_node *ni = ic->ic_bss;
 3271         u_int chan;
 3272         int error;
 3273 
 3274         KKASSERT(ic->ic_opmode == IEEE80211_M_STA);
 3275 
 3276         chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
 3277         if (chan == IEEE80211_CHAN_ANY) {
 3278                 if_printf(&ic->ic_if, "invalid curchan\n");
 3279                 return EINVAL;
 3280         }
 3281 
 3282         error = iwl2100_hw_init(sc, ni->ni_bssid,
 3283                 ni->ni_essid, ni->ni_esslen, IWL2100_INIT_F_ENABLE);
 3284         if (error)
 3285                 return error;
 3286 
 3287         /* See NOTE in iwl2100_set_scanopt() */
 3288         error = iwl2100_start_scan(sc, 1 << (chan - 1), 0);
 3289         if (error)
 3290                 return error;
 3291         return 0;
 3292 }
 3293 
 3294 static int
 3295 iwl2100_ibss(struct iwl2100_softc *sc)
 3296 {
 3297         struct ieee80211com *ic = &sc->sc_ic;
 3298         struct ieee80211_node *ni = ic->ic_bss;
 3299 
 3300         return iwl2100_hw_init(sc, ni->ni_bssid,
 3301                 ni->ni_essid, ni->ni_esslen,
 3302                 IWL2100_INIT_F_ENABLE | IWL2100_INIT_F_IBSSCHAN);
 3303 }
 3304 
 3305 static int
 3306 iwl2100_encap(struct iwl2100_softc *sc, struct mbuf *m)
 3307 {
 3308         struct iwl2100_tx_ring *tr = &sc->sc_txring;
 3309         struct iwl2100_tx_hdr *th;
 3310         struct ieee80211_frame *wh;
 3311         struct iwl_dmamap_ctx ctx;
 3312         bus_dma_segment_t segs[IWL2100_NSEG_MAX];
 3313         uint8_t src[IEEE80211_ADDR_LEN], dst[IEEE80211_ADDR_LEN];
 3314         bus_dmamap_t dmap;
 3315         int maxsegs, i, first_idx, last_idx, error, host_enc;
 3316 
 3317         /*
 3318          * Save necessary information and strip 802.11 header
 3319          */
 3320         wh = mtod(m, struct ieee80211_frame *);
 3321         IEEE80211_ADDR_COPY(src, wh->i_addr2);
 3322         if (sc->sc_ic.ic_opmode == IEEE80211_M_STA)
 3323                 IEEE80211_ADDR_COPY(dst, wh->i_addr3);
 3324         else
 3325                 IEEE80211_ADDR_COPY(dst, wh->i_addr1);
 3326         if (wh->i_fc[1] & IEEE80211_FC1_WEP)
 3327                 host_enc = 1;
 3328         else
 3329                 host_enc = 0;
 3330         m_adj(m, sizeof(*wh));
 3331 
 3332         /*
 3333          * Prepend and setup hardware TX header
 3334          */
 3335         M_PREPEND(m, sizeof(*th), MB_DONTWAIT);
 3336         if (m == NULL) {
 3337                 if_printf(&sc->sc_ic.ic_if, "prepend TX header failed\n");
 3338                 return ENOBUFS;
 3339         }
 3340         th = mtod(m, struct iwl2100_tx_hdr *);
 3341 
 3342         bzero(th, sizeof(*th));
 3343         th->th_cmd = IWL2100_CMD_TX_DATA;
 3344         th->th_host_enc = host_enc;
 3345         IEEE80211_ADDR_COPY(th->th_src, src);
 3346         IEEE80211_ADDR_COPY(th->th_dst, dst);
 3347 
 3348         /*
 3349          * Load mbuf into DMA map
 3350          */
 3351         maxsegs = IWL2100_TX_USED_MAX - tr->tr_used;
 3352         if (maxsegs > IWL2100_NSEG_MAX)
 3353                 maxsegs = IWL2100_NSEG_MAX;
 3354 
 3355         KKASSERT(tr->tr_index < IWL2100_TX_NDESC);
 3356         first_idx = tr->tr_index;
 3357         dmap = tr->tr_buf[first_idx].tb_dmap;
 3358 
 3359         ctx.nsegs = maxsegs;
 3360         ctx.segs = segs;
 3361         error = bus_dmamap_load_mbuf(sc->sc_mbuf_dtag, dmap, m,
 3362                                      iwl_dma_buf_addr, &ctx, BUS_DMA_NOWAIT);
 3363         if (!error && ctx.nsegs == 0) {
 3364                 bus_dmamap_unload(sc->sc_mbuf_dtag, dmap);
 3365                 error = EFBIG;
 3366         }
 3367         if (error && error != EFBIG) {
 3368                 if_printf(&sc->sc_ic.ic_if, "can't load TX mbuf, error %d\n",
 3369                           error);
 3370                 goto back;
 3371         }
 3372         if (error) {    /* error == EFBIG */
 3373                 struct mbuf *m_new;
 3374 
 3375                 m_new = m_defrag(m, MB_DONTWAIT);
 3376                 if (m_new == NULL) {
 3377                         if_printf(&sc->sc_ic.ic_if, "can't defrag TX mbuf\n");
 3378                         error = ENOBUFS;
 3379                         goto back;
 3380                 } else {
 3381                         m = m_new;
 3382                 }
 3383 
 3384                 ctx.nsegs = maxsegs;
 3385                 ctx.segs = segs;
 3386                 error = bus_dmamap_load_mbuf(sc->sc_mbuf_dtag, dmap, m,
 3387                                              iwl_dma_buf_addr, &ctx,
 3388                                              BUS_DMA_NOWAIT);
 3389                 if (error || ctx.nsegs == 0) {
 3390                         if (ctx.nsegs == 0) {
 3391                                 bus_dmamap_unload(sc->sc_mbuf_dtag, dmap);
 3392                                 error = EFBIG;
 3393                         }
 3394                         if_printf(&sc->sc_ic.ic_if,
 3395                                   "can't load defraged TX mbuf\n");
 3396                         goto back;
 3397                 }
 3398         }
 3399         bus_dmamap_sync(sc->sc_mbuf_dtag, dmap, BUS_DMASYNC_PREWRITE);
 3400 
 3401         /*
 3402          * Fill TX desc ring
 3403          */
 3404         last_idx = -1;
 3405         for (i = 0; i < ctx.nsegs; ++i) {
 3406                 struct iwl2100_desc *d = &tr->tr_desc[tr->tr_index];
 3407 
 3408                 d->d_paddr = segs[i].ds_addr;
 3409                 d->d_len = segs[i].ds_len;
 3410                 if (i != 0)
 3411                         d->d_nfrag = 0;
 3412                 else
 3413                         d->d_nfrag = ctx.nsegs;
 3414 
 3415                 if (i == ctx.nsegs - 1) {
 3416                         d->d_flags = IWL2100_TXD_F_INTR;
 3417                         last_idx = tr->tr_index;
 3418                 } else {
 3419                         d->d_flags = IWL2100_TXD_F_NOTLAST;
 3420                 }
 3421 
 3422                 tr->tr_index = (tr->tr_index + 1) % IWL2100_TX_NDESC;
 3423         }
 3424         KKASSERT(last_idx >= 0);
 3425 
 3426         tr->tr_buf[first_idx].tb_dmap = tr->tr_buf[last_idx].tb_dmap;
 3427         tr->tr_buf[last_idx].tb_dmap = dmap;
 3428         tr->tr_buf[last_idx].tb_mbuf = m;
 3429 
 3430         tr->tr_used += ctx.nsegs;
 3431         KKASSERT(tr->tr_used <= IWL2100_TX_USED_MAX);
 3432 
 3433         error = 0;
 3434 back:
 3435         if (error)
 3436                 m_freem(m);
 3437         return error;
 3438 }
 3439 
 3440 static void
 3441 iwl2100_restart_dispatch(struct netmsg *nmsg)
 3442 {
 3443         struct iwlmsg *msg = (struct iwlmsg *)nmsg;
 3444         struct iwl2100_softc *sc = msg->iwlm_softc;
 3445         struct ieee80211com *ic = &sc->sc_ic;
 3446         struct ifnet *ifp = &ic->ic_if;
 3447         int error = 0;
 3448 
 3449         ASSERT_SERIALIZED(ifp->if_serializer);
 3450 
 3451         if (sc->sc_flags & IWL2100_F_DETACH)
 3452                 goto reply;
 3453 
 3454         if ((ifp->if_flags & IFF_RUNNING) == 0)
 3455                 goto reply;
 3456 
 3457         if (msg->iwlm_arg != sc->sc_state_age) {
 3458                 /*
 3459                  * Restarting was triggered in old 802.11 state
 3460                  * Don't do anything, this is a staled restarting.
 3461                  */
 3462                 goto reply;
 3463         }
 3464 
 3465         if (ic->ic_state != IEEE80211_S_RUN) {
 3466                 if_printf(ifp, "restart happened when not in RUN state\n");
 3467                 goto reply;
 3468         }
 3469 
 3470         /*
 3471          * iwl2100_auth() may release slizer, so stop all
 3472          * callouts to prevent them from misfiring.
 3473          */
 3474         callout_stop(&sc->sc_restart_bmiss);
 3475         callout_stop(&sc->sc_ibss);
 3476 
 3477         if (ic->ic_opmode == IEEE80211_M_STA) {
 3478                 error = iwl2100_auth(sc);
 3479                 if (error)
 3480                         goto reply;
 3481 
 3482                 /*
 3483                  * Start software beacon missing to handle missing
 3484                  * firmware bmiss status change when we restarting
 3485                  */
 3486                 callout_reset(&sc->sc_restart_bmiss, IEEE80211_TU_TO_TICKS(
 3487                         2 * ic->ic_bmissthreshold * ic->ic_bss->ni_intval),
 3488                         iwl2100_restart_bmiss, sc);
 3489         } else if (ic->ic_opmode == IEEE80211_M_IBSS) {
 3490                 error = iwl2100_ibss(sc);
 3491                 if (error)
 3492                         goto reply;
 3493         }
 3494 
 3495         /* Turn on restarting flag before reply this message */
 3496         sc->sc_flags |= IWL2100_F_RESTARTING;
 3497 reply:
 3498         lwkt_replymsg(&nmsg->nm_lmsg, error);
 3499 }
 3500 
 3501 static void
 3502 iwl2100_restart(struct iwl2100_softc *sc)
 3503 {
 3504         if ((sc->sc_flags & (IWL2100_F_RESTARTING | IWL2100_F_DETACH)) == 0) {
 3505                 struct iwlmsg *msg = &sc->sc_restart_msg;
 3506                 struct lwkt_msg *lmsg = &msg->iwlm_nmsg.nm_lmsg;
 3507 
 3508                 DPRINTF(sc, IWL2100_DBG_RESTART, "%s", "restart\n");
 3509                 if (lmsg->ms_flags & MSGF_DONE) {
 3510                         sc->sc_flags &= ~IWL2100_F_IFSTART;
 3511                         msg->iwlm_arg = sc->sc_state_age;
 3512                         lwkt_sendmsg(&sc->sc_thread_port, lmsg);
 3513                 }
 3514         }
 3515 }
 3516 
 3517 static void
 3518 iwl2100_bmiss_dispatch(struct netmsg *nmsg)
 3519 {
 3520         struct iwlmsg *msg = (struct iwlmsg *)nmsg;
 3521         struct iwl2100_softc *sc = msg->iwlm_softc;
 3522         struct ieee80211com *ic = &sc->sc_ic;
 3523         struct ifnet *ifp = &ic->ic_if;
 3524 
 3525         ASSERT_SERIALIZED(ifp->if_serializer);
 3526 
 3527         if (sc->sc_flags & IWL2100_F_DETACH)
 3528                 goto reply;
 3529 
 3530         if (ifp->if_flags & IFF_RUNNING) {
 3531                 /*
 3532                  * Fake a ic_bmiss_count to make sure that
 3533                  * ieee80211_beacon_miss() will do its job
 3534                  */
 3535                 ic->ic_bmiss_count = ic->ic_bmiss_max;
 3536                 ieee80211_beacon_miss(ic);
 3537         }
 3538 reply:
 3539         lwkt_replymsg(&nmsg->nm_lmsg, 0);
 3540 }
 3541 
 3542 static void
 3543 iwl2100_restart_bmiss(void *xsc)
 3544 {
 3545         struct iwl2100_softc *sc = xsc;
 3546         struct ifnet *ifp = &sc->sc_ic.ic_if;
 3547 
 3548         lwkt_serialize_enter(ifp->if_serializer);
 3549 
 3550         if (sc->sc_flags & IWL2100_F_DETACH)
 3551                 goto back;
 3552 
 3553         if ((ifp->if_flags & IFF_RUNNING) == 0)
 3554                 goto back;
 3555 
 3556         if (sc->sc_flags & IWL2100_F_RESTARTING) {
 3557                 DPRINTF(sc, IWL2100_DBG_SCAN | IWL2100_DBG_RESTART, "%s",
 3558                         "restart bmiss\n");
 3559                 iwlmsg_send(&sc->sc_bmiss_msg, &sc->sc_thread_port);
 3560         }
 3561 back:
 3562         lwkt_serialize_exit(ifp->if_serializer);
 3563 }
 3564 
 3565 static void
 3566 iwl2100_ibss_bssid(void *xsc)
 3567 {
 3568         struct iwl2100_softc *sc = xsc;
 3569         struct ieee80211com *ic = &sc->sc_ic;
 3570         struct ifnet *ifp = &ic->ic_if;
 3571         char ethstr[ETHER_ADDRSTRLEN + 1];
 3572 
 3573         lwkt_serialize_enter(ifp->if_serializer);
 3574 
 3575         if (sc->sc_flags & IWL2100_F_DETACH)
 3576                 goto back;
 3577 
 3578         if ((ifp->if_flags & IFF_RUNNING) == 0)
 3579                 goto back;
 3580 
 3581         if (ic->ic_state == IEEE80211_S_RUN &&
 3582             ic->ic_opmode == IEEE80211_M_IBSS) {
 3583                 uint8_t bssid[IEEE80211_ADDR_LEN];
 3584                 int len;
 3585 
 3586                 len = iwl2100_read_ord2(sc, IWL2100_ORD2_BSSID,
 3587                                         bssid, sizeof(bssid));
 3588                 if (len < (int)sizeof(bssid)) {
 3589                         if_printf(ifp, "can't get IBSS bssid\n");
 3590                 } else {
 3591                         DPRINTF(sc, IWL2100_DBG_IBSS, "IBSS bssid: %s\n",
 3592                             kether_ntoa(bssid, ethstr));
 3593                         IEEE80211_ADDR_COPY(ic->ic_bss->ni_bssid, bssid);
 3594 
 3595                         sc->sc_flags |= IWL2100_F_IFSTART;
 3596                         if_devstart(ifp);
 3597                 }
 3598         }
 3599 back:
 3600         lwkt_serialize_exit(ifp->if_serializer);
 3601 }
 3602 
 3603 static void
 3604 iwl2100_reinit(struct iwl2100_softc *sc)
 3605 {
 3606         struct ifnet *ifp = &sc->sc_ic.ic_if;
 3607 
 3608         callout_stop(&sc->sc_restart_bmiss);
 3609         callout_stop(&sc->sc_ibss);
 3610 
 3611         ifp->if_flags &= ~IFF_RUNNING;
 3612         ifp->if_timer = 0;
 3613 
 3614         sc->sc_flags &= ~IWL2100_F_INITED;
 3615         sc->sc_tx_timer = 0;
 3616 
 3617         /* Mark error happened, and wake up the pending command */
 3618         sc->sc_flags |= IWL2100_F_ERROR;
 3619         wakeup(sc);
 3620 
 3621         if ((sc->sc_flags & IWL2100_F_DETACH) == 0) {
 3622                 /*
 3623                  * Schedule complete initialization,
 3624                  * i.e. blow away current state
 3625                  */
 3626                 iwlmsg_send(&sc->sc_reinit_msg, &sc->sc_thread_port);
 3627         }
 3628 }
 3629 
 3630 static void
 3631 iwl2100_reinit_dispatch(struct netmsg *nmsg)
 3632 {
 3633         struct iwlmsg *msg = (struct iwlmsg *)nmsg;
 3634         struct iwl2100_softc *sc = msg->iwlm_softc;
 3635         struct ifnet *ifp = &sc->sc_ic.ic_if;
 3636 
 3637         ASSERT_SERIALIZED(ifp->if_serializer);
 3638 
 3639         /*
 3640          * NOTE: Reply ASAP, so reinit msg could be used if error intr
 3641          * happened again during following iwl2100_init()
 3642          */
 3643         lwkt_replymsg(&nmsg->nm_lmsg, 0);
 3644 
 3645         if (sc->sc_flags & IWL2100_F_DETACH)
 3646                 return;
 3647 
 3648         if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
 3649                 iwl2100_init(sc);
 3650 }
 3651 
 3652 static void
 3653 iwl2100_reinit_callout(void *xsc)
 3654 {
 3655         struct iwl2100_softc *sc = xsc;
 3656         struct ifnet *ifp = &sc->sc_ic.ic_if;
 3657 
 3658         lwkt_serialize_enter(ifp->if_serializer);
 3659         if ((sc->sc_flags & IWL2100_F_DETACH) == 0)
 3660                 iwl2100_reinit(sc);
 3661         lwkt_serialize_exit(ifp->if_serializer);
 3662 }
 3663 
 3664 static void
 3665 iwl2100_chan_change(struct iwl2100_softc *sc, const struct ieee80211_channel *c)
 3666 {
 3667         sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
 3668                 htole16(c->ic_freq);
 3669 }
 3670 
 3671 static void
 3672 iwl2100_stop_callouts(struct iwl2100_softc *sc)
 3673 {
 3674         callout_stop(&sc->sc_restart_bmiss);
 3675         callout_stop(&sc->sc_ibss);
 3676         callout_stop(&sc->sc_reinit);
 3677 }

Cache object: 93024bbb8db3701fa29910072bee0762


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