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