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