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