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