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