Merge branch 'vendor/FILE'
[dragonfly.git] / sys / dev / netif / iwl / iwl2100.c
1 /*
2  * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
3  * 
4  * This code is derived from software contributed to The DragonFly Project
5  * by Sepherosa Ziehau <sepherosa@gmail.com>
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  * 
34  * $DragonFly: src/sys/dev/netif/iwl/iwl2100.c,v 1.4 2008/05/14 11:59:20 sephe Exp $
35  */
36
37 #include <sys/param.h>
38 #include <sys/bus.h>
39 #include <sys/endian.h>
40 #include <sys/firmware.h>
41 #include <sys/kernel.h>
42 #include <sys/interrupt.h>
43 #include <sys/mbuf.h>
44 #include <sys/module.h>
45 #include <sys/sysctl.h>
46 #include <sys/socket.h>
47 #include <sys/sockio.h>
48 #include <sys/rman.h>
49
50 #include <net/bpf.h>
51 #include <net/if.h>
52 #include <net/if_arp.h>
53 #include <net/ethernet.h>
54 #include <net/if_dl.h>
55 #include <net/if_media.h>
56 #include <net/ifq_var.h>
57 #include <net/netmsg2.h>
58
59 #include <netproto/802_11/ieee80211_var.h>
60 #include <netproto/802_11/ieee80211_radiotap.h>
61
62 #include <bus/pci/pcireg.h>
63 #include <bus/pci/pcivar.h>
64
65 #include "if_iwlvar.h"
66 #include "iwl2100reg.h"
67 #include "iwl2100var.h"
68
69 #define IWL2100_INIT_F_ENABLE   0x1
70 #define IWL2100_INIT_F_IBSSCHAN 0x2
71
72 #define sc_tx_th        sc_u_tx_th.u_tx_th
73 #define sc_rx_th        sc_u_rx_th.u_rx_th
74
75 static void     iwl2100_init(void *);
76 static int      iwl2100_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
77 static void     iwl2100_start(struct ifnet *);
78 static void     iwl2100_watchdog(struct ifnet *);
79 static int      iwl2100_newstate(struct ieee80211com *, enum ieee80211_state, int);
80 static int      iwl2100_media_change(struct ifnet *);
81 static void     iwl2100_media_status(struct ifnet *, struct ifmediareq *);
82 static void     iwl2100_stop(struct iwl2100_softc *);
83 static void     iwl2100_restart(struct iwl2100_softc *);
84 static void     iwl2100_reinit(struct iwl2100_softc *);
85
86 static void     iwl2100_intr(void *);
87 static void     iwl2100_txeof(struct iwl2100_softc *);
88 static void     iwl2100_rxeof(struct iwl2100_softc *);
89 static void     iwl2100_rxeof_status(struct iwl2100_softc *, int);
90 static void     iwl2100_rxeof_note(struct iwl2100_softc *, int);
91 static void     iwl2100_rxeof_cmd(struct iwl2100_softc *, int);
92 static void     iwl2100_rxeof_data(struct iwl2100_softc *, int);
93
94 static void     iwl2100_init_dispatch(struct netmsg *);
95 static void     iwl2100_reinit_dispatch(struct netmsg *);
96 static void     iwl2100_stop_dispatch(struct netmsg *);
97 static void     iwl2100_newstate_dispatch(struct netmsg *);
98 static void     iwl2100_scanend_dispatch(struct netmsg *);
99 static void     iwl2100_restart_dispatch(struct netmsg *);
100 static void     iwl2100_bmiss_dispatch(struct netmsg *);
101
102 static void     iwl2100_stop_callouts(struct iwl2100_softc *);
103 static void     iwl2100_restart_bmiss(void *);
104 static void     iwl2100_ibss_bssid(void *);
105 static void     iwl2100_reinit_callout(void *);
106
107 static int      iwl2100_dma_alloc(device_t);
108 static void     iwl2100_dma_free(device_t);
109 static int      iwl2100_dma_mbuf_create(device_t);
110 static void     iwl2100_dma_mbuf_destroy(device_t, int, int);
111 static int      iwl2100_init_tx_ring(struct iwl2100_softc *);
112 static int      iwl2100_init_rx_ring(struct iwl2100_softc *);
113 static void     iwl2100_free_tx_ring(struct iwl2100_softc *);
114 static void     iwl2100_free_rx_ring(struct iwl2100_softc *);
115
116 static int      iwl2100_alloc_cmd(struct iwl2100_softc *);
117 static void     iwl2100_free_cmd(struct iwl2100_softc *);
118 static int      iwl2100_wait_cmd(struct iwl2100_softc *);
119
120 static void     iwl2100_rxdesc_setup(struct iwl2100_softc *, int);
121 static int      iwl2100_newbuf(struct iwl2100_softc *, int, int);
122 static int      iwl2100_encap(struct iwl2100_softc *, struct mbuf *);
123
124 static void     iwl2100_chan_change(struct iwl2100_softc *,
125                                     const struct ieee80211_channel *);
126
127 static int      iwl2100_alloc_firmware(struct iwl2100_softc *,
128                                        enum ieee80211_opmode);
129 static void     iwl2100_free_firmware(struct iwl2100_softc *);
130 static int      iwl2100_load_firmware(struct iwl2100_softc *,
131                                       enum ieee80211_opmode);
132 static int      iwl2100_load_fw_ucode(struct iwl2100_softc *,
133                                       const struct iwl2100_firmware *);
134 static int      iwl2100_load_fw_data(struct iwl2100_softc *,
135                                      const struct iwl2100_firmware *);
136 static int      iwl2100_init_firmware(struct iwl2100_softc *);
137
138 static int      iwl2100_read_ord2(struct iwl2100_softc *, uint32_t,
139                                   void *, int);
140 static uint32_t iwl2100_read_ord1(struct iwl2100_softc *, uint32_t);
141 static void     iwl2100_write_ord1(struct iwl2100_softc *, uint32_t, uint32_t);
142
143 static int      iwl2100_reset(struct iwl2100_softc *);
144 static int      iwl2100_hw_reset(struct iwl2100_softc *);
145 static int      iwl2100_rfkilled(struct iwl2100_softc *);
146
147 static int      iwl2100_scan(struct iwl2100_softc *);
148 static int      iwl2100_auth(struct iwl2100_softc *);
149 static int      iwl2100_ibss(struct iwl2100_softc *);
150
151 static int      iwl2100_hw_init(struct iwl2100_softc *, const uint8_t *,
152                                 const uint8_t *, uint8_t, uint32_t);
153 static void     iwl2100_hw_stop(struct iwl2100_softc *);
154 static int      iwl2100_config(struct iwl2100_softc *, const uint8_t *,
155                                const uint8_t *, uint8_t, int);
156 static int      iwl2100_start_scan(struct iwl2100_softc *, uint32_t, uint32_t);
157
158 static int      iwl2100_config_op(struct iwl2100_softc *, uint32_t);
159 static int      iwl2100_set_addr(struct iwl2100_softc *, const uint8_t *);
160 static int      iwl2100_set_opmode(struct iwl2100_softc *,
161                                    enum ieee80211_opmode);
162 static int      iwl2100_set_80211(struct iwl2100_softc *);
163 static int      iwl2100_set_basicrates(struct iwl2100_softc *);
164 static int      iwl2100_set_txrates(struct iwl2100_softc *);
165 static int      iwl2100_set_powersave(struct iwl2100_softc *, int);
166 static int      iwl2100_set_rtsthreshold(struct iwl2100_softc *, uint16_t);
167 static int      iwl2100_set_bssid(struct iwl2100_softc *, const uint8_t *);
168 static int      iwl2100_set_essid(struct iwl2100_softc *, const uint8_t *, int);
169 static int      iwl2100_set_auth_ciphers(struct iwl2100_softc *,
170                                          enum ieee80211_authmode);
171 static int      iwl2100_set_wepkey(struct iwl2100_softc *,
172                                    const struct ieee80211_key *);
173 static int      iwl2100_set_weptxkey(struct iwl2100_softc *, ieee80211_keyix);
174 static int      iwl2100_set_privacy(struct iwl2100_softc *, int);
175 static int      iwl2100_set_chan(struct iwl2100_softc *,
176                                  const struct ieee80211_channel *);
177 static int      iwl2100_set_scanopt(struct iwl2100_softc *, uint32_t, uint32_t);
178 static int      iwl2100_set_scan(struct iwl2100_softc *);
179 static int      iwl2100_set_optie(struct iwl2100_softc *, void *, uint16_t);
180 static int      iwl2100_set_bintval(struct iwl2100_softc *, uint16_t);
181 static int      iwl2100_set_txpower(struct iwl2100_softc *, uint16_t);
182
183 static __inline int
184 iwl2100_config_done(struct iwl2100_softc *sc)
185 {
186         return iwl2100_config_op(sc, IWL2100_CMD_CONF_DONE);
187 }
188
189 static __inline int
190 iwl2100_config_start(struct iwl2100_softc *sc)
191 {
192         return iwl2100_config_op(sc, IWL2100_CMD_CONF_START);
193 }
194
195 static __inline void
196 iwl2100_restart_done(struct iwl2100_softc *sc)
197 {
198         callout_stop(&sc->sc_restart_bmiss);
199         sc->sc_flags &= ~IWL2100_F_RESTARTING;
200 }
201
202 int
203 iwl2100_attach(device_t dev)
204 {
205         struct iwl2100_softc *sc = device_get_softc(dev);
206         struct ieee80211com *ic = &sc->sc_ic;
207         struct ifnet *ifp = &ic->ic_if;
208         uint16_t val;
209         int error, i;
210
211         /*
212          * Linux voodoo:
213          * Clear the retry timeout PCI configuration register to keep
214          * PCI TX retries from interfering with C3 CPU state.
215          */
216         pci_write_config(dev, IWL2100_PCIR_RETRY_TIMEOUT, 0, 1);
217
218         /*
219          * Allocate DMA stuffs
220          */
221         error = iwl2100_dma_alloc(dev);
222         if (error)
223                 return error;
224
225         /* Disable interrupts */
226         CSR_WRITE_4(sc, IWL2100_INTR_MASK, 0);
227
228         /*
229          * SW reset before reading EEPROM
230          */
231         error = iwl2100_reset(sc);
232         if (error)
233                 return error;
234
235         ifp->if_softc = sc;
236         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
237         ifp->if_init = iwl2100_init;
238         ifp->if_ioctl = iwl2100_ioctl;
239         ifp->if_start = iwl2100_start;
240         ifp->if_watchdog = iwl2100_watchdog;
241         ifq_set_maxlen(&ifp->if_snd, IWL2100_TX_USED_MAX);
242         ifq_set_ready(&ifp->if_snd);
243
244 #ifdef DUMP_EEPROM
245         device_printf(dev, "eeprom\n");
246         for (i = 0; i < 128; ++i) {
247                 if (i != 0 && i % 8 == 0)
248                         kprintf("\n");
249                 val = iwl_read_eeprom(&sc->iwlcom, i);
250                 kprintf("%04x ", val);
251         }
252         kprintf("\n");
253 #endif
254
255         /* IBSS channel mask */
256         sc->sc_ibss_chans = iwl_read_eeprom(&sc->iwlcom,
257                             IWL2100_EEPROM_IBSS_CHANS) & IWL2100_CFG_CHANMASK;
258
259         /* BSS channel mask */
260         sc->sc_bss_chans = iwl_read_eeprom(&sc->iwlcom, IWL2100_EEPROM_CHANS);
261
262         /*
263          * Set MAC address
264          */
265         for (i = 0; i < ETHER_ADDR_LEN / 2; ++i) {
266                 val = iwl_read_eeprom(&sc->iwlcom, IWL2100_EEPROM_MAC + i);
267                 ic->ic_myaddr[i * 2] = val >> 8;
268                 ic->ic_myaddr[(i * 2) + 1] = val & 0xff;
269         }
270
271         /*
272          * Set supported channels
273          */
274         for (i = 0; i < 14; ++i) {
275                 if (sc->sc_bss_chans & (1 << i)) {
276                         int chan = i + 1;
277
278                         ic->ic_channels[chan].ic_freq =
279                                 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
280                         ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_B;
281                 }
282         }
283
284         ic->ic_sup_rates[IEEE80211_MODE_11B] = iwl_rateset_11b;
285         ic->ic_phytype = IEEE80211_T_DS;
286         ic->ic_caps = IEEE80211_C_MONITOR |
287                       IEEE80211_C_IBSS |
288                       IEEE80211_C_SHPREAMBLE |
289                       IEEE80211_C_WPA;
290         ic->ic_caps_ext = IEEE80211_CEXT_AUTOSCAN;
291         ic->ic_state = IEEE80211_S_INIT;
292         ic->ic_opmode = IEEE80211_M_STA;
293
294         ieee80211_ifattach(ic);
295
296         /*
297          * ieee80211_frame will be stripped on TX path, so only
298          * extra space needs to be reserved.
299          */
300         ic->ic_headroom = sizeof(struct iwl2100_tx_hdr) -
301                           sizeof(struct ieee80211_frame);
302
303         sc->sc_newstate = ic->ic_newstate;
304         ic->ic_newstate = iwl2100_newstate;
305
306         ieee80211_media_init(ic, iwl2100_media_change, iwl2100_media_status);
307
308         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         ifp->if_cpuid = ithread_cpuid(rman_get_start(sc->sc_irq_res));
318         KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus);
319
320         /*
321          * Attach radio tap
322          */
323         bpfattach_dlt(ifp, DLT_IEEE802_11_RADIO,
324                       sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th),
325                       &sc->sc_drvbpf);
326
327         sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(uint32_t));
328         sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len);
329         sc->sc_tx_th.wt_ihdr.it_present = htole32(IWL2100_TX_RADIOTAP_PRESENT);
330
331         sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(uint32_t));
332         sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len);
333         sc->sc_rx_th.wr_ihdr.it_present = htole32(IWL2100_RX_RADIOTAP_PRESENT);
334
335         sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
336                 htole16(IEEE80211_CHAN_B);
337
338         /*
339          * Create worker thread and initialize all necessary messages
340          */
341         iwl_create_thread(&sc->iwlcom, device_get_unit(dev));
342
343         iwlmsg_init(&sc->sc_scanend_msg, &netisr_adone_rport,
344                     iwl2100_scanend_dispatch, sc);
345         iwlmsg_init(&sc->sc_restart_msg, &netisr_adone_rport,
346                     iwl2100_restart_dispatch, sc);
347         iwlmsg_init(&sc->sc_bmiss_msg, &netisr_adone_rport,
348                     iwl2100_bmiss_dispatch, sc);
349         iwlmsg_init(&sc->sc_reinit_msg, &netisr_adone_rport,
350                     iwl2100_reinit_dispatch, sc);
351
352         iwlmsg_init(&sc->sc_assoc_msg, &netisr_adone_rport,
353                     iwl2100_newstate_dispatch, sc);
354         sc->sc_assoc_msg.iwlm_nstate = IEEE80211_S_ASSOC;
355         sc->sc_assoc_msg.iwlm_arg = -1;
356
357         iwlmsg_init(&sc->sc_run_msg, &netisr_adone_rport,
358                     iwl2100_newstate_dispatch, sc);
359         sc->sc_run_msg.iwlm_nstate = IEEE80211_S_RUN;
360         sc->sc_run_msg.iwlm_arg = -1;
361
362         /*
363          * Initialize callouts
364          */
365         callout_init(&sc->sc_restart_bmiss);
366         callout_init(&sc->sc_ibss);
367         callout_init(&sc->sc_reinit);
368
369         /* Add sysctl node */
370         SYSCTL_ADD_UINT(&sc->sc_sysctl_ctx,
371                         SYSCTL_CHILDREN(sc->sc_sysctl_tree), OID_AUTO,
372                         "debug", CTLFLAG_RW, &sc->sc_debug, 0, "debug flags");
373
374         if (bootverbose)
375                 ieee80211_announce(ic);
376         return 0;
377 }
378
379 void
380 iwl2100_detach(device_t dev)
381 {
382         struct iwl2100_softc *sc = device_get_softc(dev);
383
384         if (device_is_attached(dev)) {
385                 struct ifnet *ifp = &sc->sc_ic.ic_if;
386
387                 lwkt_serialize_enter(ifp->if_serializer);
388
389                 sc->sc_flags |= IWL2100_F_DETACH;
390                 iwl2100_stop(sc);
391                 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_handle);
392                 iwl_destroy_thread(&sc->iwlcom);
393
394                 lwkt_serialize_exit(ifp->if_serializer);
395
396                 iwl2100_free_firmware(sc);
397
398                 bpfdetach(ifp);
399                 ieee80211_ifdetach(&sc->sc_ic);
400         }
401         iwl2100_dma_free(dev);
402 }
403
404 int
405 iwl2100_shutdown(device_t dev)
406 {
407         struct iwl2100_softc *sc = device_get_softc(dev);
408         struct ifnet *ifp = &sc->sc_ic.ic_if;
409
410         lwkt_serialize_enter(ifp->if_serializer);
411         iwl2100_stop(sc);
412         lwkt_serialize_exit(ifp->if_serializer);
413
414         return 0;
415 }
416
417 static void
418 iwl2100_stop(struct iwl2100_softc *sc)
419 {
420         struct iwlmsg msg;
421
422         ASSERT_SERIALIZED(sc->sc_ic.ic_if.if_serializer);
423
424         iwl2100_stop_callouts(sc);
425
426         iwlmsg_init(&msg, &sc->sc_reply_port, iwl2100_stop_dispatch, sc);
427         lwkt_domsg(&sc->sc_thread_port, &msg.iwlm_nmsg.nm_lmsg, 0);
428 }
429
430 static void
431 iwl2100_stop_dispatch(struct netmsg *nmsg)
432 {
433         struct iwlmsg *msg = (struct iwlmsg *)nmsg;
434         struct iwl2100_softc *sc = msg->iwlm_softc;
435
436         ASSERT_SERIALIZED(sc->sc_ic.ic_if.if_serializer);
437
438         ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
439         iwl2100_hw_stop(sc);
440         lwkt_replymsg(&nmsg->nm_lmsg, 0);
441 }
442
443 static void
444 iwl2100_hw_stop(struct iwl2100_softc *sc)
445 {
446         struct ifnet *ifp = &sc->sc_ic.ic_if;
447
448         ASSERT_SERIALIZED(ifp->if_serializer);
449         KKASSERT(curthread == &sc->sc_thread);
450
451         callout_stop(&sc->sc_reinit);
452
453         /* Disable interrupts */
454         CSR_WRITE_4(sc, IWL2100_INTR_MASK, 0);
455
456         /*
457          * HW and SW reset
458          */
459         iwl2100_hw_reset(sc);
460         iwl2100_reset(sc);
461
462         /*
463          * Free TX/RX rings
464          */
465         iwl2100_free_tx_ring(sc);
466         iwl2100_free_rx_ring(sc);
467
468         /* NOTE: MUST after iwl2100_free_tx_ring() */
469         iwl2100_free_cmd(sc);
470
471         ifp->if_timer = 0;
472         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
473
474         sc->sc_tx_timer = 0;
475         sc->sc_flags &= ~(IWL2100_F_WAITCMD |
476                           IWL2100_F_INITED |
477                           IWL2100_F_SCANNING |
478                           IWL2100_F_RESTARTING |
479                           IWL2100_F_IFSTART |
480                           IWL2100_F_ERROR |
481                           IWL2100_F_ZERO_CMD);
482 }
483
484 static int
485 iwl2100_reset(struct iwl2100_softc *sc)
486 {
487         int i;
488
489         /*
490          * Software reset
491          */
492 #define WAIT_MAX        1000
493
494         CSR_WRITE_4(sc, IWL2100_RESET, IWL2100_RESET_SW);
495         for (i = 0; i < WAIT_MAX; ++i) {
496                 DELAY(10);
497                 if (CSR_READ_4(sc, IWL2100_RESET) & IWL2100_RESET_DONE)
498                         break;
499         }
500         if (i == WAIT_MAX) {
501                 if_printf(&sc->sc_ic.ic_if, "sw reset timed out\n");
502                 return ETIMEDOUT;
503         }
504
505 #undef WAIT_MAX
506
507         /*
508          * Move to D0 state, wait clock to become stable
509          */
510 #define WAIT_MAX        10000
511
512         CSR_WRITE_4(sc, IWL2100_CTRL, IWL2100_CTRL_INITDONE);
513         for (i = 0; i < WAIT_MAX; ++i) {
514                 DELAY(200);
515                 if (CSR_READ_4(sc, IWL2100_CTRL) & IWL2100_CTRL_CLKREADY)
516                         break;
517         }
518         if (i == WAIT_MAX) {
519                 if_printf(&sc->sc_ic.ic_if, "can't stablize clock\n");
520                 return ETIMEDOUT;
521         }
522
523 #undef WAIT_MAX
524
525         /*
526          * Move to D0 standby
527          */
528         CSR_SETBITS_4(sc, IWL2100_CTRL, IWL2100_CTRL_STANDBY);
529         return 0;
530 }
531
532 static int
533 iwl2100_dma_alloc(device_t dev)
534 {
535         struct iwl2100_softc *sc = device_get_softc(dev);
536         struct iwl2100_tx_ring *tr = &sc->sc_txring;
537         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
538         int error;
539
540         /*
541          * Create top level DMA tag
542          */
543         error = bus_dma_tag_create(NULL, 1, 0,
544                                    BUS_SPACE_MAXADDR_32BIT,
545                                    BUS_SPACE_MAXADDR,
546                                    NULL, NULL,
547                                    MAXBSIZE,
548                                    BUS_SPACE_UNRESTRICTED,
549                                    BUS_SPACE_MAXSIZE_32BIT,
550                                    0, &sc->sc_dtag);
551         if (error) {
552                 device_printf(dev, "can't create DMA tag\n");
553                 return error;
554         }
555
556         /*
557          * Create DMA stuffs for TX desc ring
558          */
559         error = iwl_dma_mem_create(dev, sc->sc_dtag, IWL2100_TXRING_SIZE,
560                                    &tr->tr_dtag, (void **)&tr->tr_desc,
561                                    &tr->tr_paddr, &tr->tr_dmap);
562         if (error) {
563                 device_printf(dev, "can't create DMA memory for "
564                               "TX desc ring\n");
565                 return error;
566         }
567
568         /*
569          * Create DMA stuffs for RX desc ring
570          */
571         error = iwl_dma_mem_create(dev, sc->sc_dtag, IWL2100_RXRING_SIZE,
572                                    &rr->rr_dtag, (void **)&rr->rr_desc,
573                                    &rr->rr_paddr, &rr->rr_dmap);
574         if (error) {
575                 device_printf(dev, "can't create DMA memory for "
576                               "RX desc ring\n");
577                 return error;
578         }
579
580         /*
581          * Create DMA stuffs for RX status ring
582          */
583         error = iwl_dma_mem_create(dev, sc->sc_dtag, IWL2100_RXSTATUS_SIZE,
584                                    &rr->rr_st_dtag, (void **)&rr->rr_status,
585                                    &rr->rr_st_paddr, &rr->rr_st_dmap);
586         if (error) {
587                 device_printf(dev, "can't create DMA memory for "
588                               "RX status ring\n");
589                 return error;
590         }
591
592         /*
593          * Create mbuf DMA stuffs
594          */
595         error = iwl2100_dma_mbuf_create(dev);
596         if (error)
597                 return error;
598
599         return 0;
600 }
601
602 static void
603 iwl2100_dma_free(device_t dev)
604 {
605         struct iwl2100_softc *sc = device_get_softc(dev);
606         struct iwl2100_tx_ring *tr = &sc->sc_txring;
607         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
608
609         /* Free DMA stuffs for TX desc ring */
610         iwl_dma_mem_destroy(tr->tr_dtag, tr->tr_desc, tr->tr_dmap);
611
612         /* Free DMA stuffs for RX desc ring */
613         iwl_dma_mem_destroy(rr->rr_dtag, rr->rr_desc, rr->rr_dmap);
614
615         /* Free DMA stuffs for RX status ring */
616         iwl_dma_mem_destroy(rr->rr_st_dtag, rr->rr_status, rr->rr_st_dmap);
617
618         /* Free DMA stuffs for mbufs */
619         iwl2100_dma_mbuf_destroy(dev, IWL2100_TX_NDESC, IWL2100_RX_NDESC);
620
621         /* Free top level DMA tag */
622         if (sc->sc_dtag != NULL)
623                 bus_dma_tag_destroy(sc->sc_dtag);
624 }
625
626 static int
627 iwl2100_dma_mbuf_create(device_t dev)
628 {
629         struct iwl2100_softc *sc = device_get_softc(dev);
630         struct iwl2100_tx_ring *tr = &sc->sc_txring;
631         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
632         int i, error;
633
634         /*
635          * Create mbuf DMA tag
636          */
637         error = bus_dma_tag_create(sc->sc_dtag, 1, 0,
638                                    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
639                                    NULL, NULL,
640                                    MCLBYTES, IWL2100_NSEG_MAX,
641                                    BUS_SPACE_MAXSIZE_32BIT,
642                                    BUS_DMA_ALLOCNOW, &sc->sc_mbuf_dtag);
643         if (error) {
644                 device_printf(dev, "can't create mbuf DMA tag\n");
645                 return error;
646         }
647
648         /*
649          * Create spare DMA map for RX mbufs
650          */
651         error = bus_dmamap_create(sc->sc_mbuf_dtag, 0, &rr->rr_tmp_dmap);
652         if (error) {
653                 device_printf(dev, "can't create spare mbuf DMA map\n");
654                 bus_dma_tag_destroy(sc->sc_mbuf_dtag);
655                 sc->sc_mbuf_dtag = NULL;
656                 return error;
657         }
658
659         /*
660          * Create DMA maps for RX mbufs
661          */
662         for (i = 0; i < IWL2100_RX_NDESC; ++i) {
663                 error = bus_dmamap_create(sc->sc_mbuf_dtag, 0,
664                                           &rr->rr_buf[i].rb_dmap);
665                 if (error) {
666                         device_printf(dev, "can't create %d RX mbuf "
667                                       "for RX ring\n", i);
668                         iwl2100_dma_mbuf_destroy(dev, 0, i);
669                         return error;
670                 }
671         }
672
673         /*
674          * Create DMA maps for TX mbufs
675          */
676         for (i = 0; i < IWL2100_TX_NDESC; ++i) {
677                 error = bus_dmamap_create(sc->sc_mbuf_dtag, 0,
678                                           &tr->tr_buf[i].tb_dmap);
679                 if (error) {
680                         device_printf(dev, "can't create %d TX mbuf "
681                                       "DMA map\n", i);
682                         iwl2100_dma_mbuf_destroy(dev, i, IWL2100_RX_NDESC);
683                         return error;
684                 }
685         }
686         return 0;
687 }
688
689 static void
690 iwl2100_dma_mbuf_destroy(device_t dev, int tx_done, int rx_done)
691 {
692         struct iwl2100_softc *sc = device_get_softc(dev);
693         struct iwl2100_tx_ring *tr = &sc->sc_txring;
694         struct iwl2100_rx_ring *rr = &sc->sc_rxring;
695         int i;
696
697         if (sc->sc_mbuf_dtag == NULL)
698                 return;
699
700         /*
701          * Destroy DMA maps for RX mbufs
702          */
703         for (i = 0; i < rx_done; ++i) {
704                 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
705
706                 KASSERT(rb->rb_mbuf == NULL, ("RX mbuf is not freed yet\n"));
707                 bus_dmamap_destroy(sc->sc_mbuf_dtag, rb->rb_dmap);
708         }
709
710         /*
711          * Destroy DMA maps for TX mbufs
712          */
713         for (i = 0; i < tx_done; ++i) {
714                 struct iwl2100_txbuf *tb = &tr->tr_buf[i];
715
716                 KASSERT(tb->tb_mbuf == NULL, ("TX mbuf is not freed yet\n"));
717                 bus_dmamap_destroy(sc->sc_mbuf_dtag, tb->tb_dmap);
718         }
719
720         /*
721          * Destroy spare mbuf DMA map
722          */
723         bus_dmamap_destroy(sc->sc_mbuf_dtag, rr->rr_tmp_dmap);
724
725         /*
726          * Destroy mbuf DMA tag
727          */
728         bus_dma_tag_destroy(sc->sc_mbuf_dtag);
729         sc->sc_mbuf_dtag = NULL;
730 }
731
732 static void
733 iwl2100_init(void *xsc)
734 {
735         struct iwl2100_softc *sc = xsc;
736         struct iwlmsg msg;
737
738         ASSERT_SERIALIZED(sc->sc_ic.ic_if.if_serializer);
739
740         iwl2100_stop_callouts(sc);
741
742         iwlmsg_init(&msg, &sc->sc_reply_port, iwl2100_init_dispatch, sc);
743         lwkt_domsg(&sc->sc_thread_port, &msg.iwlm_nmsg.nm_lmsg, 0);
744 }
745
746 static void
747 iwl2100_init_dispatch(struct netmsg *nmsg)
748 {
749         struct iwlmsg *msg = (struct iwlmsg *)nmsg;
750         struct iwl2100_softc *sc = msg->iwlm_softc;
751         struct ieee80211com *ic = &sc->sc_ic;
752         struct ifnet *ifp = &ic->ic_if;
753         int error = 0, flags;
754
755         ASSERT_SERIALIZED(ifp->if_serializer);
756
757         if (sc->sc_flags & IWL2100_F_DETACH)
758                 goto back;
759
760         ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
761
762         if (ic->ic_opmode != IEEE80211_M_MONITOR) {
763                 /*
764                  * XXX
765                  * Workaround for dummy firmware:
766                  * Don't enable hardware too early, since
767                  * once it is enabled, it will start scanning.
768                  */
769                 flags = 0;
770         } else {
771                 flags = IWL2100_INIT_F_ENABLE;
772         }
773
774         /* Always put the device into a known state */
775         error = iwl2100_hw_init(sc, NULL,
776                 ic->ic_des_essid, ic->ic_des_esslen, flags);
777         if (error)
778                 goto back;
779
780         if (sc->sc_flags & IWL2100_F_ZERO_CMD) {
781                 if_printf(ifp, "zero cmd, reinit 1s later\n");
782                 iwl2100_hw_stop(sc);
783
784                 callout_reset(&sc->sc_reinit, hz, iwl2100_reinit_callout, sc);
785                 goto back;
786         }
787
788         if (ic->ic_opmode != IEEE80211_M_MONITOR) {
789                 if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
790                         ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
791         } else {
792                 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
793         }
794 back:
795         if (error)
796                 iwl2100_stop(sc);
797         lwkt_replymsg(&nmsg->nm_lmsg, error);
798 }
799
800 static int
801 iwl2100_ioctl(struct ifnet *ifp, u_long cmd, caddr_t req, struct ucred *cr)
802 {
803         struct iwl2100_softc *sc = ifp->if_softc;
804         int error = 0;
805
806         ASSERT_SERIALIZED(ifp->if_serializer);
807
808         if (sc->sc_flags & IWL2100_F_DETACH)
809                 return 0;
810
811         switch (cmd) {
812         case SIOCSIFFLAGS:
813                 if (ifp->if_flags & IFF_UP) {
814                         if ((ifp->if_flags & IFF_RUNNING) == 0)
815                                 iwl2100_init(sc);
816                 } else {
817                         if (ifp->if_flags & IFF_RUNNING) {
818                                 iwl2100_stop(sc);
819                         } else {
820                                 /*
821                                  * Stop callouts explicitly, since
822                                  * if reinitialization is happening,
823                                  * IFF_RUNNING will not be turned on.
824                                  */
825                                 iwl2100_stop_callouts(sc);
826                         }
827                 }
828                 break;
829         default:
830                 error = ieee80211_ioctl(&sc->sc_ic, cmd, req, cr);
831                 break;
832         }
833
834         if (error == ENETRESET) {
835                 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
836                     (IFF_UP | IFF_RUNNING))
837                         iwl2100_init(sc);
838                 error = 0;
839         }
840         return error;
841 }
842
843 static void
844 iwl2100_start(struct ifnet *ifp)
845 {
846         struct iwl2100_softc *sc = ifp->if_softc;
847         struct ieee80211com *ic = &sc->sc_ic;
848         struct iwl2100_tx_ring *tr = &sc->sc_txring;
849         int trans = 0;
850
851         ASSERT_SERIALIZED(ifp->if_serializer);
852
853         if (sc->sc_flags & IWL2100_F_DETACH) {
854                 ieee80211_drain_mgtq(&ic->ic_mgtq);
855                 ifq_purge(&ifp->if_snd);
856                 return;
857         }
858
859         if ((ifp->if_flags & (IFF_OACTIVE | IFF_RUNNING)) != IFF_RUNNING)
860                 return;
861
862         if ((sc->sc_flags & IWL2100_F_IFSTART) == 0) {
863                 ifq_purge(&ifp->if_snd);
864                 goto back;
865         }
866
867         while (tr->tr_used < IWL2100_TX_USED_MAX) {
868                 struct ieee80211_frame *wh;
869                 struct ieee80211_node *ni;
870                 struct ether_header *eh;
871                 struct mbuf *m;
872
873                 m = ifq_dequeue(&ifp->if_snd, NULL);
874                 if (m == NULL)
875                         break;
876
877                 if (m->m_len < sizeof(*eh)) {
878                         m = m_pullup(m, sizeof(*eh));
879                         if (m == NULL) {
880                                 ifp->if_oerrors++;
881                                 continue;
882                         }
883                 }
884                 eh = mtod(m, struct ether_header *);
885
886                 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
887                 if (ni == NULL) {
888                         m_freem(m);
889                         ifp->if_oerrors++;
890                         continue;
891                 }
892
893                 /* TODO: PS */
894
895                 BPF_MTAP(ifp, m);
896
897                 m = ieee80211_encap(ic, m, ni);
898                 if (m == NULL) {
899                         ieee80211_free_node(ni);
900                         ifp->if_oerrors++;
901                         continue;
902                 }
903
904                 if (ic->ic_rawbpf != NULL)
905                         bpf_mtap(ic->ic_rawbpf, m);
906
907                 wh = mtod(m, struct ieee80211_frame *);
908                 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
909                         if (ieee80211_crypto_encap(ic, ni, m) == NULL) {
910                                 ieee80211_free_node(ni);
911                                 m_freem(m);
912                                 ifp->if_oerrors++;
913                                 continue;
914                         }
915                 }
916
917                 /*
918                  * TX radio tap
919                  */
920                 if (sc->sc_drvbpf != NULL) {
921                         if (wh->i_fc[1] & IEEE80211_FC1_WEP)
922                                 sc->sc_tx_th.wt_flags = IEEE80211_RADIOTAP_F_WEP;
923                         else
924                                 sc->sc_tx_th.wt_flags = 0;
925                         bpf_ptap(sc->sc_drvbpf, m, &sc->sc_tx_th,
926                                  sc->sc_tx_th_len);
927                 }
928                 wh = NULL;      /* Catch any invalid use */
929
930                 ieee80211_free_node(ni);
931
932                 if (iwl2100_encap(sc, m)) {
933                         ifp->if_oerrors++;
934                         continue;
935                 }
936
937                 ifp->if_opackets++;
938                 trans = 1;
939         }
940
941         if (tr->tr_used >= IWL2100_TX_USED_MAX)
942                 ifp->if_flags |= IFF_OACTIVE;
943
944         if (trans) {
945                 bus_dmamap_sync(tr->tr_dtag, tr->tr_dmap, BUS_DMASYNC_PREWRITE);
946                 CSR_WRITE_4(sc, IWL2100_TXQ_WRITE_IDX, tr->tr_index);
947                 sc->sc_tx_timer = 5;
948         }
949 back:
950         ieee80211_drain_mgtq(&ic->ic_mgtq);
951         ifp->if_timer = 1;
952 }
953
954 static void
955 iwl2100_watchdog(struct ifnet *ifp)
956 {
957         struct iwl2100_softc *sc = ifp->if_softc;
958
959         ASSERT_SERIALIZED(ifp->if_serializer);
960
961         if (sc->sc_flags & IWL2100_F_DETACH)
962                 return;
963
964         if (sc->sc_tx_timer) {
965                 if (--sc->sc_tx_timer == 0) {
966                         if_printf(ifp, "watchdog timeout!\n");
967                         ifp->if_oerrors++;
968                         iwl2100_restart(sc);
969                         return;
970                 } else {
971                         ifp->if_timer = 1;
972                 }
973         }
974         ieee80211_watchdog(&sc->sc_ic);
975 }
976
977 static int
978 iwl2100_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
979 {
980         struct ifnet *ifp = &ic->ic_if;
981         struct iwl2100_softc *sc = ifp->if_softc;
982         struct iwlmsg msg;
983
984         ASSERT_SERIALIZED(ifp->if_serializer);
985
986         iwlmsg_init(&msg, &sc->sc_reply_port, iwl2100_newstate_dispatch, sc);
987         msg.iwlm_nstate = nstate;
988         msg.iwlm_arg = arg;
989
990         return lwkt_domsg(&sc->sc_thread_port, &msg.iwlm_nmsg.nm_lmsg, 0);
991 }
992
993 static void
994 iwl2100_newstate_dispatch(struct netmsg *nmsg)
995 {
996         struct iwlmsg *msg = (struct iwlmsg *)nmsg;
997         struct iwl2100_softc *sc = msg->iwlm_softc;
998         struct ieee80211com *ic = &sc->sc_ic;
999 #ifdef INVARIANTS
1000         struct ifnet *ifp = &ic->ic_if;
1001 #endif
1002         enum ieee80211_state nstate, ostate;
1003         int arg = msg->iwlm_arg, error = 0;
1004
1005         ASSERT_SERIALIZED(ifp->if_serializer);
1006
1007         nstate = msg->iwlm_nstate;
1008         ostate = ic->ic_state;
1009
1010         sc->sc_flags &= ~IWL2100_F_IFSTART;
1011         sc->sc_state_age++;
1012
1013         iwl2100_chan_change(sc, ic->ic_curchan);
1014
1015         callout_stop(&sc->sc_ibss);
1016         iwl2100_restart_done(sc);
1017
1018         if (nstate == IEEE80211_S_INIT)
1019                 goto back;
1020
1021         if (sc->sc_flags & IWL2100_F_DETACH) {
1022                 /*
1023                  * Except for INIT, we skip rest of the
1024                  * state changes during detaching
1025                  */
1026                 goto reply;
1027         }
1028
1029         if (ic->ic_opmode == IEEE80211_M_STA) {
1030                 if (nstate == IEEE80211_S_AUTH)
1031                         error = iwl2100_auth(sc);
1032                 else if (nstate == IEEE80211_S_RUN)
1033                         sc->sc_flags |= IWL2100_F_IFSTART;
1034         } else if (ic->ic_opmode == IEEE80211_M_IBSS) {
1035                 if (nstate == IEEE80211_S_RUN) {
1036                         DPRINTF(sc, IWL2100_DBG_IBSS, "%s",
1037                                 "start/join ibss\n");
1038
1039                         /*
1040                          * IWL2100_F_IFSTART can't be turned on
1041                          * until BSSID generated by the firmware
1042                          * is extracted.
1043                          *
1044                          * XXX only if we started the IBSS
1045                          */
1046                         error = iwl2100_ibss(sc);
1047                 }
1048         }
1049 back:
1050         if (!error)
1051                 error = sc->sc_newstate(ic, nstate, arg);
1052
1053         if (!error) {
1054                 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
1055                         /*
1056                          * Don't use 'nstate' here, since for IBSS
1057                          * mode 802.11 layer may enter RUN state in
1058                          * a recursive manner, i.e. when we reach
1059                          * here, nstate != ic->ic_state
1060                          */
1061                         if (ic->ic_state == IEEE80211_S_SCAN &&
1062                             ic->ic_state != ostate) {
1063                                 DPRINTF(sc, IWL2100_DBG_SCAN, "%s",
1064                                         "start scan\n");
1065                                 error = iwl2100_scan(sc);
1066                         }
1067                 }
1068         }
1069 reply:
1070         lwkt_replymsg(&nmsg->nm_lmsg, error);
1071 }
1072
1073 static int
1074 iwl2100_media_change(struct ifnet *ifp)
1075 {
1076         int error;
1077
1078         ASSERT_SERIALIZED(ifp->if_serializer);
1079
1080         error = ieee80211_media_change(ifp);
1081         if (error != ENETRESET)
1082                 return error;
1083
1084         if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
1085                 iwl2100_init(ifp->if_softc);
1086         return 0;
1087 }
1088
1089 static void
1090 iwl2100_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1091 {
1092         struct iwl2100_softc *sc = ifp->if_softc;
1093
1094         if (sc->sc_flags & IWL2100_F_IFSTART) {
1095                 struct ieee80211_node *ni = sc->sc_ic.ic_bss;
1096                 uint32_t txrate;
1097                 int i, nrates = 4;
1098
1099                 txrate = iwl2100_read_ord1(sc, IWL2100_ORD1_TXRATE) & 0xf;
1100                 if (ni->ni_rates.rs_nrates < 4)
1101                         nrates = ni->ni_rates.rs_nrates;
1102
1103                 for (i = 0; i < nrates; ++i) {
1104                         if ((1 << i) & txrate)
1105                                 ni->ni_txrate = i;
1106                 }
1107         }
1108         ieee80211_media_status(ifp, imr);
1109 }
1110
1111 static void
1112 iwl2100_intr(void *xsc)
1113 {
1114         struct iwl2100_softc *sc = xsc;
1115         struct ifnet *ifp = &sc->sc_ic.ic_if;
1116         uint32_t intr_status;
1117
1118         ASSERT_SERIALIZED(ifp->if_serializer);
1119
1120         if ((sc->sc_flags & IWL2100_F_INITED) == 0)
1121                 return;
1122
1123         intr_status = CSR_READ_4(sc, IWL2100_INTR_STATUS);
1124         if (intr_status == 0xffffffff)  /* not for us */
1125                 return;
1126
1127         if ((intr_status & IWL2100_INTRS) == 0) /* not interested */
1128                 return;
1129
1130         sc->sc_flags |= IWL2100_F_IN_INTR;
1131
1132         /* Disable interrupts */
1133         CSR_WRITE_4(sc, IWL2100_INTR_MASK, 0);
1134
1135         if (intr_status & IWL2100_INTR_EFATAL) {
1136                 uint32_t error_info;
1137
1138                 if_printf(ifp, "intr fatal error\n");
1139                 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_EFATAL);
1140
1141                 error_info = IND_READ_4(sc, IWL2100_IND_ERROR_INFO);
1142                 IND_READ_4(sc, error_info & IWL2100_IND_ERRORADDR_MASK);
1143
1144                 callout_stop(&sc->sc_reinit);
1145                 iwl2100_reinit(sc);
1146
1147                 /* Leave interrupts disabled */
1148                 goto back;
1149         }
1150
1151         if (intr_status & IWL2100_INTR_EPARITY) {
1152                 if_printf(ifp, "intr parity error\n");
1153                 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_EPARITY);
1154         }
1155
1156         if (intr_status & IWL2100_INTR_RX) {
1157                 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_RX);
1158                 iwl2100_rxeof(sc);
1159                 iwl2100_txeof(sc);
1160         }
1161
1162         if (intr_status & IWL2100_INTR_TX) {
1163                 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_TX);
1164                 iwl2100_txeof(sc);
1165         }
1166
1167         if (intr_status & IWL2100_INTR_FW_INITED)
1168                 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_FW_INITED);
1169         if (intr_status & IWL2100_INTR_CMD_DONE)
1170                 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_CMD_DONE);
1171
1172         /* Enable interrupts */
1173         CSR_WRITE_4(sc, IWL2100_INTR_MASK, IWL2100_INTRS);
1174 back:
1175         sc->sc_flags &= ~IWL2100_F_IN_INTR;
1176 }
1177
1178 static int
1179 iwl2100_hw_reset(struct iwl2100_softc *sc)
1180 {
1181         int i;
1182
1183         /*
1184          * Initialize GPIO:
1185          * - Enable GPIO3
1186          * - Make GPIO3 firmware writable
1187          * - Enable GPIO1
1188          * - Turn off LED
1189          */
1190         CSR_WRITE_4(sc, IWL2100_GPIO,
1191                     IWL2100_GPIO_3_EN | IWL2100_GPIO_3_FWWR |
1192                     IWL2100_GPIO_1_EN | IWL2100_GPIO_LEDOFF);
1193
1194         /*
1195          * Stop master
1196          */
1197 #define WAIT_MAX        5
1198
1199         CSR_WRITE_4(sc, IWL2100_RESET, IWL2100_RESET_STOP_MASTER);
1200         for (i = 0; i < WAIT_MAX; ++i) {
1201                 DELAY(10);
1202
1203                 if (CSR_READ_4(sc, IWL2100_RESET) &
1204                     IWL2100_RESET_MASTER_STOPPED)
1205                         break;
1206         }
1207         if (i == WAIT_MAX) {
1208                 if_printf(&sc->sc_ic.ic_if, "can't stop master\n");
1209                 return ETIMEDOUT;
1210         }
1211
1212 #undef WAIT_MAX
1213
1214         CSR_WRITE_4(sc, IWL2100_RESET, IWL2100_RESET_SW);
1215         return 0;
1216 }
1217
1218 static int
1219 iwl2100_alloc_firmware(struct iwl2100_softc *sc, enum ieee80211_opmode opmode)
1220 {
1221         struct {
1222                 const char *suffix;
1223                 uint16_t mode;
1224                 enum ieee80211_opmode opmode;
1225                 struct iwl2100_firmware *fw;
1226         } fw_arr[] = {
1227                 { "", IWL2100_FW_M_STA, IEEE80211_M_STA,
1228                   &sc->sc_fw_sta },
1229                 { "-i", IWL2100_FW_M_IBSS, IEEE80211_M_IBSS,
1230                   &sc->sc_fw_ibss },
1231                 { "-p", IWL2100_FW_M_MONITOR, IEEE80211_M_MONITOR,
1232                   &sc->sc_fw_monitor },
1233                 { NULL, 0, 0, NULL }
1234         };
1235         struct ifnet *ifp = &sc->sc_ic.ic_if;
1236         const struct iwl2100_fwimg_hdr *hdr;
1237         struct iwl2100_firmware *fw = NULL;
1238         struct fw_image *image;
1239         char filename[128];
1240         int i, error;
1241
1242         for (i = 0; fw_arr[i].fw != NULL; ++i) {
1243                 fw = fw_arr[i].fw;
1244
1245                 if (fw_arr[i].opmode == opmode) {
1246                         if (fw->fw_image != NULL)
1247                                 return 0;
1248                         else
1249                                 break;
1250                 }
1251         }
1252         KASSERT(fw_arr[i].fw != NULL, ("unsupported opmode %u\n", opmode));
1253
1254         ksnprintf(filename, sizeof(filename), IWL2100_FW_PATH,
1255                   fw_arr[i].suffix);
1256
1257         /*
1258          * Release the serializer to avoid possible dead lock
1259          */
1260         lwkt_serialize_exit(ifp->if_serializer);
1261         image = firmware_image_load(filename, NULL);
1262         lwkt_serialize_enter(ifp->if_serializer);
1263
1264         if (image == NULL)
1265                 return ENOENT;
1266         fw->fw_image = image;
1267
1268         /*
1269          * Verify the image
1270          */
1271         error = EINVAL;
1272
1273         hdr = (const struct iwl2100_fwimg_hdr *)image->fw_image;
1274         if ((hdr->version & 0xff) != 1) {
1275                 if_printf(ifp, "%s unsupported firmware version %d",
1276                           image->fw_name, hdr->version & 0xff);
1277                 goto back;
1278         }
1279
1280         if (hdr->mode != fw_arr[i].mode) {
1281                 if_printf(ifp, "%s contains %d mode firmware, should be %d\n",
1282                           image->fw_name, hdr->mode, fw_arr[i].mode);
1283                 goto back;
1284         }
1285
1286         if (hdr->data_size + hdr->ucode_size + sizeof(*hdr) !=
1287             image->fw_imglen) {
1288                 if_printf(ifp, "%s size mismatch, %u/hdr %u\n", image->fw_name,
1289                           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\n", 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\n", 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\n");
2388
2389         sc->sc_flags |= IWL2100_F_WAITCMD;
2390         error = serialize_sleep(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                 ifp->if_flags &= ~IFF_OACTIVE;
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                 ifp->if_ierrors++;
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         ifp->if_flags &= ~IFF_OACTIVE;
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
3570         lwkt_serialize_enter(ifp->if_serializer);
3571
3572         if (sc->sc_flags & IWL2100_F_DETACH)
3573                 goto back;
3574
3575         if ((ifp->if_flags & IFF_RUNNING) == 0)
3576                 goto back;
3577
3578         if (ic->ic_state == IEEE80211_S_RUN &&
3579             ic->ic_opmode == IEEE80211_M_IBSS) {
3580                 uint8_t bssid[IEEE80211_ADDR_LEN];
3581                 int len;
3582
3583                 len = iwl2100_read_ord2(sc, IWL2100_ORD2_BSSID,
3584                                         bssid, sizeof(bssid));
3585                 if (len < (int)sizeof(bssid)) {
3586                         if_printf(ifp, "can't get IBSS bssid\n");
3587                 } else {
3588                         DPRINTF(sc, IWL2100_DBG_IBSS, "IBSS bssid: %6D\n",
3589                                 bssid, ":");
3590                         IEEE80211_ADDR_COPY(ic->ic_bss->ni_bssid, bssid);
3591
3592                         sc->sc_flags |= IWL2100_F_IFSTART;
3593                         if_devstart(ifp);
3594                 }
3595         }
3596 back:
3597         lwkt_serialize_exit(ifp->if_serializer);
3598 }
3599
3600 static void
3601 iwl2100_reinit(struct iwl2100_softc *sc)
3602 {
3603         struct ifnet *ifp = &sc->sc_ic.ic_if;
3604
3605         callout_stop(&sc->sc_restart_bmiss);
3606         callout_stop(&sc->sc_ibss);
3607
3608         ifp->if_flags &= ~IFF_RUNNING;
3609         ifp->if_timer = 0;
3610
3611         sc->sc_flags &= ~IWL2100_F_INITED;
3612         sc->sc_tx_timer = 0;
3613
3614         /* Mark error happened, and wake up the pending command */
3615         sc->sc_flags |= IWL2100_F_ERROR;
3616         wakeup(sc);
3617
3618         if ((sc->sc_flags & IWL2100_F_DETACH) == 0) {
3619                 /*
3620                  * Schedule complete initialization,
3621                  * i.e. blow away current state
3622                  */
3623                 iwlmsg_send(&sc->sc_reinit_msg, &sc->sc_thread_port);
3624         }
3625 }
3626
3627 static void
3628 iwl2100_reinit_dispatch(struct netmsg *nmsg)
3629 {
3630         struct iwlmsg *msg = (struct iwlmsg *)nmsg;
3631         struct iwl2100_softc *sc = msg->iwlm_softc;
3632         struct ifnet *ifp = &sc->sc_ic.ic_if;
3633
3634         ASSERT_SERIALIZED(ifp->if_serializer);
3635
3636         /*
3637          * NOTE: Reply ASAP, so reinit msg could be used if error intr
3638          * happened again during following iwl2100_init()
3639          */
3640         lwkt_replymsg(&nmsg->nm_lmsg, 0);
3641
3642         if (sc->sc_flags & IWL2100_F_DETACH)
3643                 return;
3644
3645         if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
3646                 iwl2100_init(sc);
3647 }
3648
3649 static void
3650 iwl2100_reinit_callout(void *xsc)
3651 {
3652         struct iwl2100_softc *sc = xsc;
3653         struct ifnet *ifp = &sc->sc_ic.ic_if;
3654
3655         lwkt_serialize_enter(ifp->if_serializer);
3656         if ((sc->sc_flags & IWL2100_F_DETACH) == 0)
3657                 iwl2100_reinit(sc);
3658         lwkt_serialize_exit(ifp->if_serializer);
3659 }
3660
3661 static void
3662 iwl2100_chan_change(struct iwl2100_softc *sc, const struct ieee80211_channel *c)
3663 {
3664         sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
3665                 htole16(c->ic_freq);
3666 }
3667
3668 static void
3669 iwl2100_stop_callouts(struct iwl2100_softc *sc)
3670 {
3671         callout_stop(&sc->sc_restart_bmiss);
3672         callout_stop(&sc->sc_ibss);
3673         callout_stop(&sc->sc_reinit);
3674 }