Line data Source code
1 : /* $OpenBSD: if_iwi.c,v 1.138 2018/04/26 12:50:07 pirofti Exp $ */
2 :
3 : /*-
4 : * Copyright (c) 2004-2008
5 : * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
6 : *
7 : * Permission to use, copy, modify, and distribute this software for any
8 : * purpose with or without fee is hereby granted, provided that the above
9 : * copyright notice and this permission notice appear in all copies.
10 : *
11 : * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 : * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 : * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 : * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 : * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 : * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 : */
19 :
20 : /*
21 : * Driver for Intel PRO/Wireless 2200BG/2915ABG 802.11 network adapters.
22 : */
23 :
24 : #include "bpfilter.h"
25 :
26 : #include <sys/param.h>
27 : #include <sys/sockio.h>
28 : #include <sys/mbuf.h>
29 : #include <sys/kernel.h>
30 : #include <sys/rwlock.h>
31 : #include <sys/socket.h>
32 : #include <sys/systm.h>
33 : #include <sys/conf.h>
34 : #include <sys/device.h>
35 : #include <sys/task.h>
36 : #include <sys/endian.h>
37 :
38 : #include <machine/bus.h>
39 : #include <machine/intr.h>
40 :
41 : #include <dev/pci/pcireg.h>
42 : #include <dev/pci/pcivar.h>
43 : #include <dev/pci/pcidevs.h>
44 :
45 : #if NBPFILTER > 0
46 : #include <net/bpf.h>
47 : #endif
48 : #include <net/if.h>
49 : #include <net/if_dl.h>
50 : #include <net/if_media.h>
51 :
52 : #include <netinet/in.h>
53 : #include <netinet/if_ether.h>
54 :
55 : #include <net80211/ieee80211_var.h>
56 : #include <net80211/ieee80211_radiotap.h>
57 :
58 : #include <dev/pci/if_iwireg.h>
59 : #include <dev/pci/if_iwivar.h>
60 :
61 : const struct pci_matchid iwi_devices[] = {
62 : { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_2200BG },
63 : { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_2225BG },
64 : { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_2915ABG_1 },
65 : { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_2915ABG_2 }
66 : };
67 :
68 : int iwi_match(struct device *, void *, void *);
69 : void iwi_attach(struct device *, struct device *, void *);
70 : int iwi_activate(struct device *, int);
71 : void iwi_wakeup(struct iwi_softc *);
72 : void iwi_init_task(void *);
73 : int iwi_alloc_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
74 : void iwi_reset_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
75 : void iwi_free_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
76 : int iwi_alloc_tx_ring(struct iwi_softc *, struct iwi_tx_ring *,
77 : int);
78 : void iwi_reset_tx_ring(struct iwi_softc *, struct iwi_tx_ring *);
79 : void iwi_free_tx_ring(struct iwi_softc *, struct iwi_tx_ring *);
80 : int iwi_alloc_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
81 : void iwi_reset_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
82 : void iwi_free_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
83 : int iwi_media_change(struct ifnet *);
84 : void iwi_media_status(struct ifnet *, struct ifmediareq *);
85 : uint16_t iwi_read_prom_word(struct iwi_softc *, uint8_t);
86 : int iwi_find_txnode(struct iwi_softc *, const uint8_t *);
87 : int iwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
88 : uint8_t iwi_rate(int);
89 : void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *,
90 : struct iwi_frame *);
91 : void iwi_notification_intr(struct iwi_softc *, struct iwi_rx_data *,
92 : struct iwi_notif *);
93 : void iwi_rx_intr(struct iwi_softc *);
94 : void iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *);
95 : int iwi_intr(void *);
96 : int iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t, int);
97 : int iwi_send_mgmt(struct ieee80211com *, struct ieee80211_node *,
98 : int, int, int);
99 : int iwi_tx_start(struct ifnet *, struct mbuf *,
100 : struct ieee80211_node *);
101 : void iwi_start(struct ifnet *);
102 : void iwi_watchdog(struct ifnet *);
103 : int iwi_ioctl(struct ifnet *, u_long, caddr_t);
104 : void iwi_stop_master(struct iwi_softc *);
105 : int iwi_reset(struct iwi_softc *);
106 : int iwi_load_ucode(struct iwi_softc *, const char *, int);
107 : int iwi_load_firmware(struct iwi_softc *, const char *, int);
108 : int iwi_config(struct iwi_softc *);
109 : void iwi_update_edca(struct ieee80211com *);
110 : int iwi_set_chan(struct iwi_softc *, struct ieee80211_channel *);
111 : int iwi_scan(struct iwi_softc *);
112 : int iwi_auth_and_assoc(struct iwi_softc *);
113 : int iwi_init(struct ifnet *);
114 : void iwi_stop(struct ifnet *, int);
115 :
116 : static __inline uint8_t
117 0 : MEM_READ_1(struct iwi_softc *sc, uint32_t addr)
118 : {
119 0 : CSR_WRITE_4(sc, IWI_CSR_INDIRECT_ADDR, addr);
120 0 : return CSR_READ_1(sc, IWI_CSR_INDIRECT_DATA);
121 : }
122 :
123 : static __inline uint32_t
124 0 : MEM_READ_4(struct iwi_softc *sc, uint32_t addr)
125 : {
126 0 : CSR_WRITE_4(sc, IWI_CSR_INDIRECT_ADDR, addr);
127 0 : return CSR_READ_4(sc, IWI_CSR_INDIRECT_DATA);
128 : }
129 :
130 : #ifdef IWI_DEBUG
131 : #define DPRINTF(x) do { if (iwi_debug > 0) printf x; } while (0)
132 : #define DPRINTFN(n, x) do { if (iwi_debug >= (n)) printf x; } while (0)
133 : int iwi_debug = 0;
134 : #else
135 : #define DPRINTF(x)
136 : #define DPRINTFN(n, x)
137 : #endif
138 :
139 : struct cfattach iwi_ca = {
140 : sizeof (struct iwi_softc), iwi_match, iwi_attach, NULL,
141 : iwi_activate
142 : };
143 :
144 : int
145 0 : iwi_match(struct device *parent, void *match, void *aux)
146 : {
147 0 : return pci_matchbyid((struct pci_attach_args *)aux, iwi_devices,
148 : nitems(iwi_devices));
149 : }
150 :
151 : /* Base Address Register */
152 : #define IWI_PCI_BAR0 0x10
153 :
154 : void
155 0 : iwi_attach(struct device *parent, struct device *self, void *aux)
156 : {
157 0 : struct iwi_softc *sc = (struct iwi_softc *)self;
158 0 : struct ieee80211com *ic = &sc->sc_ic;
159 0 : struct ifnet *ifp = &ic->ic_if;
160 0 : struct pci_attach_args *pa = aux;
161 : const char *intrstr;
162 0 : bus_space_tag_t memt;
163 0 : bus_space_handle_t memh;
164 0 : pci_intr_handle_t ih;
165 : pcireg_t data;
166 : uint16_t val;
167 : int error, ac, i;
168 :
169 0 : sc->sc_pct = pa->pa_pc;
170 0 : sc->sc_pcitag = pa->pa_tag;
171 :
172 : /* clear device specific PCI configuration register 0x41 */
173 0 : data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
174 0 : data &= ~0x0000ff00;
175 0 : pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
176 :
177 : /* map the register window */
178 0 : error = pci_mapreg_map(pa, IWI_PCI_BAR0, PCI_MAPREG_TYPE_MEM |
179 0 : PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt, &memh, NULL, &sc->sc_sz, 0);
180 0 : if (error != 0) {
181 0 : printf(": can't map mem space\n");
182 0 : return;
183 : }
184 :
185 0 : sc->sc_st = memt;
186 0 : sc->sc_sh = memh;
187 0 : sc->sc_dmat = pa->pa_dmat;
188 :
189 0 : if (pci_intr_map(pa, &ih) != 0) {
190 0 : printf(": can't map interrupt\n");
191 0 : return;
192 : }
193 :
194 0 : intrstr = pci_intr_string(sc->sc_pct, ih);
195 0 : sc->sc_ih = pci_intr_establish(sc->sc_pct, ih, IPL_NET, iwi_intr, sc,
196 0 : sc->sc_dev.dv_xname);
197 0 : if (sc->sc_ih == NULL) {
198 0 : printf(": can't establish interrupt");
199 0 : if (intrstr != NULL)
200 0 : printf(" at %s", intrstr);
201 0 : printf("\n");
202 0 : return;
203 : }
204 0 : printf(": %s", intrstr);
205 :
206 0 : if (iwi_reset(sc) != 0) {
207 0 : printf(": could not reset adapter\n");
208 0 : return;
209 : }
210 :
211 : /*
212 : * Allocate rings.
213 : */
214 0 : if (iwi_alloc_cmd_ring(sc, &sc->cmdq) != 0) {
215 0 : printf(": could not allocate Cmd ring\n");
216 0 : return;
217 : }
218 0 : for (ac = 0; ac < EDCA_NUM_AC; ac++) {
219 0 : if (iwi_alloc_tx_ring(sc, &sc->txq[ac], ac) != 0) {
220 0 : printf(": could not allocate Tx ring %d\n", ac);
221 0 : goto fail;
222 : }
223 : }
224 0 : if (iwi_alloc_rx_ring(sc, &sc->rxq) != 0) {
225 0 : printf(": could not allocate Rx ring\n");
226 0 : goto fail;
227 : }
228 :
229 0 : ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
230 0 : ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
231 0 : ic->ic_state = IEEE80211_S_INIT;
232 :
233 : /* set device capabilities */
234 0 : ic->ic_caps =
235 : #ifndef IEEE80211_STA_ONLY
236 : IEEE80211_C_IBSS | /* IBSS mode supported */
237 : #endif
238 : IEEE80211_C_MONITOR | /* monitor mode supported */
239 : IEEE80211_C_TXPMGT | /* tx power management */
240 : IEEE80211_C_SHPREAMBLE | /* short preamble supported */
241 : IEEE80211_C_SHSLOT | /* short slot time supported */
242 : IEEE80211_C_WEP | /* s/w WEP */
243 : IEEE80211_C_RSN | /* WPA/RSN supported */
244 : IEEE80211_C_SCANALL; /* h/w scanning */
245 :
246 : /* read MAC address from EEPROM */
247 0 : val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0);
248 0 : ic->ic_myaddr[0] = val & 0xff;
249 0 : ic->ic_myaddr[1] = val >> 8;
250 0 : val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 1);
251 0 : ic->ic_myaddr[2] = val & 0xff;
252 0 : ic->ic_myaddr[3] = val >> 8;
253 0 : val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 2);
254 0 : ic->ic_myaddr[4] = val & 0xff;
255 0 : ic->ic_myaddr[5] = val >> 8;
256 :
257 0 : printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
258 :
259 0 : if (PCI_PRODUCT(pa->pa_id) >= PCI_PRODUCT_INTEL_PRO_WL_2915ABG_1) {
260 : /* set supported .11a rates */
261 0 : ic->ic_sup_rates[IEEE80211_MODE_11A] =
262 0 : ieee80211_std_rateset_11a;
263 :
264 : /* set supported .11a channels */
265 0 : for (i = 36; i <= 64; i += 4) {
266 0 : ic->ic_channels[i].ic_freq =
267 0 : ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
268 0 : ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
269 : }
270 0 : for (i = 149; i <= 165; i += 4) {
271 0 : ic->ic_channels[i].ic_freq =
272 0 : ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
273 0 : ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
274 : }
275 : }
276 :
277 : /* set supported .11b and .11g rates */
278 0 : ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
279 0 : ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
280 :
281 : /* set supported .11b and .11g channels (1 through 14) */
282 0 : for (i = 1; i <= 14; i++) {
283 0 : ic->ic_channels[i].ic_freq =
284 0 : ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
285 0 : ic->ic_channels[i].ic_flags =
286 : IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
287 : IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
288 : }
289 :
290 : /* IBSS channel undefined for now */
291 0 : ic->ic_ibss_chan = &ic->ic_channels[0];
292 :
293 0 : ifp->if_softc = sc;
294 0 : ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
295 0 : ifp->if_ioctl = iwi_ioctl;
296 0 : ifp->if_start = iwi_start;
297 0 : ifp->if_watchdog = iwi_watchdog;
298 0 : bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
299 :
300 0 : if_attach(ifp);
301 0 : ieee80211_ifattach(ifp);
302 : /* override state transition machine */
303 0 : sc->sc_newstate = ic->ic_newstate;
304 0 : ic->ic_newstate = iwi_newstate;
305 0 : ic->ic_send_mgmt = iwi_send_mgmt;
306 0 : ieee80211_media_init(ifp, iwi_media_change, iwi_media_status);
307 :
308 : #if NBPFILTER > 0
309 0 : bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
310 : sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN);
311 :
312 0 : sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
313 0 : sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
314 0 : sc->sc_rxtap.wr_ihdr.it_present = htole32(IWI_RX_RADIOTAP_PRESENT);
315 :
316 0 : sc->sc_txtap_len = sizeof sc->sc_txtapu;
317 0 : sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
318 0 : sc->sc_txtap.wt_ihdr.it_present = htole32(IWI_TX_RADIOTAP_PRESENT);
319 : #endif
320 :
321 0 : rw_init(&sc->sc_rwlock, "iwilock");
322 0 : task_set(&sc->init_task, iwi_init_task, sc);
323 0 : return;
324 :
325 0 : fail: while (--ac >= 0)
326 0 : iwi_free_tx_ring(sc, &sc->txq[ac]);
327 0 : iwi_free_cmd_ring(sc, &sc->cmdq);
328 0 : }
329 :
330 : int
331 0 : iwi_activate(struct device *self, int act)
332 : {
333 0 : struct iwi_softc *sc = (struct iwi_softc *)self;
334 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
335 :
336 0 : switch (act) {
337 : case DVACT_SUSPEND:
338 0 : if (ifp->if_flags & IFF_RUNNING)
339 0 : iwi_stop(ifp, 0);
340 : break;
341 : case DVACT_WAKEUP:
342 0 : iwi_wakeup(sc);
343 0 : break;
344 : }
345 :
346 0 : return 0;
347 : }
348 :
349 : void
350 0 : iwi_wakeup(struct iwi_softc *sc)
351 : {
352 : pcireg_t data;
353 :
354 : /* clear device specific PCI configuration register 0x41 */
355 0 : data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
356 0 : data &= ~0x0000ff00;
357 0 : pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
358 :
359 0 : iwi_init_task(sc);
360 0 : }
361 :
362 : void
363 0 : iwi_init_task(void *arg1)
364 : {
365 0 : struct iwi_softc *sc = arg1;
366 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
367 : int s;
368 :
369 0 : rw_enter_write(&sc->sc_rwlock);
370 0 : s = splnet();
371 :
372 0 : if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
373 0 : iwi_init(ifp);
374 :
375 0 : splx(s);
376 0 : rw_exit_write(&sc->sc_rwlock);
377 0 : }
378 :
379 : int
380 0 : iwi_alloc_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring)
381 : {
382 0 : int nsegs, error;
383 :
384 0 : ring->queued = 0;
385 0 : ring->cur = ring->next = 0;
386 :
387 0 : error = bus_dmamap_create(sc->sc_dmat,
388 : sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_COUNT, 1,
389 : sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_COUNT, 0,
390 : BUS_DMA_NOWAIT, &ring->map);
391 0 : if (error != 0) {
392 0 : printf("%s: could not create cmd ring DMA map\n",
393 0 : sc->sc_dev.dv_xname);
394 0 : goto fail;
395 : }
396 :
397 0 : error = bus_dmamem_alloc(sc->sc_dmat,
398 : sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_COUNT, PAGE_SIZE, 0,
399 : &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
400 0 : if (error != 0) {
401 0 : printf("%s: could not allocate cmd ring DMA memory\n",
402 0 : sc->sc_dev.dv_xname);
403 0 : goto fail;
404 : }
405 :
406 0 : error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
407 : sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_COUNT,
408 : (caddr_t *)&ring->desc, BUS_DMA_NOWAIT);
409 0 : if (error != 0) {
410 0 : printf("%s: can't map cmd ring DMA memory\n",
411 0 : sc->sc_dev.dv_xname);
412 0 : goto fail;
413 : }
414 :
415 0 : error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
416 : sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_COUNT, NULL,
417 : BUS_DMA_NOWAIT);
418 0 : if (error != 0) {
419 0 : printf("%s: could not load cmd ring DMA map\n",
420 0 : sc->sc_dev.dv_xname);
421 0 : goto fail;
422 : }
423 :
424 0 : return 0;
425 :
426 0 : fail: iwi_free_cmd_ring(sc, ring);
427 0 : return error;
428 0 : }
429 :
430 : void
431 0 : iwi_reset_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring)
432 : {
433 0 : ring->queued = 0;
434 0 : ring->cur = ring->next = 0;
435 0 : }
436 :
437 : void
438 0 : iwi_free_cmd_ring(struct iwi_softc *sc, struct iwi_cmd_ring *ring)
439 : {
440 0 : if (ring->map != NULL) {
441 0 : if (ring->desc != NULL) {
442 0 : bus_dmamap_unload(sc->sc_dmat, ring->map);
443 0 : bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
444 : sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_COUNT);
445 0 : bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
446 0 : }
447 0 : bus_dmamap_destroy(sc->sc_dmat, ring->map);
448 0 : }
449 0 : }
450 :
451 : int
452 0 : iwi_alloc_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring, int ac)
453 : {
454 : struct iwi_tx_data *data;
455 0 : int i, nsegs, error;
456 :
457 0 : ring->queued = 0;
458 0 : ring->cur = ring->next = 0;
459 0 : ring->csr_ridx = IWI_CSR_TX_RIDX(ac);
460 0 : ring->csr_widx = IWI_CSR_TX_WIDX(ac);
461 :
462 0 : error = bus_dmamap_create(sc->sc_dmat,
463 : sizeof (struct iwi_tx_desc) * IWI_TX_RING_COUNT, 1,
464 : sizeof (struct iwi_tx_desc) * IWI_TX_RING_COUNT, 0, BUS_DMA_NOWAIT,
465 : &ring->map);
466 0 : if (error != 0) {
467 0 : printf("%s: could not create tx ring DMA map\n",
468 0 : sc->sc_dev.dv_xname);
469 0 : goto fail;
470 : }
471 :
472 0 : error = bus_dmamem_alloc(sc->sc_dmat,
473 : sizeof (struct iwi_tx_desc) * IWI_TX_RING_COUNT, PAGE_SIZE, 0,
474 : &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
475 0 : if (error != 0) {
476 0 : printf("%s: could not allocate tx ring DMA memory\n",
477 0 : sc->sc_dev.dv_xname);
478 0 : goto fail;
479 : }
480 :
481 0 : error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
482 : sizeof (struct iwi_tx_desc) * IWI_TX_RING_COUNT,
483 : (caddr_t *)&ring->desc, BUS_DMA_NOWAIT);
484 0 : if (error != 0) {
485 0 : printf("%s: can't map tx ring DMA memory\n",
486 0 : sc->sc_dev.dv_xname);
487 0 : goto fail;
488 : }
489 :
490 0 : error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
491 : sizeof (struct iwi_tx_desc) * IWI_TX_RING_COUNT, NULL,
492 : BUS_DMA_NOWAIT);
493 0 : if (error != 0) {
494 0 : printf("%s: could not load tx ring DMA map\n",
495 0 : sc->sc_dev.dv_xname);
496 0 : goto fail;
497 : }
498 :
499 0 : for (i = 0; i < IWI_TX_RING_COUNT; i++) {
500 0 : data = &ring->data[i];
501 :
502 0 : error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
503 : IWI_MAX_SCATTER, MCLBYTES, 0, BUS_DMA_NOWAIT, &data->map);
504 0 : if (error != 0) {
505 0 : printf("%s: could not create tx buf DMA map\n",
506 0 : sc->sc_dev.dv_xname);
507 0 : goto fail;
508 : }
509 : }
510 :
511 0 : return 0;
512 :
513 0 : fail: iwi_free_tx_ring(sc, ring);
514 0 : return error;
515 0 : }
516 :
517 : void
518 0 : iwi_reset_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring)
519 : {
520 : struct iwi_tx_data *data;
521 : int i;
522 :
523 0 : for (i = 0; i < IWI_TX_RING_COUNT; i++) {
524 0 : data = &ring->data[i];
525 :
526 0 : if (data->m != NULL) {
527 0 : bus_dmamap_unload(sc->sc_dmat, data->map);
528 0 : m_freem(data->m);
529 0 : data->m = NULL;
530 0 : }
531 : }
532 :
533 0 : ring->queued = 0;
534 0 : ring->cur = ring->next = 0;
535 0 : }
536 :
537 : void
538 0 : iwi_free_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring)
539 : {
540 : struct iwi_tx_data *data;
541 : int i;
542 :
543 0 : if (ring->map != NULL) {
544 0 : if (ring->desc != NULL) {
545 0 : bus_dmamap_unload(sc->sc_dmat, ring->map);
546 0 : bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
547 : sizeof (struct iwi_tx_desc) * IWI_TX_RING_COUNT);
548 0 : bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
549 0 : }
550 0 : bus_dmamap_destroy(sc->sc_dmat, ring->map);
551 0 : }
552 :
553 0 : for (i = 0; i < IWI_TX_RING_COUNT; i++) {
554 0 : data = &ring->data[i];
555 :
556 0 : if (data->m != NULL) {
557 0 : bus_dmamap_unload(sc->sc_dmat, data->map);
558 0 : m_freem(data->m);
559 0 : }
560 0 : bus_dmamap_destroy(sc->sc_dmat, data->map);
561 : }
562 0 : }
563 :
564 : int
565 0 : iwi_alloc_rx_ring(struct iwi_softc *sc, struct iwi_rx_ring *ring)
566 : {
567 : struct iwi_rx_data *data;
568 : int i, error;
569 :
570 0 : ring->cur = 0;
571 :
572 0 : for (i = 0; i < IWI_RX_RING_COUNT; i++) {
573 0 : data = &sc->rxq.data[i];
574 :
575 0 : error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
576 : 0, BUS_DMA_NOWAIT, &data->map);
577 0 : if (error != 0) {
578 0 : printf("%s: could not create rx buf DMA map\n",
579 0 : sc->sc_dev.dv_xname);
580 0 : goto fail;
581 : }
582 :
583 0 : MGETHDR(data->m, M_DONTWAIT, MT_DATA);
584 0 : if (data->m == NULL) {
585 0 : printf("%s: could not allocate rx mbuf\n",
586 0 : sc->sc_dev.dv_xname);
587 : error = ENOMEM;
588 0 : goto fail;
589 : }
590 0 : MCLGET(data->m, M_DONTWAIT);
591 0 : if (!(data->m->m_flags & M_EXT)) {
592 0 : m_freem(data->m);
593 0 : data->m = NULL;
594 0 : printf("%s: could not allocate rx mbuf cluster\n",
595 0 : sc->sc_dev.dv_xname);
596 : error = ENOMEM;
597 0 : goto fail;
598 : }
599 :
600 0 : error = bus_dmamap_load(sc->sc_dmat, data->map,
601 : mtod(data->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
602 0 : if (error != 0) {
603 0 : printf("%s: could not load rx buf DMA map\n",
604 0 : sc->sc_dev.dv_xname);
605 0 : goto fail;
606 : }
607 :
608 0 : data->reg = IWI_CSR_RX_BASE + i * 4;
609 : }
610 :
611 0 : return 0;
612 :
613 0 : fail: iwi_free_rx_ring(sc, ring);
614 0 : return error;
615 0 : }
616 :
617 : void
618 0 : iwi_reset_rx_ring(struct iwi_softc *sc, struct iwi_rx_ring *ring)
619 : {
620 0 : ring->cur = 0;
621 0 : }
622 :
623 : void
624 0 : iwi_free_rx_ring(struct iwi_softc *sc, struct iwi_rx_ring *ring)
625 : {
626 : struct iwi_rx_data *data;
627 : int i;
628 :
629 0 : for (i = 0; i < IWI_RX_RING_COUNT; i++) {
630 0 : data = &sc->rxq.data[i];
631 :
632 0 : if (data->m != NULL) {
633 0 : bus_dmamap_unload(sc->sc_dmat, data->map);
634 0 : m_freem(data->m);
635 0 : }
636 0 : bus_dmamap_destroy(sc->sc_dmat, data->map);
637 : }
638 0 : }
639 :
640 : int
641 0 : iwi_media_change(struct ifnet *ifp)
642 : {
643 : int error;
644 :
645 0 : error = ieee80211_media_change(ifp);
646 0 : if (error != ENETRESET)
647 0 : return error;
648 :
649 0 : if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
650 0 : iwi_init(ifp);
651 :
652 0 : return 0;
653 0 : }
654 :
655 : void
656 0 : iwi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
657 : {
658 0 : struct iwi_softc *sc = ifp->if_softc;
659 0 : struct ieee80211com *ic = &sc->sc_ic;
660 : uint32_t val;
661 : int rate;
662 :
663 0 : imr->ifm_status = IFM_AVALID;
664 0 : imr->ifm_active = IFM_IEEE80211;
665 0 : if (ic->ic_state == IEEE80211_S_RUN)
666 0 : imr->ifm_status |= IFM_ACTIVE;
667 :
668 : /* read current transmission rate from adapter */
669 0 : val = CSR_READ_4(sc, IWI_CSR_CURRENT_TX_RATE);
670 : /* convert PLCP signal to 802.11 rate */
671 0 : rate = iwi_rate(val);
672 :
673 0 : imr->ifm_active |= ieee80211_rate2media(ic, rate, ic->ic_curmode);
674 0 : switch (ic->ic_opmode) {
675 : case IEEE80211_M_STA:
676 : break;
677 : #ifndef IEEE80211_STA_ONLY
678 : case IEEE80211_M_IBSS:
679 0 : imr->ifm_active |= IFM_IEEE80211_ADHOC;
680 0 : break;
681 : #endif
682 : case IEEE80211_M_MONITOR:
683 0 : imr->ifm_active |= IFM_IEEE80211_MONITOR;
684 0 : break;
685 : default:
686 : /* should not get there */
687 : break;
688 : }
689 0 : }
690 :
691 : #ifndef IEEE80211_STA_ONLY
692 : /*
693 : * This is only used for IBSS mode where the firmware expect an index to an
694 : * internal node table instead of a destination address.
695 : */
696 : int
697 0 : iwi_find_txnode(struct iwi_softc *sc, const uint8_t *macaddr)
698 : {
699 0 : struct iwi_node node;
700 : int i;
701 :
702 0 : for (i = 0; i < sc->nsta; i++)
703 0 : if (IEEE80211_ADDR_EQ(sc->sta[i], macaddr))
704 0 : return i; /* already existing node */
705 :
706 0 : if (i == IWI_MAX_NODE)
707 0 : return -1; /* no place left in neighbor table */
708 :
709 : /* save this new node in our softc table */
710 0 : IEEE80211_ADDR_COPY(sc->sta[i], macaddr);
711 0 : sc->nsta = i;
712 :
713 : /* write node information into NIC memory */
714 0 : bzero(&node, sizeof node);
715 0 : IEEE80211_ADDR_COPY(node.bssid, macaddr);
716 :
717 0 : CSR_WRITE_REGION_1(sc, IWI_CSR_NODE_BASE + i * sizeof node,
718 : (uint8_t *)&node, sizeof node);
719 :
720 0 : return i;
721 0 : }
722 : #endif
723 :
724 : int
725 0 : iwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
726 : {
727 0 : struct iwi_softc *sc = ic->ic_softc;
728 : enum ieee80211_state ostate;
729 : uint32_t tmp;
730 :
731 0 : ostate = ic->ic_state;
732 :
733 0 : switch (nstate) {
734 : case IEEE80211_S_SCAN:
735 0 : iwi_scan(sc);
736 0 : break;
737 :
738 : case IEEE80211_S_AUTH:
739 0 : iwi_auth_and_assoc(sc);
740 0 : break;
741 :
742 : case IEEE80211_S_RUN:
743 : #ifndef IEEE80211_STA_ONLY
744 0 : if (ic->ic_opmode == IEEE80211_M_IBSS) {
745 0 : sc->nsta = 0; /* flush IBSS nodes */
746 0 : ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
747 0 : } else
748 : #endif
749 0 : if (ic->ic_opmode == IEEE80211_M_MONITOR)
750 0 : iwi_set_chan(sc, ic->ic_ibss_chan);
751 :
752 : /* assoc led on */
753 0 : tmp = MEM_READ_4(sc, IWI_MEM_EVENT_CTL) & IWI_LED_MASK;
754 0 : MEM_WRITE_4(sc, IWI_MEM_EVENT_CTL, tmp | IWI_LED_ASSOC);
755 0 : break;
756 :
757 : case IEEE80211_S_INIT:
758 0 : if (ostate != IEEE80211_S_RUN)
759 : break;
760 :
761 : /* assoc led off */
762 0 : tmp = MEM_READ_4(sc, IWI_MEM_EVENT_CTL) & IWI_LED_MASK;
763 0 : MEM_WRITE_4(sc, IWI_MEM_EVENT_CTL, tmp & ~IWI_LED_ASSOC);
764 0 : break;
765 :
766 : case IEEE80211_S_ASSOC:
767 : break;
768 : }
769 :
770 0 : ic->ic_state = nstate;
771 0 : return 0;
772 : }
773 :
774 : /*
775 : * Read 16 bits at address 'addr' from the serial EEPROM.
776 : * DON'T PLAY WITH THIS CODE UNLESS YOU KNOW *EXACTLY* WHAT YOU'RE DOING!
777 : */
778 : uint16_t
779 0 : iwi_read_prom_word(struct iwi_softc *sc, uint8_t addr)
780 : {
781 : uint32_t tmp;
782 : uint16_t val;
783 : int n;
784 :
785 : /* clock C once before the first command */
786 0 : IWI_EEPROM_CTL(sc, 0);
787 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
788 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_C);
789 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
790 :
791 : /* write start bit (1) */
792 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D);
793 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D | IWI_EEPROM_C);
794 :
795 : /* write READ opcode (10) */
796 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D);
797 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_D | IWI_EEPROM_C);
798 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
799 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_C);
800 :
801 : /* write address A7-A0 */
802 0 : for (n = 7; n >= 0; n--) {
803 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S |
804 : (((addr >> n) & 1) << IWI_EEPROM_SHIFT_D));
805 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S |
806 : (((addr >> n) & 1) << IWI_EEPROM_SHIFT_D) | IWI_EEPROM_C);
807 : }
808 :
809 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
810 :
811 : /* read data Q15-Q0 */
812 : val = 0;
813 0 : for (n = 15; n >= 0; n--) {
814 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S | IWI_EEPROM_C);
815 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
816 0 : tmp = MEM_READ_4(sc, IWI_MEM_EEPROM_CTL);
817 0 : val |= ((tmp & IWI_EEPROM_Q) >> IWI_EEPROM_SHIFT_Q) << n;
818 : }
819 :
820 0 : IWI_EEPROM_CTL(sc, 0);
821 :
822 : /* clear Chip Select and clock C */
823 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_S);
824 0 : IWI_EEPROM_CTL(sc, 0);
825 0 : IWI_EEPROM_CTL(sc, IWI_EEPROM_C);
826 :
827 0 : return val;
828 : }
829 :
830 : uint8_t
831 0 : iwi_rate(int plcp)
832 : {
833 0 : switch (plcp) {
834 : /* CCK rates (values are device-dependent) */
835 0 : case 10: return 2;
836 0 : case 20: return 4;
837 0 : case 55: return 11;
838 0 : case 110: return 22;
839 :
840 : /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
841 0 : case 0xd: return 12;
842 0 : case 0xf: return 18;
843 0 : case 0x5: return 24;
844 0 : case 0x7: return 36;
845 0 : case 0x9: return 48;
846 0 : case 0xb: return 72;
847 0 : case 0x1: return 96;
848 0 : case 0x3: return 108;
849 :
850 : /* unknown rate: should not happen */
851 0 : default: return 0;
852 : }
853 0 : }
854 :
855 : void
856 0 : iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data,
857 : struct iwi_frame *frame)
858 : {
859 0 : struct ieee80211com *ic = &sc->sc_ic;
860 0 : struct ifnet *ifp = &ic->ic_if;
861 : struct mbuf *mnew, *m;
862 : struct ieee80211_frame *wh;
863 0 : struct ieee80211_rxinfo rxi;
864 : struct ieee80211_node *ni;
865 : int error;
866 :
867 : DPRINTFN(5, ("received frame len=%u chan=%u rssi=%u\n",
868 : letoh16(frame->len), frame->chan, frame->rssi_dbm));
869 :
870 0 : if (letoh16(frame->len) < sizeof (struct ieee80211_frame_min) ||
871 0 : letoh16(frame->len) > MCLBYTES) {
872 : DPRINTF(("%s: bad frame length\n", sc->sc_dev.dv_xname));
873 0 : ifp->if_ierrors++;
874 0 : return;
875 : }
876 :
877 : /*
878 : * Try to allocate a new mbuf for this ring element and load it before
879 : * processing the current mbuf. If the ring element cannot be loaded,
880 : * drop the received packet and reuse the old mbuf. In the unlikely
881 : * case that the old mbuf can't be reloaded either, explicitly panic.
882 : */
883 0 : MGETHDR(mnew, M_DONTWAIT, MT_DATA);
884 0 : if (mnew == NULL) {
885 0 : ifp->if_ierrors++;
886 0 : return;
887 : }
888 0 : MCLGET(mnew, M_DONTWAIT);
889 0 : if (!(mnew->m_flags & M_EXT)) {
890 0 : m_freem(mnew);
891 0 : ifp->if_ierrors++;
892 0 : return;
893 : }
894 :
895 0 : bus_dmamap_unload(sc->sc_dmat, data->map);
896 :
897 0 : error = bus_dmamap_load(sc->sc_dmat, data->map, mtod(mnew, void *),
898 : MCLBYTES, NULL, BUS_DMA_NOWAIT);
899 0 : if (error != 0) {
900 0 : m_freem(mnew);
901 :
902 : /* try to reload the old mbuf */
903 0 : error = bus_dmamap_load(sc->sc_dmat, data->map,
904 : mtod(data->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
905 0 : if (error != 0) {
906 : /* very unlikely that it will fail... */
907 0 : panic("%s: could not load old rx mbuf",
908 0 : sc->sc_dev.dv_xname);
909 : }
910 0 : CSR_WRITE_4(sc, data->reg, data->map->dm_segs[0].ds_addr);
911 0 : ifp->if_ierrors++;
912 0 : return;
913 : }
914 :
915 0 : m = data->m;
916 0 : data->m = mnew;
917 0 : CSR_WRITE_4(sc, data->reg, data->map->dm_segs[0].ds_addr);
918 :
919 : /* finalize mbuf */
920 0 : m->m_pkthdr.len = m->m_len = sizeof (struct iwi_hdr) +
921 0 : sizeof (struct iwi_frame) + letoh16(frame->len);
922 0 : m_adj(m, sizeof (struct iwi_hdr) + sizeof (struct iwi_frame));
923 :
924 : #if NBPFILTER > 0
925 0 : if (sc->sc_drvbpf != NULL) {
926 0 : struct mbuf mb;
927 0 : struct iwi_rx_radiotap_header *tap = &sc->sc_rxtap;
928 :
929 0 : tap->wr_flags = 0;
930 0 : tap->wr_rate = iwi_rate(frame->rate);
931 0 : tap->wr_chan_freq =
932 0 : htole16(ic->ic_channels[frame->chan].ic_freq);
933 0 : tap->wr_chan_flags =
934 0 : htole16(ic->ic_channels[frame->chan].ic_flags);
935 0 : tap->wr_antsignal = frame->signal;
936 0 : tap->wr_antenna = frame->antenna & 0x3;
937 0 : if (frame->antenna & 0x40)
938 0 : tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
939 :
940 0 : mb.m_data = (caddr_t)tap;
941 0 : mb.m_len = sc->sc_rxtap_len;
942 0 : mb.m_next = m;
943 0 : mb.m_nextpkt = NULL;
944 0 : mb.m_type = 0;
945 0 : mb.m_flags = 0;
946 0 : bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
947 0 : }
948 : #endif
949 :
950 0 : wh = mtod(m, struct ieee80211_frame *);
951 0 : ni = ieee80211_find_rxnode(ic, wh);
952 :
953 : /* send the frame to the upper layer */
954 0 : rxi.rxi_flags = 0;
955 0 : rxi.rxi_rssi = frame->rssi_dbm;
956 0 : rxi.rxi_tstamp = 0; /* unused */
957 0 : ieee80211_input(ifp, m, ni, &rxi);
958 :
959 : /* node is no longer needed */
960 0 : ieee80211_release_node(ic, ni);
961 0 : }
962 :
963 : void
964 0 : iwi_notification_intr(struct iwi_softc *sc, struct iwi_rx_data *data,
965 : struct iwi_notif *notif)
966 : {
967 0 : struct ieee80211com *ic = &sc->sc_ic;
968 0 : struct ieee80211_node *ni = ic->ic_bss;
969 0 : struct ifnet *ifp = &ic->ic_if;
970 :
971 0 : switch (notif->type) {
972 : case IWI_NOTIF_TYPE_SCAN_CHANNEL:
973 : {
974 : #ifdef IWI_DEBUG
975 : struct iwi_notif_scan_channel *chan =
976 : (struct iwi_notif_scan_channel *)(notif + 1);
977 : #endif
978 : DPRINTFN(2, ("Scanning channel (%u)\n", chan->nchan));
979 : break;
980 : }
981 : case IWI_NOTIF_TYPE_SCAN_COMPLETE:
982 : {
983 : #ifdef IWI_DEBUG
984 : struct iwi_notif_scan_complete *scan =
985 : (struct iwi_notif_scan_complete *)(notif + 1);
986 : #endif
987 : DPRINTFN(2, ("Scan completed (%u, %u)\n", scan->nchan,
988 : scan->status));
989 :
990 : /* monitor mode uses scan to set the channel ... */
991 0 : if (ic->ic_opmode != IEEE80211_M_MONITOR)
992 0 : ieee80211_end_scan(ifp);
993 : else
994 0 : iwi_set_chan(sc, ic->ic_ibss_chan);
995 : break;
996 : }
997 : case IWI_NOTIF_TYPE_AUTHENTICATION:
998 : {
999 : struct iwi_notif_authentication *auth =
1000 0 : (struct iwi_notif_authentication *)(notif + 1);
1001 :
1002 : DPRINTFN(2, ("Authentication (%u)\n", auth->state));
1003 :
1004 0 : switch (auth->state) {
1005 : case IWI_AUTHENTICATED:
1006 0 : ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
1007 0 : break;
1008 :
1009 : case IWI_DEAUTHENTICATED:
1010 : break;
1011 :
1012 : default:
1013 0 : printf("%s: unknown authentication state %u\n",
1014 0 : sc->sc_dev.dv_xname, auth->state);
1015 0 : }
1016 : break;
1017 : }
1018 : case IWI_NOTIF_TYPE_ASSOCIATION:
1019 : {
1020 : struct iwi_notif_association *assoc =
1021 0 : (struct iwi_notif_association *)(notif + 1);
1022 :
1023 : DPRINTFN(2, ("Association (%u, %u)\n", assoc->state,
1024 : assoc->status));
1025 :
1026 0 : switch (assoc->state) {
1027 : case IWI_AUTHENTICATED:
1028 : /* re-association, do nothing */
1029 : break;
1030 :
1031 : case IWI_ASSOCIATED:
1032 0 : if (ic->ic_flags & IEEE80211_F_RSNON)
1033 0 : ni->ni_rsn_supp_state = RSNA_SUPP_PTKSTART;
1034 0 : ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
1035 0 : break;
1036 :
1037 : case IWI_DEASSOCIATED:
1038 0 : ieee80211_begin_scan(ifp);
1039 0 : break;
1040 :
1041 : default:
1042 0 : printf("%s: unknown association state %u\n",
1043 0 : sc->sc_dev.dv_xname, assoc->state);
1044 0 : }
1045 : break;
1046 : }
1047 : case IWI_NOTIF_TYPE_BEACON:
1048 : {
1049 : struct iwi_notif_beacon *beacon =
1050 0 : (struct iwi_notif_beacon *)(notif + 1);
1051 :
1052 0 : if (letoh32(beacon->status) == IWI_BEACON_MISSED) {
1053 : /* XXX should roam when too many beacons missed */
1054 : DPRINTFN(2, ("%s: %u beacon(s) missed\n",
1055 : sc->sc_dev.dv_xname, letoh32(beacon->count)));
1056 : }
1057 : break;
1058 : }
1059 : case IWI_NOTIF_TYPE_BAD_LINK:
1060 : DPRINTFN(2, ("link deterioration detected\n"));
1061 : break;
1062 :
1063 : case IWI_NOTIF_TYPE_NOISE:
1064 : DPRINTFN(5, ("Measured noise %u\n",
1065 : letoh32(*(uint32_t *)(notif + 1)) & 0xff));
1066 : break;
1067 :
1068 : default:
1069 : DPRINTFN(5, ("Notification (%u)\n", notif->type));
1070 : }
1071 0 : }
1072 :
1073 : void
1074 0 : iwi_rx_intr(struct iwi_softc *sc)
1075 : {
1076 : struct iwi_rx_data *data;
1077 : struct iwi_hdr *hdr;
1078 : uint32_t hw;
1079 :
1080 0 : hw = CSR_READ_4(sc, IWI_CSR_RX_RIDX);
1081 :
1082 0 : for (; sc->rxq.cur != hw;) {
1083 0 : data = &sc->rxq.data[sc->rxq.cur];
1084 :
1085 0 : bus_dmamap_sync(sc->sc_dmat, data->map, 0, MCLBYTES,
1086 : BUS_DMASYNC_POSTREAD);
1087 :
1088 0 : hdr = mtod(data->m, struct iwi_hdr *);
1089 :
1090 0 : switch (hdr->type) {
1091 : case IWI_HDR_TYPE_FRAME:
1092 0 : iwi_frame_intr(sc, data,
1093 0 : (struct iwi_frame *)(hdr + 1));
1094 0 : break;
1095 :
1096 : case IWI_HDR_TYPE_NOTIF:
1097 0 : iwi_notification_intr(sc, data,
1098 0 : (struct iwi_notif *)(hdr + 1));
1099 0 : break;
1100 :
1101 : default:
1102 0 : printf("%s: unknown hdr type %u\n",
1103 0 : sc->sc_dev.dv_xname, hdr->type);
1104 0 : }
1105 :
1106 0 : sc->rxq.cur = (sc->rxq.cur + 1) % IWI_RX_RING_COUNT;
1107 : }
1108 :
1109 : /* tell the firmware what we have processed */
1110 0 : hw = (hw == 0) ? IWI_RX_RING_COUNT - 1 : hw - 1;
1111 0 : CSR_WRITE_4(sc, IWI_CSR_RX_WIDX, hw);
1112 0 : }
1113 :
1114 : void
1115 0 : iwi_tx_intr(struct iwi_softc *sc, struct iwi_tx_ring *txq)
1116 : {
1117 0 : struct ieee80211com *ic = &sc->sc_ic;
1118 0 : struct ifnet *ifp = &ic->ic_if;
1119 : struct iwi_tx_data *data;
1120 : uint32_t hw;
1121 :
1122 0 : hw = CSR_READ_4(sc, txq->csr_ridx);
1123 :
1124 0 : for (; txq->next != hw;) {
1125 0 : data = &txq->data[txq->next];
1126 :
1127 0 : bus_dmamap_unload(sc->sc_dmat, data->map);
1128 0 : m_freem(data->m);
1129 0 : data->m = NULL;
1130 0 : ieee80211_release_node(ic, data->ni);
1131 0 : data->ni = NULL;
1132 :
1133 0 : txq->queued--;
1134 0 : txq->next = (txq->next + 1) % IWI_TX_RING_COUNT;
1135 : }
1136 :
1137 0 : sc->sc_tx_timer = 0;
1138 0 : ifq_clr_oactive(&ifp->if_snd);
1139 0 : (*ifp->if_start)(ifp);
1140 0 : }
1141 :
1142 : int
1143 0 : iwi_intr(void *arg)
1144 : {
1145 0 : struct iwi_softc *sc = arg;
1146 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
1147 : uint32_t r;
1148 :
1149 0 : if ((r = CSR_READ_4(sc, IWI_CSR_INTR)) == 0 || r == 0xffffffff)
1150 0 : return 0;
1151 :
1152 : /* disable interrupts */
1153 0 : CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0);
1154 :
1155 : /* acknowledge interrupts */
1156 0 : CSR_WRITE_4(sc, IWI_CSR_INTR, r);
1157 :
1158 0 : if (r & IWI_INTR_FATAL_ERROR) {
1159 0 : printf("%s: fatal firmware error\n", sc->sc_dev.dv_xname);
1160 0 : iwi_stop(ifp, 1);
1161 0 : task_add(systq, &sc->init_task);
1162 0 : return 1;
1163 : }
1164 :
1165 0 : if (r & IWI_INTR_FW_INITED)
1166 0 : wakeup(sc);
1167 :
1168 0 : if (r & IWI_INTR_RADIO_OFF) {
1169 : DPRINTF(("radio transmitter off\n"));
1170 0 : iwi_stop(ifp, 1);
1171 0 : return 1;
1172 : }
1173 :
1174 0 : if (r & IWI_INTR_CMD_DONE) {
1175 : /* kick next pending command if any */
1176 0 : sc->cmdq.next = (sc->cmdq.next + 1) % IWI_CMD_RING_COUNT;
1177 0 : if (--sc->cmdq.queued > 0)
1178 0 : CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.next);
1179 :
1180 0 : wakeup(sc);
1181 0 : }
1182 :
1183 0 : if (r & IWI_INTR_TX1_DONE)
1184 0 : iwi_tx_intr(sc, &sc->txq[0]);
1185 :
1186 0 : if (r & IWI_INTR_TX2_DONE)
1187 0 : iwi_tx_intr(sc, &sc->txq[1]);
1188 :
1189 0 : if (r & IWI_INTR_TX3_DONE)
1190 0 : iwi_tx_intr(sc, &sc->txq[2]);
1191 :
1192 0 : if (r & IWI_INTR_TX4_DONE)
1193 0 : iwi_tx_intr(sc, &sc->txq[3]);
1194 :
1195 0 : if (r & IWI_INTR_RX_DONE)
1196 0 : iwi_rx_intr(sc);
1197 :
1198 : /* re-enable interrupts */
1199 0 : CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, IWI_INTR_MASK);
1200 :
1201 0 : return 1;
1202 0 : }
1203 :
1204 : int
1205 0 : iwi_cmd(struct iwi_softc *sc, uint8_t type, void *data, uint8_t len, int async)
1206 : {
1207 : struct iwi_cmd_desc *desc;
1208 :
1209 0 : desc = &sc->cmdq.desc[sc->cmdq.cur];
1210 0 : desc->hdr.type = IWI_HDR_TYPE_COMMAND;
1211 0 : desc->hdr.flags = IWI_HDR_FLAG_IRQ;
1212 0 : desc->type = type;
1213 0 : desc->len = len;
1214 0 : bcopy(data, desc->data, len);
1215 :
1216 0 : bus_dmamap_sync(sc->sc_dmat, sc->cmdq.map,
1217 : sc->cmdq.cur * sizeof (struct iwi_cmd_desc),
1218 : sizeof (struct iwi_cmd_desc), BUS_DMASYNC_PREWRITE);
1219 :
1220 : DPRINTFN(2, ("sending command idx=%u type=%u len=%u\n", sc->cmdq.cur,
1221 : type, len));
1222 :
1223 0 : sc->cmdq.cur = (sc->cmdq.cur + 1) % IWI_CMD_RING_COUNT;
1224 :
1225 : /* don't kick cmd immediately if another async command is pending */
1226 0 : if (++sc->cmdq.queued == 1) {
1227 0 : sc->cmdq.next = sc->cmdq.cur;
1228 0 : CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.next);
1229 0 : }
1230 :
1231 0 : return async ? 0 : tsleep(sc, PCATCH, "iwicmd", hz);
1232 : }
1233 :
1234 : /* ARGSUSED */
1235 : int
1236 0 : iwi_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni, int type,
1237 : int arg1, int arg2)
1238 : {
1239 0 : return EOPNOTSUPP;
1240 : }
1241 :
1242 : int
1243 0 : iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni)
1244 : {
1245 0 : struct iwi_softc *sc = ifp->if_softc;
1246 0 : struct ieee80211com *ic = &sc->sc_ic;
1247 : struct ieee80211_frame *wh;
1248 : struct ieee80211_key *k;
1249 : struct iwi_tx_data *data;
1250 : struct iwi_tx_desc *desc;
1251 0 : struct iwi_tx_ring *txq = &sc->txq[0];
1252 : int hdrlen, error, i, station = 0;
1253 :
1254 0 : wh = mtod(m0, struct ieee80211_frame *);
1255 :
1256 0 : if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1257 0 : k = ieee80211_get_txkey(ic, wh, ni);
1258 :
1259 0 : if ((m0 = ieee80211_encrypt(ic, m0, k)) == NULL)
1260 0 : return ENOBUFS;
1261 :
1262 : /* packet header may have moved, reset our local pointer */
1263 0 : wh = mtod(m0, struct ieee80211_frame *);
1264 0 : }
1265 :
1266 : #if NBPFILTER > 0
1267 0 : if (sc->sc_drvbpf != NULL) {
1268 0 : struct mbuf mb;
1269 0 : struct iwi_tx_radiotap_header *tap = &sc->sc_txtap;
1270 :
1271 0 : tap->wt_flags = 0;
1272 0 : tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
1273 0 : tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
1274 :
1275 0 : mb.m_data = (caddr_t)tap;
1276 0 : mb.m_len = sc->sc_txtap_len;
1277 0 : mb.m_next = m0;
1278 0 : mb.m_nextpkt = NULL;
1279 0 : mb.m_type = 0;
1280 0 : mb.m_flags = 0;
1281 0 : bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
1282 0 : }
1283 : #endif
1284 :
1285 0 : data = &txq->data[txq->cur];
1286 0 : desc = &txq->desc[txq->cur];
1287 :
1288 : /* copy and trim IEEE802.11 header */
1289 0 : hdrlen = ieee80211_get_hdrlen(wh);
1290 0 : bcopy(wh, &desc->wh, hdrlen);
1291 0 : m_adj(m0, hdrlen);
1292 :
1293 : #ifndef IEEE80211_STA_ONLY
1294 0 : if (ic->ic_opmode == IEEE80211_M_IBSS) {
1295 0 : station = iwi_find_txnode(sc, desc->wh.i_addr1);
1296 0 : if (station == -1) {
1297 0 : m_freem(m0);
1298 0 : ieee80211_release_node(ic, ni);
1299 0 : ifp->if_oerrors++;
1300 0 : return 0;
1301 : }
1302 : }
1303 : #endif
1304 :
1305 0 : error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
1306 : BUS_DMA_NOWAIT);
1307 0 : if (error != 0 && error != EFBIG) {
1308 0 : printf("%s: can't map mbuf (error %d)\n",
1309 0 : sc->sc_dev.dv_xname, error);
1310 0 : m_freem(m0);
1311 0 : return error;
1312 : }
1313 0 : if (error != 0) {
1314 : /* too many fragments, linearize */
1315 0 : if (m_defrag(m0, M_DONTWAIT)) {
1316 0 : m_freem(m0);
1317 0 : return ENOBUFS;
1318 : }
1319 0 : error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
1320 : BUS_DMA_NOWAIT);
1321 0 : if (error != 0) {
1322 0 : printf("%s: can't map mbuf (error %d)\n",
1323 0 : sc->sc_dev.dv_xname, error);
1324 0 : m_freem(m0);
1325 0 : return error;
1326 : }
1327 : }
1328 :
1329 0 : data->m = m0;
1330 0 : data->ni = ni;
1331 :
1332 0 : desc->hdr.type = IWI_HDR_TYPE_DATA;
1333 0 : desc->hdr.flags = IWI_HDR_FLAG_IRQ;
1334 0 : desc->cmd = IWI_DATA_CMD_TX;
1335 0 : desc->len = htole16(m0->m_pkthdr.len);
1336 0 : desc->station = station;
1337 0 : desc->flags = IWI_DATA_FLAG_NO_WEP;
1338 0 : desc->xflags = 0;
1339 :
1340 0 : if (!IEEE80211_IS_MULTICAST(desc->wh.i_addr1))
1341 0 : desc->flags |= IWI_DATA_FLAG_NEED_ACK;
1342 :
1343 0 : if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
1344 0 : desc->flags |= IWI_DATA_FLAG_SHPREAMBLE;
1345 :
1346 0 : if ((desc->wh.i_fc[0] &
1347 0 : (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) ==
1348 : (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
1349 0 : desc->xflags |= IWI_DATA_XFLAG_QOS;
1350 :
1351 0 : if (ic->ic_curmode == IEEE80211_MODE_11B)
1352 0 : desc->xflags |= IWI_DATA_XFLAG_CCK;
1353 :
1354 0 : desc->nseg = htole32(data->map->dm_nsegs);
1355 0 : for (i = 0; i < data->map->dm_nsegs; i++) {
1356 0 : desc->seg_addr[i] = htole32(data->map->dm_segs[i].ds_addr);
1357 0 : desc->seg_len[i] = htole16(data->map->dm_segs[i].ds_len);
1358 : }
1359 :
1360 0 : bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
1361 : BUS_DMASYNC_PREWRITE);
1362 0 : bus_dmamap_sync(sc->sc_dmat, txq->map,
1363 : txq->cur * sizeof (struct iwi_tx_desc),
1364 : sizeof (struct iwi_tx_desc), BUS_DMASYNC_PREWRITE);
1365 :
1366 : DPRINTFN(5, ("sending data frame idx=%u len=%u nseg=%u\n", txq->cur,
1367 : letoh16(desc->len), data->map->dm_nsegs));
1368 :
1369 0 : txq->queued++;
1370 0 : txq->cur = (txq->cur + 1) % IWI_TX_RING_COUNT;
1371 0 : CSR_WRITE_4(sc, txq->csr_widx, txq->cur);
1372 :
1373 0 : return 0;
1374 0 : }
1375 :
1376 : void
1377 0 : iwi_start(struct ifnet *ifp)
1378 : {
1379 0 : struct iwi_softc *sc = ifp->if_softc;
1380 0 : struct ieee80211com *ic = &sc->sc_ic;
1381 : struct mbuf *m0;
1382 0 : struct ieee80211_node *ni;
1383 :
1384 0 : if (ic->ic_state != IEEE80211_S_RUN)
1385 0 : return;
1386 :
1387 0 : for (;;) {
1388 0 : if (sc->txq[0].queued + IWI_MAX_NSEG + 2 >= IWI_TX_RING_COUNT) {
1389 0 : ifq_set_oactive(&ifp->if_snd);
1390 0 : break;
1391 : }
1392 :
1393 0 : IFQ_DEQUEUE(&ifp->if_snd, m0);
1394 0 : if (m0 == NULL)
1395 : break;
1396 :
1397 : #if NBPFILTER > 0
1398 0 : if (ifp->if_bpf != NULL)
1399 0 : bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
1400 : #endif
1401 :
1402 0 : m0 = ieee80211_encap(ifp, m0, &ni);
1403 0 : if (m0 == NULL)
1404 0 : continue;
1405 :
1406 : #if NBPFILTER > 0
1407 0 : if (ic->ic_rawbpf != NULL)
1408 0 : bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
1409 : #endif
1410 :
1411 0 : if (iwi_tx_start(ifp, m0, ni) != 0) {
1412 0 : if (ni != NULL)
1413 0 : ieee80211_release_node(ic, ni);
1414 0 : ifp->if_oerrors++;
1415 0 : break;
1416 : }
1417 :
1418 : /* start watchdog timer */
1419 0 : sc->sc_tx_timer = 5;
1420 0 : ifp->if_timer = 1;
1421 : }
1422 0 : }
1423 :
1424 : void
1425 0 : iwi_watchdog(struct ifnet *ifp)
1426 : {
1427 0 : struct iwi_softc *sc = ifp->if_softc;
1428 :
1429 0 : ifp->if_timer = 0;
1430 :
1431 0 : if (sc->sc_tx_timer > 0) {
1432 0 : if (--sc->sc_tx_timer == 0) {
1433 0 : printf("%s: device timeout\n", sc->sc_dev.dv_xname);
1434 0 : iwi_stop(ifp, 1);
1435 0 : ifp->if_oerrors++;
1436 0 : return;
1437 : }
1438 0 : ifp->if_timer = 1;
1439 0 : }
1440 :
1441 0 : ieee80211_watchdog(ifp);
1442 0 : }
1443 :
1444 : int
1445 0 : iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1446 : {
1447 0 : struct iwi_softc *sc = ifp->if_softc;
1448 : int s, error = 0;
1449 :
1450 0 : error = rw_enter(&sc->sc_rwlock, RW_WRITE | RW_INTR);
1451 0 : if (error)
1452 0 : return error;
1453 0 : s = splnet();
1454 :
1455 0 : switch (cmd) {
1456 : case SIOCSIFADDR:
1457 0 : ifp->if_flags |= IFF_UP;
1458 : /* FALLTHROUGH */
1459 : case SIOCSIFFLAGS:
1460 0 : if (ifp->if_flags & IFF_UP) {
1461 0 : if (!(ifp->if_flags & IFF_RUNNING))
1462 0 : iwi_init(ifp);
1463 : } else {
1464 0 : if (ifp->if_flags & IFF_RUNNING)
1465 0 : iwi_stop(ifp, 1);
1466 : }
1467 : break;
1468 :
1469 : case SIOCG80211TXPOWER:
1470 : /*
1471 : * If the hardware radio transmitter switch is off, report a
1472 : * tx power of IEEE80211_TXPOWER_MIN to indicate that radio
1473 : * transmitter is killed.
1474 : */
1475 0 : ((struct ieee80211_txpower *)data)->i_val =
1476 0 : (CSR_READ_4(sc, IWI_CSR_IO) & IWI_IO_RADIO_ENABLED) ?
1477 0 : sc->sc_ic.ic_txpower : IEEE80211_TXPOWER_MIN;
1478 0 : break;
1479 :
1480 : default:
1481 0 : error = ieee80211_ioctl(ifp, cmd, data);
1482 0 : }
1483 :
1484 0 : if (error == ENETRESET) {
1485 0 : if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
1486 : (IFF_UP | IFF_RUNNING))
1487 0 : iwi_init(ifp);
1488 : error = 0;
1489 0 : }
1490 :
1491 0 : splx(s);
1492 0 : rw_exit_write(&sc->sc_rwlock);
1493 0 : return error;
1494 0 : }
1495 :
1496 : void
1497 0 : iwi_stop_master(struct iwi_softc *sc)
1498 : {
1499 : uint32_t tmp;
1500 : int ntries;
1501 :
1502 : /* disable interrupts */
1503 0 : CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0);
1504 :
1505 0 : CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_STOP_MASTER);
1506 0 : for (ntries = 0; ntries < 5; ntries++) {
1507 0 : if (CSR_READ_4(sc, IWI_CSR_RST) & IWI_RST_MASTER_DISABLED)
1508 : break;
1509 0 : DELAY(10);
1510 : }
1511 0 : if (ntries == 5) {
1512 0 : printf("%s: timeout waiting for master\n",
1513 0 : sc->sc_dev.dv_xname);
1514 0 : }
1515 :
1516 0 : tmp = CSR_READ_4(sc, IWI_CSR_RST);
1517 0 : CSR_WRITE_4(sc, IWI_CSR_RST, tmp | IWI_RST_PRINCETON_RESET);
1518 0 : }
1519 :
1520 : int
1521 0 : iwi_reset(struct iwi_softc *sc)
1522 : {
1523 : uint32_t tmp;
1524 : int i, ntries;
1525 :
1526 0 : iwi_stop_master(sc);
1527 :
1528 : /* move adapter to D0 state */
1529 0 : tmp = CSR_READ_4(sc, IWI_CSR_CTL);
1530 0 : CSR_WRITE_4(sc, IWI_CSR_CTL, tmp | IWI_CTL_INIT);
1531 :
1532 0 : CSR_WRITE_4(sc, IWI_CSR_READ_INT, IWI_READ_INT_INIT_HOST);
1533 :
1534 : /* wait for clock stabilization */
1535 0 : for (ntries = 0; ntries < 1000; ntries++) {
1536 0 : if (CSR_READ_4(sc, IWI_CSR_CTL) & IWI_CTL_CLOCK_READY)
1537 : break;
1538 0 : DELAY(200);
1539 : }
1540 0 : if (ntries == 1000) {
1541 0 : printf("%s: timeout waiting for clock stabilization\n",
1542 0 : sc->sc_dev.dv_xname);
1543 0 : return ETIMEDOUT;
1544 : }
1545 :
1546 0 : tmp = CSR_READ_4(sc, IWI_CSR_RST);
1547 0 : CSR_WRITE_4(sc, IWI_CSR_RST, tmp | IWI_RST_SW_RESET);
1548 :
1549 0 : DELAY(10);
1550 :
1551 0 : tmp = CSR_READ_4(sc, IWI_CSR_CTL);
1552 0 : CSR_WRITE_4(sc, IWI_CSR_CTL, tmp | IWI_CTL_INIT);
1553 :
1554 : /* clear NIC memory */
1555 0 : CSR_WRITE_4(sc, IWI_CSR_AUTOINC_ADDR, 0);
1556 0 : for (i = 0; i < 0xc000; i++)
1557 0 : CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, 0);
1558 :
1559 0 : return 0;
1560 0 : }
1561 :
1562 : int
1563 0 : iwi_load_ucode(struct iwi_softc *sc, const char *data, int size)
1564 : {
1565 : const uint16_t *w;
1566 : uint32_t tmp;
1567 : int ntries, i;
1568 :
1569 0 : tmp = CSR_READ_4(sc, IWI_CSR_RST);
1570 0 : CSR_WRITE_4(sc, IWI_CSR_RST, tmp | IWI_RST_STOP_MASTER);
1571 0 : for (ntries = 0; ntries < 5; ntries++) {
1572 0 : if (CSR_READ_4(sc, IWI_CSR_RST) & IWI_RST_MASTER_DISABLED)
1573 : break;
1574 0 : DELAY(10);
1575 : }
1576 0 : if (ntries == 5) {
1577 0 : printf("%s: timeout waiting for master\n",
1578 0 : sc->sc_dev.dv_xname);
1579 0 : return ETIMEDOUT;
1580 : }
1581 :
1582 0 : MEM_WRITE_4(sc, 0x3000e0, 0x80000000);
1583 0 : DELAY(5000);
1584 :
1585 0 : tmp = CSR_READ_4(sc, IWI_CSR_RST);
1586 0 : CSR_WRITE_4(sc, IWI_CSR_RST, tmp & ~IWI_RST_PRINCETON_RESET);
1587 :
1588 0 : DELAY(5000);
1589 0 : MEM_WRITE_4(sc, 0x3000e0, 0);
1590 0 : DELAY(1000);
1591 0 : MEM_WRITE_4(sc, IWI_MEM_EVENT_CTL, 1);
1592 0 : DELAY(1000);
1593 0 : MEM_WRITE_4(sc, IWI_MEM_EVENT_CTL, 0);
1594 0 : DELAY(1000);
1595 0 : MEM_WRITE_1(sc, 0x200000, 0x00);
1596 0 : MEM_WRITE_1(sc, 0x200000, 0x40);
1597 0 : DELAY(1000);
1598 :
1599 : /* adapter is buggy, we must set the address for each word */
1600 0 : for (w = (const uint16_t *)data; size > 0; w++, size -= 2)
1601 0 : MEM_WRITE_2(sc, 0x200010, htole16(*w));
1602 :
1603 0 : MEM_WRITE_1(sc, 0x200000, 0x00);
1604 0 : MEM_WRITE_1(sc, 0x200000, 0x80);
1605 :
1606 : /* wait until we get an answer */
1607 0 : for (ntries = 0; ntries < 100; ntries++) {
1608 0 : if (MEM_READ_1(sc, 0x200000) & 1)
1609 : break;
1610 0 : DELAY(100);
1611 : }
1612 0 : if (ntries == 100) {
1613 0 : printf("%s: timeout waiting for ucode to initialize\n",
1614 0 : sc->sc_dev.dv_xname);
1615 0 : return ETIMEDOUT;
1616 : }
1617 :
1618 : /* read the answer or the firmware will not initialize properly */
1619 0 : for (i = 0; i < 7; i++)
1620 0 : MEM_READ_4(sc, 0x200004);
1621 :
1622 0 : MEM_WRITE_1(sc, 0x200000, 0x00);
1623 :
1624 0 : return 0;
1625 0 : }
1626 :
1627 : /* macro to handle unaligned little endian data in firmware image */
1628 : #define GETLE32(p) ((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3] << 24)
1629 :
1630 : int
1631 0 : iwi_load_firmware(struct iwi_softc *sc, const char *data, int size)
1632 : {
1633 0 : bus_dmamap_t map;
1634 0 : bus_dma_segment_t seg;
1635 0 : caddr_t virtaddr;
1636 : u_char *p, *end;
1637 : uint32_t sentinel, tmp, ctl, src, dst, sum, len, mlen;
1638 0 : int ntries, nsegs, error;
1639 :
1640 : /* allocate DMA memory to store firmware image */
1641 0 : error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
1642 : BUS_DMA_NOWAIT, &map);
1643 0 : if (error != 0) {
1644 0 : printf("%s: could not create firmware DMA map\n",
1645 0 : sc->sc_dev.dv_xname);
1646 0 : goto fail1;
1647 : }
1648 :
1649 0 : error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &seg, 1,
1650 : &nsegs, BUS_DMA_NOWAIT);
1651 0 : if (error != 0) {
1652 0 : printf("%s: could not allocate firmware DMA memory\n",
1653 0 : sc->sc_dev.dv_xname);
1654 0 : goto fail2;
1655 : }
1656 :
1657 0 : error = bus_dmamem_map(sc->sc_dmat, &seg, nsegs, size, &virtaddr,
1658 : BUS_DMA_NOWAIT);
1659 0 : if (error != 0) {
1660 0 : printf("%s: can't map firmware DMA memory\n",
1661 0 : sc->sc_dev.dv_xname);
1662 0 : goto fail3;
1663 : }
1664 :
1665 0 : error = bus_dmamap_load(sc->sc_dmat, map, virtaddr, size, NULL,
1666 : BUS_DMA_NOWAIT);
1667 0 : if (error != 0) {
1668 0 : printf("%s: could not load firmware DMA map\n",
1669 0 : sc->sc_dev.dv_xname);
1670 0 : goto fail4;
1671 : }
1672 :
1673 : /* copy firmware image to DMA memory */
1674 0 : bcopy(data, virtaddr, size);
1675 :
1676 : /* make sure the adapter will get up-to-date values */
1677 0 : bus_dmamap_sync(sc->sc_dmat, map, 0, size, BUS_DMASYNC_PREWRITE);
1678 :
1679 : /* tell the adapter where the command blocks are stored */
1680 0 : MEM_WRITE_4(sc, 0x3000a0, 0x27000);
1681 :
1682 : /*
1683 : * Store command blocks into adapter's internal memory using register
1684 : * indirections. The adapter will read the firmware image through DMA
1685 : * using information stored in command blocks.
1686 : */
1687 0 : src = map->dm_segs[0].ds_addr;
1688 0 : p = virtaddr;
1689 0 : end = p + size;
1690 0 : CSR_WRITE_4(sc, IWI_CSR_AUTOINC_ADDR, 0x27000);
1691 :
1692 0 : while (p < end) {
1693 0 : dst = GETLE32(p); p += 4; src += 4;
1694 0 : len = GETLE32(p); p += 4; src += 4;
1695 0 : p += len;
1696 :
1697 0 : while (len > 0) {
1698 0 : mlen = min(len, IWI_CB_MAXDATALEN);
1699 :
1700 0 : ctl = IWI_CB_DEFAULT_CTL | mlen;
1701 0 : sum = ctl ^ src ^ dst;
1702 :
1703 : /* write a command block */
1704 0 : CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, ctl);
1705 0 : CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, src);
1706 0 : CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, dst);
1707 0 : CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, sum);
1708 :
1709 0 : src += mlen;
1710 0 : dst += mlen;
1711 0 : len -= mlen;
1712 : }
1713 : }
1714 :
1715 : /* write a fictive final command block (sentinel) */
1716 0 : sentinel = CSR_READ_4(sc, IWI_CSR_AUTOINC_ADDR);
1717 0 : CSR_WRITE_4(sc, IWI_CSR_AUTOINC_DATA, 0);
1718 :
1719 0 : tmp = CSR_READ_4(sc, IWI_CSR_RST);
1720 0 : tmp &= ~(IWI_RST_MASTER_DISABLED | IWI_RST_STOP_MASTER);
1721 0 : CSR_WRITE_4(sc, IWI_CSR_RST, tmp);
1722 :
1723 : /* tell the adapter to start processing command blocks */
1724 0 : MEM_WRITE_4(sc, 0x3000a4, 0x540100);
1725 :
1726 : /* wait until the adapter has processed all command blocks */
1727 0 : for (ntries = 0; ntries < 400; ntries++) {
1728 0 : if (MEM_READ_4(sc, 0x3000d0) >= sentinel)
1729 : break;
1730 0 : DELAY(100);
1731 : }
1732 0 : if (ntries == 400) {
1733 0 : printf("%s: timeout processing cb\n", sc->sc_dev.dv_xname);
1734 : error = ETIMEDOUT;
1735 0 : goto fail5;
1736 : }
1737 :
1738 : /* we're done with command blocks processing */
1739 0 : MEM_WRITE_4(sc, 0x3000a4, 0x540c00);
1740 :
1741 : /* allow interrupts so we know when the firmware is inited */
1742 0 : CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, IWI_INTR_MASK);
1743 :
1744 : /* tell the adapter to initialize the firmware */
1745 0 : CSR_WRITE_4(sc, IWI_CSR_RST, 0);
1746 :
1747 0 : tmp = CSR_READ_4(sc, IWI_CSR_CTL);
1748 0 : CSR_WRITE_4(sc, IWI_CSR_CTL, tmp | IWI_CTL_ALLOW_STANDBY);
1749 :
1750 : /* wait at most one second for firmware initialization to complete */
1751 0 : if ((error = tsleep(sc, PCATCH, "iwiinit", hz)) != 0) {
1752 0 : printf("%s: timeout waiting for firmware initialization to "
1753 0 : "complete\n", sc->sc_dev.dv_xname);
1754 0 : goto fail5;
1755 : }
1756 :
1757 0 : fail5: bus_dmamap_sync(sc->sc_dmat, map, 0, size, BUS_DMASYNC_POSTWRITE);
1758 0 : bus_dmamap_unload(sc->sc_dmat, map);
1759 0 : fail4: bus_dmamem_unmap(sc->sc_dmat, virtaddr, size);
1760 0 : fail3: bus_dmamem_free(sc->sc_dmat, &seg, 1);
1761 0 : fail2: bus_dmamap_destroy(sc->sc_dmat, map);
1762 0 : fail1: return error;
1763 0 : }
1764 :
1765 : int
1766 0 : iwi_config(struct iwi_softc *sc)
1767 : {
1768 0 : struct ieee80211com *ic = &sc->sc_ic;
1769 0 : struct ifnet *ifp = &ic->ic_if;
1770 0 : struct iwi_configuration config;
1771 0 : struct iwi_rateset rs;
1772 0 : struct iwi_txpower power;
1773 0 : uint32_t data;
1774 : int error, nchan, i;
1775 :
1776 0 : IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
1777 : DPRINTF(("Setting MAC address to %s\n", ether_sprintf(ic->ic_myaddr)));
1778 0 : error = iwi_cmd(sc, IWI_CMD_SET_MAC_ADDRESS, ic->ic_myaddr,
1779 : IEEE80211_ADDR_LEN, 0);
1780 0 : if (error != 0)
1781 0 : return error;
1782 :
1783 0 : bzero(&config, sizeof config);
1784 0 : config.multicast_enabled = 1;
1785 0 : config.silence_threshold = 30;
1786 0 : config.report_noise = 1;
1787 0 : config.answer_pbreq =
1788 : #ifndef IEEE80211_STA_ONLY
1789 0 : (ic->ic_opmode == IEEE80211_M_IBSS) ? 1 :
1790 : #endif
1791 : 0;
1792 : DPRINTF(("Configuring adapter\n"));
1793 0 : error = iwi_cmd(sc, IWI_CMD_SET_CONFIG, &config, sizeof config, 0);
1794 0 : if (error != 0)
1795 0 : return error;
1796 :
1797 0 : data = htole32(IWI_POWER_MODE_CAM);
1798 : DPRINTF(("Setting power mode to %u\n", letoh32(data)));
1799 0 : error = iwi_cmd(sc, IWI_CMD_SET_POWER_MODE, &data, sizeof data, 0);
1800 0 : if (error != 0)
1801 0 : return error;
1802 :
1803 0 : data = htole32(ic->ic_rtsthreshold);
1804 : DPRINTF(("Setting RTS threshold to %u\n", letoh32(data)));
1805 0 : error = iwi_cmd(sc, IWI_CMD_SET_RTS_THRESHOLD, &data, sizeof data, 0);
1806 0 : if (error != 0)
1807 0 : return error;
1808 :
1809 0 : data = htole32(ic->ic_fragthreshold);
1810 : DPRINTF(("Setting fragmentation threshold to %u\n", letoh32(data)));
1811 0 : error = iwi_cmd(sc, IWI_CMD_SET_FRAG_THRESHOLD, &data, sizeof data, 0);
1812 0 : if (error != 0)
1813 0 : return error;
1814 :
1815 : /*
1816 : * Set default Tx power for 802.11b/g and 802.11a channels.
1817 : */
1818 : nchan = 0;
1819 0 : for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
1820 0 : if (!IEEE80211_IS_CHAN_2GHZ(&ic->ic_channels[i]))
1821 : continue;
1822 0 : power.chan[nchan].chan = i;
1823 0 : power.chan[nchan].power = IWI_TXPOWER_MAX;
1824 0 : nchan++;
1825 0 : }
1826 0 : power.nchan = nchan;
1827 :
1828 0 : power.mode = IWI_MODE_11G;
1829 : DPRINTF(("Setting .11g channels tx power\n"));
1830 0 : error = iwi_cmd(sc, IWI_CMD_SET_TX_POWER, &power, sizeof power, 0);
1831 0 : if (error != 0)
1832 0 : return error;
1833 :
1834 0 : power.mode = IWI_MODE_11B;
1835 : DPRINTF(("Setting .11b channels tx power\n"));
1836 0 : error = iwi_cmd(sc, IWI_CMD_SET_TX_POWER, &power, sizeof power, 0);
1837 0 : if (error != 0)
1838 0 : return error;
1839 :
1840 : nchan = 0;
1841 0 : for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
1842 0 : if (!IEEE80211_IS_CHAN_5GHZ(&ic->ic_channels[i]))
1843 : continue;
1844 0 : power.chan[nchan].chan = i;
1845 0 : power.chan[nchan].power = IWI_TXPOWER_MAX;
1846 0 : nchan++;
1847 0 : }
1848 0 : power.nchan = nchan;
1849 :
1850 0 : if (nchan > 0) { /* 2915ABG only */
1851 0 : power.mode = IWI_MODE_11A;
1852 : DPRINTF(("Setting .11a channels tx power\n"));
1853 0 : error = iwi_cmd(sc, IWI_CMD_SET_TX_POWER, &power, sizeof power,
1854 : 0);
1855 0 : if (error != 0)
1856 0 : return error;
1857 : }
1858 :
1859 0 : rs.mode = IWI_MODE_11G;
1860 0 : rs.type = IWI_RATESET_TYPE_SUPPORTED;
1861 0 : rs.nrates = ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates;
1862 0 : bcopy(ic->ic_sup_rates[IEEE80211_MODE_11G].rs_rates, rs.rates,
1863 0 : rs.nrates);
1864 : DPRINTF(("Setting .11bg supported rates (%u)\n", rs.nrates));
1865 0 : error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, 0);
1866 0 : if (error != 0)
1867 0 : return error;
1868 :
1869 0 : rs.mode = IWI_MODE_11A;
1870 0 : rs.type = IWI_RATESET_TYPE_SUPPORTED;
1871 0 : rs.nrates = ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates;
1872 0 : bcopy(ic->ic_sup_rates[IEEE80211_MODE_11A].rs_rates, rs.rates,
1873 0 : rs.nrates);
1874 : DPRINTF(("Setting .11a supported rates (%u)\n", rs.nrates));
1875 0 : error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, 0);
1876 0 : if (error != 0)
1877 0 : return error;
1878 :
1879 : /* if we have a desired ESSID, set it now */
1880 0 : if (ic->ic_des_esslen != 0) {
1881 : #ifdef IWI_DEBUG
1882 : if (iwi_debug > 0) {
1883 : printf("Setting desired ESSID to ");
1884 : ieee80211_print_essid(ic->ic_des_essid,
1885 : ic->ic_des_esslen);
1886 : printf("\n");
1887 : }
1888 : #endif
1889 0 : error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ic->ic_des_essid,
1890 0 : ic->ic_des_esslen, 0);
1891 0 : if (error != 0)
1892 0 : return error;
1893 : }
1894 :
1895 0 : arc4random_buf(&data, sizeof data);
1896 : DPRINTF(("Setting random seed to %u\n", data));
1897 0 : error = iwi_cmd(sc, IWI_CMD_SET_RANDOM_SEED, &data, sizeof data, 0);
1898 0 : if (error != 0)
1899 0 : return error;
1900 :
1901 : /* enable adapter */
1902 : DPRINTF(("Enabling adapter\n"));
1903 0 : return iwi_cmd(sc, IWI_CMD_ENABLE, NULL, 0, 0);
1904 0 : }
1905 :
1906 : void
1907 0 : iwi_update_edca(struct ieee80211com *ic)
1908 : {
1909 : #define IWI_EXP2(v) htole16((1 << (v)) - 1)
1910 : #define IWI_TXOP(v) IEEE80211_TXOP_TO_US(v)
1911 0 : struct iwi_softc *sc = ic->ic_softc;
1912 0 : struct iwi_qos_cmd cmd;
1913 : struct iwi_qos_params *qos;
1914 0 : struct ieee80211_edca_ac_params *edca = ic->ic_edca_ac;
1915 : int aci;
1916 :
1917 : /* set default QoS parameters for CCK */
1918 0 : qos = &cmd.cck;
1919 0 : for (aci = 0; aci < EDCA_NUM_AC; aci++) {
1920 0 : qos->cwmin[aci] = IWI_EXP2(iwi_cck[aci].ac_ecwmin);
1921 0 : qos->cwmax[aci] = IWI_EXP2(iwi_cck[aci].ac_ecwmax);
1922 0 : qos->txop [aci] = IWI_TXOP(iwi_cck[aci].ac_txoplimit);
1923 0 : qos->aifsn[aci] = iwi_cck[aci].ac_aifsn;
1924 0 : qos->acm [aci] = 0;
1925 : }
1926 : /* set default QoS parameters for OFDM */
1927 0 : qos = &cmd.ofdm;
1928 0 : for (aci = 0; aci < EDCA_NUM_AC; aci++) {
1929 0 : qos->cwmin[aci] = IWI_EXP2(iwi_ofdm[aci].ac_ecwmin);
1930 0 : qos->cwmax[aci] = IWI_EXP2(iwi_ofdm[aci].ac_ecwmax);
1931 0 : qos->txop [aci] = IWI_TXOP(iwi_ofdm[aci].ac_txoplimit);
1932 0 : qos->aifsn[aci] = iwi_ofdm[aci].ac_aifsn;
1933 0 : qos->acm [aci] = 0;
1934 : }
1935 : /* set current QoS parameters */
1936 0 : qos = &cmd.current;
1937 0 : for (aci = 0; aci < EDCA_NUM_AC; aci++) {
1938 0 : qos->cwmin[aci] = IWI_EXP2(edca[aci].ac_ecwmin);
1939 0 : qos->cwmax[aci] = IWI_EXP2(edca[aci].ac_ecwmax);
1940 0 : qos->txop [aci] = IWI_TXOP(edca[aci].ac_txoplimit);
1941 0 : qos->aifsn[aci] = edca[aci].ac_aifsn;
1942 0 : qos->acm [aci] = 0;
1943 : }
1944 :
1945 : DPRINTF(("Setting QoS parameters\n"));
1946 0 : (void)iwi_cmd(sc, IWI_CMD_SET_QOS_PARAMS, &cmd, sizeof cmd, 1);
1947 : #undef IWI_EXP2
1948 : #undef IWI_TXOP
1949 0 : }
1950 :
1951 : int
1952 0 : iwi_set_chan(struct iwi_softc *sc, struct ieee80211_channel *chan)
1953 : {
1954 0 : struct ieee80211com *ic = &sc->sc_ic;
1955 0 : struct iwi_scan scan;
1956 :
1957 0 : bzero(&scan, sizeof scan);
1958 0 : memset(scan.type, IWI_SCAN_TYPE_PASSIVE, sizeof scan.type);
1959 0 : scan.passive = htole16(2000);
1960 0 : scan.channels[0] = 1 |
1961 0 : (IEEE80211_IS_CHAN_5GHZ(chan) ? IWI_CHAN_5GHZ : IWI_CHAN_2GHZ);
1962 0 : scan.channels[1] = ieee80211_chan2ieee(ic, chan);
1963 :
1964 : DPRINTF(("Setting channel to %u\n", ieee80211_chan2ieee(ic, chan)));
1965 0 : return iwi_cmd(sc, IWI_CMD_SCAN, &scan, sizeof scan, 1);
1966 0 : }
1967 :
1968 : int
1969 0 : iwi_scan(struct iwi_softc *sc)
1970 : {
1971 0 : struct ieee80211com *ic = &sc->sc_ic;
1972 0 : struct iwi_scan scan;
1973 : uint8_t *p;
1974 : int i, count;
1975 :
1976 0 : bzero(&scan, sizeof scan);
1977 :
1978 0 : if (ic->ic_des_esslen != 0) {
1979 0 : scan.bdirected = htole16(40);
1980 0 : memset(scan.type, IWI_SCAN_TYPE_BDIRECTED, sizeof scan.type);
1981 0 : } else {
1982 0 : scan.broadcast = htole16(40);
1983 0 : memset(scan.type, IWI_SCAN_TYPE_BROADCAST, sizeof scan.type);
1984 : }
1985 :
1986 0 : p = scan.channels;
1987 : count = 0;
1988 0 : for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
1989 0 : if (IEEE80211_IS_CHAN_5GHZ(&ic->ic_channels[i])) {
1990 0 : *++p = i;
1991 0 : count++;
1992 0 : }
1993 : }
1994 0 : *(p - count) = IWI_CHAN_5GHZ | count;
1995 :
1996 0 : p = (count > 0) ? p + 1 : scan.channels;
1997 : count = 0;
1998 0 : for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
1999 0 : if (IEEE80211_IS_CHAN_2GHZ(&ic->ic_channels[i])) {
2000 0 : *++p = i;
2001 0 : count++;
2002 0 : }
2003 : }
2004 0 : *(p - count) = IWI_CHAN_2GHZ | count;
2005 :
2006 : DPRINTF(("Start scanning\n"));
2007 0 : return iwi_cmd(sc, IWI_CMD_SCAN, &scan, sizeof scan, 1);
2008 0 : }
2009 :
2010 : int
2011 0 : iwi_auth_and_assoc(struct iwi_softc *sc)
2012 : {
2013 0 : struct ieee80211com *ic = &sc->sc_ic;
2014 0 : struct ieee80211_node *ni = ic->ic_bss;
2015 0 : struct iwi_configuration config;
2016 0 : struct iwi_associate assoc;
2017 0 : struct iwi_rateset rs;
2018 : uint8_t *frm;
2019 0 : uint32_t data;
2020 : uint16_t capinfo;
2021 0 : uint8_t buf[64]; /* XXX max WPA/RSN/WMM IE length */
2022 : int error;
2023 :
2024 : /* update adapter configuration */
2025 0 : bzero(&config, sizeof config);
2026 0 : config.multicast_enabled = 1;
2027 0 : config.disable_unicast_decryption = 1;
2028 0 : config.disable_multicast_decryption = 1;
2029 0 : config.silence_threshold = 30;
2030 0 : config.report_noise = 1;
2031 0 : config.allow_mgt = 1;
2032 0 : config.answer_pbreq =
2033 : #ifndef IEEE80211_STA_ONLY
2034 0 : (ic->ic_opmode == IEEE80211_M_IBSS) ? 1 :
2035 : #endif
2036 : 0;
2037 0 : if (ic->ic_curmode == IEEE80211_MODE_11G)
2038 0 : config.bg_autodetection = 1;
2039 : DPRINTF(("Configuring adapter\n"));
2040 0 : error = iwi_cmd(sc, IWI_CMD_SET_CONFIG, &config, sizeof config, 1);
2041 0 : if (error != 0)
2042 0 : return error;
2043 :
2044 : #ifdef IWI_DEBUG
2045 : if (iwi_debug > 0) {
2046 : printf("Setting ESSID to ");
2047 : ieee80211_print_essid(ni->ni_essid, ni->ni_esslen);
2048 : printf("\n");
2049 : }
2050 : #endif
2051 0 : error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ni->ni_essid, ni->ni_esslen, 1);
2052 0 : if (error != 0)
2053 0 : return error;
2054 :
2055 : /* the rate set has already been "negotiated" */
2056 0 : rs.mode = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? IWI_MODE_11A :
2057 : IWI_MODE_11G;
2058 0 : rs.type = IWI_RATESET_TYPE_NEGOTIATED;
2059 0 : rs.nrates = ni->ni_rates.rs_nrates;
2060 0 : if (rs.nrates > sizeof rs.rates) {
2061 : #ifdef DIAGNOSTIC
2062 : /* should not happen since the rates are negotiated */
2063 0 : printf("%s: XXX too many rates (count=%d, last=%d)\n",
2064 0 : sc->sc_dev.dv_xname, ni->ni_rates.rs_nrates,
2065 0 : ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates - 1] &
2066 : IEEE80211_RATE_VAL);
2067 : #endif
2068 0 : rs.nrates = sizeof rs.rates;
2069 0 : }
2070 0 : bcopy(ni->ni_rates.rs_rates, rs.rates, rs.nrates);
2071 : DPRINTF(("Setting negotiated rates (%u)\n", rs.nrates));
2072 0 : error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, 1);
2073 0 : if (error != 0)
2074 0 : return error;
2075 :
2076 0 : data = htole32(ni->ni_rssi);
2077 : DPRINTF(("Setting sensitivity to %d\n", (int8_t)ni->ni_rssi));
2078 0 : error = iwi_cmd(sc, IWI_CMD_SET_SENSITIVITY, &data, sizeof data, 1);
2079 0 : if (error != 0)
2080 0 : return error;
2081 :
2082 0 : if (ic->ic_flags & IEEE80211_F_QOS) {
2083 0 : iwi_update_edca(ic);
2084 :
2085 0 : frm = ieee80211_add_qos_capability(buf, ic);
2086 : DPRINTF(("Setting QoS Capability IE length %d\n", frm - buf));
2087 0 : error = iwi_cmd(sc, IWI_CMD_SET_QOS_CAP, buf, frm - buf, 1);
2088 0 : if (error != 0)
2089 0 : return error;
2090 : }
2091 0 : if (ic->ic_flags & IEEE80211_F_RSNON) {
2092 : /* tell firmware to add WPA/RSN IE to (re)assoc request */
2093 0 : if (ni->ni_rsnprotos == IEEE80211_PROTO_RSN)
2094 0 : frm = ieee80211_add_rsn(buf, ic, ni);
2095 : else
2096 0 : frm = ieee80211_add_wpa(buf, ic, ni);
2097 : DPRINTF(("Setting RSN IE length %d\n", frm - buf));
2098 0 : error = iwi_cmd(sc, IWI_CMD_SET_OPTIE, buf, frm - buf, 1);
2099 0 : if (error != 0)
2100 0 : return error;
2101 : }
2102 :
2103 0 : bzero(&assoc, sizeof assoc);
2104 : #ifndef IEEE80211_STA_ONLY
2105 0 : if (ic->ic_flags & IEEE80211_F_SIBSS)
2106 0 : assoc.type = IWI_ASSOC_SIBSS;
2107 : else
2108 : #endif
2109 0 : assoc.type = IWI_ASSOC_ASSOCIATE;
2110 0 : assoc.policy = 0;
2111 0 : if (ic->ic_flags & IEEE80211_F_RSNON)
2112 0 : assoc.policy |= htole16(IWI_ASSOC_POLICY_RSN);
2113 0 : if (ic->ic_flags & IEEE80211_F_QOS)
2114 0 : assoc.policy |= htole16(IWI_ASSOC_POLICY_QOS);
2115 0 : if (ic->ic_curmode == IEEE80211_MODE_11A)
2116 0 : assoc.mode = IWI_MODE_11A;
2117 0 : else if (ic->ic_curmode == IEEE80211_MODE_11B)
2118 0 : assoc.mode = IWI_MODE_11B;
2119 : else /* assume 802.11b/g */
2120 0 : assoc.mode = IWI_MODE_11G;
2121 0 : assoc.chan = ieee80211_chan2ieee(ic, ni->ni_chan);
2122 0 : if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
2123 0 : IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
2124 0 : assoc.plen = IWI_ASSOC_SHPREAMBLE;
2125 0 : bcopy(ni->ni_tstamp, assoc.tstamp, 8);
2126 : capinfo = IEEE80211_CAPINFO_ESS;
2127 0 : if (ic->ic_flags & IEEE80211_F_WEPON)
2128 0 : capinfo |= IEEE80211_CAPINFO_PRIVACY;
2129 0 : if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
2130 0 : IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
2131 0 : capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
2132 0 : if (ic->ic_caps & IEEE80211_C_SHSLOT)
2133 0 : capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
2134 0 : assoc.capinfo = htole16(capinfo);
2135 :
2136 0 : assoc.lintval = htole16(ic->ic_lintval);
2137 0 : assoc.intval = htole16(ni->ni_intval);
2138 0 : IEEE80211_ADDR_COPY(assoc.bssid, ni->ni_bssid);
2139 : #ifndef IEEE80211_STA_ONLY
2140 0 : if (ic->ic_opmode == IEEE80211_M_IBSS)
2141 0 : IEEE80211_ADDR_COPY(assoc.dst, etherbroadcastaddr);
2142 : else
2143 : #endif
2144 0 : IEEE80211_ADDR_COPY(assoc.dst, ni->ni_bssid);
2145 :
2146 : DPRINTF(("Trying to associate to %s channel %u auth %u\n",
2147 : ether_sprintf(assoc.bssid), assoc.chan, assoc.auth));
2148 0 : return iwi_cmd(sc, IWI_CMD_ASSOCIATE, &assoc, sizeof assoc, 1);
2149 0 : }
2150 :
2151 : int
2152 0 : iwi_init(struct ifnet *ifp)
2153 : {
2154 0 : struct iwi_softc *sc = ifp->if_softc;
2155 0 : struct ieee80211com *ic = &sc->sc_ic;
2156 : struct iwi_firmware_hdr *hdr;
2157 : const char *name, *fw;
2158 0 : u_char *data;
2159 0 : size_t size;
2160 : int i, ac, error;
2161 :
2162 0 : iwi_stop(ifp, 0);
2163 :
2164 0 : if ((error = iwi_reset(sc)) != 0) {
2165 0 : printf("%s: could not reset adapter\n", sc->sc_dev.dv_xname);
2166 0 : goto fail1;
2167 : }
2168 :
2169 0 : switch (ic->ic_opmode) {
2170 : case IEEE80211_M_STA:
2171 : name = "iwi-bss";
2172 0 : break;
2173 : #ifndef IEEE80211_STA_ONLY
2174 : case IEEE80211_M_IBSS:
2175 : case IEEE80211_M_AHDEMO:
2176 : name = "iwi-ibss";
2177 0 : break;
2178 : #endif
2179 : case IEEE80211_M_MONITOR:
2180 : name = "iwi-monitor";
2181 0 : break;
2182 : default:
2183 : /* should not get there */
2184 : error = EINVAL;
2185 0 : goto fail1;
2186 : }
2187 :
2188 0 : if ((error = loadfirmware(name, &data, &size)) != 0) {
2189 0 : printf("%s: error %d, could not read firmware %s\n",
2190 0 : sc->sc_dev.dv_xname, error, name);
2191 0 : goto fail1;
2192 : }
2193 0 : if (size < sizeof (struct iwi_firmware_hdr)) {
2194 0 : printf("%s: firmware image too short: %zu bytes\n",
2195 0 : sc->sc_dev.dv_xname, size);
2196 : error = EINVAL;
2197 0 : goto fail2;
2198 : }
2199 0 : hdr = (struct iwi_firmware_hdr *)data;
2200 :
2201 0 : if (hdr->vermaj < 3 || hdr->bootsz == 0 || hdr->ucodesz == 0 ||
2202 0 : hdr->mainsz == 0) {
2203 0 : printf("%s: firmware image too old (need at least 3.0)\n",
2204 0 : sc->sc_dev.dv_xname);
2205 : error = EINVAL;
2206 0 : goto fail2;
2207 : }
2208 :
2209 0 : if (size < sizeof (struct iwi_firmware_hdr) + letoh32(hdr->bootsz) +
2210 0 : letoh32(hdr->ucodesz) + letoh32(hdr->mainsz)) {
2211 0 : printf("%s: firmware image too short: %zu bytes\n",
2212 0 : sc->sc_dev.dv_xname, size);
2213 : error = EINVAL;
2214 0 : goto fail2;
2215 : }
2216 :
2217 0 : fw = (const char *)data + sizeof (struct iwi_firmware_hdr);
2218 0 : if ((error = iwi_load_firmware(sc, fw, letoh32(hdr->bootsz))) != 0) {
2219 0 : printf("%s: could not load boot firmware\n",
2220 0 : sc->sc_dev.dv_xname);
2221 0 : goto fail2;
2222 : }
2223 :
2224 0 : fw = (const char *)data + sizeof (struct iwi_firmware_hdr) +
2225 0 : letoh32(hdr->bootsz);
2226 0 : if ((error = iwi_load_ucode(sc, fw, letoh32(hdr->ucodesz))) != 0) {
2227 0 : printf("%s: could not load microcode\n", sc->sc_dev.dv_xname);
2228 0 : goto fail2;
2229 : }
2230 :
2231 0 : iwi_stop_master(sc);
2232 :
2233 0 : CSR_WRITE_4(sc, IWI_CSR_CMD_BASE, sc->cmdq.map->dm_segs[0].ds_addr);
2234 0 : CSR_WRITE_4(sc, IWI_CSR_CMD_SIZE, IWI_CMD_RING_COUNT);
2235 0 : CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.cur);
2236 :
2237 0 : for (ac = 0; ac < EDCA_NUM_AC; ac++) {
2238 0 : CSR_WRITE_4(sc, IWI_CSR_TX_BASE(ac),
2239 : sc->txq[ac].map->dm_segs[0].ds_addr);
2240 0 : CSR_WRITE_4(sc, IWI_CSR_TX_SIZE(ac), IWI_TX_RING_COUNT);
2241 0 : CSR_WRITE_4(sc, IWI_CSR_TX_WIDX(ac), sc->txq[ac].cur);
2242 : }
2243 :
2244 0 : for (i = 0; i < IWI_RX_RING_COUNT; i++) {
2245 0 : struct iwi_rx_data *data = &sc->rxq.data[i];
2246 0 : CSR_WRITE_4(sc, data->reg, data->map->dm_segs[0].ds_addr);
2247 : }
2248 :
2249 0 : CSR_WRITE_4(sc, IWI_CSR_RX_WIDX, IWI_RX_RING_COUNT - 1);
2250 :
2251 0 : fw = (const char *)data + sizeof (struct iwi_firmware_hdr) +
2252 0 : letoh32(hdr->bootsz) + letoh32(hdr->ucodesz);
2253 0 : if ((error = iwi_load_firmware(sc, fw, letoh32(hdr->mainsz))) != 0) {
2254 0 : printf("%s: could not load main firmware\n",
2255 0 : sc->sc_dev.dv_xname);
2256 0 : goto fail2;
2257 : }
2258 :
2259 0 : free(data, M_DEVBUF, size);
2260 :
2261 0 : if ((error = iwi_config(sc)) != 0) {
2262 0 : printf("%s: device configuration failed\n",
2263 0 : sc->sc_dev.dv_xname);
2264 0 : goto fail1;
2265 : }
2266 :
2267 0 : ifq_clr_oactive(&ifp->if_snd);
2268 0 : ifp->if_flags |= IFF_RUNNING;
2269 :
2270 0 : if (ic->ic_opmode != IEEE80211_M_MONITOR)
2271 0 : ieee80211_begin_scan(ifp);
2272 : else
2273 0 : ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
2274 :
2275 0 : return 0;
2276 :
2277 0 : fail2: free(data, M_DEVBUF, size);
2278 0 : fail1: iwi_stop(ifp, 0);
2279 0 : return error;
2280 0 : }
2281 :
2282 : void
2283 0 : iwi_stop(struct ifnet *ifp, int disable)
2284 : {
2285 0 : struct iwi_softc *sc = ifp->if_softc;
2286 0 : struct ieee80211com *ic = &sc->sc_ic;
2287 : int ac;
2288 :
2289 0 : sc->sc_tx_timer = 0;
2290 0 : ifp->if_timer = 0;
2291 0 : ifp->if_flags &= ~IFF_RUNNING;
2292 0 : ifq_clr_oactive(&ifp->if_snd);
2293 :
2294 0 : ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2295 :
2296 0 : iwi_stop_master(sc);
2297 :
2298 0 : CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_SW_RESET);
2299 :
2300 : /* reset rings */
2301 0 : iwi_reset_cmd_ring(sc, &sc->cmdq);
2302 0 : for (ac = 0; ac < EDCA_NUM_AC; ac++)
2303 0 : iwi_reset_tx_ring(sc, &sc->txq[ac]);
2304 0 : iwi_reset_rx_ring(sc, &sc->rxq);
2305 0 : }
2306 :
2307 : struct cfdriver iwi_cd = {
2308 : NULL, "iwi", DV_IFNET
2309 : };
|