- In command RX intr, if the command number returned is 0, then hardware
[dragonfly.git] / sys / dev / netif / iwl / iwl2100.c
blob3c333c9e55d952350094fd932c065ead1b055c28
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.3 2008/03/08 06:43:52 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/mbuf.h>
43 #include <sys/module.h>
44 #include <sys/sysctl.h>
45 #include <sys/socket.h>
46 #include <sys/sockio.h>
47 #include <sys/rman.h>
49 #include <net/bpf.h>
50 #include <net/if.h>
51 #include <net/if_arp.h>
52 #include <net/ethernet.h>
53 #include <net/if_dl.h>
54 #include <net/if_media.h>
55 #include <net/ifq_var.h>
56 #include <net/netmsg2.h>
58 #include <netproto/802_11/ieee80211_var.h>
59 #include <netproto/802_11/ieee80211_radiotap.h>
61 #include <bus/pci/pcireg.h>
62 #include <bus/pci/pcivar.h>
64 #include "if_iwlvar.h"
65 #include "iwl2100reg.h"
66 #include "iwl2100var.h"
68 #define IWL2100_INIT_F_ENABLE 0x1
69 #define IWL2100_INIT_F_IBSSCHAN 0x2
71 #define sc_tx_th sc_u_tx_th.u_tx_th
72 #define sc_rx_th sc_u_rx_th.u_rx_th
74 static void iwl2100_init(void *);
75 static int iwl2100_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
76 static void iwl2100_start(struct ifnet *);
77 static void iwl2100_watchdog(struct ifnet *);
78 static int iwl2100_newstate(struct ieee80211com *, enum ieee80211_state, int);
79 static int iwl2100_media_change(struct ifnet *);
80 static void iwl2100_media_status(struct ifnet *, struct ifmediareq *);
81 static void iwl2100_stop(struct iwl2100_softc *);
82 static void iwl2100_restart(struct iwl2100_softc *);
83 static void iwl2100_reinit(struct iwl2100_softc *);
85 static void iwl2100_intr(void *);
86 static void iwl2100_txeof(struct iwl2100_softc *);
87 static void iwl2100_rxeof(struct iwl2100_softc *);
88 static void iwl2100_rxeof_status(struct iwl2100_softc *, int);
89 static void iwl2100_rxeof_note(struct iwl2100_softc *, int);
90 static void iwl2100_rxeof_cmd(struct iwl2100_softc *, int);
91 static void iwl2100_rxeof_data(struct iwl2100_softc *, int);
93 static void iwl2100_init_dispatch(struct netmsg *);
94 static void iwl2100_reinit_dispatch(struct netmsg *);
95 static void iwl2100_stop_dispatch(struct netmsg *);
96 static void iwl2100_newstate_dispatch(struct netmsg *);
97 static void iwl2100_scanend_dispatch(struct netmsg *);
98 static void iwl2100_restart_dispatch(struct netmsg *);
99 static void iwl2100_bmiss_dispatch(struct netmsg *);
101 static void iwl2100_stop_callouts(struct iwl2100_softc *);
102 static void iwl2100_restart_bmiss(void *);
103 static void iwl2100_ibss_bssid(void *);
104 static void iwl2100_reinit_callout(void *);
106 static int iwl2100_dma_alloc(device_t);
107 static void iwl2100_dma_free(device_t);
108 static int iwl2100_dma_mbuf_create(device_t);
109 static void iwl2100_dma_mbuf_destroy(device_t, int, int);
110 static int iwl2100_init_tx_ring(struct iwl2100_softc *);
111 static int iwl2100_init_rx_ring(struct iwl2100_softc *);
112 static void iwl2100_free_tx_ring(struct iwl2100_softc *);
113 static void iwl2100_free_rx_ring(struct iwl2100_softc *);
115 static int iwl2100_alloc_cmd(struct iwl2100_softc *);
116 static void iwl2100_free_cmd(struct iwl2100_softc *);
117 static int iwl2100_wait_cmd(struct iwl2100_softc *);
119 static void iwl2100_rxdesc_setup(struct iwl2100_softc *, int);
120 static int iwl2100_newbuf(struct iwl2100_softc *, int, int);
121 static int iwl2100_encap(struct iwl2100_softc *, struct mbuf *);
123 static void iwl2100_chan_change(struct iwl2100_softc *,
124 const struct ieee80211_channel *);
126 static int iwl2100_alloc_firmware(struct iwl2100_softc *,
127 enum ieee80211_opmode);
128 static void iwl2100_free_firmware(struct iwl2100_softc *);
129 static int iwl2100_load_firmware(struct iwl2100_softc *,
130 enum ieee80211_opmode);
131 static int iwl2100_load_fw_ucode(struct iwl2100_softc *,
132 const struct iwl2100_firmware *);
133 static int iwl2100_load_fw_data(struct iwl2100_softc *,
134 const struct iwl2100_firmware *);
135 static int iwl2100_init_firmware(struct iwl2100_softc *);
137 static int iwl2100_read_ord2(struct iwl2100_softc *, uint32_t,
138 void *, int);
139 static uint32_t iwl2100_read_ord1(struct iwl2100_softc *, uint32_t);
140 static void iwl2100_write_ord1(struct iwl2100_softc *, uint32_t, uint32_t);
142 static int iwl2100_reset(struct iwl2100_softc *);
143 static int iwl2100_hw_reset(struct iwl2100_softc *);
144 static int iwl2100_rfkilled(struct iwl2100_softc *);
146 static int iwl2100_scan(struct iwl2100_softc *);
147 static int iwl2100_auth(struct iwl2100_softc *);
148 static int iwl2100_ibss(struct iwl2100_softc *);
150 static int iwl2100_hw_init(struct iwl2100_softc *, const uint8_t *,
151 const uint8_t *, uint8_t, uint32_t);
152 static void iwl2100_hw_stop(struct iwl2100_softc *);
153 static int iwl2100_config(struct iwl2100_softc *, const uint8_t *,
154 const uint8_t *, uint8_t, int);
155 static int iwl2100_start_scan(struct iwl2100_softc *, uint32_t, uint32_t);
157 static int iwl2100_config_op(struct iwl2100_softc *, uint32_t);
158 static int iwl2100_set_addr(struct iwl2100_softc *, const uint8_t *);
159 static int iwl2100_set_opmode(struct iwl2100_softc *,
160 enum ieee80211_opmode);
161 static int iwl2100_set_80211(struct iwl2100_softc *);
162 static int iwl2100_set_basicrates(struct iwl2100_softc *);
163 static int iwl2100_set_txrates(struct iwl2100_softc *);
164 static int iwl2100_set_powersave(struct iwl2100_softc *, int);
165 static int iwl2100_set_rtsthreshold(struct iwl2100_softc *, uint16_t);
166 static int iwl2100_set_bssid(struct iwl2100_softc *, const uint8_t *);
167 static int iwl2100_set_essid(struct iwl2100_softc *, const uint8_t *, int);
168 static int iwl2100_set_auth_ciphers(struct iwl2100_softc *,
169 enum ieee80211_authmode);
170 static int iwl2100_set_wepkey(struct iwl2100_softc *,
171 const struct ieee80211_key *);
172 static int iwl2100_set_weptxkey(struct iwl2100_softc *, ieee80211_keyix);
173 static int iwl2100_set_privacy(struct iwl2100_softc *, int);
174 static int iwl2100_set_chan(struct iwl2100_softc *,
175 const struct ieee80211_channel *);
176 static int iwl2100_set_scanopt(struct iwl2100_softc *, uint32_t, uint32_t);
177 static int iwl2100_set_scan(struct iwl2100_softc *);
178 static int iwl2100_set_optie(struct iwl2100_softc *, void *, uint16_t);
179 static int iwl2100_set_bintval(struct iwl2100_softc *, uint16_t);
180 static int iwl2100_set_txpower(struct iwl2100_softc *, uint16_t);
182 static __inline int
183 iwl2100_config_done(struct iwl2100_softc *sc)
185 return iwl2100_config_op(sc, IWL2100_CMD_CONF_DONE);
188 static __inline int
189 iwl2100_config_start(struct iwl2100_softc *sc)
191 return iwl2100_config_op(sc, IWL2100_CMD_CONF_START);
194 static __inline void
195 iwl2100_restart_done(struct iwl2100_softc *sc)
197 callout_stop(&sc->sc_restart_bmiss);
198 sc->sc_flags &= ~IWL2100_F_RESTARTING;
202 iwl2100_attach(device_t dev)
204 struct iwl2100_softc *sc = device_get_softc(dev);
205 struct ieee80211com *ic = &sc->sc_ic;
206 struct ifnet *ifp = &ic->ic_if;
207 uint16_t val;
208 int error, i;
211 * Linux voodoo:
212 * Clear the retry timeout PCI configuration register to keep
213 * PCI TX retries from interfering with C3 CPU state.
215 pci_write_config(dev, IWL2100_PCIR_RETRY_TIMEOUT, 0, 1);
218 * Allocate DMA stuffs
220 error = iwl2100_dma_alloc(dev);
221 if (error)
222 return error;
224 /* Disable interrupts */
225 CSR_WRITE_4(sc, IWL2100_INTR_MASK, 0);
228 * SW reset before reading EEPROM
230 error = iwl2100_reset(sc);
231 if (error)
232 return error;
234 ifp->if_softc = sc;
235 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
236 ifp->if_init = iwl2100_init;
237 ifp->if_ioctl = iwl2100_ioctl;
238 ifp->if_start = iwl2100_start;
239 ifp->if_watchdog = iwl2100_watchdog;
240 ifq_set_maxlen(&ifp->if_snd, IWL2100_TX_USED_MAX);
241 ifq_set_ready(&ifp->if_snd);
243 #ifdef DUMP_EEPROM
244 device_printf(dev, "eeprom\n");
245 for (i = 0; i < 128; ++i) {
246 if (i != 0 && i % 8 == 0)
247 kprintf("\n");
248 val = iwl_read_eeprom(&sc->iwlcom, i);
249 kprintf("%04x ", val);
251 kprintf("\n");
252 #endif
254 /* IBSS channel mask */
255 sc->sc_ibss_chans = iwl_read_eeprom(&sc->iwlcom,
256 IWL2100_EEPROM_IBSS_CHANS) & IWL2100_CFG_CHANMASK;
258 /* BSS channel mask */
259 sc->sc_bss_chans = iwl_read_eeprom(&sc->iwlcom, IWL2100_EEPROM_CHANS);
262 * Set MAC address
264 for (i = 0; i < ETHER_ADDR_LEN / 2; ++i) {
265 val = iwl_read_eeprom(&sc->iwlcom, IWL2100_EEPROM_MAC + i);
266 ic->ic_myaddr[i * 2] = val >> 8;
267 ic->ic_myaddr[(i * 2) + 1] = val & 0xff;
271 * Set supported channels
273 for (i = 0; i < 14; ++i) {
274 if (sc->sc_bss_chans & (1 << i)) {
275 int chan = i + 1;
277 ic->ic_channels[chan].ic_freq =
278 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
279 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_B;
283 ic->ic_sup_rates[IEEE80211_MODE_11B] = iwl_rateset_11b;
284 ic->ic_phytype = IEEE80211_T_DS;
285 ic->ic_caps = IEEE80211_C_MONITOR |
286 IEEE80211_C_IBSS |
287 IEEE80211_C_SHPREAMBLE |
288 IEEE80211_C_WPA;
289 ic->ic_caps_ext = IEEE80211_CEXT_AUTOSCAN;
290 ic->ic_state = IEEE80211_S_INIT;
291 ic->ic_opmode = IEEE80211_M_STA;
293 ieee80211_ifattach(ic);
296 * ieee80211_frame will be stripped on TX path, so only
297 * extra space needs to be reserved.
299 ic->ic_headroom = sizeof(struct iwl2100_tx_hdr) -
300 sizeof(struct ieee80211_frame);
302 sc->sc_newstate = ic->ic_newstate;
303 ic->ic_newstate = iwl2100_newstate;
305 ieee80211_media_init(ic, iwl2100_media_change, iwl2100_media_status);
307 error = bus_setup_intr(dev, sc->sc_irq_res, INTR_MPSAFE,
308 iwl2100_intr, sc, &sc->sc_irq_handle,
309 ifp->if_serializer);
310 if (error) {
311 device_printf(dev, "can't setup intr\n");
312 ieee80211_ifdetach(ic);
313 return ENXIO;
317 * Attach radio tap
319 bpfattach_dlt(ifp, DLT_IEEE802_11_RADIO,
320 sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th),
321 &sc->sc_drvbpf);
323 sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(uint32_t));
324 sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len);
325 sc->sc_tx_th.wt_ihdr.it_present = htole32(IWL2100_TX_RADIOTAP_PRESENT);
327 sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(uint32_t));
328 sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len);
329 sc->sc_rx_th.wr_ihdr.it_present = htole32(IWL2100_RX_RADIOTAP_PRESENT);
331 sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
332 htole16(IEEE80211_CHAN_B);
335 * Create worker thread and initialize all necessary messages
337 iwl_create_thread(&sc->iwlcom, device_get_unit(dev));
339 iwlmsg_init(&sc->sc_scanend_msg, &netisr_adone_rport,
340 iwl2100_scanend_dispatch, sc);
341 iwlmsg_init(&sc->sc_restart_msg, &netisr_adone_rport,
342 iwl2100_restart_dispatch, sc);
343 iwlmsg_init(&sc->sc_bmiss_msg, &netisr_adone_rport,
344 iwl2100_bmiss_dispatch, sc);
345 iwlmsg_init(&sc->sc_reinit_msg, &netisr_adone_rport,
346 iwl2100_reinit_dispatch, sc);
348 iwlmsg_init(&sc->sc_assoc_msg, &netisr_adone_rport,
349 iwl2100_newstate_dispatch, sc);
350 sc->sc_assoc_msg.iwlm_nstate = IEEE80211_S_ASSOC;
351 sc->sc_assoc_msg.iwlm_arg = -1;
353 iwlmsg_init(&sc->sc_run_msg, &netisr_adone_rport,
354 iwl2100_newstate_dispatch, sc);
355 sc->sc_run_msg.iwlm_nstate = IEEE80211_S_RUN;
356 sc->sc_run_msg.iwlm_arg = -1;
359 * Initialize callouts
361 callout_init(&sc->sc_restart_bmiss);
362 callout_init(&sc->sc_ibss);
363 callout_init(&sc->sc_reinit);
365 /* Add sysctl node */
366 SYSCTL_ADD_UINT(&sc->sc_sysctl_ctx,
367 SYSCTL_CHILDREN(sc->sc_sysctl_tree), OID_AUTO,
368 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "debug flags");
370 if (bootverbose)
371 ieee80211_announce(ic);
372 return 0;
375 void
376 iwl2100_detach(device_t dev)
378 struct iwl2100_softc *sc = device_get_softc(dev);
380 if (device_is_attached(dev)) {
381 struct ifnet *ifp = &sc->sc_ic.ic_if;
383 lwkt_serialize_enter(ifp->if_serializer);
385 sc->sc_flags |= IWL2100_F_DETACH;
386 iwl2100_stop(sc);
387 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_handle);
388 iwl_destroy_thread(&sc->iwlcom);
390 lwkt_serialize_exit(ifp->if_serializer);
392 iwl2100_free_firmware(sc);
394 bpfdetach(ifp);
395 ieee80211_ifdetach(&sc->sc_ic);
397 iwl2100_dma_free(dev);
401 iwl2100_shutdown(device_t dev)
403 struct iwl2100_softc *sc = device_get_softc(dev);
404 struct ifnet *ifp = &sc->sc_ic.ic_if;
406 lwkt_serialize_enter(ifp->if_serializer);
407 iwl2100_stop(sc);
408 lwkt_serialize_exit(ifp->if_serializer);
410 return 0;
413 static void
414 iwl2100_stop(struct iwl2100_softc *sc)
416 struct iwlmsg msg;
418 ASSERT_SERIALIZED(sc->sc_ic.ic_if.if_serializer);
420 iwl2100_stop_callouts(sc);
422 iwlmsg_init(&msg, &sc->sc_reply_port, iwl2100_stop_dispatch, sc);
423 lwkt_domsg(&sc->sc_thread_port, &msg.iwlm_nmsg.nm_lmsg, 0);
426 static void
427 iwl2100_stop_dispatch(struct netmsg *nmsg)
429 struct iwlmsg *msg = (struct iwlmsg *)nmsg;
430 struct iwl2100_softc *sc = msg->iwlm_softc;
432 ASSERT_SERIALIZED(sc->sc_ic.ic_if.if_serializer);
434 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
435 iwl2100_hw_stop(sc);
436 lwkt_replymsg(&nmsg->nm_lmsg, 0);
439 static void
440 iwl2100_hw_stop(struct iwl2100_softc *sc)
442 struct ifnet *ifp = &sc->sc_ic.ic_if;
444 ASSERT_SERIALIZED(ifp->if_serializer);
445 KKASSERT(curthread == &sc->sc_thread);
447 callout_stop(&sc->sc_reinit);
449 /* Disable interrupts */
450 CSR_WRITE_4(sc, IWL2100_INTR_MASK, 0);
453 * HW and SW reset
455 iwl2100_hw_reset(sc);
456 iwl2100_reset(sc);
459 * Free TX/RX rings
461 iwl2100_free_tx_ring(sc);
462 iwl2100_free_rx_ring(sc);
464 /* NOTE: MUST after iwl2100_free_tx_ring() */
465 iwl2100_free_cmd(sc);
467 ifp->if_timer = 0;
468 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
470 sc->sc_tx_timer = 0;
471 sc->sc_flags &= ~(IWL2100_F_WAITCMD |
472 IWL2100_F_INITED |
473 IWL2100_F_SCANNING |
474 IWL2100_F_RESTARTING |
475 IWL2100_F_IFSTART |
476 IWL2100_F_ERROR |
477 IWL2100_F_ZERO_CMD);
480 static int
481 iwl2100_reset(struct iwl2100_softc *sc)
483 int i;
486 * Software reset
488 #define WAIT_MAX 1000
490 CSR_WRITE_4(sc, IWL2100_RESET, IWL2100_RESET_SW);
491 for (i = 0; i < WAIT_MAX; ++i) {
492 DELAY(10);
493 if (CSR_READ_4(sc, IWL2100_RESET) & IWL2100_RESET_DONE)
494 break;
496 if (i == WAIT_MAX) {
497 if_printf(&sc->sc_ic.ic_if, "sw reset timed out\n");
498 return ETIMEDOUT;
501 #undef WAIT_MAX
504 * Move to D0 state, wait clock to become stable
506 #define WAIT_MAX 10000
508 CSR_WRITE_4(sc, IWL2100_CTRL, IWL2100_CTRL_INITDONE);
509 for (i = 0; i < WAIT_MAX; ++i) {
510 DELAY(200);
511 if (CSR_READ_4(sc, IWL2100_CTRL) & IWL2100_CTRL_CLKREADY)
512 break;
514 if (i == WAIT_MAX) {
515 if_printf(&sc->sc_ic.ic_if, "can't stablize clock\n");
516 return ETIMEDOUT;
519 #undef WAIT_MAX
522 * Move to D0 standby
524 CSR_SETBITS_4(sc, IWL2100_CTRL, IWL2100_CTRL_STANDBY);
525 return 0;
528 static int
529 iwl2100_dma_alloc(device_t dev)
531 struct iwl2100_softc *sc = device_get_softc(dev);
532 struct iwl2100_tx_ring *tr = &sc->sc_txring;
533 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
534 int error;
537 * Create top level DMA tag
539 error = bus_dma_tag_create(NULL, 1, 0,
540 BUS_SPACE_MAXADDR_32BIT,
541 BUS_SPACE_MAXADDR,
542 NULL, NULL,
543 MAXBSIZE,
544 BUS_SPACE_UNRESTRICTED,
545 BUS_SPACE_MAXSIZE_32BIT,
546 0, &sc->sc_dtag);
547 if (error) {
548 device_printf(dev, "can't create DMA tag\n");
549 return error;
553 * Create DMA stuffs for TX desc ring
555 error = iwl_dma_mem_create(dev, sc->sc_dtag, IWL2100_TXRING_SIZE,
556 &tr->tr_dtag, (void **)&tr->tr_desc,
557 &tr->tr_paddr, &tr->tr_dmap);
558 if (error) {
559 device_printf(dev, "can't create DMA memory for "
560 "TX desc ring\n");
561 return error;
565 * Create DMA stuffs for RX desc ring
567 error = iwl_dma_mem_create(dev, sc->sc_dtag, IWL2100_RXRING_SIZE,
568 &rr->rr_dtag, (void **)&rr->rr_desc,
569 &rr->rr_paddr, &rr->rr_dmap);
570 if (error) {
571 device_printf(dev, "can't create DMA memory for "
572 "RX desc ring\n");
573 return error;
577 * Create DMA stuffs for RX status ring
579 error = iwl_dma_mem_create(dev, sc->sc_dtag, IWL2100_RXSTATUS_SIZE,
580 &rr->rr_st_dtag, (void **)&rr->rr_status,
581 &rr->rr_st_paddr, &rr->rr_st_dmap);
582 if (error) {
583 device_printf(dev, "can't create DMA memory for "
584 "RX status ring\n");
585 return error;
589 * Create mbuf DMA stuffs
591 error = iwl2100_dma_mbuf_create(dev);
592 if (error)
593 return error;
595 return 0;
598 static void
599 iwl2100_dma_free(device_t dev)
601 struct iwl2100_softc *sc = device_get_softc(dev);
602 struct iwl2100_tx_ring *tr = &sc->sc_txring;
603 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
605 /* Free DMA stuffs for TX desc ring */
606 iwl_dma_mem_destroy(tr->tr_dtag, tr->tr_desc, tr->tr_dmap);
608 /* Free DMA stuffs for RX desc ring */
609 iwl_dma_mem_destroy(rr->rr_dtag, rr->rr_desc, rr->rr_dmap);
611 /* Free DMA stuffs for RX status ring */
612 iwl_dma_mem_destroy(rr->rr_st_dtag, rr->rr_status, rr->rr_st_dmap);
614 /* Free DMA stuffs for mbufs */
615 iwl2100_dma_mbuf_destroy(dev, IWL2100_TX_NDESC, IWL2100_RX_NDESC);
617 /* Free top level DMA tag */
618 if (sc->sc_dtag != NULL)
619 bus_dma_tag_destroy(sc->sc_dtag);
622 static int
623 iwl2100_dma_mbuf_create(device_t dev)
625 struct iwl2100_softc *sc = device_get_softc(dev);
626 struct iwl2100_tx_ring *tr = &sc->sc_txring;
627 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
628 int i, error;
631 * Create mbuf DMA tag
633 error = bus_dma_tag_create(sc->sc_dtag, 1, 0,
634 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
635 NULL, NULL,
636 MCLBYTES, IWL2100_NSEG_MAX,
637 BUS_SPACE_MAXSIZE_32BIT,
638 BUS_DMA_ALLOCNOW, &sc->sc_mbuf_dtag);
639 if (error) {
640 device_printf(dev, "can't create mbuf DMA tag\n");
641 return error;
645 * Create spare DMA map for RX mbufs
647 error = bus_dmamap_create(sc->sc_mbuf_dtag, 0, &rr->rr_tmp_dmap);
648 if (error) {
649 device_printf(dev, "can't create spare mbuf DMA map\n");
650 bus_dma_tag_destroy(sc->sc_mbuf_dtag);
651 sc->sc_mbuf_dtag = NULL;
652 return error;
656 * Create DMA maps for RX mbufs
658 for (i = 0; i < IWL2100_RX_NDESC; ++i) {
659 error = bus_dmamap_create(sc->sc_mbuf_dtag, 0,
660 &rr->rr_buf[i].rb_dmap);
661 if (error) {
662 device_printf(dev, "can't create %d RX mbuf "
663 "for RX ring\n", i);
664 iwl2100_dma_mbuf_destroy(dev, 0, i);
665 return error;
670 * Create DMA maps for TX mbufs
672 for (i = 0; i < IWL2100_TX_NDESC; ++i) {
673 error = bus_dmamap_create(sc->sc_mbuf_dtag, 0,
674 &tr->tr_buf[i].tb_dmap);
675 if (error) {
676 device_printf(dev, "can't create %d TX mbuf "
677 "DMA map\n", i);
678 iwl2100_dma_mbuf_destroy(dev, i, IWL2100_RX_NDESC);
679 return error;
682 return 0;
685 static void
686 iwl2100_dma_mbuf_destroy(device_t dev, int tx_done, int rx_done)
688 struct iwl2100_softc *sc = device_get_softc(dev);
689 struct iwl2100_tx_ring *tr = &sc->sc_txring;
690 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
691 int i;
693 if (sc->sc_mbuf_dtag == NULL)
694 return;
697 * Destroy DMA maps for RX mbufs
699 for (i = 0; i < rx_done; ++i) {
700 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
702 KASSERT(rb->rb_mbuf == NULL, ("RX mbuf is not freed yet\n"));
703 bus_dmamap_destroy(sc->sc_mbuf_dtag, rb->rb_dmap);
707 * Destroy DMA maps for TX mbufs
709 for (i = 0; i < tx_done; ++i) {
710 struct iwl2100_txbuf *tb = &tr->tr_buf[i];
712 KASSERT(tb->tb_mbuf == NULL, ("TX mbuf is not freed yet\n"));
713 bus_dmamap_destroy(sc->sc_mbuf_dtag, tb->tb_dmap);
717 * Destroy spare mbuf DMA map
719 bus_dmamap_destroy(sc->sc_mbuf_dtag, rr->rr_tmp_dmap);
722 * Destroy mbuf DMA tag
724 bus_dma_tag_destroy(sc->sc_mbuf_dtag);
725 sc->sc_mbuf_dtag = NULL;
728 static void
729 iwl2100_init(void *xsc)
731 struct iwl2100_softc *sc = xsc;
732 struct iwlmsg msg;
734 ASSERT_SERIALIZED(sc->sc_ic.ic_if.if_serializer);
736 iwl2100_stop_callouts(sc);
738 iwlmsg_init(&msg, &sc->sc_reply_port, iwl2100_init_dispatch, sc);
739 lwkt_domsg(&sc->sc_thread_port, &msg.iwlm_nmsg.nm_lmsg, 0);
742 static void
743 iwl2100_init_dispatch(struct netmsg *nmsg)
745 struct iwlmsg *msg = (struct iwlmsg *)nmsg;
746 struct iwl2100_softc *sc = msg->iwlm_softc;
747 struct ieee80211com *ic = &sc->sc_ic;
748 struct ifnet *ifp = &ic->ic_if;
749 int error = 0, flags;
751 ASSERT_SERIALIZED(ifp->if_serializer);
753 if (sc->sc_flags & IWL2100_F_DETACH)
754 goto back;
756 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
758 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
760 * XXX
761 * Workaround for dummy firmware:
762 * Don't enable hardware too early, since
763 * once it is enabled, it will start scanning.
765 flags = 0;
766 } else {
767 flags = IWL2100_INIT_F_ENABLE;
770 /* Always put the device into a known state */
771 error = iwl2100_hw_init(sc, NULL,
772 ic->ic_des_essid, ic->ic_des_esslen, flags);
773 if (error)
774 goto back;
776 if (sc->sc_flags & IWL2100_F_ZERO_CMD) {
777 if_printf(ifp, "zero cmd, reinit 1s later\n");
778 iwl2100_hw_stop(sc);
780 callout_reset(&sc->sc_reinit, hz, iwl2100_reinit_callout, sc);
781 goto back;
784 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
785 if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
786 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
787 } else {
788 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
790 back:
791 if (error)
792 iwl2100_stop(sc);
793 lwkt_replymsg(&nmsg->nm_lmsg, error);
796 static int
797 iwl2100_ioctl(struct ifnet *ifp, u_long cmd, caddr_t req, struct ucred *cr)
799 struct iwl2100_softc *sc = ifp->if_softc;
800 int error = 0;
802 ASSERT_SERIALIZED(ifp->if_serializer);
804 if (sc->sc_flags & IWL2100_F_DETACH)
805 return 0;
807 switch (cmd) {
808 case SIOCSIFFLAGS:
809 if (ifp->if_flags & IFF_UP) {
810 if ((ifp->if_flags & IFF_RUNNING) == 0)
811 iwl2100_init(sc);
812 } else {
813 if (ifp->if_flags & IFF_RUNNING) {
814 iwl2100_stop(sc);
815 } else {
817 * Stop callouts explicitly, since
818 * if reinitialization is happening,
819 * IFF_RUNNING will not be turned on.
821 iwl2100_stop_callouts(sc);
824 break;
825 default:
826 error = ieee80211_ioctl(&sc->sc_ic, cmd, req, cr);
827 break;
830 if (error == ENETRESET) {
831 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
832 (IFF_UP | IFF_RUNNING))
833 iwl2100_init(sc);
834 error = 0;
836 return error;
839 static void
840 iwl2100_start(struct ifnet *ifp)
842 struct iwl2100_softc *sc = ifp->if_softc;
843 struct ieee80211com *ic = &sc->sc_ic;
844 struct iwl2100_tx_ring *tr = &sc->sc_txring;
845 int trans = 0;
847 ASSERT_SERIALIZED(ifp->if_serializer);
849 if (sc->sc_flags & IWL2100_F_DETACH)
850 return;
852 if ((ifp->if_flags & (IFF_OACTIVE | IFF_RUNNING)) != IFF_RUNNING)
853 return;
855 if ((sc->sc_flags & IWL2100_F_IFSTART) == 0)
856 goto back;
858 while (tr->tr_used < IWL2100_TX_USED_MAX) {
859 struct ieee80211_frame *wh;
860 struct ieee80211_node *ni;
861 struct ether_header *eh;
862 struct mbuf *m;
864 m = ifq_dequeue(&ifp->if_snd, NULL);
865 if (m == NULL)
866 break;
868 if (m->m_len < sizeof(*eh)) {
869 m = m_pullup(m, sizeof(*eh));
870 if (m == NULL) {
871 ifp->if_oerrors++;
872 continue;
875 eh = mtod(m, struct ether_header *);
877 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
878 if (ni == NULL) {
879 m_freem(m);
880 ifp->if_oerrors++;
881 continue;
884 /* TODO: PS */
886 BPF_MTAP(ifp, m);
888 m = ieee80211_encap(ic, m, ni);
889 if (m == NULL) {
890 ieee80211_free_node(ni);
891 ifp->if_oerrors++;
892 continue;
895 if (ic->ic_rawbpf != NULL)
896 bpf_mtap(ic->ic_rawbpf, m);
898 wh = mtod(m, struct ieee80211_frame *);
899 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
900 if (ieee80211_crypto_encap(ic, ni, m) == NULL) {
901 ieee80211_free_node(ni);
902 m_freem(m);
903 ifp->if_oerrors++;
904 continue;
909 * TX radio tap
911 if (sc->sc_drvbpf != NULL) {
912 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
913 sc->sc_tx_th.wt_flags = IEEE80211_RADIOTAP_F_WEP;
914 else
915 sc->sc_tx_th.wt_flags = 0;
916 bpf_ptap(sc->sc_drvbpf, m, &sc->sc_tx_th,
917 sc->sc_tx_th_len);
919 wh = NULL; /* Catch any invalid use */
921 ieee80211_free_node(ni);
923 if (iwl2100_encap(sc, m)) {
924 ifp->if_oerrors++;
925 continue;
928 ifp->if_opackets++;
929 trans = 1;
932 if (tr->tr_used >= IWL2100_TX_USED_MAX)
933 ifp->if_flags |= IFF_OACTIVE;
935 if (trans) {
936 bus_dmamap_sync(tr->tr_dtag, tr->tr_dmap, BUS_DMASYNC_PREWRITE);
937 CSR_WRITE_4(sc, IWL2100_TXQ_WRITE_IDX, tr->tr_index);
938 sc->sc_tx_timer = 5;
940 back:
941 ieee80211_drain_mgtq(&ic->ic_mgtq);
942 ifp->if_timer = 1;
945 static void
946 iwl2100_watchdog(struct ifnet *ifp)
948 struct iwl2100_softc *sc = ifp->if_softc;
950 ASSERT_SERIALIZED(ifp->if_serializer);
952 if (sc->sc_flags & IWL2100_F_DETACH)
953 return;
955 if (sc->sc_tx_timer) {
956 if (--sc->sc_tx_timer == 0) {
957 if_printf(ifp, "watchdog timeout!\n");
958 ifp->if_oerrors++;
959 iwl2100_restart(sc);
960 return;
961 } else {
962 ifp->if_timer = 1;
965 ieee80211_watchdog(&sc->sc_ic);
968 static int
969 iwl2100_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
971 struct ifnet *ifp = &ic->ic_if;
972 struct iwl2100_softc *sc = ifp->if_softc;
973 struct iwlmsg msg;
975 ASSERT_SERIALIZED(ifp->if_serializer);
977 iwlmsg_init(&msg, &sc->sc_reply_port, iwl2100_newstate_dispatch, sc);
978 msg.iwlm_nstate = nstate;
979 msg.iwlm_arg = arg;
981 return lwkt_domsg(&sc->sc_thread_port, &msg.iwlm_nmsg.nm_lmsg, 0);
984 static void
985 iwl2100_newstate_dispatch(struct netmsg *nmsg)
987 struct iwlmsg *msg = (struct iwlmsg *)nmsg;
988 struct iwl2100_softc *sc = msg->iwlm_softc;
989 struct ieee80211com *ic = &sc->sc_ic;
990 struct ifnet *ifp = &ic->ic_if;
991 enum ieee80211_state nstate, ostate;
992 int arg = msg->iwlm_arg, error = 0;
994 ASSERT_SERIALIZED(ifp->if_serializer);
996 nstate = msg->iwlm_nstate;
997 ostate = ic->ic_state;
999 sc->sc_flags &= ~IWL2100_F_IFSTART;
1000 sc->sc_state_age++;
1002 iwl2100_chan_change(sc, ic->ic_curchan);
1004 callout_stop(&sc->sc_ibss);
1005 iwl2100_restart_done(sc);
1007 if (nstate == IEEE80211_S_INIT)
1008 goto back;
1010 if (sc->sc_flags & IWL2100_F_DETACH) {
1012 * Except for INIT, we skip rest of the
1013 * state changes during detaching
1015 goto reply;
1018 if (ic->ic_opmode == IEEE80211_M_STA) {
1019 if (nstate == IEEE80211_S_AUTH)
1020 error = iwl2100_auth(sc);
1021 else if (nstate == IEEE80211_S_RUN)
1022 sc->sc_flags |= IWL2100_F_IFSTART;
1023 } else if (ic->ic_opmode == IEEE80211_M_IBSS) {
1024 if (nstate == IEEE80211_S_RUN) {
1025 DPRINTF(sc, IWL2100_DBG_IBSS, "%s",
1026 "start/join ibss\n");
1029 * IWL2100_F_IFSTART can't be turned on
1030 * until BSSID generated by the firmware
1031 * is extracted.
1033 * XXX only if we started the IBSS
1035 error = iwl2100_ibss(sc);
1038 back:
1039 if (!error)
1040 error = sc->sc_newstate(ic, nstate, arg);
1042 if (!error) {
1043 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
1045 * Don't use 'nstate' here, since for IBSS
1046 * mode 802.11 layer may enter RUN state in
1047 * a recursive manner, i.e. when we reach
1048 * here, nstate != ic->ic_state
1050 if (ic->ic_state == IEEE80211_S_SCAN &&
1051 ic->ic_state != ostate) {
1052 DPRINTF(sc, IWL2100_DBG_SCAN, "%s",
1053 "start scan\n");
1054 error = iwl2100_scan(sc);
1058 reply:
1059 lwkt_replymsg(&nmsg->nm_lmsg, error);
1062 static int
1063 iwl2100_media_change(struct ifnet *ifp)
1065 int error;
1067 ASSERT_SERIALIZED(ifp->if_serializer);
1069 error = ieee80211_media_change(ifp);
1070 if (error != ENETRESET)
1071 return error;
1073 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
1074 iwl2100_init(ifp->if_softc);
1075 return 0;
1078 static void
1079 iwl2100_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1081 struct iwl2100_softc *sc = ifp->if_softc;
1083 if (sc->sc_flags & IWL2100_F_IFSTART) {
1084 struct ieee80211_node *ni = sc->sc_ic.ic_bss;
1085 uint32_t txrate;
1086 int i, nrates = 4;
1088 txrate = iwl2100_read_ord1(sc, IWL2100_ORD1_TXRATE) & 0xf;
1089 if (ni->ni_rates.rs_nrates < 4)
1090 nrates = ni->ni_rates.rs_nrates;
1092 for (i = 0; i < nrates; ++i) {
1093 if ((1 << i) & txrate)
1094 ni->ni_txrate = i;
1097 ieee80211_media_status(ifp, imr);
1100 static void
1101 iwl2100_intr(void *xsc)
1103 struct iwl2100_softc *sc = xsc;
1104 struct ifnet *ifp = &sc->sc_ic.ic_if;
1105 uint32_t intr_status;
1107 ASSERT_SERIALIZED(ifp->if_serializer);
1109 if ((sc->sc_flags & IWL2100_F_INITED) == 0)
1110 return;
1112 intr_status = CSR_READ_4(sc, IWL2100_INTR_STATUS);
1113 if (intr_status == 0xffffffff) /* not for us */
1114 return;
1116 if ((intr_status & IWL2100_INTRS) == 0) /* not interested */
1117 return;
1119 sc->sc_flags |= IWL2100_F_IN_INTR;
1121 /* Disable interrupts */
1122 CSR_WRITE_4(sc, IWL2100_INTR_MASK, 0);
1124 if (intr_status & IWL2100_INTR_EFATAL) {
1125 uint32_t error_info;
1127 if_printf(ifp, "intr fatal error\n");
1128 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_EFATAL);
1130 error_info = IND_READ_4(sc, IWL2100_IND_ERROR_INFO);
1131 IND_READ_4(sc, error_info & IWL2100_IND_ERRORADDR_MASK);
1133 callout_stop(&sc->sc_reinit);
1134 iwl2100_reinit(sc);
1136 /* Leave interrupts disabled */
1137 goto back;
1140 if (intr_status & IWL2100_INTR_EPARITY) {
1141 if_printf(ifp, "intr parity error\n");
1142 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_EPARITY);
1145 if (intr_status & IWL2100_INTR_RX) {
1146 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_RX);
1147 iwl2100_rxeof(sc);
1148 iwl2100_txeof(sc);
1151 if (intr_status & IWL2100_INTR_TX) {
1152 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_TX);
1153 iwl2100_txeof(sc);
1156 if (intr_status & IWL2100_INTR_FW_INITED)
1157 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_FW_INITED);
1158 if (intr_status & IWL2100_INTR_CMD_DONE)
1159 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, IWL2100_INTR_CMD_DONE);
1161 /* Enable interrupts */
1162 CSR_WRITE_4(sc, IWL2100_INTR_MASK, IWL2100_INTRS);
1163 back:
1164 sc->sc_flags &= ~IWL2100_F_IN_INTR;
1167 static int
1168 iwl2100_hw_reset(struct iwl2100_softc *sc)
1170 int i;
1173 * Initialize GPIO:
1174 * - Enable GPIO3
1175 * - Make GPIO3 firmware writable
1176 * - Enable GPIO1
1177 * - Turn off LED
1179 CSR_WRITE_4(sc, IWL2100_GPIO,
1180 IWL2100_GPIO_3_EN | IWL2100_GPIO_3_FWWR |
1181 IWL2100_GPIO_1_EN | IWL2100_GPIO_LEDOFF);
1184 * Stop master
1186 #define WAIT_MAX 5
1188 CSR_WRITE_4(sc, IWL2100_RESET, IWL2100_RESET_STOP_MASTER);
1189 for (i = 0; i < WAIT_MAX; ++i) {
1190 DELAY(10);
1192 if (CSR_READ_4(sc, IWL2100_RESET) &
1193 IWL2100_RESET_MASTER_STOPPED)
1194 break;
1196 if (i == WAIT_MAX) {
1197 if_printf(&sc->sc_ic.ic_if, "can't stop master\n");
1198 return ETIMEDOUT;
1201 #undef WAIT_MAX
1203 CSR_WRITE_4(sc, IWL2100_RESET, IWL2100_RESET_SW);
1204 return 0;
1207 static int
1208 iwl2100_alloc_firmware(struct iwl2100_softc *sc, enum ieee80211_opmode opmode)
1210 struct {
1211 const char *suffix;
1212 uint16_t mode;
1213 enum ieee80211_opmode opmode;
1214 struct iwl2100_firmware *fw;
1215 } fw_arr[] = {
1216 { "", IWL2100_FW_M_STA, IEEE80211_M_STA,
1217 &sc->sc_fw_sta },
1218 { "-i", IWL2100_FW_M_IBSS, IEEE80211_M_IBSS,
1219 &sc->sc_fw_ibss },
1220 { "-p", IWL2100_FW_M_MONITOR, IEEE80211_M_MONITOR,
1221 &sc->sc_fw_monitor },
1222 { NULL, 0, 0, NULL }
1224 struct ifnet *ifp = &sc->sc_ic.ic_if;
1225 const struct iwl2100_fwimg_hdr *hdr;
1226 struct iwl2100_firmware *fw = NULL;
1227 struct fw_image *image;
1228 char filename[128];
1229 int i, error;
1231 for (i = 0; fw_arr[i].fw != NULL; ++i) {
1232 fw = fw_arr[i].fw;
1234 if (fw_arr[i].opmode == opmode) {
1235 if (fw->fw_image != NULL)
1236 return 0;
1237 else
1238 break;
1241 KASSERT(fw_arr[i].fw != NULL, ("unsupported opmode %u\n", opmode));
1243 ksnprintf(filename, sizeof(filename), IWL2100_FW_PATH,
1244 fw_arr[i].suffix);
1247 * Release the serializer to avoid possible dead lock
1249 lwkt_serialize_exit(ifp->if_serializer);
1250 image = firmware_image_load(filename, NULL);
1251 lwkt_serialize_enter(ifp->if_serializer);
1253 if (image == NULL)
1254 return ENOENT;
1255 fw->fw_image = image;
1258 * Verify the image
1260 error = EINVAL;
1262 hdr = (const struct iwl2100_fwimg_hdr *)image->fw_image;
1263 if ((hdr->version & 0xff) != 1) {
1264 if_printf(ifp, "%s unsupported firmware version %d",
1265 image->fw_name, hdr->version & 0xff);
1266 goto back;
1269 if (hdr->mode != fw_arr[i].mode) {
1270 if_printf(ifp, "%s contains %d mode firmware, should be %d\n",
1271 image->fw_name, hdr->mode, fw_arr[i].mode);
1272 goto back;
1275 if (hdr->data_size + hdr->ucode_size + sizeof(*hdr) !=
1276 image->fw_imglen) {
1277 if_printf(ifp, "%s size mismatch, %u/hdr %u\n", image->fw_name,
1278 fw->fw_image->fw_imglen,
1279 hdr->data_size + hdr->ucode_size + sizeof(*hdr));
1280 goto back;
1283 fw->fw_data = (const uint8_t *)(hdr + 1);
1284 fw->fw_data_size = hdr->data_size;
1285 fw->fw_ucode = fw->fw_data + fw->fw_data_size;
1286 fw->fw_ucode_size = hdr->ucode_size;
1287 error = 0;
1288 back:
1289 if (error) {
1290 firmware_image_unload(fw->fw_image);
1291 bzero(fw, sizeof(*fw));
1293 return error;
1296 static void
1297 iwl2100_free_firmware(struct iwl2100_softc *sc)
1299 struct iwl2100_firmware *fw_arr[] =
1300 { &sc->sc_fw_sta, &sc->sc_fw_ibss, &sc->sc_fw_monitor, NULL };
1301 int i;
1303 for (i = 0; fw_arr[i] != NULL; ++i) {
1304 struct iwl2100_firmware *fw = fw_arr[i];
1306 if (fw->fw_image != NULL) {
1307 firmware_image_unload(fw->fw_image);
1308 bzero(fw, sizeof(*fw));
1313 static int
1314 iwl2100_load_firmware(struct iwl2100_softc *sc, enum ieee80211_opmode opmode)
1316 static const struct {
1317 uint32_t addr;
1318 int size;
1319 } share_mem[] = {
1320 { IWL2100_SHMEM0, IWL2100_SHMEM0_SIZE },
1321 { IWL2100_SHMEM1, IWL2100_SHMEM1_SIZE },
1322 { IWL2100_SHMEM2, IWL2100_SHMEM2_SIZE },
1323 { IWL2100_SHMEM3, IWL2100_SHMEM3_SIZE },
1324 { IWL2100_SHMEM_INTR, IWL2100_SHMEM_INTR_SIZE },
1325 { 0, 0 }
1327 const struct iwl2100_firmware *fw = NULL;
1328 int i, error;
1331 * Pick up the firmware image corresponding to
1332 * the current operation mode
1334 switch (opmode) {
1335 case IEEE80211_M_STA:
1336 fw = &sc->sc_fw_sta;
1337 break;
1338 case IEEE80211_M_IBSS:
1339 fw = &sc->sc_fw_ibss;
1340 break;
1341 case IEEE80211_M_MONITOR:
1342 fw = &sc->sc_fw_monitor;
1343 break;
1344 default:
1345 panic("unsupported opmode %d\n", opmode);
1346 break;
1348 KASSERT(fw->fw_image != NULL,
1349 ("opmode %d firmware image is not allocated yet\n", opmode));
1351 /* Load ucode */
1352 error = iwl2100_load_fw_ucode(sc, fw);
1353 if (error)
1354 return error;
1356 /* SW reset */
1357 error = iwl2100_reset(sc);
1358 if (error)
1359 return error;
1361 /* Load data */
1362 error = iwl2100_load_fw_data(sc, fw);
1363 if (error)
1364 return error;
1366 /* Clear shared memory */
1367 for (i = 0; share_mem[i].size != 0; ++i) {
1368 uint32_t addr = share_mem[i].addr;
1369 int j;
1371 for (j = 0; j < share_mem[i].size; j += 4)
1372 IND_WRITE_4(sc, addr + j, 0);
1375 return 0;
1378 #define IND_WRITE_FLUSH_2(sc, reg, val) \
1379 do { \
1380 IND_WRITE_2((sc), (reg), (val)); \
1381 CSR_READ_4((sc), 0); \
1382 } while (0)
1384 #define IND_WRITE_FLUSH_1(sc, reg, val) \
1385 do { \
1386 IND_WRITE_1((sc), (reg), (val)); \
1387 CSR_READ_4((sc), 0); \
1388 } while (0)
1390 /* XXX need more comment */
1391 static int
1392 iwl2100_load_fw_ucode(struct iwl2100_softc *sc,
1393 const struct iwl2100_firmware *fw)
1395 struct iwl2100_ucode_resp resp;
1396 const uint8_t *p;
1397 int i;
1399 /* Hold ARC */
1400 IND_WRITE_4(sc, IWL2100_IND_HALT, IWL2100_IND_HALT_HOLD);
1402 /* Allow ARC to run */
1403 CSR_WRITE_4(sc, IWL2100_RESET, 0);
1405 IND_WRITE_FLUSH_2(sc, IWL2100_IND_CTRL, 0x703);
1406 IND_WRITE_FLUSH_2(sc, IWL2100_IND_CTRL, 0x707);
1408 IND_WRITE_FLUSH_1(sc, 0x210014, 0x72);
1409 IND_WRITE_FLUSH_1(sc, 0x210014, 0x72);
1411 IND_WRITE_FLUSH_1(sc, 0x210000, 0x40);
1412 IND_WRITE_FLUSH_1(sc, 0x210000, 0);
1413 IND_WRITE_FLUSH_1(sc, 0x210000, 0x40);
1415 p = fw->fw_ucode;
1416 for (i = 0; i < fw->fw_ucode_size; ++i, ++p)
1417 IND_WRITE_1(sc, 0x210010, *p);
1419 IND_WRITE_FLUSH_1(sc, 0x210000, 0);
1420 IND_WRITE_FLUSH_1(sc, 0x210000, 0);
1421 IND_WRITE_FLUSH_1(sc, 0x210000, 0x80);
1424 IND_WRITE_FLUSH_2(sc, IWL2100_IND_CTRL, 0x703);
1425 IND_WRITE_FLUSH_2(sc, IWL2100_IND_CTRL, 0x707);
1427 IND_WRITE_FLUSH_1(sc, 0x210014, 0x72);
1428 IND_WRITE_FLUSH_1(sc, 0x210014, 0x72);
1430 IND_WRITE_FLUSH_1(sc, 0x210000, 0);
1431 IND_WRITE_1(sc, 0x210000, 0x80);
1433 #define WAIT_MAX 10
1434 for (i = 0; i < WAIT_MAX; ++i) {
1435 DELAY(10);
1437 if (IND_READ_1(sc, 0x210000) & 0x1)
1438 break;
1440 if (i == WAIT_MAX) {
1441 if_printf(&sc->sc_ic.ic_if,
1442 "wait ucode symbol init timed out\n");
1443 return ETIMEDOUT;
1445 #undef WAIT_MAX
1447 #define WAIT_MAX 30
1448 for (i = 0; i < WAIT_MAX; ++i) {
1449 uint16_t *r = (uint16_t *)&resp;
1450 int j;
1452 for (j = 0; j < sizeof(resp) / 2; ++j, ++r)
1453 *r = IND_READ_2(sc, 0x210004);
1455 if (resp.cmd_id == 1 && resp.ucode_valid == 1)
1456 break;
1457 DELAY(10);
1459 if (i == WAIT_MAX) {
1460 if_printf(&sc->sc_ic.ic_if,
1461 "wait ucode response timed out\n");
1462 return ETIMEDOUT;
1464 #undef WAIT_MAX
1466 /* Release ARC */
1467 IND_WRITE_4(sc, IWL2100_IND_HALT, 0);
1469 if (bootverbose) {
1470 if_printf(&sc->sc_ic.ic_if, "ucode rev.%d date %d.%d.20%02d "
1471 "time %02d:%02d\n", resp.ucode_rev,
1472 resp.date_time[0], resp.date_time[1],
1473 resp.date_time[2], resp.date_time[3],
1474 resp.date_time[4]);
1477 return 0;
1480 #undef IND_WRITE_FLUSH_1
1481 #undef IND_WRITE_FLUSH_2
1483 static int
1484 iwl2100_load_fw_data(struct iwl2100_softc *sc,
1485 const struct iwl2100_firmware *fw)
1487 const uint8_t *p = fw->fw_data;
1488 int w = 0;
1490 while (w < fw->fw_data_size) {
1491 const struct iwl2100_fwdata_hdr *h;
1492 int hlen, i;
1494 h = (const struct iwl2100_fwdata_hdr *)p;
1495 if (h->len > 32 || h->len == 0) {
1496 if_printf(&sc->sc_ic.ic_if,
1497 "firmware image data corrupted\n");
1498 return EINVAL;
1500 if ((h->addr & 0x3) || (h->len & 0x3)) {
1501 if_printf(&sc->sc_ic.ic_if,
1502 "firmware image data with unaligned "
1503 "address %#x or length %#x\n",
1504 h->addr, h->len);
1505 return EOPNOTSUPP;
1508 hlen = sizeof(*h) + h->len - 1;
1509 if (w + hlen > fw->fw_data_size) {
1510 if_printf(&sc->sc_ic.ic_if,
1511 "firmware image data size mismatch\n");
1512 return EINVAL;
1515 CSR_WRITE_4(sc, IWL2100_AUTOINC_ADDR, h->addr);
1516 for (i = 0; i < h->len; i += 4) {
1517 CSR_WRITE_4(sc, IWL2100_AUTOINC_DATA,
1518 *(const uint32_t *)&h->data[i]);
1521 p += hlen;
1522 w += hlen;
1524 KKASSERT(w == fw->fw_data_size);
1526 return 0;
1529 static void
1530 iwl2100_free_tx_ring(struct iwl2100_softc *sc)
1532 struct iwl2100_tx_ring *tr = &sc->sc_txring;
1533 int i;
1535 for (i = 0; i < IWL2100_TX_NDESC; ++i) {
1536 struct iwl2100_txbuf *tb = &tr->tr_buf[i];
1538 if (tb->tb_mbuf != NULL) {
1539 bus_dmamap_unload(sc->sc_mbuf_dtag, tb->tb_dmap);
1540 if (tb->tb_flags & IWL2100_TBF_CMDBUF) {
1541 KKASSERT(tb->tb_mbuf == sc->sc_cmd);
1542 tb->tb_flags &= ~IWL2100_TBF_CMDBUF;
1543 } else {
1544 m_freem(tb->tb_mbuf);
1546 tb->tb_mbuf = NULL;
1550 bzero(tr->tr_desc, IWL2100_TXRING_SIZE);
1551 bus_dmamap_sync(tr->tr_dtag, tr->tr_dmap, BUS_DMASYNC_PREWRITE);
1553 tr->tr_used = 0;
1554 tr->tr_index = 0;
1555 tr->tr_coll = 0;
1558 static void
1559 iwl2100_free_rx_ring(struct iwl2100_softc *sc)
1561 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
1562 int i;
1564 for (i = 0; i < IWL2100_RX_NDESC; ++i) {
1565 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
1567 if (rb->rb_mbuf != NULL) {
1568 bus_dmamap_unload(sc->sc_mbuf_dtag, rb->rb_dmap);
1569 m_freem(rb->rb_mbuf);
1570 rb->rb_mbuf = NULL;
1574 bzero(rr->rr_desc, IWL2100_RXRING_SIZE);
1575 bus_dmamap_sync(rr->rr_dtag, rr->rr_dmap, BUS_DMASYNC_PREWRITE);
1577 bzero(rr->rr_status, IWL2100_RXSTATUS_SIZE);
1578 bus_dmamap_sync(rr->rr_st_dtag, rr->rr_st_dmap, BUS_DMASYNC_PREWRITE);
1580 rr->rr_index = 0;
1583 static void
1584 iwl2100_free_cmd(struct iwl2100_softc *sc)
1586 if (sc->sc_cmd != NULL) {
1587 m_freem(sc->sc_cmd);
1588 sc->sc_cmd = NULL;
1592 static int
1593 iwl2100_init_tx_ring(struct iwl2100_softc *sc)
1595 struct iwl2100_tx_ring *tr = &sc->sc_txring;
1597 tr->tr_used = 0;
1598 tr->tr_index = 0;
1599 tr->tr_coll = 0;
1601 bzero(tr->tr_desc, IWL2100_TXRING_SIZE);
1602 bus_dmamap_sync(tr->tr_dtag, tr->tr_dmap, BUS_DMASYNC_PREWRITE);
1604 CSR_WRITE_4(sc, IWL2100_TXQ_ADDR, tr->tr_paddr);
1605 CSR_WRITE_4(sc, IWL2100_TXQ_SIZE, IWL2100_TX_NDESC);
1606 CSR_WRITE_4(sc, IWL2100_TXQ_READ_IDX, 0);
1607 CSR_WRITE_4(sc, IWL2100_TXQ_WRITE_IDX, tr->tr_index);
1609 return 0;
1612 static int
1613 iwl2100_init_rx_ring(struct iwl2100_softc *sc)
1615 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
1616 int i, error;
1618 for (i = 0; i < IWL2100_RX_NDESC; ++i) {
1619 error = iwl2100_newbuf(sc, i, 1);
1620 if (error)
1621 return error;
1623 bus_dmamap_sync(rr->rr_st_dtag, rr->rr_st_dmap, BUS_DMASYNC_PREWRITE);
1624 bus_dmamap_sync(rr->rr_dtag, rr->rr_dmap, BUS_DMASYNC_PREWRITE);
1626 rr->rr_index = IWL2100_RX_NDESC - 1;
1628 CSR_WRITE_4(sc, IWL2100_RXQ_ADDR, rr->rr_paddr);
1629 CSR_WRITE_4(sc, IWL2100_RXQ_SIZE, IWL2100_RX_NDESC);
1630 CSR_WRITE_4(sc, IWL2100_RXQ_READ_IDX, 0);
1631 CSR_WRITE_4(sc, IWL2100_RXQ_WRITE_IDX, rr->rr_index);
1633 CSR_WRITE_4(sc, IWL2100_RX_STATUS_ADDR, rr->rr_st_paddr);
1635 return 0;
1638 static int
1639 iwl2100_alloc_cmd(struct iwl2100_softc *sc)
1641 KKASSERT(sc->sc_cmd == NULL);
1643 sc->sc_cmd = m_getcl(MB_WAIT, MT_DATA, M_PKTHDR);
1644 if (sc->sc_cmd == NULL)
1645 return ENOBUFS;
1646 return 0;
1649 static int
1650 iwl2100_newbuf(struct iwl2100_softc *sc, int buf_idx, int init)
1652 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
1653 struct iwl2100_rxbuf *rb;
1654 struct iwl_dmamap_ctx ctx;
1655 bus_dma_segment_t seg;
1656 bus_dmamap_t dmap;
1657 struct mbuf *m;
1658 int error;
1660 KKASSERT(buf_idx < IWL2100_RX_NDESC);
1661 rb = &rr->rr_buf[buf_idx];
1663 m = m_getcl(init ? MB_WAIT : MB_DONTWAIT, MT_DATA, M_PKTHDR);
1664 if (m == NULL) {
1665 error = ENOBUFS;
1667 if (init) {
1668 if_printf(&sc->sc_ic.ic_if, "m_getcl failed\n");
1669 return error;
1670 } else {
1671 goto back;
1674 m->m_len = m->m_pkthdr.len = MCLBYTES;
1677 * Try load RX mbuf into temporary DMA map
1679 ctx.nsegs = 1;
1680 ctx.segs = &seg;
1681 error = bus_dmamap_load_mbuf(sc->sc_mbuf_dtag, rr->rr_tmp_dmap, m,
1682 iwl_dma_buf_addr, &ctx,
1683 init ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT);
1684 if (error || ctx.nsegs == 0) {
1685 if (!error) {
1686 bus_dmamap_unload(sc->sc_mbuf_dtag, rr->rr_tmp_dmap);
1687 error = EFBIG;
1688 if_printf(&sc->sc_ic.ic_if, "too many segments?!\n");
1690 m_freem(m);
1692 if (init) {
1693 if_printf(&sc->sc_ic.ic_if, "can't load RX mbuf\n");
1694 return error;
1695 } else {
1696 goto back;
1700 if (!init)
1701 bus_dmamap_unload(sc->sc_mbuf_dtag, rb->rb_dmap);
1702 rb->rb_mbuf = m;
1703 rb->rb_paddr = seg.ds_addr;
1706 * Swap RX buf's DMA map with the loaded temporary one
1708 dmap = rb->rb_dmap;
1709 rb->rb_dmap = rr->rr_tmp_dmap;
1710 rr->rr_tmp_dmap = dmap;
1712 error = 0;
1713 back:
1714 iwl2100_rxdesc_setup(sc, buf_idx);
1715 return error;
1718 static void
1719 iwl2100_rxdesc_setup(struct iwl2100_softc *sc, int buf_idx)
1721 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
1722 struct iwl2100_rxbuf *rb;
1723 struct iwl2100_desc *d;
1724 struct iwl2100_rx_status *st;
1726 KKASSERT(buf_idx < IWL2100_RX_NDESC);
1727 rb = &rr->rr_buf[buf_idx];
1729 st = &rr->rr_status[buf_idx];
1730 bzero(st, sizeof(*st));
1732 d = &rr->rr_desc[buf_idx];
1733 bzero(d, sizeof(*d));
1734 d->d_paddr = rb->rb_paddr;
1735 d->d_len = MCLBYTES;
1738 static int
1739 iwl2100_init_firmware(struct iwl2100_softc *sc)
1741 struct ifnet *ifp = &sc->sc_ic.ic_if;
1742 uint32_t intr;
1743 int i;
1745 ASSERT_SERIALIZED(ifp->if_serializer);
1747 CSR_WRITE_4(sc, IWL2100_GPIO,
1748 IWL2100_GPIO_3_EN | IWL2100_GPIO_3_FWWR |
1749 IWL2100_GPIO_1_EN | IWL2100_GPIO_LEDOFF);
1750 CSR_WRITE_4(sc, IWL2100_RESET, 0);
1753 * Wait for firmware to be initialized
1755 #define WAIT_MAX 5000
1757 for (i = 0; i < WAIT_MAX; ++i) {
1758 DELAY(8000);
1760 intr = CSR_READ_4(sc, IWL2100_INTR_STATUS);
1761 if (intr & IWL2100_INTR_FW_INITED) {
1762 CSR_WRITE_4(sc, IWL2100_INTR_STATUS,
1763 IWL2100_INTR_FW_INITED);
1764 break;
1766 if (intr & (IWL2100_INTR_EFATAL | IWL2100_INTR_EPARITY)) {
1767 CSR_WRITE_4(sc, IWL2100_INTR_STATUS,
1768 IWL2100_INTR_EFATAL | IWL2100_INTR_EPARITY);
1772 intr = CSR_READ_4(sc, IWL2100_INTR_STATUS) & IWL2100_INTRS;
1773 if (intr & CSR_READ_4(sc, IWL2100_INTR_MASK))
1774 CSR_WRITE_4(sc, IWL2100_INTR_STATUS, intr);
1776 if (i == WAIT_MAX) {
1777 if_printf(&sc->sc_ic.ic_if,
1778 "firmware initialization timed out\n");
1779 return ETIMEDOUT;
1782 #undef WAIT_MAX
1784 /* Enable GPIO1/3 and allow firmware to write to them */
1785 CSR_SETBITS_4(sc, IWL2100_GPIO,
1786 IWL2100_GPIO_1_EN | IWL2100_GPIO_1_FWWR |
1787 IWL2100_GPIO_3_EN | IWL2100_GPIO_3_FWWR);
1788 return 0;
1791 static int
1792 iwl2100_read_ord2(struct iwl2100_softc *sc, uint32_t ofs, void *buf0, int buflen)
1794 uint8_t *buf = buf0;
1795 uint32_t addr, info;
1796 int i, len, ret;
1798 #define IND_ALIGN 4
1799 #define IND_ALIGN_MASK 0x3
1801 addr = IND_READ_4(sc, sc->sc_ord2 + (ofs << 3));
1802 info = IND_READ_4(sc, sc->sc_ord2 + (ofs << 3) + sizeof(addr));
1804 len = info & 0xffff;
1805 i = info >> 16;
1807 if ((len * i) < buflen)
1808 buflen = len * i;
1809 ret = buflen;
1811 i = addr & IND_ALIGN_MASK;
1812 addr &= ~IND_ALIGN_MASK;
1813 if (i) {
1814 int lim, r;
1816 KKASSERT(i < IND_ALIGN);
1817 if (buflen + i < IND_ALIGN)
1818 lim = buflen + i;
1819 else
1820 lim = IND_ALIGN;
1821 r = lim - i;
1823 CSR_WRITE_4(sc, IWL2100_IND_ADDR, addr);
1824 for (; i < lim; ++i, ++buf)
1825 *buf = CSR_READ_1(sc, IWL2100_IND_DATA + i);
1827 KKASSERT(buflen >= r);
1828 buflen -= r;
1829 if (buflen == 0)
1830 goto back;
1832 addr += IND_ALIGN;
1835 len = buflen & ~IND_ALIGN_MASK;
1836 buflen &= IND_ALIGN_MASK;
1838 if (len) {
1839 CSR_WRITE_4(sc, IWL2100_AUTOINC_ADDR, addr);
1840 for (i = 0; i < len; i += 4, addr += 4, buf += 4) {
1841 *((uint32_t *)buf) =
1842 CSR_READ_4(sc, IWL2100_AUTOINC_DATA);
1845 if (buflen) {
1846 CSR_WRITE_4(sc, IWL2100_IND_ADDR, addr);
1847 for (i = 0; i < buflen; ++i, ++buf)
1848 *buf = CSR_READ_1(sc, IWL2100_IND_DATA + i);
1850 back:
1851 return ret;
1853 #undef IND_ALIGN
1854 #undef IND_ALIGN_MASK
1857 static uint32_t
1858 iwl2100_read_ord1(struct iwl2100_softc *sc, uint32_t ofs)
1860 uint32_t addr;
1862 addr = IND_READ_4(sc, sc->sc_ord1 + (ofs << 2));
1863 return IND_READ_4(sc, addr);
1866 static void
1867 iwl2100_write_ord1(struct iwl2100_softc *sc, uint32_t ofs, uint32_t val)
1869 uint32_t addr;
1871 addr = IND_READ_4(sc, sc->sc_ord1 + (ofs << 2));
1872 IND_WRITE_4(sc, addr, val);
1875 static int
1876 iwl2100_rfkilled(struct iwl2100_softc *sc)
1878 int i;
1880 if ((sc->sc_caps & IWL2100_C_RFKILL) == 0)
1881 return 0;
1883 #define TEST_MAX 5
1885 for (i = 0; i < TEST_MAX; ++i) {
1886 DELAY(40);
1888 if (CSR_READ_4(sc, IWL2100_GPIO) & IWL2100_GPIO_RFKILLED)
1889 break;
1891 if (i != TEST_MAX) {
1892 if_printf(&sc->sc_ic.ic_if, "RF killed\n");
1893 return 1;
1896 #undef TEST_MAX
1898 return 0;
1901 static int
1902 iwl2100_set_addr(struct iwl2100_softc *sc, const uint8_t *eaddr)
1904 struct iwl2100_cmd *cmd;
1905 int error;
1907 if (sc->sc_flags & IWL2100_F_WAITCMD) {
1908 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
1909 return EEXIST;
1912 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
1913 bzero(cmd, sizeof(*cmd));
1915 cmd->c_cmd = IWL2100_CMD_SET_ADDR;
1916 cmd->c_param_len = IEEE80211_ADDR_LEN;
1917 IEEE80211_ADDR_COPY(cmd->c_param, eaddr);
1919 error = iwl2100_wait_cmd(sc);
1920 if (error) {
1921 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
1922 return error;
1924 return 0;
1927 static int
1928 iwl2100_set_opmode(struct iwl2100_softc *sc, enum ieee80211_opmode opmode)
1930 struct iwl2100_cmd *cmd;
1931 int error;
1933 if (sc->sc_flags & IWL2100_F_WAITCMD) {
1934 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
1935 return EEXIST;
1938 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
1939 bzero(cmd, sizeof(cmd));
1941 cmd->c_cmd = IWL2100_CMD_SET_OPMODE;
1942 cmd->c_param_len = sizeof(cmd->c_param[0]);
1943 switch (opmode) {
1944 case IEEE80211_M_STA:
1945 cmd->c_param[0] = IWL2100_OPMODE_STA;
1946 break;
1947 case IEEE80211_M_IBSS:
1948 cmd->c_param[0] = IWL2100_OPMODE_IBSS;
1949 break;
1950 case IEEE80211_M_MONITOR:
1951 /* YYY ipw2100 leave this unset */
1952 cmd->c_param[0] = IWL2100_OPMODE_MONITOR;
1953 break;
1954 default:
1955 panic("unsupported opmode %d\n", opmode);
1956 break;
1959 error = iwl2100_wait_cmd(sc);
1960 if (error) {
1961 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
1962 return error;
1964 return 0;
1967 static int
1968 iwl2100_set_80211(struct iwl2100_softc *sc)
1970 struct ieee80211com *ic = &sc->sc_ic;
1971 struct iwl2100_cmd *cmd;
1972 int error;
1974 if (sc->sc_flags & IWL2100_F_WAITCMD) {
1975 if_printf(&ic->ic_if, "there is command pending\n");
1976 return EEXIST;
1979 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
1980 bzero(cmd, sizeof(cmd));
1982 cmd->c_cmd = IWL2100_CMD_SET_80211;
1983 cmd->c_param_len = sizeof(cmd->c_param[0]) * 3;
1984 cmd->c_param[0] = IWL2100_CFG_IBSS | IWL2100_CFG_STA |
1985 IWL2100_CFG_8021X | IWL2100_CFG_AUTO_PREAMBLE;
1986 if (ic->ic_opmode == IEEE80211_M_IBSS)
1987 cmd->c_param[0] |= IWL2100_CFG_IBSS_AUTO_START;
1988 else if (ic->ic_opmode == IEEE80211_M_MONITOR) /* YYY not ipw2100 */
1989 cmd->c_param[0] |= IWL2100_CFG_MONITOR;
1990 cmd->c_param[1] = IWL2100_CFG_CHANMASK; /* XXX sc->sc_bss_chans */
1991 cmd->c_param[2] = IWL2100_CFG_CHANMASK; /* YYY sc->sc_ibss_chans */
1993 error = iwl2100_wait_cmd(sc);
1994 if (error) {
1995 if_printf(&ic->ic_if, "%s failed\n", __func__);
1996 return error;
1998 return 0;
2001 static int
2002 iwl2100_set_basicrates(struct iwl2100_softc *sc)
2004 struct iwl2100_cmd *cmd;
2005 int error;
2007 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2008 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2009 return EEXIST;
2012 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2013 bzero(cmd, sizeof(cmd));
2016 * This configuration does not seem to have any effects
2017 * on probe-req and assoc-req frames.
2019 cmd->c_cmd = IWL2100_CMD_SET_BASICRATES;
2020 cmd->c_param_len = sizeof(cmd->c_param[0]);
2021 cmd->c_param[0] = 0x3; /* 1Mbps and 2Mbps. XXX from caller */
2023 error = iwl2100_wait_cmd(sc);
2024 if (error) {
2025 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2026 return error;
2028 return 0;
2031 static int
2032 iwl2100_set_txrates(struct iwl2100_softc *sc)
2034 struct ieee80211com *ic = &sc->sc_ic;
2035 struct iwl2100_cmd *cmd;
2036 uint32_t rate_mask;
2037 int error;
2039 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2040 if_printf(&ic->ic_if, "there is command pending\n");
2041 return EEXIST;
2044 /* Calculate TX rate mask. XXX let caller do this */
2045 if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
2046 rate_mask = 1 << ic->ic_fixed_rate;
2047 else
2048 rate_mask = 0xf; /* all 11b rates */
2049 KKASSERT((rate_mask & ~0xf) == 0);
2052 * Set TX rates
2054 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2055 bzero(cmd, sizeof(cmd));
2057 cmd->c_cmd = IWL2100_CMD_SET_TXRATES;
2058 cmd->c_param_len = sizeof(cmd->c_param[0]);
2059 cmd->c_param[0] = rate_mask;
2061 error = iwl2100_wait_cmd(sc);
2062 if (error) {
2063 if_printf(&ic->ic_if, "%s failed\n", __func__);
2064 return error;
2068 * Set MSDU TX rates
2070 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2071 bzero(cmd, sizeof(cmd));
2073 cmd->c_cmd = IWL2100_CMD_SET_MSDU_TXRATES;
2074 cmd->c_param_len = sizeof(cmd->c_param[0]);
2075 cmd->c_param[0] = rate_mask;
2077 error = iwl2100_wait_cmd(sc);
2078 if (error) {
2079 if_printf(&ic->ic_if, "%s failed\n", __func__);
2080 return error;
2082 return 0;
2085 static int
2086 iwl2100_set_powersave(struct iwl2100_softc *sc, int on)
2088 struct iwl2100_cmd *cmd;
2089 int error;
2091 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2092 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2093 return EEXIST;
2096 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2097 bzero(cmd, sizeof(cmd));
2099 cmd->c_cmd = IWL2100_CMD_SET_POWERSAVE;
2100 cmd->c_param_len = sizeof(cmd->c_param[0]);
2101 cmd->c_param[0] = on; /* XXX power level? */
2103 error = iwl2100_wait_cmd(sc);
2104 if (error) {
2105 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2106 return error;
2108 return 0;
2111 static int
2112 iwl2100_set_rtsthreshold(struct iwl2100_softc *sc, uint16_t rtsthreshold)
2114 struct iwl2100_cmd *cmd;
2115 int error;
2117 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2118 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2119 return EEXIST;
2122 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2123 bzero(cmd, sizeof(cmd));
2125 cmd->c_cmd = IWL2100_CMD_SET_RTSTHRESHOLD;
2126 cmd->c_param_len = sizeof(cmd->c_param[0]);
2127 if (rtsthreshold == IEEE80211_RTS_MAX) {
2128 /* Disable RTS threshold */
2129 cmd->c_param[0] = IWL2100_RTS_MAX;
2130 } else {
2131 if (rtsthreshold >= IWL2100_RTS_MAX)
2132 rtsthreshold = IWL2100_RTS_MAX - 1;
2133 cmd->c_param[0] = rtsthreshold;
2136 error = iwl2100_wait_cmd(sc);
2137 if (error) {
2138 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2139 return error;
2141 return 0;
2144 static int
2145 iwl2100_set_bssid(struct iwl2100_softc *sc, const uint8_t *bssid)
2147 struct iwl2100_cmd *cmd;
2148 int error;
2150 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2151 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2152 return EEXIST;
2155 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2156 bzero(cmd, sizeof(cmd));
2158 cmd->c_cmd = IWL2100_CMD_SET_BSSID;
2159 if (bssid != NULL) {
2160 cmd->c_param_len = IEEE80211_ADDR_LEN;
2161 IEEE80211_ADDR_COPY(cmd->c_param, bssid);
2164 error = iwl2100_wait_cmd(sc);
2165 if (error) {
2166 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2167 return error;
2169 return 0;
2172 static int
2173 iwl2100_set_essid(struct iwl2100_softc *sc, const uint8_t *essid, int essid_len)
2175 struct iwl2100_cmd *cmd;
2176 int error;
2178 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2179 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2180 return EEXIST;
2183 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2184 bzero(cmd, sizeof(cmd));
2186 cmd->c_cmd = IWL2100_CMD_SET_ESSID;
2187 if (essid != NULL) {
2188 KKASSERT(essid_len <= sizeof(cmd->c_param));
2189 cmd->c_param_len = essid_len;
2190 if (essid_len != 0)
2191 bcopy(essid, cmd->c_param, essid_len);
2194 error = iwl2100_wait_cmd(sc);
2195 if (error) {
2196 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2197 return error;
2199 return 0;
2202 static int
2203 iwl2100_set_auth_ciphers(struct iwl2100_softc *sc,
2204 enum ieee80211_authmode authmode)
2206 struct iwl2100_cmdparam_sec *sec;
2207 struct iwl2100_cmd *cmd;
2208 int error;
2210 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2211 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2212 return EEXIST;
2215 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2216 bzero(cmd, sizeof(cmd));
2218 cmd->c_cmd = IWL2100_CMD_SET_SECURITY;
2219 cmd->c_param_len = sizeof(*sec);
2220 sec = (struct iwl2100_cmdparam_sec *)cmd->c_param;
2222 sec->sec_cipher_mask = IWL2100_CIPHER_NONE |
2223 IWL2100_CIPHER_WEP40 |
2224 IWL2100_CIPHER_TKIP |
2225 IWL2100_CIPHER_CCMP |
2226 IWL2100_CIPHER_WEP104;
2227 if (authmode == IEEE80211_AUTH_SHARED)
2228 sec->sec_authmode = IWL2100_AUTH_SHARED;
2229 else
2230 sec->sec_authmode = IWL2100_AUTH_OPEN;
2232 error = iwl2100_wait_cmd(sc);
2233 if (error) {
2234 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2235 return error;
2237 return 0;
2240 static int
2241 iwl2100_set_wepkey(struct iwl2100_softc *sc, const struct ieee80211_key *k)
2243 struct iwl2100_cmdparam_wepkey *key;
2244 struct iwl2100_cmd *cmd;
2245 int error;
2247 if (k->wk_keylen > IWL2100_KEYDATA_SIZE)
2248 return E2BIG;
2250 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2251 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2252 return EEXIST;
2255 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2256 bzero(cmd, sizeof(cmd));
2258 cmd->c_cmd = IWL2100_CMD_SET_WEPKEY;
2259 cmd->c_param_len = sizeof(*key);
2260 key = (struct iwl2100_cmdparam_wepkey *)cmd->c_param;
2261 key->key_index = k->wk_keyix;
2262 key->key_len = k->wk_keylen;
2263 bcopy(k->wk_key, key->key_data, key->key_len);
2265 error = iwl2100_wait_cmd(sc);
2266 if (error) {
2267 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2268 return error;
2270 return 0;
2273 static int
2274 iwl2100_set_weptxkey(struct iwl2100_softc *sc, ieee80211_keyix txkey)
2276 struct iwl2100_cmd *cmd;
2277 int error;
2279 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2280 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2281 return EEXIST;
2284 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2285 bzero(cmd, sizeof(cmd));
2287 cmd->c_cmd = IWL2100_CMD_SET_WEPTXKEY;
2288 cmd->c_param_len = sizeof(cmd->c_param[0]);
2289 cmd->c_param[0] = txkey;
2291 error = iwl2100_wait_cmd(sc);
2292 if (error) {
2293 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2294 return error;
2296 return 0;
2299 static int
2300 iwl2100_set_privacy(struct iwl2100_softc *sc, int on)
2302 struct iwl2100_cmd *cmd;
2303 int error;
2305 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2306 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2307 return EEXIST;
2310 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2311 bzero(cmd, sizeof(cmd));
2313 cmd->c_cmd = IWL2100_CMD_SET_PRIVACY;
2314 cmd->c_param_len = sizeof(cmd->c_param[0]);
2315 cmd->c_param[0] = on ? IWL2100_PRIVACY_ENABLE : 0;
2317 error = iwl2100_wait_cmd(sc);
2318 if (error) {
2319 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2320 return error;
2322 return 0;
2325 static int
2326 iwl2100_wait_cmd(struct iwl2100_softc *sc)
2328 struct ifnet *ifp = &sc->sc_ic.ic_if;
2329 struct iwl2100_tx_ring *tr = &sc->sc_txring;
2330 struct mbuf *m = sc->sc_cmd;
2331 struct iwl_dmamap_ctx ctx;
2332 bus_dma_segment_t seg;
2333 struct iwl2100_desc *d;
2334 struct iwl2100_txbuf *tb;
2335 int error;
2337 ASSERT_SERIALIZED(ifp->if_serializer);
2339 KKASSERT(tr->tr_index < IWL2100_TX_NDESC);
2340 tb = &tr->tr_buf[tr->tr_index];
2342 ctx.nsegs = 1;
2343 ctx.segs = &seg;
2344 error = bus_dmamap_load_mbuf(sc->sc_mbuf_dtag, tb->tb_dmap, m,
2345 iwl_dma_buf_addr, &ctx, BUS_DMA_WAITOK);
2346 if (error || ctx.nsegs == 0) {
2347 if (!error) {
2348 bus_dmamap_unload(sc->sc_mbuf_dtag, tb->tb_dmap);
2349 error = EFBIG;
2350 if_printf(ifp, "too many segments?!\n");
2353 if_printf(ifp, "can't load RX mbuf\n");
2354 return error;
2356 tb->tb_mbuf = sc->sc_cmd;
2357 tb->tb_flags |= IWL2100_TBF_CMDBUF;
2359 d = &tr->tr_desc[tr->tr_index];
2360 d->d_paddr = seg.ds_addr;
2361 d->d_len = sizeof(struct iwl2100_cmd);
2362 d->d_nfrag = 1;
2363 d->d_flags = IWL2100_TXD_F_INTR | IWL2100_TXD_F_CMD;
2365 KKASSERT(tr->tr_used < IWL2100_TX_NDESC);
2366 ++tr->tr_used;
2367 tr->tr_index = (tr->tr_index + 1) % IWL2100_TX_NDESC;
2369 bus_dmamap_sync(tr->tr_dtag, tr->tr_dmap, BUS_DMASYNC_PREWRITE);
2371 CSR_WRITE_4(sc, IWL2100_TXQ_WRITE_IDX, tr->tr_index);
2373 if (sc->sc_flags & IWL2100_F_IN_INTR)
2374 panic("sleep in interrupt thread\n");
2376 sc->sc_flags |= IWL2100_F_WAITCMD;
2377 error = serialize_sleep(sc, ifp->if_serializer, 0, "iwlcmd", 2 * hz);
2378 if (!error) {
2379 sc->sc_flags &= ~IWL2100_F_WAITCMD;
2380 if (sc->sc_flags & IWL2100_F_ERROR) {
2381 if_printf(ifp, "error happened when waiting "
2382 "command to be done\n");
2383 error = EIO;
2386 return error;
2389 static void
2390 iwl2100_rxeof(struct iwl2100_softc *sc)
2392 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
2393 struct ifnet *ifp = &sc->sc_ic.ic_if;
2394 int hwidx, i;
2396 hwidx = CSR_READ_4(sc, IWL2100_RXQ_READ_IDX);
2397 CSR_READ_4(sc, IWL2100_RXQ_WRITE_IDX);
2399 if (hwidx >= IWL2100_RX_NDESC) {
2400 if_printf(ifp, "invalid hardware RX index %d\n", hwidx);
2401 return;
2404 KKASSERT(rr->rr_index < IWL2100_RX_NDESC);
2405 i = (rr->rr_index + 1) % IWL2100_RX_NDESC;
2406 while (hwidx != i) {
2407 struct iwl2100_rx_status *st = &rr->rr_status[i];
2408 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
2409 int frame_type;
2411 bus_dmamap_sync(rr->rr_st_dtag, rr->rr_st_dmap,
2412 BUS_DMASYNC_POSTREAD);
2413 frame_type = st->r_status & IWL2100_RXS_TYPE_MASK;
2415 bus_dmamap_sync(sc->sc_mbuf_dtag, rb->rb_dmap,
2416 BUS_DMASYNC_POSTREAD);
2417 switch (frame_type) {
2418 case IWL2100_RXS_TYPE_CMD:
2419 iwl2100_rxeof_cmd(sc, i);
2420 break;
2422 case IWL2100_RXS_TYPE_STATUS:
2423 iwl2100_rxeof_status(sc, i);
2424 break;
2426 case IWL2100_RXS_TYPE_NOTE:
2427 iwl2100_rxeof_note(sc, i);
2428 break;
2430 case IWL2100_RXS_TYPE_DATA:
2431 case IWL2100_RXS_TYPE_DATA1:
2432 iwl2100_rxeof_data(sc, i);
2433 break;
2435 default:
2436 if_printf(ifp, "unknown frame type: %d\n", frame_type);
2437 iwl2100_rxdesc_setup(sc, i);
2438 break;
2440 i = (i + 1) % IWL2100_RX_NDESC;
2442 bus_dmamap_sync(rr->rr_st_dtag, rr->rr_st_dmap, BUS_DMASYNC_POSTREAD);
2443 bus_dmamap_sync(rr->rr_dtag, rr->rr_dmap, BUS_DMASYNC_POSTREAD);
2445 if (i == 0)
2446 rr->rr_index = IWL2100_RX_NDESC - 1;
2447 else
2448 rr->rr_index = i - 1;
2449 CSR_WRITE_4(sc, IWL2100_RXQ_WRITE_IDX, rr->rr_index);
2452 static void
2453 iwl2100_txeof(struct iwl2100_softc *sc)
2455 struct iwl2100_tx_ring *tr = &sc->sc_txring;
2456 struct ifnet *ifp = &sc->sc_ic.ic_if;
2457 int hwidx;
2459 hwidx = CSR_READ_4(sc, IWL2100_TXQ_READ_IDX);
2460 CSR_READ_4(sc, IWL2100_TXQ_WRITE_IDX);
2461 if (hwidx >= IWL2100_TX_NDESC) {
2462 if_printf(ifp, "invalid hardware TX index %d\n", hwidx);
2463 return;
2466 KKASSERT(tr->tr_coll < IWL2100_TX_NDESC);
2467 while (tr->tr_used) {
2468 struct iwl2100_txbuf *tb;
2470 if (tr->tr_coll == hwidx)
2471 break;
2473 tb = &tr->tr_buf[tr->tr_coll];
2474 if (tb->tb_mbuf == NULL)
2475 goto next;
2477 bus_dmamap_unload(sc->sc_mbuf_dtag, tb->tb_dmap);
2478 if (tb->tb_flags & IWL2100_TBF_CMDBUF) {
2479 tb->tb_flags &= ~IWL2100_TBF_CMDBUF;
2480 KKASSERT(tb->tb_mbuf == sc->sc_cmd);
2481 } else {
2482 m_freem(tb->tb_mbuf);
2484 tb->tb_mbuf = NULL;
2485 next:
2486 tr->tr_coll = (tr->tr_coll + 1) % IWL2100_TX_NDESC;
2488 KKASSERT(tr->tr_used > 0);
2489 --tr->tr_used;
2492 if (tr->tr_used < IWL2100_TX_USED_MAX) {
2493 if (tr->tr_used == 0) {
2494 KKASSERT(tr->tr_coll == tr->tr_index);
2495 sc->sc_tx_timer = 0;
2498 ifp->if_flags &= ~IFF_OACTIVE;
2499 ifp->if_start(ifp);
2503 static int
2504 iwl2100_config(struct iwl2100_softc *sc, const uint8_t *bssid,
2505 const uint8_t *essid, uint8_t esslen, int ibss_chan)
2507 struct ieee80211com *ic = &sc->sc_ic;
2508 struct ifnet *ifp = &ic->ic_if;
2509 int error;
2511 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
2512 error = iwl2100_set_chan(sc, ic->ic_curchan);
2513 if (error) {
2514 if_printf(ifp, "can't set mon channel\n");
2515 return error;
2519 IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
2520 error = iwl2100_set_addr(sc, ic->ic_myaddr);
2521 if (error) {
2522 if_printf(ifp, "can't set MAC address\n");
2523 return error;
2526 error = iwl2100_set_opmode(sc, ic->ic_opmode);
2527 if (error) {
2528 if_printf(ifp, "can't set opmode\n");
2529 return error;
2532 if (ibss_chan) {
2533 KKASSERT(ic->ic_opmode == IEEE80211_M_IBSS);
2534 error = iwl2100_set_chan(sc, ic->ic_curchan);
2535 if (error) {
2536 if_printf(ifp, "can't set ibss channel\n");
2537 return error;
2541 error = iwl2100_set_80211(sc);
2542 if (error) {
2543 if_printf(ifp, "can't set 802.11 config\n");
2544 return error;
2547 error = iwl2100_set_basicrates(sc);
2548 if (error) {
2549 if_printf(ifp, "can't set basicrates\n");
2550 return error;
2553 error = iwl2100_set_txrates(sc);
2554 if (error) {
2555 if_printf(ifp, "can't set TX rates\n");
2556 return error;
2559 error = iwl2100_set_powersave(sc, ic->ic_flags & IEEE80211_F_PMGTON);
2560 if (error) {
2561 if_printf(ifp, "can't turn off powersave\n");
2562 return error;
2565 error = iwl2100_set_rtsthreshold(sc, ic->ic_rtsthreshold);
2566 if (error) {
2567 if_printf(ifp, "can't set RTS threshold\n");
2568 return error;
2571 error = iwl2100_set_bssid(sc, bssid);
2572 if (error) {
2573 if_printf(ifp, "can't set bssid\n");
2574 return error;
2577 error = iwl2100_set_essid(sc, essid, esslen);
2578 if (error) {
2579 if_printf(ifp, "can't set essid\n");
2580 return error;
2583 error = iwl2100_set_auth_ciphers(sc, ic->ic_bss->ni_authmode);
2584 if (error) {
2585 if_printf(ifp, "can't set authmode and ciphers\n");
2586 return error;
2589 if (ic->ic_flags & IEEE80211_F_PRIVACY) {
2590 ieee80211_keyix txkey = IEEE80211_KEYIX_NONE;
2591 int i;
2593 for (i = 0; i < IEEE80211_WEP_NKID; ++i) {
2594 const struct ieee80211_key *k = &ic->ic_nw_keys[i];
2596 if (k->wk_keyix == IEEE80211_KEYIX_NONE)
2597 continue;
2599 error = iwl2100_set_wepkey(sc, k);
2600 if (error == E2BIG) {
2601 continue;
2602 } else if (error) {
2603 if_printf(ifp, "can't set wepkey\n");
2604 return error;
2606 txkey = k->wk_keyix;
2609 if (txkey != IEEE80211_KEYIX_NONE) {
2611 * Found some valid WEP keys.
2613 * If WEP TX key index from 802.11 layer is not
2614 * set, then use the first valid WEP key as TX
2615 * key.
2617 if (ic->ic_def_txkey != IEEE80211_KEYIX_NONE)
2618 txkey = ic->ic_def_txkey;
2620 error = iwl2100_set_weptxkey(sc, txkey);
2621 if (error) {
2622 if_printf(ifp, "can't set weptxkey\n");
2623 return error;
2628 error = iwl2100_set_privacy(sc, ic->ic_flags & IEEE80211_F_PRIVACY);
2629 if (error) {
2630 if_printf(ifp, "can't set privacy\n");
2631 return error;
2634 error = iwl2100_set_optie(sc, ic->ic_opt_ie, ic->ic_opt_ie_len);
2635 if (error) {
2636 if (error != E2BIG) {
2637 if_printf(ifp, "can't set opt ie\n");
2638 return error;
2642 if (ic->ic_opmode == IEEE80211_M_IBSS) {
2643 error = iwl2100_set_bintval(sc, ic->ic_bss->ni_intval);
2644 if (error) {
2645 if_printf(ifp, "can't set bintval\n");
2646 return error;
2649 error = iwl2100_set_txpower(sc, 32 /* XXX */);
2650 if (error) {
2651 if_printf(ifp, "can't set txpwr\n");
2652 return error;
2655 return 0;
2658 static int
2659 iwl2100_config_op(struct iwl2100_softc *sc, uint32_t op)
2661 struct iwl2100_cmd *cmd;
2662 int error;
2664 KASSERT(op == IWL2100_CMD_CONF_DONE || op == IWL2100_CMD_CONF_START,
2665 ("unknown config_op %u", op));
2667 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2668 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2669 return EEXIST;
2672 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2673 bzero(cmd, sizeof(cmd));
2674 cmd->c_cmd = op;
2676 error = iwl2100_wait_cmd(sc);
2677 if (error) {
2678 if_printf(&sc->sc_ic.ic_if, "%s(%u) failed\n", __func__, op);
2679 return error;
2682 iwl2100_read_ord1(sc, IWL2100_ORD1_CONF_START); /* dummy read */
2683 return 0;
2686 static int
2687 iwl2100_set_chan(struct iwl2100_softc *sc, const struct ieee80211_channel *c)
2689 struct ieee80211com *ic = &sc->sc_ic;
2690 struct iwl2100_cmd *cmd;
2691 u_int chan;
2692 int error;
2694 KKASSERT(ic->ic_opmode != IEEE80211_M_STA);
2696 chan = ieee80211_chan2ieee(ic, c);
2697 if (chan == IEEE80211_CHAN_ANY) {
2698 if_printf(&ic->ic_if, "invalid channel!\n");
2699 return EINVAL;
2702 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2703 if_printf(&ic->ic_if, "there is command pending\n");
2704 return EEXIST;
2707 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2708 bzero(cmd, sizeof(cmd));
2710 cmd->c_cmd = IWL2100_CMD_SET_CHAN;
2711 cmd->c_param_len = sizeof(cmd->c_param[0]);
2712 cmd->c_param[0] = chan;
2714 error = iwl2100_wait_cmd(sc);
2715 if (error) {
2716 if_printf(&ic->ic_if, "%s failed\n", __func__);
2717 return error;
2719 return 0;
2722 static int
2723 iwl2100_set_scanopt(struct iwl2100_softc *sc, uint32_t chans, uint32_t flags)
2725 struct ieee80211com *ic = &sc->sc_ic;
2726 struct iwl2100_cmd *cmd;
2727 int error;
2729 KKASSERT(ic->ic_opmode != IEEE80211_M_MONITOR);
2731 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2732 if_printf(&ic->ic_if, "there is command pending\n");
2733 return EEXIST;
2736 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2737 bzero(cmd, sizeof(cmd));
2740 * NOTE:
2741 * 1) IWL2100_SCANOPT_NOASSOC is ignored by firmware, but same
2742 * function could be achieved by clearing bssid.
2743 * 2) Channel mask is ignored by firmware, if NIC is in STA opmode.
2745 * We leave the correct configuration here just with the hope
2746 * that one day firmware could do better.
2748 cmd->c_cmd = IWL2100_CMD_SET_SCANOPT;
2749 cmd->c_param_len = sizeof(cmd->c_param[0]) * 2;
2750 cmd->c_param[0] = flags | IWL2100_SCANOPT_MIXED;
2751 cmd->c_param[1] = chans;
2753 error = iwl2100_wait_cmd(sc);
2754 if (error) {
2755 if_printf(&ic->ic_if, "%s failed\n", __func__);
2756 return error;
2758 return 0;
2761 static int
2762 iwl2100_set_scan(struct iwl2100_softc *sc)
2764 struct ieee80211com *ic = &sc->sc_ic;
2765 struct iwl2100_cmd *cmd;
2766 int error;
2768 KKASSERT(ic->ic_opmode != IEEE80211_M_MONITOR);
2770 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2771 if_printf(&ic->ic_if, "there is command pending\n");
2772 return EEXIST;
2775 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2776 bzero(cmd, sizeof(cmd));
2778 cmd->c_cmd = IWL2100_CMD_SCAN;
2779 cmd->c_param_len = sizeof(cmd->c_param[0]);
2781 error = iwl2100_wait_cmd(sc);
2782 if (error) {
2783 if_printf(&ic->ic_if, "%s failed\n", __func__);
2784 return error;
2786 return 0;
2789 static int
2790 iwl2100_set_optie(struct iwl2100_softc *sc, void *optie, uint16_t optie_len)
2792 struct iwl2100_cmd *cmd;
2793 struct iwl2100_cmdparam_ie *ie;
2794 int error;
2796 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2797 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2798 return EEXIST;
2801 if (optie_len > IWL2100_OPTIE_MAX) {
2802 if_printf(&sc->sc_ic.ic_if, "optie too long\n");
2803 return E2BIG;
2806 if (optie == NULL || optie_len == 0)
2807 return 0;
2809 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2810 bzero(cmd, sizeof(cmd));
2812 cmd->c_cmd = IWL2100_CMD_SET_IE;
2813 cmd->c_param_len = sizeof(*ie);
2814 ie = (struct iwl2100_cmdparam_ie *)cmd->c_param;
2815 ie->ie_optlen = optie_len;
2816 bcopy(optie, ie->ie_opt, optie_len);
2818 error = iwl2100_wait_cmd(sc);
2819 if (error) {
2820 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2821 return error;
2823 return 0;
2826 static int
2827 iwl2100_set_bintval(struct iwl2100_softc *sc, uint16_t bintval)
2829 struct iwl2100_cmd *cmd;
2830 int error;
2832 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2833 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2834 return EEXIST;
2837 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2838 bzero(cmd, sizeof(cmd));
2840 cmd->c_cmd = IWL2100_CMD_SET_BINTVAL;
2841 cmd->c_param_len = sizeof(cmd->c_param[0]);
2842 cmd->c_param[0] = bintval;
2844 error = iwl2100_wait_cmd(sc);
2845 if (error) {
2846 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2847 return error;
2849 return 0;
2852 static int
2853 iwl2100_set_txpower(struct iwl2100_softc *sc, uint16_t txpower)
2855 struct iwl2100_cmd *cmd;
2856 int error;
2858 if (sc->sc_flags & IWL2100_F_WAITCMD) {
2859 if_printf(&sc->sc_ic.ic_if, "there is command pending\n");
2860 return EEXIST;
2863 cmd = mtod(sc->sc_cmd, struct iwl2100_cmd *);
2864 bzero(cmd, sizeof(cmd));
2866 cmd->c_cmd = IWL2100_CMD_SET_TXPOWER;
2867 cmd->c_param_len = sizeof(cmd->c_param[0]);
2868 cmd->c_param[0] = txpower;
2870 error = iwl2100_wait_cmd(sc);
2871 if (error) {
2872 if_printf(&sc->sc_ic.ic_if, "%s failed\n", __func__);
2873 return error;
2875 return 0;
2878 static void
2879 iwl2100_rxeof_status(struct iwl2100_softc *sc, int i)
2881 struct ieee80211com *ic = &sc->sc_ic;
2882 struct ifnet *ifp = &ic->ic_if;
2883 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
2884 struct iwl2100_rx_status *st = &rr->rr_status[i];
2885 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
2886 struct mbuf *m = rb->rb_mbuf;
2887 uint32_t status;
2889 if (st->r_len != sizeof(status)) {
2890 if_printf(ifp, "invalid status frame len %u\n", st->r_len);
2891 goto back;
2894 if (ic->ic_opmode == IEEE80211_M_MONITOR)
2895 goto back;
2897 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0)
2898 sc->sc_flags &= ~IWL2100_F_SCANNING;
2900 status = *mtod(m, uint32_t *);
2901 DPRINTF(sc, IWL2100_DBG_STATUS, "status 0x%08x\n", status);
2903 switch (status) {
2904 case IWL2100_STATUS_SCANDONE:
2905 if (ic->ic_flags & IEEE80211_F_SCAN) {
2907 * To make sure that firmware has iterated all
2908 * of the channels, we wait for the second scan
2909 * done status change.
2911 if (sc->sc_flags & IWL2100_F_SCANNING) {
2912 iwlmsg_send(&sc->sc_scanend_msg,
2913 &sc->sc_thread_port);
2914 } else {
2915 sc->sc_flags |= IWL2100_F_SCANNING;
2918 break;
2920 case IWL2100_STATUS_RUNNING:
2921 iwl2100_restart_done(sc);
2922 if (ic->ic_state == IEEE80211_S_ASSOC) {
2923 KKASSERT(ic->ic_opmode == IEEE80211_M_STA);
2924 iwlmsg_send(&sc->sc_run_msg, &sc->sc_thread_port);
2925 } else if (ic->ic_state == IEEE80211_S_RUN) {
2926 if (ic->ic_opmode == IEEE80211_M_STA) {
2927 DPRINTF(sc, IWL2100_DBG_RESTART, "%s",
2928 "restart done\n");
2929 sc->sc_flags |= IWL2100_F_IFSTART;
2930 ifp->if_start(ifp);
2931 } else {
2932 KKASSERT(ic->ic_opmode == IEEE80211_M_IBSS);
2933 callout_reset(&sc->sc_ibss, (100 * hz) / 1000,
2934 iwl2100_ibss_bssid, sc);
2937 break;
2939 case IWL2100_STATUS_BMISS:
2940 if (ic->ic_opmode == IEEE80211_M_STA) {
2941 DPRINTF(sc, IWL2100_DBG_SCAN, "%s", "bmiss\n");
2942 iwlmsg_send(&sc->sc_bmiss_msg, &sc->sc_thread_port);
2944 break;
2946 case IWL2100_STATUS_SCANNING:
2947 if (ic->ic_opmode == IEEE80211_M_STA &&
2948 ic->ic_state == IEEE80211_S_RUN) {
2949 /* Firmware error happens */
2950 iwl2100_restart(sc);
2952 break;
2954 back:
2955 iwl2100_rxdesc_setup(sc, i);
2958 static void
2959 iwl2100_rxeof_note(struct iwl2100_softc *sc, int i)
2961 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
2962 struct iwl2100_rx_status *st = &rr->rr_status[i];
2963 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
2964 struct mbuf *m = rb->rb_mbuf;
2965 struct ieee80211com *ic = &sc->sc_ic;
2966 struct iwl2100_note *note;
2968 if (st->r_len < sizeof(*note)) {
2969 if_printf(&ic->ic_if, "invalid note frame len %u\n", st->r_len);
2970 goto back;
2973 if (ic->ic_opmode == IEEE80211_M_MONITOR)
2974 goto back;
2976 note = mtod(m, struct iwl2100_note *);
2977 DPRINTF(sc, IWL2100_DBG_NOTE, "note subtype %u, size %u\n",
2978 note->nt_subtype, note->nt_size);
2980 if (note->nt_subtype == 19 /* XXX */ &&
2981 ic->ic_state == IEEE80211_S_AUTH) {
2982 KKASSERT(ic->ic_opmode == IEEE80211_M_STA);
2983 iwlmsg_send(&sc->sc_assoc_msg, &sc->sc_thread_port);
2985 back:
2986 iwl2100_rxdesc_setup(sc, i);
2989 static void
2990 iwl2100_rxeof_cmd(struct iwl2100_softc *sc, int i)
2992 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
2993 struct iwl2100_rx_status *st = &rr->rr_status[i];
2994 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
2995 struct mbuf *m = rb->rb_mbuf;
2996 struct iwl2100_cmd *cmd;
2998 if (st->r_len != sizeof(*cmd)) {
2999 if_printf(&sc->sc_ic.ic_if,
3000 "invalid cmd done frame len %u\n", st->r_len);
3001 goto back;
3004 cmd = mtod(m, struct iwl2100_cmd *);
3005 DPRINTF(sc, IWL2100_DBG_CMD, "cmd %u\n", cmd->c_cmd);
3006 if (cmd->c_cmd == 0)
3007 sc->sc_flags |= IWL2100_F_ZERO_CMD;
3008 wakeup(sc);
3009 back:
3010 iwl2100_rxdesc_setup(sc, i);
3013 static void
3014 iwl2100_rxeof_data(struct iwl2100_softc *sc, int i)
3016 struct ieee80211com *ic = &sc->sc_ic;
3017 struct ifnet *ifp = &ic->ic_if;
3018 struct iwl2100_rx_ring *rr = &sc->sc_rxring;
3019 struct iwl2100_rx_status *st = &rr->rr_status[i];
3020 struct iwl2100_rxbuf *rb = &rr->rr_buf[i];
3021 struct mbuf *m = rb->rb_mbuf;
3022 struct ieee80211_frame_min *wh;
3023 struct ieee80211_node *ni;
3024 int frame_len, rssi;
3025 const struct ieee80211_channel *c;
3028 * Gather all necessary information from status ring _here_,
3029 * since the following iwl2100_newbuf() will clear them out.
3031 rssi = st->r_rssi;
3032 frame_len = st->r_len;
3034 if (iwl2100_newbuf(sc, i, 0)) {
3035 ifp->if_ierrors++;
3036 return;
3039 c = ic->ic_curchan;
3041 m->m_pkthdr.rcvif = ifp;
3042 m->m_len = m->m_pkthdr.len = frame_len;
3044 wh = mtod(m, struct ieee80211_frame_min *);
3045 ni = ieee80211_find_rxnode(ic, wh);
3048 * RX radio tap
3050 if (sc->sc_drvbpf != NULL) {
3051 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
3052 sc->sc_rx_th.wr_flags = IEEE80211_RADIOTAP_F_WEP;
3053 else
3054 sc->sc_rx_th.wr_flags = 0;
3056 sc->sc_rx_th.wr_antsignal = rssi + IWL2100_NOISE_FLOOR;
3057 sc->sc_rx_th.wr_antnoise = IWL2100_NOISE_FLOOR;
3059 bpf_ptap(sc->sc_drvbpf, m, &sc->sc_rx_th, sc->sc_rx_th_len);
3062 ieee80211_input(ic, m, ni, rssi, 0);
3063 ieee80211_free_node(ni);
3065 if (c != ic->ic_curchan) /* Happen during scanning */
3066 iwl2100_chan_change(sc, ic->ic_curchan);
3069 static void
3070 iwl2100_scanend_dispatch(struct netmsg *nmsg)
3072 struct iwlmsg *msg = (struct iwlmsg *)nmsg;
3073 struct iwl2100_softc *sc = msg->iwlm_softc;
3074 struct ieee80211com *ic = &sc->sc_ic;
3075 struct ifnet *ifp = &ic->ic_if;
3077 ASSERT_SERIALIZED(ifp->if_serializer);
3079 if (sc->sc_flags & IWL2100_F_DETACH)
3080 goto reply;
3082 if (ifp->if_flags & IFF_RUNNING) {
3083 ieee80211_end_scan(ic);
3084 sc->sc_flags &= ~IWL2100_F_SCANNING;
3086 reply:
3087 lwkt_replymsg(&nmsg->nm_lmsg, 0);
3090 static int
3091 iwl2100_hw_init(struct iwl2100_softc *sc, const uint8_t *bssid,
3092 const uint8_t *essid, uint8_t esslen, uint32_t flags)
3094 struct ieee80211com *ic = &sc->sc_ic;
3095 struct ifnet *ifp = &ic->ic_if;
3096 uint32_t db_addr;
3097 int error;
3099 ASSERT_SERIALIZED(ifp->if_serializer);
3100 KKASSERT(curthread == &sc->sc_thread);
3102 iwl2100_hw_stop(sc);
3104 error = iwl2100_alloc_firmware(sc, ic->ic_opmode);
3105 if (error) {
3106 if_printf(ifp, "can't allocate firmware\n");
3107 goto back;
3110 error = iwl2100_load_firmware(sc, ic->ic_opmode);
3111 if (error) {
3112 if_printf(ifp, "can't load firmware\n");
3113 goto back;
3116 error = iwl2100_alloc_cmd(sc);
3117 if (error) {
3118 if_printf(ifp, "can't allocate cmd\n");
3119 goto back;
3122 error = iwl2100_init_tx_ring(sc);
3123 if (error) {
3124 if_printf(ifp, "can't init TX ring\n");
3125 goto back;
3128 error = iwl2100_init_rx_ring(sc);
3129 if (error) {
3130 if_printf(ifp, "can't init RX ring\n");
3131 goto back;
3134 error = iwl2100_init_firmware(sc);
3135 if (error) {
3136 if_printf(ifp, "can't initialize firmware\n");
3137 goto back;
3140 sc->sc_ord1 = CSR_READ_4(sc, IWL2100_ORD1_ADDR);
3141 sc->sc_ord2 = CSR_READ_4(sc, IWL2100_ORD2_ADDR);
3143 db_addr = iwl2100_read_ord1(sc, IWL2100_ORD1_DBADDR);
3144 if ((IND_READ_4(sc, db_addr + 0x20) >> 24) & 0x1)
3145 sc->sc_caps &= ~IWL2100_C_RFKILL;
3146 else
3147 sc->sc_caps |= IWL2100_C_RFKILL;
3149 /* Unlock firmware */
3150 iwl2100_write_ord1(sc, IWL2100_ORD1_FWLOCK, 0);
3152 if (iwl2100_rfkilled(sc)) {
3153 error = ENXIO;
3154 goto back;
3157 /* Let interrupt handler run */
3158 sc->sc_flags |= IWL2100_F_INITED;
3160 /* Enable interrupts */
3161 CSR_WRITE_4(sc, IWL2100_INTR_MASK, IWL2100_INTRS);
3163 error = iwl2100_config(sc, bssid, essid, esslen,
3164 flags & IWL2100_INIT_F_IBSSCHAN);
3165 if (error)
3166 goto back;
3168 if (flags & IWL2100_INIT_F_ENABLE) {
3169 error = iwl2100_config_done(sc);
3170 if (error) {
3171 if_printf(ifp, "can't complete config\n");
3172 goto back;
3176 ifp->if_flags &= ~IFF_OACTIVE;
3177 ifp->if_flags |= IFF_RUNNING;
3178 back:
3179 if (error)
3180 iwl2100_stop(sc);
3181 return error;
3184 static int
3185 iwl2100_start_scan(struct iwl2100_softc *sc, uint32_t chans, uint32_t flags)
3187 int error;
3190 * XXX
3191 * Firmware always starts scanning once config is done
3193 error = iwl2100_set_scanopt(sc, chans, flags);
3194 if (error) {
3195 if_printf(&sc->sc_ic.ic_if, "can't set scan opt\n");
3196 return error;
3199 error = iwl2100_set_scan(sc);
3200 if (error) {
3201 if_printf(&sc->sc_ic.ic_if, "can't set bcast scanning\n");
3202 return error;
3204 return 0;
3207 static int
3208 iwl2100_scan(struct iwl2100_softc *sc)
3210 struct ieee80211com *ic = &sc->sc_ic;
3211 uint32_t chans, flags;
3212 int error;
3214 KKASSERT(ic->ic_opmode != IEEE80211_M_MONITOR);
3216 error = iwl2100_hw_init(sc, NULL,
3217 ic->ic_des_essid, ic->ic_des_esslen, IWL2100_INIT_F_ENABLE);
3218 if (error)
3219 return error;
3221 if (ic->ic_opmode == IEEE80211_M_STA) {
3222 chans = sc->sc_bss_chans;
3223 flags = IWL2100_SCANOPT_NOASSOC;
3224 } else {
3226 * Normally # of IBSS channels is less than BSS's
3227 * but it seems IBSS mode works on all BSS channels
3229 #if 0
3230 chans = sc->sc_ibss_chans;
3231 #else
3232 chans = sc->sc_bss_chans;
3233 #endif
3235 * Don't set NOASSOC scan option, it seems that
3236 * firmware will disable itself after scanning
3237 * if this flag is set. After all, we are in
3238 * IBSS mode, which does not have concept of
3239 * association.
3241 flags = 0;
3244 /* See NOTE in iwl2100_set_scanopt() */
3245 error = iwl2100_start_scan(sc, chans, flags);
3246 if (error)
3247 return error;
3248 return 0;
3251 static int
3252 iwl2100_auth(struct iwl2100_softc *sc)
3254 struct ieee80211com *ic = &sc->sc_ic;
3255 struct ieee80211_node *ni = ic->ic_bss;
3256 u_int chan;
3257 int error;
3259 KKASSERT(ic->ic_opmode == IEEE80211_M_STA);
3261 chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
3262 if (chan == IEEE80211_CHAN_ANY) {
3263 if_printf(&ic->ic_if, "invalid curchan\n");
3264 return EINVAL;
3267 error = iwl2100_hw_init(sc, ni->ni_bssid,
3268 ni->ni_essid, ni->ni_esslen, IWL2100_INIT_F_ENABLE);
3269 if (error)
3270 return error;
3272 /* See NOTE in iwl2100_set_scanopt() */
3273 error = iwl2100_start_scan(sc, 1 << (chan - 1), 0);
3274 if (error)
3275 return error;
3276 return 0;
3279 static int
3280 iwl2100_ibss(struct iwl2100_softc *sc)
3282 struct ieee80211com *ic = &sc->sc_ic;
3283 struct ieee80211_node *ni = ic->ic_bss;
3285 return iwl2100_hw_init(sc, ni->ni_bssid,
3286 ni->ni_essid, ni->ni_esslen,
3287 IWL2100_INIT_F_ENABLE | IWL2100_INIT_F_IBSSCHAN);
3290 static int
3291 iwl2100_encap(struct iwl2100_softc *sc, struct mbuf *m)
3293 struct iwl2100_tx_ring *tr = &sc->sc_txring;
3294 struct iwl2100_tx_hdr *th;
3295 struct ieee80211_frame *wh;
3296 struct iwl_dmamap_ctx ctx;
3297 bus_dma_segment_t segs[IWL2100_NSEG_MAX];
3298 uint8_t src[IEEE80211_ADDR_LEN], dst[IEEE80211_ADDR_LEN];
3299 bus_dmamap_t dmap;
3300 int maxsegs, i, first_idx, last_idx, error, host_enc;
3303 * Save necessary information and strip 802.11 header
3305 wh = mtod(m, struct ieee80211_frame *);
3306 IEEE80211_ADDR_COPY(src, wh->i_addr2);
3307 if (sc->sc_ic.ic_opmode == IEEE80211_M_STA)
3308 IEEE80211_ADDR_COPY(dst, wh->i_addr3);
3309 else
3310 IEEE80211_ADDR_COPY(dst, wh->i_addr1);
3311 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
3312 host_enc = 1;
3313 else
3314 host_enc = 0;
3315 m_adj(m, sizeof(*wh));
3318 * Prepend and setup hardware TX header
3320 M_PREPEND(m, sizeof(*th), MB_DONTWAIT);
3321 if (m == NULL) {
3322 if_printf(&sc->sc_ic.ic_if, "prepend TX header failed\n");
3323 return ENOBUFS;
3325 th = mtod(m, struct iwl2100_tx_hdr *);
3327 bzero(th, sizeof(*th));
3328 th->th_cmd = IWL2100_CMD_TX_DATA;
3329 th->th_host_enc = host_enc;
3330 IEEE80211_ADDR_COPY(th->th_src, src);
3331 IEEE80211_ADDR_COPY(th->th_dst, dst);
3334 * Load mbuf into DMA map
3336 maxsegs = IWL2100_TX_USED_MAX - tr->tr_used;
3337 if (maxsegs > IWL2100_NSEG_MAX)
3338 maxsegs = IWL2100_NSEG_MAX;
3340 KKASSERT(tr->tr_index < IWL2100_TX_NDESC);
3341 first_idx = tr->tr_index;
3342 dmap = tr->tr_buf[first_idx].tb_dmap;
3344 ctx.nsegs = maxsegs;
3345 ctx.segs = segs;
3346 error = bus_dmamap_load_mbuf(sc->sc_mbuf_dtag, dmap, m,
3347 iwl_dma_buf_addr, &ctx, BUS_DMA_NOWAIT);
3348 if (!error && ctx.nsegs == 0) {
3349 bus_dmamap_unload(sc->sc_mbuf_dtag, dmap);
3350 error = EFBIG;
3352 if (error && error != EFBIG) {
3353 if_printf(&sc->sc_ic.ic_if, "can't load TX mbuf, error %d\n",
3354 error);
3355 goto back;
3357 if (error) { /* error == EFBIG */
3358 struct mbuf *m_new;
3360 m_new = m_defrag(m, MB_DONTWAIT);
3361 if (m_new == NULL) {
3362 if_printf(&sc->sc_ic.ic_if, "can't defrag TX mbuf\n");
3363 error = ENOBUFS;
3364 goto back;
3365 } else {
3366 m = m_new;
3369 ctx.nsegs = maxsegs;
3370 ctx.segs = segs;
3371 error = bus_dmamap_load_mbuf(sc->sc_mbuf_dtag, dmap, m,
3372 iwl_dma_buf_addr, &ctx,
3373 BUS_DMA_NOWAIT);
3374 if (error || ctx.nsegs == 0) {
3375 if (ctx.nsegs == 0) {
3376 bus_dmamap_unload(sc->sc_mbuf_dtag, dmap);
3377 error = EFBIG;
3379 if_printf(&sc->sc_ic.ic_if,
3380 "can't load defraged TX mbuf\n");
3381 goto back;
3384 bus_dmamap_sync(sc->sc_mbuf_dtag, dmap, BUS_DMASYNC_PREWRITE);
3387 * Fill TX desc ring
3389 last_idx = -1;
3390 for (i = 0; i < ctx.nsegs; ++i) {
3391 struct iwl2100_desc *d = &tr->tr_desc[tr->tr_index];
3393 d->d_paddr = segs[i].ds_addr;
3394 d->d_len = segs[i].ds_len;
3395 if (i != 0)
3396 d->d_nfrag = 0;
3397 else
3398 d->d_nfrag = ctx.nsegs;
3400 if (i == ctx.nsegs - 1) {
3401 d->d_flags = IWL2100_TXD_F_INTR;
3402 last_idx = tr->tr_index;
3403 } else {
3404 d->d_flags = IWL2100_TXD_F_NOTLAST;
3407 tr->tr_index = (tr->tr_index + 1) % IWL2100_TX_NDESC;
3409 KKASSERT(last_idx >= 0);
3411 tr->tr_buf[first_idx].tb_dmap = tr->tr_buf[last_idx].tb_dmap;
3412 tr->tr_buf[last_idx].tb_dmap = dmap;
3413 tr->tr_buf[last_idx].tb_mbuf = m;
3415 tr->tr_used += ctx.nsegs;
3416 KKASSERT(tr->tr_used <= IWL2100_TX_USED_MAX);
3418 error = 0;
3419 back:
3420 if (error)
3421 m_freem(m);
3422 return error;
3425 static void
3426 iwl2100_restart_dispatch(struct netmsg *nmsg)
3428 struct iwlmsg *msg = (struct iwlmsg *)nmsg;
3429 struct iwl2100_softc *sc = msg->iwlm_softc;
3430 struct ieee80211com *ic = &sc->sc_ic;
3431 struct ifnet *ifp = &ic->ic_if;
3432 int error = 0;
3434 ASSERT_SERIALIZED(ifp->if_serializer);
3436 if (sc->sc_flags & IWL2100_F_DETACH)
3437 goto reply;
3439 if ((ifp->if_flags & IFF_RUNNING) == 0)
3440 goto reply;
3442 if (msg->iwlm_arg != sc->sc_state_age) {
3444 * Restarting was triggered in old 802.11 state
3445 * Don't do anything, this is a staled restarting.
3447 goto reply;
3450 if (ic->ic_state != IEEE80211_S_RUN) {
3451 if_printf(ifp, "restart happened when not in RUN state\n");
3452 goto reply;
3456 * iwl2100_auth() may release slizer, so stop all
3457 * callouts to prevent them from misfiring.
3459 callout_stop(&sc->sc_restart_bmiss);
3460 callout_stop(&sc->sc_ibss);
3462 if (ic->ic_opmode == IEEE80211_M_STA) {
3463 error = iwl2100_auth(sc);
3464 if (error)
3465 goto reply;
3468 * Start software beacon missing to handle missing
3469 * firmware bmiss status change when we restarting
3471 callout_reset(&sc->sc_restart_bmiss, IEEE80211_TU_TO_TICKS(
3472 2 * ic->ic_bmissthreshold * ic->ic_bss->ni_intval),
3473 iwl2100_restart_bmiss, sc);
3474 } else if (ic->ic_opmode == IEEE80211_M_IBSS) {
3475 error = iwl2100_ibss(sc);
3476 if (error)
3477 goto reply;
3480 /* Turn on restarting flag before reply this message */
3481 sc->sc_flags |= IWL2100_F_RESTARTING;
3482 reply:
3483 lwkt_replymsg(&nmsg->nm_lmsg, error);
3486 static void
3487 iwl2100_restart(struct iwl2100_softc *sc)
3489 if ((sc->sc_flags & (IWL2100_F_RESTARTING | IWL2100_F_DETACH)) == 0) {
3490 struct iwlmsg *msg = &sc->sc_restart_msg;
3491 struct lwkt_msg *lmsg = &msg->iwlm_nmsg.nm_lmsg;
3493 DPRINTF(sc, IWL2100_DBG_RESTART, "%s", "restart\n");
3494 if (lmsg->ms_flags & MSGF_DONE) {
3495 sc->sc_flags &= ~IWL2100_F_IFSTART;
3496 msg->iwlm_arg = sc->sc_state_age;
3497 lwkt_sendmsg(&sc->sc_thread_port, lmsg);
3502 static void
3503 iwl2100_bmiss_dispatch(struct netmsg *nmsg)
3505 struct iwlmsg *msg = (struct iwlmsg *)nmsg;
3506 struct iwl2100_softc *sc = msg->iwlm_softc;
3507 struct ieee80211com *ic = &sc->sc_ic;
3508 struct ifnet *ifp = &ic->ic_if;
3510 ASSERT_SERIALIZED(ifp->if_serializer);
3512 if (sc->sc_flags & IWL2100_F_DETACH)
3513 goto reply;
3515 if (ifp->if_flags & IFF_RUNNING) {
3517 * Fake a ic_bmiss_count to make sure that
3518 * ieee80211_beacon_miss() will do its job
3520 ic->ic_bmiss_count = ic->ic_bmiss_max;
3521 ieee80211_beacon_miss(ic);
3523 reply:
3524 lwkt_replymsg(&nmsg->nm_lmsg, 0);
3527 static void
3528 iwl2100_restart_bmiss(void *xsc)
3530 struct iwl2100_softc *sc = xsc;
3531 struct ifnet *ifp = &sc->sc_ic.ic_if;
3533 lwkt_serialize_enter(ifp->if_serializer);
3535 if (sc->sc_flags & IWL2100_F_DETACH)
3536 goto back;
3538 if ((ifp->if_flags & IFF_RUNNING) == 0)
3539 goto back;
3541 if (sc->sc_flags & IWL2100_F_RESTARTING) {
3542 DPRINTF(sc, IWL2100_DBG_SCAN | IWL2100_DBG_RESTART, "%s",
3543 "restart bmiss\n");
3544 iwlmsg_send(&sc->sc_bmiss_msg, &sc->sc_thread_port);
3546 back:
3547 lwkt_serialize_exit(ifp->if_serializer);
3550 static void
3551 iwl2100_ibss_bssid(void *xsc)
3553 struct iwl2100_softc *sc = xsc;
3554 struct ieee80211com *ic = &sc->sc_ic;
3555 struct ifnet *ifp = &ic->ic_if;
3557 lwkt_serialize_enter(ifp->if_serializer);
3559 if (sc->sc_flags & IWL2100_F_DETACH)
3560 goto back;
3562 if ((ifp->if_flags & IFF_RUNNING) == 0)
3563 goto back;
3565 if (ic->ic_state == IEEE80211_S_RUN &&
3566 ic->ic_opmode == IEEE80211_M_IBSS) {
3567 uint8_t bssid[IEEE80211_ADDR_LEN];
3568 int len;
3570 len = iwl2100_read_ord2(sc, IWL2100_ORD2_BSSID,
3571 bssid, sizeof(bssid));
3572 if (len < (int)sizeof(bssid)) {
3573 if_printf(ifp, "can't get IBSS bssid\n");
3574 } else {
3575 DPRINTF(sc, IWL2100_DBG_IBSS, "IBSS bssid: %6D\n",
3576 bssid, ":");
3577 IEEE80211_ADDR_COPY(ic->ic_bss->ni_bssid, bssid);
3579 sc->sc_flags |= IWL2100_F_IFSTART;
3580 ifp->if_start(ifp);
3583 back:
3584 lwkt_serialize_exit(ifp->if_serializer);
3587 static void
3588 iwl2100_reinit(struct iwl2100_softc *sc)
3590 struct ifnet *ifp = &sc->sc_ic.ic_if;
3592 callout_stop(&sc->sc_restart_bmiss);
3593 callout_stop(&sc->sc_ibss);
3595 ifp->if_flags &= ~IFF_RUNNING;
3596 ifp->if_timer = 0;
3598 sc->sc_flags &= ~IWL2100_F_INITED;
3599 sc->sc_tx_timer = 0;
3601 /* Mark error happened, and wake up the pending command */
3602 sc->sc_flags |= IWL2100_F_ERROR;
3603 wakeup(sc);
3605 if ((sc->sc_flags & IWL2100_F_DETACH) == 0) {
3607 * Schedule complete initialization,
3608 * i.e. blow away current state
3610 iwlmsg_send(&sc->sc_reinit_msg, &sc->sc_thread_port);
3614 static void
3615 iwl2100_reinit_dispatch(struct netmsg *nmsg)
3617 struct iwlmsg *msg = (struct iwlmsg *)nmsg;
3618 struct iwl2100_softc *sc = msg->iwlm_softc;
3619 struct ifnet *ifp = &sc->sc_ic.ic_if;
3621 ASSERT_SERIALIZED(ifp->if_serializer);
3624 * NOTE: Reply ASAP, so reinit msg could be used if error intr
3625 * happened again during following iwl2100_init()
3627 lwkt_replymsg(&nmsg->nm_lmsg, 0);
3629 if (sc->sc_flags & IWL2100_F_DETACH)
3630 return;
3632 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
3633 iwl2100_init(sc);
3636 static void
3637 iwl2100_reinit_callout(void *xsc)
3639 struct iwl2100_softc *sc = xsc;
3640 struct ifnet *ifp = &sc->sc_ic.ic_if;
3642 lwkt_serialize_enter(ifp->if_serializer);
3643 if ((sc->sc_flags & IWL2100_F_DETACH) == 0)
3644 iwl2100_reinit(sc);
3645 lwkt_serialize_exit(ifp->if_serializer);
3648 static void
3649 iwl2100_chan_change(struct iwl2100_softc *sc, const struct ieee80211_channel *c)
3651 sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
3652 htole16(c->ic_freq);
3655 static void
3656 iwl2100_stop_callouts(struct iwl2100_softc *sc)
3658 callout_stop(&sc->sc_restart_bmiss);
3659 callout_stop(&sc->sc_ibss);
3660 callout_stop(&sc->sc_reinit);