if_iwi.c revision 1.4.4.5 1 1.4.4.5 christos /* $NetBSD: if_iwi.c,v 1.4.4.5 2005/12/11 10:28:58 christos Exp $ */
2 1.4.4.2 skrll
3 1.4.4.2 skrll /*-
4 1.4.4.2 skrll * Copyright (c) 2004, 2005
5 1.4.4.2 skrll * Damien Bergamini <damien.bergamini (at) free.fr>. All rights reserved.
6 1.4.4.2 skrll *
7 1.4.4.2 skrll * Redistribution and use in source and binary forms, with or without
8 1.4.4.2 skrll * modification, are permitted provided that the following conditions
9 1.4.4.2 skrll * are met:
10 1.4.4.2 skrll * 1. Redistributions of source code must retain the above copyright
11 1.4.4.2 skrll * notice unmodified, this list of conditions, and the following
12 1.4.4.2 skrll * disclaimer.
13 1.4.4.2 skrll * 2. Redistributions in binary form must reproduce the above copyright
14 1.4.4.2 skrll * notice, this list of conditions and the following disclaimer in the
15 1.4.4.2 skrll * documentation and/or other materials provided with the distribution.
16 1.4.4.2 skrll *
17 1.4.4.2 skrll * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 1.4.4.2 skrll * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 1.4.4.2 skrll * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 1.4.4.2 skrll * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 1.4.4.2 skrll * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 1.4.4.2 skrll * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 1.4.4.2 skrll * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 1.4.4.2 skrll * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 1.4.4.2 skrll * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 1.4.4.2 skrll * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 1.4.4.2 skrll * SUCH DAMAGE.
28 1.4.4.2 skrll */
29 1.4.4.2 skrll
30 1.4.4.2 skrll #include <sys/cdefs.h>
31 1.4.4.5 christos __KERNEL_RCSID(0, "$NetBSD: if_iwi.c,v 1.4.4.5 2005/12/11 10:28:58 christos Exp $");
32 1.4.4.2 skrll
33 1.4.4.2 skrll /*-
34 1.4.4.4 skrll * Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver
35 1.4.4.2 skrll * http://www.intel.com/network/connectivity/products/wireless/prowireless_mobile.htm
36 1.4.4.2 skrll */
37 1.4.4.2 skrll
38 1.4.4.2 skrll #include "bpfilter.h"
39 1.4.4.2 skrll
40 1.4.4.2 skrll #include <sys/param.h>
41 1.4.4.2 skrll #include <sys/sockio.h>
42 1.4.4.2 skrll #include <sys/sysctl.h>
43 1.4.4.2 skrll #include <sys/mbuf.h>
44 1.4.4.2 skrll #include <sys/kernel.h>
45 1.4.4.2 skrll #include <sys/socket.h>
46 1.4.4.2 skrll #include <sys/systm.h>
47 1.4.4.2 skrll #include <sys/malloc.h>
48 1.4.4.2 skrll #include <sys/conf.h>
49 1.4.4.2 skrll
50 1.4.4.2 skrll #include <machine/bus.h>
51 1.4.4.2 skrll #include <machine/endian.h>
52 1.4.4.2 skrll #include <machine/intr.h>
53 1.4.4.2 skrll
54 1.4.4.2 skrll #include <dev/pci/pcireg.h>
55 1.4.4.2 skrll #include <dev/pci/pcivar.h>
56 1.4.4.2 skrll #include <dev/pci/pcidevs.h>
57 1.4.4.2 skrll
58 1.4.4.2 skrll #if NBPFILTER > 0
59 1.4.4.2 skrll #include <net/bpf.h>
60 1.4.4.2 skrll #endif
61 1.4.4.2 skrll #include <net/if.h>
62 1.4.4.2 skrll #include <net/if_arp.h>
63 1.4.4.2 skrll #include <net/if_dl.h>
64 1.4.4.2 skrll #include <net/if_ether.h>
65 1.4.4.2 skrll #include <net/if_media.h>
66 1.4.4.2 skrll #include <net/if_types.h>
67 1.4.4.2 skrll
68 1.4.4.2 skrll #include <net80211/ieee80211_var.h>
69 1.4.4.2 skrll #include <net80211/ieee80211_radiotap.h>
70 1.4.4.2 skrll
71 1.4.4.2 skrll #include <netinet/in.h>
72 1.4.4.2 skrll #include <netinet/in_systm.h>
73 1.4.4.2 skrll #include <netinet/in_var.h>
74 1.4.4.2 skrll #include <netinet/ip.h>
75 1.4.4.2 skrll
76 1.4.4.2 skrll #include <crypto/arc4/arc4.h>
77 1.4.4.2 skrll
78 1.4.4.2 skrll #include <dev/pci/if_iwireg.h>
79 1.4.4.2 skrll #include <dev/pci/if_iwivar.h>
80 1.4.4.2 skrll
81 1.4.4.4 skrll #ifdef IWI_DEBUG
82 1.4.4.4 skrll #define DPRINTF(x) if (iwi_debug > 0) printf x
83 1.4.4.4 skrll #define DPRINTFN(n, x) if (iwi_debug >= (n)) printf x
84 1.4.4.4 skrll int iwi_debug = 4;
85 1.4.4.4 skrll #else
86 1.4.4.4 skrll #define DPRINTF(x)
87 1.4.4.4 skrll #define DPRINTFN(n, x)
88 1.4.4.4 skrll #endif
89 1.4.4.4 skrll
90 1.4.4.4 skrll static int iwi_match(struct device *, struct cfdata *, void *);
91 1.4.4.4 skrll static void iwi_attach(struct device *, struct device *, void *);
92 1.4.4.4 skrll static int iwi_detach(struct device *, int);
93 1.4.4.4 skrll
94 1.4.4.4 skrll static void iwi_shutdown(void *);
95 1.4.4.4 skrll static int iwi_suspend(struct iwi_softc *);
96 1.4.4.4 skrll static int iwi_resume(struct iwi_softc *);
97 1.4.4.4 skrll static void iwi_powerhook(int, void *);
98 1.4.4.4 skrll
99 1.4.4.4 skrll static int iwi_alloc_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *,
100 1.4.4.4 skrll int);
101 1.4.4.4 skrll static void iwi_reset_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
102 1.4.4.4 skrll static void iwi_free_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
103 1.4.4.4 skrll static int iwi_alloc_tx_ring(struct iwi_softc *, struct iwi_tx_ring *,
104 1.4.4.5 christos int, bus_addr_t, bus_addr_t);
105 1.4.4.4 skrll static void iwi_reset_tx_ring(struct iwi_softc *, struct iwi_tx_ring *);
106 1.4.4.4 skrll static void iwi_free_tx_ring(struct iwi_softc *, struct iwi_tx_ring *);
107 1.4.4.4 skrll static struct mbuf *
108 1.4.4.4 skrll iwi_alloc_rx_buf(struct iwi_softc *sc);
109 1.4.4.4 skrll static int iwi_alloc_rx_ring(struct iwi_softc *, struct iwi_rx_ring *,
110 1.4.4.4 skrll int);
111 1.4.4.4 skrll static void iwi_reset_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
112 1.4.4.4 skrll static void iwi_free_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
113 1.4.4.4 skrll
114 1.4.4.5 christos static struct ieee80211_node *iwi_node_alloc(struct ieee80211_node_table *);
115 1.4.4.5 christos static void iwi_node_free(struct ieee80211_node *);
116 1.4.4.5 christos
117 1.4.4.4 skrll static int iwi_media_change(struct ifnet *);
118 1.4.4.4 skrll static void iwi_media_status(struct ifnet *, struct ifmediareq *);
119 1.4.4.5 christos static int iwi_wme_update(struct ieee80211com *);
120 1.4.4.4 skrll static uint16_t iwi_read_prom_word(struct iwi_softc *, uint8_t);
121 1.4.4.4 skrll static int iwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
122 1.4.4.4 skrll static void iwi_fix_channel(struct ieee80211com *, struct mbuf *);
123 1.4.4.4 skrll static void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int,
124 1.4.4.4 skrll struct iwi_frame *);
125 1.4.4.4 skrll static void iwi_notification_intr(struct iwi_softc *, struct iwi_notif *);
126 1.4.4.5 christos static void iwi_cmd_intr(struct iwi_softc *);
127 1.4.4.4 skrll static void iwi_rx_intr(struct iwi_softc *);
128 1.4.4.5 christos static void iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *);
129 1.4.4.4 skrll static int iwi_intr(void *);
130 1.4.4.4 skrll static int iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t, int);
131 1.4.4.5 christos static void iwi_write_ibssnode(struct iwi_softc *, const struct iwi_node *);
132 1.4.4.5 christos static int iwi_tx_start(struct ifnet *, struct mbuf *, struct ieee80211_node *,
133 1.4.4.5 christos int);
134 1.4.4.4 skrll static void iwi_start(struct ifnet *);
135 1.4.4.4 skrll static void iwi_watchdog(struct ifnet *);
136 1.4.4.5 christos
137 1.4.4.5 christos static int iwi_alloc_unr(struct iwi_softc *);
138 1.4.4.5 christos static void iwi_free_unr(struct iwi_softc *, int);
139 1.4.4.5 christos
140 1.4.4.4 skrll static int iwi_get_table0(struct iwi_softc *, uint32_t *);
141 1.4.4.4 skrll static int iwi_get_radio(struct iwi_softc *, int *);
142 1.4.4.5 christos
143 1.4.4.4 skrll static int iwi_ioctl(struct ifnet *, u_long, caddr_t);
144 1.4.4.4 skrll static void iwi_stop_master(struct iwi_softc *);
145 1.4.4.4 skrll static int iwi_reset(struct iwi_softc *);
146 1.4.4.4 skrll static int iwi_load_ucode(struct iwi_softc *, void *, int);
147 1.4.4.4 skrll static int iwi_load_firmware(struct iwi_softc *, void *, int);
148 1.4.4.4 skrll static int iwi_cache_firmware(struct iwi_softc *, void *);
149 1.4.4.4 skrll static void iwi_free_firmware(struct iwi_softc *);
150 1.4.4.4 skrll static int iwi_config(struct iwi_softc *);
151 1.4.4.4 skrll static int iwi_set_chan(struct iwi_softc *, struct ieee80211_channel *);
152 1.4.4.4 skrll static int iwi_scan(struct iwi_softc *);
153 1.4.4.4 skrll static int iwi_auth_and_assoc(struct iwi_softc *);
154 1.4.4.4 skrll static int iwi_init(struct ifnet *);
155 1.4.4.4 skrll static void iwi_stop(struct ifnet *, int);
156 1.4.4.5 christos static void iwi_led_set(struct iwi_softc *, uint32_t, int);
157 1.4.4.5 christos static void iwi_error_log(struct iwi_softc *);
158 1.4.4.4 skrll
159 1.4.4.4 skrll /*
160 1.4.4.4 skrll * Supported rates for 802.11a/b/g modes (in 500Kbps unit).
161 1.4.4.4 skrll */
162 1.4.4.2 skrll static const struct ieee80211_rateset iwi_rateset_11a =
163 1.4.4.2 skrll { 8, { 12, 18, 24, 36, 48, 72, 96, 108 } };
164 1.4.4.2 skrll
165 1.4.4.2 skrll static const struct ieee80211_rateset iwi_rateset_11b =
166 1.4.4.2 skrll { 4, { 2, 4, 11, 22 } };
167 1.4.4.2 skrll
168 1.4.4.2 skrll static const struct ieee80211_rateset iwi_rateset_11g =
169 1.4.4.2 skrll { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
170 1.4.4.2 skrll
171 1.4.4.4 skrll static __inline uint8_t
172 1.4.4.4 skrll MEM_READ_1(struct iwi_softc *sc, uint32_t addr)
173 1.4.4.2 skrll {
174 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_INDIRECT_ADDR, addr);
175 1.4.4.2 skrll return CSR_READ_1(sc, IWI_CSR_INDIRECT_DATA);
176 1.4.4.2 skrll }
177 1.4.4.2 skrll
178 1.4.4.4 skrll static __inline uint32_t
179 1.4.4.4 skrll MEM_READ_4(struct iwi_softc *sc, uint32_t addr)
180 1.4.4.2 skrll {
181 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_INDIRECT_ADDR, addr);
182 1.4.4.2 skrll return CSR_READ_4(sc, IWI_CSR_INDIRECT_DATA);
183 1.4.4.2 skrll }
184 1.4.4.2 skrll
185 1.4.4.5 christos static void
186 1.4.4.5 christos MEM_CPY(struct iwi_softc *sc, void *dst, uint32_t base, size_t sz)
187 1.4.4.5 christos {
188 1.4.4.5 christos KASSERT(sz % 4 == 0);
189 1.4.4.5 christos int j;
190 1.4.4.5 christos
191 1.4.4.5 christos uint32_t *p = dst;
192 1.4.4.5 christos
193 1.4.4.5 christos for (j = 0; j < sz / 4; j++)
194 1.4.4.5 christos p[j] = MEM_READ_4(sc, base + j * sizeof(uint32_t));
195 1.4.4.5 christos }
196 1.4.4.5 christos
197 1.4.4.2 skrll CFATTACH_DECL(iwi, sizeof (struct iwi_softc), iwi_match, iwi_attach,
198 1.4.4.2 skrll iwi_detach, NULL);
199 1.4.4.2 skrll
200 1.4.4.2 skrll static int
201 1.4.4.2 skrll iwi_match(struct device *parent, struct cfdata *match, void *aux)
202 1.4.4.2 skrll {
203 1.4.4.2 skrll struct pci_attach_args *pa = aux;
204 1.4.4.3 skrll
205 1.4.4.2 skrll if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
206 1.4.4.2 skrll return 0;
207 1.4.4.2 skrll
208 1.4.4.2 skrll if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_WL_2200BG ||
209 1.4.4.4 skrll PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_WL_2225BG ||
210 1.4.4.4 skrll PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_WL_2915ABG_1 ||
211 1.4.4.4 skrll PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_WL_2915ABG_2)
212 1.4.4.2 skrll return 1;
213 1.4.4.3 skrll
214 1.4.4.2 skrll return 0;
215 1.4.4.2 skrll }
216 1.4.4.2 skrll
217 1.4.4.2 skrll /* Base Address Register */
218 1.4.4.2 skrll #define IWI_PCI_BAR0 0x10
219 1.4.4.2 skrll
220 1.4.4.2 skrll static void
221 1.4.4.2 skrll iwi_attach(struct device *parent, struct device *self, void *aux)
222 1.4.4.2 skrll {
223 1.4.4.2 skrll struct iwi_softc *sc = (struct iwi_softc *)self;
224 1.4.4.2 skrll struct ieee80211com *ic = &sc->sc_ic;
225 1.4.4.4 skrll struct ifnet *ifp = &sc->sc_if;
226 1.4.4.2 skrll struct pci_attach_args *pa = aux;
227 1.4.4.2 skrll const char *intrstr;
228 1.4.4.2 skrll char devinfo[256];
229 1.4.4.2 skrll bus_space_tag_t memt;
230 1.4.4.2 skrll bus_space_handle_t memh;
231 1.4.4.2 skrll bus_addr_t base;
232 1.4.4.2 skrll pci_intr_handle_t ih;
233 1.4.4.2 skrll pcireg_t data;
234 1.4.4.4 skrll uint16_t val;
235 1.4.4.2 skrll int error, revision, i;
236 1.4.4.2 skrll
237 1.4.4.2 skrll sc->sc_pct = pa->pa_pc;
238 1.4.4.2 skrll sc->sc_pcitag = pa->pa_tag;
239 1.4.4.2 skrll
240 1.4.4.2 skrll pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof devinfo);
241 1.4.4.2 skrll revision = PCI_REVISION(pa->pa_class);
242 1.4.4.2 skrll aprint_normal(": %s (rev. 0x%02x)\n", devinfo, revision);
243 1.4.4.2 skrll
244 1.4.4.2 skrll /* clear device specific PCI configuration register 0x41 */
245 1.4.4.2 skrll data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
246 1.4.4.2 skrll data &= ~0x0000ff00;
247 1.4.4.2 skrll pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
248 1.4.4.2 skrll
249 1.4.4.5 christos /* clear unit numbers allocated to IBSS */
250 1.4.4.5 christos sc->sc_unr = 0;
251 1.4.4.5 christos
252 1.4.4.2 skrll /* enable bus-mastering */
253 1.4.4.2 skrll data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
254 1.4.4.2 skrll data |= PCI_COMMAND_MASTER_ENABLE;
255 1.4.4.2 skrll pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, data);
256 1.4.4.2 skrll
257 1.4.4.2 skrll /* map the register window */
258 1.4.4.2 skrll error = pci_mapreg_map(pa, IWI_PCI_BAR0, PCI_MAPREG_TYPE_MEM |
259 1.4.4.2 skrll PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt, &memh, &base, &sc->sc_sz);
260 1.4.4.2 skrll if (error != 0) {
261 1.4.4.2 skrll aprint_error("%s: could not map memory space\n",
262 1.4.4.2 skrll sc->sc_dev.dv_xname);
263 1.4.4.2 skrll return;
264 1.4.4.2 skrll }
265 1.4.4.2 skrll
266 1.4.4.2 skrll sc->sc_st = memt;
267 1.4.4.2 skrll sc->sc_sh = memh;
268 1.4.4.2 skrll sc->sc_dmat = pa->pa_dmat;
269 1.4.4.2 skrll
270 1.4.4.2 skrll /* disable interrupts */
271 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0);
272 1.4.4.2 skrll
273 1.4.4.2 skrll if (pci_intr_map(pa, &ih) != 0) {
274 1.4.4.2 skrll aprint_error("%s: could not map interrupt\n",
275 1.4.4.2 skrll sc->sc_dev.dv_xname);
276 1.4.4.2 skrll return;
277 1.4.4.2 skrll }
278 1.4.4.2 skrll
279 1.4.4.2 skrll intrstr = pci_intr_string(sc->sc_pct, ih);
280 1.4.4.2 skrll sc->sc_ih = pci_intr_establish(sc->sc_pct, ih, IPL_NET, iwi_intr, sc);
281 1.4.4.2 skrll if (sc->sc_ih == NULL) {
282 1.4.4.2 skrll aprint_error("%s: could not establish interrupt",
283 1.4.4.2 skrll sc->sc_dev.dv_xname);
284 1.4.4.2 skrll if (intrstr != NULL)
285 1.4.4.2 skrll aprint_error(" at %s", intrstr);
286 1.4.4.2 skrll aprint_error("\n");
287 1.4.4.2 skrll return;
288 1.4.4.2 skrll }
289 1.4.4.2 skrll aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
290 1.4.4.2 skrll
291 1.4.4.2 skrll if (iwi_reset(sc) != 0) {
292 1.4.4.2 skrll aprint_error("%s: could not reset adapter\n",
293 1.4.4.2 skrll sc->sc_dev.dv_xname);
294 1.4.4.2 skrll return;
295 1.4.4.2 skrll }
296 1.4.4.2 skrll
297 1.4.4.4 skrll /*
298 1.4.4.4 skrll * Allocate rings.
299 1.4.4.4 skrll */
300 1.4.4.4 skrll if (iwi_alloc_cmd_ring(sc, &sc->cmdq, IWI_CMD_RING_COUNT) != 0) {
301 1.4.4.4 skrll aprint_error("%s: could not allocate command ring\n",
302 1.4.4.2 skrll sc->sc_dev.dv_xname);
303 1.4.4.4 skrll goto fail;
304 1.4.4.4 skrll }
305 1.4.4.4 skrll
306 1.4.4.5 christos error = iwi_alloc_tx_ring(sc, &sc->txq[0], IWI_TX_RING_COUNT,
307 1.4.4.5 christos IWI_CSR_TX1_RIDX, IWI_CSR_TX1_WIDX);
308 1.4.4.5 christos if (error != 0) {
309 1.4.4.5 christos aprint_error("%s: could not allocate Tx ring 1\n",
310 1.4.4.5 christos sc->sc_dev.dv_xname);
311 1.4.4.5 christos goto fail;
312 1.4.4.5 christos }
313 1.4.4.5 christos
314 1.4.4.5 christos error = iwi_alloc_tx_ring(sc, &sc->txq[1], IWI_TX_RING_COUNT,
315 1.4.4.5 christos IWI_CSR_TX2_RIDX, IWI_CSR_TX2_WIDX);
316 1.4.4.5 christos if (error != 0) {
317 1.4.4.5 christos aprint_error("%s: could not allocate Tx ring 2\n",
318 1.4.4.5 christos sc->sc_dev.dv_xname);
319 1.4.4.5 christos goto fail;
320 1.4.4.5 christos }
321 1.4.4.5 christos
322 1.4.4.5 christos error = iwi_alloc_tx_ring(sc, &sc->txq[2], IWI_TX_RING_COUNT,
323 1.4.4.5 christos IWI_CSR_TX3_RIDX, IWI_CSR_TX3_WIDX);
324 1.4.4.5 christos if (error != 0) {
325 1.4.4.5 christos aprint_error("%s: could not allocate Tx ring 3\n",
326 1.4.4.5 christos sc->sc_dev.dv_xname);
327 1.4.4.5 christos goto fail;
328 1.4.4.5 christos }
329 1.4.4.5 christos
330 1.4.4.5 christos error = iwi_alloc_tx_ring(sc, &sc->txq[3], IWI_TX_RING_COUNT,
331 1.4.4.5 christos IWI_CSR_TX4_RIDX, IWI_CSR_TX4_WIDX);
332 1.4.4.5 christos if (error != 0) {
333 1.4.4.5 christos aprint_error("%s: could not allocate Tx ring 4\n",
334 1.4.4.4 skrll sc->sc_dev.dv_xname);
335 1.4.4.4 skrll goto fail;
336 1.4.4.4 skrll }
337 1.4.4.4 skrll
338 1.4.4.4 skrll if (iwi_alloc_rx_ring(sc, &sc->rxq, IWI_RX_RING_COUNT) != 0) {
339 1.4.4.4 skrll aprint_error("%s: could not allocate Rx ring\n",
340 1.4.4.4 skrll sc->sc_dev.dv_xname);
341 1.4.4.4 skrll goto fail;
342 1.4.4.2 skrll }
343 1.4.4.2 skrll
344 1.4.4.4 skrll ic->ic_ifp = ifp;
345 1.4.4.5 christos ic->ic_wme.wme_update = iwi_wme_update;
346 1.4.4.4 skrll ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
347 1.4.4.4 skrll ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
348 1.4.4.2 skrll ic->ic_state = IEEE80211_S_INIT;
349 1.4.4.2 skrll
350 1.4.4.2 skrll /* set device capabilities */
351 1.4.4.5 christos ic->ic_caps =
352 1.4.4.5 christos IEEE80211_C_IBSS | /* IBSS mode supported */
353 1.4.4.5 christos IEEE80211_C_MONITOR | /* monitor mode supported */
354 1.4.4.5 christos IEEE80211_C_TXPMGT | /* tx power management */
355 1.4.4.5 christos IEEE80211_C_SHPREAMBLE | /* short preamble supported */
356 1.4.4.5 christos IEEE80211_C_WPA | /* 802.11i */
357 1.4.4.5 christos IEEE80211_C_WME; /* 802.11e */
358 1.4.4.2 skrll
359 1.4.4.2 skrll /* read MAC address from EEPROM */
360 1.4.4.2 skrll val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0);
361 1.4.4.4 skrll ic->ic_myaddr[0] = val & 0xff;
362 1.4.4.4 skrll ic->ic_myaddr[1] = val >> 8;
363 1.4.4.2 skrll val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 1);
364 1.4.4.4 skrll ic->ic_myaddr[2] = val & 0xff;
365 1.4.4.4 skrll ic->ic_myaddr[3] = val >> 8;
366 1.4.4.2 skrll val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 2);
367 1.4.4.4 skrll ic->ic_myaddr[4] = val & 0xff;
368 1.4.4.4 skrll ic->ic_myaddr[5] = val >> 8;
369 1.4.4.2 skrll
370 1.4.4.2 skrll aprint_normal("%s: 802.11 address %s\n", sc->sc_dev.dv_xname,
371 1.4.4.2 skrll ether_sprintf(ic->ic_myaddr));
372 1.4.4.2 skrll
373 1.4.4.5 christos /* read the NIC type from EEPROM */
374 1.4.4.5 christos val = iwi_read_prom_word(sc, IWI_EEPROM_NIC_TYPE);
375 1.4.4.5 christos sc->nictype = val & 0xff;
376 1.4.4.5 christos
377 1.4.4.5 christos DPRINTF(("%s: NIC type %d\n", sc->sc_dev.dv_xname, sc->nictype));
378 1.4.4.4 skrll
379 1.4.4.4 skrll if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_WL_2915ABG_1 ||
380 1.4.4.4 skrll PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_WL_2915ABG_2) {
381 1.4.4.4 skrll /* set supported .11a rates (2915ABG only) */
382 1.4.4.2 skrll ic->ic_sup_rates[IEEE80211_MODE_11A] = iwi_rateset_11a;
383 1.4.4.2 skrll
384 1.4.4.2 skrll /* set supported .11a channels */
385 1.4.4.2 skrll for (i = 36; i <= 64; i += 4) {
386 1.4.4.2 skrll ic->ic_channels[i].ic_freq =
387 1.4.4.2 skrll ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
388 1.4.4.2 skrll ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
389 1.4.4.2 skrll }
390 1.4.4.4 skrll for (i = 149; i <= 165; i += 4) {
391 1.4.4.2 skrll ic->ic_channels[i].ic_freq =
392 1.4.4.2 skrll ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
393 1.4.4.2 skrll ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
394 1.4.4.2 skrll }
395 1.4.4.2 skrll }
396 1.4.4.2 skrll
397 1.4.4.2 skrll /* set supported .11b and .11g rates */
398 1.4.4.2 skrll ic->ic_sup_rates[IEEE80211_MODE_11B] = iwi_rateset_11b;
399 1.4.4.2 skrll ic->ic_sup_rates[IEEE80211_MODE_11G] = iwi_rateset_11g;
400 1.4.4.2 skrll
401 1.4.4.2 skrll /* set supported .11b and .11g channels (1 through 14) */
402 1.4.4.2 skrll for (i = 1; i <= 14; i++) {
403 1.4.4.2 skrll ic->ic_channels[i].ic_freq =
404 1.4.4.2 skrll ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
405 1.4.4.2 skrll ic->ic_channels[i].ic_flags =
406 1.4.4.2 skrll IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
407 1.4.4.2 skrll IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
408 1.4.4.2 skrll }
409 1.4.4.2 skrll
410 1.4.4.2 skrll ifp->if_softc = sc;
411 1.4.4.2 skrll ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
412 1.4.4.2 skrll ifp->if_init = iwi_init;
413 1.4.4.2 skrll ifp->if_stop = iwi_stop;
414 1.4.4.2 skrll ifp->if_ioctl = iwi_ioctl;
415 1.4.4.2 skrll ifp->if_start = iwi_start;
416 1.4.4.2 skrll ifp->if_watchdog = iwi_watchdog;
417 1.4.4.2 skrll IFQ_SET_READY(&ifp->if_snd);
418 1.4.4.2 skrll memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
419 1.4.4.2 skrll
420 1.4.4.2 skrll if_attach(ifp);
421 1.4.4.4 skrll ieee80211_ifattach(ic);
422 1.4.4.5 christos /* override default methods */
423 1.4.4.5 christos ic->ic_node_alloc = iwi_node_alloc;
424 1.4.4.5 christos sc->sc_node_free = ic->ic_node_free;
425 1.4.4.5 christos ic->ic_node_free = iwi_node_free;
426 1.4.4.2 skrll /* override state transition machine */
427 1.4.4.2 skrll sc->sc_newstate = ic->ic_newstate;
428 1.4.4.2 skrll ic->ic_newstate = iwi_newstate;
429 1.4.4.4 skrll ieee80211_media_init(ic, iwi_media_change, iwi_media_status);
430 1.4.4.2 skrll
431 1.4.4.2 skrll #if NBPFILTER > 0
432 1.4.4.2 skrll bpfattach2(ifp, DLT_IEEE802_11_RADIO,
433 1.4.4.2 skrll sizeof (struct ieee80211_frame) + 64, &sc->sc_drvbpf);
434 1.4.4.2 skrll
435 1.4.4.2 skrll sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
436 1.4.4.2 skrll sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
437 1.4.4.2 skrll sc->sc_rxtap.wr_ihdr.it_present = htole32(IWI_RX_RADIOTAP_PRESENT);
438 1.4.4.2 skrll
439 1.4.4.2 skrll sc->sc_txtap_len = sizeof sc->sc_txtapu;
440 1.4.4.2 skrll sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
441 1.4.4.2 skrll sc->sc_txtap.wt_ihdr.it_present = htole32(IWI_TX_RADIOTAP_PRESENT);
442 1.4.4.2 skrll #endif
443 1.4.4.4 skrll
444 1.4.4.4 skrll /*
445 1.4.4.4 skrll * Make sure the interface is shutdown during reboot.
446 1.4.4.4 skrll */
447 1.4.4.4 skrll sc->sc_sdhook = shutdownhook_establish(iwi_shutdown, sc);
448 1.4.4.4 skrll if (sc->sc_sdhook == NULL)
449 1.4.4.4 skrll aprint_error("%s: WARNING: unable to establish shutdown hook\n",
450 1.4.4.4 skrll sc->sc_dev.dv_xname);
451 1.4.4.4 skrll sc->sc_powerhook = powerhook_establish(iwi_powerhook, sc);
452 1.4.4.4 skrll if (sc->sc_powerhook == NULL)
453 1.4.4.4 skrll printf("%s: WARNING: unable to establish power hook\n",
454 1.4.4.4 skrll sc->sc_dev.dv_xname);
455 1.4.4.4 skrll
456 1.4.4.4 skrll ieee80211_announce(ic);
457 1.4.4.4 skrll /*
458 1.4.4.4 skrll * Add a few sysctl knobs.
459 1.4.4.4 skrll * XXX: Not yet.
460 1.4.4.4 skrll */
461 1.4.4.4 skrll sc->dwelltime = 100;
462 1.4.4.4 skrll sc->bluetooth = 1;
463 1.4.4.4 skrll sc->antenna = 0;
464 1.4.4.4 skrll
465 1.4.4.4 skrll return;
466 1.4.4.4 skrll
467 1.4.4.4 skrll fail: iwi_detach(self, 0);
468 1.4.4.2 skrll }
469 1.4.4.2 skrll
470 1.4.4.2 skrll static int
471 1.4.4.2 skrll iwi_detach(struct device* self, int flags)
472 1.4.4.2 skrll {
473 1.4.4.2 skrll struct iwi_softc *sc = (struct iwi_softc *)self;
474 1.4.4.4 skrll struct ifnet *ifp = &sc->sc_if;
475 1.4.4.2 skrll
476 1.4.4.2 skrll iwi_stop(ifp, 1);
477 1.4.4.2 skrll iwi_free_firmware(sc);
478 1.4.4.2 skrll
479 1.4.4.2 skrll #if NBPFILTER > 0
480 1.4.4.4 skrll if (ifp != NULL)
481 1.4.4.4 skrll bpfdetach(ifp);
482 1.4.4.2 skrll #endif
483 1.4.4.4 skrll ieee80211_ifdetach(&sc->sc_ic);
484 1.4.4.4 skrll if (ifp != NULL)
485 1.4.4.4 skrll if_detach(ifp);
486 1.4.4.4 skrll
487 1.4.4.4 skrll iwi_free_cmd_ring(sc, &sc->cmdq);
488 1.4.4.5 christos iwi_free_tx_ring(sc, &sc->txq[0]);
489 1.4.4.5 christos iwi_free_tx_ring(sc, &sc->txq[1]);
490 1.4.4.5 christos iwi_free_tx_ring(sc, &sc->txq[2]);
491 1.4.4.5 christos iwi_free_tx_ring(sc, &sc->txq[3]);
492 1.4.4.4 skrll iwi_free_rx_ring(sc, &sc->rxq);
493 1.4.4.2 skrll
494 1.4.4.2 skrll if (sc->sc_ih != NULL) {
495 1.4.4.2 skrll pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
496 1.4.4.2 skrll sc->sc_ih = NULL;
497 1.4.4.2 skrll }
498 1.4.4.2 skrll
499 1.4.4.2 skrll bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
500 1.4.4.2 skrll
501 1.4.4.4 skrll powerhook_disestablish(sc->sc_powerhook);
502 1.4.4.4 skrll shutdownhook_disestablish(sc->sc_sdhook);
503 1.4.4.4 skrll
504 1.4.4.2 skrll return 0;
505 1.4.4.2 skrll }
506 1.4.4.2 skrll
507 1.4.4.2 skrll static int
508 1.4.4.4 skrll iwi_alloc_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring,
509 1.4.4.4 skrll int count)
510 1.4.4.2 skrll {
511 1.4.4.4 skrll int error, nsegs;
512 1.4.4.4 skrll
513 1.4.4.4 skrll ring->count = count;
514 1.4.4.4 skrll ring->queued = 0;
515 1.4.4.4 skrll ring->cur = ring->next = 0;
516 1.4.4.2 skrll
517 1.4.4.2 skrll /*
518 1.4.4.4 skrll * Allocate and map command ring
519 1.4.4.2 skrll */
520 1.4.4.2 skrll error = bus_dmamap_create(sc->sc_dmat,
521 1.4.4.4 skrll IWI_CMD_DESC_SIZE * count, 1,
522 1.4.4.4 skrll IWI_CMD_DESC_SIZE * count, 0,
523 1.4.4.4 skrll BUS_DMA_NOWAIT, &ring->desc_map);
524 1.4.4.2 skrll if (error != 0) {
525 1.4.4.4 skrll aprint_error("%s: could not create command ring DMA map\n",
526 1.4.4.2 skrll sc->sc_dev.dv_xname);
527 1.4.4.2 skrll goto fail;
528 1.4.4.2 skrll }
529 1.4.4.2 skrll
530 1.4.4.2 skrll error = bus_dmamem_alloc(sc->sc_dmat,
531 1.4.4.4 skrll IWI_CMD_DESC_SIZE * count, PAGE_SIZE, 0,
532 1.4.4.4 skrll &sc->cmdq.desc_seg, 1, &nsegs, BUS_DMA_NOWAIT);
533 1.4.4.2 skrll if (error != 0) {
534 1.4.4.4 skrll aprint_error("%s: could not allocate command ring DMA memory\n",
535 1.4.4.2 skrll sc->sc_dev.dv_xname);
536 1.4.4.2 skrll goto fail;
537 1.4.4.2 skrll }
538 1.4.4.2 skrll
539 1.4.4.4 skrll error = bus_dmamem_map(sc->sc_dmat, &sc->cmdq.desc_seg, nsegs,
540 1.4.4.4 skrll IWI_CMD_DESC_SIZE * count,
541 1.4.4.4 skrll (caddr_t *)&sc->cmdq.desc, BUS_DMA_NOWAIT);
542 1.4.4.2 skrll if (error != 0) {
543 1.4.4.4 skrll aprint_error("%s: could not map command ring DMA memory\n",
544 1.4.4.2 skrll sc->sc_dev.dv_xname);
545 1.4.4.2 skrll goto fail;
546 1.4.4.2 skrll }
547 1.4.4.2 skrll
548 1.4.4.4 skrll error = bus_dmamap_load(sc->sc_dmat, sc->cmdq.desc_map, sc->cmdq.desc,
549 1.4.4.4 skrll IWI_CMD_DESC_SIZE * count, NULL,
550 1.4.4.2 skrll BUS_DMA_NOWAIT);
551 1.4.4.2 skrll if (error != 0) {
552 1.4.4.4 skrll aprint_error("%s: could not load command ring DMA map\n",
553 1.4.4.2 skrll sc->sc_dev.dv_xname);
554 1.4.4.2 skrll goto fail;
555 1.4.4.2 skrll }
556 1.4.4.2 skrll
557 1.4.4.4 skrll memset(sc->cmdq.desc, 0,
558 1.4.4.4 skrll IWI_CMD_DESC_SIZE * count);
559 1.4.4.4 skrll
560 1.4.4.4 skrll return 0;
561 1.4.4.4 skrll
562 1.4.4.4 skrll fail: iwi_free_cmd_ring(sc, ring);
563 1.4.4.4 skrll return error;
564 1.4.4.4 skrll }
565 1.4.4.4 skrll
566 1.4.4.4 skrll static void
567 1.4.4.4 skrll iwi_reset_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring)
568 1.4.4.4 skrll {
569 1.4.4.5 christos int i;
570 1.4.4.5 christos
571 1.4.4.5 christos for (i = ring->next; i != ring->cur;) {
572 1.4.4.5 christos bus_dmamap_sync(sc->sc_dmat, sc->cmdq.desc_map,
573 1.4.4.5 christos i * IWI_CMD_DESC_SIZE, IWI_CMD_DESC_SIZE,
574 1.4.4.5 christos BUS_DMASYNC_POSTWRITE);
575 1.4.4.5 christos
576 1.4.4.5 christos wakeup(&ring->desc[i]);
577 1.4.4.5 christos i = (i + 1) % ring->count;
578 1.4.4.5 christos }
579 1.4.4.5 christos
580 1.4.4.4 skrll ring->queued = 0;
581 1.4.4.4 skrll ring->cur = ring->next = 0;
582 1.4.4.4 skrll }
583 1.4.4.4 skrll
584 1.4.4.4 skrll static void
585 1.4.4.4 skrll iwi_free_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring)
586 1.4.4.4 skrll {
587 1.4.4.4 skrll if (ring->desc_map != NULL) {
588 1.4.4.4 skrll if (ring->desc != NULL) {
589 1.4.4.4 skrll bus_dmamap_unload(sc->sc_dmat, ring->desc_map);
590 1.4.4.4 skrll bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
591 1.4.4.4 skrll IWI_CMD_DESC_SIZE * ring->count);
592 1.4.4.4 skrll bus_dmamem_free(sc->sc_dmat, &ring->desc_seg, 1);
593 1.4.4.4 skrll }
594 1.4.4.4 skrll bus_dmamap_destroy(sc->sc_dmat, ring->desc_map);
595 1.4.4.4 skrll }
596 1.4.4.4 skrll }
597 1.4.4.4 skrll
598 1.4.4.4 skrll static int
599 1.4.4.4 skrll iwi_alloc_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring,
600 1.4.4.5 christos int count, bus_addr_t csr_ridx, bus_addr_t csr_widx)
601 1.4.4.4 skrll {
602 1.4.4.4 skrll int i, error, nsegs;
603 1.4.4.4 skrll
604 1.4.4.4 skrll ring->count = count;
605 1.4.4.4 skrll ring->queued = 0;
606 1.4.4.4 skrll ring->cur = ring->next = 0;
607 1.4.4.5 christos ring->csr_ridx = csr_ridx;
608 1.4.4.5 christos ring->csr_widx = csr_widx;
609 1.4.4.2 skrll
610 1.4.4.2 skrll /*
611 1.4.4.4 skrll * Allocate and map Tx ring
612 1.4.4.2 skrll */
613 1.4.4.2 skrll error = bus_dmamap_create(sc->sc_dmat,
614 1.4.4.4 skrll IWI_TX_DESC_SIZE * count, 1,
615 1.4.4.4 skrll IWI_TX_DESC_SIZE * count, 0, BUS_DMA_NOWAIT,
616 1.4.4.4 skrll &ring->desc_map);
617 1.4.4.2 skrll if (error != 0) {
618 1.4.4.4 skrll aprint_error("%s: could not create tx ring DMA map\n",
619 1.4.4.2 skrll sc->sc_dev.dv_xname);
620 1.4.4.2 skrll goto fail;
621 1.4.4.2 skrll }
622 1.4.4.2 skrll
623 1.4.4.2 skrll error = bus_dmamem_alloc(sc->sc_dmat,
624 1.4.4.4 skrll IWI_TX_DESC_SIZE * count, PAGE_SIZE, 0,
625 1.4.4.4 skrll &ring->desc_seg, 1, &nsegs, BUS_DMA_NOWAIT);
626 1.4.4.2 skrll if (error != 0) {
627 1.4.4.4 skrll aprint_error("%s: could not allocate tx ring DMA memory\n",
628 1.4.4.2 skrll sc->sc_dev.dv_xname);
629 1.4.4.2 skrll goto fail;
630 1.4.4.2 skrll }
631 1.4.4.2 skrll
632 1.4.4.4 skrll error = bus_dmamem_map(sc->sc_dmat, &ring->desc_seg, nsegs,
633 1.4.4.4 skrll IWI_TX_DESC_SIZE * count,
634 1.4.4.4 skrll (caddr_t *)&ring->desc, BUS_DMA_NOWAIT);
635 1.4.4.2 skrll if (error != 0) {
636 1.4.4.4 skrll aprint_error("%s: could not map tx ring DMA memory\n",
637 1.4.4.2 skrll sc->sc_dev.dv_xname);
638 1.4.4.2 skrll goto fail;
639 1.4.4.2 skrll }
640 1.4.4.2 skrll
641 1.4.4.4 skrll error = bus_dmamap_load(sc->sc_dmat, ring->desc_map, ring->desc,
642 1.4.4.4 skrll IWI_TX_DESC_SIZE * count, NULL,
643 1.4.4.2 skrll BUS_DMA_NOWAIT);
644 1.4.4.2 skrll if (error != 0) {
645 1.4.4.4 skrll aprint_error("%s: could not load tx ring DMA map\n",
646 1.4.4.2 skrll sc->sc_dev.dv_xname);
647 1.4.4.2 skrll goto fail;
648 1.4.4.2 skrll }
649 1.4.4.2 skrll
650 1.4.4.4 skrll memset(ring->desc, 0, IWI_TX_DESC_SIZE * count);
651 1.4.4.4 skrll
652 1.4.4.4 skrll ring->data = malloc(count * sizeof (struct iwi_tx_data), M_DEVBUF,
653 1.4.4.4 skrll M_NOWAIT | M_ZERO);
654 1.4.4.4 skrll if (ring->data == NULL) {
655 1.4.4.4 skrll aprint_error("%s: could not allocate soft data\n",
656 1.4.4.4 skrll sc->sc_dev.dv_xname);
657 1.4.4.4 skrll error = ENOMEM;
658 1.4.4.4 skrll goto fail;
659 1.4.4.4 skrll }
660 1.4.4.2 skrll
661 1.4.4.2 skrll /*
662 1.4.4.2 skrll * Allocate Tx buffers DMA maps
663 1.4.4.2 skrll */
664 1.4.4.4 skrll for (i = 0; i < count; i++) {
665 1.4.4.2 skrll error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, IWI_MAX_NSEG,
666 1.4.4.4 skrll MCLBYTES, 0, BUS_DMA_NOWAIT, &ring->data[i].map);
667 1.4.4.2 skrll if (error != 0) {
668 1.4.4.2 skrll aprint_error("%s: could not create tx buf DMA map",
669 1.4.4.2 skrll sc->sc_dev.dv_xname);
670 1.4.4.2 skrll goto fail;
671 1.4.4.2 skrll }
672 1.4.4.2 skrll }
673 1.4.4.4 skrll return 0;
674 1.4.4.4 skrll
675 1.4.4.4 skrll fail: iwi_free_tx_ring(sc, ring);
676 1.4.4.4 skrll return error;
677 1.4.4.4 skrll }
678 1.4.4.4 skrll
679 1.4.4.4 skrll static void
680 1.4.4.4 skrll iwi_reset_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring)
681 1.4.4.4 skrll {
682 1.4.4.4 skrll struct iwi_tx_data *data;
683 1.4.4.4 skrll int i;
684 1.4.4.4 skrll
685 1.4.4.4 skrll for (i = 0; i < ring->count; i++) {
686 1.4.4.4 skrll data = &ring->data[i];
687 1.4.4.4 skrll
688 1.4.4.4 skrll if (data->m != NULL) {
689 1.4.4.4 skrll bus_dmamap_sync(sc->sc_dmat, data->map, 0,
690 1.4.4.4 skrll data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
691 1.4.4.4 skrll bus_dmamap_unload(sc->sc_dmat, data->map);
692 1.4.4.4 skrll m_freem(data->m);
693 1.4.4.4 skrll data->m = NULL;
694 1.4.4.4 skrll }
695 1.4.4.4 skrll
696 1.4.4.4 skrll if (data->ni != NULL) {
697 1.4.4.4 skrll ieee80211_free_node(data->ni);
698 1.4.4.4 skrll data->ni = NULL;
699 1.4.4.4 skrll }
700 1.4.4.4 skrll }
701 1.4.4.4 skrll
702 1.4.4.4 skrll ring->queued = 0;
703 1.4.4.4 skrll ring->cur = ring->next = 0;
704 1.4.4.4 skrll }
705 1.4.4.4 skrll
706 1.4.4.4 skrll static void
707 1.4.4.4 skrll iwi_free_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring)
708 1.4.4.4 skrll {
709 1.4.4.4 skrll int i;
710 1.4.4.4 skrll
711 1.4.4.4 skrll if (ring->desc_map != NULL) {
712 1.4.4.4 skrll if (ring->desc != NULL) {
713 1.4.4.4 skrll bus_dmamap_unload(sc->sc_dmat, ring->desc_map);
714 1.4.4.4 skrll bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
715 1.4.4.4 skrll IWI_TX_DESC_SIZE * ring->count);
716 1.4.4.4 skrll bus_dmamem_free(sc->sc_dmat, &ring->desc_seg, 1);
717 1.4.4.4 skrll }
718 1.4.4.4 skrll bus_dmamap_destroy(sc->sc_dmat, ring->desc_map);
719 1.4.4.4 skrll }
720 1.4.4.4 skrll
721 1.4.4.4 skrll for (i = 0; i < ring->count; i++) {
722 1.4.4.4 skrll if (ring->data[i].m != NULL) {
723 1.4.4.4 skrll bus_dmamap_unload(sc->sc_dmat, ring->data[i].map);
724 1.4.4.4 skrll m_freem(ring->data[i].m);
725 1.4.4.4 skrll }
726 1.4.4.4 skrll bus_dmamap_destroy(sc->sc_dmat, ring->data[i].map);
727 1.4.4.4 skrll }
728 1.4.4.4 skrll }
729 1.4.4.4 skrll
730 1.4.4.4 skrll static int
731 1.4.4.4 skrll iwi_alloc_rx_ring(struct iwi_softc *sc, struct iwi_rx_ring *ring,
732 1.4.4.4 skrll int count)
733 1.4.4.4 skrll {
734 1.4.4.4 skrll int i, error;
735 1.4.4.4 skrll
736 1.4.4.4 skrll ring->count = count;
737 1.4.4.4 skrll ring->cur = 0;
738 1.4.4.4 skrll
739 1.4.4.4 skrll ring->data = malloc(count * sizeof (struct iwi_rx_data), M_DEVBUF,
740 1.4.4.4 skrll M_NOWAIT | M_ZERO);
741 1.4.4.4 skrll if (ring->data == NULL) {
742 1.4.4.4 skrll aprint_error("%s: could not allocate soft data\n",
743 1.4.4.4 skrll sc->sc_dev.dv_xname);
744 1.4.4.4 skrll error = ENOMEM;
745 1.4.4.4 skrll goto fail;
746 1.4.4.4 skrll }
747 1.4.4.2 skrll
748 1.4.4.2 skrll /*
749 1.4.4.2 skrll * Allocate and map Rx buffers
750 1.4.4.2 skrll */
751 1.4.4.4 skrll for (i = 0; i < count; i++) {
752 1.4.4.2 skrll
753 1.4.4.2 skrll error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
754 1.4.4.4 skrll 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &ring->data[i].map);
755 1.4.4.2 skrll if (error != 0) {
756 1.4.4.2 skrll aprint_error("%s: could not create rx buf DMA map",
757 1.4.4.2 skrll sc->sc_dev.dv_xname);
758 1.4.4.2 skrll goto fail;
759 1.4.4.2 skrll }
760 1.4.4.2 skrll
761 1.4.4.4 skrll if ((ring->data[i].m = iwi_alloc_rx_buf(sc)) == NULL) {
762 1.4.4.2 skrll error = ENOMEM;
763 1.4.4.2 skrll goto fail;
764 1.4.4.2 skrll }
765 1.4.4.2 skrll
766 1.4.4.4 skrll error = bus_dmamap_load_mbuf(sc->sc_dmat, ring->data[i].map,
767 1.4.4.4 skrll ring->data[i].m, BUS_DMA_READ | BUS_DMA_NOWAIT);
768 1.4.4.2 skrll if (error != 0) {
769 1.4.4.2 skrll aprint_error("%s: could not load rx buffer DMA map\n",
770 1.4.4.2 skrll sc->sc_dev.dv_xname);
771 1.4.4.2 skrll goto fail;
772 1.4.4.2 skrll }
773 1.4.4.5 christos
774 1.4.4.5 christos bus_dmamap_sync(sc->sc_dmat, ring->data[i].map, 0,
775 1.4.4.5 christos ring->data[i].map->dm_mapsize, BUS_DMASYNC_PREREAD);
776 1.4.4.2 skrll }
777 1.4.4.2 skrll
778 1.4.4.2 skrll return 0;
779 1.4.4.2 skrll
780 1.4.4.4 skrll fail: iwi_free_rx_ring(sc, ring);
781 1.4.4.2 skrll return error;
782 1.4.4.2 skrll }
783 1.4.4.2 skrll
784 1.4.4.2 skrll static void
785 1.4.4.4 skrll iwi_reset_rx_ring(struct iwi_softc *sc, struct iwi_rx_ring *ring)
786 1.4.4.4 skrll {
787 1.4.4.4 skrll ring->cur = 0;
788 1.4.4.4 skrll }
789 1.4.4.4 skrll
790 1.4.4.4 skrll static void
791 1.4.4.4 skrll iwi_free_rx_ring(struct iwi_softc *sc, struct iwi_rx_ring *ring)
792 1.4.4.2 skrll {
793 1.4.4.2 skrll int i;
794 1.4.4.2 skrll
795 1.4.4.4 skrll for (i = 0; i < ring->count; i++) {
796 1.4.4.4 skrll if (ring->data[i].m != NULL) {
797 1.4.4.4 skrll bus_dmamap_unload(sc->sc_dmat, ring->data[i].map);
798 1.4.4.4 skrll m_freem(ring->data[i].m);
799 1.4.4.2 skrll }
800 1.4.4.4 skrll bus_dmamap_destroy(sc->sc_dmat, ring->data[i].map);
801 1.4.4.2 skrll }
802 1.4.4.4 skrll }
803 1.4.4.2 skrll
804 1.4.4.4 skrll static void
805 1.4.4.4 skrll iwi_shutdown(void *arg)
806 1.4.4.4 skrll {
807 1.4.4.4 skrll struct iwi_softc *sc = (struct iwi_softc *)arg;
808 1.4.4.4 skrll struct ifnet *ifp = sc->sc_ic.ic_ifp;
809 1.4.4.2 skrll
810 1.4.4.4 skrll iwi_stop(ifp, 1);
811 1.4.4.4 skrll }
812 1.4.4.4 skrll
813 1.4.4.4 skrll static int
814 1.4.4.4 skrll iwi_suspend(struct iwi_softc *sc)
815 1.4.4.4 skrll {
816 1.4.4.4 skrll struct ifnet *ifp = sc->sc_ic.ic_ifp;
817 1.4.4.4 skrll
818 1.4.4.4 skrll iwi_stop(ifp, 1);
819 1.4.4.4 skrll
820 1.4.4.4 skrll return 0;
821 1.4.4.4 skrll }
822 1.4.4.4 skrll
823 1.4.4.4 skrll static int
824 1.4.4.4 skrll iwi_resume(struct iwi_softc *sc)
825 1.4.4.4 skrll {
826 1.4.4.4 skrll struct ifnet *ifp = sc->sc_ic.ic_ifp;
827 1.4.4.4 skrll pcireg_t data;
828 1.4.4.4 skrll
829 1.4.4.4 skrll /* clear device specific PCI configuration register 0x41 */
830 1.4.4.4 skrll data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
831 1.4.4.4 skrll data &= ~0x0000ff00;
832 1.4.4.4 skrll pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
833 1.4.4.4 skrll
834 1.4.4.4 skrll if (ifp->if_flags & IFF_UP) {
835 1.4.4.4 skrll iwi_init(ifp);
836 1.4.4.4 skrll if (ifp->if_flags & IFF_RUNNING)
837 1.4.4.4 skrll iwi_start(ifp);
838 1.4.4.2 skrll }
839 1.4.4.2 skrll
840 1.4.4.4 skrll return 0;
841 1.4.4.4 skrll }
842 1.4.4.4 skrll
843 1.4.4.4 skrll static void
844 1.4.4.4 skrll iwi_powerhook(int why, void *arg)
845 1.4.4.4 skrll {
846 1.4.4.4 skrll struct iwi_softc *sc = arg;
847 1.4.4.4 skrll int s;
848 1.4.4.4 skrll
849 1.4.4.4 skrll s = splnet();
850 1.4.4.4 skrll switch (why) {
851 1.4.4.4 skrll case PWR_SUSPEND:
852 1.4.4.4 skrll case PWR_STANDBY:
853 1.4.4.4 skrll iwi_suspend(sc);
854 1.4.4.4 skrll break;
855 1.4.4.4 skrll case PWR_RESUME:
856 1.4.4.4 skrll iwi_resume(sc);
857 1.4.4.4 skrll break;
858 1.4.4.4 skrll case PWR_SOFTSUSPEND:
859 1.4.4.4 skrll case PWR_SOFTSTANDBY:
860 1.4.4.4 skrll case PWR_SOFTRESUME:
861 1.4.4.4 skrll break;
862 1.4.4.2 skrll }
863 1.4.4.4 skrll splx(s);
864 1.4.4.2 skrll }
865 1.4.4.2 skrll
866 1.4.4.5 christos static struct ieee80211_node *
867 1.4.4.5 christos iwi_node_alloc(struct ieee80211_node_table *nt)
868 1.4.4.5 christos {
869 1.4.4.5 christos struct iwi_node *in;
870 1.4.4.5 christos
871 1.4.4.5 christos in = malloc(sizeof (struct iwi_node), M_80211_NODE, M_NOWAIT | M_ZERO);
872 1.4.4.5 christos if (in == NULL)
873 1.4.4.5 christos return NULL;
874 1.4.4.5 christos
875 1.4.4.5 christos in->in_station = -1;
876 1.4.4.5 christos
877 1.4.4.5 christos return &in->in_node;
878 1.4.4.5 christos }
879 1.4.4.5 christos
880 1.4.4.5 christos static int
881 1.4.4.5 christos iwi_alloc_unr(struct iwi_softc *sc)
882 1.4.4.5 christos {
883 1.4.4.5 christos int i;
884 1.4.4.5 christos
885 1.4.4.5 christos for (i = 0; i < IWI_MAX_IBSSNODE - 1; i++)
886 1.4.4.5 christos if ((sc->sc_unr & (1 << i)) == 0) {
887 1.4.4.5 christos sc->sc_unr |= 1 << i;
888 1.4.4.5 christos return i;
889 1.4.4.5 christos }
890 1.4.4.5 christos
891 1.4.4.5 christos return -1;
892 1.4.4.5 christos }
893 1.4.4.5 christos
894 1.4.4.5 christos static void
895 1.4.4.5 christos iwi_free_unr(struct iwi_softc *sc, int r)
896 1.4.4.5 christos {
897 1.4.4.5 christos
898 1.4.4.5 christos sc->sc_unr &= 1 << r;
899 1.4.4.5 christos }
900 1.4.4.5 christos
901 1.4.4.5 christos static void
902 1.4.4.5 christos iwi_node_free(struct ieee80211_node *ni)
903 1.4.4.5 christos {
904 1.4.4.5 christos struct ieee80211com *ic = ni->ni_ic;
905 1.4.4.5 christos struct iwi_softc *sc = ic->ic_ifp->if_softc;
906 1.4.4.5 christos struct iwi_node *in = (struct iwi_node *)ni;
907 1.4.4.5 christos
908 1.4.4.5 christos if (in->in_station != -1)
909 1.4.4.5 christos iwi_free_unr(sc, in->in_station);
910 1.4.4.5 christos
911 1.4.4.5 christos sc->sc_node_free(ni);
912 1.4.4.5 christos }
913 1.4.4.5 christos
914 1.4.4.2 skrll static int
915 1.4.4.2 skrll iwi_media_change(struct ifnet *ifp)
916 1.4.4.2 skrll {
917 1.4.4.2 skrll int error;
918 1.4.4.2 skrll
919 1.4.4.2 skrll error = ieee80211_media_change(ifp);
920 1.4.4.2 skrll if (error != ENETRESET)
921 1.4.4.2 skrll return error;
922 1.4.4.2 skrll
923 1.4.4.2 skrll if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
924 1.4.4.2 skrll iwi_init(ifp);
925 1.4.4.2 skrll
926 1.4.4.2 skrll return 0;
927 1.4.4.2 skrll }
928 1.4.4.2 skrll
929 1.4.4.4 skrll /*
930 1.4.4.5 christos * The firmware automatically adapts the transmit speed. We report its current
931 1.4.4.5 christos * value here.
932 1.4.4.4 skrll */
933 1.4.4.2 skrll static void
934 1.4.4.2 skrll iwi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
935 1.4.4.2 skrll {
936 1.4.4.2 skrll struct iwi_softc *sc = ifp->if_softc;
937 1.4.4.2 skrll struct ieee80211com *ic = &sc->sc_ic;
938 1.4.4.2 skrll #define N(a) (sizeof (a) / sizeof (a[0]))
939 1.4.4.2 skrll static const struct {
940 1.4.4.4 skrll uint32_t val;
941 1.4.4.2 skrll int rate;
942 1.4.4.2 skrll } rates[] = {
943 1.4.4.2 skrll { IWI_RATE_DS1, 2 },
944 1.4.4.2 skrll { IWI_RATE_DS2, 4 },
945 1.4.4.2 skrll { IWI_RATE_DS5, 11 },
946 1.4.4.2 skrll { IWI_RATE_DS11, 22 },
947 1.4.4.2 skrll { IWI_RATE_OFDM6, 12 },
948 1.4.4.2 skrll { IWI_RATE_OFDM9, 18 },
949 1.4.4.2 skrll { IWI_RATE_OFDM12, 24 },
950 1.4.4.2 skrll { IWI_RATE_OFDM18, 36 },
951 1.4.4.2 skrll { IWI_RATE_OFDM24, 48 },
952 1.4.4.2 skrll { IWI_RATE_OFDM36, 72 },
953 1.4.4.2 skrll { IWI_RATE_OFDM48, 96 },
954 1.4.4.2 skrll { IWI_RATE_OFDM54, 108 },
955 1.4.4.2 skrll };
956 1.4.4.4 skrll uint32_t val;
957 1.4.4.2 skrll int rate, i;
958 1.4.4.2 skrll
959 1.4.4.2 skrll imr->ifm_status = IFM_AVALID;
960 1.4.4.2 skrll imr->ifm_active = IFM_IEEE80211;
961 1.4.4.2 skrll if (ic->ic_state == IEEE80211_S_RUN)
962 1.4.4.2 skrll imr->ifm_status |= IFM_ACTIVE;
963 1.4.4.2 skrll
964 1.4.4.2 skrll /* read current transmission rate from adapter */
965 1.4.4.2 skrll val = CSR_READ_4(sc, IWI_CSR_CURRENT_TX_RATE);
966 1.4.4.2 skrll
967 1.4.4.2 skrll /* convert rate to 802.11 rate */
968 1.4.4.2 skrll for (i = 0; i < N(rates) && rates[i].val != val; i++);
969 1.4.4.2 skrll rate = (i < N(rates)) ? rates[i].rate : 0;
970 1.4.4.2 skrll
971 1.4.4.2 skrll imr->ifm_active |= ieee80211_rate2media(ic, rate, ic->ic_curmode);
972 1.4.4.2 skrll switch (ic->ic_opmode) {
973 1.4.4.2 skrll case IEEE80211_M_STA:
974 1.4.4.2 skrll break;
975 1.4.4.2 skrll
976 1.4.4.2 skrll case IEEE80211_M_IBSS:
977 1.4.4.2 skrll imr->ifm_active |= IFM_IEEE80211_ADHOC;
978 1.4.4.2 skrll break;
979 1.4.4.2 skrll
980 1.4.4.2 skrll case IEEE80211_M_MONITOR:
981 1.4.4.2 skrll imr->ifm_active |= IFM_IEEE80211_MONITOR;
982 1.4.4.2 skrll break;
983 1.4.4.2 skrll
984 1.4.4.2 skrll case IEEE80211_M_AHDEMO:
985 1.4.4.2 skrll case IEEE80211_M_HOSTAP:
986 1.4.4.2 skrll /* should not get there */
987 1.4.4.2 skrll break;
988 1.4.4.2 skrll }
989 1.4.4.2 skrll #undef N
990 1.4.4.2 skrll }
991 1.4.4.2 skrll
992 1.4.4.2 skrll static int
993 1.4.4.2 skrll iwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
994 1.4.4.2 skrll {
995 1.4.4.4 skrll struct iwi_softc *sc = ic->ic_ifp->if_softc;
996 1.4.4.2 skrll
997 1.4.4.2 skrll switch (nstate) {
998 1.4.4.2 skrll case IEEE80211_S_SCAN:
999 1.4.4.4 skrll if (sc->flags & IWI_FLAG_SCANNING)
1000 1.4.4.4 skrll break;
1001 1.4.4.4 skrll
1002 1.4.4.4 skrll ieee80211_node_table_reset(&ic->ic_scan);
1003 1.4.4.4 skrll ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN;
1004 1.4.4.4 skrll sc->flags |= IWI_FLAG_SCANNING;
1005 1.4.4.5 christos /* blink the led while scanning */
1006 1.4.4.5 christos iwi_led_set(sc, IWI_LED_ASSOCIATED, 1);
1007 1.4.4.2 skrll iwi_scan(sc);
1008 1.4.4.2 skrll break;
1009 1.4.4.2 skrll
1010 1.4.4.2 skrll case IEEE80211_S_AUTH:
1011 1.4.4.2 skrll iwi_auth_and_assoc(sc);
1012 1.4.4.2 skrll break;
1013 1.4.4.2 skrll
1014 1.4.4.2 skrll case IEEE80211_S_RUN:
1015 1.4.4.2 skrll if (ic->ic_opmode == IEEE80211_M_IBSS)
1016 1.4.4.2 skrll ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
1017 1.4.4.4 skrll else if (ic->ic_opmode == IEEE80211_M_MONITOR)
1018 1.4.4.4 skrll iwi_set_chan(sc, ic->ic_ibss_chan);
1019 1.4.4.4 skrll
1020 1.4.4.4 skrll return (*sc->sc_newstate)(ic, nstate,
1021 1.4.4.4 skrll IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
1022 1.4.4.2 skrll
1023 1.4.4.2 skrll case IEEE80211_S_ASSOC:
1024 1.4.4.5 christos iwi_led_set(sc, IWI_LED_ASSOCIATED, 0);
1025 1.4.4.2 skrll break;
1026 1.4.4.4 skrll
1027 1.4.4.4 skrll case IEEE80211_S_INIT:
1028 1.4.4.4 skrll sc->flags &= ~IWI_FLAG_SCANNING;
1029 1.4.4.4 skrll return (*sc->sc_newstate)(ic, nstate, arg);
1030 1.4.4.2 skrll }
1031 1.4.4.2 skrll
1032 1.4.4.2 skrll ic->ic_state = nstate;
1033 1.4.4.2 skrll return 0;
1034 1.4.4.2 skrll }
1035 1.4.4.2 skrll
1036 1.4.4.2 skrll /*
1037 1.4.4.5 christos * WME parameters coming from IEEE 802.11e specification. These values are
1038 1.4.4.5 christos * already declared in ieee80211_proto.c, but they are static so they can't
1039 1.4.4.5 christos * be reused here.
1040 1.4.4.5 christos */
1041 1.4.4.5 christos static const struct wmeParams iwi_wme_cck_params[WME_NUM_AC] = {
1042 1.4.4.5 christos { 0, 3, 5, 7, 0 }, /* WME_AC_BE */
1043 1.4.4.5 christos { 0, 3, 5, 10, 0 }, /* WME_AC_BK */
1044 1.4.4.5 christos { 0, 2, 4, 5, 188 }, /* WME_AC_VI */
1045 1.4.4.5 christos { 0, 2, 3, 4, 102 } /* WME_AC_VO */
1046 1.4.4.5 christos };
1047 1.4.4.5 christos
1048 1.4.4.5 christos static const struct wmeParams iwi_wme_ofdm_params[WME_NUM_AC] = {
1049 1.4.4.5 christos { 0, 3, 4, 6, 0 }, /* WME_AC_BE */
1050 1.4.4.5 christos { 0, 3, 4, 10, 0 }, /* WME_AC_BK */
1051 1.4.4.5 christos { 0, 2, 3, 4, 94 }, /* WME_AC_VI */
1052 1.4.4.5 christos { 0, 2, 2, 3, 47 } /* WME_AC_VO */
1053 1.4.4.5 christos };
1054 1.4.4.5 christos
1055 1.4.4.5 christos static int
1056 1.4.4.5 christos iwi_wme_update(struct ieee80211com *ic)
1057 1.4.4.5 christos {
1058 1.4.4.5 christos #define IWI_EXP2(v) htole16((1 << (v)) - 1)
1059 1.4.4.5 christos #define IWI_USEC(v) htole16(IEEE80211_TXOP_TO_US(v))
1060 1.4.4.5 christos struct iwi_softc *sc = ic->ic_ifp->if_softc;
1061 1.4.4.5 christos struct iwi_wme_params wme[3];
1062 1.4.4.5 christos const struct wmeParams *wmep;
1063 1.4.4.5 christos int ac;
1064 1.4.4.5 christos
1065 1.4.4.5 christos /*
1066 1.4.4.5 christos * We shall not override firmware default WME values if WME is not
1067 1.4.4.5 christos * actually enabled.
1068 1.4.4.5 christos */
1069 1.4.4.5 christos if (!(ic->ic_flags & IEEE80211_F_WME))
1070 1.4.4.5 christos return 0;
1071 1.4.4.5 christos
1072 1.4.4.5 christos for (ac = 0; ac < WME_NUM_AC; ac++) {
1073 1.4.4.5 christos /* set WME values for current operating mode */
1074 1.4.4.5 christos wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
1075 1.4.4.5 christos wme[0].aifsn[ac] = wmep->wmep_aifsn;
1076 1.4.4.5 christos wme[0].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
1077 1.4.4.5 christos wme[0].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
1078 1.4.4.5 christos wme[0].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
1079 1.4.4.5 christos wme[0].acm[ac] = wmep->wmep_acm;
1080 1.4.4.5 christos
1081 1.4.4.5 christos /* set WME values for CCK modulation */
1082 1.4.4.5 christos wmep = &iwi_wme_cck_params[ac];
1083 1.4.4.5 christos wme[1].aifsn[ac] = wmep->wmep_aifsn;
1084 1.4.4.5 christos wme[1].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
1085 1.4.4.5 christos wme[1].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
1086 1.4.4.5 christos wme[1].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
1087 1.4.4.5 christos wme[1].acm[ac] = wmep->wmep_acm;
1088 1.4.4.5 christos
1089 1.4.4.5 christos /* set WME values for OFDM modulation */
1090 1.4.4.5 christos wmep = &iwi_wme_ofdm_params[ac];
1091 1.4.4.5 christos wme[2].aifsn[ac] = wmep->wmep_aifsn;
1092 1.4.4.5 christos wme[2].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
1093 1.4.4.5 christos wme[2].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
1094 1.4.4.5 christos wme[2].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
1095 1.4.4.5 christos wme[2].acm[ac] = wmep->wmep_acm;
1096 1.4.4.5 christos }
1097 1.4.4.5 christos
1098 1.4.4.5 christos DPRINTF(("Setting WME parameters\n"));
1099 1.4.4.5 christos return iwi_cmd(sc, IWI_CMD_SET_WME_PARAMS, wme, sizeof wme, 1);
1100 1.4.4.5 christos #undef IWI_USEC
1101 1.4.4.5 christos #undef IWI_EXP2
1102 1.4.4.5 christos }
1103 1.4.4.5 christos
1104 1.4.4.5 christos /*
1105 1.4.4.2 skrll * Read 16 bits at address 'addr' from the serial EEPROM.
1106 1.4.4.2 skrll */
1107 1.4.4.4 skrll static uint16_t
1108 1.4.4.4 skrll iwi_read_prom_word(struct iwi_softc *sc, uint8_t addr)
1109 1.4.4.2 skrll {
1110 1.4.4.4 skrll uint32_t tmp;
1111 1.4.4.4 skrll uint16_t val;
1112 1.4.4.2 skrll int n;
1113 1.4.4.2 skrll
1114 1.4.4.2 skrll /* Clock C once before the first command */
1115 1.4.4.2 skrll IWI_EEPROM_CTL(sc, 0);
1116 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
1117 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_C);
1118 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
1119 1.4.4.2 skrll
1120 1.4.4.2 skrll /* Write start bit (1) */
1121 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D);
1122 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D | IWI_EEPROM_C);
1123 1.4.4.2 skrll
1124 1.4.4.2 skrll /* Write READ opcode (10) */
1125 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D);
1126 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D | IWI_EEPROM_C);
1127 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
1128 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_C);
1129 1.4.4.2 skrll
1130 1.4.4.2 skrll /* Write address A7-A0 */
1131 1.4.4.2 skrll for (n = 7; n >= 0; n--) {
1132 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S |
1133 1.4.4.2 skrll (((addr >> n) & 1) << IWI_EEPROM_SHIFT_D));
1134 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S |
1135 1.4.4.2 skrll (((addr >> n) & 1) << IWI_EEPROM_SHIFT_D) | IWI_EEPROM_C);
1136 1.4.4.2 skrll }
1137 1.4.4.2 skrll
1138 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
1139 1.4.4.2 skrll
1140 1.4.4.2 skrll /* Read data Q15-Q0 */
1141 1.4.4.2 skrll val = 0;
1142 1.4.4.2 skrll for (n = 15; n >= 0; n--) {
1143 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_C);
1144 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
1145 1.4.4.2 skrll tmp = MEM_READ_4(sc, IWI_MEM_EEPROM_CTL);
1146 1.4.4.2 skrll val |= ((tmp & IWI_EEPROM_Q) >> IWI_EEPROM_SHIFT_Q) << n;
1147 1.4.4.2 skrll }
1148 1.4.4.2 skrll
1149 1.4.4.2 skrll IWI_EEPROM_CTL(sc, 0);
1150 1.4.4.2 skrll
1151 1.4.4.2 skrll /* Clear Chip Select and clock C */
1152 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
1153 1.4.4.2 skrll IWI_EEPROM_CTL(sc, 0);
1154 1.4.4.2 skrll IWI_EEPROM_CTL(sc, IWI_EEPROM_C);
1155 1.4.4.2 skrll
1156 1.4.4.4 skrll return val;
1157 1.4.4.2 skrll }
1158 1.4.4.2 skrll
1159 1.4.4.2 skrll /*
1160 1.4.4.2 skrll * XXX: Hack to set the current channel to the value advertised in beacons or
1161 1.4.4.2 skrll * probe responses. Only used during AP detection.
1162 1.4.4.2 skrll */
1163 1.4.4.2 skrll static void
1164 1.4.4.2 skrll iwi_fix_channel(struct ieee80211com *ic, struct mbuf *m)
1165 1.4.4.2 skrll {
1166 1.4.4.2 skrll struct ieee80211_frame *wh;
1167 1.4.4.4 skrll uint8_t subtype;
1168 1.4.4.4 skrll uint8_t *frm, *efrm;
1169 1.4.4.2 skrll
1170 1.4.4.2 skrll wh = mtod(m, struct ieee80211_frame *);
1171 1.4.4.2 skrll
1172 1.4.4.2 skrll if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT)
1173 1.4.4.2 skrll return;
1174 1.4.4.2 skrll
1175 1.4.4.2 skrll subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1176 1.4.4.2 skrll
1177 1.4.4.2 skrll if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
1178 1.4.4.2 skrll subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1179 1.4.4.2 skrll return;
1180 1.4.4.2 skrll
1181 1.4.4.4 skrll frm = (uint8_t *)(wh + 1);
1182 1.4.4.4 skrll efrm = mtod(m, uint8_t *) + m->m_len;
1183 1.4.4.2 skrll
1184 1.4.4.2 skrll frm += 12; /* skip tstamp, bintval and capinfo fields */
1185 1.4.4.2 skrll while (frm < efrm) {
1186 1.4.4.2 skrll if (*frm == IEEE80211_ELEMID_DSPARMS)
1187 1.4.4.2 skrll #if IEEE80211_CHAN_MAX < 255
1188 1.4.4.2 skrll if (frm[2] <= IEEE80211_CHAN_MAX)
1189 1.4.4.2 skrll #endif
1190 1.4.4.5 christos ic->ic_curchan = &ic->ic_channels[frm[2]];
1191 1.4.4.2 skrll
1192 1.4.4.2 skrll frm += frm[1] + 2;
1193 1.4.4.2 skrll }
1194 1.4.4.2 skrll }
1195 1.4.4.2 skrll
1196 1.4.4.4 skrll static struct mbuf *
1197 1.4.4.4 skrll iwi_alloc_rx_buf(struct iwi_softc *sc)
1198 1.4.4.4 skrll {
1199 1.4.4.4 skrll struct mbuf *m;
1200 1.4.4.4 skrll
1201 1.4.4.4 skrll MGETHDR(m, M_DONTWAIT, MT_DATA);
1202 1.4.4.4 skrll if (m == NULL) {
1203 1.4.4.4 skrll aprint_error("%s: could not allocate rx mbuf\n",
1204 1.4.4.4 skrll sc->sc_dev.dv_xname);
1205 1.4.4.4 skrll return NULL;
1206 1.4.4.4 skrll }
1207 1.4.4.4 skrll
1208 1.4.4.4 skrll MCLGET(m, M_DONTWAIT);
1209 1.4.4.4 skrll if (!(m->m_flags & M_EXT)) {
1210 1.4.4.4 skrll aprint_error("%s: could not allocate rx mbuf cluster\n",
1211 1.4.4.4 skrll sc->sc_dev.dv_xname);
1212 1.4.4.4 skrll m_freem(m);
1213 1.4.4.4 skrll return NULL;
1214 1.4.4.4 skrll }
1215 1.4.4.4 skrll
1216 1.4.4.4 skrll m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
1217 1.4.4.4 skrll return m;
1218 1.4.4.4 skrll }
1219 1.4.4.4 skrll
1220 1.4.4.2 skrll static void
1221 1.4.4.4 skrll iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i,
1222 1.4.4.2 skrll struct iwi_frame *frame)
1223 1.4.4.2 skrll {
1224 1.4.4.2 skrll struct ieee80211com *ic = &sc->sc_ic;
1225 1.4.4.4 skrll struct ifnet *ifp = ic->ic_ifp;
1226 1.4.4.4 skrll struct mbuf *m, *m_new;
1227 1.4.4.2 skrll struct ieee80211_frame *wh;
1228 1.4.4.2 skrll struct ieee80211_node *ni;
1229 1.4.4.2 skrll int error;
1230 1.4.4.2 skrll
1231 1.4.4.4 skrll DPRINTFN(5, ("received frame len=%u chan=%u rssi=%u\n",
1232 1.4.4.4 skrll le16toh(frame->len), frame->chan, frame->rssi_dbm));
1233 1.4.4.2 skrll
1234 1.4.4.4 skrll if (le16toh(frame->len) < sizeof (struct ieee80211_frame) ||
1235 1.4.4.2 skrll le16toh(frame->len) > MCLBYTES) {
1236 1.4.4.4 skrll DPRINTF(("%s: bad frame length\n", sc->sc_dev.dv_xname));
1237 1.4.4.4 skrll ifp->if_ierrors++;
1238 1.4.4.4 skrll return;
1239 1.4.4.2 skrll }
1240 1.4.4.2 skrll
1241 1.4.4.4 skrll /*
1242 1.4.4.4 skrll * Try to allocate a new mbuf for this ring element and
1243 1.4.4.4 skrll * load it before processing the current mbuf. If the ring
1244 1.4.4.4 skrll * element cannot be reloaded, drop the received packet
1245 1.4.4.4 skrll * and reuse the old mbuf. In the unlikely case that
1246 1.4.4.4 skrll * the old mbuf can't be reloaded either, explicitly panic.
1247 1.4.4.4 skrll *
1248 1.4.4.4 skrll * XXX Reorganize buffer by moving elements from the logical
1249 1.4.4.4 skrll * end of the ring to the front instead of dropping.
1250 1.4.4.4 skrll */
1251 1.4.4.4 skrll if ((m_new = iwi_alloc_rx_buf(sc)) == NULL) {
1252 1.4.4.4 skrll ifp->if_ierrors++;
1253 1.4.4.4 skrll return;
1254 1.4.4.4 skrll }
1255 1.4.4.4 skrll
1256 1.4.4.4 skrll bus_dmamap_unload(sc->sc_dmat, data->map);
1257 1.4.4.4 skrll
1258 1.4.4.4 skrll error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m_new,
1259 1.4.4.4 skrll BUS_DMA_READ | BUS_DMA_NOWAIT);
1260 1.4.4.4 skrll if (error != 0) {
1261 1.4.4.4 skrll aprint_error("%s: could not load rx buf DMA map\n",
1262 1.4.4.4 skrll sc->sc_dev.dv_xname);
1263 1.4.4.4 skrll m_freem(m_new);
1264 1.4.4.4 skrll ifp->if_ierrors++;
1265 1.4.4.4 skrll error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map,
1266 1.4.4.4 skrll data->m, BUS_DMA_READ | BUS_DMA_NOWAIT);
1267 1.4.4.4 skrll if (error)
1268 1.4.4.4 skrll panic("%s: unable to remap rx buf",
1269 1.4.4.4 skrll sc->sc_dev.dv_xname);
1270 1.4.4.4 skrll return;
1271 1.4.4.4 skrll }
1272 1.4.4.4 skrll
1273 1.4.4.4 skrll /*
1274 1.4.4.4 skrll * New mbuf successfully loaded, update RX ring and continue
1275 1.4.4.4 skrll * processing.
1276 1.4.4.4 skrll */
1277 1.4.4.4 skrll m = data->m;
1278 1.4.4.4 skrll data->m = m_new;
1279 1.4.4.4 skrll CSR_WRITE_4(sc, IWI_CSR_RX_BASE + i * 4, data->map->dm_segs[0].ds_addr);
1280 1.4.4.2 skrll
1281 1.4.4.2 skrll /* Finalize mbuf */
1282 1.4.4.2 skrll m->m_pkthdr.rcvif = ifp;
1283 1.4.4.2 skrll m->m_pkthdr.len = m->m_len = sizeof (struct iwi_hdr) +
1284 1.4.4.2 skrll sizeof (struct iwi_frame) + le16toh(frame->len);
1285 1.4.4.2 skrll
1286 1.4.4.2 skrll m_adj(m, sizeof (struct iwi_hdr) + sizeof (struct iwi_frame));
1287 1.4.4.2 skrll
1288 1.4.4.4 skrll if (ic->ic_state == IEEE80211_S_SCAN)
1289 1.4.4.4 skrll iwi_fix_channel(ic, m);
1290 1.4.4.2 skrll
1291 1.4.4.2 skrll #if NBPFILTER > 0
1292 1.4.4.2 skrll if (sc->sc_drvbpf != NULL) {
1293 1.4.4.2 skrll struct iwi_rx_radiotap_header *tap = &sc->sc_rxtap;
1294 1.4.4.2 skrll
1295 1.4.4.4 skrll tap->wr_flags = 0;
1296 1.4.4.4 skrll tap->wr_rate = frame->rate;
1297 1.4.4.4 skrll tap->wr_chan_freq =
1298 1.4.4.4 skrll htole16(ic->ic_channels[frame->chan].ic_freq);
1299 1.4.4.4 skrll tap->wr_chan_flags =
1300 1.4.4.4 skrll htole16(ic->ic_channels[frame->chan].ic_flags);
1301 1.4.4.4 skrll tap->wr_antsignal = frame->signal;
1302 1.4.4.4 skrll tap->wr_antenna = frame->antenna;
1303 1.4.4.4 skrll
1304 1.4.4.4 skrll bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
1305 1.4.4.2 skrll }
1306 1.4.4.2 skrll #endif
1307 1.4.4.2 skrll
1308 1.4.4.4 skrll wh = mtod(m, struct ieee80211_frame *);
1309 1.4.4.4 skrll ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
1310 1.4.4.3 skrll
1311 1.4.4.2 skrll /* Send the frame to the upper layer */
1312 1.4.4.4 skrll ieee80211_input(ic, m, ni, frame->rssi_dbm, 0);
1313 1.4.4.2 skrll
1314 1.4.4.4 skrll /* node is no longer needed */
1315 1.4.4.4 skrll ieee80211_free_node(ni);
1316 1.4.4.2 skrll }
1317 1.4.4.2 skrll
1318 1.4.4.2 skrll static void
1319 1.4.4.4 skrll iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif)
1320 1.4.4.2 skrll {
1321 1.4.4.2 skrll struct ieee80211com *ic = &sc->sc_ic;
1322 1.4.4.2 skrll struct iwi_notif_scan_channel *chan;
1323 1.4.4.2 skrll struct iwi_notif_scan_complete *scan;
1324 1.4.4.2 skrll struct iwi_notif_authentication *auth;
1325 1.4.4.2 skrll struct iwi_notif_association *assoc;
1326 1.4.4.2 skrll
1327 1.4.4.2 skrll switch (notif->type) {
1328 1.4.4.2 skrll case IWI_NOTIF_TYPE_SCAN_CHANNEL:
1329 1.4.4.2 skrll chan = (struct iwi_notif_scan_channel *)(notif + 1);
1330 1.4.4.2 skrll
1331 1.4.4.4 skrll DPRINTFN(2, ("Finished scanning channel (%u)\n", chan->nchan));
1332 1.4.4.2 skrll break;
1333 1.4.4.2 skrll
1334 1.4.4.2 skrll case IWI_NOTIF_TYPE_SCAN_COMPLETE:
1335 1.4.4.2 skrll scan = (struct iwi_notif_scan_complete *)(notif + 1);
1336 1.4.4.2 skrll
1337 1.4.4.2 skrll DPRINTFN(2, ("Scan completed (%u, %u)\n", scan->nchan,
1338 1.4.4.2 skrll scan->status));
1339 1.4.4.2 skrll
1340 1.4.4.4 skrll /* monitor mode uses scan to set the channel ... */
1341 1.4.4.4 skrll if (ic->ic_opmode != IEEE80211_M_MONITOR) {
1342 1.4.4.4 skrll sc->flags &= ~IWI_FLAG_SCANNING;
1343 1.4.4.4 skrll ieee80211_end_scan(ic);
1344 1.4.4.4 skrll } else
1345 1.4.4.4 skrll iwi_set_chan(sc, ic->ic_ibss_chan);
1346 1.4.4.2 skrll break;
1347 1.4.4.2 skrll
1348 1.4.4.2 skrll case IWI_NOTIF_TYPE_AUTHENTICATION:
1349 1.4.4.2 skrll auth = (struct iwi_notif_authentication *)(notif + 1);
1350 1.4.4.2 skrll
1351 1.4.4.2 skrll DPRINTFN(2, ("Authentication (%u)\n", auth->state));
1352 1.4.4.2 skrll
1353 1.4.4.2 skrll switch (auth->state) {
1354 1.4.4.2 skrll case IWI_AUTHENTICATED:
1355 1.4.4.5 christos ieee80211_node_authorize(ic->ic_bss);
1356 1.4.4.2 skrll ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
1357 1.4.4.2 skrll break;
1358 1.4.4.2 skrll
1359 1.4.4.2 skrll case IWI_DEAUTHENTICATED:
1360 1.4.4.2 skrll break;
1361 1.4.4.2 skrll
1362 1.4.4.2 skrll default:
1363 1.4.4.2 skrll aprint_error("%s: unknown authentication state %u\n",
1364 1.4.4.2 skrll sc->sc_dev.dv_xname, auth->state);
1365 1.4.4.2 skrll }
1366 1.4.4.2 skrll break;
1367 1.4.4.2 skrll
1368 1.4.4.2 skrll case IWI_NOTIF_TYPE_ASSOCIATION:
1369 1.4.4.2 skrll assoc = (struct iwi_notif_association *)(notif + 1);
1370 1.4.4.2 skrll
1371 1.4.4.2 skrll DPRINTFN(2, ("Association (%u, %u)\n", assoc->state,
1372 1.4.4.2 skrll assoc->status));
1373 1.4.4.2 skrll
1374 1.4.4.2 skrll switch (assoc->state) {
1375 1.4.4.4 skrll case IWI_AUTHENTICATED:
1376 1.4.4.4 skrll /* re-association, do nothing */
1377 1.4.4.4 skrll break;
1378 1.4.4.4 skrll
1379 1.4.4.2 skrll case IWI_ASSOCIATED:
1380 1.4.4.2 skrll ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
1381 1.4.4.2 skrll break;
1382 1.4.4.2 skrll
1383 1.4.4.2 skrll case IWI_DEASSOCIATED:
1384 1.4.4.4 skrll ieee80211_begin_scan(ic, 1);
1385 1.4.4.2 skrll break;
1386 1.4.4.2 skrll
1387 1.4.4.2 skrll default:
1388 1.4.4.2 skrll aprint_error("%s: unknown association state %u\n",
1389 1.4.4.2 skrll sc->sc_dev.dv_xname, assoc->state);
1390 1.4.4.2 skrll }
1391 1.4.4.2 skrll break;
1392 1.4.4.2 skrll
1393 1.4.4.2 skrll case IWI_NOTIF_TYPE_CALIBRATION:
1394 1.4.4.2 skrll case IWI_NOTIF_TYPE_BEACON:
1395 1.4.4.2 skrll case IWI_NOTIF_TYPE_NOISE:
1396 1.4.4.2 skrll DPRINTFN(5, ("Notification (%u)\n", notif->type));
1397 1.4.4.2 skrll break;
1398 1.4.4.2 skrll
1399 1.4.4.2 skrll default:
1400 1.4.4.2 skrll aprint_error("%s: unknown notification type %u\n",
1401 1.4.4.2 skrll sc->sc_dev.dv_xname, notif->type);
1402 1.4.4.2 skrll }
1403 1.4.4.2 skrll }
1404 1.4.4.2 skrll
1405 1.4.4.2 skrll static void
1406 1.4.4.5 christos iwi_cmd_intr(struct iwi_softc *sc)
1407 1.4.4.5 christos {
1408 1.4.4.5 christos uint32_t hw;
1409 1.4.4.5 christos
1410 1.4.4.5 christos hw = CSR_READ_4(sc, IWI_CSR_CMD_RIDX);
1411 1.4.4.5 christos
1412 1.4.4.5 christos for (; sc->cmdq.next != hw;) {
1413 1.4.4.5 christos bus_dmamap_sync(sc->sc_dmat, sc->cmdq.desc_map,
1414 1.4.4.5 christos sc->cmdq.next * IWI_CMD_DESC_SIZE, IWI_CMD_DESC_SIZE,
1415 1.4.4.5 christos BUS_DMASYNC_POSTWRITE);
1416 1.4.4.5 christos
1417 1.4.4.5 christos wakeup(&sc->cmdq.desc[sc->cmdq.next]);
1418 1.4.4.5 christos sc->cmdq.next = (sc->cmdq.next + 1) % sc->cmdq.count;
1419 1.4.4.5 christos }
1420 1.4.4.5 christos }
1421 1.4.4.5 christos
1422 1.4.4.5 christos static void
1423 1.4.4.2 skrll iwi_rx_intr(struct iwi_softc *sc)
1424 1.4.4.2 skrll {
1425 1.4.4.4 skrll struct iwi_rx_data *data;
1426 1.4.4.2 skrll struct iwi_hdr *hdr;
1427 1.4.4.4 skrll uint32_t hw;
1428 1.4.4.2 skrll
1429 1.4.4.4 skrll hw = CSR_READ_4(sc, IWI_CSR_RX_RIDX);
1430 1.4.4.2 skrll
1431 1.4.4.4 skrll for (; sc->rxq.cur != hw;) {
1432 1.4.4.4 skrll data = &sc->rxq.data[sc->rxq.cur];
1433 1.4.4.2 skrll
1434 1.4.4.4 skrll bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1435 1.4.4.4 skrll data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
1436 1.4.4.2 skrll
1437 1.4.4.4 skrll hdr = mtod(data->m, struct iwi_hdr *);
1438 1.4.4.2 skrll
1439 1.4.4.2 skrll switch (hdr->type) {
1440 1.4.4.2 skrll case IWI_HDR_TYPE_FRAME:
1441 1.4.4.4 skrll iwi_frame_intr(sc, data, sc->rxq.cur,
1442 1.4.4.2 skrll (struct iwi_frame *)(hdr + 1));
1443 1.4.4.2 skrll break;
1444 1.4.4.2 skrll
1445 1.4.4.2 skrll case IWI_HDR_TYPE_NOTIF:
1446 1.4.4.4 skrll iwi_notification_intr(sc,
1447 1.4.4.2 skrll (struct iwi_notif *)(hdr + 1));
1448 1.4.4.2 skrll break;
1449 1.4.4.2 skrll
1450 1.4.4.2 skrll default:
1451 1.4.4.2 skrll aprint_error("%s: unknown hdr type %u\n",
1452 1.4.4.2 skrll sc->sc_dev.dv_xname, hdr->type);
1453 1.4.4.2 skrll }
1454 1.4.4.4 skrll
1455 1.4.4.5 christos bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1456 1.4.4.5 christos data->map->dm_mapsize, BUS_DMASYNC_PREREAD);
1457 1.4.4.5 christos
1458 1.4.4.4 skrll DPRINTFN(15, ("rx done idx=%u\n", sc->rxq.cur));
1459 1.4.4.4 skrll
1460 1.4.4.4 skrll sc->rxq.cur = (sc->rxq.cur + 1) % sc->rxq.count;
1461 1.4.4.2 skrll }
1462 1.4.4.2 skrll
1463 1.4.4.4 skrll
1464 1.4.4.2 skrll /* Tell the firmware what we have processed */
1465 1.4.4.4 skrll hw = (hw == 0) ? sc->rxq.count - 1 : hw - 1;
1466 1.4.4.4 skrll CSR_WRITE_4(sc, IWI_CSR_RX_WIDX, hw);
1467 1.4.4.2 skrll }
1468 1.4.4.2 skrll
1469 1.4.4.2 skrll static void
1470 1.4.4.5 christos iwi_tx_intr(struct iwi_softc *sc, struct iwi_tx_ring *txq)
1471 1.4.4.2 skrll {
1472 1.4.4.4 skrll struct ifnet *ifp = &sc->sc_if;
1473 1.4.4.4 skrll struct iwi_tx_data *data;
1474 1.4.4.4 skrll uint32_t hw;
1475 1.4.4.2 skrll
1476 1.4.4.5 christos hw = CSR_READ_4(sc, txq->csr_ridx);
1477 1.4.4.2 skrll
1478 1.4.4.5 christos for (; txq->next != hw;) {
1479 1.4.4.5 christos data = &txq->data[txq->next];
1480 1.4.4.2 skrll
1481 1.4.4.4 skrll bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1482 1.4.4.4 skrll data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1483 1.4.4.4 skrll bus_dmamap_unload(sc->sc_dmat, data->map);
1484 1.4.4.4 skrll m_freem(data->m);
1485 1.4.4.4 skrll data->m = NULL;
1486 1.4.4.4 skrll ieee80211_free_node(data->ni);
1487 1.4.4.4 skrll data->ni = NULL;
1488 1.4.4.2 skrll
1489 1.4.4.5 christos DPRINTFN(15, ("tx done idx=%u\n", txq->next));
1490 1.4.4.2 skrll
1491 1.4.4.4 skrll ifp->if_opackets++;
1492 1.4.4.2 skrll
1493 1.4.4.5 christos txq->queued--;
1494 1.4.4.5 christos txq->next = (txq->next + 1) % txq->count;
1495 1.4.4.2 skrll }
1496 1.4.4.2 skrll
1497 1.4.4.4 skrll sc->sc_tx_timer = 0;
1498 1.4.4.4 skrll ifp->if_flags &= ~IFF_OACTIVE;
1499 1.4.4.2 skrll
1500 1.4.4.2 skrll /* Call start() since some buffer descriptors have been released */
1501 1.4.4.2 skrll (*ifp->if_start)(ifp);
1502 1.4.4.2 skrll }
1503 1.4.4.2 skrll
1504 1.4.4.2 skrll static int
1505 1.4.4.2 skrll iwi_intr(void *arg)
1506 1.4.4.2 skrll {
1507 1.4.4.2 skrll struct iwi_softc *sc = arg;
1508 1.4.4.4 skrll uint32_t r;
1509 1.4.4.2 skrll
1510 1.4.4.2 skrll if ((r = CSR_READ_4(sc, IWI_CSR_INTR)) == 0 || r == 0xffffffff)
1511 1.4.4.2 skrll return 0;
1512 1.4.4.2 skrll
1513 1.4.4.4 skrll /* Acknowledge interrupts */
1514 1.4.4.4 skrll CSR_WRITE_4(sc, IWI_CSR_INTR, r);
1515 1.4.4.2 skrll
1516 1.4.4.2 skrll if (r & (IWI_INTR_FATAL_ERROR | IWI_INTR_PARITY_ERROR)) {
1517 1.4.4.2 skrll aprint_error("%s: fatal error\n", sc->sc_dev.dv_xname);
1518 1.4.4.5 christos if (r & IWI_INTR_FATAL_ERROR)
1519 1.4.4.5 christos iwi_error_log(sc);
1520 1.4.4.4 skrll sc->sc_ic.ic_ifp->if_flags &= ~IFF_UP;
1521 1.4.4.4 skrll iwi_stop(&sc->sc_if, 1);
1522 1.4.4.5 christos return (1);
1523 1.4.4.2 skrll }
1524 1.4.4.2 skrll
1525 1.4.4.2 skrll if (r & IWI_INTR_FW_INITED) {
1526 1.4.4.2 skrll if (!(r & (IWI_INTR_FATAL_ERROR | IWI_INTR_PARITY_ERROR)))
1527 1.4.4.2 skrll wakeup(sc);
1528 1.4.4.2 skrll }
1529 1.4.4.2 skrll
1530 1.4.4.2 skrll if (r & IWI_INTR_RADIO_OFF) {
1531 1.4.4.2 skrll DPRINTF(("radio transmitter off\n"));
1532 1.4.4.4 skrll sc->sc_ic.ic_ifp->if_flags &= ~IFF_UP;
1533 1.4.4.4 skrll iwi_stop(&sc->sc_if, 1);
1534 1.4.4.5 christos return (1);
1535 1.4.4.2 skrll }
1536 1.4.4.2 skrll
1537 1.4.4.4 skrll if (r & IWI_INTR_CMD_DONE)
1538 1.4.4.5 christos iwi_cmd_intr(sc);
1539 1.4.4.2 skrll
1540 1.4.4.4 skrll if (r & IWI_INTR_TX1_DONE)
1541 1.4.4.5 christos iwi_tx_intr(sc, &sc->txq[0]);
1542 1.4.4.5 christos
1543 1.4.4.5 christos if (r & IWI_INTR_TX2_DONE)
1544 1.4.4.5 christos iwi_tx_intr(sc, &sc->txq[1]);
1545 1.4.4.5 christos
1546 1.4.4.5 christos if (r & IWI_INTR_TX3_DONE)
1547 1.4.4.5 christos iwi_tx_intr(sc, &sc->txq[2]);
1548 1.4.4.5 christos
1549 1.4.4.5 christos if (r & IWI_INTR_TX4_DONE)
1550 1.4.4.5 christos iwi_tx_intr(sc, &sc->txq[3]);
1551 1.4.4.5 christos
1552 1.4.4.5 christos if (r & IWI_INTR_RX_DONE)
1553 1.4.4.5 christos iwi_rx_intr(sc);
1554 1.4.4.2 skrll
1555 1.4.4.2 skrll return 1;
1556 1.4.4.2 skrll }
1557 1.4.4.2 skrll
1558 1.4.4.2 skrll static int
1559 1.4.4.4 skrll iwi_cmd(struct iwi_softc *sc, uint8_t type, void *data, uint8_t len,
1560 1.4.4.2 skrll int async)
1561 1.4.4.2 skrll {
1562 1.4.4.2 skrll struct iwi_cmd_desc *desc;
1563 1.4.4.2 skrll
1564 1.4.4.4 skrll desc = &sc->cmdq.desc[sc->cmdq.cur];
1565 1.4.4.2 skrll
1566 1.4.4.2 skrll desc->hdr.type = IWI_HDR_TYPE_COMMAND;
1567 1.4.4.2 skrll desc->hdr.flags = IWI_HDR_FLAG_IRQ;
1568 1.4.4.2 skrll desc->type = type;
1569 1.4.4.2 skrll desc->len = len;
1570 1.4.4.2 skrll memcpy(desc->data, data, len);
1571 1.4.4.2 skrll
1572 1.4.4.4 skrll bus_dmamap_sync(sc->sc_dmat, sc->cmdq.desc_map,
1573 1.4.4.4 skrll sc->cmdq.cur * IWI_CMD_DESC_SIZE,
1574 1.4.4.4 skrll IWI_CMD_DESC_SIZE, BUS_DMASYNC_PREWRITE);
1575 1.4.4.4 skrll
1576 1.4.4.4 skrll DPRINTFN(2, ("sending command idx=%u type=%u len=%u\n", sc->cmdq.cur,
1577 1.4.4.4 skrll type, len));
1578 1.4.4.2 skrll
1579 1.4.4.4 skrll sc->cmdq.cur = (sc->cmdq.cur + 1) % sc->cmdq.count;
1580 1.4.4.4 skrll CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.cur);
1581 1.4.4.2 skrll
1582 1.4.4.5 christos return async ? 0 : tsleep(desc, 0, "iwicmd", hz);
1583 1.4.4.5 christos }
1584 1.4.4.5 christos
1585 1.4.4.5 christos static void
1586 1.4.4.5 christos iwi_write_ibssnode(struct iwi_softc *sc, const struct iwi_node *in)
1587 1.4.4.5 christos {
1588 1.4.4.5 christos struct iwi_ibssnode node;
1589 1.4.4.5 christos
1590 1.4.4.5 christos /* write node information into NIC memory */
1591 1.4.4.5 christos memset(&node, 0, sizeof node);
1592 1.4.4.5 christos IEEE80211_ADDR_COPY(node.bssid, in->in_node.ni_macaddr);
1593 1.4.4.5 christos
1594 1.4.4.5 christos CSR_WRITE_REGION_1(sc,
1595 1.4.4.5 christos IWI_CSR_NODE_BASE + in->in_station * sizeof node,
1596 1.4.4.5 christos (uint8_t *)&node, sizeof node);
1597 1.4.4.2 skrll }
1598 1.4.4.2 skrll
1599 1.4.4.2 skrll static int
1600 1.4.4.5 christos iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni,
1601 1.4.4.5 christos int ac)
1602 1.4.4.2 skrll {
1603 1.4.4.2 skrll struct iwi_softc *sc = ifp->if_softc;
1604 1.4.4.2 skrll struct ieee80211com *ic = &sc->sc_ic;
1605 1.4.4.5 christos struct iwi_node *in = (struct iwi_node *)ni;
1606 1.4.4.5 christos struct ieee80211_frame *wh;
1607 1.4.4.4 skrll struct ieee80211_key *k;
1608 1.4.4.5 christos const struct chanAccParams *cap;
1609 1.4.4.5 christos struct iwi_tx_ring *txq = &sc->txq[ac];
1610 1.4.4.4 skrll struct iwi_tx_data *data;
1611 1.4.4.2 skrll struct iwi_tx_desc *desc;
1612 1.4.4.2 skrll struct mbuf *mnew;
1613 1.4.4.5 christos int error, hdrlen, i, noack = 0;
1614 1.4.4.5 christos
1615 1.4.4.5 christos wh = mtod(m0, struct ieee80211_frame *);
1616 1.4.4.2 skrll
1617 1.4.4.5 christos if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
1618 1.4.4.5 christos hdrlen = sizeof (struct ieee80211_qosframe);
1619 1.4.4.5 christos cap = &ic->ic_wme.wme_chanParams;
1620 1.4.4.5 christos noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
1621 1.4.4.5 christos } else
1622 1.4.4.5 christos hdrlen = sizeof (struct ieee80211_frame);
1623 1.4.4.5 christos
1624 1.4.4.5 christos /*
1625 1.4.4.5 christos * This is only used in IBSS mode where the firmware expect an index
1626 1.4.4.5 christos * in a h/w table instead of a destination address.
1627 1.4.4.5 christos */
1628 1.4.4.5 christos if (ic->ic_opmode == IEEE80211_M_IBSS && in->in_station == -1) {
1629 1.4.4.5 christos in->in_station = iwi_alloc_unr(sc);
1630 1.4.4.5 christos
1631 1.4.4.5 christos if (in->in_station == -1) { /* h/w table is full */
1632 1.4.4.5 christos m_freem(m0);
1633 1.4.4.5 christos ieee80211_free_node(ni);
1634 1.4.4.5 christos ifp->if_oerrors++;
1635 1.4.4.5 christos return 0;
1636 1.4.4.5 christos }
1637 1.4.4.5 christos iwi_write_ibssnode(sc, in);
1638 1.4.4.5 christos }
1639 1.4.4.5 christos
1640 1.4.4.5 christos if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1641 1.4.4.4 skrll k = ieee80211_crypto_encap(ic, ni, m0);
1642 1.4.4.4 skrll if (k == NULL) {
1643 1.4.4.4 skrll m_freem(m0);
1644 1.4.4.4 skrll return ENOBUFS;
1645 1.4.4.4 skrll }
1646 1.4.4.5 christos
1647 1.4.4.5 christos /* packet header may have moved, reset our local pointer */
1648 1.4.4.5 christos wh = mtod(m0, struct ieee80211_frame *);
1649 1.4.4.4 skrll }
1650 1.4.4.4 skrll
1651 1.4.4.2 skrll #if NBPFILTER > 0
1652 1.4.4.2 skrll if (sc->sc_drvbpf != NULL) {
1653 1.4.4.2 skrll struct iwi_tx_radiotap_header *tap = &sc->sc_txtap;
1654 1.4.4.2 skrll
1655 1.4.4.2 skrll tap->wt_flags = 0;
1656 1.4.4.4 skrll tap->wt_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
1657 1.4.4.4 skrll tap->wt_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
1658 1.4.4.2 skrll
1659 1.4.4.2 skrll bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
1660 1.4.4.2 skrll }
1661 1.4.4.2 skrll #endif
1662 1.4.4.2 skrll
1663 1.4.4.5 christos data = &txq->data[txq->cur];
1664 1.4.4.5 christos desc = &txq->desc[txq->cur];
1665 1.4.4.2 skrll
1666 1.4.4.5 christos /* save and trim IEEE802.11 header */
1667 1.4.4.5 christos m_copydata(m0, 0, hdrlen, (caddr_t)&desc->wh);
1668 1.4.4.5 christos m_adj(m0, hdrlen);
1669 1.4.4.2 skrll
1670 1.4.4.4 skrll error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
1671 1.4.4.4 skrll BUS_DMA_WRITE | BUS_DMA_NOWAIT);
1672 1.4.4.2 skrll if (error != 0 && error != EFBIG) {
1673 1.4.4.2 skrll aprint_error("%s: could not map mbuf (error %d)\n",
1674 1.4.4.2 skrll sc->sc_dev.dv_xname, error);
1675 1.4.4.2 skrll m_freem(m0);
1676 1.4.4.2 skrll return error;
1677 1.4.4.2 skrll }
1678 1.4.4.2 skrll if (error != 0) {
1679 1.4.4.2 skrll /* too many fragments, linearize */
1680 1.4.4.2 skrll
1681 1.4.4.2 skrll MGETHDR(mnew, M_DONTWAIT, MT_DATA);
1682 1.4.4.2 skrll if (mnew == NULL) {
1683 1.4.4.2 skrll m_freem(m0);
1684 1.4.4.2 skrll return ENOMEM;
1685 1.4.4.2 skrll }
1686 1.4.4.2 skrll
1687 1.4.4.2 skrll M_COPY_PKTHDR(mnew, m0);
1688 1.4.4.2 skrll
1689 1.4.4.4 skrll /* If the data won't fit in the header, get a cluster */
1690 1.4.4.4 skrll if (m0->m_pkthdr.len > MHLEN) {
1691 1.4.4.4 skrll MCLGET(mnew, M_DONTWAIT);
1692 1.4.4.4 skrll if (!(mnew->m_flags & M_EXT)) {
1693 1.4.4.4 skrll m_freem(m0);
1694 1.4.4.4 skrll m_freem(mnew);
1695 1.4.4.4 skrll return ENOMEM;
1696 1.4.4.4 skrll }
1697 1.4.4.4 skrll }
1698 1.4.4.2 skrll m_copydata(m0, 0, m0->m_pkthdr.len, mtod(mnew, caddr_t));
1699 1.4.4.2 skrll m_freem(m0);
1700 1.4.4.2 skrll mnew->m_len = mnew->m_pkthdr.len;
1701 1.4.4.2 skrll m0 = mnew;
1702 1.4.4.2 skrll
1703 1.4.4.4 skrll error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
1704 1.4.4.4 skrll BUS_DMA_WRITE | BUS_DMA_NOWAIT);
1705 1.4.4.2 skrll if (error != 0) {
1706 1.4.4.2 skrll aprint_error("%s: could not map mbuf (error %d)\n",
1707 1.4.4.2 skrll sc->sc_dev.dv_xname, error);
1708 1.4.4.2 skrll m_freem(m0);
1709 1.4.4.2 skrll return error;
1710 1.4.4.2 skrll }
1711 1.4.4.2 skrll }
1712 1.4.4.2 skrll
1713 1.4.4.4 skrll data->m = m0;
1714 1.4.4.4 skrll data->ni = ni;
1715 1.4.4.2 skrll
1716 1.4.4.2 skrll desc->hdr.type = IWI_HDR_TYPE_DATA;
1717 1.4.4.2 skrll desc->hdr.flags = IWI_HDR_FLAG_IRQ;
1718 1.4.4.5 christos desc->station =
1719 1.4.4.5 christos (ic->ic_opmode == IEEE80211_M_IBSS) ? in->in_station : 0;
1720 1.4.4.2 skrll desc->cmd = IWI_DATA_CMD_TX;
1721 1.4.4.2 skrll desc->len = htole16(m0->m_pkthdr.len);
1722 1.4.4.2 skrll desc->flags = 0;
1723 1.4.4.5 christos desc->xflags = 0;
1724 1.4.4.5 christos
1725 1.4.4.5 christos if (!noack && !IEEE80211_IS_MULTICAST(desc->wh.i_addr1))
1726 1.4.4.2 skrll desc->flags |= IWI_DATA_FLAG_NEED_ACK;
1727 1.4.4.2 skrll
1728 1.4.4.4 skrll #if 0
1729 1.4.4.2 skrll if (ic->ic_flags & IEEE80211_F_PRIVACY) {
1730 1.4.4.5 christos desc->wh.i_fc[1] |= IEEE80211_FC1_WEP;
1731 1.4.4.4 skrll desc->wep_txkey = ic->ic_crypto.cs_def_txkey;
1732 1.4.4.2 skrll } else
1733 1.4.4.4 skrll #endif
1734 1.4.4.2 skrll desc->flags |= IWI_DATA_FLAG_NO_WEP;
1735 1.4.4.2 skrll
1736 1.4.4.2 skrll if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
1737 1.4.4.2 skrll desc->flags |= IWI_DATA_FLAG_SHPREAMBLE;
1738 1.4.4.2 skrll
1739 1.4.4.5 christos if (desc->wh.i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS)
1740 1.4.4.5 christos desc->xflags |= IWI_DATA_XFLAG_QOS;
1741 1.4.4.5 christos
1742 1.4.4.4 skrll desc->nseg = htole32(data->map->dm_nsegs);
1743 1.4.4.4 skrll for (i = 0; i < data->map->dm_nsegs; i++) {
1744 1.4.4.4 skrll desc->seg_addr[i] = htole32(data->map->dm_segs[i].ds_addr);
1745 1.4.4.4 skrll desc->seg_len[i] = htole16(data->map->dm_segs[i].ds_len);
1746 1.4.4.2 skrll }
1747 1.4.4.2 skrll
1748 1.4.4.5 christos bus_dmamap_sync(sc->sc_dmat, txq->desc_map,
1749 1.4.4.5 christos txq->cur * IWI_TX_DESC_SIZE,
1750 1.4.4.4 skrll IWI_TX_DESC_SIZE, BUS_DMASYNC_PREWRITE);
1751 1.4.4.2 skrll
1752 1.4.4.4 skrll bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
1753 1.4.4.2 skrll BUS_DMASYNC_PREWRITE);
1754 1.4.4.2 skrll
1755 1.4.4.5 christos DPRINTFN(5, ("sending data frame txq=%u idx=%u len=%u nseg=%u\n",
1756 1.4.4.5 christos ac, txq->cur, le16toh(desc->len), le32toh(desc->nseg)));
1757 1.4.4.2 skrll
1758 1.4.4.2 skrll /* Inform firmware about this new packet */
1759 1.4.4.5 christos txq->queued++;
1760 1.4.4.5 christos txq->cur = (txq->cur + 1) % txq->count;
1761 1.4.4.5 christos CSR_WRITE_4(sc, txq->csr_widx, txq->cur);
1762 1.4.4.2 skrll
1763 1.4.4.2 skrll return 0;
1764 1.4.4.2 skrll }
1765 1.4.4.2 skrll
1766 1.4.4.2 skrll static void
1767 1.4.4.2 skrll iwi_start(struct ifnet *ifp)
1768 1.4.4.2 skrll {
1769 1.4.4.2 skrll struct iwi_softc *sc = ifp->if_softc;
1770 1.4.4.2 skrll struct ieee80211com *ic = &sc->sc_ic;
1771 1.4.4.2 skrll struct mbuf *m0;
1772 1.4.4.4 skrll struct ether_header *eh;
1773 1.4.4.2 skrll struct ieee80211_node *ni;
1774 1.4.4.5 christos int ac;
1775 1.4.4.2 skrll
1776 1.4.4.2 skrll if (ic->ic_state != IEEE80211_S_RUN)
1777 1.4.4.2 skrll return;
1778 1.4.4.2 skrll
1779 1.4.4.2 skrll for (;;) {
1780 1.4.4.2 skrll IF_DEQUEUE(&ifp->if_snd, m0);
1781 1.4.4.2 skrll if (m0 == NULL)
1782 1.4.4.2 skrll break;
1783 1.4.4.2 skrll
1784 1.4.4.4 skrll if (m0->m_len < sizeof (struct ether_header) &&
1785 1.4.4.5 christos (m0 = m_pullup(m0, sizeof (struct ether_header))) == NULL) {
1786 1.4.4.5 christos ifp->if_oerrors++;
1787 1.4.4.4 skrll continue;
1788 1.4.4.5 christos }
1789 1.4.4.2 skrll
1790 1.4.4.4 skrll eh = mtod(m0, struct ether_header *);
1791 1.4.4.4 skrll ni = ieee80211_find_txnode(ic, eh->ether_dhost);
1792 1.4.4.4 skrll if (ni == NULL) {
1793 1.4.4.4 skrll m_freem(m0);
1794 1.4.4.5 christos ifp->if_oerrors++;
1795 1.4.4.4 skrll continue;
1796 1.4.4.4 skrll }
1797 1.4.4.4 skrll
1798 1.4.4.5 christos /* classify mbuf so we can find which tx ring to use */
1799 1.4.4.5 christos if (ieee80211_classify(ic, m0, ni) != 0) {
1800 1.4.4.5 christos m_freem(m0);
1801 1.4.4.5 christos ieee80211_free_node(ni);
1802 1.4.4.5 christos ifp->if_oerrors++;
1803 1.4.4.5 christos continue;
1804 1.4.4.5 christos }
1805 1.4.4.5 christos
1806 1.4.4.5 christos /* no QoS encapsulation for EAPOL frames */
1807 1.4.4.5 christos ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
1808 1.4.4.5 christos M_WME_GETAC(m0) : WME_AC_BE;
1809 1.4.4.5 christos
1810 1.4.4.5 christos if (sc->txq[ac].queued > sc->txq[ac].count - 8) {
1811 1.4.4.5 christos /* there is no place left in this ring */
1812 1.4.4.5 christos IF_PREPEND(&ifp->if_snd, m0);
1813 1.4.4.5 christos ifp->if_flags |= IFF_OACTIVE;
1814 1.4.4.5 christos break;
1815 1.4.4.5 christos }
1816 1.4.4.5 christos
1817 1.4.4.5 christos #if NBPFILTER > 0
1818 1.4.4.5 christos if (ifp->if_bpf != NULL)
1819 1.4.4.5 christos bpf_mtap(ifp->if_bpf, m0);
1820 1.4.4.5 christos #endif
1821 1.4.4.5 christos
1822 1.4.4.4 skrll m0 = ieee80211_encap(ic, m0, ni);
1823 1.4.4.4 skrll if (m0 == NULL) {
1824 1.4.4.4 skrll ieee80211_free_node(ni);
1825 1.4.4.5 christos ifp->if_oerrors++;
1826 1.4.4.2 skrll continue;
1827 1.4.4.4 skrll }
1828 1.4.4.2 skrll
1829 1.4.4.2 skrll #if NBPFILTER > 0
1830 1.4.4.2 skrll if (ic->ic_rawbpf != NULL)
1831 1.4.4.2 skrll bpf_mtap(ic->ic_rawbpf, m0);
1832 1.4.4.2 skrll #endif
1833 1.4.4.2 skrll
1834 1.4.4.5 christos if (iwi_tx_start(ifp, m0, ni, ac) != 0) {
1835 1.4.4.4 skrll ieee80211_free_node(ni);
1836 1.4.4.4 skrll ifp->if_oerrors++;
1837 1.4.4.2 skrll break;
1838 1.4.4.2 skrll }
1839 1.4.4.2 skrll
1840 1.4.4.2 skrll /* start watchdog timer */
1841 1.4.4.2 skrll sc->sc_tx_timer = 5;
1842 1.4.4.2 skrll ifp->if_timer = 1;
1843 1.4.4.2 skrll }
1844 1.4.4.2 skrll }
1845 1.4.4.2 skrll
1846 1.4.4.2 skrll static void
1847 1.4.4.2 skrll iwi_watchdog(struct ifnet *ifp)
1848 1.4.4.2 skrll {
1849 1.4.4.2 skrll struct iwi_softc *sc = ifp->if_softc;
1850 1.4.4.2 skrll
1851 1.4.4.2 skrll ifp->if_timer = 0;
1852 1.4.4.2 skrll
1853 1.4.4.2 skrll if (sc->sc_tx_timer > 0) {
1854 1.4.4.2 skrll if (--sc->sc_tx_timer == 0) {
1855 1.4.4.2 skrll aprint_error("%s: device timeout\n",
1856 1.4.4.2 skrll sc->sc_dev.dv_xname);
1857 1.4.4.4 skrll ifp->if_oerrors++;
1858 1.4.4.4 skrll ifp->if_flags &= ~IFF_UP;
1859 1.4.4.2 skrll iwi_stop(ifp, 1);
1860 1.4.4.2 skrll return;
1861 1.4.4.2 skrll }
1862 1.4.4.2 skrll ifp->if_timer = 1;
1863 1.4.4.2 skrll }
1864 1.4.4.2 skrll
1865 1.4.4.4 skrll ieee80211_watchdog(&sc->sc_ic);
1866 1.4.4.2 skrll }
1867 1.4.4.2 skrll
1868 1.4.4.2 skrll static int
1869 1.4.4.4 skrll iwi_get_table0(struct iwi_softc *sc, uint32_t *tbl)
1870 1.4.4.2 skrll {
1871 1.4.4.4 skrll uint32_t size, buf[128];
1872 1.4.4.2 skrll
1873 1.4.4.2 skrll if (!(sc->flags & IWI_FLAG_FW_INITED)) {
1874 1.4.4.2 skrll memset(buf, 0, sizeof buf);
1875 1.4.4.2 skrll return copyout(buf, tbl, sizeof buf);
1876 1.4.4.2 skrll }
1877 1.4.4.2 skrll
1878 1.4.4.2 skrll size = min(CSR_READ_4(sc, IWI_CSR_TABLE0_SIZE), 128 - 1);
1879 1.4.4.2 skrll CSR_READ_REGION_4(sc, IWI_CSR_TABLE0_BASE, &buf[1], size);
1880 1.4.4.2 skrll
1881 1.4.4.2 skrll return copyout(buf, tbl, sizeof buf);
1882 1.4.4.2 skrll }
1883 1.4.4.2 skrll
1884 1.4.4.2 skrll static int
1885 1.4.4.2 skrll iwi_get_radio(struct iwi_softc *sc, int *ret)
1886 1.4.4.2 skrll {
1887 1.4.4.2 skrll int val;
1888 1.4.4.2 skrll
1889 1.4.4.2 skrll val = (CSR_READ_4(sc, IWI_CSR_IO) & IWI_IO_RADIO_ENABLED) ? 1 : 0;
1890 1.4.4.2 skrll return copyout(&val, ret, sizeof val);
1891 1.4.4.2 skrll }
1892 1.4.4.2 skrll
1893 1.4.4.2 skrll static int
1894 1.4.4.2 skrll iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1895 1.4.4.2 skrll {
1896 1.4.4.5 christos #define IS_RUNNING(ifp) \
1897 1.4.4.5 christos ((ifp->if_flags & IFF_UP) && (ifp->if_flags & IFF_RUNNING))
1898 1.4.4.5 christos
1899 1.4.4.2 skrll struct iwi_softc *sc = ifp->if_softc;
1900 1.4.4.5 christos struct ieee80211com *ic = &sc->sc_ic;
1901 1.4.4.5 christos struct ifreq *ifr = (struct ifreq *)data;
1902 1.4.4.2 skrll int s, error = 0;
1903 1.4.4.2 skrll
1904 1.4.4.2 skrll s = splnet();
1905 1.4.4.2 skrll
1906 1.4.4.2 skrll switch (cmd) {
1907 1.4.4.2 skrll case SIOCSIFFLAGS:
1908 1.4.4.2 skrll if (ifp->if_flags & IFF_UP) {
1909 1.4.4.2 skrll if (!(ifp->if_flags & IFF_RUNNING))
1910 1.4.4.2 skrll iwi_init(ifp);
1911 1.4.4.2 skrll } else {
1912 1.4.4.2 skrll if (ifp->if_flags & IFF_RUNNING)
1913 1.4.4.2 skrll iwi_stop(ifp, 1);
1914 1.4.4.2 skrll }
1915 1.4.4.2 skrll break;
1916 1.4.4.2 skrll
1917 1.4.4.5 christos case SIOCADDMULTI:
1918 1.4.4.5 christos case SIOCDELMULTI:
1919 1.4.4.5 christos error = (cmd == SIOCADDMULTI) ?
1920 1.4.4.5 christos ether_addmulti(ifr, &sc->sc_ec) :
1921 1.4.4.5 christos ether_delmulti(ifr, &sc->sc_ec);
1922 1.4.4.5 christos if (error == ENETRESET) {
1923 1.4.4.5 christos /* setup multicast filter, etc */
1924 1.4.4.5 christos error = 0;
1925 1.4.4.5 christos }
1926 1.4.4.5 christos break;
1927 1.4.4.5 christos
1928 1.4.4.2 skrll case SIOCGTABLE0:
1929 1.4.4.4 skrll error = iwi_get_table0(sc, (uint32_t *)ifr->ifr_data);
1930 1.4.4.2 skrll break;
1931 1.4.4.2 skrll
1932 1.4.4.2 skrll case SIOCGRADIO:
1933 1.4.4.2 skrll error = iwi_get_radio(sc, (int *)ifr->ifr_data);
1934 1.4.4.2 skrll break;
1935 1.4.4.2 skrll
1936 1.4.4.2 skrll case SIOCSLOADFW:
1937 1.4.4.2 skrll /* only super-user can do that! */
1938 1.4.4.2 skrll if ((error = suser(curproc->p_ucred, &curproc->p_acflag)) != 0)
1939 1.4.4.2 skrll break;
1940 1.4.4.2 skrll
1941 1.4.4.2 skrll error = iwi_cache_firmware(sc, ifr->ifr_data);
1942 1.4.4.2 skrll break;
1943 1.4.4.2 skrll
1944 1.4.4.2 skrll case SIOCSKILLFW:
1945 1.4.4.2 skrll /* only super-user can do that! */
1946 1.4.4.2 skrll if ((error = suser(curproc->p_ucred, &curproc->p_acflag)) != 0)
1947 1.4.4.2 skrll break;
1948 1.4.4.2 skrll
1949 1.4.4.4 skrll ifp->if_flags &= ~IFF_UP;
1950 1.4.4.2 skrll iwi_stop(ifp, 1);
1951 1.4.4.2 skrll iwi_free_firmware(sc);
1952 1.4.4.2 skrll break;
1953 1.4.4.2 skrll
1954 1.4.4.2 skrll default:
1955 1.4.4.4 skrll error = ieee80211_ioctl(&sc->sc_ic, cmd, data);
1956 1.4.4.2 skrll
1957 1.4.4.5 christos if (error == ENETRESET) {
1958 1.4.4.5 christos if (IS_RUNNING(ifp) &&
1959 1.4.4.5 christos (ic->ic_roaming != IEEE80211_ROAMING_MANUAL))
1960 1.4.4.5 christos iwi_init(ifp);
1961 1.4.4.5 christos error = 0;
1962 1.4.4.5 christos }
1963 1.4.4.2 skrll }
1964 1.4.4.2 skrll
1965 1.4.4.2 skrll splx(s);
1966 1.4.4.2 skrll return error;
1967 1.4.4.5 christos #undef IS_RUNNING
1968 1.4.4.2 skrll }
1969 1.4.4.2 skrll
1970 1.4.4.2 skrll static void
1971 1.4.4.2 skrll iwi_stop_master(struct iwi_softc *sc)
1972 1.4.4.2 skrll {
1973 1.4.4.2 skrll int ntries;
1974 1.4.4.2 skrll
1975 1.4.4.2 skrll /* Disable interrupts */
1976 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0);
1977 1.4.4.2 skrll
1978 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_STOP_MASTER);
1979 1.4.4.2 skrll for (ntries = 0; ntries < 5; ntries++) {
1980 1.4.4.2 skrll if (CSR_READ_4(sc, IWI_CSR_RST) & IWI_RST_MASTER_DISABLED)
1981 1.4.4.2 skrll break;
1982 1.4.4.2 skrll DELAY(10);
1983 1.4.4.2 skrll }
1984 1.4.4.2 skrll if (ntries == 5)
1985 1.4.4.2 skrll aprint_error("%s: timeout waiting for master\n",
1986 1.4.4.2 skrll sc->sc_dev.dv_xname);
1987 1.4.4.2 skrll
1988 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) |
1989 1.4.4.2 skrll IWI_RST_PRINCETON_RESET);
1990 1.4.4.2 skrll
1991 1.4.4.2 skrll sc->flags &= ~IWI_FLAG_FW_INITED;
1992 1.4.4.2 skrll }
1993 1.4.4.2 skrll
1994 1.4.4.2 skrll static int
1995 1.4.4.2 skrll iwi_reset(struct iwi_softc *sc)
1996 1.4.4.2 skrll {
1997 1.4.4.2 skrll int i, ntries;
1998 1.4.4.2 skrll
1999 1.4.4.2 skrll iwi_stop_master(sc);
2000 1.4.4.2 skrll
2001 1.4.4.2 skrll /* Move adapter to D0 state */
2002 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_CTL, CSR_READ_4(sc, IWI_CSR_CTL) |
2003 1.4.4.2 skrll IWI_CTL_INIT);
2004 1.4.4.2 skrll
2005 1.4.4.2 skrll /* Initialize Phase-Locked Level (PLL) */
2006 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_READ_INT, IWI_READ_INT_INIT_HOST);
2007 1.4.4.2 skrll
2008 1.4.4.2 skrll /* Wait for clock stabilization */
2009 1.4.4.2 skrll for (ntries = 0; ntries < 1000; ntries++) {
2010 1.4.4.2 skrll if (CSR_READ_4(sc, IWI_CSR_CTL) & IWI_CTL_CLOCK_READY)
2011 1.4.4.2 skrll break;
2012 1.4.4.2 skrll DELAY(200);
2013 1.4.4.2 skrll }
2014 1.4.4.4 skrll if (ntries == 1000) {
2015 1.4.4.4 skrll aprint_error("%s: timeout waiting for clock stabilization\n",
2016 1.4.4.4 skrll sc->sc_dev.dv_xname);
2017 1.4.4.2 skrll return EIO;
2018 1.4.4.4 skrll }
2019 1.4.4.2 skrll
2020 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) |
2021 1.4.4.2 skrll IWI_RST_SW_RESET);
2022 1.4.4.2 skrll
2023 1.4.4.2 skrll DELAY(10);
2024 1.4.4.2 skrll
2025 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_CTL, CSR_READ_4(sc, IWI_CSR_CTL) |
2026 1.4.4.2 skrll IWI_CTL_INIT);
2027 1.4.4.2 skrll
2028 1.4.4.2 skrll /* Clear NIC memory */
2029 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_AUTOINC_ADDR, 0);
2030 1.4.4.2 skrll for (i = 0; i < 0xc000; i++)
2031 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, 0);
2032 1.4.4.2 skrll
2033 1.4.4.2 skrll return 0;
2034 1.4.4.2 skrll }
2035 1.4.4.2 skrll
2036 1.4.4.2 skrll static int
2037 1.4.4.2 skrll iwi_load_ucode(struct iwi_softc *sc, void *uc, int size)
2038 1.4.4.2 skrll {
2039 1.4.4.4 skrll uint16_t *w;
2040 1.4.4.2 skrll int ntries, i;
2041 1.4.4.2 skrll
2042 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) |
2043 1.4.4.2 skrll IWI_RST_STOP_MASTER);
2044 1.4.4.2 skrll for (ntries = 0; ntries < 5; ntries++) {
2045 1.4.4.2 skrll if (CSR_READ_4(sc, IWI_CSR_RST) & IWI_RST_MASTER_DISABLED)
2046 1.4.4.2 skrll break;
2047 1.4.4.2 skrll DELAY(10);
2048 1.4.4.2 skrll }
2049 1.4.4.2 skrll if (ntries == 5) {
2050 1.4.4.2 skrll aprint_error("%s: timeout waiting for master\n",
2051 1.4.4.2 skrll sc->sc_dev.dv_xname);
2052 1.4.4.2 skrll return EIO;
2053 1.4.4.2 skrll }
2054 1.4.4.2 skrll
2055 1.4.4.2 skrll MEM_WRITE_4(sc, 0x3000e0, 0x80000000);
2056 1.4.4.2 skrll DELAY(5000);
2057 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) &
2058 1.4.4.2 skrll ~IWI_RST_PRINCETON_RESET);
2059 1.4.4.2 skrll DELAY(5000);
2060 1.4.4.2 skrll MEM_WRITE_4(sc, 0x3000e0, 0);
2061 1.4.4.2 skrll DELAY(1000);
2062 1.4.4.2 skrll MEM_WRITE_4(sc, 0x300004, 1);
2063 1.4.4.2 skrll DELAY(1000);
2064 1.4.4.2 skrll MEM_WRITE_4(sc, 0x300004, 0);
2065 1.4.4.2 skrll DELAY(1000);
2066 1.4.4.2 skrll MEM_WRITE_1(sc, 0x200000, 0x00);
2067 1.4.4.2 skrll MEM_WRITE_1(sc, 0x200000, 0x40);
2068 1.4.4.4 skrll DELAY(1000);
2069 1.4.4.2 skrll
2070 1.4.4.2 skrll /* Adapter is buggy, we must set the address for each word */
2071 1.4.4.2 skrll for (w = uc; size > 0; w++, size -= 2)
2072 1.4.4.4 skrll MEM_WRITE_2(sc, 0x200010, htole16(*w));
2073 1.4.4.2 skrll
2074 1.4.4.2 skrll MEM_WRITE_1(sc, 0x200000, 0x00);
2075 1.4.4.2 skrll MEM_WRITE_1(sc, 0x200000, 0x80);
2076 1.4.4.2 skrll
2077 1.4.4.2 skrll /* Wait until we get a response in the uc queue */
2078 1.4.4.2 skrll for (ntries = 0; ntries < 100; ntries++) {
2079 1.4.4.2 skrll if (MEM_READ_1(sc, 0x200000) & 1)
2080 1.4.4.2 skrll break;
2081 1.4.4.2 skrll DELAY(100);
2082 1.4.4.2 skrll }
2083 1.4.4.2 skrll if (ntries == 100) {
2084 1.4.4.2 skrll aprint_error("%s: timeout waiting for ucode to initialize\n",
2085 1.4.4.2 skrll sc->sc_dev.dv_xname);
2086 1.4.4.2 skrll return EIO;
2087 1.4.4.2 skrll }
2088 1.4.4.2 skrll
2089 1.4.4.2 skrll /* Empty the uc queue or the firmware will not initialize properly */
2090 1.4.4.2 skrll for (i = 0; i < 7; i++)
2091 1.4.4.2 skrll MEM_READ_4(sc, 0x200004);
2092 1.4.4.2 skrll
2093 1.4.4.2 skrll MEM_WRITE_1(sc, 0x200000, 0x00);
2094 1.4.4.2 skrll
2095 1.4.4.2 skrll return 0;
2096 1.4.4.2 skrll }
2097 1.4.4.2 skrll
2098 1.4.4.2 skrll /* macro to handle unaligned little endian data in firmware image */
2099 1.4.4.2 skrll #define GETLE32(p) ((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3] << 24)
2100 1.4.4.2 skrll static int
2101 1.4.4.2 skrll iwi_load_firmware(struct iwi_softc *sc, void *fw, int size)
2102 1.4.4.2 skrll {
2103 1.4.4.2 skrll bus_dmamap_t map;
2104 1.4.4.2 skrll u_char *p, *end;
2105 1.4.4.4 skrll uint32_t sentinel, ctl, sum;
2106 1.4.4.4 skrll uint32_t cs, sl, cd, cl;
2107 1.4.4.2 skrll int ntries, nsegs, error;
2108 1.4.4.4 skrll int sn;
2109 1.4.4.4 skrll
2110 1.4.4.4 skrll nsegs = (size + PAGE_SIZE - 1) / PAGE_SIZE;
2111 1.4.4.2 skrll
2112 1.4.4.4 skrll /* Create a DMA map for the firmware image */
2113 1.4.4.4 skrll error = bus_dmamap_create(sc->sc_dmat, size, nsegs, size, 0,
2114 1.4.4.2 skrll BUS_DMA_NOWAIT, &map);
2115 1.4.4.2 skrll if (error != 0) {
2116 1.4.4.2 skrll aprint_error("%s: could not create firmware DMA map\n",
2117 1.4.4.2 skrll sc->sc_dev.dv_xname);
2118 1.4.4.2 skrll goto fail1;
2119 1.4.4.2 skrll }
2120 1.4.4.2 skrll
2121 1.4.4.4 skrll error = bus_dmamap_load(sc->sc_dmat, map, fw, size, NULL,
2122 1.4.4.4 skrll BUS_DMA_NOWAIT | BUS_DMA_WRITE);
2123 1.4.4.2 skrll if (error != 0) {
2124 1.4.4.4 skrll aprint_error("%s: could not load fw dma map(%d)\n",
2125 1.4.4.4 skrll sc->sc_dev.dv_xname, error);
2126 1.4.4.2 skrll goto fail2;
2127 1.4.4.2 skrll }
2128 1.4.4.2 skrll
2129 1.4.4.2 skrll /* Make sure the adapter will get up-to-date values */
2130 1.4.4.2 skrll bus_dmamap_sync(sc->sc_dmat, map, 0, size, BUS_DMASYNC_PREWRITE);
2131 1.4.4.2 skrll
2132 1.4.4.2 skrll /* Tell the adapter where the command blocks are stored */
2133 1.4.4.2 skrll MEM_WRITE_4(sc, 0x3000a0, 0x27000);
2134 1.4.4.2 skrll
2135 1.4.4.2 skrll /*
2136 1.4.4.2 skrll * Store command blocks into adapter's internal memory using register
2137 1.4.4.2 skrll * indirections. The adapter will read the firmware image through DMA
2138 1.4.4.2 skrll * using information stored in command blocks.
2139 1.4.4.2 skrll */
2140 1.4.4.4 skrll p = fw;
2141 1.4.4.2 skrll end = p + size;
2142 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_AUTOINC_ADDR, 0x27000);
2143 1.4.4.2 skrll
2144 1.4.4.4 skrll sn = 0;
2145 1.4.4.4 skrll sl = cl = 0;
2146 1.4.4.4 skrll cs = cd = 0;
2147 1.4.4.2 skrll while (p < end) {
2148 1.4.4.4 skrll if (sl == 0) {
2149 1.4.4.4 skrll cs = map->dm_segs[sn].ds_addr;
2150 1.4.4.4 skrll sl = map->dm_segs[sn].ds_len;
2151 1.4.4.4 skrll sn++;
2152 1.4.4.4 skrll }
2153 1.4.4.4 skrll if (cl == 0) {
2154 1.4.4.4 skrll cd = GETLE32(p); p += 4; cs += 4; sl -= 4;
2155 1.4.4.4 skrll cl = GETLE32(p); p += 4; cs += 4; sl -= 4;
2156 1.4.4.4 skrll }
2157 1.4.4.4 skrll while (sl > 0 && cl > 0) {
2158 1.4.4.4 skrll int len = min(cl, sl);
2159 1.4.4.4 skrll
2160 1.4.4.4 skrll sl -= len;
2161 1.4.4.4 skrll cl -= len;
2162 1.4.4.4 skrll p += len;
2163 1.4.4.4 skrll
2164 1.4.4.4 skrll while (len > 0) {
2165 1.4.4.4 skrll int mlen = min(len, IWI_CB_MAXDATALEN);
2166 1.4.4.4 skrll
2167 1.4.4.4 skrll ctl = IWI_CB_DEFAULT_CTL | mlen;
2168 1.4.4.4 skrll sum = ctl ^ cs ^ cd;
2169 1.4.4.4 skrll
2170 1.4.4.4 skrll /* Write a command block */
2171 1.4.4.4 skrll CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, ctl);
2172 1.4.4.4 skrll CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, cs);
2173 1.4.4.4 skrll CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, cd);
2174 1.4.4.4 skrll CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, sum);
2175 1.4.4.4 skrll
2176 1.4.4.4 skrll cs += mlen;
2177 1.4.4.4 skrll cd += mlen;
2178 1.4.4.4 skrll len -= mlen;
2179 1.4.4.4 skrll }
2180 1.4.4.2 skrll }
2181 1.4.4.2 skrll }
2182 1.4.4.2 skrll
2183 1.4.4.2 skrll /* Write a fictive final command block (sentinel) */
2184 1.4.4.2 skrll sentinel = CSR_READ_4(sc, IWI_CSR_AUTOINC_ADDR);
2185 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, 0);
2186 1.4.4.2 skrll
2187 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) &
2188 1.4.4.2 skrll ~(IWI_RST_MASTER_DISABLED | IWI_RST_STOP_MASTER));
2189 1.4.4.2 skrll
2190 1.4.4.2 skrll /* Tell the adapter to start processing command blocks */
2191 1.4.4.2 skrll MEM_WRITE_4(sc, 0x3000a4, 0x540100);
2192 1.4.4.2 skrll
2193 1.4.4.2 skrll /* Wait until the adapter has processed all command blocks */
2194 1.4.4.2 skrll for (ntries = 0; ntries < 400; ntries++) {
2195 1.4.4.2 skrll if (MEM_READ_4(sc, 0x3000d0) >= sentinel)
2196 1.4.4.2 skrll break;
2197 1.4.4.2 skrll DELAY(100);
2198 1.4.4.2 skrll }
2199 1.4.4.2 skrll if (ntries == 400) {
2200 1.4.4.2 skrll aprint_error("%s: timeout processing cb\n",
2201 1.4.4.2 skrll sc->sc_dev.dv_xname);
2202 1.4.4.2 skrll error = EIO;
2203 1.4.4.5 christos goto fail3;
2204 1.4.4.2 skrll }
2205 1.4.4.2 skrll
2206 1.4.4.2 skrll /* We're done with command blocks processing */
2207 1.4.4.2 skrll MEM_WRITE_4(sc, 0x3000a4, 0x540c00);
2208 1.4.4.2 skrll
2209 1.4.4.2 skrll /* Allow interrupts so we know when the firmware is inited */
2210 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, IWI_INTR_MASK);
2211 1.4.4.2 skrll
2212 1.4.4.2 skrll /* Tell the adapter to initialize the firmware */
2213 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_RST, 0);
2214 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_CTL, CSR_READ_4(sc, IWI_CSR_CTL) |
2215 1.4.4.2 skrll IWI_CTL_ALLOW_STANDBY);
2216 1.4.4.2 skrll
2217 1.4.4.2 skrll /* Wait at most one second for firmware initialization to complete */
2218 1.4.4.2 skrll if ((error = tsleep(sc, 0, "iwiinit", hz)) != 0) {
2219 1.4.4.2 skrll aprint_error("%s: timeout waiting for firmware initialization "
2220 1.4.4.2 skrll "to complete\n", sc->sc_dev.dv_xname);
2221 1.4.4.4 skrll goto fail3;
2222 1.4.4.2 skrll }
2223 1.4.4.2 skrll
2224 1.4.4.4 skrll fail3:
2225 1.4.4.4 skrll bus_dmamap_sync(sc->sc_dmat, map, 0, size, BUS_DMASYNC_POSTWRITE);
2226 1.4.4.2 skrll bus_dmamap_unload(sc->sc_dmat, map);
2227 1.4.4.4 skrll fail2:
2228 1.4.4.4 skrll bus_dmamap_destroy(sc->sc_dmat, map);
2229 1.4.4.3 skrll
2230 1.4.4.4 skrll fail1:
2231 1.4.4.4 skrll return error;
2232 1.4.4.2 skrll }
2233 1.4.4.2 skrll
2234 1.4.4.2 skrll /*
2235 1.4.4.2 skrll * Store firmware into kernel memory so we can download it when we need to,
2236 1.4.4.2 skrll * e.g when the adapter wakes up from suspend mode.
2237 1.4.4.2 skrll */
2238 1.4.4.2 skrll static int
2239 1.4.4.2 skrll iwi_cache_firmware(struct iwi_softc *sc, void *data)
2240 1.4.4.2 skrll {
2241 1.4.4.2 skrll struct iwi_firmware *kfw = &sc->fw;
2242 1.4.4.2 skrll struct iwi_firmware ufw;
2243 1.4.4.2 skrll int error;
2244 1.4.4.2 skrll
2245 1.4.4.2 skrll iwi_free_firmware(sc);
2246 1.4.4.2 skrll
2247 1.4.4.2 skrll if ((error = copyin(data, &ufw, sizeof ufw)) != 0)
2248 1.4.4.2 skrll goto fail1;
2249 1.4.4.2 skrll
2250 1.4.4.2 skrll kfw->boot_size = ufw.boot_size;
2251 1.4.4.2 skrll kfw->ucode_size = ufw.ucode_size;
2252 1.4.4.2 skrll kfw->main_size = ufw.main_size;
2253 1.4.4.2 skrll
2254 1.4.4.2 skrll kfw->boot = malloc(kfw->boot_size, M_DEVBUF, M_NOWAIT);
2255 1.4.4.2 skrll if (kfw->boot == NULL) {
2256 1.4.4.2 skrll error = ENOMEM;
2257 1.4.4.2 skrll goto fail1;
2258 1.4.4.2 skrll }
2259 1.4.4.2 skrll
2260 1.4.4.2 skrll kfw->ucode = malloc(kfw->ucode_size, M_DEVBUF, M_NOWAIT);
2261 1.4.4.2 skrll if (kfw->ucode == NULL) {
2262 1.4.4.2 skrll error = ENOMEM;
2263 1.4.4.2 skrll goto fail2;
2264 1.4.4.2 skrll }
2265 1.4.4.2 skrll
2266 1.4.4.2 skrll kfw->main = malloc(kfw->main_size, M_DEVBUF, M_NOWAIT);
2267 1.4.4.2 skrll if (kfw->main == NULL) {
2268 1.4.4.2 skrll error = ENOMEM;
2269 1.4.4.2 skrll goto fail3;
2270 1.4.4.2 skrll }
2271 1.4.4.2 skrll
2272 1.4.4.2 skrll if ((error = copyin(ufw.boot, kfw->boot, kfw->boot_size)) != 0)
2273 1.4.4.2 skrll goto fail4;
2274 1.4.4.2 skrll
2275 1.4.4.2 skrll if ((error = copyin(ufw.ucode, kfw->ucode, kfw->ucode_size)) != 0)
2276 1.4.4.2 skrll goto fail4;
2277 1.4.4.2 skrll
2278 1.4.4.2 skrll if ((error = copyin(ufw.main, kfw->main, kfw->main_size)) != 0)
2279 1.4.4.2 skrll goto fail4;
2280 1.4.4.2 skrll
2281 1.4.4.2 skrll DPRINTF(("Firmware cached: boot %u, ucode %u, main %u\n",
2282 1.4.4.2 skrll kfw->boot_size, kfw->ucode_size, kfw->main_size));
2283 1.4.4.2 skrll
2284 1.4.4.2 skrll sc->flags |= IWI_FLAG_FW_CACHED;
2285 1.4.4.2 skrll
2286 1.4.4.2 skrll return 0;
2287 1.4.4.2 skrll
2288 1.4.4.2 skrll fail4: free(kfw->boot, M_DEVBUF);
2289 1.4.4.2 skrll fail3: free(kfw->ucode, M_DEVBUF);
2290 1.4.4.2 skrll fail2: free(kfw->main, M_DEVBUF);
2291 1.4.4.2 skrll fail1:
2292 1.4.4.2 skrll return error;
2293 1.4.4.2 skrll }
2294 1.4.4.2 skrll
2295 1.4.4.2 skrll static void
2296 1.4.4.2 skrll iwi_free_firmware(struct iwi_softc *sc)
2297 1.4.4.2 skrll {
2298 1.4.4.2 skrll if (!(sc->flags & IWI_FLAG_FW_CACHED))
2299 1.4.4.2 skrll return;
2300 1.4.4.3 skrll
2301 1.4.4.2 skrll free(sc->fw.boot, M_DEVBUF);
2302 1.4.4.2 skrll free(sc->fw.ucode, M_DEVBUF);
2303 1.4.4.2 skrll free(sc->fw.main, M_DEVBUF);
2304 1.4.4.2 skrll
2305 1.4.4.2 skrll sc->flags &= ~IWI_FLAG_FW_CACHED;
2306 1.4.4.2 skrll }
2307 1.4.4.2 skrll
2308 1.4.4.2 skrll static int
2309 1.4.4.2 skrll iwi_config(struct iwi_softc *sc)
2310 1.4.4.2 skrll {
2311 1.4.4.2 skrll struct ieee80211com *ic = &sc->sc_ic;
2312 1.4.4.4 skrll struct ifnet *ifp = &sc->sc_if;
2313 1.4.4.2 skrll struct iwi_configuration config;
2314 1.4.4.2 skrll struct iwi_rateset rs;
2315 1.4.4.2 skrll struct iwi_txpower power;
2316 1.4.4.4 skrll struct ieee80211_key *wk;
2317 1.4.4.2 skrll struct iwi_wep_key wepkey;
2318 1.4.4.4 skrll uint32_t data;
2319 1.4.4.2 skrll int error, i;
2320 1.4.4.2 skrll
2321 1.4.4.2 skrll IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
2322 1.4.4.2 skrll DPRINTF(("Setting MAC address to %s\n", ether_sprintf(ic->ic_myaddr)));
2323 1.4.4.2 skrll error = iwi_cmd(sc, IWI_CMD_SET_MAC_ADDRESS, ic->ic_myaddr,
2324 1.4.4.2 skrll IEEE80211_ADDR_LEN, 0);
2325 1.4.4.2 skrll if (error != 0)
2326 1.4.4.2 skrll return error;
2327 1.4.4.2 skrll
2328 1.4.4.2 skrll memset(&config, 0, sizeof config);
2329 1.4.4.4 skrll config.bluetooth_coexistence = sc->bluetooth;
2330 1.4.4.4 skrll config.antenna = sc->antenna;
2331 1.4.4.2 skrll config.multicast_enabled = 1;
2332 1.4.4.4 skrll config.answer_pbreq = (ic->ic_opmode == IEEE80211_M_IBSS) ? 1 : 0;
2333 1.4.4.4 skrll config.disable_unicast_decryption = 1;
2334 1.4.4.4 skrll config.disable_multicast_decryption = 1;
2335 1.4.4.2 skrll DPRINTF(("Configuring adapter\n"));
2336 1.4.4.2 skrll error = iwi_cmd(sc, IWI_CMD_SET_CONFIGURATION, &config, sizeof config,
2337 1.4.4.2 skrll 0);
2338 1.4.4.2 skrll if (error != 0)
2339 1.4.4.2 skrll return error;
2340 1.4.4.2 skrll
2341 1.4.4.2 skrll data = htole32(IWI_POWER_MODE_CAM);
2342 1.4.4.2 skrll DPRINTF(("Setting power mode to %u\n", le32toh(data)));
2343 1.4.4.2 skrll error = iwi_cmd(sc, IWI_CMD_SET_POWER_MODE, &data, sizeof data, 0);
2344 1.4.4.2 skrll if (error != 0)
2345 1.4.4.2 skrll return error;
2346 1.4.4.2 skrll
2347 1.4.4.2 skrll data = htole32(ic->ic_rtsthreshold);
2348 1.4.4.2 skrll DPRINTF(("Setting RTS threshold to %u\n", le32toh(data)));
2349 1.4.4.2 skrll error = iwi_cmd(sc, IWI_CMD_SET_RTS_THRESHOLD, &data, sizeof data, 0);
2350 1.4.4.2 skrll if (error != 0)
2351 1.4.4.2 skrll return error;
2352 1.4.4.2 skrll
2353 1.4.4.4 skrll data = htole32(ic->ic_fragthreshold);
2354 1.4.4.4 skrll DPRINTF(("Setting fragmentation threshold to %u\n", le32toh(data)));
2355 1.4.4.4 skrll error = iwi_cmd(sc, IWI_CMD_SET_FRAG_THRESHOLD, &data, sizeof data, 0);
2356 1.4.4.4 skrll if (error != 0)
2357 1.4.4.4 skrll return error;
2358 1.4.4.4 skrll
2359 1.4.4.2 skrll if (ic->ic_opmode == IEEE80211_M_IBSS) {
2360 1.4.4.2 skrll power.mode = IWI_MODE_11B;
2361 1.4.4.2 skrll power.nchan = 11;
2362 1.4.4.2 skrll for (i = 0; i < 11; i++) {
2363 1.4.4.2 skrll power.chan[i].chan = i + 1;
2364 1.4.4.2 skrll power.chan[i].power = IWI_TXPOWER_MAX;
2365 1.4.4.2 skrll }
2366 1.4.4.2 skrll DPRINTF(("Setting .11b channels tx power\n"));
2367 1.4.4.2 skrll error = iwi_cmd(sc, IWI_CMD_SET_TX_POWER, &power, sizeof power,
2368 1.4.4.2 skrll 0);
2369 1.4.4.2 skrll if (error != 0)
2370 1.4.4.2 skrll return error;
2371 1.4.4.2 skrll
2372 1.4.4.2 skrll power.mode = IWI_MODE_11G;
2373 1.4.4.2 skrll DPRINTF(("Setting .11g channels tx power\n"));
2374 1.4.4.2 skrll error = iwi_cmd(sc, IWI_CMD_SET_TX_POWER, &power, sizeof power,
2375 1.4.4.2 skrll 0);
2376 1.4.4.2 skrll if (error != 0)
2377 1.4.4.2 skrll return error;
2378 1.4.4.2 skrll }
2379 1.4.4.2 skrll
2380 1.4.4.2 skrll rs.mode = IWI_MODE_11G;
2381 1.4.4.2 skrll rs.type = IWI_RATESET_TYPE_SUPPORTED;
2382 1.4.4.2 skrll rs.nrates = ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates;
2383 1.4.4.2 skrll memcpy(rs.rates, ic->ic_sup_rates[IEEE80211_MODE_11G].rs_rates,
2384 1.4.4.2 skrll rs.nrates);
2385 1.4.4.2 skrll DPRINTF(("Setting .11bg supported rates (%u)\n", rs.nrates));
2386 1.4.4.2 skrll error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, 0);
2387 1.4.4.2 skrll if (error != 0)
2388 1.4.4.2 skrll return error;
2389 1.4.4.2 skrll
2390 1.4.4.2 skrll rs.mode = IWI_MODE_11A;
2391 1.4.4.2 skrll rs.type = IWI_RATESET_TYPE_SUPPORTED;
2392 1.4.4.2 skrll rs.nrates = ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates;
2393 1.4.4.2 skrll memcpy(rs.rates, ic->ic_sup_rates[IEEE80211_MODE_11A].rs_rates,
2394 1.4.4.2 skrll rs.nrates);
2395 1.4.4.2 skrll DPRINTF(("Setting .11a supported rates (%u)\n", rs.nrates));
2396 1.4.4.2 skrll error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, 0);
2397 1.4.4.2 skrll if (error != 0)
2398 1.4.4.2 skrll return error;
2399 1.4.4.2 skrll
2400 1.4.4.5 christos /* if we have a desired ESSID, set it now */
2401 1.4.4.5 christos if (ic->ic_des_esslen != 0) {
2402 1.4.4.5 christos #ifdef IWI_DEBUG
2403 1.4.4.5 christos if (iwi_debug > 0) {
2404 1.4.4.5 christos printf("Setting desired ESSID to ");
2405 1.4.4.5 christos ieee80211_print_essid(ic->ic_des_essid,
2406 1.4.4.5 christos ic->ic_des_esslen);
2407 1.4.4.5 christos printf("\n");
2408 1.4.4.5 christos }
2409 1.4.4.5 christos #endif
2410 1.4.4.5 christos error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ic->ic_des_essid,
2411 1.4.4.5 christos ic->ic_des_esslen, 0);
2412 1.4.4.5 christos if (error != 0)
2413 1.4.4.5 christos return error;
2414 1.4.4.5 christos }
2415 1.4.4.5 christos
2416 1.4.4.2 skrll data = htole32(arc4random());
2417 1.4.4.2 skrll DPRINTF(("Setting initialization vector to %u\n", le32toh(data)));
2418 1.4.4.2 skrll error = iwi_cmd(sc, IWI_CMD_SET_IV, &data, sizeof data, 0);
2419 1.4.4.2 skrll if (error != 0)
2420 1.4.4.2 skrll return error;
2421 1.4.4.2 skrll
2422 1.4.4.4 skrll for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2423 1.4.4.4 skrll wk = &ic->ic_crypto.cs_nw_keys[i];
2424 1.4.4.4 skrll
2425 1.4.4.4 skrll wepkey.cmd = IWI_WEP_KEY_CMD_SETKEY;
2426 1.4.4.4 skrll wepkey.idx = i;
2427 1.4.4.4 skrll wepkey.len = wk->wk_keylen;
2428 1.4.4.4 skrll memset(wepkey.key, 0, sizeof wepkey.key);
2429 1.4.4.4 skrll memcpy(wepkey.key, wk->wk_key, wk->wk_keylen);
2430 1.4.4.4 skrll DPRINTF(("Setting wep key index %u len %u\n",
2431 1.4.4.4 skrll wepkey.idx, wepkey.len));
2432 1.4.4.4 skrll error = iwi_cmd(sc, IWI_CMD_SET_WEP_KEY, &wepkey,
2433 1.4.4.4 skrll sizeof wepkey, 0);
2434 1.4.4.4 skrll if (error != 0)
2435 1.4.4.4 skrll return error;
2436 1.4.4.2 skrll }
2437 1.4.4.2 skrll
2438 1.4.4.2 skrll /* Enable adapter */
2439 1.4.4.2 skrll DPRINTF(("Enabling adapter\n"));
2440 1.4.4.2 skrll return iwi_cmd(sc, IWI_CMD_ENABLE, NULL, 0, 0);
2441 1.4.4.2 skrll }
2442 1.4.4.2 skrll
2443 1.4.4.2 skrll static int
2444 1.4.4.4 skrll iwi_set_chan(struct iwi_softc *sc, struct ieee80211_channel *chan)
2445 1.4.4.4 skrll {
2446 1.4.4.4 skrll struct ieee80211com *ic = &sc->sc_ic;
2447 1.4.4.4 skrll struct iwi_scan_v2 scan;
2448 1.4.4.4 skrll
2449 1.4.4.4 skrll (void)memset(&scan, 0, sizeof scan);
2450 1.4.4.4 skrll
2451 1.4.4.4 skrll scan.dwelltime[IWI_SCAN_TYPE_PASSIVE] = htole16(2000);
2452 1.4.4.4 skrll scan.channels[0] = 1 |
2453 1.4.4.4 skrll (IEEE80211_IS_CHAN_5GHZ(chan) ? IWI_CHAN_5GHZ : IWI_CHAN_2GHZ);
2454 1.4.4.4 skrll scan.channels[1] = ieee80211_chan2ieee(ic, chan);
2455 1.4.4.4 skrll iwi_scan_type_set(scan, 1, IWI_SCAN_TYPE_PASSIVE);
2456 1.4.4.4 skrll
2457 1.4.4.4 skrll DPRINTF(("Setting channel to %u\n", ieee80211_chan2ieee(ic, chan)));
2458 1.4.4.4 skrll return iwi_cmd(sc, IWI_CMD_SCAN_V2, &scan, sizeof scan, 1);
2459 1.4.4.4 skrll }
2460 1.4.4.4 skrll
2461 1.4.4.4 skrll static int
2462 1.4.4.2 skrll iwi_scan(struct iwi_softc *sc)
2463 1.4.4.2 skrll {
2464 1.4.4.2 skrll struct ieee80211com *ic = &sc->sc_ic;
2465 1.4.4.4 skrll struct iwi_scan_v2 scan;
2466 1.4.4.4 skrll uint32_t type;
2467 1.4.4.4 skrll uint8_t *p;
2468 1.4.4.4 skrll int i, count, idx;
2469 1.4.4.4 skrll
2470 1.4.4.4 skrll (void)memset(&scan, 0, sizeof scan);
2471 1.4.4.4 skrll scan.dwelltime[IWI_SCAN_TYPE_ACTIVE_BROADCAST] =
2472 1.4.4.4 skrll htole16(sc->dwelltime);
2473 1.4.4.4 skrll scan.dwelltime[IWI_SCAN_TYPE_ACTIVE_BDIRECT] =
2474 1.4.4.4 skrll htole16(sc->dwelltime);
2475 1.4.4.4 skrll
2476 1.4.4.4 skrll /* tell the firmware about the desired essid */
2477 1.4.4.4 skrll if (ic->ic_des_esslen) {
2478 1.4.4.4 skrll int error;
2479 1.4.4.4 skrll
2480 1.4.4.4 skrll DPRINTF(("%s: Setting adapter desired ESSID to %s\n",
2481 1.4.4.4 skrll __func__, ic->ic_des_essid));
2482 1.4.4.4 skrll
2483 1.4.4.4 skrll error = iwi_cmd(sc, IWI_CMD_SET_ESSID,
2484 1.4.4.4 skrll ic->ic_des_essid, ic->ic_des_esslen, 1);
2485 1.4.4.4 skrll if (error)
2486 1.4.4.4 skrll return error;
2487 1.4.4.2 skrll
2488 1.4.4.4 skrll type = IWI_SCAN_TYPE_ACTIVE_BDIRECT;
2489 1.4.4.4 skrll } else {
2490 1.4.4.4 skrll type = IWI_SCAN_TYPE_ACTIVE_BROADCAST;
2491 1.4.4.4 skrll }
2492 1.4.4.4 skrll
2493 1.4.4.4 skrll p = &scan.channels[0];
2494 1.4.4.4 skrll count = idx = 0;
2495 1.4.4.2 skrll for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
2496 1.4.4.2 skrll if (IEEE80211_IS_CHAN_5GHZ(&ic->ic_channels[i]) &&
2497 1.4.4.2 skrll isset(ic->ic_chan_active, i)) {
2498 1.4.4.2 skrll *++p = i;
2499 1.4.4.2 skrll count++;
2500 1.4.4.4 skrll idx++;
2501 1.4.4.4 skrll iwi_scan_type_set(scan, idx, type);
2502 1.4.4.2 skrll }
2503 1.4.4.2 skrll }
2504 1.4.4.4 skrll if (count) {
2505 1.4.4.4 skrll *(p - count) = IWI_CHAN_5GHZ | count;
2506 1.4.4.4 skrll p++;
2507 1.4.4.4 skrll }
2508 1.4.4.2 skrll
2509 1.4.4.2 skrll count = 0;
2510 1.4.4.2 skrll for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
2511 1.4.4.2 skrll if (IEEE80211_IS_CHAN_2GHZ(&ic->ic_channels[i]) &&
2512 1.4.4.2 skrll isset(ic->ic_chan_active, i)) {
2513 1.4.4.2 skrll *++p = i;
2514 1.4.4.2 skrll count++;
2515 1.4.4.4 skrll idx++;
2516 1.4.4.4 skrll iwi_scan_type_set(scan, idx, type);
2517 1.4.4.2 skrll }
2518 1.4.4.2 skrll }
2519 1.4.4.2 skrll *(p - count) = IWI_CHAN_2GHZ | count;
2520 1.4.4.2 skrll
2521 1.4.4.2 skrll DPRINTF(("Start scanning\n"));
2522 1.4.4.4 skrll return iwi_cmd(sc, IWI_CMD_SCAN_V2, &scan, sizeof scan, 1);
2523 1.4.4.2 skrll }
2524 1.4.4.2 skrll
2525 1.4.4.2 skrll static int
2526 1.4.4.2 skrll iwi_auth_and_assoc(struct iwi_softc *sc)
2527 1.4.4.2 skrll {
2528 1.4.4.2 skrll struct ieee80211com *ic = &sc->sc_ic;
2529 1.4.4.2 skrll struct ieee80211_node *ni = ic->ic_bss;
2530 1.4.4.4 skrll struct ifnet *ifp = &sc->sc_if;
2531 1.4.4.5 christos struct ieee80211_wme_info wme;
2532 1.4.4.2 skrll struct iwi_configuration config;
2533 1.4.4.2 skrll struct iwi_associate assoc;
2534 1.4.4.2 skrll struct iwi_rateset rs;
2535 1.4.4.4 skrll uint16_t capinfo;
2536 1.4.4.4 skrll uint32_t data;
2537 1.4.4.2 skrll int error;
2538 1.4.4.2 skrll
2539 1.4.4.2 skrll if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) {
2540 1.4.4.2 skrll memset(&config, 0, sizeof config);
2541 1.4.4.4 skrll config.bluetooth_coexistence = sc->bluetooth;
2542 1.4.4.4 skrll config.antenna = sc->antenna;
2543 1.4.4.2 skrll config.multicast_enabled = 1;
2544 1.4.4.4 skrll config.use_protection = 1;
2545 1.4.4.4 skrll config.answer_pbreq =
2546 1.4.4.4 skrll (ic->ic_opmode == IEEE80211_M_IBSS) ? 1 : 0;
2547 1.4.4.4 skrll config.disable_unicast_decryption = 1;
2548 1.4.4.4 skrll config.disable_multicast_decryption = 1;
2549 1.4.4.2 skrll DPRINTF(("Configuring adapter\n"));
2550 1.4.4.2 skrll error = iwi_cmd(sc, IWI_CMD_SET_CONFIGURATION, &config,
2551 1.4.4.2 skrll sizeof config, 1);
2552 1.4.4.2 skrll if (error != 0)
2553 1.4.4.2 skrll return error;
2554 1.4.4.2 skrll }
2555 1.4.4.2 skrll
2556 1.4.4.2 skrll #ifdef IWI_DEBUG
2557 1.4.4.2 skrll if (iwi_debug > 0) {
2558 1.4.4.2 skrll printf("Setting ESSID to ");
2559 1.4.4.2 skrll ieee80211_print_essid(ni->ni_essid, ni->ni_esslen);
2560 1.4.4.2 skrll printf("\n");
2561 1.4.4.2 skrll }
2562 1.4.4.2 skrll #endif
2563 1.4.4.2 skrll error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ni->ni_essid, ni->ni_esslen, 1);
2564 1.4.4.2 skrll if (error != 0)
2565 1.4.4.2 skrll return error;
2566 1.4.4.2 skrll
2567 1.4.4.4 skrll /* the rate set has already been "negotiated" */
2568 1.4.4.2 skrll rs.mode = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? IWI_MODE_11A :
2569 1.4.4.2 skrll IWI_MODE_11G;
2570 1.4.4.4 skrll rs.type = IWI_RATESET_TYPE_NEGOTIATED;
2571 1.4.4.2 skrll rs.nrates = ni->ni_rates.rs_nrates;
2572 1.4.4.2 skrll memcpy(rs.rates, ni->ni_rates.rs_rates, rs.nrates);
2573 1.4.4.4 skrll DPRINTF(("Setting negotiated rates (%u)\n", rs.nrates));
2574 1.4.4.2 skrll error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, 1);
2575 1.4.4.2 skrll if (error != 0)
2576 1.4.4.2 skrll return error;
2577 1.4.4.2 skrll
2578 1.4.4.5 christos if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) {
2579 1.4.4.5 christos wme.wme_id = IEEE80211_ELEMID_VENDOR;
2580 1.4.4.5 christos wme.wme_len = sizeof (struct ieee80211_wme_info) - 2;
2581 1.4.4.5 christos wme.wme_oui[0] = 0x00;
2582 1.4.4.5 christos wme.wme_oui[1] = 0x50;
2583 1.4.4.5 christos wme.wme_oui[2] = 0xf2;
2584 1.4.4.5 christos wme.wme_type = WME_OUI_TYPE;
2585 1.4.4.5 christos wme.wme_subtype = WME_INFO_OUI_SUBTYPE;
2586 1.4.4.5 christos wme.wme_version = WME_VERSION;
2587 1.4.4.5 christos wme.wme_info = 0;
2588 1.4.4.5 christos
2589 1.4.4.5 christos DPRINTF(("Setting WME IE (len=%u)\n", wme.wme_len));
2590 1.4.4.5 christos error = iwi_cmd(sc, IWI_CMD_SET_WMEIE, &wme, sizeof wme, 1);
2591 1.4.4.5 christos if (error != 0)
2592 1.4.4.5 christos return error;
2593 1.4.4.5 christos }
2594 1.4.4.5 christos
2595 1.4.4.4 skrll if (ic->ic_opt_ie != NULL) {
2596 1.4.4.4 skrll DPRINTF(("Setting optional IE (len=%u)\n", ic->ic_opt_ie_len));
2597 1.4.4.4 skrll error = iwi_cmd(sc, IWI_CMD_SET_OPTIE, ic->ic_opt_ie,
2598 1.4.4.4 skrll ic->ic_opt_ie_len, 1);
2599 1.4.4.4 skrll if (error != 0)
2600 1.4.4.4 skrll return error;
2601 1.4.4.4 skrll }
2602 1.4.4.2 skrll data = htole32(ni->ni_rssi);
2603 1.4.4.2 skrll DPRINTF(("Setting sensitivity to %d\n", (int8_t)ni->ni_rssi));
2604 1.4.4.2 skrll error = iwi_cmd(sc, IWI_CMD_SET_SENSITIVITY, &data, sizeof data, 1);
2605 1.4.4.2 skrll if (error != 0)
2606 1.4.4.2 skrll return error;
2607 1.4.4.2 skrll
2608 1.4.4.2 skrll memset(&assoc, 0, sizeof assoc);
2609 1.4.4.2 skrll assoc.mode = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? IWI_MODE_11A :
2610 1.4.4.2 skrll IWI_MODE_11G;
2611 1.4.4.2 skrll assoc.chan = ieee80211_chan2ieee(ic, ni->ni_chan);
2612 1.4.4.4 skrll if (ni->ni_authmode == IEEE80211_AUTH_SHARED)
2613 1.4.4.4 skrll assoc.auth = (ic->ic_crypto.cs_def_txkey << 4) | IWI_AUTH_SHARED;
2614 1.4.4.5 christos if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL)
2615 1.4.4.5 christos assoc.policy |= htole16(IWI_POLICY_WME);
2616 1.4.4.4 skrll if (ic->ic_opt_ie != NULL)
2617 1.4.4.5 christos assoc.policy |= htole16(IWI_POLICY_WPA);
2618 1.4.4.4 skrll memcpy(assoc.tstamp, ni->ni_tstamp.data, 8);
2619 1.4.4.4 skrll
2620 1.4.4.4 skrll if (ic->ic_opmode == IEEE80211_M_IBSS)
2621 1.4.4.4 skrll capinfo = IEEE80211_CAPINFO_IBSS;
2622 1.4.4.4 skrll else
2623 1.4.4.4 skrll capinfo = IEEE80211_CAPINFO_ESS;
2624 1.4.4.4 skrll if (ic->ic_flags & IEEE80211_F_PRIVACY)
2625 1.4.4.4 skrll capinfo |= IEEE80211_CAPINFO_PRIVACY;
2626 1.4.4.4 skrll if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
2627 1.4.4.4 skrll IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
2628 1.4.4.4 skrll capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
2629 1.4.4.4 skrll if (ic->ic_flags & IEEE80211_F_SHSLOT)
2630 1.4.4.4 skrll capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
2631 1.4.4.4 skrll assoc.capinfo = htole16(capinfo);
2632 1.4.4.4 skrll
2633 1.4.4.2 skrll assoc.lintval = htole16(ic->ic_lintval);
2634 1.4.4.2 skrll assoc.intval = htole16(ni->ni_intval);
2635 1.4.4.2 skrll IEEE80211_ADDR_COPY(assoc.bssid, ni->ni_bssid);
2636 1.4.4.4 skrll if (ic->ic_opmode == IEEE80211_M_IBSS)
2637 1.4.4.4 skrll IEEE80211_ADDR_COPY(assoc.dst, ifp->if_broadcastaddr);
2638 1.4.4.4 skrll else
2639 1.4.4.4 skrll IEEE80211_ADDR_COPY(assoc.dst, ni->ni_bssid);
2640 1.4.4.2 skrll DPRINTF(("Trying to associate to %s channel %u auth %u\n",
2641 1.4.4.2 skrll ether_sprintf(assoc.bssid), assoc.chan, assoc.auth));
2642 1.4.4.2 skrll return iwi_cmd(sc, IWI_CMD_ASSOCIATE, &assoc, sizeof assoc, 1);
2643 1.4.4.2 skrll }
2644 1.4.4.2 skrll
2645 1.4.4.2 skrll static int
2646 1.4.4.2 skrll iwi_init(struct ifnet *ifp)
2647 1.4.4.2 skrll {
2648 1.4.4.2 skrll struct iwi_softc *sc = ifp->if_softc;
2649 1.4.4.2 skrll struct ieee80211com *ic = &sc->sc_ic;
2650 1.4.4.2 skrll struct iwi_firmware *fw = &sc->fw;
2651 1.4.4.2 skrll int i, error;
2652 1.4.4.2 skrll
2653 1.4.4.2 skrll /* exit immediately if firmware has not been ioctl'd */
2654 1.4.4.2 skrll if (!(sc->flags & IWI_FLAG_FW_CACHED)) {
2655 1.4.4.4 skrll if (!(sc->flags & IWI_FLAG_FW_WARNED))
2656 1.4.4.4 skrll aprint_error("%s: Firmware not loaded\n",
2657 1.4.4.4 skrll sc->sc_dev.dv_xname);
2658 1.4.4.4 skrll sc->flags |= IWI_FLAG_FW_WARNED;
2659 1.4.4.2 skrll ifp->if_flags &= ~IFF_UP;
2660 1.4.4.2 skrll return EIO;
2661 1.4.4.2 skrll }
2662 1.4.4.2 skrll
2663 1.4.4.4 skrll iwi_stop(ifp, 0);
2664 1.4.4.4 skrll
2665 1.4.4.2 skrll if ((error = iwi_reset(sc)) != 0) {
2666 1.4.4.2 skrll aprint_error("%s: could not reset adapter\n",
2667 1.4.4.2 skrll sc->sc_dev.dv_xname);
2668 1.4.4.2 skrll goto fail;
2669 1.4.4.2 skrll }
2670 1.4.4.2 skrll
2671 1.4.4.2 skrll if ((error = iwi_load_firmware(sc, fw->boot, fw->boot_size)) != 0) {
2672 1.4.4.2 skrll aprint_error("%s: could not load boot firmware\n",
2673 1.4.4.2 skrll sc->sc_dev.dv_xname);
2674 1.4.4.2 skrll goto fail;
2675 1.4.4.2 skrll }
2676 1.4.4.2 skrll
2677 1.4.4.2 skrll if ((error = iwi_load_ucode(sc, fw->ucode, fw->ucode_size)) != 0) {
2678 1.4.4.2 skrll aprint_error("%s: could not load microcode\n",
2679 1.4.4.2 skrll sc->sc_dev.dv_xname);
2680 1.4.4.2 skrll goto fail;
2681 1.4.4.2 skrll }
2682 1.4.4.2 skrll
2683 1.4.4.2 skrll iwi_stop_master(sc);
2684 1.4.4.2 skrll
2685 1.4.4.4 skrll CSR_WRITE_4(sc, IWI_CSR_CMD_BASE, sc->cmdq.desc_map->dm_segs[0].ds_addr);
2686 1.4.4.4 skrll CSR_WRITE_4(sc, IWI_CSR_CMD_SIZE, sc->cmdq.count);
2687 1.4.4.4 skrll CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.cur);
2688 1.4.4.4 skrll
2689 1.4.4.5 christos CSR_WRITE_4(sc, IWI_CSR_TX1_BASE, sc->txq[0].desc_map->dm_segs[0].ds_addr);
2690 1.4.4.5 christos CSR_WRITE_4(sc, IWI_CSR_TX1_SIZE, sc->txq[0].count);
2691 1.4.4.5 christos CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq[0].cur);
2692 1.4.4.5 christos
2693 1.4.4.5 christos CSR_WRITE_4(sc, IWI_CSR_TX2_BASE, sc->txq[1].desc_map->dm_segs[0].ds_addr);
2694 1.4.4.5 christos CSR_WRITE_4(sc, IWI_CSR_TX2_SIZE, sc->txq[1].count);
2695 1.4.4.5 christos CSR_WRITE_4(sc, IWI_CSR_TX2_WIDX, sc->txq[1].cur);
2696 1.4.4.5 christos
2697 1.4.4.5 christos CSR_WRITE_4(sc, IWI_CSR_TX3_BASE, sc->txq[2].desc_map->dm_segs[0].ds_addr);
2698 1.4.4.5 christos CSR_WRITE_4(sc, IWI_CSR_TX3_SIZE, sc->txq[2].count);
2699 1.4.4.5 christos CSR_WRITE_4(sc, IWI_CSR_TX3_WIDX, sc->txq[2].cur);
2700 1.4.4.5 christos
2701 1.4.4.5 christos CSR_WRITE_4(sc, IWI_CSR_TX4_BASE, sc->txq[3].desc_map->dm_segs[0].ds_addr);
2702 1.4.4.5 christos CSR_WRITE_4(sc, IWI_CSR_TX4_SIZE, sc->txq[3].count);
2703 1.4.4.5 christos CSR_WRITE_4(sc, IWI_CSR_TX4_WIDX, sc->txq[3].cur);
2704 1.4.4.2 skrll
2705 1.4.4.4 skrll for (i = 0; i < sc->rxq.count; i++)
2706 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_RX_BASE + i * 4,
2707 1.4.4.4 skrll sc->rxq.data[i].map->dm_segs[0].ds_addr);
2708 1.4.4.2 skrll
2709 1.4.4.4 skrll CSR_WRITE_4(sc, IWI_CSR_RX_WIDX, sc->rxq.count -1);
2710 1.4.4.2 skrll
2711 1.4.4.2 skrll if ((error = iwi_load_firmware(sc, fw->main, fw->main_size)) != 0) {
2712 1.4.4.2 skrll aprint_error("%s: could not load main firmware\n",
2713 1.4.4.2 skrll sc->sc_dev.dv_xname);
2714 1.4.4.2 skrll goto fail;
2715 1.4.4.2 skrll }
2716 1.4.4.2 skrll
2717 1.4.4.2 skrll sc->flags |= IWI_FLAG_FW_INITED;
2718 1.4.4.2 skrll
2719 1.4.4.2 skrll if ((error = iwi_config(sc)) != 0) {
2720 1.4.4.2 skrll aprint_error("%s: device configuration failed\n",
2721 1.4.4.2 skrll sc->sc_dev.dv_xname);
2722 1.4.4.2 skrll goto fail;
2723 1.4.4.2 skrll }
2724 1.4.4.2 skrll
2725 1.4.4.5 christos ic->ic_state = IEEE80211_S_INIT;
2726 1.4.4.2 skrll
2727 1.4.4.2 skrll ifp->if_flags &= ~IFF_OACTIVE;
2728 1.4.4.2 skrll ifp->if_flags |= IFF_RUNNING;
2729 1.4.4.2 skrll
2730 1.4.4.5 christos if (ic->ic_opmode != IEEE80211_M_MONITOR) {
2731 1.4.4.5 christos if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
2732 1.4.4.5 christos ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2733 1.4.4.5 christos } else
2734 1.4.4.5 christos ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
2735 1.4.4.5 christos
2736 1.4.4.2 skrll return 0;
2737 1.4.4.2 skrll
2738 1.4.4.4 skrll fail: ifp->if_flags &= ~IFF_UP;
2739 1.4.4.4 skrll iwi_stop(ifp, 0);
2740 1.4.4.2 skrll
2741 1.4.4.2 skrll return error;
2742 1.4.4.2 skrll }
2743 1.4.4.2 skrll
2744 1.4.4.2 skrll static void
2745 1.4.4.2 skrll iwi_stop(struct ifnet *ifp, int disable)
2746 1.4.4.2 skrll {
2747 1.4.4.2 skrll struct iwi_softc *sc = ifp->if_softc;
2748 1.4.4.2 skrll struct ieee80211com *ic = &sc->sc_ic;
2749 1.4.4.2 skrll
2750 1.4.4.5 christos IWI_LED_OFF(sc);
2751 1.4.4.5 christos
2752 1.4.4.2 skrll iwi_stop_master(sc);
2753 1.4.4.2 skrll CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_SW_RESET);
2754 1.4.4.2 skrll
2755 1.4.4.4 skrll /* reset rings */
2756 1.4.4.4 skrll iwi_reset_cmd_ring(sc, &sc->cmdq);
2757 1.4.4.5 christos iwi_reset_tx_ring(sc, &sc->txq[0]);
2758 1.4.4.5 christos iwi_reset_tx_ring(sc, &sc->txq[1]);
2759 1.4.4.5 christos iwi_reset_tx_ring(sc, &sc->txq[2]);
2760 1.4.4.5 christos iwi_reset_tx_ring(sc, &sc->txq[3]);
2761 1.4.4.4 skrll iwi_reset_rx_ring(sc, &sc->rxq);
2762 1.4.4.2 skrll
2763 1.4.4.2 skrll ifp->if_timer = 0;
2764 1.4.4.2 skrll ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2765 1.4.4.2 skrll
2766 1.4.4.2 skrll ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2767 1.4.4.2 skrll }
2768 1.4.4.5 christos
2769 1.4.4.5 christos static void
2770 1.4.4.5 christos iwi_led_set(struct iwi_softc *sc, uint32_t state, int toggle)
2771 1.4.4.5 christos {
2772 1.4.4.5 christos uint32_t val;
2773 1.4.4.5 christos
2774 1.4.4.5 christos val = MEM_READ_4(sc, IWI_MEM_EVENT_CTL);
2775 1.4.4.5 christos
2776 1.4.4.5 christos switch (sc->nictype) {
2777 1.4.4.5 christos case 1:
2778 1.4.4.5 christos /* special NIC type: reversed leds */
2779 1.4.4.5 christos if (state == IWI_LED_ACTIVITY) {
2780 1.4.4.5 christos state &= ~IWI_LED_ACTIVITY;
2781 1.4.4.5 christos state |= IWI_LED_ASSOCIATED;
2782 1.4.4.5 christos } else if (state == IWI_LED_ASSOCIATED) {
2783 1.4.4.5 christos state &= ~IWI_LED_ASSOCIATED;
2784 1.4.4.5 christos state |= IWI_LED_ACTIVITY;
2785 1.4.4.5 christos }
2786 1.4.4.5 christos /* and ignore toggle effect */
2787 1.4.4.5 christos val |= state;
2788 1.4.4.5 christos break;
2789 1.4.4.5 christos case 0:
2790 1.4.4.5 christos case 2:
2791 1.4.4.5 christos case 3:
2792 1.4.4.5 christos case 4:
2793 1.4.4.5 christos val = (toggle && (val & state)) ? val & ~state : val | state;
2794 1.4.4.5 christos break;
2795 1.4.4.5 christos default:
2796 1.4.4.5 christos aprint_normal("%s: unknown NIC type %d\n",
2797 1.4.4.5 christos sc->sc_dev.dv_xname, sc->nictype);
2798 1.4.4.5 christos return;
2799 1.4.4.5 christos break;
2800 1.4.4.5 christos }
2801 1.4.4.5 christos
2802 1.4.4.5 christos MEM_WRITE_4(sc, IWI_MEM_EVENT_CTL, val);
2803 1.4.4.5 christos
2804 1.4.4.5 christos return;
2805 1.4.4.5 christos }
2806 1.4.4.5 christos
2807 1.4.4.5 christos static void
2808 1.4.4.5 christos iwi_error_log(struct iwi_softc *sc)
2809 1.4.4.5 christos {
2810 1.4.4.5 christos uint32_t b, n;
2811 1.4.4.5 christos int i;
2812 1.4.4.5 christos
2813 1.4.4.5 christos static const char *const msg[] = {
2814 1.4.4.5 christos "no error",
2815 1.4.4.5 christos "failed",
2816 1.4.4.5 christos "memory range low",
2817 1.4.4.5 christos "memory range high",
2818 1.4.4.5 christos "bad parameter",
2819 1.4.4.5 christos "checksum",
2820 1.4.4.5 christos "NMI",
2821 1.4.4.5 christos "bad database",
2822 1.4.4.5 christos "allocation failed",
2823 1.4.4.5 christos "DMA underrun",
2824 1.4.4.5 christos "DMA status",
2825 1.4.4.5 christos "DINO",
2826 1.4.4.5 christos "EEPROM",
2827 1.4.4.5 christos "device assert",
2828 1.4.4.5 christos "fatal"
2829 1.4.4.5 christos };
2830 1.4.4.5 christos
2831 1.4.4.5 christos b = CSR_READ_4(sc, IWI_CSR_ERRORLOG);
2832 1.4.4.5 christos n = MEM_READ_4(sc, b);
2833 1.4.4.5 christos
2834 1.4.4.5 christos b += 4;
2835 1.4.4.5 christos
2836 1.4.4.5 christos for (i = 0; i < n ; i++) {
2837 1.4.4.5 christos struct iwi_error fw_error;
2838 1.4.4.5 christos
2839 1.4.4.5 christos MEM_CPY(sc, &fw_error, b, sizeof(fw_error));
2840 1.4.4.5 christos
2841 1.4.4.5 christos printf("%s: %s\n", sc->sc_dev.dv_xname,
2842 1.4.4.5 christos msg[fw_error.type]);
2843 1.4.4.5 christos
2844 1.4.4.5 christos b += sizeof(fw_error);
2845 1.4.4.5 christos }
2846 1.4.4.5 christos }
2847