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.3 2008/03/08 06:43:52 sephe Exp $
37 #include <sys/param.h>
39 #include <sys/endian.h>
40 #include <sys/firmware.h>
41 #include <sys/kernel.h>
43 #include <sys/module.h>
44 #include <sys/sysctl.h>
45 #include <sys/socket.h>
46 #include <sys/sockio.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,
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);
183 iwl2100_config_done(struct iwl2100_softc
*sc
)
185 return iwl2100_config_op(sc
, IWL2100_CMD_CONF_DONE
);
189 iwl2100_config_start(struct iwl2100_softc
*sc
)
191 return iwl2100_config_op(sc
, IWL2100_CMD_CONF_START
);
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
;
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
);
224 /* Disable interrupts */
225 CSR_WRITE_4(sc
, IWL2100_INTR_MASK
, 0);
228 * SW reset before reading EEPROM
230 error
= iwl2100_reset(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
);
244 device_printf(dev
, "eeprom\n");
245 for (i
= 0; i
< 128; ++i
) {
246 if (i
!= 0 && i
% 8 == 0)
248 val
= iwl_read_eeprom(&sc
->iwlcom
, i
);
249 kprintf("%04x ", val
);
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
);
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
)) {
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
|
287 IEEE80211_C_SHPREAMBLE
|
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
,
311 device_printf(dev
, "can't setup intr\n");
312 ieee80211_ifdetach(ic
);
319 bpfattach_dlt(ifp
, DLT_IEEE802_11_RADIO
,
320 sizeof(struct ieee80211_frame
) + sizeof(sc
->sc_tx_th
),
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");
371 ieee80211_announce(ic
);
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
;
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
);
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
);
408 lwkt_serialize_exit(ifp
->if_serializer
);
414 iwl2100_stop(struct iwl2100_softc
*sc
)
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);
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);
436 lwkt_replymsg(&nmsg
->nm_lmsg
, 0);
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);
455 iwl2100_hw_reset(sc
);
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
);
468 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
471 sc
->sc_flags
&= ~(IWL2100_F_WAITCMD
|
474 IWL2100_F_RESTARTING
|
481 iwl2100_reset(struct iwl2100_softc
*sc
)
488 #define WAIT_MAX 1000
490 CSR_WRITE_4(sc
, IWL2100_RESET
, IWL2100_RESET_SW
);
491 for (i
= 0; i
< WAIT_MAX
; ++i
) {
493 if (CSR_READ_4(sc
, IWL2100_RESET
) & IWL2100_RESET_DONE
)
497 if_printf(&sc
->sc_ic
.ic_if
, "sw reset timed out\n");
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
) {
511 if (CSR_READ_4(sc
, IWL2100_CTRL
) & IWL2100_CTRL_CLKREADY
)
515 if_printf(&sc
->sc_ic
.ic_if
, "can't stablize clock\n");
524 CSR_SETBITS_4(sc
, IWL2100_CTRL
, IWL2100_CTRL_STANDBY
);
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
;
537 * Create top level DMA tag
539 error
= bus_dma_tag_create(NULL
, 1, 0,
540 BUS_SPACE_MAXADDR_32BIT
,
544 BUS_SPACE_UNRESTRICTED
,
545 BUS_SPACE_MAXSIZE_32BIT
,
548 device_printf(dev
, "can't create DMA tag\n");
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
);
559 device_printf(dev
, "can't create DMA memory for "
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
);
571 device_printf(dev
, "can't create DMA memory for "
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
);
583 device_printf(dev
, "can't create DMA memory for "
589 * Create mbuf DMA stuffs
591 error
= iwl2100_dma_mbuf_create(dev
);
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
);
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
;
631 * Create mbuf DMA tag
633 error
= bus_dma_tag_create(sc
->sc_dtag
, 1, 0,
634 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
,
636 MCLBYTES
, IWL2100_NSEG_MAX
,
637 BUS_SPACE_MAXSIZE_32BIT
,
638 BUS_DMA_ALLOCNOW
, &sc
->sc_mbuf_dtag
);
640 device_printf(dev
, "can't create mbuf DMA tag\n");
645 * Create spare DMA map for RX mbufs
647 error
= bus_dmamap_create(sc
->sc_mbuf_dtag
, 0, &rr
->rr_tmp_dmap
);
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
;
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
);
662 device_printf(dev
, "can't create %d RX mbuf "
664 iwl2100_dma_mbuf_destroy(dev
, 0, i
);
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
);
676 device_printf(dev
, "can't create %d TX mbuf "
678 iwl2100_dma_mbuf_destroy(dev
, i
, IWL2100_RX_NDESC
);
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
;
693 if (sc
->sc_mbuf_dtag
== NULL
)
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
;
729 iwl2100_init(void *xsc
)
731 struct iwl2100_softc
*sc
= xsc
;
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);
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
)
756 ieee80211_new_state(ic
, IEEE80211_S_INIT
, -1);
758 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
) {
761 * Workaround for dummy firmware:
762 * Don't enable hardware too early, since
763 * once it is enabled, it will start scanning.
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
);
776 if (sc
->sc_flags
& IWL2100_F_ZERO_CMD
) {
777 if_printf(ifp
, "zero cmd, reinit 1s later\n");
780 callout_reset(&sc
->sc_reinit
, hz
, iwl2100_reinit_callout
, sc
);
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);
788 ieee80211_new_state(ic
, IEEE80211_S_RUN
, -1);
793 lwkt_replymsg(&nmsg
->nm_lmsg
, error
);
797 iwl2100_ioctl(struct ifnet
*ifp
, u_long cmd
, caddr_t req
, struct ucred
*cr
)
799 struct iwl2100_softc
*sc
= ifp
->if_softc
;
802 ASSERT_SERIALIZED(ifp
->if_serializer
);
804 if (sc
->sc_flags
& IWL2100_F_DETACH
)
809 if (ifp
->if_flags
& IFF_UP
) {
810 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
813 if (ifp
->if_flags
& IFF_RUNNING
) {
817 * Stop callouts explicitly, since
818 * if reinitialization is happening,
819 * IFF_RUNNING will not be turned on.
821 iwl2100_stop_callouts(sc
);
826 error
= ieee80211_ioctl(&sc
->sc_ic
, cmd
, req
, cr
);
830 if (error
== ENETRESET
) {
831 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) ==
832 (IFF_UP
| IFF_RUNNING
))
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
;
847 ASSERT_SERIALIZED(ifp
->if_serializer
);
849 if (sc
->sc_flags
& IWL2100_F_DETACH
)
852 if ((ifp
->if_flags
& (IFF_OACTIVE
| IFF_RUNNING
)) != IFF_RUNNING
)
855 if ((sc
->sc_flags
& IWL2100_F_IFSTART
) == 0)
858 while (tr
->tr_used
< IWL2100_TX_USED_MAX
) {
859 struct ieee80211_frame
*wh
;
860 struct ieee80211_node
*ni
;
861 struct ether_header
*eh
;
864 m
= ifq_dequeue(&ifp
->if_snd
, NULL
);
868 if (m
->m_len
< sizeof(*eh
)) {
869 m
= m_pullup(m
, sizeof(*eh
));
875 eh
= mtod(m
, struct ether_header
*);
877 ni
= ieee80211_find_txnode(ic
, eh
->ether_dhost
);
888 m
= ieee80211_encap(ic
, m
, ni
);
890 ieee80211_free_node(ni
);
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
);
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
;
915 sc
->sc_tx_th
.wt_flags
= 0;
916 bpf_ptap(sc
->sc_drvbpf
, m
, &sc
->sc_tx_th
,
919 wh
= NULL
; /* Catch any invalid use */
921 ieee80211_free_node(ni
);
923 if (iwl2100_encap(sc
, m
)) {
932 if (tr
->tr_used
>= IWL2100_TX_USED_MAX
)
933 ifp
->if_flags
|= IFF_OACTIVE
;
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
);
941 ieee80211_drain_mgtq(&ic
->ic_mgtq
);
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
)
955 if (sc
->sc_tx_timer
) {
956 if (--sc
->sc_tx_timer
== 0) {
957 if_printf(ifp
, "watchdog timeout!\n");
965 ieee80211_watchdog(&sc
->sc_ic
);
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
;
975 ASSERT_SERIALIZED(ifp
->if_serializer
);
977 iwlmsg_init(&msg
, &sc
->sc_reply_port
, iwl2100_newstate_dispatch
, sc
);
978 msg
.iwlm_nstate
= nstate
;
981 return lwkt_domsg(&sc
->sc_thread_port
, &msg
.iwlm_nmsg
.nm_lmsg
, 0);
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
;
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
)
1010 if (sc
->sc_flags
& IWL2100_F_DETACH
) {
1012 * Except for INIT, we skip rest of the
1013 * state changes during detaching
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
1033 * XXX only if we started the IBSS
1035 error
= iwl2100_ibss(sc
);
1040 error
= sc
->sc_newstate(ic
, nstate
, arg
);
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",
1054 error
= iwl2100_scan(sc
);
1059 lwkt_replymsg(&nmsg
->nm_lmsg
, error
);
1063 iwl2100_media_change(struct ifnet
*ifp
)
1067 ASSERT_SERIALIZED(ifp
->if_serializer
);
1069 error
= ieee80211_media_change(ifp
);
1070 if (error
!= ENETRESET
)
1073 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) == (IFF_UP
| IFF_RUNNING
))
1074 iwl2100_init(ifp
->if_softc
);
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
;
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
)
1097 ieee80211_media_status(ifp
, imr
);
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)
1112 intr_status
= CSR_READ_4(sc
, IWL2100_INTR_STATUS
);
1113 if (intr_status
== 0xffffffff) /* not for us */
1116 if ((intr_status
& IWL2100_INTRS
) == 0) /* not interested */
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
);
1136 /* Leave interrupts disabled */
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
);
1151 if (intr_status
& IWL2100_INTR_TX
) {
1152 CSR_WRITE_4(sc
, IWL2100_INTR_STATUS
, IWL2100_INTR_TX
);
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
);
1164 sc
->sc_flags
&= ~IWL2100_F_IN_INTR
;
1168 iwl2100_hw_reset(struct iwl2100_softc
*sc
)
1175 * - Make GPIO3 firmware writable
1179 CSR_WRITE_4(sc
, IWL2100_GPIO
,
1180 IWL2100_GPIO_3_EN
| IWL2100_GPIO_3_FWWR
|
1181 IWL2100_GPIO_1_EN
| IWL2100_GPIO_LEDOFF
);
1188 CSR_WRITE_4(sc
, IWL2100_RESET
, IWL2100_RESET_STOP_MASTER
);
1189 for (i
= 0; i
< WAIT_MAX
; ++i
) {
1192 if (CSR_READ_4(sc
, IWL2100_RESET
) &
1193 IWL2100_RESET_MASTER_STOPPED
)
1196 if (i
== WAIT_MAX
) {
1197 if_printf(&sc
->sc_ic
.ic_if
, "can't stop master\n");
1203 CSR_WRITE_4(sc
, IWL2100_RESET
, IWL2100_RESET_SW
);
1208 iwl2100_alloc_firmware(struct iwl2100_softc
*sc
, enum ieee80211_opmode opmode
)
1213 enum ieee80211_opmode opmode
;
1214 struct iwl2100_firmware
*fw
;
1216 { "", IWL2100_FW_M_STA
, IEEE80211_M_STA
,
1218 { "-i", IWL2100_FW_M_IBSS
, IEEE80211_M_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
;
1231 for (i
= 0; fw_arr
[i
].fw
!= NULL
; ++i
) {
1234 if (fw_arr
[i
].opmode
== opmode
) {
1235 if (fw
->fw_image
!= NULL
)
1241 KASSERT(fw_arr
[i
].fw
!= NULL
, ("unsupported opmode %u\n", opmode
));
1243 ksnprintf(filename
, sizeof(filename
), IWL2100_FW_PATH
,
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
);
1255 fw
->fw_image
= image
;
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);
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
);
1275 if (hdr
->data_size
+ hdr
->ucode_size
+ sizeof(*hdr
) !=
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
));
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
;
1290 firmware_image_unload(fw
->fw_image
);
1291 bzero(fw
, sizeof(*fw
));
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
};
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
));
1314 iwl2100_load_firmware(struct iwl2100_softc
*sc
, enum ieee80211_opmode opmode
)
1316 static const struct {
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
},
1327 const struct iwl2100_firmware
*fw
= NULL
;
1331 * Pick up the firmware image corresponding to
1332 * the current operation mode
1335 case IEEE80211_M_STA
:
1336 fw
= &sc
->sc_fw_sta
;
1338 case IEEE80211_M_IBSS
:
1339 fw
= &sc
->sc_fw_ibss
;
1341 case IEEE80211_M_MONITOR
:
1342 fw
= &sc
->sc_fw_monitor
;
1345 panic("unsupported opmode %d\n", opmode
);
1348 KASSERT(fw
->fw_image
!= NULL
,
1349 ("opmode %d firmware image is not allocated yet\n", opmode
));
1352 error
= iwl2100_load_fw_ucode(sc
, fw
);
1357 error
= iwl2100_reset(sc
);
1362 error
= iwl2100_load_fw_data(sc
, fw
);
1366 /* Clear shared memory */
1367 for (i
= 0; share_mem
[i
].size
!= 0; ++i
) {
1368 uint32_t addr
= share_mem
[i
].addr
;
1371 for (j
= 0; j
< share_mem
[i
].size
; j
+= 4)
1372 IND_WRITE_4(sc
, addr
+ j
, 0);
1378 #define IND_WRITE_FLUSH_2(sc, reg, val) \
1380 IND_WRITE_2((sc), (reg), (val)); \
1381 CSR_READ_4((sc), 0); \
1384 #define IND_WRITE_FLUSH_1(sc, reg, val) \
1386 IND_WRITE_1((sc), (reg), (val)); \
1387 CSR_READ_4((sc), 0); \
1390 /* XXX need more comment */
1392 iwl2100_load_fw_ucode(struct iwl2100_softc
*sc
,
1393 const struct iwl2100_firmware
*fw
)
1395 struct iwl2100_ucode_resp resp
;
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);
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);
1434 for (i
= 0; i
< WAIT_MAX
; ++i
) {
1437 if (IND_READ_1(sc
, 0x210000) & 0x1)
1440 if (i
== WAIT_MAX
) {
1441 if_printf(&sc
->sc_ic
.ic_if
,
1442 "wait ucode symbol init timed out\n");
1448 for (i
= 0; i
< WAIT_MAX
; ++i
) {
1449 uint16_t *r
= (uint16_t *)&resp
;
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)
1459 if (i
== WAIT_MAX
) {
1460 if_printf(&sc
->sc_ic
.ic_if
,
1461 "wait ucode response timed out\n");
1467 IND_WRITE_4(sc
, IWL2100_IND_HALT
, 0);
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],
1480 #undef IND_WRITE_FLUSH_1
1481 #undef IND_WRITE_FLUSH_2
1484 iwl2100_load_fw_data(struct iwl2100_softc
*sc
,
1485 const struct iwl2100_firmware
*fw
)
1487 const uint8_t *p
= fw
->fw_data
;
1490 while (w
< fw
->fw_data_size
) {
1491 const struct iwl2100_fwdata_hdr
*h
;
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");
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",
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");
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
]);
1524 KKASSERT(w
== fw
->fw_data_size
);
1530 iwl2100_free_tx_ring(struct iwl2100_softc
*sc
)
1532 struct iwl2100_tx_ring
*tr
= &sc
->sc_txring
;
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
;
1544 m_freem(tb
->tb_mbuf
);
1550 bzero(tr
->tr_desc
, IWL2100_TXRING_SIZE
);
1551 bus_dmamap_sync(tr
->tr_dtag
, tr
->tr_dmap
, BUS_DMASYNC_PREWRITE
);
1559 iwl2100_free_rx_ring(struct iwl2100_softc
*sc
)
1561 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
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
);
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
);
1584 iwl2100_free_cmd(struct iwl2100_softc
*sc
)
1586 if (sc
->sc_cmd
!= NULL
) {
1587 m_freem(sc
->sc_cmd
);
1593 iwl2100_init_tx_ring(struct iwl2100_softc
*sc
)
1595 struct iwl2100_tx_ring
*tr
= &sc
->sc_txring
;
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
);
1613 iwl2100_init_rx_ring(struct iwl2100_softc
*sc
)
1615 struct iwl2100_rx_ring
*rr
= &sc
->sc_rxring
;
1618 for (i
= 0; i
< IWL2100_RX_NDESC
; ++i
) {
1619 error
= iwl2100_newbuf(sc
, i
, 1);
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
);
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
)
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
;
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
);
1668 if_printf(&sc
->sc_ic
.ic_if
, "m_getcl failed\n");
1674 m
->m_len
= m
->m_pkthdr
.len
= MCLBYTES
;
1677 * Try load RX mbuf into temporary DMA map
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) {
1686 bus_dmamap_unload(sc
->sc_mbuf_dtag
, rr
->rr_tmp_dmap
);
1688 if_printf(&sc
->sc_ic
.ic_if
, "too many segments?!\n");
1693 if_printf(&sc
->sc_ic
.ic_if
, "can't load RX mbuf\n");
1701 bus_dmamap_unload(sc
->sc_mbuf_dtag
, rb
->rb_dmap
);
1703 rb
->rb_paddr
= seg
.ds_addr
;
1706 * Swap RX buf's DMA map with the loaded temporary one
1709 rb
->rb_dmap
= rr
->rr_tmp_dmap
;
1710 rr
->rr_tmp_dmap
= dmap
;
1714 iwl2100_rxdesc_setup(sc
, buf_idx
);
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
;
1739 iwl2100_init_firmware(struct iwl2100_softc
*sc
)
1741 struct ifnet
*ifp
= &sc
->sc_ic
.ic_if
;
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
) {
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
);
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");
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
);
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
;
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;
1807 if ((len
* i
) < buflen
)
1811 i
= addr
& IND_ALIGN_MASK
;
1812 addr
&= ~IND_ALIGN_MASK
;
1816 KKASSERT(i
< IND_ALIGN
);
1817 if (buflen
+ i
< IND_ALIGN
)
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
);
1835 len
= buflen
& ~IND_ALIGN_MASK
;
1836 buflen
&= IND_ALIGN_MASK
;
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
);
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
);
1854 #undef IND_ALIGN_MASK
1858 iwl2100_read_ord1(struct iwl2100_softc
*sc
, uint32_t ofs
)
1862 addr
= IND_READ_4(sc
, sc
->sc_ord1
+ (ofs
<< 2));
1863 return IND_READ_4(sc
, addr
);
1867 iwl2100_write_ord1(struct iwl2100_softc
*sc
, uint32_t ofs
, uint32_t val
)
1871 addr
= IND_READ_4(sc
, sc
->sc_ord1
+ (ofs
<< 2));
1872 IND_WRITE_4(sc
, addr
, val
);
1876 iwl2100_rfkilled(struct iwl2100_softc
*sc
)
1880 if ((sc
->sc_caps
& IWL2100_C_RFKILL
) == 0)
1885 for (i
= 0; i
< TEST_MAX
; ++i
) {
1888 if (CSR_READ_4(sc
, IWL2100_GPIO
) & IWL2100_GPIO_RFKILLED
)
1891 if (i
!= TEST_MAX
) {
1892 if_printf(&sc
->sc_ic
.ic_if
, "RF killed\n");
1902 iwl2100_set_addr(struct iwl2100_softc
*sc
, const uint8_t *eaddr
)
1904 struct iwl2100_cmd
*cmd
;
1907 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
1908 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
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
);
1921 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
1928 iwl2100_set_opmode(struct iwl2100_softc
*sc
, enum ieee80211_opmode opmode
)
1930 struct iwl2100_cmd
*cmd
;
1933 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
1934 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
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]);
1944 case IEEE80211_M_STA
:
1945 cmd
->c_param
[0] = IWL2100_OPMODE_STA
;
1947 case IEEE80211_M_IBSS
:
1948 cmd
->c_param
[0] = IWL2100_OPMODE_IBSS
;
1950 case IEEE80211_M_MONITOR
:
1951 /* YYY ipw2100 leave this unset */
1952 cmd
->c_param
[0] = IWL2100_OPMODE_MONITOR
;
1955 panic("unsupported opmode %d\n", opmode
);
1959 error
= iwl2100_wait_cmd(sc
);
1961 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
1968 iwl2100_set_80211(struct iwl2100_softc
*sc
)
1970 struct ieee80211com
*ic
= &sc
->sc_ic
;
1971 struct iwl2100_cmd
*cmd
;
1974 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
1975 if_printf(&ic
->ic_if
, "there is command pending\n");
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
);
1995 if_printf(&ic
->ic_if
, "%s failed\n", __func__
);
2002 iwl2100_set_basicrates(struct iwl2100_softc
*sc
)
2004 struct iwl2100_cmd
*cmd
;
2007 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2008 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
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
);
2025 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2032 iwl2100_set_txrates(struct iwl2100_softc
*sc
)
2034 struct ieee80211com
*ic
= &sc
->sc_ic
;
2035 struct iwl2100_cmd
*cmd
;
2039 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2040 if_printf(&ic
->ic_if
, "there is command pending\n");
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
;
2048 rate_mask
= 0xf; /* all 11b rates */
2049 KKASSERT((rate_mask
& ~0xf) == 0);
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
);
2063 if_printf(&ic
->ic_if
, "%s failed\n", __func__
);
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
);
2079 if_printf(&ic
->ic_if
, "%s failed\n", __func__
);
2086 iwl2100_set_powersave(struct iwl2100_softc
*sc
, int on
)
2088 struct iwl2100_cmd
*cmd
;
2091 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2092 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
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
);
2105 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2112 iwl2100_set_rtsthreshold(struct iwl2100_softc
*sc
, uint16_t rtsthreshold
)
2114 struct iwl2100_cmd
*cmd
;
2117 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2118 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
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
;
2131 if (rtsthreshold
>= IWL2100_RTS_MAX
)
2132 rtsthreshold
= IWL2100_RTS_MAX
- 1;
2133 cmd
->c_param
[0] = rtsthreshold
;
2136 error
= iwl2100_wait_cmd(sc
);
2138 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2145 iwl2100_set_bssid(struct iwl2100_softc
*sc
, const uint8_t *bssid
)
2147 struct iwl2100_cmd
*cmd
;
2150 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2151 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
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
);
2166 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2173 iwl2100_set_essid(struct iwl2100_softc
*sc
, const uint8_t *essid
, int essid_len
)
2175 struct iwl2100_cmd
*cmd
;
2178 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2179 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
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
;
2191 bcopy(essid
, cmd
->c_param
, essid_len
);
2194 error
= iwl2100_wait_cmd(sc
);
2196 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
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
;
2210 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2211 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
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
;
2230 sec
->sec_authmode
= IWL2100_AUTH_OPEN
;
2232 error
= iwl2100_wait_cmd(sc
);
2234 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2241 iwl2100_set_wepkey(struct iwl2100_softc
*sc
, const struct ieee80211_key
*k
)
2243 struct iwl2100_cmdparam_wepkey
*key
;
2244 struct iwl2100_cmd
*cmd
;
2247 if (k
->wk_keylen
> IWL2100_KEYDATA_SIZE
)
2250 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2251 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
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
);
2267 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2274 iwl2100_set_weptxkey(struct iwl2100_softc
*sc
, ieee80211_keyix txkey
)
2276 struct iwl2100_cmd
*cmd
;
2279 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2280 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
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
);
2293 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2300 iwl2100_set_privacy(struct iwl2100_softc
*sc
, int on
)
2302 struct iwl2100_cmd
*cmd
;
2305 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2306 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
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
);
2319 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
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
;
2337 ASSERT_SERIALIZED(ifp
->if_serializer
);
2339 KKASSERT(tr
->tr_index
< IWL2100_TX_NDESC
);
2340 tb
= &tr
->tr_buf
[tr
->tr_index
];
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) {
2348 bus_dmamap_unload(sc
->sc_mbuf_dtag
, tb
->tb_dmap
);
2350 if_printf(ifp
, "too many segments?!\n");
2353 if_printf(ifp
, "can't load RX mbuf\n");
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
);
2363 d
->d_flags
= IWL2100_TXD_F_INTR
| IWL2100_TXD_F_CMD
;
2365 KKASSERT(tr
->tr_used
< IWL2100_TX_NDESC
);
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
);
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");
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
;
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
);
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
];
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
);
2422 case IWL2100_RXS_TYPE_STATUS
:
2423 iwl2100_rxeof_status(sc
, i
);
2426 case IWL2100_RXS_TYPE_NOTE
:
2427 iwl2100_rxeof_note(sc
, i
);
2430 case IWL2100_RXS_TYPE_DATA
:
2431 case IWL2100_RXS_TYPE_DATA1
:
2432 iwl2100_rxeof_data(sc
, i
);
2436 if_printf(ifp
, "unknown frame type: %d\n", frame_type
);
2437 iwl2100_rxdesc_setup(sc
, i
);
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
);
2446 rr
->rr_index
= IWL2100_RX_NDESC
- 1;
2448 rr
->rr_index
= i
- 1;
2449 CSR_WRITE_4(sc
, IWL2100_RXQ_WRITE_IDX
, rr
->rr_index
);
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
;
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
);
2466 KKASSERT(tr
->tr_coll
< IWL2100_TX_NDESC
);
2467 while (tr
->tr_used
) {
2468 struct iwl2100_txbuf
*tb
;
2470 if (tr
->tr_coll
== hwidx
)
2473 tb
= &tr
->tr_buf
[tr
->tr_coll
];
2474 if (tb
->tb_mbuf
== NULL
)
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
);
2482 m_freem(tb
->tb_mbuf
);
2486 tr
->tr_coll
= (tr
->tr_coll
+ 1) % IWL2100_TX_NDESC
;
2488 KKASSERT(tr
->tr_used
> 0);
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
;
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
;
2511 if (ic
->ic_opmode
== IEEE80211_M_MONITOR
) {
2512 error
= iwl2100_set_chan(sc
, ic
->ic_curchan
);
2514 if_printf(ifp
, "can't set mon channel\n");
2519 IEEE80211_ADDR_COPY(ic
->ic_myaddr
, IF_LLADDR(ifp
));
2520 error
= iwl2100_set_addr(sc
, ic
->ic_myaddr
);
2522 if_printf(ifp
, "can't set MAC address\n");
2526 error
= iwl2100_set_opmode(sc
, ic
->ic_opmode
);
2528 if_printf(ifp
, "can't set opmode\n");
2533 KKASSERT(ic
->ic_opmode
== IEEE80211_M_IBSS
);
2534 error
= iwl2100_set_chan(sc
, ic
->ic_curchan
);
2536 if_printf(ifp
, "can't set ibss channel\n");
2541 error
= iwl2100_set_80211(sc
);
2543 if_printf(ifp
, "can't set 802.11 config\n");
2547 error
= iwl2100_set_basicrates(sc
);
2549 if_printf(ifp
, "can't set basicrates\n");
2553 error
= iwl2100_set_txrates(sc
);
2555 if_printf(ifp
, "can't set TX rates\n");
2559 error
= iwl2100_set_powersave(sc
, ic
->ic_flags
& IEEE80211_F_PMGTON
);
2561 if_printf(ifp
, "can't turn off powersave\n");
2565 error
= iwl2100_set_rtsthreshold(sc
, ic
->ic_rtsthreshold
);
2567 if_printf(ifp
, "can't set RTS threshold\n");
2571 error
= iwl2100_set_bssid(sc
, bssid
);
2573 if_printf(ifp
, "can't set bssid\n");
2577 error
= iwl2100_set_essid(sc
, essid
, esslen
);
2579 if_printf(ifp
, "can't set essid\n");
2583 error
= iwl2100_set_auth_ciphers(sc
, ic
->ic_bss
->ni_authmode
);
2585 if_printf(ifp
, "can't set authmode and ciphers\n");
2589 if (ic
->ic_flags
& IEEE80211_F_PRIVACY
) {
2590 ieee80211_keyix txkey
= IEEE80211_KEYIX_NONE
;
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
)
2599 error
= iwl2100_set_wepkey(sc
, k
);
2600 if (error
== E2BIG
) {
2603 if_printf(ifp
, "can't set wepkey\n");
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
2617 if (ic
->ic_def_txkey
!= IEEE80211_KEYIX_NONE
)
2618 txkey
= ic
->ic_def_txkey
;
2620 error
= iwl2100_set_weptxkey(sc
, txkey
);
2622 if_printf(ifp
, "can't set weptxkey\n");
2628 error
= iwl2100_set_privacy(sc
, ic
->ic_flags
& IEEE80211_F_PRIVACY
);
2630 if_printf(ifp
, "can't set privacy\n");
2634 error
= iwl2100_set_optie(sc
, ic
->ic_opt_ie
, ic
->ic_opt_ie_len
);
2636 if (error
!= E2BIG
) {
2637 if_printf(ifp
, "can't set opt ie\n");
2642 if (ic
->ic_opmode
== IEEE80211_M_IBSS
) {
2643 error
= iwl2100_set_bintval(sc
, ic
->ic_bss
->ni_intval
);
2645 if_printf(ifp
, "can't set bintval\n");
2649 error
= iwl2100_set_txpower(sc
, 32 /* XXX */);
2651 if_printf(ifp
, "can't set txpwr\n");
2659 iwl2100_config_op(struct iwl2100_softc
*sc
, uint32_t op
)
2661 struct iwl2100_cmd
*cmd
;
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");
2672 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2673 bzero(cmd
, sizeof(cmd
));
2676 error
= iwl2100_wait_cmd(sc
);
2678 if_printf(&sc
->sc_ic
.ic_if
, "%s(%u) failed\n", __func__
, op
);
2682 iwl2100_read_ord1(sc
, IWL2100_ORD1_CONF_START
); /* dummy read */
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
;
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");
2702 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2703 if_printf(&ic
->ic_if
, "there is command pending\n");
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
);
2716 if_printf(&ic
->ic_if
, "%s failed\n", __func__
);
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
;
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");
2736 cmd
= mtod(sc
->sc_cmd
, struct iwl2100_cmd
*);
2737 bzero(cmd
, sizeof(cmd
));
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
);
2755 if_printf(&ic
->ic_if
, "%s failed\n", __func__
);
2762 iwl2100_set_scan(struct iwl2100_softc
*sc
)
2764 struct ieee80211com
*ic
= &sc
->sc_ic
;
2765 struct iwl2100_cmd
*cmd
;
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");
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
);
2783 if_printf(&ic
->ic_if
, "%s failed\n", __func__
);
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
;
2796 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2797 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
2801 if (optie_len
> IWL2100_OPTIE_MAX
) {
2802 if_printf(&sc
->sc_ic
.ic_if
, "optie too long\n");
2806 if (optie
== NULL
|| optie_len
== 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
);
2820 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2827 iwl2100_set_bintval(struct iwl2100_softc
*sc
, uint16_t bintval
)
2829 struct iwl2100_cmd
*cmd
;
2832 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2833 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
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
);
2846 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
2853 iwl2100_set_txpower(struct iwl2100_softc
*sc
, uint16_t txpower
)
2855 struct iwl2100_cmd
*cmd
;
2858 if (sc
->sc_flags
& IWL2100_F_WAITCMD
) {
2859 if_printf(&sc
->sc_ic
.ic_if
, "there is command pending\n");
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
);
2872 if_printf(&sc
->sc_ic
.ic_if
, "%s failed\n", __func__
);
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
;
2889 if (st
->r_len
!= sizeof(status
)) {
2890 if_printf(ifp
, "invalid status frame len %u\n", st
->r_len
);
2894 if (ic
->ic_opmode
== IEEE80211_M_MONITOR
)
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
);
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
);
2915 sc
->sc_flags
|= IWL2100_F_SCANNING
;
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",
2929 sc
->sc_flags
|= IWL2100_F_IFSTART
;
2932 KKASSERT(ic
->ic_opmode
== IEEE80211_M_IBSS
);
2933 callout_reset(&sc
->sc_ibss
, (100 * hz
) / 1000,
2934 iwl2100_ibss_bssid
, sc
);
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
);
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
);
2955 iwl2100_rxdesc_setup(sc
, i
);
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
);
2973 if (ic
->ic_opmode
== IEEE80211_M_MONITOR
)
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
);
2986 iwl2100_rxdesc_setup(sc
, i
);
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
);
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
;
3010 iwl2100_rxdesc_setup(sc
, i
);
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.
3032 frame_len
= st
->r_len
;
3034 if (iwl2100_newbuf(sc
, i
, 0)) {
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
);
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
;
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
);
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
)
3082 if (ifp
->if_flags
& IFF_RUNNING
) {
3083 ieee80211_end_scan(ic
);
3084 sc
->sc_flags
&= ~IWL2100_F_SCANNING
;
3087 lwkt_replymsg(&nmsg
->nm_lmsg
, 0);
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
;
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
);
3106 if_printf(ifp
, "can't allocate firmware\n");
3110 error
= iwl2100_load_firmware(sc
, ic
->ic_opmode
);
3112 if_printf(ifp
, "can't load firmware\n");
3116 error
= iwl2100_alloc_cmd(sc
);
3118 if_printf(ifp
, "can't allocate cmd\n");
3122 error
= iwl2100_init_tx_ring(sc
);
3124 if_printf(ifp
, "can't init TX ring\n");
3128 error
= iwl2100_init_rx_ring(sc
);
3130 if_printf(ifp
, "can't init RX ring\n");
3134 error
= iwl2100_init_firmware(sc
);
3136 if_printf(ifp
, "can't initialize firmware\n");
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
;
3147 sc
->sc_caps
|= IWL2100_C_RFKILL
;
3149 /* Unlock firmware */
3150 iwl2100_write_ord1(sc
, IWL2100_ORD1_FWLOCK
, 0);
3152 if (iwl2100_rfkilled(sc
)) {
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
);
3168 if (flags
& IWL2100_INIT_F_ENABLE
) {
3169 error
= iwl2100_config_done(sc
);
3171 if_printf(ifp
, "can't complete config\n");
3176 ifp
->if_flags
&= ~IFF_OACTIVE
;
3177 ifp
->if_flags
|= IFF_RUNNING
;
3185 iwl2100_start_scan(struct iwl2100_softc
*sc
, uint32_t chans
, uint32_t flags
)
3191 * Firmware always starts scanning once config is done
3193 error
= iwl2100_set_scanopt(sc
, chans
, flags
);
3195 if_printf(&sc
->sc_ic
.ic_if
, "can't set scan opt\n");
3199 error
= iwl2100_set_scan(sc
);
3201 if_printf(&sc
->sc_ic
.ic_if
, "can't set bcast scanning\n");
3208 iwl2100_scan(struct iwl2100_softc
*sc
)
3210 struct ieee80211com
*ic
= &sc
->sc_ic
;
3211 uint32_t chans
, flags
;
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
);
3221 if (ic
->ic_opmode
== IEEE80211_M_STA
) {
3222 chans
= sc
->sc_bss_chans
;
3223 flags
= IWL2100_SCANOPT_NOASSOC
;
3226 * Normally # of IBSS channels is less than BSS's
3227 * but it seems IBSS mode works on all BSS channels
3230 chans
= sc
->sc_ibss_chans
;
3232 chans
= sc
->sc_bss_chans
;
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
3244 /* See NOTE in iwl2100_set_scanopt() */
3245 error
= iwl2100_start_scan(sc
, chans
, flags
);
3252 iwl2100_auth(struct iwl2100_softc
*sc
)
3254 struct ieee80211com
*ic
= &sc
->sc_ic
;
3255 struct ieee80211_node
*ni
= ic
->ic_bss
;
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");
3267 error
= iwl2100_hw_init(sc
, ni
->ni_bssid
,
3268 ni
->ni_essid
, ni
->ni_esslen
, IWL2100_INIT_F_ENABLE
);
3272 /* See NOTE in iwl2100_set_scanopt() */
3273 error
= iwl2100_start_scan(sc
, 1 << (chan
- 1), 0);
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
);
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
];
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
);
3310 IEEE80211_ADDR_COPY(dst
, wh
->i_addr1
);
3311 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
)
3315 m_adj(m
, sizeof(*wh
));
3318 * Prepend and setup hardware TX header
3320 M_PREPEND(m
, sizeof(*th
), MB_DONTWAIT
);
3322 if_printf(&sc
->sc_ic
.ic_if
, "prepend TX header failed\n");
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
;
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
);
3352 if (error
&& error
!= EFBIG
) {
3353 if_printf(&sc
->sc_ic
.ic_if
, "can't load TX mbuf, error %d\n",
3357 if (error
) { /* error == EFBIG */
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");
3369 ctx
.nsegs
= maxsegs
;
3371 error
= bus_dmamap_load_mbuf(sc
->sc_mbuf_dtag
, dmap
, m
,
3372 iwl_dma_buf_addr
, &ctx
,
3374 if (error
|| ctx
.nsegs
== 0) {
3375 if (ctx
.nsegs
== 0) {
3376 bus_dmamap_unload(sc
->sc_mbuf_dtag
, dmap
);
3379 if_printf(&sc
->sc_ic
.ic_if
,
3380 "can't load defraged TX mbuf\n");
3384 bus_dmamap_sync(sc
->sc_mbuf_dtag
, dmap
, BUS_DMASYNC_PREWRITE
);
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
;
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
;
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
);
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
;
3434 ASSERT_SERIALIZED(ifp
->if_serializer
);
3436 if (sc
->sc_flags
& IWL2100_F_DETACH
)
3439 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
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.
3450 if (ic
->ic_state
!= IEEE80211_S_RUN
) {
3451 if_printf(ifp
, "restart happened when not in RUN state\n");
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
);
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
);
3480 /* Turn on restarting flag before reply this message */
3481 sc
->sc_flags
|= IWL2100_F_RESTARTING
;
3483 lwkt_replymsg(&nmsg
->nm_lmsg
, error
);
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
);
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
)
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
);
3524 lwkt_replymsg(&nmsg
->nm_lmsg
, 0);
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
)
3538 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
3541 if (sc
->sc_flags
& IWL2100_F_RESTARTING
) {
3542 DPRINTF(sc
, IWL2100_DBG_SCAN
| IWL2100_DBG_RESTART
, "%s",
3544 iwlmsg_send(&sc
->sc_bmiss_msg
, &sc
->sc_thread_port
);
3547 lwkt_serialize_exit(ifp
->if_serializer
);
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
)
3562 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
3565 if (ic
->ic_state
== IEEE80211_S_RUN
&&
3566 ic
->ic_opmode
== IEEE80211_M_IBSS
) {
3567 uint8_t bssid
[IEEE80211_ADDR_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");
3575 DPRINTF(sc
, IWL2100_DBG_IBSS
, "IBSS bssid: %6D\n",
3577 IEEE80211_ADDR_COPY(ic
->ic_bss
->ni_bssid
, bssid
);
3579 sc
->sc_flags
|= IWL2100_F_IFSTART
;
3584 lwkt_serialize_exit(ifp
->if_serializer
);
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
;
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
;
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
);
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
)
3632 if ((ifp
->if_flags
& (IFF_UP
| IFF_RUNNING
)) == IFF_UP
)
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)
3645 lwkt_serialize_exit(ifp
->if_serializer
);
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
);
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
);