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