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