Oops, I accidentally MFC'd too much.
[dragonfly.git] / sys / dev / netif / iwl / iwl2100.c
blobc1af330b4b0899b8bc2b1f07b9dda8d83d728ba9
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:
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.
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.
34 * $DragonFly: src/sys/dev/netif/iwl/iwl2100.c,v 1.4 2008/05/14 11:59:20 sephe Exp $
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>
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>
59 #include <netproto/802_11/ieee80211_var.h>
60 #include <netproto/802_11/ieee80211_radiotap.h>
62 #include <bus/pci/pcireg.h>
63 #include <bus/pci/pcivar.h>
65 #include "if_iwlvar.h"
66 #include "iwl2100reg.h"
67 #include "iwl2100var.h"
69 #define IWL2100_INIT_F_ENABLE 0x1
70 #define IWL2100_INIT_F_IBSSCHAN 0x2
72 #define sc_tx_th sc_u_tx_th.u_tx_th
73 #define sc_rx_th sc_u_rx_th.u_rx_th
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 *);
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);
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 *);
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 *);
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 *);
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 *);
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 *);
124 static void iwl2100_chan_change(struct iwl2100_softc *,
125 const struct ieee80211_channel *);
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 *);
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);
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 *);
147 static int iwl2100_scan(struct iwl2100_softc *);
148 static int iwl2100_auth(struct iwl2100_softc *);
149 static int iwl2100_ibss(struct iwl2100_softc *);
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);
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);
183 static __inline int
184 iwl2100_config_done(struct iwl2100_softc *sc)
186 return iwl2100_config_op(sc, IWL2100_CMD_CONF_DONE);
189 static __inline int
190 iwl2100_config_start(struct iwl2100_softc *sc)
192 return iwl2100_config_op(sc, IWL2100_CMD_CONF_START);
195 static __inline void
196 iwl2100_restart_done(struct iwl2100_softc *sc)
198 callout_stop(&sc->sc_restart_bmiss);
199 sc->sc_flags &= ~IWL2100_F_RESTARTING;
203 iwl2100_attach(device_t dev)
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;
212 * Linux voodoo:
213 * Clear the retry timeout PCI configuration register to keep
214 * PCI TX retries from interfering with C3 CPU state.
216 pci_write_config(dev, IWL2100_PCIR_RETRY_TIMEOUT, 0, 1);
219 * Allocate DMA stuffs
221 error = iwl2100_dma_alloc(dev);
222 if (error)
223 return error;
225 /* Disable interrupts */
226 CSR_WRITE_4(sc, IWL2100_INTR_MASK, 0);
229 * SW reset before reading EEPROM
231 error = iwl2100_reset(sc);
232 if (error)
233 return error;
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);
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);
252 kprintf("\n");
253 #endif
255 /* IBSS channel mask */
256 sc->sc_ibss_chans = iwl_read_eeprom(&sc->iwlcom,
257 IWL2100_EEPROM_IBSS_CHANS) & IWL2100_CFG_CHANMASK;
259 /* BSS channel mask */
260 sc->sc_bss_chans = iwl_read_eeprom(&sc->iwlcom, IWL2100_EEPROM_CHANS);
263 * Set MAC address
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;
272 * Set supported channels
274 for (i = 0; i < 14; ++i) {
275 if (sc->sc_bss_chans & (1 << i)) {
276 int chan = i + 1;
278 ic->ic_channels[chan].ic_freq =
279 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
280 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_B;
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;
294 ieee80211_ifattach(ic);
297 * ieee80211_frame will be stripped on TX path, so only
298 * extra space needs to be reserved.
300 ic->ic_headroom = sizeof(struct iwl2100_tx_hdr) -
301 sizeof(struct ieee80211_frame);
303 sc->sc_newstate = ic->ic_newstate;
304 ic->ic_newstate = iwl2100_newstate;
306 ieee80211_media_init(ic, iwl2100_media_change, iwl2100_media_status);
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;
317 ifp->if_cpuid = ithread_cpuid(rman_get_start(sc->sc_irq_res));
318 KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus);
321 * Attach radio tap
323 bpfattach_dlt(ifp, DLT_IEEE802_11_RADIO,
324 sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th),
325 &sc->sc_drvbpf);
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);
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);
335 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
336 htole16(IEEE80211_CHAN_B);
339 * Create worker thread and initialize all necessary messages
341 iwl_create_thread(&sc->iwlcom, device_get_unit(dev));
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);
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;
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;
363 * Initialize callouts
365 callout_init(&sc->sc_restart_bmiss);
366 callout_init(&sc->sc_ibss);
367 callout_init(&sc->sc_reinit);
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");
374 if (bootverbose)
375 ieee80211_announce(ic);
376 return 0;
379 void
380 iwl2100_detach(device_t dev)
382 struct iwl2100_softc *sc = device_get_softc(dev);
384 if (device_is_attached(dev)) {
385 struct ifnet *ifp = &sc->sc_ic.ic_if;
387 lwkt_serialize_enter(ifp->if_serializer);
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);
394 lwkt_serialize_exit(ifp->if_serializer);
396 iwl2100_free_firmware(sc);
398 bpfdetach(ifp);
399 ieee80211_ifdetach(&sc->sc_ic);
401 iwl2100_dma_free(dev);
405 iwl2100_shutdown(device_t dev)
407 struct iwl2100_softc *sc = device_get_softc(dev);
408 struct ifnet *ifp = &sc->sc_ic.ic_if;
410 lwkt_serialize_enter(ifp->if_serializer);
411 iwl2100_stop(sc);
412 lwkt_serialize_exit(ifp->if_serializer);
414 return 0;
417 static void
418 iwl2100_stop(struct iwl2100_softc *sc)
420 struct iwlmsg msg;
422 ASSERT_SERIALIZED(sc->sc_ic.ic_if.if_serializer);
424 iwl2100_stop_callouts(sc);
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);
430 static void
431 iwl2100_stop_dispatch(struct netmsg *nmsg)
433 struct iwlmsg *msg = (struct iwlmsg *)nmsg;
434 struct iwl2100_softc *sc = msg->iwlm_softc;
436 ASSERT_SERIALIZED(sc->sc_ic.ic_if.if_serializer);
438 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
439 iwl2100_hw_stop(sc);
440 lwkt_replymsg(&nmsg->nm_lmsg, 0);
443 static void
444 iwl2100_hw_stop(struct iwl2100_softc *sc)
446 struct ifnet *ifp = &sc->sc_ic.ic_if;
448 ASSERT_SERIALIZED(ifp->if_serializer);
449 KKASSERT(curthread == &sc->sc_thread);
451 callout_stop(&sc->sc_reinit);
453 /* Disable interrupts */
454 CSR_WRITE_4(sc, IWL2100_INTR_MASK, 0);
457 * HW and SW reset
459 iwl2100_hw_reset(sc);
460 iwl2100_reset(sc);
463 * Free TX/RX rings
465 iwl2100_free_tx_ring(sc);
466 iwl2100_free_rx_ring(sc);
468 /* NOTE: MUST after iwl2100_free_tx_ring() */
469 iwl2100_free_cmd(sc);
471 ifp->if_timer = 0;
472 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
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);
484 static int
485 iwl2100_reset(struct iwl2100_softc *sc)
487 int i;
490 * Software reset
492 #define WAIT_MAX 1000
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;
500 if (i == WAIT_MAX) {
501 if_printf(&sc->sc_ic.ic_if, "sw reset timed out\n");
502 return ETIMEDOUT;
505 #undef WAIT_MAX
508 * Move to D0 state, wait clock to become stable
510 #define WAIT_MAX 10000
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;
518 if (i == WAIT_MAX) {
519 if_printf(&sc->sc_ic.ic_if, "can't stablize clock\n");
520 return ETIMEDOUT;
523 #undef WAIT_MAX
526 * Move to D0 standby
528 CSR_SETBITS_4(sc, IWL2100_CTRL, IWL2100_CTRL_STANDBY);
529 return 0;
532 static int
533 iwl2100_dma_alloc(device_t dev)
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;
541 * Create top level DMA tag
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;
557 * Create DMA stuffs for TX desc ring
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;
569 * Create DMA stuffs for RX desc ring
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;
581 * Create DMA stuffs for RX status ring
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;
593 * Create mbuf DMA stuffs
595 error = iwl2100_dma_mbuf_create(dev);
596 if (error)
597 return error;
599 return 0;
602 static void
603 iwl2100_dma_free(device_t dev)
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;
609 /* Free DMA stuffs for TX desc ring */
610 iwl_dma_mem_destroy(tr->tr_dtag, tr->tr_desc, tr->tr_dmap);
612 /* Free DMA stuffs for RX desc ring */
613 iwl_dma_mem_destroy(rr->rr_dtag, rr->rr_desc, rr->rr_dmap);
615 /* Free DMA stuffs for RX status ring */
616 iwl_dma_mem_destroy(rr->rr_st_dtag, rr->rr_status, rr->rr_st_dmap);
618 /* Free DMA stuffs for mbufs */
619 iwl2100_dma_mbuf_destroy(dev, IWL2100_TX_NDESC, IWL2100_RX_NDESC);
621 /* Free top level DMA tag */
622 if (sc->sc_dtag != NULL)
623 bus_dma_tag_destroy(sc->sc_dtag);
626 static int
627 iwl2100_dma_mbuf_create(device_t dev)
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;
635 * Create mbuf DMA tag
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;
649 * Create spare DMA map for RX mbufs
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;
660 * Create DMA maps for RX mbufs
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;
674 * Create DMA maps for TX mbufs
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;
686 return 0;
689 static void
690 iwl2100_dma_mbuf_destroy(device_t dev, int tx_done, int rx_done)
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;
697 if (sc->sc_mbuf_dtag == NULL)
698 return;
701 * Destroy DMA maps for RX mbufs
703 for (i = 0; i < rx_done; ++i) {
704 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
706 KASSERT(rb->rb_mbuf == NULL, ("RX mbuf is not freed yet\n"));
707 bus_dmamap_destroy(sc->sc_mbuf_dtag, rb->rb_dmap);
711 * Destroy DMA maps for TX mbufs
713 for (i = 0; i < tx_done; ++i) {
714 struct iwl2100_txbuf *tb = &tr->tr_buf[i];
716 KASSERT(tb->tb_mbuf == NULL, ("TX mbuf is not freed yet\n"));
717 bus_dmamap_destroy(sc->sc_mbuf_dtag, tb->tb_dmap);
721 * Destroy spare mbuf DMA map
723 bus_dmamap_destroy(sc->sc_mbuf_dtag, rr->rr_tmp_dmap);
726 * Destroy mbuf DMA tag
728 bus_dma_tag_destroy(sc->sc_mbuf_dtag);
729 sc->sc_mbuf_dtag = NULL;
732 static void
733 iwl2100_init(void *xsc)
735 struct iwl2100_softc *sc = xsc;
736 struct iwlmsg msg;
738 ASSERT_SERIALIZED(sc->sc_ic.ic_if.if_serializer);
740 iwl2100_stop_callouts(sc);
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);
746 static void
747 iwl2100_init_dispatch(struct netmsg *nmsg)
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;
755 ASSERT_SERIALIZED(ifp->if_serializer);
757 if (sc->sc_flags & IWL2100_F_DETACH)
758 goto back;
760 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
762 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
764 * XXX
765 * Workaround for dummy firmware:
766 * Don't enable hardware too early, since
767 * once it is enabled, it will start scanning.
769 flags = 0;
770 } else {
771 flags = IWL2100_INIT_F_ENABLE;
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;
780 if (sc->sc_flags & IWL2100_F_ZERO_CMD) {
781 if_printf(ifp, "zero cmd, reinit 1s later\n");
782 iwl2100_hw_stop(sc);
784 callout_reset(&sc->sc_reinit, hz, iwl2100_reinit_callout, sc);
785 goto back;
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);
794 back:
795 if (error)
796 iwl2100_stop(sc);
797 lwkt_replymsg(&nmsg->nm_lmsg, error);
800 static int
801 iwl2100_ioctl(struct ifnet *ifp, u_long cmd, caddr_t req, struct ucred *cr)
803 struct iwl2100_softc *sc = ifp->if_softc;
804 int error = 0;
806 ASSERT_SERIALIZED(ifp->if_serializer);
808 if (sc->sc_flags & IWL2100_F_DETACH)
809 return 0;
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 {
821 * Stop callouts explicitly, since
822 * if reinitialization is happening,
823 * IFF_RUNNING will not be turned on.
825 iwl2100_stop_callouts(sc);
828 break;
829 default:
830 error = ieee80211_ioctl(&sc->sc_ic, cmd, req, cr);
831 break;
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;
840 return error;
843 static void
844 iwl2100_start(struct ifnet *ifp)
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;
851 ASSERT_SERIALIZED(ifp->if_serializer);
853 if (sc->sc_flags & IWL2100_F_DETACH) {
854 ieee80211_drain_mgtq(&ic->ic_mgtq);
855 ifq_purge(&ifp->if_snd);
856 return;
859 if ((ifp->if_flags & (IFF_OACTIVE | IFF_RUNNING)) != IFF_RUNNING)
860 return;
862 if ((sc->sc_flags & IWL2100_F_IFSTART) == 0) {
863 ifq_purge(&ifp->if_snd);
864 goto back;
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;
873 m = ifq_dequeue(&ifp->if_snd, NULL);
874 if (m == NULL)
875 break;
877 if (m->m_len < sizeof(*eh)) {
878 m = m_pullup(m, sizeof(*eh));
879 if (m == NULL) {
880 ifp->if_oerrors++;
881 continue;
884 eh = mtod(m, struct ether_header *);
886 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
887 if (ni == NULL) {
888 m_freem(m);
889 ifp->if_oerrors++;
890 continue;
893 /* TODO: PS */
895 BPF_MTAP(ifp, m);
897 m = ieee80211_encap(ic, m, ni);
898 if (m == NULL) {
899 ieee80211_free_node(ni);
900 ifp->if_oerrors++;
901 continue;
904 if (ic->ic_rawbpf != NULL)
905 bpf_mtap(ic->ic_rawbpf, m);
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;
918 * TX radio tap
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);
928 wh = NULL; /* Catch any invalid use */
930 ieee80211_free_node(ni);
932 if (iwl2100_encap(sc, m)) {
933 ifp->if_oerrors++;
934 continue;
937 ifp->if_opackets++;
938 trans = 1;
941 if (tr->tr_used >= IWL2100_TX_USED_MAX)
942 ifp->if_flags |= IFF_OACTIVE;
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;
949 back:
950 ieee80211_drain_mgtq(&ic->ic_mgtq);
951 ifp->if_timer = 1;
954 static void
955 iwl2100_watchdog(struct ifnet *ifp)
957 struct iwl2100_softc *sc = ifp->if_softc;
959 ASSERT_SERIALIZED(ifp->if_serializer);
961 if (sc->sc_flags & IWL2100_F_DETACH)
962 return;
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;
974 ieee80211_watchdog(&sc->sc_ic);
977 static int
978 iwl2100_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
980 struct ifnet *ifp = &ic->ic_if;
981 struct iwl2100_softc *sc = ifp->if_softc;
982 struct iwlmsg msg;
984 ASSERT_SERIALIZED(ifp->if_serializer);
986 iwlmsg_init(&msg, &sc->sc_reply_port, iwl2100_newstate_dispatch, sc);
987 msg.iwlm_nstate = nstate;
988 msg.iwlm_arg = arg;
990 return lwkt_domsg(&sc->sc_thread_port, &msg.iwlm_nmsg.nm_lmsg, 0);
993 static void
994 iwl2100_newstate_dispatch(struct netmsg *nmsg)
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;
1005 ASSERT_SERIALIZED(ifp->if_serializer);
1007 nstate = msg->iwlm_nstate;
1008 ostate = ic->ic_state;
1010 sc->sc_flags &= ~IWL2100_F_IFSTART;
1011 sc->sc_state_age++;
1013 iwl2100_chan_change(sc, ic->ic_curchan);
1015 callout_stop(&sc->sc_ibss);
1016 iwl2100_restart_done(sc);
1018 if (nstate == IEEE80211_S_INIT)
1019 goto back;
1021 if (sc->sc_flags & IWL2100_F_DETACH) {
1023 * Except for INIT, we skip rest of the
1024 * state changes during detaching
1026 goto reply;
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");
1040 * IWL2100_F_IFSTART can't be turned on
1041 * until BSSID generated by the firmware
1042 * is extracted.
1044 * XXX only if we started the IBSS
1046 error = iwl2100_ibss(sc);
1049 back:
1050 if (!error)
1051 error = sc->sc_newstate(ic, nstate, arg);
1053 if (!error) {
1054 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
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
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);
1069 reply:
1070 lwkt_replymsg(&nmsg->nm_lmsg, error);
1073 static int
1074 iwl2100_media_change(struct ifnet *ifp)
1076 int error;
1078 ASSERT_SERIALIZED(ifp->if_serializer);
1080 error = ieee80211_media_change(ifp);
1081 if (error != ENETRESET)
1082 return error;
1084 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
1085 iwl2100_init(ifp->if_softc);
1086 return 0;
1089 static void
1090 iwl2100_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1092 struct iwl2100_softc *sc = ifp->if_softc;
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;
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;
1103 for (i = 0; i < nrates; ++i) {
1104 if ((1 << i) & txrate)
1105 ni->ni_txrate = i;
1108 ieee80211_media_status(ifp, imr);
1111 static void
1112 iwl2100_intr(void *xsc)
1114 struct iwl2100_softc *sc = xsc;
1115 struct ifnet *ifp = &sc->sc_ic.ic_if;
1116 uint32_t intr_status;
1118 ASSERT_SERIALIZED(ifp->if_serializer);
1120 if ((sc->sc_flags & IWL2100_F_INITED) == 0)
1121 return;
1123 intr_status = CSR_READ_4(sc, IWL2100_INTR_STATUS);
1124 if (intr_status == 0xffffffff) /* not for us */
1125 return;
1127 if ((intr_status & IWL2100_INTRS) == 0) /* not interested */
1128 return;
1130 sc->sc_flags |= IWL2100_F_IN_INTR;
1132 /* Disable interrupts */
1133 CSR_WRITE_4(sc, IWL2100_INTR_MASK, 0);
1135 if (intr_status & IWL2100_INTR_EFATAL) {
1136 uint32_t error_info;
1138 if_printf(ifp, "intr fatal error\n");
1139 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_EFATAL);
1141 error_info = IND_READ_4(sc, IWL2100_IND_ERROR_INFO);
1142 IND_READ_4(sc, error_info & IWL2100_IND_ERRORADDR_MASK);
1144 callout_stop(&sc->sc_reinit);
1145 iwl2100_reinit(sc);
1147 /* Leave interrupts disabled */
1148 goto back;
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);
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);
1162 if (intr_status & IWL2100_INTR_TX) {
1163 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_TX);
1164 iwl2100_txeof(sc);
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);
1172 /* Enable interrupts */
1173 CSR_WRITE_4(sc, IWL2100_INTR_MASK, IWL2100_INTRS);
1174 back:
1175 sc->sc_flags &= ~IWL2100_F_IN_INTR;
1178 static int
1179 iwl2100_hw_reset(struct iwl2100_softc *sc)
1181 int i;
1184 * Initialize GPIO:
1185 * - Enable GPIO3
1186 * - Make GPIO3 firmware writable
1187 * - Enable GPIO1
1188 * - Turn off LED
1190 CSR_WRITE_4(sc, IWL2100_GPIO,
1191 IWL2100_GPIO_3_EN | IWL2100_GPIO_3_FWWR |
1192 IWL2100_GPIO_1_EN | IWL2100_GPIO_LEDOFF);
1195 * Stop master
1197 #define WAIT_MAX 5
1199 CSR_WRITE_4(sc, IWL2100_RESET, IWL2100_RESET_STOP_MASTER);
1200 for (i = 0; i < WAIT_MAX; ++i) {
1201 DELAY(10);
1203 if (CSR_READ_4(sc, IWL2100_RESET) &
1204 IWL2100_RESET_MASTER_STOPPED)
1205 break;
1207 if (i == WAIT_MAX) {
1208 if_printf(&sc->sc_ic.ic_if, "can't stop master\n");
1209 return ETIMEDOUT;
1212 #undef WAIT_MAX
1214 CSR_WRITE_4(sc, IWL2100_RESET, IWL2100_RESET_SW);
1215 return 0;
1218 static int
1219 iwl2100_alloc_firmware(struct iwl2100_softc *sc, enum ieee80211_opmode opmode)
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 }
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;
1242 for (i = 0; fw_arr[i].fw != NULL; ++i) {
1243 fw = fw_arr[i].fw;
1245 if (fw_arr[i].opmode == opmode) {
1246 if (fw->fw_image != NULL)
1247 return 0;
1248 else
1249 break;
1252 KASSERT(fw_arr[i].fw != NULL, ("unsupported opmode %u\n", opmode));
1254 ksnprintf(filename, sizeof(filename), IWL2100_FW_PATH,
1255 fw_arr[i].suffix);
1258 * Release the serializer to avoid possible dead lock
1260 lwkt_serialize_exit(ifp->if_serializer);
1261 image = firmware_image_load(filename, NULL);
1262 lwkt_serialize_enter(ifp->if_serializer);
1264 if (image == NULL)
1265 return ENOENT;
1266 fw->fw_image = image;
1269 * Verify the image
1271 error = EINVAL;
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;
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;
1286 if (hdr->data_size + hdr->ucode_size + sizeof(*hdr) !=
1287 image->fw_imglen) {
1288 if_printf(ifp, "%s size mismatch, %u/hdr %u\n", image->fw_name,
1289 fw->fw_image->fw_imglen,
1290 hdr->data_size + hdr->ucode_size + sizeof(*hdr));
1291 goto back;
1294 fw->fw_data = (const uint8_t *)(hdr + 1);
1295 fw->fw_data_size = hdr->data_size;
1296 fw->fw_ucode = fw->fw_data + fw->fw_data_size;
1297 fw->fw_ucode_size = hdr->ucode_size;
1298 error = 0;
1299 back:
1300 if (error) {
1301 firmware_image_unload(fw->fw_image);
1302 bzero(fw, sizeof(*fw));
1304 return error;
1307 static void
1308 iwl2100_free_firmware(struct iwl2100_softc *sc)
1310 struct iwl2100_firmware *fw_arr[] =
1311 { &sc->sc_fw_sta, &sc->sc_fw_ibss, &sc->sc_fw_monitor, NULL };
1312 int i;
1314 for (i = 0; fw_arr[i] != NULL; ++i) {
1315 struct iwl2100_firmware *fw = fw_arr[i];
1317 if (fw->fw_image != NULL) {
1318 firmware_image_unload(fw->fw_image);
1319 bzero(fw, sizeof(*fw));
1324 static int
1325 iwl2100_load_firmware(struct iwl2100_softc *sc, enum ieee80211_opmode opmode)
1327 static const struct {
1328 uint32_t addr;
1329 int size;
1330 } share_mem[] = {
1331 { IWL2100_SHMEM0, IWL2100_SHMEM0_SIZE },
1332 { IWL2100_SHMEM1, IWL2100_SHMEM1_SIZE },
1333 { IWL2100_SHMEM2, IWL2100_SHMEM2_SIZE },
1334 { IWL2100_SHMEM3, IWL2100_SHMEM3_SIZE },
1335 { IWL2100_SHMEM_INTR, IWL2100_SHMEM_INTR_SIZE },
1336 { 0, 0 }
1338 const struct iwl2100_firmware *fw = NULL;
1339 int i, error;
1342 * Pick up the firmware image corresponding to
1343 * the current operation mode
1345 switch (opmode) {
1346 case IEEE80211_M_STA:
1347 fw = &sc->sc_fw_sta;
1348 break;
1349 case IEEE80211_M_IBSS:
1350 fw = &sc->sc_fw_ibss;
1351 break;
1352 case IEEE80211_M_MONITOR:
1353 fw = &sc->sc_fw_monitor;
1354 break;
1355 default:
1356 panic("unsupported opmode %d\n", opmode);
1357 break;
1359 KASSERT(fw->fw_image != NULL,
1360 ("opmode %d firmware image is not allocated yet\n", opmode));
1362 /* Load ucode */
1363 error = iwl2100_load_fw_ucode(sc, fw);
1364 if (error)
1365 return error;
1367 /* SW reset */
1368 error = iwl2100_reset(sc);
1369 if (error)
1370 return error;
1372 /* Load data */
1373 error = iwl2100_load_fw_data(sc, fw);
1374 if (error)
1375 return error;
1377 /* Clear shared memory */
1378 for (i = 0; share_mem[i].size != 0; ++i) {
1379 uint32_t addr = share_mem[i].addr;
1380 int j;
1382 for (j = 0; j < share_mem[i].size; j += 4)
1383 IND_WRITE_4(sc, addr + j, 0);
1386 return 0;
1389 #define IND_WRITE_FLUSH_2(sc, reg, val) \
1390 do { \
1391 IND_WRITE_2((sc), (reg), (val)); \
1392 CSR_READ_4((sc), 0); \
1393 } while (0)
1395 #define IND_WRITE_FLUSH_1(sc, reg, val) \
1396 do { \
1397 IND_WRITE_1((sc), (reg), (val)); \
1398 CSR_READ_4((sc), 0); \
1399 } while (0)
1401 /* XXX need more comment */
1402 static int
1403 iwl2100_load_fw_ucode(struct iwl2100_softc *sc,
1404 const struct iwl2100_firmware *fw)
1406 struct iwl2100_ucode_resp resp;
1407 const uint8_t *p;
1408 int i;
1410 /* Hold ARC */
1411 IND_WRITE_4(sc, IWL2100_IND_HALT, IWL2100_IND_HALT_HOLD);
1413 /* Allow ARC to run */
1414 CSR_WRITE_4(sc, IWL2100_RESET, 0);
1416 IND_WRITE_FLUSH_2(sc, IWL2100_IND_CTRL, 0x703);
1417 IND_WRITE_FLUSH_2(sc, IWL2100_IND_CTRL, 0x707);
1419 IND_WRITE_FLUSH_1(sc, 0x210014, 0x72);
1420 IND_WRITE_FLUSH_1(sc, 0x210014, 0x72);
1422 IND_WRITE_FLUSH_1(sc, 0x210000, 0x40);
1423 IND_WRITE_FLUSH_1(sc, 0x210000, 0);
1424 IND_WRITE_FLUSH_1(sc, 0x210000, 0x40);
1426 p = fw->fw_ucode;
1427 for (i = 0; i < fw->fw_ucode_size; ++i, ++p)
1428 IND_WRITE_1(sc, 0x210010, *p);
1430 IND_WRITE_FLUSH_1(sc, 0x210000, 0);
1431 IND_WRITE_FLUSH_1(sc, 0x210000, 0);
1432 IND_WRITE_FLUSH_1(sc, 0x210000, 0x80);
1435 IND_WRITE_FLUSH_2(sc, IWL2100_IND_CTRL, 0x703);
1436 IND_WRITE_FLUSH_2(sc, IWL2100_IND_CTRL, 0x707);
1438 IND_WRITE_FLUSH_1(sc, 0x210014, 0x72);
1439 IND_WRITE_FLUSH_1(sc, 0x210014, 0x72);
1441 IND_WRITE_FLUSH_1(sc, 0x210000, 0);
1442 IND_WRITE_1(sc, 0x210000, 0x80);
1444 #define WAIT_MAX 10
1445 for (i = 0; i < WAIT_MAX; ++i) {
1446 DELAY(10);
1448 if (IND_READ_1(sc, 0x210000) & 0x1)
1449 break;
1451 if (i == WAIT_MAX) {
1452 if_printf(&sc->sc_ic.ic_if,
1453 "wait ucode symbol init timed out\n");
1454 return ETIMEDOUT;
1456 #undef WAIT_MAX
1458 #define WAIT_MAX 30
1459 for (i = 0; i < WAIT_MAX; ++i) {
1460 uint16_t *r = (uint16_t *)&resp;
1461 int j;
1463 for (j = 0; j < sizeof(resp) / 2; ++j, ++r)
1464 *r = IND_READ_2(sc, 0x210004);
1466 if (resp.cmd_id == 1 && resp.ucode_valid == 1)
1467 break;
1468 DELAY(10);
1470 if (i == WAIT_MAX) {
1471 if_printf(&sc->sc_ic.ic_if,
1472 "wait ucode response timed out\n");
1473 return ETIMEDOUT;
1475 #undef WAIT_MAX
1477 /* Release ARC */
1478 IND_WRITE_4(sc, IWL2100_IND_HALT, 0);
1480 if (bootverbose) {
1481 if_printf(&sc->sc_ic.ic_if, "ucode rev.%d date %d.%d.20%02d "
1482 "time %02d:%02d\n", resp.ucode_rev,
1483 resp.date_time[0], resp.date_time[1],
1484 resp.date_time[2], resp.date_time[3],
1485 resp.date_time[4]);
1488 return 0;
1491 #undef IND_WRITE_FLUSH_1
1492 #undef IND_WRITE_FLUSH_2
1494 static int
1495 iwl2100_load_fw_data(struct iwl2100_softc *sc,
1496 const struct iwl2100_firmware *fw)
1498 const uint8_t *p = fw->fw_data;
1499 int w = 0;
1501 while (w < fw->fw_data_size) {
1502 const struct iwl2100_fwdata_hdr *h;
1503 int hlen, i;
1505 h = (const struct iwl2100_fwdata_hdr *)p;
1506 if (h->len > 32 || h->len == 0) {
1507 if_printf(&sc->sc_ic.ic_if,
1508 "firmware image data corrupted\n");
1509 return EINVAL;
1511 if ((h->addr & 0x3) || (h->len & 0x3)) {
1512 if_printf(&sc->sc_ic.ic_if,
1513 "firmware image data with unaligned "
1514 "address %#x or length %#x\n",
1515 h->addr, h->len);
1516 return EOPNOTSUPP;
1519 hlen = sizeof(*h) + h->len - 1;
1520 if (w + hlen > fw->fw_data_size) {
1521 if_printf(&sc->sc_ic.ic_if,
1522 "firmware image data size mismatch\n");
1523 return EINVAL;
1526 CSR_WRITE_4(sc, IWL2100_AUTOINC_ADDR, h->addr);
1527 for (i = 0; i < h->len; i += 4) {
1528 CSR_WRITE_4(sc, IWL2100_AUTOINC_DATA,
1529 *(const uint32_t *)&h->data[i]);
1532 p += hlen;
1533 w += hlen;
1535 KKASSERT(w == fw->fw_data_size);
1537 return 0;
1540 static void
1541 iwl2100_free_tx_ring(struct iwl2100_softc *sc)
1543 struct iwl2100_tx_ring *tr = &sc->sc_txring;
1544 int i;
1546 for (i = 0; i < IWL2100_TX_NDESC; ++i) {
1547 struct iwl2100_txbuf *tb = &tr->tr_buf[i];
1549 if (tb->tb_mbuf != NULL) {
1550 bus_dmamap_unload(sc->sc_mbuf_dtag, tb->tb_dmap);
1551 if (tb->tb_flags & IWL2100_TBF_CMDBUF) {
1552 KKASSERT(tb->tb_mbuf == sc->sc_cmd);
1553 tb->tb_flags &= ~IWL2100_TBF_CMDBUF;
1554 } else {
1555 m_freem(tb->tb_mbuf);
1557 tb->tb_mbuf = NULL;
1561 bzero(tr->tr_desc, IWL2100_TXRING_SIZE);
1562 bus_dmamap_sync(tr->tr_dtag, tr->tr_dmap, BUS_DMASYNC_PREWRITE);
1564 tr->tr_used = 0;
1565 tr->tr_index = 0;
1566 tr->tr_coll = 0;
1569 static void
1570 iwl2100_free_rx_ring(struct iwl2100_softc *sc)
1572 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
1573 int i;
1575 for (i = 0; i < IWL2100_RX_NDESC; ++i) {
1576 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
1578 if (rb->rb_mbuf != NULL) {
1579 bus_dmamap_unload(sc->sc_mbuf_dtag, rb->rb_dmap);
1580 m_freem(rb->rb_mbuf);
1581 rb->rb_mbuf = NULL;
1585 bzero(rr->rr_desc, IWL2100_RXRING_SIZE);
1586 bus_dmamap_sync(rr->rr_dtag, rr->rr_dmap, BUS_DMASYNC_PREWRITE);
1588 bzero(rr->rr_status, IWL2100_RXSTATUS_SIZE);
1589 bus_dmamap_sync(rr->rr_st_dtag, rr->rr_st_dmap, BUS_DMASYNC_PREWRITE);
1591 rr->rr_index = 0;
1594 static void
1595 iwl2100_free_cmd(struct iwl2100_softc *sc)
1597 if (sc->sc_cmd != NULL) {
1598 m_freem(sc->sc_cmd);
1599 sc->sc_cmd = NULL;
1603 static int
1604 iwl2100_init_tx_ring(struct iwl2100_softc *sc)
1606 struct iwl2100_tx_ring *tr = &sc->sc_txring;
1608 tr->tr_used = 0;
1609 tr->tr_index = 0;
1610 tr->tr_coll = 0;
1612 bzero(tr->tr_desc, IWL2100_TXRING_SIZE);
1613 bus_dmamap_sync(tr->tr_dtag, tr->tr_dmap, BUS_DMASYNC_PREWRITE);
1615 CSR_WRITE_4(sc, IWL2100_TXQ_ADDR, tr->tr_paddr);
1616 CSR_WRITE_4(sc, IWL2100_TXQ_SIZE, IWL2100_TX_NDESC);
1617 CSR_WRITE_4(sc, IWL2100_TXQ_READ_IDX, 0);
1618 CSR_WRITE_4(sc, IWL2100_TXQ_WRITE_IDX, tr->tr_index);
1620 return 0;
1623 static int
1624 iwl2100_init_rx_ring(struct iwl2100_softc *sc)
1626 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
1627 int i, error;
1629 for (i = 0; i < IWL2100_RX_NDESC; ++i) {
1630 error = iwl2100_newbuf(sc, i, 1);
1631 if (error)
1632 return error;
1634 bus_dmamap_sync(rr->rr_st_dtag, rr->rr_st_dmap, BUS_DMASYNC_PREWRITE);
1635 bus_dmamap_sync(rr->rr_dtag, rr->rr_dmap, BUS_DMASYNC_PREWRITE);
1637 rr->rr_index = IWL2100_RX_NDESC - 1;
1639 CSR_WRITE_4(sc, IWL2100_RXQ_ADDR, rr->rr_paddr);
1640 CSR_WRITE_4(sc, IWL2100_RXQ_SIZE, IWL2100_RX_NDESC);
1641 CSR_WRITE_4(sc, IWL2100_RXQ_READ_IDX, 0);
1642 CSR_WRITE_4(sc, IWL2100_RXQ_WRITE_IDX, rr->rr_index);
1644 CSR_WRITE_4(sc, IWL2100_RX_STATUS_ADDR, rr->rr_st_paddr);
1646 return 0;
1649 static int
1650 iwl2100_alloc_cmd(struct iwl2100_softc *sc)
1652 KKASSERT(sc->sc_cmd == NULL);
1654 sc->sc_cmd = m_getcl(MB_WAIT, MT_DATA, M_PKTHDR);
1655 if (sc->sc_cmd == NULL)
1656 return ENOBUFS;
1657 return 0;
1660 static int
1661 iwl2100_newbuf(struct iwl2100_softc *sc, int buf_idx, int init)
1663 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
1664 struct iwl2100_rxbuf *rb;
1665 struct iwl_dmamap_ctx ctx;
1666 bus_dma_segment_t seg;
1667 bus_dmamap_t dmap;
1668 struct mbuf *m;
1669 int error;
1671 KKASSERT(buf_idx < IWL2100_RX_NDESC);
1672 rb = &rr->rr_buf[buf_idx];
1674 m = m_getcl(init ? MB_WAIT : MB_DONTWAIT, MT_DATA, M_PKTHDR);
1675 if (m == NULL) {
1676 error = ENOBUFS;
1678 if (init) {
1679 if_printf(&sc->sc_ic.ic_if, "m_getcl failed\n");
1680 return error;
1681 } else {
1682 goto back;
1685 m->m_len = m->m_pkthdr.len = MCLBYTES;
1688 * Try load RX mbuf into temporary DMA map
1690 ctx.nsegs = 1;
1691 ctx.segs = &seg;
1692 error = bus_dmamap_load_mbuf(sc->sc_mbuf_dtag, rr->rr_tmp_dmap, m,
1693 iwl_dma_buf_addr, &ctx,
1694 init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT);
1695 if (error || ctx.nsegs == 0) {
1696 if (!error) {
1697 bus_dmamap_unload(sc->sc_mbuf_dtag, rr->rr_tmp_dmap);
1698 error = EFBIG;
1699 if_printf(&sc->sc_ic.ic_if, "too many segments?!\n");
1701 m_freem(m);
1703 if (init) {
1704 if_printf(&sc->sc_ic.ic_if, "can't load RX mbuf\n");
1705 return error;
1706 } else {
1707 goto back;
1711 if (!init)
1712 bus_dmamap_unload(sc->sc_mbuf_dtag, rb->rb_dmap);
1713 rb->rb_mbuf = m;
1714 rb->rb_paddr = seg.ds_addr;
1717 * Swap RX buf's DMA map with the loaded temporary one
1719 dmap = rb->rb_dmap;
1720 rb->rb_dmap = rr->rr_tmp_dmap;
1721 rr->rr_tmp_dmap = dmap;
1723 error = 0;
1724 back:
1725 iwl2100_rxdesc_setup(sc, buf_idx);
1726 return error;
1729 static void
1730 iwl2100_rxdesc_setup(struct iwl2100_softc *sc, int buf_idx)
1732 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
1733 struct iwl2100_rxbuf *rb;
1734 struct iwl2100_desc *d;
1735 struct iwl2100_rx_status *st;
1737 KKASSERT(buf_idx < IWL2100_RX_NDESC);
1738 rb = &rr->rr_buf[buf_idx];
1740 st = &rr->rr_status[buf_idx];
1741 bzero(st, sizeof(*st));
1743 d = &rr->rr_desc[buf_idx];
1744 bzero(d, sizeof(*d));
1745 d->d_paddr = rb->rb_paddr;
1746 d->d_len = MCLBYTES;
1749 static int
1750 iwl2100_init_firmware(struct iwl2100_softc *sc)
1752 #ifdef INVARIANTS
1753 struct ifnet *ifp = &sc->sc_ic.ic_if;
1754 #endif
1755 uint32_t intr;
1756 int i;
1758 ASSERT_SERIALIZED(ifp->if_serializer);
1760 CSR_WRITE_4(sc, IWL2100_GPIO,
1761 IWL2100_GPIO_3_EN | IWL2100_GPIO_3_FWWR |
1762 IWL2100_GPIO_1_EN | IWL2100_GPIO_LEDOFF);
1763 CSR_WRITE_4(sc, IWL2100_RESET, 0);
1766 * Wait for firmware to be initialized
1768 #define WAIT_MAX 5000
1770 for (i = 0; i < WAIT_MAX; ++i) {
1771 DELAY(8000);
1773 intr = CSR_READ_4(sc, IWL2100_INTR_STATUS);
1774 if (intr & IWL2100_INTR_FW_INITED) {
1775 CSR_WRITE_4(sc, IWL2100_INTR_STATUS,
1776 IWL2100_INTR_FW_INITED);
1777 break;
1779 if (intr & (IWL2100_INTR_EFATAL | IWL2100_INTR_EPARITY)) {
1780 CSR_WRITE_4(sc, IWL2100_INTR_STATUS,
1781 IWL2100_INTR_EFATAL | IWL2100_INTR_EPARITY);
1785 intr = CSR_READ_4(sc, IWL2100_INTR_STATUS) & IWL2100_INTRS;
1786 if (intr & CSR_READ_4(sc, IWL2100_INTR_MASK))
1787 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, intr);
1789 if (i == WAIT_MAX) {
1790 if_printf(&sc->sc_ic.ic_if,
1791 "firmware initialization timed out\n");
1792 return ETIMEDOUT;
1795 #undef WAIT_MAX
1797 /* Enable GPIO1/3 and allow firmware to write to them */
1798 CSR_SETBITS_4(sc, IWL2100_GPIO,
1799 IWL2100_GPIO_1_EN | IWL2100_GPIO_1_FWWR |
1800 IWL2100_GPIO_3_EN | IWL2100_GPIO_3_FWWR);
1801 return 0;
1804 static int
1805 iwl2100_read_ord2(struct iwl2100_softc *sc, uint32_t ofs, void *buf0, int buflen)
1807 uint8_t *buf = buf0;
1808 uint32_t addr, info;
1809 int i, len, ret;
1811 #define IND_ALIGN 4
1812 #define IND_ALIGN_MASK 0x3
1814 addr = IND_READ_4(sc, sc->sc_ord2 + (ofs << 3));
1815 info = IND_READ_4(sc, sc->sc_ord2 + (ofs << 3) + sizeof(addr));
1817 len = info & 0xffff;
1818 i = info >> 16;
1820 if ((len * i) < buflen)
1821 buflen = len * i;
1822 ret = buflen;
1824 i = addr & IND_ALIGN_MASK;
1825 addr &= ~IND_ALIGN_MASK;
1826 if (i) {
1827 int lim, r;
1829 KKASSERT(i < IND_ALIGN);
1830 if (buflen + i < IND_ALIGN)
1831 lim = buflen + i;
1832 else
1833 lim = IND_ALIGN;
1834 r = lim - i;
1836 CSR_WRITE_4(sc, IWL2100_IND_ADDR, addr);
1837 for (; i < lim; ++i, ++buf)
1838 *buf = CSR_READ_1(sc, IWL2100_IND_DATA + i);
1840 KKASSERT(buflen >= r);
1841 buflen -= r;
1842 if (buflen == 0)
1843 goto back;
1845 addr += IND_ALIGN;
1848 len = buflen & ~IND_ALIGN_MASK;
1849 buflen &= IND_ALIGN_MASK;
1851 if (len) {
1852 CSR_WRITE_4(sc, IWL2100_AUTOINC_ADDR, addr);
1853 for (i = 0; i < len; i += 4, addr += 4, buf += 4) {
1854 *((uint32_t *)buf) =
1855 CSR_READ_4(sc, IWL2100_AUTOINC_DATA);
1858 if (buflen) {
1859 CSR_WRITE_4(sc, IWL2100_IND_ADDR, addr);
1860 for (i = 0; i < buflen; ++i, ++buf)
1861 *buf = CSR_READ_1(sc, IWL2100_IND_DATA + i);
1863 back:
1864 return ret;
1866 #undef IND_ALIGN
1867 #undef IND_ALIGN_MASK
1870 static uint32_t
1871 iwl2100_read_ord1(struct iwl2100_softc *sc, uint32_t ofs)
1873 uint32_t addr;
1875 addr = IND_READ_4(sc, sc->sc_ord1 + (ofs << 2));
1876 return IND_READ_4(sc, addr);
1879 static void
1880 iwl2100_write_ord1(struct iwl2100_softc *sc, uint32_t ofs, uint32_t val)
1882 uint32_t addr;
1884 addr = IND_READ_4(sc, sc->sc_ord1 + (ofs << 2));
1885 IND_WRITE_4(sc, addr, val);
1888 static int
1889 iwl2100_rfkilled(struct iwl2100_softc *sc)
1891 int i;
1893 if ((sc->sc_caps & IWL2100_C_RFKILL) == 0)
1894 return 0;
1896 #define TEST_MAX 5
1898 for (i = 0; i < TEST_MAX; ++i) {
1899 DELAY(40);
1901 if (CSR_READ_4(sc, IWL2100_GPIO) & IWL2100_GPIO_RFKILLED)
1902 break;
1904 if (i != TEST_MAX) {
1905 if_printf(&sc->sc_ic.ic_if, "RF killed\n");
1906 return 1;
1909 #undef TEST_MAX
1911 return 0;
1914 static int
1915 iwl2100_set_addr(struct iwl2100_softc *sc, const uint8_t *eaddr)
1917 struct iwl2100_cmd *cmd;
1918 int error;
1920 if (sc->sc_flags & IWL2100_F_WAITCMD) {
1921 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
1922 return EEXIST;
1925 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
1926 bzero(cmd, sizeof(*cmd));
1928 cmd->c_cmd = IWL2100_CMD_SET_ADDR;
1929 cmd->c_param_len = IEEE80211_ADDR_LEN;
1930 IEEE80211_ADDR_COPY(cmd->c_param, eaddr);
1932 error = iwl2100_wait_cmd(sc);
1933 if (error) {
1934 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
1935 return error;
1937 return 0;
1940 static int
1941 iwl2100_set_opmode(struct iwl2100_softc *sc, enum ieee80211_opmode opmode)
1943 struct iwl2100_cmd *cmd;
1944 int error;
1946 if (sc->sc_flags & IWL2100_F_WAITCMD) {
1947 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
1948 return EEXIST;
1951 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
1952 bzero(cmd, sizeof(cmd));
1954 cmd->c_cmd = IWL2100_CMD_SET_OPMODE;
1955 cmd->c_param_len = sizeof(cmd->c_param[0]);
1956 switch (opmode) {
1957 case IEEE80211_M_STA:
1958 cmd->c_param[0] = IWL2100_OPMODE_STA;
1959 break;
1960 case IEEE80211_M_IBSS:
1961 cmd->c_param[0] = IWL2100_OPMODE_IBSS;
1962 break;
1963 case IEEE80211_M_MONITOR:
1964 /* YYY ipw2100 leave this unset */
1965 cmd->c_param[0] = IWL2100_OPMODE_MONITOR;
1966 break;
1967 default:
1968 panic("unsupported opmode %d\n", opmode);
1969 break;
1972 error = iwl2100_wait_cmd(sc);
1973 if (error) {
1974 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
1975 return error;
1977 return 0;
1980 static int
1981 iwl2100_set_80211(struct iwl2100_softc *sc)
1983 struct ieee80211com *ic = &sc->sc_ic;
1984 struct iwl2100_cmd *cmd;
1985 int error;
1987 if (sc->sc_flags & IWL2100_F_WAITCMD) {
1988 if_printf(&ic->ic_if, "there is command pending\n");
1989 return EEXIST;
1992 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
1993 bzero(cmd, sizeof(cmd));
1995 cmd->c_cmd = IWL2100_CMD_SET_80211;
1996 cmd->c_param_len = sizeof(cmd->c_param[0]) * 3;
1997 cmd->c_param[0] = IWL2100_CFG_IBSS | IWL2100_CFG_STA |
1998 IWL2100_CFG_8021X | IWL2100_CFG_AUTO_PREAMBLE;
1999 if (ic->ic_opmode == IEEE80211_M_IBSS)
2000 cmd->c_param[0] |= IWL2100_CFG_IBSS_AUTO_START;
2001 else if (ic->ic_opmode == IEEE80211_M_MONITOR) /* YYY not ipw2100 */
2002 cmd->c_param[0] |= IWL2100_CFG_MONITOR;
2003 cmd->c_param[1] = IWL2100_CFG_CHANMASK; /* XXX sc->sc_bss_chans */
2004 cmd->c_param[2] = IWL2100_CFG_CHANMASK; /* YYY sc->sc_ibss_chans */
2006 error = iwl2100_wait_cmd(sc);
2007 if (error) {
2008 if_printf(&ic->ic_if, "%s failed\n", __func__);
2009 return error;
2011 return 0;
2014 static int
2015 iwl2100_set_basicrates(struct iwl2100_softc *sc)
2017 struct iwl2100_cmd *cmd;
2018 int error;
2020 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2021 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2022 return EEXIST;
2025 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2026 bzero(cmd, sizeof(cmd));
2029 * This configuration does not seem to have any effects
2030 * on probe-req and assoc-req frames.
2032 cmd->c_cmd = IWL2100_CMD_SET_BASICRATES;
2033 cmd->c_param_len = sizeof(cmd->c_param[0]);
2034 cmd->c_param[0] = 0x3; /* 1Mbps and 2Mbps. XXX from caller */
2036 error = iwl2100_wait_cmd(sc);
2037 if (error) {
2038 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2039 return error;
2041 return 0;
2044 static int
2045 iwl2100_set_txrates(struct iwl2100_softc *sc)
2047 struct ieee80211com *ic = &sc->sc_ic;
2048 struct iwl2100_cmd *cmd;
2049 uint32_t rate_mask;
2050 int error;
2052 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2053 if_printf(&ic->ic_if, "there is command pending\n");
2054 return EEXIST;
2057 /* Calculate TX rate mask. XXX let caller do this */
2058 if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
2059 rate_mask = 1 << ic->ic_fixed_rate;
2060 else
2061 rate_mask = 0xf; /* all 11b rates */
2062 KKASSERT((rate_mask & ~0xf) == 0);
2065 * Set TX rates
2067 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2068 bzero(cmd, sizeof(cmd));
2070 cmd->c_cmd = IWL2100_CMD_SET_TXRATES;
2071 cmd->c_param_len = sizeof(cmd->c_param[0]);
2072 cmd->c_param[0] = rate_mask;
2074 error = iwl2100_wait_cmd(sc);
2075 if (error) {
2076 if_printf(&ic->ic_if, "%s failed\n", __func__);
2077 return error;
2081 * Set MSDU TX rates
2083 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2084 bzero(cmd, sizeof(cmd));
2086 cmd->c_cmd = IWL2100_CMD_SET_MSDU_TXRATES;
2087 cmd->c_param_len = sizeof(cmd->c_param[0]);
2088 cmd->c_param[0] = rate_mask;
2090 error = iwl2100_wait_cmd(sc);
2091 if (error) {
2092 if_printf(&ic->ic_if, "%s failed\n", __func__);
2093 return error;
2095 return 0;
2098 static int
2099 iwl2100_set_powersave(struct iwl2100_softc *sc, int on)
2101 struct iwl2100_cmd *cmd;
2102 int error;
2104 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2105 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2106 return EEXIST;
2109 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2110 bzero(cmd, sizeof(cmd));
2112 cmd->c_cmd = IWL2100_CMD_SET_POWERSAVE;
2113 cmd->c_param_len = sizeof(cmd->c_param[0]);
2114 cmd->c_param[0] = on; /* XXX power level? */
2116 error = iwl2100_wait_cmd(sc);
2117 if (error) {
2118 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2119 return error;
2121 return 0;
2124 static int
2125 iwl2100_set_rtsthreshold(struct iwl2100_softc *sc, uint16_t rtsthreshold)
2127 struct iwl2100_cmd *cmd;
2128 int error;
2130 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2131 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2132 return EEXIST;
2135 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2136 bzero(cmd, sizeof(cmd));
2138 cmd->c_cmd = IWL2100_CMD_SET_RTSTHRESHOLD;
2139 cmd->c_param_len = sizeof(cmd->c_param[0]);
2140 if (rtsthreshold == IEEE80211_RTS_MAX) {
2141 /* Disable RTS threshold */
2142 cmd->c_param[0] = IWL2100_RTS_MAX;
2143 } else {
2144 if (rtsthreshold >= IWL2100_RTS_MAX)
2145 rtsthreshold = IWL2100_RTS_MAX - 1;
2146 cmd->c_param[0] = rtsthreshold;
2149 error = iwl2100_wait_cmd(sc);
2150 if (error) {
2151 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2152 return error;
2154 return 0;
2157 static int
2158 iwl2100_set_bssid(struct iwl2100_softc *sc, const uint8_t *bssid)
2160 struct iwl2100_cmd *cmd;
2161 int error;
2163 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2164 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2165 return EEXIST;
2168 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2169 bzero(cmd, sizeof(cmd));
2171 cmd->c_cmd = IWL2100_CMD_SET_BSSID;
2172 if (bssid != NULL) {
2173 cmd->c_param_len = IEEE80211_ADDR_LEN;
2174 IEEE80211_ADDR_COPY(cmd->c_param, bssid);
2177 error = iwl2100_wait_cmd(sc);
2178 if (error) {
2179 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2180 return error;
2182 return 0;
2185 static int
2186 iwl2100_set_essid(struct iwl2100_softc *sc, const uint8_t *essid, int essid_len)
2188 struct iwl2100_cmd *cmd;
2189 int error;
2191 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2192 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2193 return EEXIST;
2196 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2197 bzero(cmd, sizeof(cmd));
2199 cmd->c_cmd = IWL2100_CMD_SET_ESSID;
2200 if (essid != NULL) {
2201 KKASSERT(essid_len <= sizeof(cmd->c_param));
2202 cmd->c_param_len = essid_len;
2203 if (essid_len != 0)
2204 bcopy(essid, cmd->c_param, essid_len);
2207 error = iwl2100_wait_cmd(sc);
2208 if (error) {
2209 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2210 return error;
2212 return 0;
2215 static int
2216 iwl2100_set_auth_ciphers(struct iwl2100_softc *sc,
2217 enum ieee80211_authmode authmode)
2219 struct iwl2100_cmdparam_sec *sec;
2220 struct iwl2100_cmd *cmd;
2221 int error;
2223 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2224 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2225 return EEXIST;
2228 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2229 bzero(cmd, sizeof(cmd));
2231 cmd->c_cmd = IWL2100_CMD_SET_SECURITY;
2232 cmd->c_param_len = sizeof(*sec);
2233 sec = (struct iwl2100_cmdparam_sec *)cmd->c_param;
2235 sec->sec_cipher_mask = IWL2100_CIPHER_NONE |
2236 IWL2100_CIPHER_WEP40 |
2237 IWL2100_CIPHER_TKIP |
2238 IWL2100_CIPHER_CCMP |
2239 IWL2100_CIPHER_WEP104;
2240 if (authmode == IEEE80211_AUTH_SHARED)
2241 sec->sec_authmode = IWL2100_AUTH_SHARED;
2242 else
2243 sec->sec_authmode = IWL2100_AUTH_OPEN;
2245 error = iwl2100_wait_cmd(sc);
2246 if (error) {
2247 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2248 return error;
2250 return 0;
2253 static int
2254 iwl2100_set_wepkey(struct iwl2100_softc *sc, const struct ieee80211_key *k)
2256 struct iwl2100_cmdparam_wepkey *key;
2257 struct iwl2100_cmd *cmd;
2258 int error;
2260 if (k->wk_keylen > IWL2100_KEYDATA_SIZE)
2261 return E2BIG;
2263 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2264 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2265 return EEXIST;
2268 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2269 bzero(cmd, sizeof(cmd));
2271 cmd->c_cmd = IWL2100_CMD_SET_WEPKEY;
2272 cmd->c_param_len = sizeof(*key);
2273 key = (struct iwl2100_cmdparam_wepkey *)cmd->c_param;
2274 key->key_index = k->wk_keyix;
2275 key->key_len = k->wk_keylen;
2276 bcopy(k->wk_key, key->key_data, key->key_len);
2278 error = iwl2100_wait_cmd(sc);
2279 if (error) {
2280 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2281 return error;
2283 return 0;
2286 static int
2287 iwl2100_set_weptxkey(struct iwl2100_softc *sc, ieee80211_keyix txkey)
2289 struct iwl2100_cmd *cmd;
2290 int error;
2292 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2293 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2294 return EEXIST;
2297 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2298 bzero(cmd, sizeof(cmd));
2300 cmd->c_cmd = IWL2100_CMD_SET_WEPTXKEY;
2301 cmd->c_param_len = sizeof(cmd->c_param[0]);
2302 cmd->c_param[0] = txkey;
2304 error = iwl2100_wait_cmd(sc);
2305 if (error) {
2306 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2307 return error;
2309 return 0;
2312 static int
2313 iwl2100_set_privacy(struct iwl2100_softc *sc, int on)
2315 struct iwl2100_cmd *cmd;
2316 int error;
2318 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2319 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2320 return EEXIST;
2323 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2324 bzero(cmd, sizeof(cmd));
2326 cmd->c_cmd = IWL2100_CMD_SET_PRIVACY;
2327 cmd->c_param_len = sizeof(cmd->c_param[0]);
2328 cmd->c_param[0] = on ? IWL2100_PRIVACY_ENABLE : 0;
2330 error = iwl2100_wait_cmd(sc);
2331 if (error) {
2332 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2333 return error;
2335 return 0;
2338 static int
2339 iwl2100_wait_cmd(struct iwl2100_softc *sc)
2341 struct ifnet *ifp = &sc->sc_ic.ic_if;
2342 struct iwl2100_tx_ring *tr = &sc->sc_txring;
2343 struct mbuf *m = sc->sc_cmd;
2344 struct iwl_dmamap_ctx ctx;
2345 bus_dma_segment_t seg;
2346 struct iwl2100_desc *d;
2347 struct iwl2100_txbuf *tb;
2348 int error;
2350 ASSERT_SERIALIZED(ifp->if_serializer);
2352 KKASSERT(tr->tr_index < IWL2100_TX_NDESC);
2353 tb = &tr->tr_buf[tr->tr_index];
2355 ctx.nsegs = 1;
2356 ctx.segs = &seg;
2357 error = bus_dmamap_load_mbuf(sc->sc_mbuf_dtag, tb->tb_dmap, m,
2358 iwl_dma_buf_addr, &ctx, BUS_DMA_WAITOK);
2359 if (error || ctx.nsegs == 0) {
2360 if (!error) {
2361 bus_dmamap_unload(sc->sc_mbuf_dtag, tb->tb_dmap);
2362 error = EFBIG;
2363 if_printf(ifp, "too many segments?!\n");
2366 if_printf(ifp, "can't load RX mbuf\n");
2367 return error;
2369 tb->tb_mbuf = sc->sc_cmd;
2370 tb->tb_flags |= IWL2100_TBF_CMDBUF;
2372 d = &tr->tr_desc[tr->tr_index];
2373 d->d_paddr = seg.ds_addr;
2374 d->d_len = sizeof(struct iwl2100_cmd);
2375 d->d_nfrag = 1;
2376 d->d_flags = IWL2100_TXD_F_INTR | IWL2100_TXD_F_CMD;
2378 KKASSERT(tr->tr_used < IWL2100_TX_NDESC);
2379 ++tr->tr_used;
2380 tr->tr_index = (tr->tr_index + 1) % IWL2100_TX_NDESC;
2382 bus_dmamap_sync(tr->tr_dtag, tr->tr_dmap, BUS_DMASYNC_PREWRITE);
2384 CSR_WRITE_4(sc, IWL2100_TXQ_WRITE_IDX, tr->tr_index);
2386 if (sc->sc_flags & IWL2100_F_IN_INTR)
2387 panic("sleep in interrupt thread\n");
2389 sc->sc_flags |= IWL2100_F_WAITCMD;
2390 error = serialize_sleep(sc, ifp->if_serializer, 0, "iwlcmd", 2 * hz);
2391 if (!error) {
2392 sc->sc_flags &= ~IWL2100_F_WAITCMD;
2393 if (sc->sc_flags & IWL2100_F_ERROR) {
2394 if_printf(ifp, "error happened when waiting "
2395 "command to be done\n");
2396 error = EIO;
2399 return error;
2402 static void
2403 iwl2100_rxeof(struct iwl2100_softc *sc)
2405 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
2406 struct ifnet *ifp = &sc->sc_ic.ic_if;
2407 int hwidx, i;
2409 hwidx = CSR_READ_4(sc, IWL2100_RXQ_READ_IDX);
2410 CSR_READ_4(sc, IWL2100_RXQ_WRITE_IDX);
2412 if (hwidx >= IWL2100_RX_NDESC) {
2413 if_printf(ifp, "invalid hardware RX index %d\n", hwidx);
2414 return;
2417 KKASSERT(rr->rr_index < IWL2100_RX_NDESC);
2418 i = (rr->rr_index + 1) % IWL2100_RX_NDESC;
2419 while (hwidx != i) {
2420 struct iwl2100_rx_status *st = &rr->rr_status[i];
2421 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
2422 int frame_type;
2424 bus_dmamap_sync(rr->rr_st_dtag, rr->rr_st_dmap,
2425 BUS_DMASYNC_POSTREAD);
2426 frame_type = st->r_status & IWL2100_RXS_TYPE_MASK;
2428 bus_dmamap_sync(sc->sc_mbuf_dtag, rb->rb_dmap,
2429 BUS_DMASYNC_POSTREAD);
2430 switch (frame_type) {
2431 case IWL2100_RXS_TYPE_CMD:
2432 iwl2100_rxeof_cmd(sc, i);
2433 break;
2435 case IWL2100_RXS_TYPE_STATUS:
2436 iwl2100_rxeof_status(sc, i);
2437 break;
2439 case IWL2100_RXS_TYPE_NOTE:
2440 iwl2100_rxeof_note(sc, i);
2441 break;
2443 case IWL2100_RXS_TYPE_DATA:
2444 case IWL2100_RXS_TYPE_DATA1:
2445 iwl2100_rxeof_data(sc, i);
2446 break;
2448 default:
2449 if_printf(ifp, "unknown frame type: %d\n", frame_type);
2450 iwl2100_rxdesc_setup(sc, i);
2451 break;
2453 i = (i + 1) % IWL2100_RX_NDESC;
2455 bus_dmamap_sync(rr->rr_st_dtag, rr->rr_st_dmap, BUS_DMASYNC_POSTREAD);
2456 bus_dmamap_sync(rr->rr_dtag, rr->rr_dmap, BUS_DMASYNC_POSTREAD);
2458 if (i == 0)
2459 rr->rr_index = IWL2100_RX_NDESC - 1;
2460 else
2461 rr->rr_index = i - 1;
2462 CSR_WRITE_4(sc, IWL2100_RXQ_WRITE_IDX, rr->rr_index);
2465 static void
2466 iwl2100_txeof(struct iwl2100_softc *sc)
2468 struct iwl2100_tx_ring *tr = &sc->sc_txring;
2469 struct ifnet *ifp = &sc->sc_ic.ic_if;
2470 int hwidx;
2472 hwidx = CSR_READ_4(sc, IWL2100_TXQ_READ_IDX);
2473 CSR_READ_4(sc, IWL2100_TXQ_WRITE_IDX);
2474 if (hwidx >= IWL2100_TX_NDESC) {
2475 if_printf(ifp, "invalid hardware TX index %d\n", hwidx);
2476 return;
2479 KKASSERT(tr->tr_coll < IWL2100_TX_NDESC);
2480 while (tr->tr_used) {
2481 struct iwl2100_txbuf *tb;
2483 if (tr->tr_coll == hwidx)
2484 break;
2486 tb = &tr->tr_buf[tr->tr_coll];
2487 if (tb->tb_mbuf == NULL)
2488 goto next;
2490 bus_dmamap_unload(sc->sc_mbuf_dtag, tb->tb_dmap);
2491 if (tb->tb_flags & IWL2100_TBF_CMDBUF) {
2492 tb->tb_flags &= ~IWL2100_TBF_CMDBUF;
2493 KKASSERT(tb->tb_mbuf == sc->sc_cmd);
2494 } else {
2495 m_freem(tb->tb_mbuf);
2497 tb->tb_mbuf = NULL;
2498 next:
2499 tr->tr_coll = (tr->tr_coll + 1) % IWL2100_TX_NDESC;
2501 KKASSERT(tr->tr_used > 0);
2502 --tr->tr_used;
2505 if (tr->tr_used < IWL2100_TX_USED_MAX) {
2506 if (tr->tr_used == 0) {
2507 KKASSERT(tr->tr_coll == tr->tr_index);
2508 sc->sc_tx_timer = 0;
2511 ifp->if_flags &= ~IFF_OACTIVE;
2512 if_devstart(ifp);
2516 static int
2517 iwl2100_config(struct iwl2100_softc *sc, const uint8_t *bssid,
2518 const uint8_t *essid, uint8_t esslen, int ibss_chan)
2520 struct ieee80211com *ic = &sc->sc_ic;
2521 struct ifnet *ifp = &ic->ic_if;
2522 int error;
2524 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
2525 error = iwl2100_set_chan(sc, ic->ic_curchan);
2526 if (error) {
2527 if_printf(ifp, "can't set mon channel\n");
2528 return error;
2532 IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
2533 error = iwl2100_set_addr(sc, ic->ic_myaddr);
2534 if (error) {
2535 if_printf(ifp, "can't set MAC address\n");
2536 return error;
2539 error = iwl2100_set_opmode(sc, ic->ic_opmode);
2540 if (error) {
2541 if_printf(ifp, "can't set opmode\n");
2542 return error;
2545 if (ibss_chan) {
2546 KKASSERT(ic->ic_opmode == IEEE80211_M_IBSS);
2547 error = iwl2100_set_chan(sc, ic->ic_curchan);
2548 if (error) {
2549 if_printf(ifp, "can't set ibss channel\n");
2550 return error;
2554 error = iwl2100_set_80211(sc);
2555 if (error) {
2556 if_printf(ifp, "can't set 802.11 config\n");
2557 return error;
2560 error = iwl2100_set_basicrates(sc);
2561 if (error) {
2562 if_printf(ifp, "can't set basicrates\n");
2563 return error;
2566 error = iwl2100_set_txrates(sc);
2567 if (error) {
2568 if_printf(ifp, "can't set TX rates\n");
2569 return error;
2572 error = iwl2100_set_powersave(sc, ic->ic_flags & IEEE80211_F_PMGTON);
2573 if (error) {
2574 if_printf(ifp, "can't turn off powersave\n");
2575 return error;
2578 error = iwl2100_set_rtsthreshold(sc, ic->ic_rtsthreshold);
2579 if (error) {
2580 if_printf(ifp, "can't set RTS threshold\n");
2581 return error;
2584 error = iwl2100_set_bssid(sc, bssid);
2585 if (error) {
2586 if_printf(ifp, "can't set bssid\n");
2587 return error;
2590 error = iwl2100_set_essid(sc, essid, esslen);
2591 if (error) {
2592 if_printf(ifp, "can't set essid\n");
2593 return error;
2596 error = iwl2100_set_auth_ciphers(sc, ic->ic_bss->ni_authmode);
2597 if (error) {
2598 if_printf(ifp, "can't set authmode and ciphers\n");
2599 return error;
2602 if (ic->ic_flags & IEEE80211_F_PRIVACY) {
2603 ieee80211_keyix txkey = IEEE80211_KEYIX_NONE;
2604 int i;
2606 for (i = 0; i < IEEE80211_WEP_NKID; ++i) {
2607 const struct ieee80211_key *k = &ic->ic_nw_keys[i];
2609 if (k->wk_keyix == IEEE80211_KEYIX_NONE)
2610 continue;
2612 error = iwl2100_set_wepkey(sc, k);
2613 if (error == E2BIG) {
2614 continue;
2615 } else if (error) {
2616 if_printf(ifp, "can't set wepkey\n");
2617 return error;
2619 txkey = k->wk_keyix;
2622 if (txkey != IEEE80211_KEYIX_NONE) {
2624 * Found some valid WEP keys.
2626 * If WEP TX key index from 802.11 layer is not
2627 * set, then use the first valid WEP key as TX
2628 * key.
2630 if (ic->ic_def_txkey != IEEE80211_KEYIX_NONE)
2631 txkey = ic->ic_def_txkey;
2633 error = iwl2100_set_weptxkey(sc, txkey);
2634 if (error) {
2635 if_printf(ifp, "can't set weptxkey\n");
2636 return error;
2641 error = iwl2100_set_privacy(sc, ic->ic_flags & IEEE80211_F_PRIVACY);
2642 if (error) {
2643 if_printf(ifp, "can't set privacy\n");
2644 return error;
2647 error = iwl2100_set_optie(sc, ic->ic_opt_ie, ic->ic_opt_ie_len);
2648 if (error) {
2649 if (error != E2BIG) {
2650 if_printf(ifp, "can't set opt ie\n");
2651 return error;
2655 if (ic->ic_opmode == IEEE80211_M_IBSS) {
2656 error = iwl2100_set_bintval(sc, ic->ic_bss->ni_intval);
2657 if (error) {
2658 if_printf(ifp, "can't set bintval\n");
2659 return error;
2662 error = iwl2100_set_txpower(sc, 32 /* XXX */);
2663 if (error) {
2664 if_printf(ifp, "can't set txpwr\n");
2665 return error;
2668 return 0;
2671 static int
2672 iwl2100_config_op(struct iwl2100_softc *sc, uint32_t op)
2674 struct iwl2100_cmd *cmd;
2675 int error;
2677 KASSERT(op == IWL2100_CMD_CONF_DONE || op == IWL2100_CMD_CONF_START,
2678 ("unknown config_op %u", op));
2680 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2681 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2682 return EEXIST;
2685 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2686 bzero(cmd, sizeof(cmd));
2687 cmd->c_cmd = op;
2689 error = iwl2100_wait_cmd(sc);
2690 if (error) {
2691 if_printf(&sc->sc_ic.ic_if, "%s(%u) failed\n", __func__, op);
2692 return error;
2695 iwl2100_read_ord1(sc, IWL2100_ORD1_CONF_START); /* dummy read */
2696 return 0;
2699 static int
2700 iwl2100_set_chan(struct iwl2100_softc *sc, const struct ieee80211_channel *c)
2702 struct ieee80211com *ic = &sc->sc_ic;
2703 struct iwl2100_cmd *cmd;
2704 u_int chan;
2705 int error;
2707 KKASSERT(ic->ic_opmode != IEEE80211_M_STA);
2709 chan = ieee80211_chan2ieee(ic, c);
2710 if (chan == IEEE80211_CHAN_ANY) {
2711 if_printf(&ic->ic_if, "invalid channel!\n");
2712 return EINVAL;
2715 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2716 if_printf(&ic->ic_if, "there is command pending\n");
2717 return EEXIST;
2720 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2721 bzero(cmd, sizeof(cmd));
2723 cmd->c_cmd = IWL2100_CMD_SET_CHAN;
2724 cmd->c_param_len = sizeof(cmd->c_param[0]);
2725 cmd->c_param[0] = chan;
2727 error = iwl2100_wait_cmd(sc);
2728 if (error) {
2729 if_printf(&ic->ic_if, "%s failed\n", __func__);
2730 return error;
2732 return 0;
2735 static int
2736 iwl2100_set_scanopt(struct iwl2100_softc *sc, uint32_t chans, uint32_t flags)
2738 struct ieee80211com *ic = &sc->sc_ic;
2739 struct iwl2100_cmd *cmd;
2740 int error;
2742 KKASSERT(ic->ic_opmode != IEEE80211_M_MONITOR);
2744 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2745 if_printf(&ic->ic_if, "there is command pending\n");
2746 return EEXIST;
2749 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2750 bzero(cmd, sizeof(cmd));
2753 * NOTE:
2754 * 1) IWL2100_SCANOPT_NOASSOC is ignored by firmware, but same
2755 * function could be achieved by clearing bssid.
2756 * 2) Channel mask is ignored by firmware, if NIC is in STA opmode.
2758 * We leave the correct configuration here just with the hope
2759 * that one day firmware could do better.
2761 cmd->c_cmd = IWL2100_CMD_SET_SCANOPT;
2762 cmd->c_param_len = sizeof(cmd->c_param[0]) * 2;
2763 cmd->c_param[0] = flags | IWL2100_SCANOPT_MIXED;
2764 cmd->c_param[1] = chans;
2766 error = iwl2100_wait_cmd(sc);
2767 if (error) {
2768 if_printf(&ic->ic_if, "%s failed\n", __func__);
2769 return error;
2771 return 0;
2774 static int
2775 iwl2100_set_scan(struct iwl2100_softc *sc)
2777 struct ieee80211com *ic = &sc->sc_ic;
2778 struct iwl2100_cmd *cmd;
2779 int error;
2781 KKASSERT(ic->ic_opmode != IEEE80211_M_MONITOR);
2783 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2784 if_printf(&ic->ic_if, "there is command pending\n");
2785 return EEXIST;
2788 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2789 bzero(cmd, sizeof(cmd));
2791 cmd->c_cmd = IWL2100_CMD_SCAN;
2792 cmd->c_param_len = sizeof(cmd->c_param[0]);
2794 error = iwl2100_wait_cmd(sc);
2795 if (error) {
2796 if_printf(&ic->ic_if, "%s failed\n", __func__);
2797 return error;
2799 return 0;
2802 static int
2803 iwl2100_set_optie(struct iwl2100_softc *sc, void *optie, uint16_t optie_len)
2805 struct iwl2100_cmd *cmd;
2806 struct iwl2100_cmdparam_ie *ie;
2807 int error;
2809 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2810 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2811 return EEXIST;
2814 if (optie_len > IWL2100_OPTIE_MAX) {
2815 if_printf(&sc->sc_ic.ic_if, "optie too long\n");
2816 return E2BIG;
2819 if (optie == NULL || optie_len == 0)
2820 return 0;
2822 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2823 bzero(cmd, sizeof(cmd));
2825 cmd->c_cmd = IWL2100_CMD_SET_IE;
2826 cmd->c_param_len = sizeof(*ie);
2827 ie = (struct iwl2100_cmdparam_ie *)cmd->c_param;
2828 ie->ie_optlen = optie_len;
2829 bcopy(optie, ie->ie_opt, optie_len);
2831 error = iwl2100_wait_cmd(sc);
2832 if (error) {
2833 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2834 return error;
2836 return 0;
2839 static int
2840 iwl2100_set_bintval(struct iwl2100_softc *sc, uint16_t bintval)
2842 struct iwl2100_cmd *cmd;
2843 int error;
2845 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2846 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2847 return EEXIST;
2850 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2851 bzero(cmd, sizeof(cmd));
2853 cmd->c_cmd = IWL2100_CMD_SET_BINTVAL;
2854 cmd->c_param_len = sizeof(cmd->c_param[0]);
2855 cmd->c_param[0] = bintval;
2857 error = iwl2100_wait_cmd(sc);
2858 if (error) {
2859 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2860 return error;
2862 return 0;
2865 static int
2866 iwl2100_set_txpower(struct iwl2100_softc *sc, uint16_t txpower)
2868 struct iwl2100_cmd *cmd;
2869 int error;
2871 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2872 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2873 return EEXIST;
2876 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2877 bzero(cmd, sizeof(cmd));
2879 cmd->c_cmd = IWL2100_CMD_SET_TXPOWER;
2880 cmd->c_param_len = sizeof(cmd->c_param[0]);
2881 cmd->c_param[0] = txpower;
2883 error = iwl2100_wait_cmd(sc);
2884 if (error) {
2885 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2886 return error;
2888 return 0;
2891 static void
2892 iwl2100_rxeof_status(struct iwl2100_softc *sc, int i)
2894 struct ieee80211com *ic = &sc->sc_ic;
2895 struct ifnet *ifp = &ic->ic_if;
2896 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
2897 struct iwl2100_rx_status *st = &rr->rr_status[i];
2898 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
2899 struct mbuf *m = rb->rb_mbuf;
2900 uint32_t status;
2902 if (st->r_len != sizeof(status)) {
2903 if_printf(ifp, "invalid status frame len %u\n", st->r_len);
2904 goto back;
2907 if (ic->ic_opmode == IEEE80211_M_MONITOR)
2908 goto back;
2910 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0)
2911 sc->sc_flags &= ~IWL2100_F_SCANNING;
2913 status = *mtod(m, uint32_t *);
2914 DPRINTF(sc, IWL2100_DBG_STATUS, "status 0x%08x\n", status);
2916 switch (status) {
2917 case IWL2100_STATUS_SCANDONE:
2918 if (ic->ic_flags & IEEE80211_F_SCAN) {
2920 * To make sure that firmware has iterated all
2921 * of the channels, we wait for the second scan
2922 * done status change.
2924 if (sc->sc_flags & IWL2100_F_SCANNING) {
2925 iwlmsg_send(&sc->sc_scanend_msg,
2926 &sc->sc_thread_port);
2927 } else {
2928 sc->sc_flags |= IWL2100_F_SCANNING;
2931 break;
2933 case IWL2100_STATUS_RUNNING:
2934 iwl2100_restart_done(sc);
2935 if (ic->ic_state == IEEE80211_S_ASSOC) {
2936 KKASSERT(ic->ic_opmode == IEEE80211_M_STA);
2937 iwlmsg_send(&sc->sc_run_msg, &sc->sc_thread_port);
2938 } else if (ic->ic_state == IEEE80211_S_RUN) {
2939 if (ic->ic_opmode == IEEE80211_M_STA) {
2940 DPRINTF(sc, IWL2100_DBG_RESTART, "%s",
2941 "restart done\n");
2942 sc->sc_flags |= IWL2100_F_IFSTART;
2943 if_devstart(ifp);
2944 } else {
2945 KKASSERT(ic->ic_opmode == IEEE80211_M_IBSS);
2946 callout_reset(&sc->sc_ibss, (100 * hz) / 1000,
2947 iwl2100_ibss_bssid, sc);
2950 break;
2952 case IWL2100_STATUS_BMISS:
2953 if (ic->ic_opmode == IEEE80211_M_STA) {
2954 DPRINTF(sc, IWL2100_DBG_SCAN, "%s", "bmiss\n");
2955 iwlmsg_send(&sc->sc_bmiss_msg, &sc->sc_thread_port);
2957 break;
2959 case IWL2100_STATUS_SCANNING:
2960 if (ic->ic_opmode == IEEE80211_M_STA &&
2961 ic->ic_state == IEEE80211_S_RUN) {
2962 /* Firmware error happens */
2963 iwl2100_restart(sc);
2965 break;
2967 back:
2968 iwl2100_rxdesc_setup(sc, i);
2971 static void
2972 iwl2100_rxeof_note(struct iwl2100_softc *sc, int i)
2974 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
2975 struct iwl2100_rx_status *st = &rr->rr_status[i];
2976 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
2977 struct mbuf *m = rb->rb_mbuf;
2978 struct ieee80211com *ic = &sc->sc_ic;
2979 struct iwl2100_note *note;
2981 if (st->r_len < sizeof(*note)) {
2982 if_printf(&ic->ic_if, "invalid note frame len %u\n", st->r_len);
2983 goto back;
2986 if (ic->ic_opmode == IEEE80211_M_MONITOR)
2987 goto back;
2989 note = mtod(m, struct iwl2100_note *);
2990 DPRINTF(sc, IWL2100_DBG_NOTE, "note subtype %u, size %u\n",
2991 note->nt_subtype, note->nt_size);
2993 if (note->nt_subtype == 19 /* XXX */ &&
2994 ic->ic_state == IEEE80211_S_AUTH) {
2995 KKASSERT(ic->ic_opmode == IEEE80211_M_STA);
2996 iwlmsg_send(&sc->sc_assoc_msg, &sc->sc_thread_port);
2998 back:
2999 iwl2100_rxdesc_setup(sc, i);
3002 static void
3003 iwl2100_rxeof_cmd(struct iwl2100_softc *sc, int i)
3005 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
3006 struct iwl2100_rx_status *st = &rr->rr_status[i];
3007 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
3008 struct mbuf *m = rb->rb_mbuf;
3009 struct iwl2100_cmd *cmd;
3011 if (st->r_len != sizeof(*cmd)) {
3012 if_printf(&sc->sc_ic.ic_if,
3013 "invalid cmd done frame len %u\n", st->r_len);
3014 goto back;
3017 cmd = mtod(m, struct iwl2100_cmd *);
3018 DPRINTF(sc, IWL2100_DBG_CMD, "cmd %u\n", cmd->c_cmd);
3019 if (cmd->c_cmd == 0)
3020 sc->sc_flags |= IWL2100_F_ZERO_CMD;
3021 wakeup(sc);
3022 back:
3023 iwl2100_rxdesc_setup(sc, i);
3026 static void
3027 iwl2100_rxeof_data(struct iwl2100_softc *sc, int i)
3029 struct ieee80211com *ic = &sc->sc_ic;
3030 struct ifnet *ifp = &ic->ic_if;
3031 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
3032 struct iwl2100_rx_status *st = &rr->rr_status[i];
3033 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
3034 struct mbuf *m = rb->rb_mbuf;
3035 struct ieee80211_frame_min *wh;
3036 struct ieee80211_node *ni;
3037 int frame_len, rssi;
3038 const struct ieee80211_channel *c;
3041 * Gather all necessary information from status ring _here_,
3042 * since the following iwl2100_newbuf() will clear them out.
3044 rssi = st->r_rssi;
3045 frame_len = st->r_len;
3047 if (iwl2100_newbuf(sc, i, 0)) {
3048 ifp->if_ierrors++;
3049 return;
3052 c = ic->ic_curchan;
3054 m->m_pkthdr.rcvif = ifp;
3055 m->m_len = m->m_pkthdr.len = frame_len;
3057 wh = mtod(m, struct ieee80211_frame_min *);
3058 ni = ieee80211_find_rxnode(ic, wh);
3061 * RX radio tap
3063 if (sc->sc_drvbpf != NULL) {
3064 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
3065 sc->sc_rx_th.wr_flags = IEEE80211_RADIOTAP_F_WEP;
3066 else
3067 sc->sc_rx_th.wr_flags = 0;
3069 sc->sc_rx_th.wr_antsignal = rssi + IWL2100_NOISE_FLOOR;
3070 sc->sc_rx_th.wr_antnoise = IWL2100_NOISE_FLOOR;
3072 bpf_ptap(sc->sc_drvbpf, m, &sc->sc_rx_th, sc->sc_rx_th_len);
3075 ieee80211_input(ic, m, ni, rssi, 0);
3076 ieee80211_free_node(ni);
3078 if (c != ic->ic_curchan) /* Happen during scanning */
3079 iwl2100_chan_change(sc, ic->ic_curchan);
3082 static void
3083 iwl2100_scanend_dispatch(struct netmsg *nmsg)
3085 struct iwlmsg *msg = (struct iwlmsg *)nmsg;
3086 struct iwl2100_softc *sc = msg->iwlm_softc;
3087 struct ieee80211com *ic = &sc->sc_ic;
3088 struct ifnet *ifp = &ic->ic_if;
3090 ASSERT_SERIALIZED(ifp->if_serializer);
3092 if (sc->sc_flags & IWL2100_F_DETACH)
3093 goto reply;
3095 if (ifp->if_flags & IFF_RUNNING) {
3096 ieee80211_end_scan(ic);
3097 sc->sc_flags &= ~IWL2100_F_SCANNING;
3099 reply:
3100 lwkt_replymsg(&nmsg->nm_lmsg, 0);
3103 static int
3104 iwl2100_hw_init(struct iwl2100_softc *sc, const uint8_t *bssid,
3105 const uint8_t *essid, uint8_t esslen, uint32_t flags)
3107 struct ieee80211com *ic = &sc->sc_ic;
3108 struct ifnet *ifp = &ic->ic_if;
3109 uint32_t db_addr;
3110 int error;
3112 ASSERT_SERIALIZED(ifp->if_serializer);
3113 KKASSERT(curthread == &sc->sc_thread);
3115 iwl2100_hw_stop(sc);
3117 error = iwl2100_alloc_firmware(sc, ic->ic_opmode);
3118 if (error) {
3119 if_printf(ifp, "can't allocate firmware\n");
3120 goto back;
3123 error = iwl2100_load_firmware(sc, ic->ic_opmode);
3124 if (error) {
3125 if_printf(ifp, "can't load firmware\n");
3126 goto back;
3129 error = iwl2100_alloc_cmd(sc);
3130 if (error) {
3131 if_printf(ifp, "can't allocate cmd\n");
3132 goto back;
3135 error = iwl2100_init_tx_ring(sc);
3136 if (error) {
3137 if_printf(ifp, "can't init TX ring\n");
3138 goto back;
3141 error = iwl2100_init_rx_ring(sc);
3142 if (error) {
3143 if_printf(ifp, "can't init RX ring\n");
3144 goto back;
3147 error = iwl2100_init_firmware(sc);
3148 if (error) {
3149 if_printf(ifp, "can't initialize firmware\n");
3150 goto back;
3153 sc->sc_ord1 = CSR_READ_4(sc, IWL2100_ORD1_ADDR);
3154 sc->sc_ord2 = CSR_READ_4(sc, IWL2100_ORD2_ADDR);
3156 db_addr = iwl2100_read_ord1(sc, IWL2100_ORD1_DBADDR);
3157 if ((IND_READ_4(sc, db_addr + 0x20) >> 24) & 0x1)
3158 sc->sc_caps &= ~IWL2100_C_RFKILL;
3159 else
3160 sc->sc_caps |= IWL2100_C_RFKILL;
3162 /* Unlock firmware */
3163 iwl2100_write_ord1(sc, IWL2100_ORD1_FWLOCK, 0);
3165 if (iwl2100_rfkilled(sc)) {
3166 error = ENXIO;
3167 goto back;
3170 /* Let interrupt handler run */
3171 sc->sc_flags |= IWL2100_F_INITED;
3173 /* Enable interrupts */
3174 CSR_WRITE_4(sc, IWL2100_INTR_MASK, IWL2100_INTRS);
3176 error = iwl2100_config(sc, bssid, essid, esslen,
3177 flags & IWL2100_INIT_F_IBSSCHAN);
3178 if (error)
3179 goto back;
3181 if (flags & IWL2100_INIT_F_ENABLE) {
3182 error = iwl2100_config_done(sc);
3183 if (error) {
3184 if_printf(ifp, "can't complete config\n");
3185 goto back;
3189 ifp->if_flags &= ~IFF_OACTIVE;
3190 ifp->if_flags |= IFF_RUNNING;
3191 back:
3192 if (error)
3193 iwl2100_stop(sc);
3194 return error;
3197 static int
3198 iwl2100_start_scan(struct iwl2100_softc *sc, uint32_t chans, uint32_t flags)
3200 int error;
3203 * XXX
3204 * Firmware always starts scanning once config is done
3206 error = iwl2100_set_scanopt(sc, chans, flags);
3207 if (error) {
3208 if_printf(&sc->sc_ic.ic_if, "can't set scan opt\n");
3209 return error;
3212 error = iwl2100_set_scan(sc);
3213 if (error) {
3214 if_printf(&sc->sc_ic.ic_if, "can't set bcast scanning\n");
3215 return error;
3217 return 0;
3220 static int
3221 iwl2100_scan(struct iwl2100_softc *sc)
3223 struct ieee80211com *ic = &sc->sc_ic;
3224 uint32_t chans, flags;
3225 int error;
3227 KKASSERT(ic->ic_opmode != IEEE80211_M_MONITOR);
3229 error = iwl2100_hw_init(sc, NULL,
3230 ic->ic_des_essid, ic->ic_des_esslen, IWL2100_INIT_F_ENABLE);
3231 if (error)
3232 return error;
3234 if (ic->ic_opmode == IEEE80211_M_STA) {
3235 chans = sc->sc_bss_chans;
3236 flags = IWL2100_SCANOPT_NOASSOC;
3237 } else {
3239 * Normally # of IBSS channels is less than BSS's
3240 * but it seems IBSS mode works on all BSS channels
3242 #if 0
3243 chans = sc->sc_ibss_chans;
3244 #else
3245 chans = sc->sc_bss_chans;
3246 #endif
3248 * Don't set NOASSOC scan option, it seems that
3249 * firmware will disable itself after scanning
3250 * if this flag is set. After all, we are in
3251 * IBSS mode, which does not have concept of
3252 * association.
3254 flags = 0;
3257 /* See NOTE in iwl2100_set_scanopt() */
3258 error = iwl2100_start_scan(sc, chans, flags);
3259 if (error)
3260 return error;
3261 return 0;
3264 static int
3265 iwl2100_auth(struct iwl2100_softc *sc)
3267 struct ieee80211com *ic = &sc->sc_ic;
3268 struct ieee80211_node *ni = ic->ic_bss;
3269 u_int chan;
3270 int error;
3272 KKASSERT(ic->ic_opmode == IEEE80211_M_STA);
3274 chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
3275 if (chan == IEEE80211_CHAN_ANY) {
3276 if_printf(&ic->ic_if, "invalid curchan\n");
3277 return EINVAL;
3280 error = iwl2100_hw_init(sc, ni->ni_bssid,
3281 ni->ni_essid, ni->ni_esslen, IWL2100_INIT_F_ENABLE);
3282 if (error)
3283 return error;
3285 /* See NOTE in iwl2100_set_scanopt() */
3286 error = iwl2100_start_scan(sc, 1 << (chan - 1), 0);
3287 if (error)
3288 return error;
3289 return 0;
3292 static int
3293 iwl2100_ibss(struct iwl2100_softc *sc)
3295 struct ieee80211com *ic = &sc->sc_ic;
3296 struct ieee80211_node *ni = ic->ic_bss;
3298 return iwl2100_hw_init(sc, ni->ni_bssid,
3299 ni->ni_essid, ni->ni_esslen,
3300 IWL2100_INIT_F_ENABLE | IWL2100_INIT_F_IBSSCHAN);
3303 static int
3304 iwl2100_encap(struct iwl2100_softc *sc, struct mbuf *m)
3306 struct iwl2100_tx_ring *tr = &sc->sc_txring;
3307 struct iwl2100_tx_hdr *th;
3308 struct ieee80211_frame *wh;
3309 struct iwl_dmamap_ctx ctx;
3310 bus_dma_segment_t segs[IWL2100_NSEG_MAX];
3311 uint8_t src[IEEE80211_ADDR_LEN], dst[IEEE80211_ADDR_LEN];
3312 bus_dmamap_t dmap;
3313 int maxsegs, i, first_idx, last_idx, error, host_enc;
3316 * Save necessary information and strip 802.11 header
3318 wh = mtod(m, struct ieee80211_frame *);
3319 IEEE80211_ADDR_COPY(src, wh->i_addr2);
3320 if (sc->sc_ic.ic_opmode == IEEE80211_M_STA)
3321 IEEE80211_ADDR_COPY(dst, wh->i_addr3);
3322 else
3323 IEEE80211_ADDR_COPY(dst, wh->i_addr1);
3324 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
3325 host_enc = 1;
3326 else
3327 host_enc = 0;
3328 m_adj(m, sizeof(*wh));
3331 * Prepend and setup hardware TX header
3333 M_PREPEND(m, sizeof(*th), MB_DONTWAIT);
3334 if (m == NULL) {
3335 if_printf(&sc->sc_ic.ic_if, "prepend TX header failed\n");
3336 return ENOBUFS;
3338 th = mtod(m, struct iwl2100_tx_hdr *);
3340 bzero(th, sizeof(*th));
3341 th->th_cmd = IWL2100_CMD_TX_DATA;
3342 th->th_host_enc = host_enc;
3343 IEEE80211_ADDR_COPY(th->th_src, src);
3344 IEEE80211_ADDR_COPY(th->th_dst, dst);
3347 * Load mbuf into DMA map
3349 maxsegs = IWL2100_TX_USED_MAX - tr->tr_used;
3350 if (maxsegs > IWL2100_NSEG_MAX)
3351 maxsegs = IWL2100_NSEG_MAX;
3353 KKASSERT(tr->tr_index < IWL2100_TX_NDESC);
3354 first_idx = tr->tr_index;
3355 dmap = tr->tr_buf[first_idx].tb_dmap;
3357 ctx.nsegs = maxsegs;
3358 ctx.segs = segs;
3359 error = bus_dmamap_load_mbuf(sc->sc_mbuf_dtag, dmap, m,
3360 iwl_dma_buf_addr, &ctx, BUS_DMA_NOWAIT);
3361 if (!error && ctx.nsegs == 0) {
3362 bus_dmamap_unload(sc->sc_mbuf_dtag, dmap);
3363 error = EFBIG;
3365 if (error && error != EFBIG) {
3366 if_printf(&sc->sc_ic.ic_if, "can't load TX mbuf, error %d\n",
3367 error);
3368 goto back;
3370 if (error) { /* error == EFBIG */
3371 struct mbuf *m_new;
3373 m_new = m_defrag(m, MB_DONTWAIT);
3374 if (m_new == NULL) {
3375 if_printf(&sc->sc_ic.ic_if, "can't defrag TX mbuf\n");
3376 error = ENOBUFS;
3377 goto back;
3378 } else {
3379 m = m_new;
3382 ctx.nsegs = maxsegs;
3383 ctx.segs = segs;
3384 error = bus_dmamap_load_mbuf(sc->sc_mbuf_dtag, dmap, m,
3385 iwl_dma_buf_addr, &ctx,
3386 BUS_DMA_NOWAIT);
3387 if (error || ctx.nsegs == 0) {
3388 if (ctx.nsegs == 0) {
3389 bus_dmamap_unload(sc->sc_mbuf_dtag, dmap);
3390 error = EFBIG;
3392 if_printf(&sc->sc_ic.ic_if,
3393 "can't load defraged TX mbuf\n");
3394 goto back;
3397 bus_dmamap_sync(sc->sc_mbuf_dtag, dmap, BUS_DMASYNC_PREWRITE);
3400 * Fill TX desc ring
3402 last_idx = -1;
3403 for (i = 0; i < ctx.nsegs; ++i) {
3404 struct iwl2100_desc *d = &tr->tr_desc[tr->tr_index];
3406 d->d_paddr = segs[i].ds_addr;
3407 d->d_len = segs[i].ds_len;
3408 if (i != 0)
3409 d->d_nfrag = 0;
3410 else
3411 d->d_nfrag = ctx.nsegs;
3413 if (i == ctx.nsegs - 1) {
3414 d->d_flags = IWL2100_TXD_F_INTR;
3415 last_idx = tr->tr_index;
3416 } else {
3417 d->d_flags = IWL2100_TXD_F_NOTLAST;
3420 tr->tr_index = (tr->tr_index + 1) % IWL2100_TX_NDESC;
3422 KKASSERT(last_idx >= 0);
3424 tr->tr_buf[first_idx].tb_dmap = tr->tr_buf[last_idx].tb_dmap;
3425 tr->tr_buf[last_idx].tb_dmap = dmap;
3426 tr->tr_buf[last_idx].tb_mbuf = m;
3428 tr->tr_used += ctx.nsegs;
3429 KKASSERT(tr->tr_used <= IWL2100_TX_USED_MAX);
3431 error = 0;
3432 back:
3433 if (error)
3434 m_freem(m);
3435 return error;
3438 static void
3439 iwl2100_restart_dispatch(struct netmsg *nmsg)
3441 struct iwlmsg *msg = (struct iwlmsg *)nmsg;
3442 struct iwl2100_softc *sc = msg->iwlm_softc;
3443 struct ieee80211com *ic = &sc->sc_ic;
3444 struct ifnet *ifp = &ic->ic_if;
3445 int error = 0;
3447 ASSERT_SERIALIZED(ifp->if_serializer);
3449 if (sc->sc_flags & IWL2100_F_DETACH)
3450 goto reply;
3452 if ((ifp->if_flags & IFF_RUNNING) == 0)
3453 goto reply;
3455 if (msg->iwlm_arg != sc->sc_state_age) {
3457 * Restarting was triggered in old 802.11 state
3458 * Don't do anything, this is a staled restarting.
3460 goto reply;
3463 if (ic->ic_state != IEEE80211_S_RUN) {
3464 if_printf(ifp, "restart happened when not in RUN state\n");
3465 goto reply;
3469 * iwl2100_auth() may release slizer, so stop all
3470 * callouts to prevent them from misfiring.
3472 callout_stop(&sc->sc_restart_bmiss);
3473 callout_stop(&sc->sc_ibss);
3475 if (ic->ic_opmode == IEEE80211_M_STA) {
3476 error = iwl2100_auth(sc);
3477 if (error)
3478 goto reply;
3481 * Start software beacon missing to handle missing
3482 * firmware bmiss status change when we restarting
3484 callout_reset(&sc->sc_restart_bmiss, IEEE80211_TU_TO_TICKS(
3485 2 * ic->ic_bmissthreshold * ic->ic_bss->ni_intval),
3486 iwl2100_restart_bmiss, sc);
3487 } else if (ic->ic_opmode == IEEE80211_M_IBSS) {
3488 error = iwl2100_ibss(sc);
3489 if (error)
3490 goto reply;
3493 /* Turn on restarting flag before reply this message */
3494 sc->sc_flags |= IWL2100_F_RESTARTING;
3495 reply:
3496 lwkt_replymsg(&nmsg->nm_lmsg, error);
3499 static void
3500 iwl2100_restart(struct iwl2100_softc *sc)
3502 if ((sc->sc_flags & (IWL2100_F_RESTARTING | IWL2100_F_DETACH)) == 0) {
3503 struct iwlmsg *msg = &sc->sc_restart_msg;
3504 struct lwkt_msg *lmsg = &msg->iwlm_nmsg.nm_lmsg;
3506 DPRINTF(sc, IWL2100_DBG_RESTART, "%s", "restart\n");
3507 if (lmsg->ms_flags & MSGF_DONE) {
3508 sc->sc_flags &= ~IWL2100_F_IFSTART;
3509 msg->iwlm_arg = sc->sc_state_age;
3510 lwkt_sendmsg(&sc->sc_thread_port, lmsg);
3515 static void
3516 iwl2100_bmiss_dispatch(struct netmsg *nmsg)
3518 struct iwlmsg *msg = (struct iwlmsg *)nmsg;
3519 struct iwl2100_softc *sc = msg->iwlm_softc;
3520 struct ieee80211com *ic = &sc->sc_ic;
3521 struct ifnet *ifp = &ic->ic_if;
3523 ASSERT_SERIALIZED(ifp->if_serializer);
3525 if (sc->sc_flags & IWL2100_F_DETACH)
3526 goto reply;
3528 if (ifp->if_flags & IFF_RUNNING) {
3530 * Fake a ic_bmiss_count to make sure that
3531 * ieee80211_beacon_miss() will do its job
3533 ic->ic_bmiss_count = ic->ic_bmiss_max;
3534 ieee80211_beacon_miss(ic);
3536 reply:
3537 lwkt_replymsg(&nmsg->nm_lmsg, 0);
3540 static void
3541 iwl2100_restart_bmiss(void *xsc)
3543 struct iwl2100_softc *sc = xsc;
3544 struct ifnet *ifp = &sc->sc_ic.ic_if;
3546 lwkt_serialize_enter(ifp->if_serializer);
3548 if (sc->sc_flags & IWL2100_F_DETACH)
3549 goto back;
3551 if ((ifp->if_flags & IFF_RUNNING) == 0)
3552 goto back;
3554 if (sc->sc_flags & IWL2100_F_RESTARTING) {
3555 DPRINTF(sc, IWL2100_DBG_SCAN | IWL2100_DBG_RESTART, "%s",
3556 "restart bmiss\n");
3557 iwlmsg_send(&sc->sc_bmiss_msg, &sc->sc_thread_port);
3559 back:
3560 lwkt_serialize_exit(ifp->if_serializer);
3563 static void
3564 iwl2100_ibss_bssid(void *xsc)
3566 struct iwl2100_softc *sc = xsc;
3567 struct ieee80211com *ic = &sc->sc_ic;
3568 struct ifnet *ifp = &ic->ic_if;
3570 lwkt_serialize_enter(ifp->if_serializer);
3572 if (sc->sc_flags & IWL2100_F_DETACH)
3573 goto back;
3575 if ((ifp->if_flags & IFF_RUNNING) == 0)
3576 goto back;
3578 if (ic->ic_state == IEEE80211_S_RUN &&
3579 ic->ic_opmode == IEEE80211_M_IBSS) {
3580 uint8_t bssid[IEEE80211_ADDR_LEN];
3581 int len;
3583 len = iwl2100_read_ord2(sc, IWL2100_ORD2_BSSID,
3584 bssid, sizeof(bssid));
3585 if (len < (int)sizeof(bssid)) {
3586 if_printf(ifp, "can't get IBSS bssid\n");
3587 } else {
3588 DPRINTF(sc, IWL2100_DBG_IBSS, "IBSS bssid: %6D\n",
3589 bssid, ":");
3590 IEEE80211_ADDR_COPY(ic->ic_bss->ni_bssid, bssid);
3592 sc->sc_flags |= IWL2100_F_IFSTART;
3593 if_devstart(ifp);
3596 back:
3597 lwkt_serialize_exit(ifp->if_serializer);
3600 static void
3601 iwl2100_reinit(struct iwl2100_softc *sc)
3603 struct ifnet *ifp = &sc->sc_ic.ic_if;
3605 callout_stop(&sc->sc_restart_bmiss);
3606 callout_stop(&sc->sc_ibss);
3608 ifp->if_flags &= ~IFF_RUNNING;
3609 ifp->if_timer = 0;
3611 sc->sc_flags &= ~IWL2100_F_INITED;
3612 sc->sc_tx_timer = 0;
3614 /* Mark error happened, and wake up the pending command */
3615 sc->sc_flags |= IWL2100_F_ERROR;
3616 wakeup(sc);
3618 if ((sc->sc_flags & IWL2100_F_DETACH) == 0) {
3620 * Schedule complete initialization,
3621 * i.e. blow away current state
3623 iwlmsg_send(&sc->sc_reinit_msg, &sc->sc_thread_port);
3627 static void
3628 iwl2100_reinit_dispatch(struct netmsg *nmsg)
3630 struct iwlmsg *msg = (struct iwlmsg *)nmsg;
3631 struct iwl2100_softc *sc = msg->iwlm_softc;
3632 struct ifnet *ifp = &sc->sc_ic.ic_if;
3634 ASSERT_SERIALIZED(ifp->if_serializer);
3637 * NOTE: Reply ASAP, so reinit msg could be used if error intr
3638 * happened again during following iwl2100_init()
3640 lwkt_replymsg(&nmsg->nm_lmsg, 0);
3642 if (sc->sc_flags & IWL2100_F_DETACH)
3643 return;
3645 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
3646 iwl2100_init(sc);
3649 static void
3650 iwl2100_reinit_callout(void *xsc)
3652 struct iwl2100_softc *sc = xsc;
3653 struct ifnet *ifp = &sc->sc_ic.ic_if;
3655 lwkt_serialize_enter(ifp->if_serializer);
3656 if ((sc->sc_flags & IWL2100_F_DETACH) == 0)
3657 iwl2100_reinit(sc);
3658 lwkt_serialize_exit(ifp->if_serializer);
3661 static void
3662 iwl2100_chan_change(struct iwl2100_softc *sc, const struct ieee80211_channel *c)
3664 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
3665 htole16(c->ic_freq);
3668 static void
3669 iwl2100_stop_callouts(struct iwl2100_softc *sc)
3671 callout_stop(&sc->sc_restart_bmiss);
3672 callout_stop(&sc->sc_ibss);
3673 callout_stop(&sc->sc_reinit);