2 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Sepherosa Ziehau <sepherosa@gmail.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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
34 * $DragonFly: src/sys/dev/netif/iwl/iwl2100.c,v 1.4 2008/05/14 11:59:20 sephe Exp $
37 #include <sys/param.h>
39 #include <sys/endian.h>
40 #include <sys/firmware.h>
41 #include <sys/kernel.h>
42 #include <sys/interrupt.h>
44 #include <sys/module.h>
45 #include <sys/sysctl.h>
46 #include <sys/socket.h>
47 #include <sys/sockio.h>
52 #include <net/if_arp.h>
53 #include <net/ethernet.h>
54 #include <net/if_dl.h>
55 #include <net/if_media.h>
56 #include <net/ifq_var.h>
57 #include <net/netmsg2.h>
59 #include <netproto/802_11/ieee80211_var.h>
60 #include <netproto/802_11/ieee80211_radiotap.h>
62 #include <bus/pci/pcireg.h>
63 #include <bus/pci/pcivar.h>
65 #include "if_iwlvar.h"
66 #include "iwl2100reg.h"
67 #include "iwl2100var.h"
69 #define IWL2100_INIT_F_ENABLE 0x1
70 #define IWL2100_INIT_F_IBSSCHAN 0x2
72 #define sc_tx_th sc_u_tx_th.u_tx_th
73 #define sc_rx_th sc_u_rx_th.u_rx_th
75 static void iwl2100_init(void *);
76 static int iwl2100_ioctl(struct ifnet
*, u_long
, caddr_t
, struct ucred
*);
77 static void iwl2100_start(struct ifnet
*);
78 static void iwl2100_watchdog(struct ifnet
*);
79 static int iwl2100_newstate(struct ieee80211com
*, enum ieee80211_state
, int);
80 static int iwl2100_media_change(struct ifnet
*);
81 static void iwl2100_media_status(struct ifnet
*, struct ifmediareq
*);
82 static void iwl2100_stop(struct iwl2100_softc
*);
83 static void iwl2100_restart(struct iwl2100_softc
*);
84 static void iwl2100_reinit(struct iwl2100_softc
*);
86 static void iwl2100_intr(void *);
87 static void iwl2100_txeof(struct iwl2100_softc
*);
88 static void iwl2100_rxeof(struct iwl2100_softc
*);
89 static void iwl2100_rxeof_status(struct iwl2100_softc
*, int);
90 static void iwl2100_rxeof_note(struct iwl2100_softc
*, int);
91 static void iwl2100_rxeof_cmd(struct iwl2100_softc
*, int);
92 static void iwl2100_rxeof_data(struct iwl2100_softc
*, int);
94 static void iwl2100_init_dispatch(struct netmsg
*);
95 static void iwl2100_reinit_dispatch(struct netmsg
*);
96 static void iwl2100_stop_dispatch(struct netmsg
*);
97 static void iwl2100_newstate_dispatch(struct netmsg
*);
98 static void iwl2100_scanend_dispatch(struct netmsg
*);
99 static void iwl2100_restart_dispatch(struct netmsg
*);
100 static void iwl2100_bmiss_dispatch(struct netmsg
*);
102 static void iwl2100_stop_callouts(struct iwl2100_softc
*);
103 static void iwl2100_restart_bmiss(void *);
104 static void iwl2100_ibss_bssid(void *);
105 static void iwl2100_reinit_callout(void *);
107 static int iwl2100_dma_alloc(device_t
);
108 static void iwl2100_dma_free(device_t
);
109 static int iwl2100_dma_mbuf_create(device_t
);
110 static void iwl2100_dma_mbuf_destroy(device_t
, int, int);
111 static int iwl2100_init_tx_ring(struct iwl2100_softc
*);
112 static int iwl2100_init_rx_ring(struct iwl2100_softc
*);
113 static void iwl2100_free_tx_ring(struct iwl2100_softc
*);
114 static void iwl2100_free_rx_ring(struct iwl2100_softc
*);
116 static int iwl2100_alloc_cmd(struct iwl2100_softc
*);
117 static void iwl2100_free_cmd(struct iwl2100_softc
*);
118 static int iwl2100_wait_cmd(struct iwl2100_softc
*);
120 static void iwl2100_rxdesc_setup(struct iwl2100_softc
*, int);
121 static int iwl2100_newbuf(struct iwl2100_softc
*, int, int);
122 static int iwl2100_encap(struct iwl2100_softc
*, struct mbuf
*);
124 static void iwl2100_chan_change(struct iwl2100_softc
*,
125 const struct ieee80211_channel
*);
127 static int iwl2100_alloc_firmware(struct iwl2100_softc
*,
128 enum ieee80211_opmode
);
129 static void iwl2100_free_firmware(struct iwl2100_softc
*);
130 static int iwl2100_load_firmware(struct iwl2100_softc
*,
131 enum ieee80211_opmode
);
132 static int iwl2100_load_fw_ucode(struct iwl2100_softc
*,
133 const struct iwl2100_firmware
*);
134 static int iwl2100_load_fw_data(struct iwl2100_softc
*,
135 const struct iwl2100_firmware
*);
136 static int iwl2100_init_firmware(struct iwl2100_softc
*);
138 static int iwl2100_read_ord2(struct iwl2100_softc
*, uint32_t,
140 static uint32_t iwl2100_read_ord1(struct iwl2100_softc
*, uint32_t);
141 static void iwl2100_write_ord1(struct iwl2100_softc
*, uint32_t, uint32_t);
143 static int iwl2100_reset(struct iwl2100_softc
*);
144 static int iwl2100_hw_reset(struct iwl2100_softc
*);
145 static int iwl2100_rfkilled(struct iwl2100_softc
*);
147 static int iwl2100_scan(struct iwl2100_softc
*);
148 static int iwl2100_auth(struct iwl2100_softc
*);
149 static int iwl2100_ibss(struct iwl2100_softc
*);
151 static int iwl2100_hw_init(struct iwl2100_softc
*, const uint8_t *,
152 const uint8_t *, uint8_t, uint32_t);
153 static void iwl2100_hw_stop(struct iwl2100_softc
*);
154 static int iwl2100_config(struct iwl2100_softc
*, const uint8_t *,
155 const uint8_t *, uint8_t, int);
156 static int iwl2100_start_scan(struct iwl2100_softc
*, uint32_t, uint32_t);
158 static int iwl2100_config_op(struct iwl2100_softc
*, uint32_t);
159 static int iwl2100_set_addr(struct iwl2100_softc
*, const uint8_t *);
160 static int iwl2100_set_opmode(struct iwl2100_softc
*,
161 enum ieee80211_opmode
);
162 static int iwl2100_set_80211(struct iwl2100_softc
*);
163 static int iwl2100_set_basicrates(struct iwl2100_softc
*);
164 static int iwl2100_set_txrates(struct iwl2100_softc
*);
165 static int iwl2100_set_powersave(struct iwl2100_softc
*, int);
166 static int iwl2100_set_rtsthreshold(struct iwl2100_softc
*, uint16_t);
167 static int iwl2100_set_bssid(struct iwl2100_softc
*, const uint8_t *);
168 static int iwl2100_set_essid(struct iwl2100_softc
*, const uint8_t *, int);
169 static int iwl2100_set_auth_ciphers(struct iwl2100_softc
*,
170 enum ieee80211_authmode
);
171 static int iwl2100_set_wepkey(struct iwl2100_softc
*,
172 const struct ieee80211_key
*);
173 static int iwl2100_set_weptxkey(struct iwl2100_softc
*, ieee80211_keyix
);
174 static int iwl2100_set_privacy(struct iwl2100_softc
*, int);
175 static int iwl2100_set_chan(struct iwl2100_softc
*,
176 const struct ieee80211_channel
*);
177 static int iwl2100_set_scanopt(struct iwl2100_softc
*, uint32_t, uint32_t);
178 static int iwl2100_set_scan(struct iwl2100_softc
*);
179 static int iwl2100_set_optie(struct iwl2100_softc
*, void *, uint16_t);
180 static int iwl2100_set_bintval(struct iwl2100_softc
*, uint16_t);
181 static int iwl2100_set_txpower(struct iwl2100_softc
*, uint16_t);
184 iwl2100_config_done(struct iwl2100_softc
*sc
)
186 return iwl2100_config_op(sc
, IWL2100_CMD_CONF_DONE
);
190 iwl2100_config_start(struct iwl2100_softc
*sc
)
192 return iwl2100_config_op(sc
, IWL2100_CMD_CONF_START
);
196 iwl2100_restart_done(struct iwl2100_softc
*sc
)
198 callout_stop(&sc
->sc_restart_bmiss
);
199 sc
->sc_flags
&= ~IWL2100_F_RESTARTING
;
203 iwl2100_attach(device_t dev
)
205 struct iwl2100_softc
*sc
= device_get_softc(dev
);
206 struct ieee80211com
*ic
= &sc
->sc_ic
;
207 struct ifnet
*ifp
= &ic
->ic_if
;
213 * Clear the retry timeout PCI configuration register to keep
214 * PCI TX retries from interfering with C3 CPU state.
216 pci_write_config(dev
, IWL2100_PCIR_RETRY_TIMEOUT
, 0, 1);
219 * Allocate DMA stuffs
221 error
= iwl2100_dma_alloc(dev
);
225 /* Disable interrupts */
226 CSR_WRITE_4(sc
, IWL2100_INTR_MASK
, 0);
229 * SW reset before reading EEPROM
231 error
= iwl2100_reset(sc
);
236 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
237 ifp
->if_init
= iwl2100_init
;
238 ifp
->if_ioctl
= iwl2100_ioctl
;
239 ifp
->if_start
= iwl2100_start
;
240 ifp
->if_watchdog
= iwl2100_watchdog
;
241 ifq_set_maxlen(&ifp
->if_snd
, IWL2100_TX_USED_MAX
);
242 ifq_set_ready(&ifp
->if_snd
);
245 device_printf(dev
, "eeprom\n");
246 for (i
= 0; i
< 128; ++i
) {
247 if (i
!= 0 && i
% 8 == 0)
249 val
= iwl_read_eeprom(&sc
->iwlcom
, i
);
250 kprintf("%04x ", val
);
255 /* IBSS channel mask */
256 sc
->sc_ibss_chans
= iwl_read_eeprom(&sc
->iwlcom
,
257 IWL2100_EEPROM_IBSS_CHANS
) & IWL2100_CFG_CHANMASK
;
259 /* BSS channel mask */
260 sc
->sc_bss_chans
= iwl_read_eeprom(&sc
->iwlcom
, IWL2100_EEPROM_CHANS
);
265 for (i
= 0; i
< ETHER_ADDR_LEN
/ 2; ++i
) {
266 val
= iwl_read_eeprom(&sc
->iwlcom
, IWL2100_EEPROM_MAC
+ i
);
267 ic
->ic_myaddr
[i
* 2] = val
>> 8;
268 ic
->ic_myaddr
[(i
* 2) + 1] = val
& 0xff;
272 * Set supported channels
274 for (i
= 0; i
< 14; ++i
) {
275 if (sc
->sc_bss_chans
& (1 << i
)) {
278 ic
->ic_channels
[chan
].ic_freq
=
279 ieee80211_ieee2mhz(chan
, IEEE80211_CHAN_2GHZ
);
280 ic
->ic_channels
[chan
].ic_flags
= IEEE80211_CHAN_B
;
284 ic
->ic_sup_rates
[IEEE80211_MODE_11B
] = iwl_rateset_11b
;
285 ic
->ic_phytype
= IEEE80211_T_DS
;
286 ic
->ic_caps
= IEEE80211_C_MONITOR
|
288 IEEE80211_C_SHPREAMBLE
|
290 ic
->ic_caps_ext
= IEEE80211_CEXT_AUTOSCAN
;
291 ic
->ic_state
= IEEE80211_S_INIT
;
292 ic
->ic_opmode
= IEEE80211_M_STA
;
294 ieee80211_ifattach(ic
);
297 * ieee80211_frame will be stripped on TX path, so only
298 * extra space needs to be reserved.
300 ic
->ic_headroom
= sizeof(struct iwl2100_tx_hdr
) -
301 sizeof(struct ieee80211_frame
);
303 sc
->sc_newstate
= ic
->ic_newstate
;
304 ic
->ic_newstate
= iwl2100_newstate
;
306 ieee80211_media_init(ic
, iwl2100_media_change
, iwl2100_media_status
);
308 error
= bus_setup_intr(dev
, sc
->sc_irq_res
, INTR_MPSAFE
,
309 iwl2100_intr
, sc
, &sc
->sc_irq_handle
,
312 device_printf(dev
, "can't setup intr\n");
313 ieee80211_ifdetach(ic
);
317 ifp
->if_cpuid
= ithread_cpuid(rman_get_start(sc
->sc_irq_res
));
318 KKASSERT(ifp
->if_cpuid
>= 0 && ifp
->if_cpuid
< ncpus
);
323 bpfattach_dlt(ifp
, DLT_IEEE802_11_RADIO
,
324 sizeof(struct ieee80211_frame
) + sizeof(sc
->sc_tx_th
),
327 sc
->sc_tx_th_len
= roundup(sizeof(sc
->sc_tx_th
), sizeof(uint32_t));
328 sc
->sc_tx_th
.wt_ihdr
.it_len
= htole16(sc
->sc_tx_th_len
);
329 sc
->sc_tx_th
.wt_ihdr
.it_present
= htole32(IWL2100_TX_RADIOTAP_PRESENT
);
331 sc
->sc_rx_th_len
= roundup(sizeof(sc
->sc_rx_th
), sizeof(uint32_t));
332 sc
->sc_rx_th
.wr_ihdr
.it_len
= htole16(sc
->sc_rx_th_len
);
333 sc
->sc_rx_th
.wr_ihdr
.it_present
= htole32(IWL2100_RX_RADIOTAP_PRESENT
);
335 sc
->sc_tx_th
.wt_chan_flags
= sc
->sc_rx_th
.wr_chan_flags
=
336 htole16(IEEE80211_CHAN_B
);
339 * Create worker thread and initialize all necessary messages
341 iwl_create_thread(&sc
->iwlcom
, device_get_unit(dev
));
343 iwlmsg_init(&sc
->sc_scanend_msg
, &netisr_adone_rport
,
344 iwl2100_scanend_dispatch
, sc
);
345 iwlmsg_init(&sc
->sc_restart_msg
, &netisr_adone_rport
,
346 iwl2100_restart_dispatch
, sc
);
347 iwlmsg_init(&sc
->sc_bmiss_msg
, &netisr_adone_rport
,
348 iwl2100_bmiss_dispatch
, sc
);
349 iwlmsg_init(&sc
->sc_reinit_msg
, &netisr_adone_rport
,
350 iwl2100_reinit_dispatch
, sc
);
352 iwlmsg_init(&sc
->sc_assoc_msg
, &netisr_adone_rport
,
353 iwl2100_newstate_dispatch
, sc
);
354 sc
->sc_assoc_msg
.iwlm_nstate
= IEEE80211_S_ASSOC
;
355 sc
->sc_assoc_msg
.iwlm_arg
= -1;
357 iwlmsg_init(&sc
->sc_run_msg
, &netisr_adone_rport
,
358 iwl2100_newstate_dispatch
, sc
);
359 sc
->sc_run_msg
.iwlm_nstate
= IEEE80211_S_RUN
;
360 sc
->sc_run_msg
.iwlm_arg
= -1;
363 * Initialize callouts
365 callout_init(&sc
->sc_restart_bmiss
);
366 callout_init(&sc
->sc_ibss
);
367 callout_init(&sc
->sc_reinit
);
369 /* Add sysctl node */
370 SYSCTL_ADD_UINT(&sc
->sc_sysctl_ctx
,
371 SYSCTL_CHILDREN(sc
->sc_sysctl_tree
), OID_AUTO
,
372 "debug", CTLFLAG_RW
, &sc
->sc_debug
, 0, "debug flags");
375 ieee80211_announce(ic
);
380 iwl2100_detach(device_t dev
)
382 struct iwl2100_softc
*sc
= device_get_softc(dev
);
384 if (device_is_attached(dev
)) {
385 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
387 lwkt_serialize_enter(ifp
->if_serializer
);
389 sc
->sc_flags
|= IWL2100_F_DETACH
;
391 bus_teardown_intr(dev
, sc
->sc_irq_res
, sc
->sc_irq_handle
);
392 iwl_destroy_thread(&sc
->iwlcom
);
394 lwkt_serialize_exit(ifp
->if_serializer
);
396 iwl2100_free_firmware(sc
);
399 ieee80211_ifdetach(&sc
->sc_ic
);
401 iwl2100_dma_free(dev
);
405 iwl2100_shutdown(device_t dev
)
407 struct iwl2100_softc
*sc
= device_get_softc(dev
);
408 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
410 lwkt_serialize_enter(ifp
->if_serializer
);
412 lwkt_serialize_exit(ifp
->if_serializer
);
418 iwl2100_stop(struct iwl2100_softc
*sc
)
422 ASSERT_SERIALIZED(sc
->sc_ic
.ic_if
.if_serializer
);
424 iwl2100_stop_callouts(sc
);
426 iwlmsg_init(&msg
, &sc
->sc_reply_port
, iwl2100_stop_dispatch
, sc
);
427 lwkt_domsg(&sc
->sc_thread_port
, &msg
.iwlm_nmsg
.nm_lmsg
, 0);
431 iwl2100_stop_dispatch(struct netmsg
*nmsg
)
433 struct iwlmsg
*msg
= (struct iwlmsg
*)nmsg
;
434 struct iwl2100_softc
*sc
= msg
->iwlm_softc
;
436 ASSERT_SERIALIZED(sc
->sc_ic
.ic_if
.if_serializer
);
438 ieee80211_new_state(&sc
->sc_ic
, IEEE80211_S_INIT
, -1);
440 lwkt_replymsg(&nmsg
->nm_lmsg
, 0);
444 iwl2100_hw_stop(struct iwl2100_softc
*sc
)
446 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
448 ASSERT_SERIALIZED(ifp
->if_serializer
);
449 KKASSERT(curthread
== &sc
->sc_thread
);
451 callout_stop(&sc
->sc_reinit
);
453 /* Disable interrupts */
454 CSR_WRITE_4(sc
, IWL2100_INTR_MASK
, 0);
459 iwl2100_hw_reset(sc
);
465 iwl2100_free_tx_ring(sc
);
466 iwl2100_free_rx_ring(sc
);
468 /* NOTE: MUST after iwl2100_free_tx_ring() */
469 iwl2100_free_cmd(sc
);
472 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
475 sc
->sc_flags
&= ~(IWL2100_F_WAITCMD
|
478 IWL2100_F_RESTARTING
|
485 iwl2100_reset(struct iwl2100_softc
*sc
)
492 #define WAIT_MAX 1000
494 CSR_WRITE_4(sc
, IWL2100_RESET
, IWL2100_RESET_SW
);
495 for (i
= 0; i
< WAIT_MAX
; ++i
) {
497 if (CSR_READ_4(sc
, IWL2100_RESET
) & IWL2100_RESET_DONE
)
501 if_printf(&sc
->sc_ic
.ic_if
, "sw reset timed out\n");
508 * Move to D0 state, wait clock to become stable
510 #define WAIT_MAX 10000
512 CSR_WRITE_4(sc
, IWL2100_CTRL
, IWL2100_CTRL_INITDONE
);
513 for (i
= 0; i
< WAIT_MAX
; ++i
) {
515 if (CSR_READ_4(sc
, IWL2100_CTRL
) & IWL2100_CTRL_CLKREADY
)
519 if_printf(&sc
->sc_ic
.ic_if
, "can't stablize clock\n");
528 CSR_SETBITS_4(sc
, IWL2100_CTRL
, IWL2100_CTRL_STANDBY
);
533 iwl2100_dma_alloc(device_t dev
)
535 struct iwl2100_softc
*sc
= device_get_softc(dev
);
536 struct iwl2100_tx_ring
*tr
= &sc
->sc_txring
;
537 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
541 * Create top level DMA tag
543 error
= bus_dma_tag_create(NULL
, 1, 0,
544 BUS_SPACE_MAXADDR_32BIT
,
548 BUS_SPACE_UNRESTRICTED
,
549 BUS_SPACE_MAXSIZE_32BIT
,
552 device_printf(dev
, "can't create DMA tag\n");
557 * Create DMA stuffs for TX desc ring
559 error
= iwl_dma_mem_create(dev
, sc
->sc_dtag
, IWL2100_TXRING_SIZE
,
560 &tr
->tr_dtag
, (void **)&tr
->tr_desc
,
561 &tr
->tr_paddr
, &tr
->tr_dmap
);
563 device_printf(dev
, "can't create DMA memory for "
569 * Create DMA stuffs for RX desc ring
571 error
= iwl_dma_mem_create(dev
, sc
->sc_dtag
, IWL2100_RXRING_SIZE
,
572 &rr
->rr_dtag
, (void **)&rr
->rr_desc
,
573 &rr
->rr_paddr
, &rr
->rr_dmap
);
575 device_printf(dev
, "can't create DMA memory for "
581 * Create DMA stuffs for RX status ring
583 error
= iwl_dma_mem_create(dev
, sc
->sc_dtag
, IWL2100_RXSTATUS_SIZE
,
584 &rr
->rr_st_dtag
, (void **)&rr
->rr_status
,
585 &rr
->rr_st_paddr
, &rr
->rr_st_dmap
);
587 device_printf(dev
, "can't create DMA memory for "
593 * Create mbuf DMA stuffs
595 error
= iwl2100_dma_mbuf_create(dev
);
603 iwl2100_dma_free(device_t dev
)
605 struct iwl2100_softc
*sc
= device_get_softc(dev
);
606 struct iwl2100_tx_ring
*tr
= &sc
->sc_txring
;
607 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
609 /* Free DMA stuffs for TX desc ring */
610 iwl_dma_mem_destroy(tr
->tr_dtag
, tr
->tr_desc
, tr
->tr_dmap
);
612 /* Free DMA stuffs for RX desc ring */
613 iwl_dma_mem_destroy(rr
->rr_dtag
, rr
->rr_desc
, rr
->rr_dmap
);
615 /* Free DMA stuffs for RX status ring */
616 iwl_dma_mem_destroy(rr
->rr_st_dtag
, rr
->rr_status
, rr
->rr_st_dmap
);
618 /* Free DMA stuffs for mbufs */
619 iwl2100_dma_mbuf_destroy(dev
, IWL2100_TX_NDESC
, IWL2100_RX_NDESC
);
621 /* Free top level DMA tag */
622 if (sc
->sc_dtag
!= NULL
)
623 bus_dma_tag_destroy(sc
->sc_dtag
);
627 iwl2100_dma_mbuf_create(device_t dev
)
629 struct iwl2100_softc
*sc
= device_get_softc(dev
);
630 struct iwl2100_tx_ring
*tr
= &sc
->sc_txring
;
631 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
635 * Create mbuf DMA tag
637 error
= bus_dma_tag_create(sc
->sc_dtag
, 1, 0,
638 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
640 MCLBYTES
, IWL2100_NSEG_MAX
,
641 BUS_SPACE_MAXSIZE_32BIT
,
642 BUS_DMA_ALLOCNOW
, &sc
->sc_mbuf_dtag
);
644 device_printf(dev
, "can't create mbuf DMA tag\n");
649 * Create spare DMA map for RX mbufs
651 error
= bus_dmamap_create(sc
->sc_mbuf_dtag
, 0, &rr
->rr_tmp_dmap
);
653 device_printf(dev
, "can't create spare mbuf DMA map\n");
654 bus_dma_tag_destroy(sc
->sc_mbuf_dtag
);
655 sc
->sc_mbuf_dtag
= NULL
;
660 * Create DMA maps for RX mbufs
662 for (i
= 0; i
< IWL2100_RX_NDESC
; ++i
) {
663 error
= bus_dmamap_create(sc
->sc_mbuf_dtag
, 0,
664 &rr
->rr_buf
[i
].rb_dmap
);
666 device_printf(dev
, "can't create %d RX mbuf "
668 iwl2100_dma_mbuf_destroy(dev
, 0, i
);
674 * Create DMA maps for TX mbufs
676 for (i
= 0; i
< IWL2100_TX_NDESC
; ++i
) {
677 error
= bus_dmamap_create(sc
->sc_mbuf_dtag
, 0,
678 &tr
->tr_buf
[i
].tb_dmap
);
680 device_printf(dev
, "can't create %d TX mbuf "
682 iwl2100_dma_mbuf_destroy(dev
, i
, IWL2100_RX_NDESC
);
690 iwl2100_dma_mbuf_destroy(device_t dev
, int tx_done
, int rx_done
)
692 struct iwl2100_softc
*sc
= device_get_softc(dev
);
693 struct iwl2100_tx_ring
*tr
= &sc
->sc_txring
;
694 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
697 if (sc
->sc_mbuf_dtag
== NULL
)
701 * Destroy DMA maps for RX mbufs
703 for (i
= 0; i
< rx_done
; ++i
) {
704 struct iwl2100_rxbuf
*rb
= &rr
->rr_buf
[i
];
706 KASSERT(rb
->rb_mbuf
== NULL
, ("RX mbuf is not freed yet\n"));
707 bus_dmamap_destroy(sc
->sc_mbuf_dtag
, rb
->rb_dmap
);
711 * Destroy DMA maps for TX mbufs
713 for (i
= 0; i
< tx_done
; ++i
) {
714 struct iwl2100_txbuf
*tb
= &tr
->tr_buf
[i
];
716 KASSERT(tb
->tb_mbuf
== NULL
, ("TX mbuf is not freed yet\n"));
717 bus_dmamap_destroy(sc
->sc_mbuf_dtag
, tb
->tb_dmap
);
721 * Destroy spare mbuf DMA map
723 bus_dmamap_destroy(sc
->sc_mbuf_dtag
, rr
->rr_tmp_dmap
);
726 * Destroy mbuf DMA tag
728 bus_dma_tag_destroy(sc
->sc_mbuf_dtag
);
729 sc
->sc_mbuf_dtag
= NULL
;
733 iwl2100_init(void *xsc
)
735 struct iwl2100_softc
*sc
= xsc
;
738 ASSERT_SERIALIZED(sc
->sc_ic
.ic_if
.if_serializer
);
740 iwl2100_stop_callouts(sc
);
742 iwlmsg_init(&msg
, &sc
->sc_reply_port
, iwl2100_init_dispatch
, sc
);
743 lwkt_domsg(&sc
->sc_thread_port
, &msg
.iwlm_nmsg
.nm_lmsg
, 0);
747 iwl2100_init_dispatch(struct netmsg
*nmsg
)
749 struct iwlmsg
*msg
= (struct iwlmsg
*)nmsg
;
750 struct iwl2100_softc
*sc
= msg
->iwlm_softc
;
751 struct ieee80211com
*ic
= &sc
->sc_ic
;
752 struct ifnet
*ifp
= &ic
->ic_if
;
753 int error
= 0, flags
;
755 ASSERT_SERIALIZED(ifp
->if_serializer
);
757 if (sc
->sc_flags
& IWL2100_F_DETACH
)
760 ieee80211_new_state(ic
, IEEE80211_S_INIT
, -1);
762 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
) {
765 * Workaround for dummy firmware:
766 * Don't enable hardware too early, since
767 * once it is enabled, it will start scanning.
771 flags
= IWL2100_INIT_F_ENABLE
;
774 /* Always put the device into a known state */
775 error
= iwl2100_hw_init(sc
, NULL
,
776 ic
->ic_des_essid
, ic
->ic_des_esslen
, flags
);
780 if (sc
->sc_flags
& IWL2100_F_ZERO_CMD
) {
781 if_printf(ifp
, "zero cmd, reinit 1s later\n");
784 callout_reset(&sc
->sc_reinit
, hz
, iwl2100_reinit_callout
, sc
);
788 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
) {
789 if (ic
->ic_roaming
!= IEEE80211_ROAMING_MANUAL
)
790 ieee80211_new_state(ic
, IEEE80211_S_SCAN
, -1);
792 ieee80211_new_state(ic
, IEEE80211_S_RUN
, -1);
797 lwkt_replymsg(&nmsg
->nm_lmsg
, error
);
801 iwl2100_ioctl(struct ifnet
*ifp
, u_long cmd
, caddr_t req
, struct ucred
*cr
)
803 struct iwl2100_softc
*sc
= ifp
->if_softc
;
806 ASSERT_SERIALIZED(ifp
->if_serializer
);
808 if (sc
->sc_flags
& IWL2100_F_DETACH
)
813 if (ifp
->if_flags
& IFF_UP
) {
814 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
817 if (ifp
->if_flags
& IFF_RUNNING
) {
821 * Stop callouts explicitly, since
822 * if reinitialization is happening,
823 * IFF_RUNNING will not be turned on.
825 iwl2100_stop_callouts(sc
);
830 error
= ieee80211_ioctl(&sc
->sc_ic
, cmd
, req
, cr
);
834 if (error
== ENETRESET
) {
835 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) ==
836 (IFF_UP
| IFF_RUNNING
))
844 iwl2100_start(struct ifnet
*ifp
)
846 struct iwl2100_softc
*sc
= ifp
->if_softc
;
847 struct ieee80211com
*ic
= &sc
->sc_ic
;
848 struct iwl2100_tx_ring
*tr
= &sc
->sc_txring
;
851 ASSERT_SERIALIZED(ifp
->if_serializer
);
853 if (sc
->sc_flags
& IWL2100_F_DETACH
) {
854 ieee80211_drain_mgtq(&ic
->ic_mgtq
);
855 ifq_purge(&ifp
->if_snd
);
859 if ((ifp
->if_flags
& (IFF_OACTIVE
| IFF_RUNNING
)) != IFF_RUNNING
)
862 if ((sc
->sc_flags
& IWL2100_F_IFSTART
) == 0) {
863 ifq_purge(&ifp
->if_snd
);
867 while (tr
->tr_used
< IWL2100_TX_USED_MAX
) {
868 struct ieee80211_frame
*wh
;
869 struct ieee80211_node
*ni
;
870 struct ether_header
*eh
;
873 m
= ifq_dequeue(&ifp
->if_snd
, NULL
);
877 if (m
->m_len
< sizeof(*eh
)) {
878 m
= m_pullup(m
, sizeof(*eh
));
884 eh
= mtod(m
, struct ether_header
*);
886 ni
= ieee80211_find_txnode(ic
, eh
->ether_dhost
);
897 m
= ieee80211_encap(ic
, m
, ni
);
899 ieee80211_free_node(ni
);
904 if (ic
->ic_rawbpf
!= NULL
)
905 bpf_mtap(ic
->ic_rawbpf
, m
);
907 wh
= mtod(m
, struct ieee80211_frame
*);
908 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
) {
909 if (ieee80211_crypto_encap(ic
, ni
, m
) == NULL
) {
910 ieee80211_free_node(ni
);
920 if (sc
->sc_drvbpf
!= NULL
) {
921 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
922 sc
->sc_tx_th
.wt_flags
= IEEE80211_RADIOTAP_F_WEP
;
924 sc
->sc_tx_th
.wt_flags
= 0;
925 bpf_ptap(sc
->sc_drvbpf
, m
, &sc
->sc_tx_th
,
928 wh
= NULL
; /* Catch any invalid use */
930 ieee80211_free_node(ni
);
932 if (iwl2100_encap(sc
, m
)) {
941 if (tr
->tr_used
>= IWL2100_TX_USED_MAX
)
942 ifp
->if_flags
|= IFF_OACTIVE
;
945 bus_dmamap_sync(tr
->tr_dtag
, tr
->tr_dmap
, BUS_DMASYNC_PREWRITE
);
946 CSR_WRITE_4(sc
, IWL2100_TXQ_WRITE_IDX
, tr
->tr_index
);
950 ieee80211_drain_mgtq(&ic
->ic_mgtq
);
955 iwl2100_watchdog(struct ifnet
*ifp
)
957 struct iwl2100_softc
*sc
= ifp
->if_softc
;
959 ASSERT_SERIALIZED(ifp
->if_serializer
);
961 if (sc
->sc_flags
& IWL2100_F_DETACH
)
964 if (sc
->sc_tx_timer
) {
965 if (--sc
->sc_tx_timer
== 0) {
966 if_printf(ifp
, "watchdog timeout!\n");
974 ieee80211_watchdog(&sc
->sc_ic
);
978 iwl2100_newstate(struct ieee80211com
*ic
, enum ieee80211_state nstate
, int arg
)
980 struct ifnet
*ifp
= &ic
->ic_if
;
981 struct iwl2100_softc
*sc
= ifp
->if_softc
;
984 ASSERT_SERIALIZED(ifp
->if_serializer
);
986 iwlmsg_init(&msg
, &sc
->sc_reply_port
, iwl2100_newstate_dispatch
, sc
);
987 msg
.iwlm_nstate
= nstate
;
990 return lwkt_domsg(&sc
->sc_thread_port
, &msg
.iwlm_nmsg
.nm_lmsg
, 0);
994 iwl2100_newstate_dispatch(struct netmsg
*nmsg
)
996 struct iwlmsg
*msg
= (struct iwlmsg
*)nmsg
;
997 struct iwl2100_softc
*sc
= msg
->iwlm_softc
;
998 struct ieee80211com
*ic
= &sc
->sc_ic
;
1000 struct ifnet
*ifp
= &ic
->ic_if
;
1002 enum ieee80211_state nstate
, ostate
;
1003 int arg
= msg
->iwlm_arg
, error
= 0;
1005 ASSERT_SERIALIZED(ifp
->if_serializer
);
1007 nstate
= msg
->iwlm_nstate
;
1008 ostate
= ic
->ic_state
;
1010 sc
->sc_flags
&= ~IWL2100_F_IFSTART
;
1013 iwl2100_chan_change(sc
, ic
->ic_curchan
);
1015 callout_stop(&sc
->sc_ibss
);
1016 iwl2100_restart_done(sc
);
1018 if (nstate
== IEEE80211_S_INIT
)
1021 if (sc
->sc_flags
& IWL2100_F_DETACH
) {
1023 * Except for INIT, we skip rest of the
1024 * state changes during detaching
1029 if (ic
->ic_opmode
== IEEE80211_M_STA
) {
1030 if (nstate
== IEEE80211_S_AUTH
)
1031 error
= iwl2100_auth(sc
);
1032 else if (nstate
== IEEE80211_S_RUN
)
1033 sc
->sc_flags
|= IWL2100_F_IFSTART
;
1034 } else if (ic
->ic_opmode
== IEEE80211_M_IBSS
) {
1035 if (nstate
== IEEE80211_S_RUN
) {
1036 DPRINTF(sc
, IWL2100_DBG_IBSS
, "%s",
1037 "start/join ibss\n");
1040 * IWL2100_F_IFSTART can't be turned on
1041 * until BSSID generated by the firmware
1044 * XXX only if we started the IBSS
1046 error
= iwl2100_ibss(sc
);
1051 error
= sc
->sc_newstate(ic
, nstate
, arg
);
1054 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
) {
1056 * Don't use 'nstate' here, since for IBSS
1057 * mode 802.11 layer may enter RUN state in
1058 * a recursive manner, i.e. when we reach
1059 * here, nstate != ic->ic_state
1061 if (ic
->ic_state
== IEEE80211_S_SCAN
&&
1062 ic
->ic_state
!= ostate
) {
1063 DPRINTF(sc
, IWL2100_DBG_SCAN
, "%s",
1065 error
= iwl2100_scan(sc
);
1070 lwkt_replymsg(&nmsg
->nm_lmsg
, error
);
1074 iwl2100_media_change(struct ifnet
*ifp
)
1078 ASSERT_SERIALIZED(ifp
->if_serializer
);
1080 error
= ieee80211_media_change(ifp
);
1081 if (error
!= ENETRESET
)
1084 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) == (IFF_UP
| IFF_RUNNING
))
1085 iwl2100_init(ifp
->if_softc
);
1090 iwl2100_media_status(struct ifnet
*ifp
, struct ifmediareq
*imr
)
1092 struct iwl2100_softc
*sc
= ifp
->if_softc
;
1094 if (sc
->sc_flags
& IWL2100_F_IFSTART
) {
1095 struct ieee80211_node
*ni
= sc
->sc_ic
.ic_bss
;
1099 txrate
= iwl2100_read_ord1(sc
, IWL2100_ORD1_TXRATE
) & 0xf;
1100 if (ni
->ni_rates
.rs_nrates
< 4)
1101 nrates
= ni
->ni_rates
.rs_nrates
;
1103 for (i
= 0; i
< nrates
; ++i
) {
1104 if ((1 << i
) & txrate
)
1108 ieee80211_media_status(ifp
, imr
);
1112 iwl2100_intr(void *xsc
)
1114 struct iwl2100_softc
*sc
= xsc
;
1115 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
1116 uint32_t intr_status
;
1118 ASSERT_SERIALIZED(ifp
->if_serializer
);
1120 if ((sc
->sc_flags
& IWL2100_F_INITED
) == 0)
1123 intr_status
= CSR_READ_4(sc
, IWL2100_INTR_STATUS
);
1124 if (intr_status
== 0xffffffff) /* not for us */
1127 if ((intr_status
& IWL2100_INTRS
) == 0) /* not interested */
1130 sc
->sc_flags
|= IWL2100_F_IN_INTR
;
1132 /* Disable interrupts */
1133 CSR_WRITE_4(sc
, IWL2100_INTR_MASK
, 0);
1135 if (intr_status
& IWL2100_INTR_EFATAL
) {
1136 uint32_t error_info
;
1138 if_printf(ifp
, "intr fatal error\n");
1139 CSR_WRITE_4(sc
, IWL2100_INTR_STATUS
, IWL2100_INTR_EFATAL
);
1141 error_info
= IND_READ_4(sc
, IWL2100_IND_ERROR_INFO
);
1142 IND_READ_4(sc
, error_info
& IWL2100_IND_ERRORADDR_MASK
);
1144 callout_stop(&sc
->sc_reinit
);
1147 /* Leave interrupts disabled */
1151 if (intr_status
& IWL2100_INTR_EPARITY
) {
1152 if_printf(ifp
, "intr parity error\n");
1153 CSR_WRITE_4(sc
, IWL2100_INTR_STATUS
, IWL2100_INTR_EPARITY
);
1156 if (intr_status
& IWL2100_INTR_RX
) {
1157 CSR_WRITE_4(sc
, IWL2100_INTR_STATUS
, IWL2100_INTR_RX
);
1162 if (intr_status
& IWL2100_INTR_TX
) {
1163 CSR_WRITE_4(sc
, IWL2100_INTR_STATUS
, IWL2100_INTR_TX
);
1167 if (intr_status
& IWL2100_INTR_FW_INITED
)
1168 CSR_WRITE_4(sc
, IWL2100_INTR_STATUS
, IWL2100_INTR_FW_INITED
);
1169 if (intr_status
& IWL2100_INTR_CMD_DONE
)
1170 CSR_WRITE_4(sc
, IWL2100_INTR_STATUS
, IWL2100_INTR_CMD_DONE
);
1172 /* Enable interrupts */
1173 CSR_WRITE_4(sc
, IWL2100_INTR_MASK
, IWL2100_INTRS
);
1175 sc
->sc_flags
&= ~IWL2100_F_IN_INTR
;
1179 iwl2100_hw_reset(struct iwl2100_softc
*sc
)
1186 * - Make GPIO3 firmware writable
1190 CSR_WRITE_4(sc
, IWL2100_GPIO
,
1191 IWL2100_GPIO_3_EN
| IWL2100_GPIO_3_FWWR
|
1192 IWL2100_GPIO_1_EN
| IWL2100_GPIO_LEDOFF
);
1199 CSR_WRITE_4(sc
, IWL2100_RESET
, IWL2100_RESET_STOP_MASTER
);
1200 for (i
= 0; i
< WAIT_MAX
; ++i
) {
1203 if (CSR_READ_4(sc
, IWL2100_RESET
) &
1204 IWL2100_RESET_MASTER_STOPPED
)
1207 if (i
== WAIT_MAX
) {
1208 if_printf(&sc
->sc_ic
.ic_if
, "can't stop master\n");
1214 CSR_WRITE_4(sc
, IWL2100_RESET
, IWL2100_RESET_SW
);
1219 iwl2100_alloc_firmware(struct iwl2100_softc
*sc
, enum ieee80211_opmode opmode
)
1224 enum ieee80211_opmode opmode
;
1225 struct iwl2100_firmware
*fw
;
1227 { "", IWL2100_FW_M_STA
, IEEE80211_M_STA
,
1229 { "-i", IWL2100_FW_M_IBSS
, IEEE80211_M_IBSS
,
1231 { "-p", IWL2100_FW_M_MONITOR
, IEEE80211_M_MONITOR
,
1232 &sc
->sc_fw_monitor
},
1233 { NULL
, 0, 0, NULL
}
1235 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
1236 const struct iwl2100_fwimg_hdr
*hdr
;
1237 struct iwl2100_firmware
*fw
= NULL
;
1238 struct fw_image
*image
;
1242 for (i
= 0; fw_arr
[i
].fw
!= NULL
; ++i
) {
1245 if (fw_arr
[i
].opmode
== opmode
) {
1246 if (fw
->fw_image
!= NULL
)
1252 KASSERT(fw_arr
[i
].fw
!= NULL
, ("unsupported opmode %u\n", opmode
));
1254 ksnprintf(filename
, sizeof(filename
), IWL2100_FW_PATH
,
1258 * Release the serializer to avoid possible dead lock
1260 lwkt_serialize_exit(ifp
->if_serializer
);
1261 image
= firmware_image_load(filename
, NULL
);
1262 lwkt_serialize_enter(ifp
->if_serializer
);
1266 fw
->fw_image
= image
;
1273 hdr
= (const struct iwl2100_fwimg_hdr
*)image
->fw_image
;
1274 if ((hdr
->version
& 0xff) != 1) {
1275 if_printf(ifp
, "%s unsupported firmware version %d",
1276 image
->fw_name
, hdr
->version
& 0xff);
1280 if (hdr
->mode
!= fw_arr
[i
].mode
) {
1281 if_printf(ifp
, "%s contains %d mode firmware, should be %d\n",
1282 image
->fw_name
, hdr
->mode
, fw_arr
[i
].mode
);
1286 if (hdr
->data_size
+ hdr
->ucode_size
+ sizeof(*hdr
) !=
1288 if_printf(ifp
, "%s size mismatch, %u/hdr %u\n", image
->fw_name
,
1289 fw
->fw_image
->fw_imglen
,
1290 hdr
->data_size
+ hdr
->ucode_size
+ sizeof(*hdr
));
1294 fw
->fw_data
= (const uint8_t *)(hdr
+ 1);
1295 fw
->fw_data_size
= hdr
->data_size
;
1296 fw
->fw_ucode
= fw
->fw_data
+ fw
->fw_data_size
;
1297 fw
->fw_ucode_size
= hdr
->ucode_size
;
1301 firmware_image_unload(fw
->fw_image
);
1302 bzero(fw
, sizeof(*fw
));
1308 iwl2100_free_firmware(struct iwl2100_softc
*sc
)
1310 struct iwl2100_firmware
*fw_arr
[] =
1311 { &sc
->sc_fw_sta
, &sc
->sc_fw_ibss
, &sc
->sc_fw_monitor
, NULL
};
1314 for (i
= 0; fw_arr
[i
] != NULL
; ++i
) {
1315 struct iwl2100_firmware
*fw
= fw_arr
[i
];
1317 if (fw
->fw_image
!= NULL
) {
1318 firmware_image_unload(fw
->fw_image
);
1319 bzero(fw
, sizeof(*fw
));
1325 iwl2100_load_firmware(struct iwl2100_softc
*sc
, enum ieee80211_opmode opmode
)
1327 static const struct {
1331 { IWL2100_SHMEM0
, IWL2100_SHMEM0_SIZE
},
1332 { IWL2100_SHMEM1
, IWL2100_SHMEM1_SIZE
},
1333 { IWL2100_SHMEM2
, IWL2100_SHMEM2_SIZE
},
1334 { IWL2100_SHMEM3
, IWL2100_SHMEM3_SIZE
},
1335 { IWL2100_SHMEM_INTR
, IWL2100_SHMEM_INTR_SIZE
},
1338 const struct iwl2100_firmware
*fw
= NULL
;
1342 * Pick up the firmware image corresponding to
1343 * the current operation mode
1346 case IEEE80211_M_STA
:
1347 fw
= &sc
->sc_fw_sta
;
1349 case IEEE80211_M_IBSS
:
1350 fw
= &sc
->sc_fw_ibss
;
1352 case IEEE80211_M_MONITOR
:
1353 fw
= &sc
->sc_fw_monitor
;
1356 panic("unsupported opmode %d\n", opmode
);
1359 KASSERT(fw
->fw_image
!= NULL
,
1360 ("opmode %d firmware image is not allocated yet\n", opmode
));
1363 error
= iwl2100_load_fw_ucode(sc
, fw
);
1368 error
= iwl2100_reset(sc
);
1373 error
= iwl2100_load_fw_data(sc
, fw
);
1377 /* Clear shared memory */
1378 for (i
= 0; share_mem
[i
].size
!= 0; ++i
) {
1379 uint32_t addr
= share_mem
[i
].addr
;
1382 for (j
= 0; j
< share_mem
[i
].size
; j
+= 4)
1383 IND_WRITE_4(sc
, addr
+ j
, 0);
1389 #define IND_WRITE_FLUSH_2(sc, reg, val) \
1391 IND_WRITE_2((sc), (reg), (val)); \
1392 CSR_READ_4((sc), 0); \
1395 #define IND_WRITE_FLUSH_1(sc, reg, val) \
1397 IND_WRITE_1((sc), (reg), (val)); \
1398 CSR_READ_4((sc), 0); \
1401 /* XXX need more comment */
1403 iwl2100_load_fw_ucode(struct iwl2100_softc
*sc
,
1404 const struct iwl2100_firmware
*fw
)
1406 struct iwl2100_ucode_resp resp
;
1411 IND_WRITE_4(sc
, IWL2100_IND_HALT
, IWL2100_IND_HALT_HOLD
);
1413 /* Allow ARC to run */
1414 CSR_WRITE_4(sc
, IWL2100_RESET
, 0);
1416 IND_WRITE_FLUSH_2(sc
, IWL2100_IND_CTRL
, 0x703);
1417 IND_WRITE_FLUSH_2(sc
, IWL2100_IND_CTRL
, 0x707);
1419 IND_WRITE_FLUSH_1(sc
, 0x210014, 0x72);
1420 IND_WRITE_FLUSH_1(sc
, 0x210014, 0x72);
1422 IND_WRITE_FLUSH_1(sc
, 0x210000, 0x40);
1423 IND_WRITE_FLUSH_1(sc
, 0x210000, 0);
1424 IND_WRITE_FLUSH_1(sc
, 0x210000, 0x40);
1427 for (i
= 0; i
< fw
->fw_ucode_size
; ++i
, ++p
)
1428 IND_WRITE_1(sc
, 0x210010, *p
);
1430 IND_WRITE_FLUSH_1(sc
, 0x210000, 0);
1431 IND_WRITE_FLUSH_1(sc
, 0x210000, 0);
1432 IND_WRITE_FLUSH_1(sc
, 0x210000, 0x80);
1435 IND_WRITE_FLUSH_2(sc
, IWL2100_IND_CTRL
, 0x703);
1436 IND_WRITE_FLUSH_2(sc
, IWL2100_IND_CTRL
, 0x707);
1438 IND_WRITE_FLUSH_1(sc
, 0x210014, 0x72);
1439 IND_WRITE_FLUSH_1(sc
, 0x210014, 0x72);
1441 IND_WRITE_FLUSH_1(sc
, 0x210000, 0);
1442 IND_WRITE_1(sc
, 0x210000, 0x80);
1445 for (i
= 0; i
< WAIT_MAX
; ++i
) {
1448 if (IND_READ_1(sc
, 0x210000) & 0x1)
1451 if (i
== WAIT_MAX
) {
1452 if_printf(&sc
->sc_ic
.ic_if
,
1453 "wait ucode symbol init timed out\n");
1459 for (i
= 0; i
< WAIT_MAX
; ++i
) {
1460 uint16_t *r
= (uint16_t *)&resp
;
1463 for (j
= 0; j
< sizeof(resp
) / 2; ++j
, ++r
)
1464 *r
= IND_READ_2(sc
, 0x210004);
1466 if (resp
.cmd_id
== 1 && resp
.ucode_valid
== 1)
1470 if (i
== WAIT_MAX
) {
1471 if_printf(&sc
->sc_ic
.ic_if
,
1472 "wait ucode response timed out\n");
1478 IND_WRITE_4(sc
, IWL2100_IND_HALT
, 0);
1481 if_printf(&sc
->sc_ic
.ic_if
, "ucode rev.%d date %d.%d.20%02d "
1482 "time %02d:%02d\n", resp
.ucode_rev
,
1483 resp
.date_time
[0], resp
.date_time
[1],
1484 resp
.date_time
[2], resp
.date_time
[3],
1491 #undef IND_WRITE_FLUSH_1
1492 #undef IND_WRITE_FLUSH_2
1495 iwl2100_load_fw_data(struct iwl2100_softc
*sc
,
1496 const struct iwl2100_firmware
*fw
)
1498 const uint8_t *p
= fw
->fw_data
;
1501 while (w
< fw
->fw_data_size
) {
1502 const struct iwl2100_fwdata_hdr
*h
;
1505 h
= (const struct iwl2100_fwdata_hdr
*)p
;
1506 if (h
->len
> 32 || h
->len
== 0) {
1507 if_printf(&sc
->sc_ic
.ic_if
,
1508 "firmware image data corrupted\n");
1511 if ((h
->addr
& 0x3) || (h
->len
& 0x3)) {
1512 if_printf(&sc
->sc_ic
.ic_if
,
1513 "firmware image data with unaligned "
1514 "address %#x or length %#x\n",
1519 hlen
= sizeof(*h
) + h
->len
- 1;
1520 if (w
+ hlen
> fw
->fw_data_size
) {
1521 if_printf(&sc
->sc_ic
.ic_if
,
1522 "firmware image data size mismatch\n");
1526 CSR_WRITE_4(sc
, IWL2100_AUTOINC_ADDR
, h
->addr
);
1527 for (i
= 0; i
< h
->len
; i
+= 4) {
1528 CSR_WRITE_4(sc
, IWL2100_AUTOINC_DATA
,
1529 *(const uint32_t *)&h
->data
[i
]);
1535 KKASSERT(w
== fw
->fw_data_size
);
1541 iwl2100_free_tx_ring(struct iwl2100_softc
*sc
)
1543 struct iwl2100_tx_ring
*tr
= &sc
->sc_txring
;
1546 for (i
= 0; i
< IWL2100_TX_NDESC
; ++i
) {
1547 struct iwl2100_txbuf
*tb
= &tr
->tr_buf
[i
];
1549 if (tb
->tb_mbuf
!= NULL
) {
1550 bus_dmamap_unload(sc
->sc_mbuf_dtag
, tb
->tb_dmap
);
1551 if (tb
->tb_flags
& IWL2100_TBF_CMDBUF
) {
1552 KKASSERT(tb
->tb_mbuf
== sc
->sc_cmd
);
1553 tb
->tb_flags
&= ~IWL2100_TBF_CMDBUF
;
1555 m_freem(tb
->tb_mbuf
);
1561 bzero(tr
->tr_desc
, IWL2100_TXRING_SIZE
);
1562 bus_dmamap_sync(tr
->tr_dtag
, tr
->tr_dmap
, BUS_DMASYNC_PREWRITE
);
1570 iwl2100_free_rx_ring(struct iwl2100_softc
*sc
)
1572 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
1575 for (i
= 0; i
< IWL2100_RX_NDESC
; ++i
) {
1576 struct iwl2100_rxbuf
*rb
= &rr
->rr_buf
[i
];
1578 if (rb
->rb_mbuf
!= NULL
) {
1579 bus_dmamap_unload(sc
->sc_mbuf_dtag
, rb
->rb_dmap
);
1580 m_freem(rb
->rb_mbuf
);
1585 bzero(rr
->rr_desc
, IWL2100_RXRING_SIZE
);
1586 bus_dmamap_sync(rr
->rr_dtag
, rr
->rr_dmap
, BUS_DMASYNC_PREWRITE
);
1588 bzero(rr
->rr_status
, IWL2100_RXSTATUS_SIZE
);
1589 bus_dmamap_sync(rr
->rr_st_dtag
, rr
->rr_st_dmap
, BUS_DMASYNC_PREWRITE
);
1595 iwl2100_free_cmd(struct iwl2100_softc
*sc
)
1597 if (sc
->sc_cmd
!= NULL
) {
1598 m_freem(sc
->sc_cmd
);
1604 iwl2100_init_tx_ring(struct iwl2100_softc
*sc
)
1606 struct iwl2100_tx_ring
*tr
= &sc
->sc_txring
;
1612 bzero(tr
->tr_desc
, IWL2100_TXRING_SIZE
);
1613 bus_dmamap_sync(tr
->tr_dtag
, tr
->tr_dmap
, BUS_DMASYNC_PREWRITE
);
1615 CSR_WRITE_4(sc
, IWL2100_TXQ_ADDR
, tr
->tr_paddr
);
1616 CSR_WRITE_4(sc
, IWL2100_TXQ_SIZE
, IWL2100_TX_NDESC
);
1617 CSR_WRITE_4(sc
, IWL2100_TXQ_READ_IDX
, 0);
1618 CSR_WRITE_4(sc
, IWL2100_TXQ_WRITE_IDX
, tr
->tr_index
);
1624 iwl2100_init_rx_ring(struct iwl2100_softc
*sc
)
1626 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
1629 for (i
= 0; i
< IWL2100_RX_NDESC
; ++i
) {
1630 error
= iwl2100_newbuf(sc
, i
, 1);
1634 bus_dmamap_sync(rr
->rr_st_dtag
, rr
->rr_st_dmap
, BUS_DMASYNC_PREWRITE
);
1635 bus_dmamap_sync(rr
->rr_dtag
, rr
->rr_dmap
, BUS_DMASYNC_PREWRITE
);
1637 rr
->rr_index
= IWL2100_RX_NDESC
- 1;
1639 CSR_WRITE_4(sc
, IWL2100_RXQ_ADDR
, rr
->rr_paddr
);
1640 CSR_WRITE_4(sc
, IWL2100_RXQ_SIZE
, IWL2100_RX_NDESC
);
1641 CSR_WRITE_4(sc
, IWL2100_RXQ_READ_IDX
, 0);
1642 CSR_WRITE_4(sc
, IWL2100_RXQ_WRITE_IDX
, rr
->rr_index
);
1644 CSR_WRITE_4(sc
, IWL2100_RX_STATUS_ADDR
, rr
->rr_st_paddr
);
1650 iwl2100_alloc_cmd(struct iwl2100_softc
*sc
)
1652 KKASSERT(sc
->sc_cmd
== NULL
);
1654 sc
->sc_cmd
= m_getcl(MB_WAIT
, MT_DATA
, M_PKTHDR
);
1655 if (sc
->sc_cmd
== NULL
)
1661 iwl2100_newbuf(struct iwl2100_softc
*sc
, int buf_idx
, int init
)
1663 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
1664 struct iwl2100_rxbuf
*rb
;
1665 struct iwl_dmamap_ctx ctx
;
1666 bus_dma_segment_t seg
;
1671 KKASSERT(buf_idx
< IWL2100_RX_NDESC
);
1672 rb
= &rr
->rr_buf
[buf_idx
];
1674 m
= m_getcl(init
? MB_WAIT
: MB_DONTWAIT
, MT_DATA
, M_PKTHDR
);
1679 if_printf(&sc
->sc_ic
.ic_if
, "m_getcl failed\n");
1685 m
->m_len
= m
->m_pkthdr
.len
= MCLBYTES
;
1688 * Try load RX mbuf into temporary DMA map
1692 error
= bus_dmamap_load_mbuf(sc
->sc_mbuf_dtag
, rr
->rr_tmp_dmap
, m
,
1693 iwl_dma_buf_addr
, &ctx
,
1694 init
? BUS_DMA_WAITOK
: BUS_DMA_NOWAIT
);
1695 if (error
|| ctx
.nsegs
== 0) {
1697 bus_dmamap_unload(sc
->sc_mbuf_dtag
, rr
->rr_tmp_dmap
);
1699 if_printf(&sc
->sc_ic
.ic_if
, "too many segments?!\n");
1704 if_printf(&sc
->sc_ic
.ic_if
, "can't load RX mbuf\n");
1712 bus_dmamap_unload(sc
->sc_mbuf_dtag
, rb
->rb_dmap
);
1714 rb
->rb_paddr
= seg
.ds_addr
;
1717 * Swap RX buf's DMA map with the loaded temporary one
1720 rb
->rb_dmap
= rr
->rr_tmp_dmap
;
1721 rr
->rr_tmp_dmap
= dmap
;
1725 iwl2100_rxdesc_setup(sc
, buf_idx
);
1730 iwl2100_rxdesc_setup(struct iwl2100_softc
*sc
, int buf_idx
)
1732 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
1733 struct iwl2100_rxbuf
*rb
;
1734 struct iwl2100_desc
*d
;
1735 struct iwl2100_rx_status
*st
;
1737 KKASSERT(buf_idx
< IWL2100_RX_NDESC
);
1738 rb
= &rr
->rr_buf
[buf_idx
];
1740 st
= &rr
->rr_status
[buf_idx
];
1741 bzero(st
, sizeof(*st
));
1743 d
= &rr
->rr_desc
[buf_idx
];
1744 bzero(d
, sizeof(*d
));
1745 d
->d_paddr
= rb
->rb_paddr
;
1746 d
->d_len
= MCLBYTES
;
1750 iwl2100_init_firmware(struct iwl2100_softc
*sc
)
1753 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
1758 ASSERT_SERIALIZED(ifp
->if_serializer
);
1760 CSR_WRITE_4(sc
, IWL2100_GPIO
,
1761 IWL2100_GPIO_3_EN
| IWL2100_GPIO_3_FWWR
|
1762 IWL2100_GPIO_1_EN
| IWL2100_GPIO_LEDOFF
);
1763 CSR_WRITE_4(sc
, IWL2100_RESET
, 0);
1766 * Wait for firmware to be initialized
1768 #define WAIT_MAX 5000
1770 for (i
= 0; i
< WAIT_MAX
; ++i
) {
1773 intr
= CSR_READ_4(sc
, IWL2100_INTR_STATUS
);
1774 if (intr
& IWL2100_INTR_FW_INITED
) {
1775 CSR_WRITE_4(sc
, IWL2100_INTR_STATUS
,
1776 IWL2100_INTR_FW_INITED
);
1779 if (intr
& (IWL2100_INTR_EFATAL
| IWL2100_INTR_EPARITY
)) {
1780 CSR_WRITE_4(sc
, IWL2100_INTR_STATUS
,
1781 IWL2100_INTR_EFATAL
| IWL2100_INTR_EPARITY
);
1785 intr
= CSR_READ_4(sc
, IWL2100_INTR_STATUS
) & IWL2100_INTRS
;
1786 if (intr
& CSR_READ_4(sc
, IWL2100_INTR_MASK
))
1787 CSR_WRITE_4(sc
, IWL2100_INTR_STATUS
, intr
);
1789 if (i
== WAIT_MAX
) {
1790 if_printf(&sc
->sc_ic
.ic_if
,
1791 "firmware initialization timed out\n");
1797 /* Enable GPIO1/3 and allow firmware to write to them */
1798 CSR_SETBITS_4(sc
, IWL2100_GPIO
,
1799 IWL2100_GPIO_1_EN
| IWL2100_GPIO_1_FWWR
|
1800 IWL2100_GPIO_3_EN
| IWL2100_GPIO_3_FWWR
);
1805 iwl2100_read_ord2(struct iwl2100_softc
*sc
, uint32_t ofs
, void *buf0
, int buflen
)
1807 uint8_t *buf
= buf0
;
1808 uint32_t addr
, info
;
1812 #define IND_ALIGN_MASK 0x3
1814 addr
= IND_READ_4(sc
, sc
->sc_ord2
+ (ofs
<< 3));
1815 info
= IND_READ_4(sc
, sc
->sc_ord2
+ (ofs
<< 3) + sizeof(addr
));
1817 len
= info
& 0xffff;
1820 if ((len
* i
) < buflen
)
1824 i
= addr
& IND_ALIGN_MASK
;
1825 addr
&= ~IND_ALIGN_MASK
;
1829 KKASSERT(i
< IND_ALIGN
);
1830 if (buflen
+ i
< IND_ALIGN
)
1836 CSR_WRITE_4(sc
, IWL2100_IND_ADDR
, addr
);
1837 for (; i
< lim
; ++i
, ++buf
)
1838 *buf
= CSR_READ_1(sc
, IWL2100_IND_DATA
+ i
);
1840 KKASSERT(buflen
>= r
);
1848 len
= buflen
& ~IND_ALIGN_MASK
;
1849 buflen
&= IND_ALIGN_MASK
;
1852 CSR_WRITE_4(sc
, IWL2100_AUTOINC_ADDR
, addr
);
1853 for (i
= 0; i
< len
; i
+= 4, addr
+= 4, buf
+= 4) {
1854 *((uint32_t *)buf
) =
1855 CSR_READ_4(sc
, IWL2100_AUTOINC_DATA
);
1859 CSR_WRITE_4(sc
, IWL2100_IND_ADDR
, addr
);
1860 for (i
= 0; i
< buflen
; ++i
, ++buf
)
1861 *buf
= CSR_READ_1(sc
, IWL2100_IND_DATA
+ i
);
1867 #undef IND_ALIGN_MASK
1871 iwl2100_read_ord1(struct iwl2100_softc
*sc
, uint32_t ofs
)
1875 addr
= IND_READ_4(sc
, sc
->sc_ord1
+ (ofs
<< 2));
1876 return IND_READ_4(sc
, addr
);
1880 iwl2100_write_ord1(struct iwl2100_softc
*sc
, uint32_t ofs
, uint32_t val
)
1884 addr
= IND_READ_4(sc
, sc
->sc_ord1
+ (ofs
<< 2));
1885 IND_WRITE_4(sc
, addr
, val
);
1889 iwl2100_rfkilled(struct iwl2100_softc
*sc
)
1893 if ((sc
->sc_caps
& IWL2100_C_RFKILL
) == 0)
1898 for (i
= 0; i
< TEST_MAX
; ++i
) {
1901 if (CSR_READ_4(sc
, IWL2100_GPIO
) & IWL2100_GPIO_RFKILLED
)
1904 if (i
!= TEST_MAX
) {
1905 if_printf(&sc
->sc_ic
.ic_if
, "RF killed\n");
1915 iwl2100_set_addr(struct iwl2100_softc
*sc
, const uint8_t *eaddr
)
1917 struct iwl2100_cmd
*cmd
;
1920 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
1921 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
1925 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
1926 bzero(cmd
, sizeof(*cmd
));
1928 cmd
->c_cmd
= IWL2100_CMD_SET_ADDR
;
1929 cmd
->c_param_len
= IEEE80211_ADDR_LEN
;
1930 IEEE80211_ADDR_COPY(cmd
->c_param
, eaddr
);
1932 error
= iwl2100_wait_cmd(sc
);
1934 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
1941 iwl2100_set_opmode(struct iwl2100_softc
*sc
, enum ieee80211_opmode opmode
)
1943 struct iwl2100_cmd
*cmd
;
1946 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
1947 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
1951 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
1952 bzero(cmd
, sizeof(cmd
));
1954 cmd
->c_cmd
= IWL2100_CMD_SET_OPMODE
;
1955 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]);
1957 case IEEE80211_M_STA
:
1958 cmd
->c_param
[0] = IWL2100_OPMODE_STA
;
1960 case IEEE80211_M_IBSS
:
1961 cmd
->c_param
[0] = IWL2100_OPMODE_IBSS
;
1963 case IEEE80211_M_MONITOR
:
1964 /* YYY ipw2100 leave this unset */
1965 cmd
->c_param
[0] = IWL2100_OPMODE_MONITOR
;
1968 panic("unsupported opmode %d\n", opmode
);
1972 error
= iwl2100_wait_cmd(sc
);
1974 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
1981 iwl2100_set_80211(struct iwl2100_softc
*sc
)
1983 struct ieee80211com
*ic
= &sc
->sc_ic
;
1984 struct iwl2100_cmd
*cmd
;
1987 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
1988 if_printf(&ic
->ic_if
, "there is command pending\n");
1992 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
1993 bzero(cmd
, sizeof(cmd
));
1995 cmd
->c_cmd
= IWL2100_CMD_SET_80211
;
1996 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]) * 3;
1997 cmd
->c_param
[0] = IWL2100_CFG_IBSS
| IWL2100_CFG_STA
|
1998 IWL2100_CFG_8021X
| IWL2100_CFG_AUTO_PREAMBLE
;
1999 if (ic
->ic_opmode
== IEEE80211_M_IBSS
)
2000 cmd
->c_param
[0] |= IWL2100_CFG_IBSS_AUTO_START
;
2001 else if (ic
->ic_opmode
== IEEE80211_M_MONITOR
) /* YYY not ipw2100 */
2002 cmd
->c_param
[0] |= IWL2100_CFG_MONITOR
;
2003 cmd
->c_param
[1] = IWL2100_CFG_CHANMASK
; /* XXX sc->sc_bss_chans */
2004 cmd
->c_param
[2] = IWL2100_CFG_CHANMASK
; /* YYY sc->sc_ibss_chans */
2006 error
= iwl2100_wait_cmd(sc
);
2008 if_printf(&ic
->ic_if
, "%s failed\n", __func__
);
2015 iwl2100_set_basicrates(struct iwl2100_softc
*sc
)
2017 struct iwl2100_cmd
*cmd
;
2020 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2021 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2025 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2026 bzero(cmd
, sizeof(cmd
));
2029 * This configuration does not seem to have any effects
2030 * on probe-req and assoc-req frames.
2032 cmd
->c_cmd
= IWL2100_CMD_SET_BASICRATES
;
2033 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]);
2034 cmd
->c_param
[0] = 0x3; /* 1Mbps and 2Mbps. XXX from caller */
2036 error
= iwl2100_wait_cmd(sc
);
2038 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2045 iwl2100_set_txrates(struct iwl2100_softc
*sc
)
2047 struct ieee80211com
*ic
= &sc
->sc_ic
;
2048 struct iwl2100_cmd
*cmd
;
2052 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2053 if_printf(&ic
->ic_if
, "there is command pending\n");
2057 /* Calculate TX rate mask. XXX let caller do this */
2058 if (ic
->ic_fixed_rate
!= IEEE80211_FIXED_RATE_NONE
)
2059 rate_mask
= 1 << ic
->ic_fixed_rate
;
2061 rate_mask
= 0xf; /* all 11b rates */
2062 KKASSERT((rate_mask
& ~0xf) == 0);
2067 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2068 bzero(cmd
, sizeof(cmd
));
2070 cmd
->c_cmd
= IWL2100_CMD_SET_TXRATES
;
2071 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]);
2072 cmd
->c_param
[0] = rate_mask
;
2074 error
= iwl2100_wait_cmd(sc
);
2076 if_printf(&ic
->ic_if
, "%s failed\n", __func__
);
2083 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2084 bzero(cmd
, sizeof(cmd
));
2086 cmd
->c_cmd
= IWL2100_CMD_SET_MSDU_TXRATES
;
2087 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]);
2088 cmd
->c_param
[0] = rate_mask
;
2090 error
= iwl2100_wait_cmd(sc
);
2092 if_printf(&ic
->ic_if
, "%s failed\n", __func__
);
2099 iwl2100_set_powersave(struct iwl2100_softc
*sc
, int on
)
2101 struct iwl2100_cmd
*cmd
;
2104 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2105 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2109 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2110 bzero(cmd
, sizeof(cmd
));
2112 cmd
->c_cmd
= IWL2100_CMD_SET_POWERSAVE
;
2113 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]);
2114 cmd
->c_param
[0] = on
; /* XXX power level? */
2116 error
= iwl2100_wait_cmd(sc
);
2118 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2125 iwl2100_set_rtsthreshold(struct iwl2100_softc
*sc
, uint16_t rtsthreshold
)
2127 struct iwl2100_cmd
*cmd
;
2130 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2131 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2135 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2136 bzero(cmd
, sizeof(cmd
));
2138 cmd
->c_cmd
= IWL2100_CMD_SET_RTSTHRESHOLD
;
2139 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]);
2140 if (rtsthreshold
== IEEE80211_RTS_MAX
) {
2141 /* Disable RTS threshold */
2142 cmd
->c_param
[0] = IWL2100_RTS_MAX
;
2144 if (rtsthreshold
>= IWL2100_RTS_MAX
)
2145 rtsthreshold
= IWL2100_RTS_MAX
- 1;
2146 cmd
->c_param
[0] = rtsthreshold
;
2149 error
= iwl2100_wait_cmd(sc
);
2151 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2158 iwl2100_set_bssid(struct iwl2100_softc
*sc
, const uint8_t *bssid
)
2160 struct iwl2100_cmd
*cmd
;
2163 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2164 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2168 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2169 bzero(cmd
, sizeof(cmd
));
2171 cmd
->c_cmd
= IWL2100_CMD_SET_BSSID
;
2172 if (bssid
!= NULL
) {
2173 cmd
->c_param_len
= IEEE80211_ADDR_LEN
;
2174 IEEE80211_ADDR_COPY(cmd
->c_param
, bssid
);
2177 error
= iwl2100_wait_cmd(sc
);
2179 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2186 iwl2100_set_essid(struct iwl2100_softc
*sc
, const uint8_t *essid
, int essid_len
)
2188 struct iwl2100_cmd
*cmd
;
2191 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2192 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2196 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2197 bzero(cmd
, sizeof(cmd
));
2199 cmd
->c_cmd
= IWL2100_CMD_SET_ESSID
;
2200 if (essid
!= NULL
) {
2201 KKASSERT(essid_len
<= sizeof(cmd
->c_param
));
2202 cmd
->c_param_len
= essid_len
;
2204 bcopy(essid
, cmd
->c_param
, essid_len
);
2207 error
= iwl2100_wait_cmd(sc
);
2209 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2216 iwl2100_set_auth_ciphers(struct iwl2100_softc
*sc
,
2217 enum ieee80211_authmode authmode
)
2219 struct iwl2100_cmdparam_sec
*sec
;
2220 struct iwl2100_cmd
*cmd
;
2223 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2224 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2228 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2229 bzero(cmd
, sizeof(cmd
));
2231 cmd
->c_cmd
= IWL2100_CMD_SET_SECURITY
;
2232 cmd
->c_param_len
= sizeof(*sec
);
2233 sec
= (struct iwl2100_cmdparam_sec
*)cmd
->c_param
;
2235 sec
->sec_cipher_mask
= IWL2100_CIPHER_NONE
|
2236 IWL2100_CIPHER_WEP40
|
2237 IWL2100_CIPHER_TKIP
|
2238 IWL2100_CIPHER_CCMP
|
2239 IWL2100_CIPHER_WEP104
;
2240 if (authmode
== IEEE80211_AUTH_SHARED
)
2241 sec
->sec_authmode
= IWL2100_AUTH_SHARED
;
2243 sec
->sec_authmode
= IWL2100_AUTH_OPEN
;
2245 error
= iwl2100_wait_cmd(sc
);
2247 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2254 iwl2100_set_wepkey(struct iwl2100_softc
*sc
, const struct ieee80211_key
*k
)
2256 struct iwl2100_cmdparam_wepkey
*key
;
2257 struct iwl2100_cmd
*cmd
;
2260 if (k
->wk_keylen
> IWL2100_KEYDATA_SIZE
)
2263 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2264 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2268 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2269 bzero(cmd
, sizeof(cmd
));
2271 cmd
->c_cmd
= IWL2100_CMD_SET_WEPKEY
;
2272 cmd
->c_param_len
= sizeof(*key
);
2273 key
= (struct iwl2100_cmdparam_wepkey
*)cmd
->c_param
;
2274 key
->key_index
= k
->wk_keyix
;
2275 key
->key_len
= k
->wk_keylen
;
2276 bcopy(k
->wk_key
, key
->key_data
, key
->key_len
);
2278 error
= iwl2100_wait_cmd(sc
);
2280 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2287 iwl2100_set_weptxkey(struct iwl2100_softc
*sc
, ieee80211_keyix txkey
)
2289 struct iwl2100_cmd
*cmd
;
2292 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2293 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2297 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2298 bzero(cmd
, sizeof(cmd
));
2300 cmd
->c_cmd
= IWL2100_CMD_SET_WEPTXKEY
;
2301 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]);
2302 cmd
->c_param
[0] = txkey
;
2304 error
= iwl2100_wait_cmd(sc
);
2306 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2313 iwl2100_set_privacy(struct iwl2100_softc
*sc
, int on
)
2315 struct iwl2100_cmd
*cmd
;
2318 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2319 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2323 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2324 bzero(cmd
, sizeof(cmd
));
2326 cmd
->c_cmd
= IWL2100_CMD_SET_PRIVACY
;
2327 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]);
2328 cmd
->c_param
[0] = on
? IWL2100_PRIVACY_ENABLE
: 0;
2330 error
= iwl2100_wait_cmd(sc
);
2332 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2339 iwl2100_wait_cmd(struct iwl2100_softc
*sc
)
2341 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
2342 struct iwl2100_tx_ring
*tr
= &sc
->sc_txring
;
2343 struct mbuf
*m
= sc
->sc_cmd
;
2344 struct iwl_dmamap_ctx ctx
;
2345 bus_dma_segment_t seg
;
2346 struct iwl2100_desc
*d
;
2347 struct iwl2100_txbuf
*tb
;
2350 ASSERT_SERIALIZED(ifp
->if_serializer
);
2352 KKASSERT(tr
->tr_index
< IWL2100_TX_NDESC
);
2353 tb
= &tr
->tr_buf
[tr
->tr_index
];
2357 error
= bus_dmamap_load_mbuf(sc
->sc_mbuf_dtag
, tb
->tb_dmap
, m
,
2358 iwl_dma_buf_addr
, &ctx
, BUS_DMA_WAITOK
);
2359 if (error
|| ctx
.nsegs
== 0) {
2361 bus_dmamap_unload(sc
->sc_mbuf_dtag
, tb
->tb_dmap
);
2363 if_printf(ifp
, "too many segments?!\n");
2366 if_printf(ifp
, "can't load RX mbuf\n");
2369 tb
->tb_mbuf
= sc
->sc_cmd
;
2370 tb
->tb_flags
|= IWL2100_TBF_CMDBUF
;
2372 d
= &tr
->tr_desc
[tr
->tr_index
];
2373 d
->d_paddr
= seg
.ds_addr
;
2374 d
->d_len
= sizeof(struct iwl2100_cmd
);
2376 d
->d_flags
= IWL2100_TXD_F_INTR
| IWL2100_TXD_F_CMD
;
2378 KKASSERT(tr
->tr_used
< IWL2100_TX_NDESC
);
2380 tr
->tr_index
= (tr
->tr_index
+ 1) % IWL2100_TX_NDESC
;
2382 bus_dmamap_sync(tr
->tr_dtag
, tr
->tr_dmap
, BUS_DMASYNC_PREWRITE
);
2384 CSR_WRITE_4(sc
, IWL2100_TXQ_WRITE_IDX
, tr
->tr_index
);
2386 if (sc
->sc_flags
& IWL2100_F_IN_INTR
)
2387 panic("sleep in interrupt thread\n");
2389 sc
->sc_flags
|= IWL2100_F_WAITCMD
;
2390 error
= serialize_sleep(sc
, ifp
->if_serializer
, 0, "iwlcmd", 2 * hz
);
2392 sc
->sc_flags
&= ~IWL2100_F_WAITCMD
;
2393 if (sc
->sc_flags
& IWL2100_F_ERROR
) {
2394 if_printf(ifp
, "error happened when waiting "
2395 "command to be done\n");
2403 iwl2100_rxeof(struct iwl2100_softc
*sc
)
2405 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
2406 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
2409 hwidx
= CSR_READ_4(sc
, IWL2100_RXQ_READ_IDX
);
2410 CSR_READ_4(sc
, IWL2100_RXQ_WRITE_IDX
);
2412 if (hwidx
>= IWL2100_RX_NDESC
) {
2413 if_printf(ifp
, "invalid hardware RX index %d\n", hwidx
);
2417 KKASSERT(rr
->rr_index
< IWL2100_RX_NDESC
);
2418 i
= (rr
->rr_index
+ 1) % IWL2100_RX_NDESC
;
2419 while (hwidx
!= i
) {
2420 struct iwl2100_rx_status
*st
= &rr
->rr_status
[i
];
2421 struct iwl2100_rxbuf
*rb
= &rr
->rr_buf
[i
];
2424 bus_dmamap_sync(rr
->rr_st_dtag
, rr
->rr_st_dmap
,
2425 BUS_DMASYNC_POSTREAD
);
2426 frame_type
= st
->r_status
& IWL2100_RXS_TYPE_MASK
;
2428 bus_dmamap_sync(sc
->sc_mbuf_dtag
, rb
->rb_dmap
,
2429 BUS_DMASYNC_POSTREAD
);
2430 switch (frame_type
) {
2431 case IWL2100_RXS_TYPE_CMD
:
2432 iwl2100_rxeof_cmd(sc
, i
);
2435 case IWL2100_RXS_TYPE_STATUS
:
2436 iwl2100_rxeof_status(sc
, i
);
2439 case IWL2100_RXS_TYPE_NOTE
:
2440 iwl2100_rxeof_note(sc
, i
);
2443 case IWL2100_RXS_TYPE_DATA
:
2444 case IWL2100_RXS_TYPE_DATA1
:
2445 iwl2100_rxeof_data(sc
, i
);
2449 if_printf(ifp
, "unknown frame type: %d\n", frame_type
);
2450 iwl2100_rxdesc_setup(sc
, i
);
2453 i
= (i
+ 1) % IWL2100_RX_NDESC
;
2455 bus_dmamap_sync(rr
->rr_st_dtag
, rr
->rr_st_dmap
, BUS_DMASYNC_POSTREAD
);
2456 bus_dmamap_sync(rr
->rr_dtag
, rr
->rr_dmap
, BUS_DMASYNC_POSTREAD
);
2459 rr
->rr_index
= IWL2100_RX_NDESC
- 1;
2461 rr
->rr_index
= i
- 1;
2462 CSR_WRITE_4(sc
, IWL2100_RXQ_WRITE_IDX
, rr
->rr_index
);
2466 iwl2100_txeof(struct iwl2100_softc
*sc
)
2468 struct iwl2100_tx_ring
*tr
= &sc
->sc_txring
;
2469 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
2472 hwidx
= CSR_READ_4(sc
, IWL2100_TXQ_READ_IDX
);
2473 CSR_READ_4(sc
, IWL2100_TXQ_WRITE_IDX
);
2474 if (hwidx
>= IWL2100_TX_NDESC
) {
2475 if_printf(ifp
, "invalid hardware TX index %d\n", hwidx
);
2479 KKASSERT(tr
->tr_coll
< IWL2100_TX_NDESC
);
2480 while (tr
->tr_used
) {
2481 struct iwl2100_txbuf
*tb
;
2483 if (tr
->tr_coll
== hwidx
)
2486 tb
= &tr
->tr_buf
[tr
->tr_coll
];
2487 if (tb
->tb_mbuf
== NULL
)
2490 bus_dmamap_unload(sc
->sc_mbuf_dtag
, tb
->tb_dmap
);
2491 if (tb
->tb_flags
& IWL2100_TBF_CMDBUF
) {
2492 tb
->tb_flags
&= ~IWL2100_TBF_CMDBUF
;
2493 KKASSERT(tb
->tb_mbuf
== sc
->sc_cmd
);
2495 m_freem(tb
->tb_mbuf
);
2499 tr
->tr_coll
= (tr
->tr_coll
+ 1) % IWL2100_TX_NDESC
;
2501 KKASSERT(tr
->tr_used
> 0);
2505 if (tr
->tr_used
< IWL2100_TX_USED_MAX
) {
2506 if (tr
->tr_used
== 0) {
2507 KKASSERT(tr
->tr_coll
== tr
->tr_index
);
2508 sc
->sc_tx_timer
= 0;
2511 ifp
->if_flags
&= ~IFF_OACTIVE
;
2517 iwl2100_config(struct iwl2100_softc
*sc
, const uint8_t *bssid
,
2518 const uint8_t *essid
, uint8_t esslen
, int ibss_chan
)
2520 struct ieee80211com
*ic
= &sc
->sc_ic
;
2521 struct ifnet
*ifp
= &ic
->ic_if
;
2524 if (ic
->ic_opmode
== IEEE80211_M_MONITOR
) {
2525 error
= iwl2100_set_chan(sc
, ic
->ic_curchan
);
2527 if_printf(ifp
, "can't set mon channel\n");
2532 IEEE80211_ADDR_COPY(ic
->ic_myaddr
, IF_LLADDR(ifp
));
2533 error
= iwl2100_set_addr(sc
, ic
->ic_myaddr
);
2535 if_printf(ifp
, "can't set MAC address\n");
2539 error
= iwl2100_set_opmode(sc
, ic
->ic_opmode
);
2541 if_printf(ifp
, "can't set opmode\n");
2546 KKASSERT(ic
->ic_opmode
== IEEE80211_M_IBSS
);
2547 error
= iwl2100_set_chan(sc
, ic
->ic_curchan
);
2549 if_printf(ifp
, "can't set ibss channel\n");
2554 error
= iwl2100_set_80211(sc
);
2556 if_printf(ifp
, "can't set 802.11 config\n");
2560 error
= iwl2100_set_basicrates(sc
);
2562 if_printf(ifp
, "can't set basicrates\n");
2566 error
= iwl2100_set_txrates(sc
);
2568 if_printf(ifp
, "can't set TX rates\n");
2572 error
= iwl2100_set_powersave(sc
, ic
->ic_flags
& IEEE80211_F_PMGTON
);
2574 if_printf(ifp
, "can't turn off powersave\n");
2578 error
= iwl2100_set_rtsthreshold(sc
, ic
->ic_rtsthreshold
);
2580 if_printf(ifp
, "can't set RTS threshold\n");
2584 error
= iwl2100_set_bssid(sc
, bssid
);
2586 if_printf(ifp
, "can't set bssid\n");
2590 error
= iwl2100_set_essid(sc
, essid
, esslen
);
2592 if_printf(ifp
, "can't set essid\n");
2596 error
= iwl2100_set_auth_ciphers(sc
, ic
->ic_bss
->ni_authmode
);
2598 if_printf(ifp
, "can't set authmode and ciphers\n");
2602 if (ic
->ic_flags
& IEEE80211_F_PRIVACY
) {
2603 ieee80211_keyix txkey
= IEEE80211_KEYIX_NONE
;
2606 for (i
= 0; i
< IEEE80211_WEP_NKID
; ++i
) {
2607 const struct ieee80211_key
*k
= &ic
->ic_nw_keys
[i
];
2609 if (k
->wk_keyix
== IEEE80211_KEYIX_NONE
)
2612 error
= iwl2100_set_wepkey(sc
, k
);
2613 if (error
== E2BIG
) {
2616 if_printf(ifp
, "can't set wepkey\n");
2619 txkey
= k
->wk_keyix
;
2622 if (txkey
!= IEEE80211_KEYIX_NONE
) {
2624 * Found some valid WEP keys.
2626 * If WEP TX key index from 802.11 layer is not
2627 * set, then use the first valid WEP key as TX
2630 if (ic
->ic_def_txkey
!= IEEE80211_KEYIX_NONE
)
2631 txkey
= ic
->ic_def_txkey
;
2633 error
= iwl2100_set_weptxkey(sc
, txkey
);
2635 if_printf(ifp
, "can't set weptxkey\n");
2641 error
= iwl2100_set_privacy(sc
, ic
->ic_flags
& IEEE80211_F_PRIVACY
);
2643 if_printf(ifp
, "can't set privacy\n");
2647 error
= iwl2100_set_optie(sc
, ic
->ic_opt_ie
, ic
->ic_opt_ie_len
);
2649 if (error
!= E2BIG
) {
2650 if_printf(ifp
, "can't set opt ie\n");
2655 if (ic
->ic_opmode
== IEEE80211_M_IBSS
) {
2656 error
= iwl2100_set_bintval(sc
, ic
->ic_bss
->ni_intval
);
2658 if_printf(ifp
, "can't set bintval\n");
2662 error
= iwl2100_set_txpower(sc
, 32 /* XXX */);
2664 if_printf(ifp
, "can't set txpwr\n");
2672 iwl2100_config_op(struct iwl2100_softc
*sc
, uint32_t op
)
2674 struct iwl2100_cmd
*cmd
;
2677 KASSERT(op
== IWL2100_CMD_CONF_DONE
|| op
== IWL2100_CMD_CONF_START
,
2678 ("unknown config_op %u", op
));
2680 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2681 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2685 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2686 bzero(cmd
, sizeof(cmd
));
2689 error
= iwl2100_wait_cmd(sc
);
2691 if_printf(&sc
->sc_ic
.ic_if
, "%s(%u) failed\n", __func__
, op
);
2695 iwl2100_read_ord1(sc
, IWL2100_ORD1_CONF_START
); /* dummy read */
2700 iwl2100_set_chan(struct iwl2100_softc
*sc
, const struct ieee80211_channel
*c
)
2702 struct ieee80211com
*ic
= &sc
->sc_ic
;
2703 struct iwl2100_cmd
*cmd
;
2707 KKASSERT(ic
->ic_opmode
!= IEEE80211_M_STA
);
2709 chan
= ieee80211_chan2ieee(ic
, c
);
2710 if (chan
== IEEE80211_CHAN_ANY
) {
2711 if_printf(&ic
->ic_if
, "invalid channel!\n");
2715 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2716 if_printf(&ic
->ic_if
, "there is command pending\n");
2720 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2721 bzero(cmd
, sizeof(cmd
));
2723 cmd
->c_cmd
= IWL2100_CMD_SET_CHAN
;
2724 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]);
2725 cmd
->c_param
[0] = chan
;
2727 error
= iwl2100_wait_cmd(sc
);
2729 if_printf(&ic
->ic_if
, "%s failed\n", __func__
);
2736 iwl2100_set_scanopt(struct iwl2100_softc
*sc
, uint32_t chans
, uint32_t flags
)
2738 struct ieee80211com
*ic
= &sc
->sc_ic
;
2739 struct iwl2100_cmd
*cmd
;
2742 KKASSERT(ic
->ic_opmode
!= IEEE80211_M_MONITOR
);
2744 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2745 if_printf(&ic
->ic_if
, "there is command pending\n");
2749 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2750 bzero(cmd
, sizeof(cmd
));
2754 * 1) IWL2100_SCANOPT_NOASSOC is ignored by firmware, but same
2755 * function could be achieved by clearing bssid.
2756 * 2) Channel mask is ignored by firmware, if NIC is in STA opmode.
2758 * We leave the correct configuration here just with the hope
2759 * that one day firmware could do better.
2761 cmd
->c_cmd
= IWL2100_CMD_SET_SCANOPT
;
2762 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]) * 2;
2763 cmd
->c_param
[0] = flags
| IWL2100_SCANOPT_MIXED
;
2764 cmd
->c_param
[1] = chans
;
2766 error
= iwl2100_wait_cmd(sc
);
2768 if_printf(&ic
->ic_if
, "%s failed\n", __func__
);
2775 iwl2100_set_scan(struct iwl2100_softc
*sc
)
2777 struct ieee80211com
*ic
= &sc
->sc_ic
;
2778 struct iwl2100_cmd
*cmd
;
2781 KKASSERT(ic
->ic_opmode
!= IEEE80211_M_MONITOR
);
2783 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2784 if_printf(&ic
->ic_if
, "there is command pending\n");
2788 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2789 bzero(cmd
, sizeof(cmd
));
2791 cmd
->c_cmd
= IWL2100_CMD_SCAN
;
2792 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]);
2794 error
= iwl2100_wait_cmd(sc
);
2796 if_printf(&ic
->ic_if
, "%s failed\n", __func__
);
2803 iwl2100_set_optie(struct iwl2100_softc
*sc
, void *optie
, uint16_t optie_len
)
2805 struct iwl2100_cmd
*cmd
;
2806 struct iwl2100_cmdparam_ie
*ie
;
2809 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2810 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2814 if (optie_len
> IWL2100_OPTIE_MAX
) {
2815 if_printf(&sc
->sc_ic
.ic_if
, "optie too long\n");
2819 if (optie
== NULL
|| optie_len
== 0)
2822 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2823 bzero(cmd
, sizeof(cmd
));
2825 cmd
->c_cmd
= IWL2100_CMD_SET_IE
;
2826 cmd
->c_param_len
= sizeof(*ie
);
2827 ie
= (struct iwl2100_cmdparam_ie
*)cmd
->c_param
;
2828 ie
->ie_optlen
= optie_len
;
2829 bcopy(optie
, ie
->ie_opt
, optie_len
);
2831 error
= iwl2100_wait_cmd(sc
);
2833 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2840 iwl2100_set_bintval(struct iwl2100_softc
*sc
, uint16_t bintval
)
2842 struct iwl2100_cmd
*cmd
;
2845 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2846 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2850 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2851 bzero(cmd
, sizeof(cmd
));
2853 cmd
->c_cmd
= IWL2100_CMD_SET_BINTVAL
;
2854 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]);
2855 cmd
->c_param
[0] = bintval
;
2857 error
= iwl2100_wait_cmd(sc
);
2859 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2866 iwl2100_set_txpower(struct iwl2100_softc
*sc
, uint16_t txpower
)
2868 struct iwl2100_cmd
*cmd
;
2871 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2872 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2876 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2877 bzero(cmd
, sizeof(cmd
));
2879 cmd
->c_cmd
= IWL2100_CMD_SET_TXPOWER
;
2880 cmd
->c_param_len
= sizeof(cmd
->c_param
[0]);
2881 cmd
->c_param
[0] = txpower
;
2883 error
= iwl2100_wait_cmd(sc
);
2885 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2892 iwl2100_rxeof_status(struct iwl2100_softc
*sc
, int i
)
2894 struct ieee80211com
*ic
= &sc
->sc_ic
;
2895 struct ifnet
*ifp
= &ic
->ic_if
;
2896 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
2897 struct iwl2100_rx_status
*st
= &rr
->rr_status
[i
];
2898 struct iwl2100_rxbuf
*rb
= &rr
->rr_buf
[i
];
2899 struct mbuf
*m
= rb
->rb_mbuf
;
2902 if (st
->r_len
!= sizeof(status
)) {
2903 if_printf(ifp
, "invalid status frame len %u\n", st
->r_len
);
2907 if (ic
->ic_opmode
== IEEE80211_M_MONITOR
)
2910 if ((ic
->ic_flags
& IEEE80211_F_SCAN
) == 0)
2911 sc
->sc_flags
&= ~IWL2100_F_SCANNING
;
2913 status
= *mtod(m
, uint32_t *);
2914 DPRINTF(sc
, IWL2100_DBG_STATUS
, "status 0x%08x\n", status
);
2917 case IWL2100_STATUS_SCANDONE
:
2918 if (ic
->ic_flags
& IEEE80211_F_SCAN
) {
2920 * To make sure that firmware has iterated all
2921 * of the channels, we wait for the second scan
2922 * done status change.
2924 if (sc
->sc_flags
& IWL2100_F_SCANNING
) {
2925 iwlmsg_send(&sc
->sc_scanend_msg
,
2926 &sc
->sc_thread_port
);
2928 sc
->sc_flags
|= IWL2100_F_SCANNING
;
2933 case IWL2100_STATUS_RUNNING
:
2934 iwl2100_restart_done(sc
);
2935 if (ic
->ic_state
== IEEE80211_S_ASSOC
) {
2936 KKASSERT(ic
->ic_opmode
== IEEE80211_M_STA
);
2937 iwlmsg_send(&sc
->sc_run_msg
, &sc
->sc_thread_port
);
2938 } else if (ic
->ic_state
== IEEE80211_S_RUN
) {
2939 if (ic
->ic_opmode
== IEEE80211_M_STA
) {
2940 DPRINTF(sc
, IWL2100_DBG_RESTART
, "%s",
2942 sc
->sc_flags
|= IWL2100_F_IFSTART
;
2945 KKASSERT(ic
->ic_opmode
== IEEE80211_M_IBSS
);
2946 callout_reset(&sc
->sc_ibss
, (100 * hz
) / 1000,
2947 iwl2100_ibss_bssid
, sc
);
2952 case IWL2100_STATUS_BMISS
:
2953 if (ic
->ic_opmode
== IEEE80211_M_STA
) {
2954 DPRINTF(sc
, IWL2100_DBG_SCAN
, "%s", "bmiss\n");
2955 iwlmsg_send(&sc
->sc_bmiss_msg
, &sc
->sc_thread_port
);
2959 case IWL2100_STATUS_SCANNING
:
2960 if (ic
->ic_opmode
== IEEE80211_M_STA
&&
2961 ic
->ic_state
== IEEE80211_S_RUN
) {
2962 /* Firmware error happens */
2963 iwl2100_restart(sc
);
2968 iwl2100_rxdesc_setup(sc
, i
);
2972 iwl2100_rxeof_note(struct iwl2100_softc
*sc
, int i
)
2974 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
2975 struct iwl2100_rx_status
*st
= &rr
->rr_status
[i
];
2976 struct iwl2100_rxbuf
*rb
= &rr
->rr_buf
[i
];
2977 struct mbuf
*m
= rb
->rb_mbuf
;
2978 struct ieee80211com
*ic
= &sc
->sc_ic
;
2979 struct iwl2100_note
*note
;
2981 if (st
->r_len
< sizeof(*note
)) {
2982 if_printf(&ic
->ic_if
, "invalid note frame len %u\n", st
->r_len
);
2986 if (ic
->ic_opmode
== IEEE80211_M_MONITOR
)
2989 note
= mtod(m
, struct iwl2100_note
*);
2990 DPRINTF(sc
, IWL2100_DBG_NOTE
, "note subtype %u, size %u\n",
2991 note
->nt_subtype
, note
->nt_size
);
2993 if (note
->nt_subtype
== 19 /* XXX */ &&
2994 ic
->ic_state
== IEEE80211_S_AUTH
) {
2995 KKASSERT(ic
->ic_opmode
== IEEE80211_M_STA
);
2996 iwlmsg_send(&sc
->sc_assoc_msg
, &sc
->sc_thread_port
);
2999 iwl2100_rxdesc_setup(sc
, i
);
3003 iwl2100_rxeof_cmd(struct iwl2100_softc
*sc
, int i
)
3005 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
3006 struct iwl2100_rx_status
*st
= &rr
->rr_status
[i
];
3007 struct iwl2100_rxbuf
*rb
= &rr
->rr_buf
[i
];
3008 struct mbuf
*m
= rb
->rb_mbuf
;
3009 struct iwl2100_cmd
*cmd
;
3011 if (st
->r_len
!= sizeof(*cmd
)) {
3012 if_printf(&sc
->sc_ic
.ic_if
,
3013 "invalid cmd done frame len %u\n", st
->r_len
);
3017 cmd
= mtod(m
, struct iwl2100_cmd
*);
3018 DPRINTF(sc
, IWL2100_DBG_CMD
, "cmd %u\n", cmd
->c_cmd
);
3019 if (cmd
->c_cmd
== 0)
3020 sc
->sc_flags
|= IWL2100_F_ZERO_CMD
;
3023 iwl2100_rxdesc_setup(sc
, i
);
3027 iwl2100_rxeof_data(struct iwl2100_softc
*sc
, int i
)
3029 struct ieee80211com
*ic
= &sc
->sc_ic
;
3030 struct ifnet
*ifp
= &ic
->ic_if
;
3031 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
3032 struct iwl2100_rx_status
*st
= &rr
->rr_status
[i
];
3033 struct iwl2100_rxbuf
*rb
= &rr
->rr_buf
[i
];
3034 struct mbuf
*m
= rb
->rb_mbuf
;
3035 struct ieee80211_frame_min
*wh
;
3036 struct ieee80211_node
*ni
;
3037 int frame_len
, rssi
;
3038 const struct ieee80211_channel
*c
;
3041 * Gather all necessary information from status ring _here_,
3042 * since the following iwl2100_newbuf() will clear them out.
3045 frame_len
= st
->r_len
;
3047 if (iwl2100_newbuf(sc
, i
, 0)) {
3054 m
->m_pkthdr
.rcvif
= ifp
;
3055 m
->m_len
= m
->m_pkthdr
.len
= frame_len
;
3057 wh
= mtod(m
, struct ieee80211_frame_min
*);
3058 ni
= ieee80211_find_rxnode(ic
, wh
);
3063 if (sc
->sc_drvbpf
!= NULL
) {
3064 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
3065 sc
->sc_rx_th
.wr_flags
= IEEE80211_RADIOTAP_F_WEP
;
3067 sc
->sc_rx_th
.wr_flags
= 0;
3069 sc
->sc_rx_th
.wr_antsignal
= rssi
+ IWL2100_NOISE_FLOOR
;
3070 sc
->sc_rx_th
.wr_antnoise
= IWL2100_NOISE_FLOOR
;
3072 bpf_ptap(sc
->sc_drvbpf
, m
, &sc
->sc_rx_th
, sc
->sc_rx_th_len
);
3075 ieee80211_input(ic
, m
, ni
, rssi
, 0);
3076 ieee80211_free_node(ni
);
3078 if (c
!= ic
->ic_curchan
) /* Happen during scanning */
3079 iwl2100_chan_change(sc
, ic
->ic_curchan
);
3083 iwl2100_scanend_dispatch(struct netmsg
*nmsg
)
3085 struct iwlmsg
*msg
= (struct iwlmsg
*)nmsg
;
3086 struct iwl2100_softc
*sc
= msg
->iwlm_softc
;
3087 struct ieee80211com
*ic
= &sc
->sc_ic
;
3088 struct ifnet
*ifp
= &ic
->ic_if
;
3090 ASSERT_SERIALIZED(ifp
->if_serializer
);
3092 if (sc
->sc_flags
& IWL2100_F_DETACH
)
3095 if (ifp
->if_flags
& IFF_RUNNING
) {
3096 ieee80211_end_scan(ic
);
3097 sc
->sc_flags
&= ~IWL2100_F_SCANNING
;
3100 lwkt_replymsg(&nmsg
->nm_lmsg
, 0);
3104 iwl2100_hw_init(struct iwl2100_softc
*sc
, const uint8_t *bssid
,
3105 const uint8_t *essid
, uint8_t esslen
, uint32_t flags
)
3107 struct ieee80211com
*ic
= &sc
->sc_ic
;
3108 struct ifnet
*ifp
= &ic
->ic_if
;
3112 ASSERT_SERIALIZED(ifp
->if_serializer
);
3113 KKASSERT(curthread
== &sc
->sc_thread
);
3115 iwl2100_hw_stop(sc
);
3117 error
= iwl2100_alloc_firmware(sc
, ic
->ic_opmode
);
3119 if_printf(ifp
, "can't allocate firmware\n");
3123 error
= iwl2100_load_firmware(sc
, ic
->ic_opmode
);
3125 if_printf(ifp
, "can't load firmware\n");
3129 error
= iwl2100_alloc_cmd(sc
);
3131 if_printf(ifp
, "can't allocate cmd\n");
3135 error
= iwl2100_init_tx_ring(sc
);
3137 if_printf(ifp
, "can't init TX ring\n");
3141 error
= iwl2100_init_rx_ring(sc
);
3143 if_printf(ifp
, "can't init RX ring\n");
3147 error
= iwl2100_init_firmware(sc
);
3149 if_printf(ifp
, "can't initialize firmware\n");
3153 sc
->sc_ord1
= CSR_READ_4(sc
, IWL2100_ORD1_ADDR
);
3154 sc
->sc_ord2
= CSR_READ_4(sc
, IWL2100_ORD2_ADDR
);
3156 db_addr
= iwl2100_read_ord1(sc
, IWL2100_ORD1_DBADDR
);
3157 if ((IND_READ_4(sc
, db_addr
+ 0x20) >> 24) & 0x1)
3158 sc
->sc_caps
&= ~IWL2100_C_RFKILL
;
3160 sc
->sc_caps
|= IWL2100_C_RFKILL
;
3162 /* Unlock firmware */
3163 iwl2100_write_ord1(sc
, IWL2100_ORD1_FWLOCK
, 0);
3165 if (iwl2100_rfkilled(sc
)) {
3170 /* Let interrupt handler run */
3171 sc
->sc_flags
|= IWL2100_F_INITED
;
3173 /* Enable interrupts */
3174 CSR_WRITE_4(sc
, IWL2100_INTR_MASK
, IWL2100_INTRS
);
3176 error
= iwl2100_config(sc
, bssid
, essid
, esslen
,
3177 flags
& IWL2100_INIT_F_IBSSCHAN
);
3181 if (flags
& IWL2100_INIT_F_ENABLE
) {
3182 error
= iwl2100_config_done(sc
);
3184 if_printf(ifp
, "can't complete config\n");
3189 ifp
->if_flags
&= ~IFF_OACTIVE
;
3190 ifp
->if_flags
|= IFF_RUNNING
;
3198 iwl2100_start_scan(struct iwl2100_softc
*sc
, uint32_t chans
, uint32_t flags
)
3204 * Firmware always starts scanning once config is done
3206 error
= iwl2100_set_scanopt(sc
, chans
, flags
);
3208 if_printf(&sc
->sc_ic
.ic_if
, "can't set scan opt\n");
3212 error
= iwl2100_set_scan(sc
);
3214 if_printf(&sc
->sc_ic
.ic_if
, "can't set bcast scanning\n");
3221 iwl2100_scan(struct iwl2100_softc
*sc
)
3223 struct ieee80211com
*ic
= &sc
->sc_ic
;
3224 uint32_t chans
, flags
;
3227 KKASSERT(ic
->ic_opmode
!= IEEE80211_M_MONITOR
);
3229 error
= iwl2100_hw_init(sc
, NULL
,
3230 ic
->ic_des_essid
, ic
->ic_des_esslen
, IWL2100_INIT_F_ENABLE
);
3234 if (ic
->ic_opmode
== IEEE80211_M_STA
) {
3235 chans
= sc
->sc_bss_chans
;
3236 flags
= IWL2100_SCANOPT_NOASSOC
;
3239 * Normally # of IBSS channels is less than BSS's
3240 * but it seems IBSS mode works on all BSS channels
3243 chans
= sc
->sc_ibss_chans
;
3245 chans
= sc
->sc_bss_chans
;
3248 * Don't set NOASSOC scan option, it seems that
3249 * firmware will disable itself after scanning
3250 * if this flag is set. After all, we are in
3251 * IBSS mode, which does not have concept of
3257 /* See NOTE in iwl2100_set_scanopt() */
3258 error
= iwl2100_start_scan(sc
, chans
, flags
);
3265 iwl2100_auth(struct iwl2100_softc
*sc
)
3267 struct ieee80211com
*ic
= &sc
->sc_ic
;
3268 struct ieee80211_node
*ni
= ic
->ic_bss
;
3272 KKASSERT(ic
->ic_opmode
== IEEE80211_M_STA
);
3274 chan
= ieee80211_chan2ieee(ic
, ic
->ic_curchan
);
3275 if (chan
== IEEE80211_CHAN_ANY
) {
3276 if_printf(&ic
->ic_if
, "invalid curchan\n");
3280 error
= iwl2100_hw_init(sc
, ni
->ni_bssid
,
3281 ni
->ni_essid
, ni
->ni_esslen
, IWL2100_INIT_F_ENABLE
);
3285 /* See NOTE in iwl2100_set_scanopt() */
3286 error
= iwl2100_start_scan(sc
, 1 << (chan
- 1), 0);
3293 iwl2100_ibss(struct iwl2100_softc
*sc
)
3295 struct ieee80211com
*ic
= &sc
->sc_ic
;
3296 struct ieee80211_node
*ni
= ic
->ic_bss
;
3298 return iwl2100_hw_init(sc
, ni
->ni_bssid
,
3299 ni
->ni_essid
, ni
->ni_esslen
,
3300 IWL2100_INIT_F_ENABLE
| IWL2100_INIT_F_IBSSCHAN
);
3304 iwl2100_encap(struct iwl2100_softc
*sc
, struct mbuf
*m
)
3306 struct iwl2100_tx_ring
*tr
= &sc
->sc_txring
;
3307 struct iwl2100_tx_hdr
*th
;
3308 struct ieee80211_frame
*wh
;
3309 struct iwl_dmamap_ctx ctx
;
3310 bus_dma_segment_t segs
[IWL2100_NSEG_MAX
];
3311 uint8_t src
[IEEE80211_ADDR_LEN
], dst
[IEEE80211_ADDR_LEN
];
3313 int maxsegs
, i
, first_idx
, last_idx
, error
, host_enc
;
3316 * Save necessary information and strip 802.11 header
3318 wh
= mtod(m
, struct ieee80211_frame
*);
3319 IEEE80211_ADDR_COPY(src
, wh
->i_addr2
);
3320 if (sc
->sc_ic
.ic_opmode
== IEEE80211_M_STA
)
3321 IEEE80211_ADDR_COPY(dst
, wh
->i_addr3
);
3323 IEEE80211_ADDR_COPY(dst
, wh
->i_addr1
);
3324 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
3328 m_adj(m
, sizeof(*wh
));
3331 * Prepend and setup hardware TX header
3333 M_PREPEND(m
, sizeof(*th
), MB_DONTWAIT
);
3335 if_printf(&sc
->sc_ic
.ic_if
, "prepend TX header failed\n");
3338 th
= mtod(m
, struct iwl2100_tx_hdr
*);
3340 bzero(th
, sizeof(*th
));
3341 th
->th_cmd
= IWL2100_CMD_TX_DATA
;
3342 th
->th_host_enc
= host_enc
;
3343 IEEE80211_ADDR_COPY(th
->th_src
, src
);
3344 IEEE80211_ADDR_COPY(th
->th_dst
, dst
);
3347 * Load mbuf into DMA map
3349 maxsegs
= IWL2100_TX_USED_MAX
- tr
->tr_used
;
3350 if (maxsegs
> IWL2100_NSEG_MAX
)
3351 maxsegs
= IWL2100_NSEG_MAX
;
3353 KKASSERT(tr
->tr_index
< IWL2100_TX_NDESC
);
3354 first_idx
= tr
->tr_index
;
3355 dmap
= tr
->tr_buf
[first_idx
].tb_dmap
;
3357 ctx
.nsegs
= maxsegs
;
3359 error
= bus_dmamap_load_mbuf(sc
->sc_mbuf_dtag
, dmap
, m
,
3360 iwl_dma_buf_addr
, &ctx
, BUS_DMA_NOWAIT
);
3361 if (!error
&& ctx
.nsegs
== 0) {
3362 bus_dmamap_unload(sc
->sc_mbuf_dtag
, dmap
);
3365 if (error
&& error
!= EFBIG
) {
3366 if_printf(&sc
->sc_ic
.ic_if
, "can't load TX mbuf, error %d\n",
3370 if (error
) { /* error == EFBIG */
3373 m_new
= m_defrag(m
, MB_DONTWAIT
);
3374 if (m_new
== NULL
) {
3375 if_printf(&sc
->sc_ic
.ic_if
, "can't defrag TX mbuf\n");
3382 ctx
.nsegs
= maxsegs
;
3384 error
= bus_dmamap_load_mbuf(sc
->sc_mbuf_dtag
, dmap
, m
,
3385 iwl_dma_buf_addr
, &ctx
,
3387 if (error
|| ctx
.nsegs
== 0) {
3388 if (ctx
.nsegs
== 0) {
3389 bus_dmamap_unload(sc
->sc_mbuf_dtag
, dmap
);
3392 if_printf(&sc
->sc_ic
.ic_if
,
3393 "can't load defraged TX mbuf\n");
3397 bus_dmamap_sync(sc
->sc_mbuf_dtag
, dmap
, BUS_DMASYNC_PREWRITE
);
3403 for (i
= 0; i
< ctx
.nsegs
; ++i
) {
3404 struct iwl2100_desc
*d
= &tr
->tr_desc
[tr
->tr_index
];
3406 d
->d_paddr
= segs
[i
].ds_addr
;
3407 d
->d_len
= segs
[i
].ds_len
;
3411 d
->d_nfrag
= ctx
.nsegs
;
3413 if (i
== ctx
.nsegs
- 1) {
3414 d
->d_flags
= IWL2100_TXD_F_INTR
;
3415 last_idx
= tr
->tr_index
;
3417 d
->d_flags
= IWL2100_TXD_F_NOTLAST
;
3420 tr
->tr_index
= (tr
->tr_index
+ 1) % IWL2100_TX_NDESC
;
3422 KKASSERT(last_idx
>= 0);
3424 tr
->tr_buf
[first_idx
].tb_dmap
= tr
->tr_buf
[last_idx
].tb_dmap
;
3425 tr
->tr_buf
[last_idx
].tb_dmap
= dmap
;
3426 tr
->tr_buf
[last_idx
].tb_mbuf
= m
;
3428 tr
->tr_used
+= ctx
.nsegs
;
3429 KKASSERT(tr
->tr_used
<= IWL2100_TX_USED_MAX
);
3439 iwl2100_restart_dispatch(struct netmsg
*nmsg
)
3441 struct iwlmsg
*msg
= (struct iwlmsg
*)nmsg
;
3442 struct iwl2100_softc
*sc
= msg
->iwlm_softc
;
3443 struct ieee80211com
*ic
= &sc
->sc_ic
;
3444 struct ifnet
*ifp
= &ic
->ic_if
;
3447 ASSERT_SERIALIZED(ifp
->if_serializer
);
3449 if (sc
->sc_flags
& IWL2100_F_DETACH
)
3452 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
3455 if (msg
->iwlm_arg
!= sc
->sc_state_age
) {
3457 * Restarting was triggered in old 802.11 state
3458 * Don't do anything, this is a staled restarting.
3463 if (ic
->ic_state
!= IEEE80211_S_RUN
) {
3464 if_printf(ifp
, "restart happened when not in RUN state\n");
3469 * iwl2100_auth() may release slizer, so stop all
3470 * callouts to prevent them from misfiring.
3472 callout_stop(&sc
->sc_restart_bmiss
);
3473 callout_stop(&sc
->sc_ibss
);
3475 if (ic
->ic_opmode
== IEEE80211_M_STA
) {
3476 error
= iwl2100_auth(sc
);
3481 * Start software beacon missing to handle missing
3482 * firmware bmiss status change when we restarting
3484 callout_reset(&sc
->sc_restart_bmiss
, IEEE80211_TU_TO_TICKS(
3485 2 * ic
->ic_bmissthreshold
* ic
->ic_bss
->ni_intval
),
3486 iwl2100_restart_bmiss
, sc
);
3487 } else if (ic
->ic_opmode
== IEEE80211_M_IBSS
) {
3488 error
= iwl2100_ibss(sc
);
3493 /* Turn on restarting flag before reply this message */
3494 sc
->sc_flags
|= IWL2100_F_RESTARTING
;
3496 lwkt_replymsg(&nmsg
->nm_lmsg
, error
);
3500 iwl2100_restart(struct iwl2100_softc
*sc
)
3502 if ((sc
->sc_flags
& (IWL2100_F_RESTARTING
| IWL2100_F_DETACH
)) == 0) {
3503 struct iwlmsg
*msg
= &sc
->sc_restart_msg
;
3504 struct lwkt_msg
*lmsg
= &msg
->iwlm_nmsg
.nm_lmsg
;
3506 DPRINTF(sc
, IWL2100_DBG_RESTART
, "%s", "restart\n");
3507 if (lmsg
->ms_flags
& MSGF_DONE
) {
3508 sc
->sc_flags
&= ~IWL2100_F_IFSTART
;
3509 msg
->iwlm_arg
= sc
->sc_state_age
;
3510 lwkt_sendmsg(&sc
->sc_thread_port
, lmsg
);
3516 iwl2100_bmiss_dispatch(struct netmsg
*nmsg
)
3518 struct iwlmsg
*msg
= (struct iwlmsg
*)nmsg
;
3519 struct iwl2100_softc
*sc
= msg
->iwlm_softc
;
3520 struct ieee80211com
*ic
= &sc
->sc_ic
;
3521 struct ifnet
*ifp
= &ic
->ic_if
;
3523 ASSERT_SERIALIZED(ifp
->if_serializer
);
3525 if (sc
->sc_flags
& IWL2100_F_DETACH
)
3528 if (ifp
->if_flags
& IFF_RUNNING
) {
3530 * Fake a ic_bmiss_count to make sure that
3531 * ieee80211_beacon_miss() will do its job
3533 ic
->ic_bmiss_count
= ic
->ic_bmiss_max
;
3534 ieee80211_beacon_miss(ic
);
3537 lwkt_replymsg(&nmsg
->nm_lmsg
, 0);
3541 iwl2100_restart_bmiss(void *xsc
)
3543 struct iwl2100_softc
*sc
= xsc
;
3544 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
3546 lwkt_serialize_enter(ifp
->if_serializer
);
3548 if (sc
->sc_flags
& IWL2100_F_DETACH
)
3551 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
3554 if (sc
->sc_flags
& IWL2100_F_RESTARTING
) {
3555 DPRINTF(sc
, IWL2100_DBG_SCAN
| IWL2100_DBG_RESTART
, "%s",
3557 iwlmsg_send(&sc
->sc_bmiss_msg
, &sc
->sc_thread_port
);
3560 lwkt_serialize_exit(ifp
->if_serializer
);
3564 iwl2100_ibss_bssid(void *xsc
)
3566 struct iwl2100_softc
*sc
= xsc
;
3567 struct ieee80211com
*ic
= &sc
->sc_ic
;
3568 struct ifnet
*ifp
= &ic
->ic_if
;
3570 lwkt_serialize_enter(ifp
->if_serializer
);
3572 if (sc
->sc_flags
& IWL2100_F_DETACH
)
3575 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
3578 if (ic
->ic_state
== IEEE80211_S_RUN
&&
3579 ic
->ic_opmode
== IEEE80211_M_IBSS
) {
3580 uint8_t bssid
[IEEE80211_ADDR_LEN
];
3583 len
= iwl2100_read_ord2(sc
, IWL2100_ORD2_BSSID
,
3584 bssid
, sizeof(bssid
));
3585 if (len
< (int)sizeof(bssid
)) {
3586 if_printf(ifp
, "can't get IBSS bssid\n");
3588 DPRINTF(sc
, IWL2100_DBG_IBSS
, "IBSS bssid: %6D\n",
3590 IEEE80211_ADDR_COPY(ic
->ic_bss
->ni_bssid
, bssid
);
3592 sc
->sc_flags
|= IWL2100_F_IFSTART
;
3597 lwkt_serialize_exit(ifp
->if_serializer
);
3601 iwl2100_reinit(struct iwl2100_softc
*sc
)
3603 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
3605 callout_stop(&sc
->sc_restart_bmiss
);
3606 callout_stop(&sc
->sc_ibss
);
3608 ifp
->if_flags
&= ~IFF_RUNNING
;
3611 sc
->sc_flags
&= ~IWL2100_F_INITED
;
3612 sc
->sc_tx_timer
= 0;
3614 /* Mark error happened, and wake up the pending command */
3615 sc
->sc_flags
|= IWL2100_F_ERROR
;
3618 if ((sc
->sc_flags
& IWL2100_F_DETACH
) == 0) {
3620 * Schedule complete initialization,
3621 * i.e. blow away current state
3623 iwlmsg_send(&sc
->sc_reinit_msg
, &sc
->sc_thread_port
);
3628 iwl2100_reinit_dispatch(struct netmsg
*nmsg
)
3630 struct iwlmsg
*msg
= (struct iwlmsg
*)nmsg
;
3631 struct iwl2100_softc
*sc
= msg
->iwlm_softc
;
3632 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
3634 ASSERT_SERIALIZED(ifp
->if_serializer
);
3637 * NOTE: Reply ASAP, so reinit msg could be used if error intr
3638 * happened again during following iwl2100_init()
3640 lwkt_replymsg(&nmsg
->nm_lmsg
, 0);
3642 if (sc
->sc_flags
& IWL2100_F_DETACH
)
3645 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) == IFF_UP
)
3650 iwl2100_reinit_callout(void *xsc
)
3652 struct iwl2100_softc
*sc
= xsc
;
3653 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
3655 lwkt_serialize_enter(ifp
->if_serializer
);
3656 if ((sc
->sc_flags
& IWL2100_F_DETACH
) == 0)
3658 lwkt_serialize_exit(ifp
->if_serializer
);
3662 iwl2100_chan_change(struct iwl2100_softc
*sc
, const struct ieee80211_channel
*c
)
3664 sc
->sc_tx_th
.wt_chan_freq
= sc
->sc_rx_th
.wr_chan_freq
=
3665 htole16(c
->ic_freq
);
3669 iwl2100_stop_callouts(struct iwl2100_softc
*sc
)
3671 callout_stop(&sc
->sc_restart_bmiss
);
3672 callout_stop(&sc
->sc_ibss
);
3673 callout_stop(&sc
->sc_reinit
);