]> CyberLeo.Net >> Repos - FreeBSD/releng/8.0.git/blob - sys/dev/iwn/if_iwn.c
Adjust to reflect 8.0-RELEASE.
[FreeBSD/releng/8.0.git] / sys / dev / iwn / if_iwn.c
1 /*-
2  * Copyright (c) 2007
3  *      Damien Bergamini <damien.bergamini@free.fr>
4  * Copyright (c) 2008
5  *      Benjamin Close <benjsc@FreeBSD.org>
6  * Copyright (c) 2008 Sam Leffler, Errno Consulting
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20
21 /*
22  * Driver for Intel Wireless WiFi Link 4965AGN 802.11 network adapters.
23  */
24
25 #include <sys/cdefs.h>
26 __FBSDID("$FreeBSD$");
27
28 #include <sys/param.h>
29 #include <sys/sockio.h>
30 #include <sys/sysctl.h>
31 #include <sys/mbuf.h>
32 #include <sys/kernel.h>
33 #include <sys/socket.h>
34 #include <sys/systm.h>
35 #include <sys/malloc.h>
36 #include <sys/bus.h>
37 #include <sys/rman.h>
38 #include <sys/endian.h>
39 #include <sys/firmware.h>
40 #include <sys/limits.h>
41 #include <sys/module.h>
42 #include <sys/queue.h>
43 #include <sys/taskqueue.h>
44
45 #include <machine/bus.h>
46 #include <machine/resource.h>
47 #include <machine/clock.h>
48
49 #include <dev/pci/pcireg.h>
50 #include <dev/pci/pcivar.h>
51
52 #include <net/bpf.h>
53 #include <net/if.h>
54 #include <net/if_arp.h>
55 #include <net/ethernet.h>
56 #include <net/if_dl.h>
57 #include <net/if_media.h>
58 #include <net/if_types.h>
59
60 #include <netinet/in.h>
61 #include <netinet/in_systm.h>
62 #include <netinet/in_var.h>
63 #include <netinet/if_ether.h>
64 #include <netinet/ip.h>
65
66 #include <net80211/ieee80211_var.h>
67 #include <net80211/ieee80211_amrr.h>
68 #include <net80211/ieee80211_radiotap.h>
69 #include <net80211/ieee80211_regdomain.h>
70
71 #include <dev/iwn/if_iwnreg.h>
72 #include <dev/iwn/if_iwnvar.h>
73
74 static int      iwn_probe(device_t);
75 static int      iwn_attach(device_t);
76 static int      iwn_detach(device_t);
77 static int      iwn_cleanup(device_t);
78 static struct ieee80211vap *iwn_vap_create(struct ieee80211com *,
79                     const char name[IFNAMSIZ], int unit, int opmode,
80                     int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
81                     const uint8_t mac[IEEE80211_ADDR_LEN]);
82 static void     iwn_vap_delete(struct ieee80211vap *);
83 static int      iwn_shutdown(device_t);
84 static int      iwn_suspend(device_t);
85 static int      iwn_resume(device_t);
86 static int      iwn_dma_contig_alloc(struct iwn_softc *, struct iwn_dma_info *,
87                     void **, bus_size_t, bus_size_t, int);
88 static void     iwn_dma_contig_free(struct iwn_dma_info *);
89 int             iwn_alloc_shared(struct iwn_softc *);
90 void            iwn_free_shared(struct iwn_softc *);
91 int             iwn_alloc_kw(struct iwn_softc *);
92 void            iwn_free_kw(struct iwn_softc *);
93 int             iwn_alloc_fwmem(struct iwn_softc *);
94 void            iwn_free_fwmem(struct iwn_softc *);
95 struct          iwn_rbuf *iwn_alloc_rbuf(struct iwn_softc *);
96 void            iwn_free_rbuf(void *, void *);
97 int             iwn_alloc_rpool(struct iwn_softc *);
98 void            iwn_free_rpool(struct iwn_softc *);
99 int             iwn_alloc_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
100 void            iwn_reset_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
101 void            iwn_free_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
102 int             iwn_alloc_tx_ring(struct iwn_softc *, struct iwn_tx_ring *,
103                     int);
104 void            iwn_reset_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
105 void            iwn_free_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
106 static struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
107                     const uint8_t [IEEE80211_ADDR_LEN]);
108 void            iwn_newassoc(struct ieee80211_node *, int);
109 int             iwn_media_change(struct ifnet *);
110 int             iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
111 void            iwn_mem_lock(struct iwn_softc *);
112 void            iwn_mem_unlock(struct iwn_softc *);
113 uint32_t        iwn_mem_read(struct iwn_softc *, uint32_t);
114 void            iwn_mem_write(struct iwn_softc *, uint32_t, uint32_t);
115 void            iwn_mem_write_region_4(struct iwn_softc *, uint32_t,
116                     const uint32_t *, int);
117 int             iwn_eeprom_lock(struct iwn_softc *);
118 void            iwn_eeprom_unlock(struct iwn_softc *);
119 int             iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
120 int             iwn_transfer_microcode(struct iwn_softc *, const uint8_t *, int);
121 int             iwn_transfer_firmware(struct iwn_softc *);
122 int             iwn_load_firmware(struct iwn_softc *);
123 void            iwn_unload_firmware(struct iwn_softc *);
124 static void     iwn_timer_timeout(void *);
125 static void     iwn_calib_reset(struct iwn_softc *);
126 void            iwn_ampdu_rx_start(struct iwn_softc *, struct iwn_rx_desc *);
127 void            iwn_rx_intr(struct iwn_softc *, struct iwn_rx_desc *,
128                     struct iwn_rx_data *);
129 void            iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *);
130 void            iwn_tx_intr(struct iwn_softc *, struct iwn_rx_desc *);
131 void            iwn_cmd_intr(struct iwn_softc *, struct iwn_rx_desc *);
132 void            iwn_notif_intr(struct iwn_softc *);
133 void            iwn_intr(void *);
134 void            iwn_read_eeprom(struct iwn_softc *,
135                     uint8_t macaddr[IEEE80211_ADDR_LEN]);
136 static void     iwn_read_eeprom_channels(struct iwn_softc *);
137 void            iwn_print_power_group(struct iwn_softc *, int);
138 uint8_t         iwn_plcp_signal(int);
139 int             iwn_tx_data(struct iwn_softc *, struct mbuf *,
140                     struct ieee80211_node *, struct iwn_tx_ring *);
141 void            iwn_start(struct ifnet *);
142 void            iwn_start_locked(struct ifnet *);
143 static int      iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
144                     const struct ieee80211_bpf_params *);
145 static void     iwn_watchdog(struct iwn_softc *);
146 int             iwn_ioctl(struct ifnet *, u_long, caddr_t);
147 int             iwn_cmd(struct iwn_softc *, int, const void *, int, int);
148 int             iwn_set_link_quality(struct iwn_softc *, uint8_t,
149                     const struct ieee80211_channel *, int);
150 int             iwn_set_key(struct ieee80211com *, struct ieee80211_node *,
151                     const struct ieee80211_key *);
152 int             iwn_wme_update(struct ieee80211com *);
153 void            iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
154 int             iwn_set_critical_temp(struct iwn_softc *);
155 void            iwn_enable_tsf(struct iwn_softc *, struct ieee80211_node *);
156 void            iwn_power_calibration(struct iwn_softc *, int);
157 int             iwn_set_txpower(struct iwn_softc *,
158                     struct ieee80211_channel *, int);
159 int8_t          iwn_get_rssi(struct iwn_softc *, const struct iwn_rx_stat *);
160 int             iwn_get_noise(const struct iwn_rx_general_stats *);
161 int             iwn_get_temperature(struct iwn_softc *);
162 int             iwn_init_sensitivity(struct iwn_softc *);
163 void            iwn_compute_differential_gain(struct iwn_softc *,
164                     const struct iwn_rx_general_stats *);
165 void            iwn_tune_sensitivity(struct iwn_softc *,
166                     const struct iwn_rx_stats *);
167 int             iwn_send_sensitivity(struct iwn_softc *);
168 int             iwn_auth(struct iwn_softc *, struct ieee80211vap *);
169 int             iwn_run(struct iwn_softc *, struct ieee80211vap *);
170 int             iwn_scan(struct iwn_softc *);
171 int             iwn_config(struct iwn_softc *);
172 void            iwn_post_alive(struct iwn_softc *);
173 void            iwn_stop_master(struct iwn_softc *);
174 int             iwn_reset(struct iwn_softc *);
175 void            iwn_hw_config(struct iwn_softc *);
176 void            iwn_init_locked(struct iwn_softc *);
177 void            iwn_init(void *);
178 void            iwn_stop_locked(struct iwn_softc *);
179 void            iwn_stop(struct iwn_softc *);
180 static void     iwn_scan_start(struct ieee80211com *);
181 static void     iwn_scan_end(struct ieee80211com *);
182 static void     iwn_set_channel(struct ieee80211com *);
183 static void     iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long);
184 static void     iwn_scan_mindwell(struct ieee80211_scan_state *);
185 static void     iwn_hwreset(void *, int);
186 static void     iwn_radioon(void *, int);
187 static void     iwn_radiooff(void *, int);
188 static void     iwn_sysctlattach(struct iwn_softc *);
189
190 #define IWN_DEBUG
191 #ifdef IWN_DEBUG
192 enum {
193         IWN_DEBUG_XMIT          = 0x00000001,   /* basic xmit operation */
194         IWN_DEBUG_RECV          = 0x00000002,   /* basic recv operation */
195         IWN_DEBUG_STATE         = 0x00000004,   /* 802.11 state transitions */
196         IWN_DEBUG_TXPOW         = 0x00000008,   /* tx power processing */
197         IWN_DEBUG_RESET         = 0x00000010,   /* reset processing */
198         IWN_DEBUG_OPS           = 0x00000020,   /* iwn_ops processing */
199         IWN_DEBUG_BEACON        = 0x00000040,   /* beacon handling */
200         IWN_DEBUG_WATCHDOG      = 0x00000080,   /* watchdog timeout */
201         IWN_DEBUG_INTR          = 0x00000100,   /* ISR */
202         IWN_DEBUG_CALIBRATE     = 0x00000200,   /* periodic calibration */
203         IWN_DEBUG_NODE          = 0x00000400,   /* node management */
204         IWN_DEBUG_LED           = 0x00000800,   /* led management */
205         IWN_DEBUG_CMD           = 0x00001000,   /* cmd submission */
206         IWN_DEBUG_FATAL         = 0x80000000,   /* fatal errors */
207         IWN_DEBUG_ANY           = 0xffffffff
208 };
209
210 #define DPRINTF(sc, m, fmt, ...) do {                   \
211         if (sc->sc_debug & (m))                         \
212                 printf(fmt, __VA_ARGS__);               \
213 } while (0)
214
215 static const char *iwn_intr_str(uint8_t);
216 #else
217 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
218 #endif
219
220 struct iwn_ident {
221         uint16_t        vendor;
222         uint16_t        device;
223         const char      *name;
224 };
225
226 static const struct iwn_ident iwn_ident_table [] = {
227         { 0x8086, 0x4229, "Intel(R) PRO/Wireless 4965BGN" },
228         { 0x8086, 0x422D, "Intel(R) PRO/Wireless 4965BGN" },
229         { 0x8086, 0x4230, "Intel(R) PRO/Wireless 4965BGN" },
230         { 0x8086, 0x4233, "Intel(R) PRO/Wireless 4965BGN" },
231         { 0, 0, NULL }
232 };
233
234 static int
235 iwn_probe(device_t dev)
236 {
237         const struct iwn_ident *ident;
238
239         for (ident = iwn_ident_table; ident->name != NULL; ident++) {
240                 if (pci_get_vendor(dev) == ident->vendor &&
241                     pci_get_device(dev) == ident->device) {
242                         device_set_desc(dev, ident->name);
243                         return 0;
244                 }
245         }
246         return ENXIO;
247 }
248
249 static int
250 iwn_attach(device_t dev)
251 {
252         struct iwn_softc *sc = (struct iwn_softc *)device_get_softc(dev);
253         struct ieee80211com *ic;
254         struct ifnet *ifp;
255         int i, error, result;
256         uint8_t macaddr[IEEE80211_ADDR_LEN];
257
258         sc->sc_dev = dev;
259
260         /* XXX */
261         if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
262                 device_printf(dev, "chip is in D%d power mode "
263                     "-- setting to D0\n", pci_get_powerstate(dev));
264                 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
265         }
266
267         /* clear device specific PCI configuration register 0x41 */
268         pci_write_config(dev, 0x41, 0, 1);
269
270         /* enable bus-mastering */
271         pci_enable_busmaster(dev);
272
273         sc->mem_rid= PCIR_BAR(0);
274         sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
275                                          RF_ACTIVE);
276         if (sc->mem == NULL ) {
277                 device_printf(dev, "could not allocate memory resources\n");
278                 error = ENOMEM; 
279                 return error;
280         }
281
282         sc->sc_st = rman_get_bustag(sc->mem);
283         sc->sc_sh = rman_get_bushandle(sc->mem);
284         sc->irq_rid = 0;
285         if ((result = pci_msi_count(dev)) == 1 &&
286             pci_alloc_msi(dev, &result) == 0)
287                 sc->irq_rid = 1;
288         sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
289                                          RF_ACTIVE | RF_SHAREABLE);
290         if (sc->irq == NULL) {
291                 device_printf(dev, "could not allocate interrupt resource\n");
292                 error = ENOMEM;
293                 return error;
294         }
295
296         IWN_LOCK_INIT(sc);
297         callout_init_mtx(&sc->sc_timer_to, &sc->sc_mtx, 0);
298         TASK_INIT(&sc->sc_reinit_task, 0, iwn_hwreset, sc );
299         TASK_INIT(&sc->sc_radioon_task, 0, iwn_radioon, sc );
300         TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radiooff, sc );
301
302         /*
303          * Put adapter into a known state.
304          */
305         error = iwn_reset(sc);
306         if (error != 0) {
307                 device_printf(dev,
308                     "could not reset adapter, error %d\n", error);
309                 goto fail;
310         }
311
312         /*
313          * Allocate DMA memory for firmware transfers.
314          */
315         error = iwn_alloc_fwmem(sc);
316         if (error != 0) {
317                 device_printf(dev,
318                     "could not allocate firmware memory, error %d\n", error);
319                 goto fail;
320         }
321
322         /*
323          * Allocate a "keep warm" page.
324          */
325         error = iwn_alloc_kw(sc);
326         if (error != 0) {
327                 device_printf(dev,
328                     "could not allocate keep-warm page, error %d\n", error);
329                 goto fail;
330         }
331
332         /*
333          * Allocate shared area (communication area).
334          */
335         error = iwn_alloc_shared(sc);
336         if (error != 0) {
337                 device_printf(dev,
338                     "could not allocate shared area, error %d\n", error);
339                 goto fail;
340         }
341
342         /*
343          * Allocate Tx rings.
344          */
345         for (i = 0; i < IWN_NTXQUEUES; i++) {
346                 error = iwn_alloc_tx_ring(sc, &sc->txq[i], i);
347                 if (error != 0) {
348                         device_printf(dev,
349                             "could not allocate Tx ring %d, error %d\n",
350                             i, error);
351                         goto fail;
352                 }
353         }
354
355         error = iwn_alloc_rx_ring(sc, &sc->rxq);
356         if (error != 0 ){
357                 device_printf(dev,
358                     "could not allocate Rx ring, error %d\n", error);
359                 goto fail;
360         }
361
362         ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
363         if (ifp == NULL) {
364                 device_printf(dev, "can not allocate ifnet structure\n");
365                 goto fail;
366         }
367         ic = ifp->if_l2com;
368
369         ic->ic_ifp = ifp;       
370         ic->ic_phytype = IEEE80211_T_OFDM;      /* not only, but not used */
371         ic->ic_opmode = IEEE80211_M_STA;        /* default to BSS mode */
372
373         /* set device capabilities */
374         ic->ic_caps =
375                   IEEE80211_C_STA               /* station mode supported */
376                 | IEEE80211_C_MONITOR           /* monitor mode supported */
377                 | IEEE80211_C_TXPMGT            /* tx power management */
378                 | IEEE80211_C_SHSLOT            /* short slot time supported */
379                 | IEEE80211_C_WPA
380                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
381 #if 0
382                 | IEEE80211_C_BGSCAN            /* background scanning */
383                 | IEEE80211_C_IBSS              /* ibss/adhoc mode */
384 #endif
385                 | IEEE80211_C_WME               /* WME */
386                 ;
387 #if 0
388         /* XXX disable until HT channel setup works */
389         ic->ic_htcaps =
390                   IEEE80211_HTCAP_SMPS_ENA      /* SM PS mode enabled */
391                 | IEEE80211_HTCAP_CHWIDTH40     /* 40MHz channel width */
392                 | IEEE80211_HTCAP_SHORTGI20     /* short GI in 20MHz */
393                 | IEEE80211_HTCAP_SHORTGI40     /* short GI in 40MHz */
394                 | IEEE80211_HTCAP_RXSTBC_2STREAM/* 1-2 spatial streams */
395                 | IEEE80211_HTCAP_MAXAMSDU_3839 /* max A-MSDU length */
396                 /* s/w capabilities */
397                 | IEEE80211_HTC_HT              /* HT operation */
398                 | IEEE80211_HTC_AMPDU           /* tx A-MPDU */
399                 | IEEE80211_HTC_AMSDU           /* tx A-MSDU */
400                 ;
401 #endif
402         /* read supported channels and MAC address from EEPROM */
403         iwn_read_eeprom(sc, macaddr);
404
405         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
406         ifp->if_softc = sc;
407         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
408         ifp->if_init = iwn_init;
409         ifp->if_ioctl = iwn_ioctl;
410         ifp->if_start = iwn_start;
411         IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
412         ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
413         IFQ_SET_READY(&ifp->if_snd);
414
415         ieee80211_ifattach(ic, macaddr);
416         ic->ic_vap_create = iwn_vap_create;
417         ic->ic_vap_delete = iwn_vap_delete;
418         ic->ic_raw_xmit = iwn_raw_xmit;
419         ic->ic_node_alloc = iwn_node_alloc;
420         ic->ic_newassoc = iwn_newassoc;
421         ic->ic_wme.wme_update = iwn_wme_update;
422         ic->ic_scan_start = iwn_scan_start;
423         ic->ic_scan_end = iwn_scan_end;
424         ic->ic_set_channel = iwn_set_channel;
425         ic->ic_scan_curchan = iwn_scan_curchan;
426         ic->ic_scan_mindwell = iwn_scan_mindwell;
427
428         ieee80211_radiotap_attach(ic,
429             &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
430                 IWN_TX_RADIOTAP_PRESENT,
431             &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
432                 IWN_RX_RADIOTAP_PRESENT);
433
434         iwn_sysctlattach(sc);
435
436         /*
437          * Hook our interrupt after all initialization is complete.
438          */
439         error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
440             NULL, iwn_intr, sc, &sc->sc_ih);
441         if (error != 0) {
442                 device_printf(dev, "could not set up interrupt, error %d\n", error);
443                 goto fail;
444         }
445
446         ieee80211_announce(ic);
447         return 0;
448 fail:
449         iwn_cleanup(dev);
450         return error;
451 }
452
453 static int
454 iwn_detach(device_t dev)
455 {
456         iwn_cleanup(dev);
457         return 0;
458 }
459
460 /*
461  * Cleanup any device resources that were allocated
462  */
463 int
464 iwn_cleanup(device_t dev)
465 {
466         struct iwn_softc *sc = device_get_softc(dev);
467         struct ifnet *ifp = sc->sc_ifp;
468         struct ieee80211com *ic = ifp->if_l2com;
469         int i;
470
471         ieee80211_draintask(ic, &sc->sc_reinit_task);
472         ieee80211_draintask(ic, &sc->sc_radioon_task);
473         ieee80211_draintask(ic, &sc->sc_radiooff_task);
474
475         if (ifp != NULL) {
476                 iwn_stop(sc);
477                 callout_drain(&sc->sc_timer_to);
478                 ieee80211_ifdetach(ic);
479         }
480
481         iwn_unload_firmware(sc);
482
483         iwn_free_rx_ring(sc, &sc->rxq);
484         for (i = 0; i < IWN_NTXQUEUES; i++)
485                 iwn_free_tx_ring(sc, &sc->txq[i]);
486         iwn_free_kw(sc);
487         iwn_free_fwmem(sc);
488         if (sc->irq != NULL) {
489                 bus_teardown_intr(dev, sc->irq, sc->sc_ih);
490                 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
491                 if (sc->irq_rid == 1)
492                         pci_release_msi(dev);
493         }
494         if (sc->mem != NULL)
495                 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
496         if (ifp != NULL)
497                 if_free(ifp);
498         IWN_LOCK_DESTROY(sc);
499         return 0;
500 }
501
502 static struct ieee80211vap *
503 iwn_vap_create(struct ieee80211com *ic,
504         const char name[IFNAMSIZ], int unit, int opmode, int flags,
505         const uint8_t bssid[IEEE80211_ADDR_LEN],
506         const uint8_t mac[IEEE80211_ADDR_LEN])
507 {
508         struct iwn_vap *ivp;
509         struct ieee80211vap *vap;
510
511         if (!TAILQ_EMPTY(&ic->ic_vaps))         /* only one at a time */
512                 return NULL;
513         ivp = (struct iwn_vap *) malloc(sizeof(struct iwn_vap),
514             M_80211_VAP, M_NOWAIT | M_ZERO);
515         if (ivp == NULL)
516                 return NULL;
517         vap = &ivp->iv_vap;
518         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
519         vap->iv_bmissthreshold = 10;            /* override default */
520         /* override with driver methods */
521         ivp->iv_newstate = vap->iv_newstate;
522         vap->iv_newstate = iwn_newstate;
523
524         ieee80211_amrr_init(&ivp->iv_amrr, vap,
525             IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
526             IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
527             500 /*ms*/);
528
529         /* complete setup */
530         ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
531         ic->ic_opmode = opmode;
532         return vap;
533 }
534
535 static void
536 iwn_vap_delete(struct ieee80211vap *vap)
537 {
538         struct iwn_vap *ivp = IWN_VAP(vap);
539
540         ieee80211_amrr_cleanup(&ivp->iv_amrr);
541         ieee80211_vap_detach(vap);
542         free(ivp, M_80211_VAP);
543 }
544
545 static int
546 iwn_shutdown(device_t dev)
547 {
548         struct iwn_softc *sc = device_get_softc(dev);
549
550         iwn_stop(sc);
551         return 0;
552 }
553
554 static int
555 iwn_suspend(device_t dev)
556 {
557         struct iwn_softc *sc = device_get_softc(dev);
558
559         iwn_stop(sc);
560         return 0;
561 }
562
563 static int
564 iwn_resume(device_t dev)
565 {
566         struct iwn_softc *sc = device_get_softc(dev);
567         struct ifnet *ifp = sc->sc_ifp;
568
569         pci_write_config(dev, 0x41, 0, 1);
570
571         if (ifp->if_flags & IFF_UP)
572                 iwn_init(sc);
573         return 0;
574 }
575
576 static void
577 iwn_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
578 {
579         if (error != 0)
580                 return;
581         KASSERT(nsegs == 1, ("too many DMA segments, %d should be 1", nsegs));
582         *(bus_addr_t *)arg = segs[0].ds_addr;
583 }
584
585 static int 
586 iwn_dma_contig_alloc(struct iwn_softc *sc, struct iwn_dma_info *dma,
587         void **kvap, bus_size_t size, bus_size_t alignment, int flags)
588 {
589         int error, lalignment, i;
590
591         /*
592          * FreeBSD can't guarrenty 16k alignment at the moment (11/2007) so
593          * we allocate an extra 12k with 4k alignement and walk through
594          * it trying to find where the alignment is. It's a nasty fix for
595          * a bigger problem.
596         */
597         DPRINTF(sc, IWN_DEBUG_RESET,
598             "Size: %zd - alignment %zd\n", size, alignment);
599         if (alignment == 0x4000) {
600                 size += 12*1024;
601                 lalignment = 4096;
602                 DPRINTF(sc, IWN_DEBUG_RESET, "%s\n",
603                     "Attempting to find a 16k boundary");
604         } else
605                 lalignment = alignment;
606         dma->size = size;
607         dma->tag = NULL;
608
609         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), lalignment,
610             0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size,
611             1, size, flags, NULL, NULL, &dma->tag);
612         if (error != 0) {
613                 device_printf(sc->sc_dev,
614                     "%s: bus_dma_tag_create failed, error %d\n",
615                     __func__, error);
616                 goto fail;
617         }
618         error = bus_dmamem_alloc(dma->tag, (void **)&dma->vaddr,
619             flags | BUS_DMA_ZERO, &dma->map);
620         if (error != 0) {
621                 device_printf(sc->sc_dev,
622                    "%s: bus_dmamem_alloc failed, error %d\n",
623                    __func__, error);
624                 goto fail;
625         }
626         if (alignment == 0x4000) {
627                 for (i = 0; i < 3 && (((uintptr_t)dma->vaddr) & 0x3fff); i++) {
628                         DPRINTF(sc, IWN_DEBUG_RESET,  "%s\n",
629                             "Memory Unaligned, shifting pointer by 4k");
630                         dma->vaddr += 4096;
631                         size -= 4096;
632                 }
633                 if ((((uintptr_t)dma->vaddr ) & (alignment-1))) {
634                         DPRINTF(sc, IWN_DEBUG_ANY,
635                             "%s: failed to align memory, vaddr %p, align %zd\n",
636                             __func__, dma->vaddr, alignment);
637                         error = ENOMEM;
638                         goto fail;
639                 }
640         }
641
642         error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr,
643             size, iwn_dma_map_addr, &dma->paddr, flags);
644         if (error != 0) {
645                 device_printf(sc->sc_dev,
646                     "%s: bus_dmamap_load failed, error %d\n", __func__, error);
647                 goto fail;
648         }
649
650         if (kvap != NULL)
651                 *kvap = dma->vaddr;
652         return 0;
653 fail:
654         iwn_dma_contig_free(dma);
655         return error;
656 }
657
658 static void
659 iwn_dma_contig_free(struct iwn_dma_info *dma)
660 {
661         if (dma->tag != NULL) {
662                 if (dma->map != NULL) {
663                         if (dma->paddr == 0) {
664                                 bus_dmamap_sync(dma->tag, dma->map,
665                                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
666                                 bus_dmamap_unload(dma->tag, dma->map);
667                         }
668                         bus_dmamem_free(dma->tag, &dma->vaddr, dma->map);
669                 }
670                 bus_dma_tag_destroy(dma->tag);
671         }
672 }
673
674 int
675 iwn_alloc_shared(struct iwn_softc *sc)
676 {
677         /* must be aligned on a 1KB boundary */
678         return iwn_dma_contig_alloc(sc, &sc->shared_dma,
679             (void **)&sc->shared, sizeof (struct iwn_shared), 1024,
680             BUS_DMA_NOWAIT);
681 }
682
683 void
684 iwn_free_shared(struct iwn_softc *sc)
685 {
686         iwn_dma_contig_free(&sc->shared_dma);
687 }
688
689 int
690 iwn_alloc_kw(struct iwn_softc *sc)
691 {
692         /* must be aligned on a 4k boundary */
693         return iwn_dma_contig_alloc(sc, &sc->kw_dma, NULL,
694             PAGE_SIZE, PAGE_SIZE, BUS_DMA_NOWAIT);
695 }
696
697 void
698 iwn_free_kw(struct iwn_softc *sc)
699 {
700         iwn_dma_contig_free(&sc->kw_dma);
701 }
702
703 int
704 iwn_alloc_fwmem(struct iwn_softc *sc)
705 {
706         /* allocate enough contiguous space to store text and data */
707         return iwn_dma_contig_alloc(sc, &sc->fw_dma, NULL,
708             IWN_FW_MAIN_TEXT_MAXSZ + IWN_FW_MAIN_DATA_MAXSZ, 16,
709             BUS_DMA_NOWAIT);
710 }
711
712 void
713 iwn_free_fwmem(struct iwn_softc *sc)
714 {
715         iwn_dma_contig_free(&sc->fw_dma);
716 }
717
718 int
719 iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
720 {
721         int i, error;
722
723         ring->cur = 0;
724
725         error = iwn_dma_contig_alloc(sc, &ring->desc_dma,
726             (void **)&ring->desc, IWN_RX_RING_COUNT * sizeof (uint32_t),
727             IWN_RING_DMA_ALIGN, BUS_DMA_NOWAIT);
728         if (error != 0) {
729                 device_printf(sc->sc_dev,
730                     "%s: could not allocate rx ring DMA memory, error %d\n",
731                     __func__, error);
732                 goto fail;
733         }
734
735         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 
736             BUS_SPACE_MAXADDR_32BIT,
737             BUS_SPACE_MAXADDR, NULL, NULL, MJUMPAGESIZE, 1,
738             MJUMPAGESIZE, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat);
739         if (error != 0) {
740                 device_printf(sc->sc_dev,
741                     "%s: bus_dma_tag_create_failed, error %d\n",
742                     __func__, error);
743                 goto fail;
744         }
745
746         /*
747          * Setup Rx buffers.
748          */
749         for (i = 0; i < IWN_RX_RING_COUNT; i++) {
750                 struct iwn_rx_data *data = &ring->data[i];
751                 struct mbuf *m;
752                 bus_addr_t paddr;
753
754                 error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
755                 if (error != 0) {
756                         device_printf(sc->sc_dev,
757                             "%s: bus_dmamap_create failed, error %d\n",
758                             __func__, error);
759                         goto fail;
760                 }
761                 m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
762                 if (m == NULL) {
763                         device_printf(sc->sc_dev,
764                            "%s: could not allocate rx mbuf\n", __func__);
765                         error = ENOMEM;
766                         goto fail;
767                 }
768                 /* map page */
769                 error = bus_dmamap_load(ring->data_dmat, data->map,
770                     mtod(m, caddr_t), MJUMPAGESIZE,
771                     iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
772                 if (error != 0 && error != EFBIG) {
773                         device_printf(sc->sc_dev,
774                             "%s: bus_dmamap_load failed, error %d\n",
775                             __func__, error);
776                         m_freem(m);
777                         error = ENOMEM; /* XXX unique code */
778                         goto fail;
779                 }
780                 bus_dmamap_sync(ring->data_dmat, data->map, 
781                     BUS_DMASYNC_PREWRITE);
782
783                 data->m = m;
784                 /* Rx buffers are aligned on a 256-byte boundary */
785                 ring->desc[i] = htole32(paddr >> 8);
786         }
787         bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
788             BUS_DMASYNC_PREWRITE);
789         return 0;
790 fail:
791         iwn_free_rx_ring(sc, ring);
792         return error;
793 }
794
795 void
796 iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
797 {
798         int ntries;
799
800         iwn_mem_lock(sc);
801
802         IWN_WRITE(sc, IWN_RX_CONFIG, 0);
803         for (ntries = 0; ntries < 100; ntries++) {
804                 if (IWN_READ(sc, IWN_RX_STATUS) & IWN_RX_IDLE)
805                         break;
806                 DELAY(10);
807         }
808 #ifdef IWN_DEBUG
809         if (ntries == 100)
810                 DPRINTF(sc, IWN_DEBUG_ANY, "%s\n", "timeout resetting Rx ring");
811 #endif
812         iwn_mem_unlock(sc);
813
814         ring->cur = 0;
815 }
816
817 void
818 iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
819 {
820         int i;
821
822         iwn_dma_contig_free(&ring->desc_dma);
823
824         for (i = 0; i < IWN_RX_RING_COUNT; i++)
825                 if (ring->data[i].m != NULL)
826                         m_freem(ring->data[i].m);
827 }
828
829 int
830 iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)
831 {
832         bus_size_t size;
833         int i, error;
834
835         ring->qid = qid;
836         ring->queued = 0;
837         ring->cur = 0;
838
839         size = IWN_TX_RING_COUNT * sizeof(struct iwn_tx_desc);
840         error = iwn_dma_contig_alloc(sc, &ring->desc_dma,
841             (void **)&ring->desc, size, IWN_RING_DMA_ALIGN, BUS_DMA_NOWAIT);
842         if (error != 0) {
843                 device_printf(sc->sc_dev,
844                     "%s: could not allocate tx ring DMA memory, error %d\n",
845                     __func__, error);
846                 goto fail;
847         }
848
849         size = IWN_TX_RING_COUNT * sizeof(struct iwn_tx_cmd);
850         error = iwn_dma_contig_alloc(sc, &ring->cmd_dma,
851             (void **)&ring->cmd, size, 4, BUS_DMA_NOWAIT);
852         if (error != 0) {
853                 device_printf(sc->sc_dev,
854                     "%s: could not allocate tx cmd DMA memory, error %d\n",
855                     __func__, error);
856                 goto fail;
857         }
858
859         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 
860             BUS_SPACE_MAXADDR_32BIT,
861             BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, IWN_MAX_SCATTER - 1,
862             MCLBYTES, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat);
863         if (error != 0) {
864                 device_printf(sc->sc_dev,
865                     "%s: bus_dma_tag_create_failed, error %d\n",
866                     __func__, error);
867                 goto fail;
868         }
869
870         for (i = 0; i < IWN_TX_RING_COUNT; i++) {
871                 struct iwn_tx_data *data = &ring->data[i];
872
873                 error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
874                 if (error != 0) {
875                         device_printf(sc->sc_dev,
876                             "%s: bus_dmamap_create failed, error %d\n",
877                             __func__, error);
878                         goto fail;
879                 }
880                 bus_dmamap_sync(ring->data_dmat, data->map, 
881                     BUS_DMASYNC_PREWRITE);
882         }
883         return 0;
884 fail:
885         iwn_free_tx_ring(sc, ring);
886         return error;
887 }
888
889 void
890 iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
891 {
892         uint32_t tmp;
893         int i, ntries;
894
895         iwn_mem_lock(sc);
896
897         IWN_WRITE(sc, IWN_TX_CONFIG(ring->qid), 0);
898         for (ntries = 0; ntries < 20; ntries++) {
899                 tmp = IWN_READ(sc, IWN_TX_STATUS);
900                 if ((tmp & IWN_TX_IDLE(ring->qid)) == IWN_TX_IDLE(ring->qid))
901                         break;
902                 DELAY(10);
903         }
904 #ifdef IWN_DEBUG
905         if (ntries == 20)
906                 DPRINTF(sc, IWN_DEBUG_RESET,
907                     "%s: timeout resetting Tx ring %d\n", __func__, ring->qid);
908 #endif
909         iwn_mem_unlock(sc);
910
911         for (i = 0; i < IWN_TX_RING_COUNT; i++) {
912                 struct iwn_tx_data *data = &ring->data[i];
913
914                 if (data->m != NULL) {
915                         bus_dmamap_unload(ring->data_dmat, data->map);
916                         m_freem(data->m);
917                         data->m = NULL;
918                 }
919         }
920
921         ring->queued = 0;
922         ring->cur = 0;
923 }
924
925 void
926 iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
927 {
928         int i;
929
930         iwn_dma_contig_free(&ring->desc_dma);
931         iwn_dma_contig_free(&ring->cmd_dma);
932
933         if (ring->data != NULL) {
934                 for (i = 0; i < IWN_TX_RING_COUNT; i++) {
935                         struct iwn_tx_data *data = &ring->data[i];
936
937                         if (data->m != NULL) {
938                                 bus_dmamap_unload(ring->data_dmat, data->map);
939                                 m_freem(data->m);
940                         }
941                 }
942         }
943 }
944
945 struct ieee80211_node *
946 iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
947 {
948         return malloc(sizeof (struct iwn_node), M_80211_NODE,M_NOWAIT | M_ZERO);
949 }
950
951 void
952 iwn_newassoc(struct ieee80211_node *ni, int isnew)
953 {
954         struct ieee80211vap *vap = ni->ni_vap;
955
956         ieee80211_amrr_node_init(&IWN_VAP(vap)->iv_amrr,
957            &IWN_NODE(ni)->amn, ni);
958 }
959
960 int
961 iwn_media_change(struct ifnet *ifp)
962 {
963         int error = ieee80211_media_change(ifp);
964         /* NB: only the fixed rate can change and that doesn't need a reset */
965         return (error == ENETRESET ? 0 : error);
966 }
967
968 int
969 iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
970 {
971         struct iwn_vap *ivp = IWN_VAP(vap);
972         struct ieee80211com *ic = vap->iv_ic;
973         struct iwn_softc *sc = ic->ic_ifp->if_softc;
974         int error;
975
976         DPRINTF(sc, IWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
977                 ieee80211_state_name[vap->iv_state],
978                 ieee80211_state_name[nstate]);
979
980         IEEE80211_UNLOCK(ic);
981         IWN_LOCK(sc);
982         callout_stop(&sc->sc_timer_to);
983
984         if (nstate == IEEE80211_S_AUTH && vap->iv_state != IEEE80211_S_AUTH) {
985                 /* !AUTH -> AUTH requires adapter config */
986                 error = iwn_auth(sc, vap);
987         }
988         if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) {
989                 /*
990                  * !RUN -> RUN requires setting the association id
991                  * which is done with a firmware cmd.  We also defer
992                  * starting the timers until that work is done.
993                  */
994                 error = iwn_run(sc, vap);
995         }
996         if (nstate == IEEE80211_S_RUN) {
997                 /*
998                  * RUN -> RUN transition; just restart the timers.
999                  */
1000                 iwn_calib_reset(sc);
1001         }
1002         IWN_UNLOCK(sc);
1003         IEEE80211_LOCK(ic);
1004         return ivp->iv_newstate(vap, nstate, arg);
1005 }
1006
1007 /*
1008  * Grab exclusive access to NIC memory.
1009  */
1010 void
1011 iwn_mem_lock(struct iwn_softc *sc)
1012 {
1013         uint32_t tmp;
1014         int ntries;
1015
1016         tmp = IWN_READ(sc, IWN_GPIO_CTL);
1017         IWN_WRITE(sc, IWN_GPIO_CTL, tmp | IWN_GPIO_MAC);
1018
1019         /* spin until we actually get the lock */
1020         for (ntries = 0; ntries < 1000; ntries++) {
1021                 if ((IWN_READ(sc, IWN_GPIO_CTL) &
1022                     (IWN_GPIO_CLOCK | IWN_GPIO_SLEEP)) == IWN_GPIO_CLOCK)
1023                         break;
1024                 DELAY(10);
1025         }
1026         if (ntries == 1000)
1027                 device_printf(sc->sc_dev,
1028                     "%s: could not lock memory\n", __func__);
1029 }
1030
1031 /*
1032  * Release lock on NIC memory.
1033  */
1034 void
1035 iwn_mem_unlock(struct iwn_softc *sc)
1036 {
1037         uint32_t tmp = IWN_READ(sc, IWN_GPIO_CTL);
1038         IWN_WRITE(sc, IWN_GPIO_CTL, tmp & ~IWN_GPIO_MAC);
1039 }
1040
1041 uint32_t
1042 iwn_mem_read(struct iwn_softc *sc, uint32_t addr)
1043 {
1044         IWN_WRITE(sc, IWN_READ_MEM_ADDR, IWN_MEM_4 | addr);
1045         return IWN_READ(sc, IWN_READ_MEM_DATA);
1046 }
1047
1048 void
1049 iwn_mem_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
1050 {
1051         IWN_WRITE(sc, IWN_WRITE_MEM_ADDR, IWN_MEM_4 | addr);
1052         IWN_WRITE(sc, IWN_WRITE_MEM_DATA, data);
1053 }
1054
1055 void
1056 iwn_mem_write_region_4(struct iwn_softc *sc, uint32_t addr,
1057     const uint32_t *data, int wlen)
1058 {
1059         for (; wlen > 0; wlen--, data++, addr += 4)
1060                 iwn_mem_write(sc, addr, *data);
1061 }
1062
1063 int
1064 iwn_eeprom_lock(struct iwn_softc *sc)
1065 {
1066         uint32_t tmp;
1067         int ntries;
1068
1069         tmp = IWN_READ(sc, IWN_HWCONFIG);
1070         IWN_WRITE(sc, IWN_HWCONFIG, tmp | IWN_HW_EEPROM_LOCKED);
1071
1072         /* spin until we actually get the lock */
1073         for (ntries = 0; ntries < 100; ntries++) {
1074                 if (IWN_READ(sc, IWN_HWCONFIG) & IWN_HW_EEPROM_LOCKED)
1075                         return 0;
1076                 DELAY(10);
1077         }
1078         return ETIMEDOUT;
1079 }
1080
1081 void
1082 iwn_eeprom_unlock(struct iwn_softc *sc)
1083 {
1084         uint32_t tmp = IWN_READ(sc, IWN_HWCONFIG);
1085         IWN_WRITE(sc, IWN_HWCONFIG, tmp & ~IWN_HW_EEPROM_LOCKED);
1086 }
1087
1088 /*
1089  * Read `len' bytes from the EEPROM.  We access the EEPROM through the MAC
1090  * instead of using the traditional bit-bang method.
1091  */
1092 int
1093 iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int len)
1094 {
1095         uint8_t *out = data;
1096         uint32_t val;
1097         int ntries, tmp;
1098
1099         iwn_mem_lock(sc);
1100         for (; len > 0; len -= 2, addr++) {
1101                 IWN_WRITE(sc, IWN_EEPROM_CTL, addr << 2);
1102                 tmp = IWN_READ(sc, IWN_EEPROM_CTL);     
1103                 IWN_WRITE(sc, IWN_EEPROM_CTL, tmp & ~IWN_EEPROM_MSK );
1104
1105                 for (ntries = 0; ntries < 10; ntries++) {
1106                         if ((val = IWN_READ(sc, IWN_EEPROM_CTL)) &
1107                             IWN_EEPROM_READY)
1108                                 break;
1109                         DELAY(5);
1110                 }
1111                 if (ntries == 10) {
1112                         device_printf(sc->sc_dev,"could not read EEPROM\n");
1113                         return ETIMEDOUT;
1114                 }
1115                 *out++ = val >> 16;
1116                 if (len > 1)
1117                         *out++ = val >> 24;
1118         }
1119         iwn_mem_unlock(sc);
1120
1121         return 0;
1122 }
1123
1124 /*
1125  * The firmware boot code is small and is intended to be copied directly into
1126  * the NIC internal memory.
1127  */
1128 int
1129 iwn_transfer_microcode(struct iwn_softc *sc, const uint8_t *ucode, int size)
1130 {
1131         int ntries;
1132
1133         size /= sizeof (uint32_t);
1134
1135         iwn_mem_lock(sc);
1136
1137         /* copy microcode image into NIC memory */
1138         iwn_mem_write_region_4(sc, IWN_MEM_UCODE_BASE,
1139             (const uint32_t *)ucode, size);
1140
1141         iwn_mem_write(sc, IWN_MEM_UCODE_SRC, 0);
1142         iwn_mem_write(sc, IWN_MEM_UCODE_DST, IWN_FW_TEXT);
1143         iwn_mem_write(sc, IWN_MEM_UCODE_SIZE, size);
1144
1145         /* run microcode */
1146         iwn_mem_write(sc, IWN_MEM_UCODE_CTL, IWN_UC_RUN);
1147
1148         /* wait for transfer to complete */
1149         for (ntries = 0; ntries < 1000; ntries++) {
1150                 if (!(iwn_mem_read(sc, IWN_MEM_UCODE_CTL) & IWN_UC_RUN))
1151                         break;
1152                 DELAY(10);
1153         }
1154         if (ntries == 1000) {
1155                 iwn_mem_unlock(sc);
1156                 device_printf(sc->sc_dev,
1157                     "%s: could not load boot firmware\n", __func__);
1158                 return ETIMEDOUT;
1159         }
1160         iwn_mem_write(sc, IWN_MEM_UCODE_CTL, IWN_UC_ENABLE);
1161
1162         iwn_mem_unlock(sc);
1163
1164         return 0;
1165 }
1166
1167 int
1168 iwn_load_firmware(struct iwn_softc *sc)
1169 {
1170         int error;
1171
1172         KASSERT(sc->fw_fp == NULL, ("firmware already loaded"));
1173
1174         IWN_UNLOCK(sc);
1175         /* load firmware image from disk */
1176         sc->fw_fp = firmware_get("iwnfw");
1177         if (sc->fw_fp == NULL) {
1178                 device_printf(sc->sc_dev,
1179                     "%s: could not load firmare image \"iwnfw\"\n", __func__);
1180                 error = EINVAL;
1181         } else
1182                 error = 0;
1183         IWN_LOCK(sc);
1184         return error;
1185 }
1186
1187 int
1188 iwn_transfer_firmware(struct iwn_softc *sc)
1189 {
1190         struct iwn_dma_info *dma = &sc->fw_dma;
1191         const struct iwn_firmware_hdr *hdr;
1192         const uint8_t *init_text, *init_data, *main_text, *main_data;
1193         const uint8_t *boot_text;
1194         uint32_t init_textsz, init_datasz, main_textsz, main_datasz;
1195         uint32_t boot_textsz;
1196         int error = 0;
1197         const struct firmware *fp = sc->fw_fp;
1198
1199         /* extract firmware header information */
1200         if (fp->datasize < sizeof (struct iwn_firmware_hdr)) {
1201                 device_printf(sc->sc_dev,
1202                     "%s: truncated firmware header: %zu bytes, expecting %zu\n",
1203                     __func__, fp->datasize, sizeof (struct iwn_firmware_hdr));
1204                 error = EINVAL;
1205                 goto fail;
1206         }
1207         hdr = (const struct iwn_firmware_hdr *)fp->data;
1208         main_textsz = le32toh(hdr->main_textsz);
1209         main_datasz = le32toh(hdr->main_datasz);
1210         init_textsz = le32toh(hdr->init_textsz);
1211         init_datasz = le32toh(hdr->init_datasz);
1212         boot_textsz = le32toh(hdr->boot_textsz);
1213
1214         /* sanity-check firmware segments sizes */
1215         if (main_textsz > IWN_FW_MAIN_TEXT_MAXSZ ||
1216             main_datasz > IWN_FW_MAIN_DATA_MAXSZ ||
1217             init_textsz > IWN_FW_INIT_TEXT_MAXSZ ||
1218             init_datasz > IWN_FW_INIT_DATA_MAXSZ ||
1219             boot_textsz > IWN_FW_BOOT_TEXT_MAXSZ ||
1220             (boot_textsz & 3) != 0) {
1221                 device_printf(sc->sc_dev,
1222                     "%s: invalid firmware header, main [%d,%d], init [%d,%d] "
1223                     "boot %d\n", __func__, main_textsz, main_datasz,
1224                     init_textsz, init_datasz, boot_textsz);
1225                 error = EINVAL;
1226                 goto fail;
1227         }
1228
1229         /* check that all firmware segments are present */
1230         if (fp->datasize < sizeof (struct iwn_firmware_hdr) + main_textsz +
1231             main_datasz + init_textsz + init_datasz + boot_textsz) {
1232                 device_printf(sc->sc_dev, "%s: firmware file too short: "
1233                     "%zu bytes, main [%d, %d], init [%d,%d] boot %d\n",
1234                     __func__, fp->datasize, main_textsz, main_datasz,
1235                     init_textsz, init_datasz, boot_textsz);
1236                 error = EINVAL;
1237                 goto fail;
1238         }
1239
1240         /* get pointers to firmware segments */
1241         main_text = (const uint8_t *)(hdr + 1);
1242         main_data = main_text + main_textsz;
1243         init_text = main_data + main_datasz;
1244         init_data = init_text + init_textsz;
1245         boot_text = init_data + init_datasz;
1246
1247         /* copy initialization images into pre-allocated DMA-safe memory */
1248         memcpy(dma->vaddr, init_data, init_datasz);
1249         memcpy(dma->vaddr + IWN_FW_INIT_DATA_MAXSZ, init_text, init_textsz);
1250
1251         /* tell adapter where to find initialization images */
1252         iwn_mem_lock(sc);
1253         iwn_mem_write(sc, IWN_MEM_DATA_BASE, dma->paddr >> 4);
1254         iwn_mem_write(sc, IWN_MEM_DATA_SIZE, init_datasz);
1255         iwn_mem_write(sc, IWN_MEM_TEXT_BASE,
1256             (dma->paddr + IWN_FW_INIT_DATA_MAXSZ) >> 4);
1257         iwn_mem_write(sc, IWN_MEM_TEXT_SIZE, init_textsz);
1258         iwn_mem_unlock(sc);
1259
1260         /* load firmware boot code */
1261         error = iwn_transfer_microcode(sc, boot_text, boot_textsz);
1262         if (error != 0) {
1263                 device_printf(sc->sc_dev,
1264                     "%s: could not load boot firmware, error %d\n",
1265                     __func__, error);
1266                 goto fail;
1267         }
1268
1269         /* now press "execute" ;-) */
1270         IWN_WRITE(sc, IWN_RESET, 0);
1271
1272         /* wait at most one second for first alive notification */
1273         error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
1274         if (error != 0) {
1275                 /* this isn't what was supposed to happen.. */
1276                 device_printf(sc->sc_dev,
1277                     "%s: timeout waiting for first alive notice, error %d\n",
1278                     __func__, error);
1279                 goto fail;
1280         }
1281
1282         /* copy runtime images into pre-allocated DMA-safe memory */
1283         memcpy(dma->vaddr, main_data, main_datasz);
1284         memcpy(dma->vaddr + IWN_FW_MAIN_DATA_MAXSZ, main_text, main_textsz);
1285
1286         /* tell adapter where to find runtime images */
1287         iwn_mem_lock(sc);
1288         iwn_mem_write(sc, IWN_MEM_DATA_BASE, dma->paddr >> 4);
1289         iwn_mem_write(sc, IWN_MEM_DATA_SIZE, main_datasz);
1290         iwn_mem_write(sc, IWN_MEM_TEXT_BASE,
1291             (dma->paddr + IWN_FW_MAIN_DATA_MAXSZ) >> 4);
1292         iwn_mem_write(sc, IWN_MEM_TEXT_SIZE, IWN_FW_UPDATED | main_textsz);
1293         iwn_mem_unlock(sc);
1294
1295         /* wait at most one second for second alive notification */
1296         error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
1297         if (error != 0) {
1298                 /* this isn't what was supposed to happen.. */
1299                 device_printf(sc->sc_dev,
1300                    "%s: timeout waiting for second alive notice, error %d\n",
1301                    __func__, error);
1302                 goto fail;
1303         }
1304         return 0;
1305 fail:
1306         return error;
1307 }
1308
1309 void
1310 iwn_unload_firmware(struct iwn_softc *sc)
1311 {
1312         if (sc->fw_fp != NULL) {
1313                 firmware_put(sc->fw_fp, FIRMWARE_UNLOAD);
1314                 sc->fw_fp = NULL;
1315         }
1316 }
1317
1318 static void
1319 iwn_timer_timeout(void *arg)
1320 {
1321         struct iwn_softc *sc = arg;
1322
1323         IWN_LOCK_ASSERT(sc);
1324
1325         if (sc->calib_cnt && --sc->calib_cnt == 0) {
1326                 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s\n",
1327                     "send statistics request");
1328                 (void) iwn_cmd(sc, IWN_CMD_GET_STATISTICS, NULL, 0, 1);
1329                 sc->calib_cnt = 60;     /* do calibration every 60s */
1330         }
1331         iwn_watchdog(sc);               /* NB: piggyback tx watchdog */
1332         callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
1333 }
1334
1335 static void
1336 iwn_calib_reset(struct iwn_softc *sc)
1337 {
1338         callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
1339         sc->calib_cnt = 60;             /* do calibration every 60s */
1340 }
1341
1342 void
1343 iwn_ampdu_rx_start(struct iwn_softc *sc, struct iwn_rx_desc *desc)
1344 {
1345         struct iwn_rx_stat *stat;
1346
1347         DPRINTF(sc, IWN_DEBUG_RECV, "%s\n", "received AMPDU stats");
1348         /* save Rx statistics, they will be used on IWN_AMPDU_RX_DONE */
1349         stat = (struct iwn_rx_stat *)(desc + 1);
1350         memcpy(&sc->last_rx_stat, stat, sizeof (*stat));
1351         sc->last_rx_valid = 1;
1352 }
1353
1354 static __inline int
1355 maprate(int iwnrate)
1356 {
1357         switch (iwnrate) {
1358         /* CCK rates */
1359         case  10: return   2;
1360         case  20: return   4;
1361         case  55: return  11;
1362         case 110: return  22;
1363         /* OFDM rates */
1364         case 0xd: return  12;
1365         case 0xf: return  18;
1366         case 0x5: return  24;
1367         case 0x7: return  36;
1368         case 0x9: return  48;
1369         case 0xb: return  72;
1370         case 0x1: return  96;
1371         case 0x3: return 108;
1372         /* XXX MCS */
1373         }
1374         /* unknown rate: should not happen */
1375         return 0;
1376 }
1377
1378 void
1379 iwn_rx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc,
1380     struct iwn_rx_data *data)
1381 {
1382         struct ifnet *ifp = sc->sc_ifp;
1383         struct ieee80211com *ic = ifp->if_l2com;
1384         struct iwn_rx_ring *ring = &sc->rxq;
1385         struct ieee80211_frame *wh;
1386         struct ieee80211_node *ni;
1387         struct mbuf *m, *mnew;
1388         struct iwn_rx_stat *stat;
1389         caddr_t head;
1390         uint32_t *tail;
1391         int8_t rssi, nf;
1392         int len, error;
1393         bus_addr_t paddr;
1394
1395         if (desc->type == IWN_AMPDU_RX_DONE) {
1396                 /* check for prior AMPDU_RX_START */
1397                 if (!sc->last_rx_valid) {
1398                         DPRINTF(sc, IWN_DEBUG_ANY,
1399                             "%s: missing AMPDU_RX_START\n", __func__);
1400                         ifp->if_ierrors++;
1401                         return;
1402                 }
1403                 sc->last_rx_valid = 0;
1404                 stat = &sc->last_rx_stat;
1405         } else
1406                 stat = (struct iwn_rx_stat *)(desc + 1);
1407
1408         if (stat->cfg_phy_len > IWN_STAT_MAXLEN) {
1409                 device_printf(sc->sc_dev,
1410                     "%s: invalid rx statistic header, len %d\n",
1411                     __func__, stat->cfg_phy_len);
1412                 ifp->if_ierrors++;
1413                 return;
1414         }
1415         if (desc->type == IWN_AMPDU_RX_DONE) {
1416                 struct iwn_rx_ampdu *ampdu = (struct iwn_rx_ampdu *)(desc + 1);
1417                 head = (caddr_t)(ampdu + 1);
1418                 len = le16toh(ampdu->len);
1419         } else {
1420                 head = (caddr_t)(stat + 1) + stat->cfg_phy_len;
1421                 len = le16toh(stat->len);
1422         }
1423
1424         /* discard Rx frames with bad CRC early */
1425         tail = (uint32_t *)(head + len);
1426         if ((le32toh(*tail) & IWN_RX_NOERROR) != IWN_RX_NOERROR) {
1427                 DPRINTF(sc, IWN_DEBUG_RECV, "%s: rx flags error %x\n",
1428                     __func__, le32toh(*tail));
1429                 ifp->if_ierrors++;
1430                 return;
1431         }
1432         if (len < sizeof (struct ieee80211_frame)) {
1433                 DPRINTF(sc, IWN_DEBUG_RECV, "%s: frame too short: %d\n",
1434                     __func__, len);
1435                 ifp->if_ierrors++;
1436                 return;
1437         }
1438
1439         /* XXX don't need mbuf, just dma buffer */
1440         mnew = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
1441         if (mnew == NULL) {
1442                 DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n",
1443                     __func__);
1444                 ifp->if_ierrors++;
1445                 return;
1446         }
1447         error = bus_dmamap_load(ring->data_dmat, data->map,
1448             mtod(mnew, caddr_t), MJUMPAGESIZE,
1449             iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
1450         if (error != 0 && error != EFBIG) {
1451                 device_printf(sc->sc_dev,
1452                     "%s: bus_dmamap_load failed, error %d\n", __func__, error);
1453                 m_freem(mnew);
1454                 ifp->if_ierrors++;
1455                 return;
1456         }
1457         bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
1458
1459         /* finalize mbuf and swap in new one */
1460         m = data->m;
1461         m->m_pkthdr.rcvif = ifp;
1462         m->m_data = head;
1463         m->m_pkthdr.len = m->m_len = len;
1464
1465         data->m = mnew;
1466         /* update Rx descriptor */
1467         ring->desc[ring->cur] = htole32(paddr >> 8);
1468
1469         rssi = iwn_get_rssi(sc, stat);
1470
1471         /* grab a reference to the source node */
1472         wh = mtod(m, struct ieee80211_frame *);
1473         ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
1474
1475         nf = (ni != NULL && ni->ni_vap->iv_state == IEEE80211_S_RUN &&
1476             (ic->ic_flags & IEEE80211_F_SCAN) == 0) ? sc->noise : -95;
1477
1478         if (ieee80211_radiotap_active(ic)) {
1479                 struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
1480
1481                 tap->wr_tsft = htole64(stat->tstamp);
1482                 tap->wr_flags = 0;
1483                 if (stat->flags & htole16(IWN_CONFIG_SHPREAMBLE))
1484                         tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
1485                 tap->wr_rate = maprate(stat->rate);
1486                 tap->wr_dbm_antsignal = rssi;
1487                 tap->wr_dbm_antnoise = nf;
1488         }
1489
1490         IWN_UNLOCK(sc);
1491
1492         /* send the frame to the 802.11 layer */
1493         if (ni != NULL) {
1494                 (void) ieee80211_input(ni, m, rssi - nf, nf);
1495                 ieee80211_free_node(ni);
1496         } else
1497                 (void) ieee80211_input_all(ic, m, rssi - nf, nf);
1498
1499         IWN_LOCK(sc);
1500 }
1501
1502 void
1503 iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc)
1504 {
1505         struct ifnet *ifp = sc->sc_ifp;
1506         struct ieee80211com *ic = ifp->if_l2com;
1507         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1508         struct iwn_calib_state *calib = &sc->calib;
1509         struct iwn_stats *stats = (struct iwn_stats *)(desc + 1);
1510
1511         /* beacon stats are meaningful only when associated and not scanning */
1512         if (vap->iv_state != IEEE80211_S_RUN ||
1513             (ic->ic_flags & IEEE80211_F_SCAN))
1514                 return;
1515
1516         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: cmd %d\n", __func__, desc->type);
1517         iwn_calib_reset(sc);
1518
1519         /* test if temperature has changed */
1520         if (stats->general.temp != sc->rawtemp) {
1521                 int temp;
1522
1523                 sc->rawtemp = stats->general.temp;
1524                 temp = iwn_get_temperature(sc);
1525                 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d\n",
1526                     __func__, temp);
1527
1528                 /* update Tx power if need be */
1529                 iwn_power_calibration(sc, temp);
1530         }
1531
1532         if (desc->type != IWN_BEACON_STATISTICS)
1533                 return; /* reply to a statistics request */
1534
1535         sc->noise = iwn_get_noise(&stats->rx.general);
1536         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: noise %d\n", __func__, sc->noise);
1537
1538         /* test that RSSI and noise are present in stats report */
1539         if (stats->rx.general.flags != htole32(1)) {
1540                 DPRINTF(sc, IWN_DEBUG_ANY, "%s\n",
1541                     "received statistics without RSSI");
1542                 return;
1543         }
1544
1545         if (calib->state == IWN_CALIB_STATE_ASSOC)
1546                 iwn_compute_differential_gain(sc, &stats->rx.general);
1547         else if (calib->state == IWN_CALIB_STATE_RUN)
1548                 iwn_tune_sensitivity(sc, &stats->rx);
1549 }
1550
1551 void
1552 iwn_tx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc)
1553 {
1554         struct ifnet *ifp = sc->sc_ifp;
1555         struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
1556         struct iwn_tx_data *data = &ring->data[desc->idx];
1557         struct iwn_tx_stat *stat = (struct iwn_tx_stat *)(desc + 1);
1558         struct iwn_node *wn = IWN_NODE(data->ni);
1559         struct mbuf *m;
1560         struct ieee80211_node *ni;
1561         uint32_t status;
1562
1563         KASSERT(data->ni != NULL, ("no node"));
1564
1565         DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
1566             "qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
1567             __func__, desc->qid, desc->idx, stat->ntries,
1568             stat->nkill, stat->rate, le16toh(stat->duration),
1569             le32toh(stat->status));
1570
1571         /*
1572          * Update rate control statistics for the node.
1573          */
1574         status = le32toh(stat->status) & 0xff;
1575         if (status & 0x80) {
1576                 DPRINTF(sc, IWN_DEBUG_ANY, "%s: status 0x%x\n",
1577                     __func__, le32toh(stat->status));
1578                 ifp->if_oerrors++;
1579                 ieee80211_amrr_tx_complete(&wn->amn,
1580                     IEEE80211_AMRR_FAILURE, stat->ntries);
1581         } else {
1582                 ieee80211_amrr_tx_complete(&wn->amn,
1583                     IEEE80211_AMRR_SUCCESS, stat->ntries);
1584         }
1585
1586         bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTWRITE);
1587         bus_dmamap_unload(ring->data_dmat, data->map);
1588
1589         m = data->m, data->m = NULL;
1590         ni = data->ni, data->ni = NULL;
1591
1592         if (m->m_flags & M_TXCB) {
1593                 /*
1594                  * Channels marked for "radar" require traffic to be received
1595                  * to unlock before we can transmit.  Until traffic is seen
1596                  * any attempt to transmit is returned immediately with status
1597                  * set to IWN_TX_FAIL_TX_LOCKED.  Unfortunately this can easily
1598                  * happen on first authenticate after scanning.  To workaround
1599                  * this we ignore a failure of this sort in AUTH state so the
1600                  * 802.11 layer will fall back to using a timeout to wait for
1601                  * the AUTH reply.  This allows the firmware time to see
1602                  * traffic so a subsequent retry of AUTH succeeds.  It's
1603                  * unclear why the firmware does not maintain state for
1604                  * channels recently visited as this would allow immediate
1605                  * use of the channel after a scan (where we see traffic).
1606                  */
1607                 if (status == IWN_TX_FAIL_TX_LOCKED &&
1608                     ni->ni_vap->iv_state == IEEE80211_S_AUTH)
1609                         ieee80211_process_callback(ni, m, 0);
1610                 else
1611                         ieee80211_process_callback(ni, m,
1612                             (status & IWN_TX_FAIL) != 0);
1613         }
1614         m_freem(m);
1615         ieee80211_free_node(ni);
1616
1617         ring->queued--;
1618
1619         sc->sc_tx_timer = 0;
1620         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1621         iwn_start_locked(ifp);
1622 }
1623
1624 void
1625 iwn_cmd_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc)
1626 {
1627         struct iwn_tx_ring *ring = &sc->txq[4];
1628         struct iwn_tx_data *data;
1629
1630         if ((desc->qid & 0xf) != 4)
1631                 return; /* not a command ack */
1632
1633         data = &ring->data[desc->idx];
1634
1635         /* if the command was mapped in a mbuf, free it */
1636         if (data->m != NULL) {
1637                 bus_dmamap_unload(ring->data_dmat, data->map);
1638                 m_freem(data->m);
1639                 data->m = NULL;
1640         }
1641
1642         wakeup(&ring->cmd[desc->idx]);
1643 }
1644
1645 void
1646 iwn_notif_intr(struct iwn_softc *sc)
1647 {
1648         struct ifnet *ifp = sc->sc_ifp;
1649         struct ieee80211com *ic = ifp->if_l2com;
1650         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1651         uint16_t hw;
1652
1653         hw = le16toh(sc->shared->closed_count) & 0xfff;
1654         while (sc->rxq.cur != hw) {
1655                 struct iwn_rx_data *data = &sc->rxq.data[sc->rxq.cur];
1656                 struct iwn_rx_desc *desc = (void *)data->m->m_ext.ext_buf;
1657
1658                 DPRINTF(sc, IWN_DEBUG_RECV,
1659                     "%s: qid %x idx %d flags %x type %d(%s) len %d\n",
1660                     __func__, desc->qid, desc->idx, desc->flags,
1661                     desc->type, iwn_intr_str(desc->type),
1662                     le16toh(desc->len));
1663
1664                 if (!(desc->qid & 0x80))        /* reply to a command */
1665                         iwn_cmd_intr(sc, desc);
1666
1667                 switch (desc->type) {
1668                 case IWN_RX_DONE:
1669                 case IWN_AMPDU_RX_DONE:
1670                         iwn_rx_intr(sc, desc, data);
1671                         break;
1672
1673                 case IWN_AMPDU_RX_START:
1674                         iwn_ampdu_rx_start(sc, desc);
1675                         break;
1676
1677                 case IWN_TX_DONE:
1678                         /* a 802.11 frame has been transmitted */
1679                         iwn_tx_intr(sc, desc);
1680                         break;
1681
1682                 case IWN_RX_STATISTICS:
1683                 case IWN_BEACON_STATISTICS:
1684                         iwn_rx_statistics(sc, desc);
1685                         break;
1686
1687                 case IWN_BEACON_MISSED: {
1688                         struct iwn_beacon_missed *miss =
1689                             (struct iwn_beacon_missed *)(desc + 1);
1690                         int misses = le32toh(miss->consecutive);
1691
1692                         /* XXX not sure why we're notified w/ zero */
1693                         if (misses == 0)
1694                                 break;
1695                         DPRINTF(sc, IWN_DEBUG_STATE,
1696                             "%s: beacons missed %d/%d\n", __func__,
1697                             misses, le32toh(miss->total));
1698                         /*
1699                          * If more than 5 consecutive beacons are missed,
1700                          * reinitialize the sensitivity state machine.
1701                          */
1702                         if (vap->iv_state == IEEE80211_S_RUN && misses > 5)
1703                                 (void) iwn_init_sensitivity(sc);
1704                         if (misses >= vap->iv_bmissthreshold)
1705                                 ieee80211_beacon_miss(ic);
1706                         break;
1707                 }
1708                 case IWN_UC_READY: {
1709                         struct iwn_ucode_info *uc =
1710                             (struct iwn_ucode_info *)(desc + 1);
1711
1712                         /* the microcontroller is ready */
1713                         DPRINTF(sc, IWN_DEBUG_RESET,
1714                             "microcode alive notification version=%d.%d "
1715                             "subtype=%x alive=%x\n", uc->major, uc->minor,
1716                             uc->subtype, le32toh(uc->valid));
1717
1718                         if (le32toh(uc->valid) != 1) {
1719                                 device_printf(sc->sc_dev,
1720                                 "microcontroller initialization failed");
1721                                 break;
1722                         }
1723                         if (uc->subtype == IWN_UCODE_INIT) {
1724                                 /* save microcontroller's report */
1725                                 memcpy(&sc->ucode_info, uc, sizeof (*uc));
1726                         }
1727                         break;
1728                 }
1729                 case IWN_STATE_CHANGED: {
1730                         uint32_t *status = (uint32_t *)(desc + 1);
1731
1732                         /*
1733                          * State change allows hardware switch change to be
1734                          * noted. However, we handle this in iwn_intr as we
1735                          * get both the enable/disble intr.
1736                          */
1737                         DPRINTF(sc, IWN_DEBUG_INTR, "state changed to %x\n",
1738                             le32toh(*status));
1739                         break;
1740                 }
1741                 case IWN_START_SCAN: {
1742                         struct iwn_start_scan *scan =
1743                             (struct iwn_start_scan *)(desc + 1);
1744
1745                         DPRINTF(sc, IWN_DEBUG_ANY,
1746                             "%s: scanning channel %d status %x\n",
1747                             __func__, scan->chan, le32toh(scan->status));
1748                         break;
1749                 }
1750                 case IWN_STOP_SCAN: {
1751                         struct iwn_stop_scan *scan =
1752                             (struct iwn_stop_scan *)(desc + 1);
1753
1754                         DPRINTF(sc, IWN_DEBUG_STATE,
1755                             "scan finished nchan=%d status=%d chan=%d\n",
1756                             scan->nchan, scan->status, scan->chan);
1757
1758                         ieee80211_scan_next(vap);
1759                         break;
1760                 }
1761                 }
1762                 sc->rxq.cur = (sc->rxq.cur + 1) % IWN_RX_RING_COUNT;
1763         }
1764
1765         /* tell the firmware what we have processed */
1766         hw = (hw == 0) ? IWN_RX_RING_COUNT - 1 : hw - 1;
1767         IWN_WRITE(sc, IWN_RX_WIDX, hw & ~7);
1768 }
1769
1770 static void
1771 iwn_rftoggle_intr(struct iwn_softc *sc)
1772 {
1773         struct ifnet *ifp = sc->sc_ifp;
1774         struct ieee80211com *ic = ifp->if_l2com;
1775         uint32_t tmp = IWN_READ(sc, IWN_GPIO_CTL);
1776
1777         IWN_LOCK_ASSERT(sc);
1778
1779         device_printf(sc->sc_dev, "RF switch: radio %s\n",
1780             (tmp & IWN_GPIO_RF_ENABLED) ? "enabled" : "disabled");
1781         if (tmp & IWN_GPIO_RF_ENABLED)
1782                 ieee80211_runtask(ic, &sc->sc_radioon_task);
1783         else
1784                 ieee80211_runtask(ic, &sc->sc_radiooff_task);
1785 }
1786
1787 static void
1788 iwn_error_intr(struct iwn_softc *sc, uint32_t r1, uint32_t r2)
1789 {
1790         struct ifnet *ifp = sc->sc_ifp;
1791         struct ieee80211com *ic = ifp->if_l2com;
1792         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1793
1794         IWN_LOCK_ASSERT(sc);
1795
1796         device_printf(sc->sc_dev, "error, INTR=%b STATUS=0x%x\n",
1797             r1, IWN_INTR_BITS, r2);
1798         if (vap != NULL)
1799                 ieee80211_cancel_scan(vap);
1800         ieee80211_runtask(ic, &sc->sc_reinit_task);
1801 }
1802
1803 void
1804 iwn_intr(void *arg)
1805 {
1806         struct iwn_softc *sc = arg;
1807         uint32_t r1, r2;
1808
1809         IWN_LOCK(sc);
1810
1811         /* disable interrupts */
1812         IWN_WRITE(sc, IWN_MASK, 0);
1813
1814         r1 = IWN_READ(sc, IWN_INTR);
1815         r2 = IWN_READ(sc, IWN_INTR_STATUS);
1816
1817         if (r1 == 0 && r2 == 0) {
1818                 IWN_WRITE(sc, IWN_MASK, IWN_INTR_MASK);
1819                 goto done;      /* not for us */
1820         }
1821
1822         if (r1 == 0xffffffff)
1823                 goto done;      /* hardware gone */
1824
1825         /* ack interrupts */
1826         IWN_WRITE(sc, IWN_INTR, r1);
1827         IWN_WRITE(sc, IWN_INTR_STATUS, r2);
1828
1829         DPRINTF(sc, IWN_DEBUG_INTR, "interrupt reg1=%x reg2=%x\n", r1, r2);
1830
1831         if (r1 & IWN_RF_TOGGLED)
1832                 iwn_rftoggle_intr(sc);
1833         if (r1 & IWN_CT_REACHED)
1834                 device_printf(sc->sc_dev, "critical temperature reached!\n");
1835         if (r1 & (IWN_SW_ERROR | IWN_HW_ERROR)) {
1836                 iwn_error_intr(sc, r1, r2);
1837                 goto done;
1838         }
1839         if ((r1 & (IWN_RX_INTR | IWN_SW_RX_INTR)) || (r2 & IWN_RX_STATUS_INTR))
1840                 iwn_notif_intr(sc);
1841         if (r1 & IWN_ALIVE_INTR)
1842                 wakeup(sc);
1843
1844         /* re-enable interrupts */
1845         IWN_WRITE(sc, IWN_MASK, IWN_INTR_MASK);
1846 done:
1847         IWN_UNLOCK(sc);
1848 }
1849
1850 uint8_t
1851 iwn_plcp_signal(int rate)
1852 {
1853         switch (rate) {
1854         /* CCK rates (returned values are device-dependent) */
1855         case 2:         return 10;
1856         case 4:         return 20;
1857         case 11:        return 55;
1858         case 22:        return 110;
1859
1860         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
1861         /* R1-R4, (u)ral is R4-R1 */
1862         case 12:        return 0xd;
1863         case 18:        return 0xf;
1864         case 24:        return 0x5;
1865         case 36:        return 0x7;
1866         case 48:        return 0x9;
1867         case 72:        return 0xb;
1868         case 96:        return 0x1;
1869         case 108:       return 0x3;
1870         case 120:       return 0x3;
1871         }
1872         /* unknown rate (should not get there) */
1873         return 0;
1874 }
1875
1876 /* determine if a given rate is CCK or OFDM */
1877 #define IWN_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
1878
1879 int
1880 iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
1881     struct iwn_tx_ring *ring)
1882 {
1883         struct ieee80211vap *vap = ni->ni_vap;
1884         struct ieee80211com *ic = ni->ni_ic;
1885         struct ifnet *ifp = sc->sc_ifp;
1886         const struct ieee80211_txparam *tp;
1887         struct iwn_tx_desc *desc;
1888         struct iwn_tx_data *data;
1889         struct iwn_tx_cmd *cmd;
1890         struct iwn_cmd_data *tx;
1891         struct ieee80211_frame *wh;
1892         struct ieee80211_key *k;
1893         bus_addr_t paddr;
1894         uint32_t flags;
1895         uint16_t timeout;
1896         uint8_t type;
1897         u_int hdrlen;
1898         struct mbuf *mnew;
1899         int rate, error, pad, nsegs, i, ismcast, id;
1900         bus_dma_segment_t segs[IWN_MAX_SCATTER];
1901
1902         IWN_LOCK_ASSERT(sc);
1903
1904         wh = mtod(m0, struct ieee80211_frame *);
1905         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1906         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
1907         hdrlen = ieee80211_anyhdrsize(wh);
1908
1909         /* pick a tx rate */
1910         /* XXX ni_chan */
1911         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
1912         if (type == IEEE80211_FC0_TYPE_MGT)
1913                 rate = tp->mgmtrate;
1914         else if (ismcast)
1915                 rate = tp->mcastrate;
1916         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
1917                 rate = tp->ucastrate;
1918         else {
1919                 (void) ieee80211_amrr_choose(ni, &IWN_NODE(ni)->amn);
1920                 rate = ni->ni_txrate;
1921         }
1922
1923         if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1924                 k = ieee80211_crypto_encap(ni, m0);
1925                 if (k == NULL) {
1926                         m_freem(m0);
1927                         return ENOBUFS;
1928                 }
1929                 /* packet header may have moved, reset our local pointer */
1930                 wh = mtod(m0, struct ieee80211_frame *);
1931         } else
1932                 k = NULL;
1933
1934         if (ieee80211_radiotap_active_vap(vap)) {
1935                 struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
1936
1937                 tap->wt_flags = 0;
1938                 tap->wt_rate = rate;
1939                 if (k != NULL)
1940                         tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
1941
1942                 ieee80211_radiotap_tx(vap, m0);
1943         }
1944
1945         flags = IWN_TX_AUTO_SEQ;
1946         /* XXX honor ACM */
1947         if (!ismcast)
1948                 flags |= IWN_TX_NEED_ACK;
1949
1950         if (ismcast || type != IEEE80211_FC0_TYPE_DATA)
1951                 id = IWN_ID_BROADCAST;
1952         else
1953                 id = IWN_ID_BSS;
1954
1955         /* check if RTS/CTS or CTS-to-self protection must be used */
1956         if (!ismcast) {
1957                 /* multicast frames are not sent at OFDM rates in 802.11b/g */
1958                 if (m0->m_pkthdr.len+IEEE80211_CRC_LEN > vap->iv_rtsthreshold) {
1959                         flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
1960                 } else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
1961                     IWN_RATE_IS_OFDM(rate)) {
1962                         if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
1963                                 flags |= IWN_TX_NEED_CTS | IWN_TX_FULL_TXOP;
1964                         else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
1965                                 flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
1966                 }
1967         }
1968
1969         if (type == IEEE80211_FC0_TYPE_MGT) {
1970                 uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1971
1972                 /* tell h/w to set timestamp in probe responses */
1973                 if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1974                         flags |= IWN_TX_INSERT_TSTAMP;
1975
1976                 if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
1977                     subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
1978                         timeout = htole16(3);
1979                 else
1980                         timeout = htole16(2);
1981         } else
1982                 timeout = htole16(0);
1983
1984         if (hdrlen & 3) {
1985                 /* first segment's length must be a multiple of 4 */
1986                 flags |= IWN_TX_NEED_PADDING;
1987                 pad = 4 - (hdrlen & 3);
1988         } else
1989                 pad = 0;
1990
1991         desc = &ring->desc[ring->cur];
1992         data = &ring->data[ring->cur];
1993
1994         cmd = &ring->cmd[ring->cur];
1995         cmd->code = IWN_CMD_TX_DATA;
1996         cmd->flags = 0;
1997         cmd->qid = ring->qid;
1998         cmd->idx = ring->cur;
1999
2000         tx = (struct iwn_cmd_data *)cmd->data;
2001         /* NB: no need to bzero tx, all fields are reinitialized here */
2002         tx->id = id;
2003         tx->flags = htole32(flags);
2004         tx->len = htole16(m0->m_pkthdr.len);
2005         tx->rate = iwn_plcp_signal(rate);
2006         tx->rts_ntries = 60;            /* XXX? */
2007         tx->data_ntries = 15;           /* XXX? */
2008         tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
2009         tx->timeout = timeout;
2010
2011         if (k != NULL) {
2012                 /* XXX fill in */;
2013         } else
2014                 tx->security = 0;
2015
2016         /* XXX alternate between Ant A and Ant B ? */
2017         tx->rflags = IWN_RFLAG_ANT_B;
2018         if (tx->id == IWN_ID_BROADCAST) {
2019                 tx->ridx = IWN_MAX_TX_RETRIES - 1;
2020                 if (!IWN_RATE_IS_OFDM(rate))
2021                         tx->rflags |= IWN_RFLAG_CCK;
2022         } else {
2023                 tx->ridx = 0;
2024                 /* tell adapter to ignore rflags */
2025                 tx->flags |= htole32(IWN_TX_USE_NODE_RATE);
2026         }
2027
2028         /* copy and trim IEEE802.11 header */
2029         memcpy((uint8_t *)(tx + 1), wh, hdrlen);
2030         m_adj(m0, hdrlen);
2031
2032         error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m0, segs,
2033             &nsegs, BUS_DMA_NOWAIT);
2034         if (error != 0) {
2035                 if (error == EFBIG) {
2036                         /* too many fragments, linearize */
2037                         mnew = m_collapse(m0, M_DONTWAIT, IWN_MAX_SCATTER);
2038                         if (mnew == NULL) {
2039                                 IWN_UNLOCK(sc);
2040                                 device_printf(sc->sc_dev,
2041                                     "%s: could not defrag mbuf\n", __func__);
2042                                 m_freem(m0);
2043                                 return ENOBUFS;
2044                         }
2045                         m0 = mnew;
2046                         error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
2047                             data->map, m0, segs, &nsegs, BUS_DMA_NOWAIT);
2048                 }
2049                 if (error != 0) {
2050                         IWN_UNLOCK(sc);
2051                         device_printf(sc->sc_dev,
2052                             "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
2053                              __func__, error);
2054                         m_freem(m0);
2055                         return error;
2056                 }
2057         }
2058
2059         data->m = m0;
2060         data->ni = ni;
2061
2062         DPRINTF(sc, IWN_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
2063             __func__, ring->qid, ring->cur, m0->m_pkthdr.len, nsegs);
2064
2065         paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
2066         tx->loaddr = htole32(paddr + 4 +
2067             offsetof(struct iwn_cmd_data, ntries));
2068         tx->hiaddr = 0; /* limit to 32-bit physical addresses */
2069
2070         /* first scatter/gather segment is used by the tx data command */
2071         IWN_SET_DESC_NSEGS(desc, 1 + nsegs);
2072         IWN_SET_DESC_SEG(desc, 0, paddr, 4 + sizeof (*tx) + hdrlen + pad);
2073         for (i = 1; i <= nsegs; i++) {
2074                 IWN_SET_DESC_SEG(desc, i, segs[i - 1].ds_addr,
2075                      segs[i - 1].ds_len);
2076         }
2077         sc->shared->len[ring->qid][ring->cur] =
2078             htole16(hdrlen + m0->m_pkthdr.len + 8);
2079
2080         if (ring->cur < IWN_TX_WINDOW)
2081                 sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
2082                         htole16(hdrlen + m0->m_pkthdr.len + 8);
2083
2084         ring->queued++;
2085
2086         /* kick Tx ring */
2087         ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
2088         IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
2089
2090         ifp->if_opackets++;
2091         sc->sc_tx_timer = 5;
2092
2093         return 0;
2094 }
2095
2096 void
2097 iwn_start(struct ifnet *ifp)
2098 {
2099         struct iwn_softc *sc = ifp->if_softc;
2100
2101         IWN_LOCK(sc);
2102         iwn_start_locked(ifp);
2103         IWN_UNLOCK(sc);
2104 }
2105
2106 void
2107 iwn_start_locked(struct ifnet *ifp)
2108 {
2109         struct iwn_softc *sc = ifp->if_softc;
2110         struct ieee80211_node *ni;
2111         struct iwn_tx_ring *txq;
2112         struct mbuf *m;
2113         int pri;
2114
2115         IWN_LOCK_ASSERT(sc);
2116
2117         for (;;) {
2118                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
2119                 if (m == NULL)
2120                         break;
2121                 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
2122                 pri = M_WME_GETAC(m);
2123                 txq = &sc->txq[pri];
2124                 if (txq->queued >= IWN_TX_RING_COUNT - 8) {
2125                         /* XXX not right */
2126                         /* ring is nearly full, stop flow */
2127                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2128                 }
2129                 if (iwn_tx_data(sc, m, ni, txq) != 0) {
2130                         ifp->if_oerrors++;
2131                         ieee80211_free_node(ni);
2132                         break;
2133                 }
2134         }
2135 }
2136
2137 static int
2138 iwn_tx_handoff(struct iwn_softc *sc,
2139         struct iwn_tx_ring *ring,
2140         struct iwn_tx_cmd *cmd,
2141         struct iwn_cmd_data *tx,
2142         struct ieee80211_node *ni,
2143         struct mbuf *m0, u_int hdrlen, int pad)
2144 {
2145         struct ifnet *ifp = sc->sc_ifp;
2146         struct iwn_tx_desc *desc;
2147         struct iwn_tx_data *data;
2148         bus_addr_t paddr;
2149         struct mbuf *mnew;
2150         int error, nsegs, i;
2151         bus_dma_segment_t segs[IWN_MAX_SCATTER];
2152
2153         /* copy and trim IEEE802.11 header */
2154         memcpy((uint8_t *)(tx + 1), mtod(m0, uint8_t *), hdrlen);
2155         m_adj(m0, hdrlen);
2156
2157         desc = &ring->desc[ring->cur];
2158         data = &ring->data[ring->cur];
2159
2160         error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m0, segs,
2161             &nsegs, BUS_DMA_NOWAIT);
2162         if (error != 0) {
2163                 if (error == EFBIG) {
2164                         /* too many fragments, linearize */
2165                         mnew = m_collapse(m0, M_DONTWAIT, IWN_MAX_SCATTER);
2166                         if (mnew == NULL) {
2167                                 IWN_UNLOCK(sc);
2168                                 device_printf(sc->sc_dev,
2169                                     "%s: could not defrag mbuf\n", __func__);
2170                                 m_freem(m0);
2171                                 return ENOBUFS;
2172                         }
2173                         m0 = mnew;
2174                         error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
2175                             data->map, m0, segs, &nsegs, BUS_DMA_NOWAIT);
2176                 }
2177                 if (error != 0) {
2178                         IWN_UNLOCK(sc);
2179                         device_printf(sc->sc_dev,
2180                             "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
2181                              __func__, error);
2182                         m_freem(m0);
2183                         return error;
2184                 }
2185         }
2186
2187         data->m = m0;
2188         data->ni = ni;
2189
2190         DPRINTF(sc, IWN_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
2191             __func__, ring->qid, ring->cur, m0->m_pkthdr.len, nsegs);
2192
2193         paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
2194         tx->loaddr = htole32(paddr + 4 +
2195             offsetof(struct iwn_cmd_data, ntries));
2196         tx->hiaddr = 0; /* limit to 32-bit physical addresses */
2197
2198         /* first scatter/gather segment is used by the tx data command */
2199         IWN_SET_DESC_NSEGS(desc, 1 + nsegs);
2200         IWN_SET_DESC_SEG(desc, 0, paddr, 4 + sizeof (*tx) + hdrlen + pad);
2201         for (i = 1; i <= nsegs; i++) {
2202                 IWN_SET_DESC_SEG(desc, i, segs[i - 1].ds_addr,
2203                      segs[i - 1].ds_len);
2204         }
2205         sc->shared->len[ring->qid][ring->cur] =
2206             htole16(hdrlen + m0->m_pkthdr.len + 8);
2207
2208         if (ring->cur < IWN_TX_WINDOW)
2209                 sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
2210                         htole16(hdrlen + m0->m_pkthdr.len + 8);
2211
2212         ring->queued++;
2213
2214         /* kick Tx ring */
2215         ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
2216         IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
2217
2218         ifp->if_opackets++;
2219         sc->sc_tx_timer = 5;
2220
2221         return 0;
2222 }
2223
2224 static int
2225 iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m0,
2226     struct ieee80211_node *ni, struct iwn_tx_ring *ring,
2227     const struct ieee80211_bpf_params *params)
2228 {
2229         struct ieee80211vap *vap = ni->ni_vap;
2230         struct ieee80211com *ic = ni->ni_ic;
2231         struct iwn_tx_cmd *cmd;
2232         struct iwn_cmd_data *tx;
2233         struct ieee80211_frame *wh;
2234         uint32_t flags;
2235         uint8_t type, subtype;
2236         u_int hdrlen;
2237         int rate, pad;
2238
2239         IWN_LOCK_ASSERT(sc);
2240
2241         wh = mtod(m0, struct ieee80211_frame *);
2242         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
2243         subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
2244         hdrlen = ieee80211_anyhdrsize(wh);
2245
2246         flags = IWN_TX_AUTO_SEQ;
2247         if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
2248                 flags |= IWN_TX_NEED_ACK;
2249         if (params->ibp_flags & IEEE80211_BPF_RTS)
2250                 flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
2251         if (params->ibp_flags & IEEE80211_BPF_CTS)
2252                 flags |= IWN_TX_NEED_CTS | IWN_TX_FULL_TXOP;
2253         if (type == IEEE80211_FC0_TYPE_MGT &&
2254             subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
2255                 /* tell h/w to set timestamp in probe responses */
2256                 flags |= IWN_TX_INSERT_TSTAMP;
2257         }
2258         if (hdrlen & 3) {
2259                 /* first segment's length must be a multiple of 4 */
2260                 flags |= IWN_TX_NEED_PADDING;
2261                 pad = 4 - (hdrlen & 3);
2262         } else
2263                 pad = 0;
2264
2265         /* pick a tx rate */
2266         rate = params->ibp_rate0;
2267         if (!ieee80211_isratevalid(ic->ic_rt, rate)) {
2268                 /* XXX fall back to mcast/mgmt rate? */
2269                 m_freem(m0);
2270                 return EINVAL;
2271         }
2272
2273         if (ieee80211_radiotap_active_vap(vap)) {
2274                 struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
2275
2276                 tap->wt_flags = 0;
2277                 tap->wt_rate = rate;
2278
2279                 ieee80211_radiotap_tx(vap, m0);
2280         }
2281
2282         cmd = &ring->cmd[ring->cur];
2283         cmd->code = IWN_CMD_TX_DATA;
2284         cmd->flags = 0;
2285         cmd->qid = ring->qid;
2286         cmd->idx = ring->cur;
2287
2288         tx = (struct iwn_cmd_data *)cmd->data;
2289         /* NB: no need to bzero tx, all fields are reinitialized here */
2290         tx->id = IWN_ID_BROADCAST;
2291         tx->flags = htole32(flags);
2292         tx->len = htole16(m0->m_pkthdr.len);
2293         tx->rate = iwn_plcp_signal(rate);
2294         tx->rts_ntries = params->ibp_try1;              /* XXX? */
2295         tx->data_ntries = params->ibp_try0;
2296         tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
2297         /* XXX use try count? */
2298         if (type == IEEE80211_FC0_TYPE_MGT) {
2299                 if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
2300                     subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
2301                         tx->timeout = htole16(3);
2302                 else
2303                         tx->timeout = htole16(2);
2304         } else
2305                 tx->timeout = htole16(0);
2306         tx->security = 0;
2307         /* XXX alternate between Ant A and Ant B ? */
2308         tx->rflags = IWN_RFLAG_ANT_B;   /* XXX params->ibp_pri >> 2 */
2309         tx->ridx = IWN_MAX_TX_RETRIES - 1;
2310         if (!IWN_RATE_IS_OFDM(rate))
2311                 tx->rflags |= IWN_RFLAG_CCK;
2312
2313         return iwn_tx_handoff(sc, ring, cmd, tx, ni, m0, hdrlen, pad);
2314 }
2315
2316 static int
2317 iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2318         const struct ieee80211_bpf_params *params)
2319 {
2320         struct ieee80211com *ic = ni->ni_ic;
2321         struct ifnet *ifp = ic->ic_ifp;
2322         struct iwn_softc *sc = ifp->if_softc;
2323         struct iwn_tx_ring *txq;
2324         int error;
2325
2326         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
2327                 ieee80211_free_node(ni);
2328                 m_freem(m);
2329                 return ENETDOWN;
2330         }
2331
2332         IWN_LOCK(sc);
2333         if (params == NULL)
2334                 txq = &sc->txq[M_WME_GETAC(m)];
2335         else
2336                 txq = &sc->txq[params->ibp_pri & 3];
2337         if (txq->queued >= IWN_TX_RING_COUNT - 8) {
2338                 /* XXX not right */
2339                 /* ring is nearly full, stop flow */
2340                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2341         }
2342         if (params == NULL) {
2343                 /*
2344                  * Legacy path; interpret frame contents to decide
2345                  * precisely how to send the frame.
2346                  */
2347                 error = iwn_tx_data(sc, m, ni, txq);
2348         } else {
2349                 /*
2350                  * Caller supplied explicit parameters to use in
2351                  * sending the frame.
2352                  */
2353                 error = iwn_tx_data_raw(sc, m, ni, txq, params);
2354         }
2355         if (error != 0) {
2356                 /* NB: m is reclaimed on tx failure */
2357                 ieee80211_free_node(ni);
2358                 ifp->if_oerrors++;
2359         }
2360         IWN_UNLOCK(sc);
2361         return error;
2362 }
2363
2364 static void
2365 iwn_watchdog(struct iwn_softc *sc)
2366 {
2367         if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
2368                 struct ifnet *ifp = sc->sc_ifp;
2369                 struct ieee80211com *ic = ifp->if_l2com;
2370
2371                 if_printf(ifp, "device timeout\n");
2372                 ieee80211_runtask(ic, &sc->sc_reinit_task);
2373         }
2374 }
2375
2376 int
2377 iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2378 {
2379         struct iwn_softc *sc = ifp->if_softc;
2380         struct ieee80211com *ic = ifp->if_l2com;
2381         struct ifreq *ifr = (struct ifreq *) data;
2382         int error = 0, startall = 0;
2383
2384         switch (cmd) {
2385         case SIOCSIFFLAGS:
2386                 IWN_LOCK(sc);
2387                 if (ifp->if_flags & IFF_UP) {
2388                         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
2389                                 iwn_init_locked(sc);
2390                                 startall = 1;
2391                         }
2392                 } else {
2393                         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
2394                                 iwn_stop_locked(sc);
2395                 }
2396                 IWN_UNLOCK(sc);
2397                 if (startall)
2398                         ieee80211_start_all(ic);
2399                 break;
2400         case SIOCGIFMEDIA:
2401                 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
2402                 break;
2403         case SIOCGIFADDR:
2404                 error = ether_ioctl(ifp, cmd, data);
2405                 break;
2406         default:
2407                 error = EINVAL;
2408                 break;
2409         }
2410         return error;
2411 }
2412
2413 void
2414 iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
2415 {
2416         char domain[4];
2417         uint16_t val;
2418         int i, error;
2419
2420         if ((error = iwn_eeprom_lock(sc)) != 0) {
2421                 device_printf(sc->sc_dev,
2422                     "%s: could not lock EEPROM, error %d\n", __func__, error);
2423                 return;
2424         }
2425         /* read and print regulatory domain */
2426         iwn_read_prom_data(sc, IWN_EEPROM_DOMAIN, domain, 4);
2427         device_printf(sc->sc_dev,"Reg Domain: %.4s", domain);
2428
2429         /* read and print MAC address */
2430         iwn_read_prom_data(sc, IWN_EEPROM_MAC, macaddr, 6);
2431         printf(", address %6D\n", macaddr, ":");
2432
2433         /* read the list of authorized channels */
2434         iwn_read_eeprom_channels(sc);
2435
2436         /* read maximum allowed Tx power for 2GHz and 5GHz bands */
2437         iwn_read_prom_data(sc, IWN_EEPROM_MAXPOW, &val, 2);
2438         sc->maxpwr2GHz = val & 0xff;
2439         sc->maxpwr5GHz = val >> 8;
2440         /* check that EEPROM values are correct */
2441         if (sc->maxpwr5GHz < 20 || sc->maxpwr5GHz > 50)
2442                 sc->maxpwr5GHz = 38;
2443         if (sc->maxpwr2GHz < 20 || sc->maxpwr2GHz > 50)
2444                 sc->maxpwr2GHz = 38;
2445         DPRINTF(sc, IWN_DEBUG_RESET, "maxpwr 2GHz=%d 5GHz=%d\n",
2446             sc->maxpwr2GHz, sc->maxpwr5GHz);
2447
2448         /* read voltage at which samples were taken */
2449         iwn_read_prom_data(sc, IWN_EEPROM_VOLTAGE, &val, 2);
2450         sc->eeprom_voltage = (int16_t)le16toh(val);
2451         DPRINTF(sc, IWN_DEBUG_RESET, "voltage=%d (in 0.3V)\n",
2452             sc->eeprom_voltage);
2453
2454         /* read power groups */
2455         iwn_read_prom_data(sc, IWN_EEPROM_BANDS, sc->bands, sizeof sc->bands);
2456 #ifdef IWN_DEBUG
2457         if (sc->sc_debug & IWN_DEBUG_ANY) {
2458                 for (i = 0; i < IWN_NBANDS; i++)
2459                         iwn_print_power_group(sc, i);
2460         }
2461 #endif
2462         iwn_eeprom_unlock(sc);
2463 }
2464
2465 struct iwn_chan_band {
2466         uint32_t        addr;   /* offset in EEPROM */
2467         uint32_t        flags;  /* net80211 flags */
2468         uint8_t         nchan;
2469 #define IWN_MAX_CHAN_PER_BAND   14
2470         uint8_t         chan[IWN_MAX_CHAN_PER_BAND];
2471 };
2472
2473 static void
2474 iwn_read_eeprom_band(struct iwn_softc *sc, const struct iwn_chan_band *band)
2475 {
2476         struct ifnet *ifp = sc->sc_ifp;
2477         struct ieee80211com *ic = ifp->if_l2com;
2478         struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
2479         struct ieee80211_channel *c;
2480         int i, chan, flags;
2481
2482         iwn_read_prom_data(sc, band->addr, channels,
2483             band->nchan * sizeof (struct iwn_eeprom_chan));
2484
2485         for (i = 0; i < band->nchan; i++) {
2486                 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
2487                         DPRINTF(sc, IWN_DEBUG_RESET,
2488                             "skip chan %d flags 0x%x maxpwr %d\n",
2489                             band->chan[i], channels[i].flags,
2490                             channels[i].maxpwr);
2491                         continue;
2492                 }
2493                 chan = band->chan[i];
2494
2495                 /* translate EEPROM flags to net80211 */
2496                 flags = 0;
2497                 if ((channels[i].flags & IWN_EEPROM_CHAN_ACTIVE) == 0)
2498                         flags |= IEEE80211_CHAN_PASSIVE;
2499                 if ((channels[i].flags & IWN_EEPROM_CHAN_IBSS) == 0)
2500                         flags |= IEEE80211_CHAN_NOADHOC;
2501                 if (channels[i].flags & IWN_EEPROM_CHAN_RADAR) {
2502                         flags |= IEEE80211_CHAN_DFS;
2503                         /* XXX apparently IBSS may still be marked */
2504                         flags |= IEEE80211_CHAN_NOADHOC;
2505                 }
2506
2507                 DPRINTF(sc, IWN_DEBUG_RESET,
2508                     "add chan %d flags 0x%x maxpwr %d\n",
2509                     chan, channels[i].flags, channels[i].maxpwr);
2510
2511                 c = &ic->ic_channels[ic->ic_nchans++];
2512                 c->ic_ieee = chan;
2513                 c->ic_freq = ieee80211_ieee2mhz(chan, band->flags);
2514                 c->ic_maxregpower = channels[i].maxpwr;
2515                 c->ic_maxpower = 2*c->ic_maxregpower;
2516                 if (band->flags & IEEE80211_CHAN_2GHZ) {
2517                         /* G =>'s B is supported */
2518                         c->ic_flags = IEEE80211_CHAN_B | flags;
2519
2520                         c = &ic->ic_channels[ic->ic_nchans++];
2521                         c[0] = c[-1];
2522                         c->ic_flags = IEEE80211_CHAN_G | flags;
2523                 } else {        /* 5GHz band */
2524                         c->ic_flags = IEEE80211_CHAN_A | flags;
2525                 }
2526                 /* XXX no constraints on using HT20 */
2527                 /* add HT20, HT40 added separately */
2528                 c = &ic->ic_channels[ic->ic_nchans++];
2529                 c[0] = c[-1];
2530                 c->ic_flags |= IEEE80211_CHAN_HT20;
2531                 /* XXX NARROW =>'s 1/2 and 1/4 width? */
2532         }
2533 }
2534
2535 static void
2536 iwn_read_eeprom_ht40(struct iwn_softc *sc, const struct iwn_chan_band *band)
2537 {
2538         struct ifnet *ifp = sc->sc_ifp;
2539         struct ieee80211com *ic = ifp->if_l2com;
2540         struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
2541         struct ieee80211_channel *c, *cent, *extc;
2542         int i;
2543
2544         iwn_read_prom_data(sc, band->addr, channels,
2545             band->nchan * sizeof (struct iwn_eeprom_chan));
2546
2547         for (i = 0; i < band->nchan; i++) {
2548                 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID) ||
2549                     !(channels[i].flags & IWN_EEPROM_CHAN_WIDE)) {
2550                         DPRINTF(sc, IWN_DEBUG_RESET,
2551                             "skip chan %d flags 0x%x maxpwr %d\n",
2552                             band->chan[i], channels[i].flags,
2553                             channels[i].maxpwr);
2554                         continue;
2555                 }
2556                 /*
2557                  * Each entry defines an HT40 channel pair; find the
2558                  * center channel, then the extension channel above.
2559                  */
2560                 cent = ieee80211_find_channel_byieee(ic, band->chan[i],
2561                     band->flags & ~IEEE80211_CHAN_HT);
2562                 if (cent == NULL) {     /* XXX shouldn't happen */
2563                         device_printf(sc->sc_dev,
2564                             "%s: no entry for channel %d\n",
2565                             __func__, band->chan[i]);
2566                         continue;
2567                 }
2568                 extc = ieee80211_find_channel(ic, cent->ic_freq+20,
2569                     band->flags & ~IEEE80211_CHAN_HT);
2570                 if (extc == NULL) {
2571                         DPRINTF(sc, IWN_DEBUG_RESET,
2572                             "skip chan %d, extension channel not found\n",
2573                             band->chan[i]);
2574                         continue;
2575                 }
2576
2577                 DPRINTF(sc, IWN_DEBUG_RESET,
2578                     "add ht40 chan %d flags 0x%x maxpwr %d\n",
2579                     band->chan[i], channels[i].flags, channels[i].maxpwr);
2580
2581                 c = &ic->ic_channels[ic->ic_nchans++];
2582                 c[0] = cent[0];
2583                 c->ic_extieee = extc->ic_ieee;
2584                 c->ic_flags &= ~IEEE80211_CHAN_HT;
2585                 c->ic_flags |= IEEE80211_CHAN_HT40U;
2586                 c = &ic->ic_channels[ic->ic_nchans++];
2587                 c[0] = extc[0];
2588                 c->ic_extieee = cent->ic_ieee;
2589                 c->ic_flags &= ~IEEE80211_CHAN_HT;
2590                 c->ic_flags |= IEEE80211_CHAN_HT40D;
2591         }
2592 }
2593
2594 static void
2595 iwn_read_eeprom_channels(struct iwn_softc *sc)
2596 {
2597 #define N(a)    (sizeof(a)/sizeof(a[0]))
2598         static const struct iwn_chan_band iwn_bands[] = {
2599             { IWN_EEPROM_BAND1, IEEE80211_CHAN_G, 14,
2600                 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } },
2601             { IWN_EEPROM_BAND2, IEEE80211_CHAN_A, 13,
2602                 { 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 } },
2603             { IWN_EEPROM_BAND3, IEEE80211_CHAN_A, 12,
2604                 { 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 } },
2605             { IWN_EEPROM_BAND4, IEEE80211_CHAN_A, 11,
2606                 { 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 } },
2607             { IWN_EEPROM_BAND5, IEEE80211_CHAN_A, 6,
2608                 { 145, 149, 153, 157, 161, 165 } },
2609             { IWN_EEPROM_BAND6, IEEE80211_CHAN_G | IEEE80211_CHAN_HT40, 7,
2610                 { 1, 2, 3, 4, 5, 6, 7 } },
2611             { IWN_EEPROM_BAND7, IEEE80211_CHAN_A | IEEE80211_CHAN_HT40, 11,
2612                 { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 } }
2613         };
2614         struct ifnet *ifp = sc->sc_ifp;
2615         struct ieee80211com *ic = ifp->if_l2com;
2616         int i;
2617
2618         /* read the list of authorized channels */
2619         for (i = 0; i < N(iwn_bands)-2; i++)
2620                 iwn_read_eeprom_band(sc, &iwn_bands[i]);
2621         for (; i < N(iwn_bands); i++)
2622                 iwn_read_eeprom_ht40(sc, &iwn_bands[i]);
2623         ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
2624 #undef N
2625 }
2626
2627 #ifdef IWN_DEBUG
2628 void
2629 iwn_print_power_group(struct iwn_softc *sc, int i)
2630 {
2631         struct iwn_eeprom_band *band = &sc->bands[i];
2632         struct iwn_eeprom_chan_samples *chans = band->chans;
2633         int j, c;
2634
2635         printf("===band %d===\n", i);
2636         printf("chan lo=%d, chan hi=%d\n", band->lo, band->hi);
2637         printf("chan1 num=%d\n", chans[0].num);
2638         for (c = 0; c < IWN_NTXCHAINS; c++) {
2639                 for (j = 0; j < IWN_NSAMPLES; j++) {
2640                         printf("chain %d, sample %d: temp=%d gain=%d "
2641                             "power=%d pa_det=%d\n", c, j,
2642                             chans[0].samples[c][j].temp,
2643                             chans[0].samples[c][j].gain,
2644                             chans[0].samples[c][j].power,
2645                             chans[0].samples[c][j].pa_det);
2646                 }
2647         }
2648         printf("chan2 num=%d\n", chans[1].num);
2649         for (c = 0; c < IWN_NTXCHAINS; c++) {
2650                 for (j = 0; j < IWN_NSAMPLES; j++) {
2651                         printf("chain %d, sample %d: temp=%d gain=%d "
2652                             "power=%d pa_det=%d\n", c, j,
2653                             chans[1].samples[c][j].temp,
2654                             chans[1].samples[c][j].gain,
2655                             chans[1].samples[c][j].power,
2656                             chans[1].samples[c][j].pa_det);
2657                 }
2658         }
2659 }
2660 #endif
2661
2662 /*
2663  * Send a command to the firmware.
2664  */
2665 int
2666 iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
2667 {
2668         struct iwn_tx_ring *ring = &sc->txq[4];
2669         struct iwn_tx_desc *desc;
2670         struct iwn_tx_cmd *cmd;
2671         bus_addr_t paddr;
2672
2673         IWN_LOCK_ASSERT(sc);
2674
2675         KASSERT(size <= sizeof cmd->data, ("Command too big"));
2676
2677         desc = &ring->desc[ring->cur];
2678         cmd = &ring->cmd[ring->cur];
2679
2680         cmd->code = code;
2681         cmd->flags = 0;
2682         cmd->qid = ring->qid;
2683         cmd->idx = ring->cur;
2684         memcpy(cmd->data, buf, size);
2685
2686         paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
2687
2688         IWN_SET_DESC_NSEGS(desc, 1);
2689         IWN_SET_DESC_SEG(desc, 0, paddr, 4 + size);
2690         sc->shared->len[ring->qid][ring->cur] = htole16(8);
2691         if (ring->cur < IWN_TX_WINDOW) {
2692             sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
2693                 htole16(8);
2694         }
2695
2696         DPRINTF(sc, IWN_DEBUG_CMD, "%s: %s (0x%x) flags %d qid %d idx %d\n",
2697             __func__, iwn_intr_str(cmd->code), cmd->code,
2698             cmd->flags, cmd->qid, cmd->idx);
2699
2700         /* kick cmd ring */
2701         ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
2702         IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
2703
2704         return async ? 0 : msleep(cmd, &sc->sc_mtx, PCATCH, "iwncmd", hz);
2705 }
2706
2707 static const uint8_t iwn_ridx_to_plcp[] = {
2708         10, 20, 55, 110, /* CCK */
2709         0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */
2710 };
2711 static const uint8_t iwn_siso_mcs_to_plcp[] = {
2712         0, 0, 0, 0,                     /* CCK */
2713         0, 0, 1, 2, 3, 4, 5, 6, 7       /* HT */
2714 };
2715 static const uint8_t iwn_mimo_mcs_to_plcp[] = {
2716         0, 0, 0, 0,                     /* CCK */
2717         8, 8, 9, 10, 11, 12, 13, 14, 15 /* HT */
2718 };
2719 static const uint8_t iwn_prev_ridx[] = {
2720         /* NB: allow fallback from CCK11 to OFDM9 and from OFDM6 to CCK5 */
2721         0, 0, 1, 5,                     /* CCK */
2722         2, 4, 3, 6, 7, 8, 9, 10, 10     /* OFDM */
2723 };
2724
2725 /*
2726  * Configure hardware link parameters for the specified
2727  * node operating on the specified channel.
2728  */
2729 int
2730 iwn_set_link_quality(struct iwn_softc *sc, uint8_t id,
2731         const struct ieee80211_channel *c, int async)
2732 {
2733         struct iwn_cmd_link_quality lq;
2734         int i, ridx;
2735
2736         memset(&lq, 0, sizeof(lq));
2737         lq.id = id;
2738         if (IEEE80211_IS_CHAN_HT(c)) {
2739                 lq.mimo = 1;
2740                 lq.ssmask = 0x1;
2741         } else
2742                 lq.ssmask = 0x2;
2743
2744         if (id == IWN_ID_BSS)
2745                 ridx = IWN_RATE_OFDM54;
2746         else if (IEEE80211_IS_CHAN_A(c))
2747                 ridx = IWN_RATE_OFDM6;
2748         else
2749                 ridx = IWN_RATE_CCK1;
2750         for (i = 0; i < IWN_MAX_TX_RETRIES; i++) {
2751                 /* XXX toggle antenna for retry patterns */
2752                 if (IEEE80211_IS_CHAN_HT40(c)) {
2753                         lq.table[i].rate = iwn_mimo_mcs_to_plcp[ridx]
2754                                          | IWN_RATE_MCS;
2755                         lq.table[i].rflags = IWN_RFLAG_HT
2756                                          | IWN_RFLAG_HT40
2757                                          | IWN_RFLAG_ANT_A;
2758                         /* XXX shortGI */
2759                 } else if (IEEE80211_IS_CHAN_HT(c)) {
2760                         lq.table[i].rate = iwn_siso_mcs_to_plcp[ridx]
2761                                          | IWN_RATE_MCS;
2762                         lq.table[i].rflags = IWN_RFLAG_HT
2763                                          | IWN_RFLAG_ANT_A;
2764                         /* XXX shortGI */
2765                 } else {
2766                         lq.table[i].rate = iwn_ridx_to_plcp[ridx];
2767                         if (ridx <= IWN_RATE_CCK11)
2768                                 lq.table[i].rflags = IWN_RFLAG_CCK;
2769                         lq.table[i].rflags |= IWN_RFLAG_ANT_B;
2770                 }
2771                 ridx = iwn_prev_ridx[ridx];
2772         }
2773
2774         lq.dsmask = 0x3;
2775         lq.ampdu_disable = 3;
2776         lq.ampdu_limit = htole16(4000);
2777 #ifdef IWN_DEBUG
2778         if (sc->sc_debug & IWN_DEBUG_STATE) {
2779                 printf("%s: set link quality for node %d, mimo %d ssmask %d\n",
2780                     __func__, id, lq.mimo, lq.ssmask);
2781                 printf("%s:", __func__);
2782                 for (i = 0; i < IWN_MAX_TX_RETRIES; i++)
2783                         printf(" %d:%x", lq.table[i].rate, lq.table[i].rflags);
2784                 printf("\n");
2785         }
2786 #endif
2787         return iwn_cmd(sc, IWN_CMD_TX_LINK_QUALITY, &lq, sizeof(lq), async);
2788 }
2789
2790 #if 0
2791
2792 /*
2793  * Install a pairwise key into the hardware.
2794  */
2795 int
2796 iwn_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
2797     const struct ieee80211_key *k)
2798 {
2799         struct iwn_softc *sc = ic->ic_softc;
2800         struct iwn_node_info node;
2801
2802         if (k->k_flags & IEEE80211_KEY_GROUP)
2803                 return 0;
2804
2805         memset(&node, 0, sizeof node);
2806
2807         switch (k->k_cipher) {
2808         case IEEE80211_CIPHER_CCMP:
2809                 node.security = htole16(IWN_CIPHER_CCMP);
2810                 memcpy(node.key, k->k_key, k->k_len);
2811                 break;
2812         default:
2813                 return 0;
2814         }
2815
2816         node.id = IWN_ID_BSS;
2817         IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
2818         node.control = IWN_NODE_UPDATE;
2819         node.flags = IWN_FLAG_SET_KEY;
2820
2821         return iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 1);
2822 }
2823 #endif
2824
2825 int
2826 iwn_wme_update(struct ieee80211com *ic)
2827 {
2828 #define IWN_EXP2(x)     ((1 << (x)) - 1)        /* CWmin = 2^ECWmin - 1 */
2829 #define IWN_TXOP_TO_US(v)               (v<<5)
2830         struct iwn_softc *sc = ic->ic_ifp->if_softc;
2831         struct iwn_edca_params cmd;
2832         int i;
2833
2834         memset(&cmd, 0, sizeof cmd);
2835         cmd.flags = htole32(IWN_EDCA_UPDATE);
2836         for (i = 0; i < WME_NUM_AC; i++) {
2837                 const struct wmeParams *wmep =
2838                     &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
2839                 cmd.ac[i].aifsn = wmep->wmep_aifsn;
2840                 cmd.ac[i].cwmin = htole16(IWN_EXP2(wmep->wmep_logcwmin));
2841                 cmd.ac[i].cwmax = htole16(IWN_EXP2(wmep->wmep_logcwmax));
2842                 cmd.ac[i].txoplimit =
2843                     htole16(IWN_TXOP_TO_US(wmep->wmep_txopLimit));
2844         }
2845         IWN_LOCK(sc);
2846         (void) iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1 /*async*/);
2847         IWN_UNLOCK(sc);
2848         return 0;
2849 #undef IWN_TXOP_TO_US
2850 #undef IWN_EXP2
2851 }
2852
2853 void
2854 iwn_set_led(struct iwn_softc *sc, uint8_t which, uint8_t off, uint8_t on)
2855 {
2856         struct iwn_cmd_led led;
2857
2858         led.which = which;
2859         led.unit = htole32(100000);     /* on/off in unit of 100ms */
2860         led.off = off;
2861         led.on = on;
2862
2863         (void) iwn_cmd(sc, IWN_CMD_SET_LED, &led, sizeof led, 1);
2864 }
2865
2866 /*
2867  * Set the critical temperature at which the firmware will automatically stop
2868  * the radio transmitter.
2869  */
2870 int
2871 iwn_set_critical_temp(struct iwn_softc *sc)
2872 {
2873         struct iwn_ucode_info *uc = &sc->ucode_info;
2874         struct iwn_critical_temp crit;
2875         uint32_t r1, r2, r3, temp;
2876
2877         r1 = le32toh(uc->temp[0].chan20MHz);
2878         r2 = le32toh(uc->temp[1].chan20MHz);
2879         r3 = le32toh(uc->temp[2].chan20MHz);
2880         /* inverse function of iwn_get_temperature() */
2881         temp = r2 + (IWN_CTOK(110) * (r3 - r1)) / 259;
2882
2883         IWN_WRITE(sc, IWN_UCODE_CLR, IWN_CTEMP_STOP_RF);
2884
2885         memset(&crit, 0, sizeof crit);
2886         crit.tempR = htole32(temp);
2887         DPRINTF(sc, IWN_DEBUG_RESET, "setting critical temp to %u\n", temp);
2888         return iwn_cmd(sc, IWN_CMD_SET_CRITICAL_TEMP, &crit, sizeof crit, 0);
2889 }
2890
2891 void
2892 iwn_enable_tsf(struct iwn_softc *sc, struct ieee80211_node *ni)
2893 {
2894         struct iwn_cmd_tsf tsf;
2895         uint64_t val, mod;
2896
2897         memset(&tsf, 0, sizeof tsf);
2898         memcpy(&tsf.tstamp, ni->ni_tstamp.data, sizeof (uint64_t));
2899         tsf.bintval = htole16(ni->ni_intval);
2900         tsf.lintval = htole16(10);
2901
2902         /* XXX all wrong */
2903         /* compute remaining time until next beacon */
2904         val = (uint64_t)ni->ni_intval * 1024;   /* msecs -> usecs */
2905         DPRINTF(sc, IWN_DEBUG_ANY, "%s: val = %ju %s\n", __func__,
2906             val, val == 0 ? "correcting" : "");
2907         if (val == 0)
2908                 val = 1;
2909         mod = le64toh(tsf.tstamp) % val;
2910         tsf.binitval = htole32((uint32_t)(val - mod));
2911
2912         DPRINTF(sc, IWN_DEBUG_RESET, "TSF bintval=%u tstamp=%ju, init=%u\n",
2913             ni->ni_intval, le64toh(tsf.tstamp), (uint32_t)(val - mod));
2914
2915         if (iwn_cmd(sc, IWN_CMD_TSF, &tsf, sizeof tsf, 1) != 0)
2916                 device_printf(sc->sc_dev,
2917                     "%s: could not enable TSF\n", __func__);
2918 }
2919
2920 void
2921 iwn_power_calibration(struct iwn_softc *sc, int temp)
2922 {
2923         struct ifnet *ifp = sc->sc_ifp;
2924         struct ieee80211com *ic = ifp->if_l2com;
2925 #if 0
2926         KASSERT(ic->ic_state == IEEE80211_S_RUN, ("not running"));
2927 #endif
2928         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d->%d\n",
2929             __func__, sc->temp, temp);
2930
2931         /* adjust Tx power if need be (delta >= 3°C) */
2932         if (abs(temp - sc->temp) < 3)
2933                 return;
2934
2935         sc->temp = temp;
2936
2937         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: set Tx power for channel %d\n",
2938             __func__, ieee80211_chan2ieee(ic, ic->ic_bsschan));
2939         if (iwn_set_txpower(sc, ic->ic_bsschan, 1) != 0) {
2940                 /* just warn, too bad for the automatic calibration... */
2941                 device_printf(sc->sc_dev,
2942                     "%s: could not adjust Tx power\n", __func__);
2943         }
2944 }
2945
2946 /*
2947  * Set Tx power for a given channel (each rate has its own power settings).
2948  * This function takes into account the regulatory information from EEPROM,
2949  * the current temperature and the current voltage.
2950  */
2951 int
2952 iwn_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch, int async)
2953 {
2954 /* fixed-point arithmetic division using a n-bit fractional part */
2955 #define fdivround(a, b, n)      \
2956         ((((1 << n) * (a)) / (b) + (1 << n) / 2) / (1 << n))
2957 /* linear interpolation */
2958 #define interpolate(x, x1, y1, x2, y2, n)       \
2959         ((y1) + fdivround(((int)(x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n))
2960
2961         static const int tdiv[IWN_NATTEN_GROUPS] = { 9, 8, 8, 8, 6 };
2962         struct ifnet *ifp = sc->sc_ifp;
2963         struct ieee80211com *ic = ifp->if_l2com;
2964         struct iwn_ucode_info *uc = &sc->ucode_info;
2965         struct iwn_cmd_txpower cmd;
2966         struct iwn_eeprom_chan_samples *chans;
2967         const uint8_t *rf_gain, *dsp_gain;
2968         int32_t vdiff, tdiff;
2969         int i, c, grp, maxpwr;
2970         u_int chan;
2971
2972         /* get channel number */
2973         chan = ieee80211_chan2ieee(ic, ch);
2974
2975         memset(&cmd, 0, sizeof cmd);
2976         cmd.band = IEEE80211_IS_CHAN_5GHZ(ch) ? 0 : 1;
2977         cmd.chan = chan;
2978
2979         if (IEEE80211_IS_CHAN_5GHZ(ch)) {
2980                 maxpwr   = sc->maxpwr5GHz;
2981                 rf_gain  = iwn_rf_gain_5ghz;
2982                 dsp_gain = iwn_dsp_gain_5ghz;
2983         } else {
2984                 maxpwr   = sc->maxpwr2GHz;
2985                 rf_gain  = iwn_rf_gain_2ghz;
2986                 dsp_gain = iwn_dsp_gain_2ghz;
2987         }
2988
2989         /* compute voltage compensation */
2990         vdiff = ((int32_t)le32toh(uc->volt) - sc->eeprom_voltage) / 7;
2991         if (vdiff > 0)
2992                 vdiff *= 2;
2993         if (abs(vdiff) > 2)
2994                 vdiff = 0;
2995         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
2996             "%s: voltage compensation=%d (UCODE=%d, EEPROM=%d)\n",
2997             __func__, vdiff, le32toh(uc->volt), sc->eeprom_voltage);
2998
2999         /* get channel's attenuation group */
3000         if (chan <= 20)         /* 1-20 */
3001                 grp = 4;
3002         else if (chan <= 43)    /* 34-43 */
3003                 grp = 0;
3004         else if (chan <= 70)    /* 44-70 */
3005                 grp = 1;
3006         else if (chan <= 124)   /* 71-124 */
3007                 grp = 2;
3008         else                    /* 125-200 */
3009                 grp = 3;
3010         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
3011             "%s: chan %d, attenuation group=%d\n", __func__, chan, grp);
3012
3013         /* get channel's sub-band */
3014         for (i = 0; i < IWN_NBANDS; i++)
3015                 if (sc->bands[i].lo != 0 &&
3016                     sc->bands[i].lo <= chan && chan <= sc->bands[i].hi)
3017                         break;
3018         chans = sc->bands[i].chans;
3019         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
3020             "%s: chan %d sub-band=%d\n", __func__, chan, i);
3021
3022         for (c = 0; c < IWN_NTXCHAINS; c++) {
3023                 uint8_t power, gain, temp;
3024                 int maxchpwr, pwr, ridx, idx;
3025
3026                 power = interpolate(chan,
3027                     chans[0].num, chans[0].samples[c][1].power,
3028                     chans[1].num, chans[1].samples[c][1].power, 1);
3029                 gain  = interpolate(chan,
3030                     chans[0].num, chans[0].samples[c][1].gain,
3031                     chans[1].num, chans[1].samples[c][1].gain, 1);
3032                 temp  = interpolate(chan,
3033                     chans[0].num, chans[0].samples[c][1].temp,
3034                     chans[1].num, chans[1].samples[c][1].temp, 1);
3035                 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
3036                     "%s: Tx chain %d: power=%d gain=%d temp=%d\n",
3037                     __func__, c, power, gain, temp);
3038
3039                 /* compute temperature compensation */
3040                 tdiff = ((sc->temp - temp) * 2) / tdiv[grp];
3041                 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
3042                     "%s: temperature compensation=%d (current=%d, EEPROM=%d)\n",
3043                     __func__, tdiff, sc->temp, temp);
3044
3045                 for (ridx = 0; ridx <= IWN_RIDX_MAX; ridx++) {
3046                         maxchpwr = ch->ic_maxpower;
3047                         if ((ridx / 8) & 1) {
3048                                 /* MIMO: decrease Tx power (-3dB) */
3049                                 maxchpwr -= 6;
3050                         }
3051
3052                         pwr = maxpwr - 10;
3053
3054                         /* decrease power for highest OFDM rates */
3055                         if ((ridx % 8) == 5)            /* 48Mbit/s */
3056                                 pwr -= 5;
3057                         else if ((ridx % 8) == 6)       /* 54Mbit/s */
3058                                 pwr -= 7;
3059                         else if ((ridx % 8) == 7)       /* 60Mbit/s */
3060                                 pwr -= 10;
3061
3062                         if (pwr > maxchpwr)
3063                                 pwr = maxchpwr;
3064
3065                         idx = gain - (pwr - power) - tdiff - vdiff;
3066                         if ((ridx / 8) & 1)     /* MIMO */
3067                                 idx += (int32_t)le32toh(uc->atten[grp][c]);
3068
3069                         if (cmd.band == 0)
3070                                 idx += 9;       /* 5GHz */
3071                         if (ridx == IWN_RIDX_MAX)
3072                                 idx += 5;       /* CCK */
3073
3074                         /* make sure idx stays in a valid range */
3075                         if (idx < 0)
3076                                 idx = 0;
3077                         else if (idx > IWN_MAX_PWR_INDEX)
3078                                 idx = IWN_MAX_PWR_INDEX;
3079
3080                         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
3081                             "%s: Tx chain %d, rate idx %d: power=%d\n",
3082                             __func__, c, ridx, idx);
3083                         cmd.power[ridx].rf_gain[c] = rf_gain[idx];
3084                         cmd.power[ridx].dsp_gain[c] = dsp_gain[idx];
3085                 }
3086         }
3087
3088         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
3089             "%s: set tx power for chan %d\n", __func__, chan);
3090         return iwn_cmd(sc, IWN_CMD_TXPOWER, &cmd, sizeof cmd, async);
3091
3092 #undef interpolate
3093 #undef fdivround
3094 }
3095
3096 /*
3097  * Get the best (maximum) RSSI among the
3098  * connected antennas and convert to dBm.
3099  */
3100 int8_t
3101 iwn_get_rssi(struct iwn_softc *sc, const struct iwn_rx_stat *stat)
3102 {
3103         int mask, agc, rssi;
3104
3105         mask = (le16toh(stat->antenna) >> 4) & 0x7;
3106         agc  = (le16toh(stat->agc) >> 7) & 0x7f;
3107
3108         rssi = 0;
3109 #if 0
3110         if (mask & (1 << 0))    /* Ant A */
3111                 rssi = max(rssi, stat->rssi[0]);
3112         if (mask & (1 << 1))    /* Ant B */
3113                 rssi = max(rssi, stat->rssi[2]);
3114         if (mask & (1 << 2))    /* Ant C */
3115                 rssi = max(rssi, stat->rssi[4]);
3116 #else
3117         rssi = max(rssi, stat->rssi[0]);
3118         rssi = max(rssi, stat->rssi[2]);
3119         rssi = max(rssi, stat->rssi[4]);
3120 #endif
3121         DPRINTF(sc, IWN_DEBUG_RECV, "%s: agc %d mask 0x%x rssi %d %d %d "
3122             "result %d\n", __func__, agc, mask,
3123             stat->rssi[0], stat->rssi[2], stat->rssi[4],
3124             rssi - agc - IWN_RSSI_TO_DBM);
3125         return rssi - agc - IWN_RSSI_TO_DBM;
3126 }
3127
3128 /*
3129  * Get the average noise among Rx antennas (in dBm).
3130  */
3131 int
3132 iwn_get_noise(const struct iwn_rx_general_stats *stats)
3133 {
3134         int i, total, nbant, noise;
3135
3136         total = nbant = 0;
3137         for (i = 0; i < 3; i++) {
3138                 noise = le32toh(stats->noise[i]) & 0xff;
3139                 if (noise != 0) {
3140                         total += noise;
3141                         nbant++;
3142                 }
3143         }
3144         /* there should be at least one antenna but check anyway */
3145         return (nbant == 0) ? -127 : (total / nbant) - 107;
3146 }
3147
3148 /*
3149  * Read temperature (in degC) from the on-board thermal sensor.
3150  */
3151 int
3152 iwn_get_temperature(struct iwn_softc *sc)
3153 {
3154         struct iwn_ucode_info *uc = &sc->ucode_info;
3155         int32_t r1, r2, r3, r4, temp;
3156
3157         r1 = le32toh(uc->temp[0].chan20MHz);
3158         r2 = le32toh(uc->temp[1].chan20MHz);
3159         r3 = le32toh(uc->temp[2].chan20MHz);
3160         r4 = le32toh(sc->rawtemp);
3161
3162         if (r1 == r3)   /* prevents division by 0 (should not happen) */
3163                 return 0;
3164
3165         /* sign-extend 23-bit R4 value to 32-bit */
3166         r4 = (r4 << 8) >> 8;
3167         /* compute temperature */
3168         temp = (259 * (r4 - r2)) / (r3 - r1);
3169         temp = (temp * 97) / 100 + 8;
3170
3171         return IWN_KTOC(temp);
3172 }
3173
3174 /*
3175  * Initialize sensitivity calibration state machine.
3176  */
3177 int
3178 iwn_init_sensitivity(struct iwn_softc *sc)
3179 {
3180         struct iwn_calib_state *calib = &sc->calib;
3181         struct iwn_phy_calib_cmd cmd;
3182         int error;
3183
3184         /* reset calibration state */
3185         memset(calib, 0, sizeof (*calib));
3186         calib->state = IWN_CALIB_STATE_INIT;
3187         calib->cck_state = IWN_CCK_STATE_HIFA;
3188         /* initial values taken from the reference driver */
3189         calib->corr_ofdm_x1     = 105;
3190         calib->corr_ofdm_mrc_x1 = 220;
3191         calib->corr_ofdm_x4     =  90;
3192         calib->corr_ofdm_mrc_x4 = 170;
3193         calib->corr_cck_x4      = 125;
3194         calib->corr_cck_mrc_x4  = 200;
3195         calib->energy_cck       = 100;
3196
3197         /* write initial sensitivity values */
3198         error = iwn_send_sensitivity(sc);
3199         if (error != 0)
3200                 return error;
3201
3202         memset(&cmd, 0, sizeof cmd);
3203         cmd.code = IWN_SET_DIFF_GAIN;
3204         /* differential gains initially set to 0 for all 3 antennas */
3205         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: calibrate phy\n", __func__);
3206         return iwn_cmd(sc, IWN_PHY_CALIB, &cmd, sizeof cmd, 1);
3207 }
3208
3209 /*
3210  * Collect noise and RSSI statistics for the first 20 beacons received
3211  * after association and use them to determine connected antennas and
3212  * set differential gains.
3213  */
3214 void
3215 iwn_compute_differential_gain(struct iwn_softc *sc,
3216     const struct iwn_rx_general_stats *stats)
3217 {
3218         struct iwn_calib_state *calib = &sc->calib;
3219         struct iwn_phy_calib_cmd cmd;
3220         int i, val;
3221
3222         /* accumulate RSSI and noise for all 3 antennas */
3223         for (i = 0; i < 3; i++) {
3224                 calib->rssi[i] += le32toh(stats->rssi[i]) & 0xff;
3225                 calib->noise[i] += le32toh(stats->noise[i]) & 0xff;
3226         }
3227
3228         /* we update differential gain only once after 20 beacons */
3229         if (++calib->nbeacons < 20)
3230                 return;
3231
3232         /* determine antenna with highest average RSSI */
3233         val = max(calib->rssi[0], calib->rssi[1]);
3234         val = max(calib->rssi[2], val);
3235
3236         /* determine which antennas are connected */
3237         sc->antmsk = 0;
3238         for (i = 0; i < 3; i++)
3239                 if (val - calib->rssi[i] <= 15 * 20)
3240                         sc->antmsk |= 1 << i;
3241         /* if neither Ant A and Ant B are connected.. */
3242         if ((sc->antmsk & (1 << 0 | 1 << 1)) == 0)
3243                 sc->antmsk |= 1 << 1;   /* ..mark Ant B as connected! */
3244
3245         /* get minimal noise among connected antennas */
3246         val = INT_MAX;  /* ok, there's at least one */
3247         for (i = 0; i < 3; i++)
3248                 if (sc->antmsk & (1 << i))
3249                         val = min(calib->noise[i], val);
3250
3251         memset(&cmd, 0, sizeof cmd);
3252         cmd.code = IWN_SET_DIFF_GAIN;
3253         /* set differential gains for connected antennas */
3254         for (i = 0; i < 3; i++) {
3255                 if (sc->antmsk & (1 << i)) {
3256                         cmd.gain[i] = (calib->noise[i] - val) / 30;
3257                         /* limit differential gain to 3 */
3258                         cmd.gain[i] = min(cmd.gain[i], 3);
3259                         cmd.gain[i] |= IWN_GAIN_SET;
3260                 }
3261         }
3262         DPRINTF(sc, IWN_DEBUG_CALIBRATE,
3263             "%s: set differential gains Ant A/B/C: %x/%x/%x (%x)\n",
3264             __func__,cmd.gain[0], cmd.gain[1], cmd.gain[2], sc->antmsk);
3265         if (iwn_cmd(sc, IWN_PHY_CALIB, &cmd, sizeof cmd, 1) == 0)
3266                 calib->state = IWN_CALIB_STATE_RUN;
3267 }
3268
3269 /*
3270  * Tune RF Rx sensitivity based on the number of false alarms detected
3271  * during the last beacon period.
3272  */
3273 void
3274 iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
3275 {
3276 #define inc_clip(val, inc, max)                 \
3277         if ((val) < (max)) {                    \
3278                 if ((val) < (max) - (inc))      \
3279                         (val) += (inc);         \
3280                 else                            \
3281                         (val) = (max);          \
3282                 needs_update = 1;               \
3283         }
3284 #define dec_clip(val, dec, min)                 \
3285         if ((val) > (min)) {                    \
3286                 if ((val) > (min) + (dec))      \
3287                         (val) -= (dec);         \
3288                 else                            \
3289                         (val) = (min);          \
3290                 needs_update = 1;               \
3291         }
3292
3293         struct iwn_calib_state *calib = &sc->calib;
3294         uint32_t val, rxena, fa;
3295         uint32_t energy[3], energy_min;
3296         uint8_t noise[3], noise_ref;
3297         int i, needs_update = 0;
3298
3299         /* check that we've been enabled long enough */
3300         if ((rxena = le32toh(stats->general.load)) == 0)
3301                 return;
3302
3303         /* compute number of false alarms since last call for OFDM */
3304         fa  = le32toh(stats->ofdm.bad_plcp) - calib->bad_plcp_ofdm;
3305         fa += le32toh(stats->ofdm.fa) - calib->fa_ofdm;
3306         fa *= 200 * 1024;       /* 200TU */
3307
3308         /* save counters values for next call */
3309         calib->bad_plcp_ofdm = le32toh(stats->ofdm.bad_plcp);
3310         calib->fa_ofdm = le32toh(stats->ofdm.fa);
3311
3312         if (fa > 50 * rxena) {
3313                 /* high false alarm count, decrease sensitivity */
3314                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
3315                     "%s: OFDM high false alarm count: %u\n", __func__, fa);
3316                 inc_clip(calib->corr_ofdm_x1,     1, 140);
3317                 inc_clip(calib->corr_ofdm_mrc_x1, 1, 270);
3318                 inc_clip(calib->corr_ofdm_x4,     1, 120);
3319                 inc_clip(calib->corr_ofdm_mrc_x4, 1, 210);
3320
3321         } else if (fa < 5 * rxena) {
3322                 /* low false alarm count, increase sensitivity */
3323                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
3324                     "%s: OFDM low false alarm count: %u\n", __func__, fa);
3325                 dec_clip(calib->corr_ofdm_x1,     1, 105);
3326                 dec_clip(calib->corr_ofdm_mrc_x1, 1, 220);
3327                 dec_clip(calib->corr_ofdm_x4,     1,  85);
3328                 dec_clip(calib->corr_ofdm_mrc_x4, 1, 170);
3329         }
3330
3331         /* compute maximum noise among 3 antennas */
3332         for (i = 0; i < 3; i++)
3333                 noise[i] = (le32toh(stats->general.noise[i]) >> 8) & 0xff;
3334         val = max(noise[0], noise[1]);
3335         val = max(noise[2], val);
3336         /* insert it into our samples table */
3337         calib->noise_samples[calib->cur_noise_sample] = val;
3338         calib->cur_noise_sample = (calib->cur_noise_sample + 1) % 20;
3339
3340         /* compute maximum noise among last 20 samples */
3341         noise_ref = calib->noise_samples[0];
3342         for (i = 1; i < 20; i++)
3343                 noise_ref = max(noise_ref, calib->noise_samples[i]);
3344
3345         /* compute maximum energy among 3 antennas */
3346         for (i = 0; i < 3; i++)
3347                 energy[i] = le32toh(stats->general.energy[i]);
3348         val = min(energy[0], energy[1]);
3349         val = min(energy[2], val);
3350         /* insert it into our samples table */
3351         calib->energy_samples[calib->cur_energy_sample] = val;
3352         calib->cur_energy_sample = (calib->cur_energy_sample + 1) % 10;
3353
3354         /* compute minimum energy among last 10 samples */
3355         energy_min = calib->energy_samples[0];
3356         for (i = 1; i < 10; i++)
3357                 energy_min = max(energy_min, calib->energy_samples[i]);
3358         energy_min += 6;
3359
3360         /* compute number of false alarms since last call for CCK */
3361         fa  = le32toh(stats->cck.bad_plcp) - calib->bad_plcp_cck;
3362         fa += le32toh(stats->cck.fa) - calib->fa_cck;
3363         fa *= 200 * 1024;       /* 200TU */
3364
3365         /* save counters values for next call */
3366         calib->bad_plcp_cck = le32toh(stats->cck.bad_plcp);
3367         calib->fa_cck = le32toh(stats->cck.fa);
3368
3369         if (fa > 50 * rxena) {
3370                 /* high false alarm count, decrease sensitivity */
3371                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
3372                     "%s: CCK high false alarm count: %u\n", __func__, fa);
3373                 calib->cck_state = IWN_CCK_STATE_HIFA;
3374                 calib->low_fa = 0;
3375
3376                 if (calib->corr_cck_x4 > 160) {
3377                         calib->noise_ref = noise_ref;
3378                         if (calib->energy_cck > 2)
3379                                 dec_clip(calib->energy_cck, 2, energy_min);
3380                 }
3381                 if (calib->corr_cck_x4 < 160) {
3382                         calib->corr_cck_x4 = 161;
3383                         needs_update = 1;
3384                 } else
3385                         inc_clip(calib->corr_cck_x4, 3, 200);
3386
3387                 inc_clip(calib->corr_cck_mrc_x4, 3, 400);
3388
3389         } else if (fa < 5 * rxena) {
3390                 /* low false alarm count, increase sensitivity */
3391                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
3392                     "%s: CCK low false alarm count: %u\n", __func__, fa);
3393                 calib->cck_state = IWN_CCK_STATE_LOFA;
3394                 calib->low_fa++;
3395
3396                 if (calib->cck_state != 0 &&
3397                     ((calib->noise_ref - noise_ref) > 2 ||
3398                      calib->low_fa > 100)) {
3399                         inc_clip(calib->energy_cck,      2,  97);
3400                         dec_clip(calib->corr_cck_x4,     3, 125);
3401                         dec_clip(calib->corr_cck_mrc_x4, 3, 200);
3402                 }
3403         } else {
3404                 /* not worth to increase or decrease sensitivity */
3405                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
3406                     "%s: CCK normal false alarm count: %u\n", __func__, fa);
3407                 calib->low_fa = 0;
3408                 calib->noise_ref = noise_ref;
3409
3410                 if (calib->cck_state == IWN_CCK_STATE_HIFA) {
3411                         /* previous interval had many false alarms */
3412                         dec_clip(calib->energy_cck, 8, energy_min);
3413                 }
3414                 calib->cck_state = IWN_CCK_STATE_INIT;
3415         }
3416
3417         if (needs_update)
3418                 (void)iwn_send_sensitivity(sc);
3419 #undef dec_clip
3420 #undef inc_clip
3421 }
3422
3423 int
3424 iwn_send_sensitivity(struct iwn_softc *sc)
3425 {
3426         struct iwn_calib_state *calib = &sc->calib;
3427         struct iwn_sensitivity_cmd cmd;
3428
3429         memset(&cmd, 0, sizeof cmd);
3430         cmd.which = IWN_SENSITIVITY_WORKTBL;
3431         /* OFDM modulation */
3432         cmd.corr_ofdm_x1     = htole16(calib->corr_ofdm_x1);
3433         cmd.corr_ofdm_mrc_x1 = htole16(calib->corr_ofdm_mrc_x1);
3434         cmd.corr_ofdm_x4     = htole16(calib->corr_ofdm_x4);
3435         cmd.corr_ofdm_mrc_x4 = htole16(calib->corr_ofdm_mrc_x4);
3436         cmd.energy_ofdm      = htole16(100);
3437         cmd.energy_ofdm_th   = htole16(62);
3438         /* CCK modulation */
3439         cmd.corr_cck_x4      = htole16(calib->corr_cck_x4);
3440         cmd.corr_cck_mrc_x4  = htole16(calib->corr_cck_mrc_x4);
3441         cmd.energy_cck       = htole16(calib->energy_cck);
3442         /* Barker modulation: use default values */
3443         cmd.corr_barker      = htole16(190);
3444         cmd.corr_barker_mrc  = htole16(390);
3445
3446         DPRINTF(sc, IWN_DEBUG_RESET, 
3447             "%s: set sensitivity %d/%d/%d/%d/%d/%d/%d\n", __func__,
3448             calib->corr_ofdm_x1, calib->corr_ofdm_mrc_x1, calib->corr_ofdm_x4,
3449             calib->corr_ofdm_mrc_x4, calib->corr_cck_x4,
3450             calib->corr_cck_mrc_x4, calib->energy_cck);
3451         return iwn_cmd(sc, IWN_SENSITIVITY, &cmd, sizeof cmd, 1);
3452 }
3453
3454 int
3455 iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
3456 {
3457         struct ifnet *ifp = sc->sc_ifp;
3458         struct ieee80211com *ic = ifp->if_l2com;
3459         struct ieee80211_node *ni = vap->iv_bss;
3460         struct iwn_node_info node;
3461         int error;
3462
3463         sc->calib.state = IWN_CALIB_STATE_INIT;
3464
3465         /* update adapter's configuration */
3466         sc->config.associd = 0;
3467         IEEE80211_ADDR_COPY(sc->config.bssid, ni->ni_bssid);
3468         sc->config.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));
3469         sc->config.flags = htole32(IWN_CONFIG_TSF);
3470         if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
3471                 sc->config.flags |= htole32(IWN_CONFIG_AUTO | IWN_CONFIG_24GHZ);
3472         if (IEEE80211_IS_CHAN_A(ni->ni_chan)) {
3473                 sc->config.cck_mask  = 0;
3474                 sc->config.ofdm_mask = 0x15;
3475         } else if (IEEE80211_IS_CHAN_B(ni->ni_chan)) {
3476                 sc->config.cck_mask  = 0x03;
3477                 sc->config.ofdm_mask = 0;
3478         } else {
3479                 /* XXX assume 802.11b/g */
3480                 sc->config.cck_mask  = 0x0f;
3481                 sc->config.ofdm_mask = 0x15;
3482         }
3483         if (ic->ic_flags & IEEE80211_F_SHSLOT)
3484                 sc->config.flags |= htole32(IWN_CONFIG_SHSLOT);
3485         if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
3486                 sc->config.flags |= htole32(IWN_CONFIG_SHPREAMBLE);
3487         sc->config.filter &= ~htole32(IWN_FILTER_BSS);
3488
3489         DPRINTF(sc, IWN_DEBUG_STATE,
3490            "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
3491            "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
3492            "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
3493            __func__,
3494            le16toh(sc->config.chan), sc->config.mode, le32toh(sc->config.flags),
3495            sc->config.cck_mask, sc->config.ofdm_mask,
3496            sc->config.ht_single_mask, sc->config.ht_dual_mask,
3497            le16toh(sc->config.rxchain),
3498            sc->config.myaddr, ":", sc->config.wlap, ":", sc->config.bssid, ":",
3499            le16toh(sc->config.associd), le32toh(sc->config.filter));
3500         error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->config,
3501             sizeof (struct iwn_config), 1);
3502         if (error != 0) {
3503                 device_printf(sc->sc_dev,
3504                     "%s: could not configure, error %d\n", __func__, error);
3505                 return error;
3506         }
3507         sc->sc_curchan = ic->ic_curchan;
3508
3509         /* configuration has changed, set Tx power accordingly */
3510         error = iwn_set_txpower(sc, ni->ni_chan, 1);
3511         if (error != 0) {
3512                 device_printf(sc->sc_dev,
3513                     "%s: could not set Tx power, error %d\n", __func__, error);
3514                 return error;
3515         }
3516
3517         /*
3518          * Reconfiguring clears the adapter's nodes table so we must
3519          * add the broadcast node again.
3520          */
3521         memset(&node, 0, sizeof node);
3522         IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr);
3523         node.id = IWN_ID_BROADCAST;
3524         DPRINTF(sc, IWN_DEBUG_STATE, "%s: add broadcast node\n", __func__);
3525         error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 1);
3526         if (error != 0) {
3527                 device_printf(sc->sc_dev,
3528                     "%s: could not add broadcast node, error %d\n",
3529                     __func__, error);
3530                 return error;
3531         }
3532         error = iwn_set_link_quality(sc, node.id, ic->ic_curchan, 1);
3533         if (error != 0) {
3534                 device_printf(sc->sc_dev,
3535                     "%s: could not setup MRR for broadcast node, error %d\n",
3536                     __func__, error);
3537                 return error;
3538         }
3539
3540         return 0;
3541 }
3542
3543 /*
3544  * Configure the adapter for associated state.
3545  */
3546 int
3547 iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
3548 {
3549 #define MS(v,x) (((v) & x) >> x##_S)
3550         struct ifnet *ifp = sc->sc_ifp;
3551         struct ieee80211com *ic = ifp->if_l2com;
3552         struct ieee80211_node *ni = vap->iv_bss;
3553         struct iwn_node_info node;
3554         int error, maxrxampdu, ampdudensity;
3555
3556         sc->calib.state = IWN_CALIB_STATE_INIT;
3557
3558         if (ic->ic_opmode == IEEE80211_M_MONITOR) {
3559                 /* link LED blinks while monitoring */
3560                 iwn_set_led(sc, IWN_LED_LINK, 5, 5);
3561                 return 0;
3562         }
3563
3564         iwn_enable_tsf(sc, ni);
3565
3566         /* update adapter's configuration */
3567         sc->config.associd = htole16(IEEE80211_AID(ni->ni_associd));
3568         /* short preamble/slot time are negotiated when associating */
3569         sc->config.flags &= ~htole32(IWN_CONFIG_SHPREAMBLE | IWN_CONFIG_SHSLOT);
3570         if (ic->ic_flags & IEEE80211_F_SHSLOT)
3571                 sc->config.flags |= htole32(IWN_CONFIG_SHSLOT);
3572         if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
3573                 sc->config.flags |= htole32(IWN_CONFIG_SHPREAMBLE);
3574         if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) {
3575                 sc->config.flags &= ~htole32(IWN_CONFIG_HT);
3576                 if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan))
3577                         sc->config.flags |= htole32(IWN_CONFIG_HT40U);
3578                 else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan))
3579                         sc->config.flags |= htole32(IWN_CONFIG_HT40D);
3580                 else
3581                         sc->config.flags |= htole32(IWN_CONFIG_HT20);
3582                 sc->config.rxchain = htole16(
3583                           (3 << IWN_RXCHAIN_VALID_S)
3584                         | (3 << IWN_RXCHAIN_MIMO_CNT_S)
3585                         | (1 << IWN_RXCHAIN_CNT_S)
3586                         | IWN_RXCHAIN_MIMO_FORCE);
3587
3588                 maxrxampdu = MS(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU);
3589                 ampdudensity = MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
3590         } else
3591                 maxrxampdu = ampdudensity = 0;
3592         sc->config.filter |= htole32(IWN_FILTER_BSS);
3593
3594         DPRINTF(sc, IWN_DEBUG_STATE,
3595            "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
3596            "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
3597            "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
3598            __func__,
3599            le16toh(sc->config.chan), sc->config.mode, le32toh(sc->config.flags),
3600            sc->config.cck_mask, sc->config.ofdm_mask,
3601            sc->config.ht_single_mask, sc->config.ht_dual_mask,
3602            le16toh(sc->config.rxchain),
3603            sc->config.myaddr, ":", sc->config.wlap, ":", sc->config.bssid, ":",
3604            le16toh(sc->config.associd), le32toh(sc->config.filter));
3605         error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->config,
3606             sizeof (struct iwn_config), 1);
3607         if (error != 0) {
3608                 device_printf(sc->sc_dev,
3609                     "%s: could not update configuration, error %d\n",
3610                     __func__, error);
3611                 return error;
3612         }
3613         sc->sc_curchan = ni->ni_chan;
3614
3615         /* configuration has changed, set Tx power accordingly */
3616         error = iwn_set_txpower(sc, ni->ni_chan, 1);
3617         if (error != 0) {
3618                 device_printf(sc->sc_dev,
3619                     "%s: could not set Tx power, error %d\n", __func__, error);
3620                 return error;
3621         }
3622
3623         /* add BSS node */
3624         memset(&node, 0, sizeof node);
3625         IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
3626         node.id = IWN_ID_BSS;
3627         node.htflags = htole32(
3628             (maxrxampdu << IWN_MAXRXAMPDU_S) |
3629             (ampdudensity << IWN_MPDUDENSITY_S));
3630         DPRINTF(sc, IWN_DEBUG_STATE, "%s: add BSS node, id %d htflags 0x%x\n",
3631             __func__, node.id, le32toh(node.htflags));
3632         error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 1);
3633         if (error != 0) {
3634                 device_printf(sc->sc_dev,"could not add BSS node\n");
3635                 return error;
3636         }
3637         error = iwn_set_link_quality(sc, node.id, ni->ni_chan, 1);
3638         if (error != 0) {
3639                 device_printf(sc->sc_dev,
3640                     "%s: could not setup MRR for node %d, error %d\n",
3641                     __func__, node.id, error);
3642                 return error;
3643         }
3644
3645         error = iwn_init_sensitivity(sc);
3646         if (error != 0) {
3647                 device_printf(sc->sc_dev,
3648                     "%s: could not set sensitivity, error %d\n",
3649                     __func__, error);
3650                 return error;
3651         }
3652
3653         /* start/restart periodic calibration timer */
3654         sc->calib.state = IWN_CALIB_STATE_ASSOC;
3655         iwn_calib_reset(sc);
3656
3657         /* link LED always on while associated */
3658         iwn_set_led(sc, IWN_LED_LINK, 0, 1);
3659
3660         return 0;
3661 #undef MS
3662 }
3663
3664 /*
3665  * Send a scan request to the firmware.  Since this command is huge, we map it
3666  * into a mbuf instead of using the pre-allocated set of commands.
3667  */
3668 int
3669 iwn_scan(struct iwn_softc *sc)
3670 {
3671         struct ifnet *ifp = sc->sc_ifp;
3672         struct ieee80211com *ic = ifp->if_l2com;
3673         struct ieee80211_scan_state *ss = ic->ic_scan;  /*XXX*/
3674         struct iwn_tx_ring *ring = &sc->txq[4];
3675         struct iwn_tx_desc *desc;
3676         struct iwn_tx_data *data;
3677         struct iwn_tx_cmd *cmd;
3678         struct iwn_cmd_data *tx;
3679         struct iwn_scan_hdr *hdr;
3680         struct iwn_scan_essid *essid;
3681         struct iwn_scan_chan *chan;
3682         struct ieee80211_frame *wh;
3683         struct ieee80211_rateset *rs;
3684         struct ieee80211_channel *c;
3685         enum ieee80211_phymode mode;
3686         uint8_t *frm;
3687         int pktlen, error, nrates;
3688         bus_addr_t physaddr;
3689
3690         desc = &ring->desc[ring->cur];
3691         data = &ring->data[ring->cur];
3692
3693         /* XXX malloc */
3694         data->m = m_getcl(M_DONTWAIT, MT_DATA, 0);
3695         if (data->m == NULL) {
3696                 device_printf(sc->sc_dev,
3697                     "%s: could not allocate mbuf for scan command\n", __func__);
3698                 return ENOMEM;
3699         }
3700
3701         cmd = mtod(data->m, struct iwn_tx_cmd *);
3702         cmd->code = IWN_CMD_SCAN;
3703         cmd->flags = 0;
3704         cmd->qid = ring->qid;
3705         cmd->idx = ring->cur;
3706
3707         hdr = (struct iwn_scan_hdr *)cmd->data;
3708         memset(hdr, 0, sizeof (struct iwn_scan_hdr));
3709
3710         /* XXX use scan state */
3711         /*
3712          * Move to the next channel if no packets are received within 5 msecs
3713          * after sending the probe request (this helps to reduce the duration
3714          * of active scans).
3715          */
3716         hdr->quiet = htole16(5);        /* timeout in milliseconds */
3717         hdr->plcp_threshold = htole16(1);       /* min # of packets */
3718
3719         /* select Ant B and Ant C for scanning */
3720         hdr->rxchain = htole16(0x3e1 | (7 << IWN_RXCHAIN_VALID_S));
3721
3722         tx = (struct iwn_cmd_data *)(hdr + 1);
3723         memset(tx, 0, sizeof (struct iwn_cmd_data));
3724         tx->flags = htole32(IWN_TX_AUTO_SEQ | 0x200);   /* XXX */
3725         tx->id = IWN_ID_BROADCAST;
3726         tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
3727         tx->rflags = IWN_RFLAG_ANT_B;
3728
3729         if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) {
3730                 hdr->crc_threshold = htole16(1);
3731                 /* send probe requests at 6Mbps */
3732                 tx->rate = iwn_ridx_to_plcp[IWN_RATE_OFDM6];
3733         } else {
3734                 hdr->flags = htole32(IWN_CONFIG_24GHZ | IWN_CONFIG_AUTO);
3735                 /* send probe requests at 1Mbps */
3736                 tx->rate = iwn_ridx_to_plcp[IWN_RATE_CCK1];
3737                 tx->rflags |= IWN_RFLAG_CCK;
3738         }
3739
3740         essid = (struct iwn_scan_essid *)(tx + 1);
3741         memset(essid, 0, 4 * sizeof (struct iwn_scan_essid));
3742         essid[0].id  = IEEE80211_ELEMID_SSID;
3743         essid[0].len = ss->ss_ssid[0].len;
3744         memcpy(essid[0].data, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
3745
3746         /*
3747          * Build a probe request frame.  Most of the following code is a
3748          * copy & paste of what is done in net80211.
3749          */
3750         wh = (struct ieee80211_frame *)&essid[4];
3751         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
3752             IEEE80211_FC0_SUBTYPE_PROBE_REQ;
3753         wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
3754         IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
3755         IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(ifp));
3756         IEEE80211_ADDR_COPY(wh->i_addr3, ifp->if_broadcastaddr);
3757         *(u_int16_t *)&wh->i_dur[0] = 0;        /* filled by h/w */
3758         *(u_int16_t *)&wh->i_seq[0] = 0;        /* filled by h/w */
3759
3760         frm = (uint8_t *)(wh + 1);
3761
3762         /* add SSID IE */
3763         *frm++ = IEEE80211_ELEMID_SSID;
3764         *frm++ = ss->ss_ssid[0].len;
3765         memcpy(frm, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
3766         frm += ss->ss_ssid[0].len;
3767
3768         mode = ieee80211_chan2mode(ic->ic_curchan);
3769         rs = &ic->ic_sup_rates[mode];
3770
3771         /* add supported rates IE */
3772         *frm++ = IEEE80211_ELEMID_RATES;
3773         nrates = rs->rs_nrates;
3774         if (nrates > IEEE80211_RATE_SIZE)
3775                 nrates = IEEE80211_RATE_SIZE;
3776         *frm++ = nrates;
3777         memcpy(frm, rs->rs_rates, nrates);
3778         frm += nrates;
3779
3780         /* add supported xrates IE */
3781         if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
3782                 nrates = rs->rs_nrates - IEEE80211_RATE_SIZE;
3783                 *frm++ = IEEE80211_ELEMID_XRATES;
3784                 *frm++ = (uint8_t)nrates;
3785                 memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates);
3786                 frm += nrates;
3787         }
3788
3789         /* setup length of probe request */
3790         tx->len = htole16(frm - (uint8_t *)wh);
3791
3792         c = ic->ic_curchan;
3793         chan = (struct iwn_scan_chan *)frm;
3794         chan->chan = ieee80211_chan2ieee(ic, c);
3795         chan->flags = 0;
3796         if ((c->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) {
3797                 chan->flags |= IWN_CHAN_ACTIVE;
3798                 if (ss->ss_nssid > 0)
3799                         chan->flags |= IWN_CHAN_DIRECT;
3800         }
3801         chan->dsp_gain = 0x6e;
3802         if (IEEE80211_IS_CHAN_5GHZ(c)) {
3803                 chan->rf_gain = 0x3b;
3804                 chan->active  = htole16(10);
3805                 chan->passive = htole16(110);
3806         } else {
3807                 chan->rf_gain = 0x28;
3808                 chan->active  = htole16(20);
3809                 chan->passive = htole16(120);
3810         }
3811
3812         DPRINTF(sc, IWN_DEBUG_STATE, "%s: chan %u flags 0x%x rf_gain 0x%x "
3813             "dsp_gain 0x%x active 0x%x passive 0x%x\n", __func__,
3814             chan->chan, chan->flags, chan->rf_gain, chan->dsp_gain,
3815             chan->active, chan->passive);
3816         hdr->nchan++;
3817         chan++;
3818
3819         frm += sizeof (struct iwn_scan_chan);
3820
3821         hdr->len = htole16(frm - (uint8_t *)hdr);
3822         pktlen = frm - (uint8_t *)cmd;
3823
3824         error = bus_dmamap_load(ring->data_dmat, data->map, cmd, pktlen,
3825             iwn_dma_map_addr, &physaddr, BUS_DMA_NOWAIT);
3826         if (error != 0) {
3827                 device_printf(sc->sc_dev,
3828                     "%s: could not map scan command, error %d\n",
3829                     __func__, error);
3830                 m_freem(data->m);
3831                 data->m = NULL;
3832                 return error;
3833         }
3834
3835         IWN_SET_DESC_NSEGS(desc, 1);
3836         IWN_SET_DESC_SEG(desc, 0, physaddr, pktlen);
3837         sc->shared->len[ring->qid][ring->cur] = htole16(8);
3838         if (ring->cur < IWN_TX_WINDOW)
3839                 sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
3840                     htole16(8);
3841
3842         bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
3843             BUS_DMASYNC_PREWRITE);
3844         bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
3845
3846         /* kick cmd ring */
3847         ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
3848         IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
3849
3850         return 0;       /* will be notified async. of failure/success */
3851 }
3852
3853 int
3854 iwn_config(struct iwn_softc *sc)
3855 {
3856         struct ifnet *ifp = sc->sc_ifp;
3857         struct ieee80211com *ic = ifp->if_l2com;
3858         struct iwn_power power;
3859         struct iwn_bluetooth bluetooth;
3860         struct iwn_node_info node;
3861         int error;
3862
3863         /* set power mode */
3864         memset(&power, 0, sizeof power);
3865         power.flags = htole16(IWN_POWER_CAM | 0x8);
3866         DPRINTF(sc, IWN_DEBUG_RESET, "%s: set power mode\n", __func__);
3867         error = iwn_cmd(sc, IWN_CMD_SET_POWER_MODE, &power, sizeof power, 0);
3868         if (error != 0) {
3869                 device_printf(sc->sc_dev,
3870                     "%s: could not set power mode, error %d\n",
3871                     __func__, error);
3872                 return error;
3873         }
3874
3875         /* configure bluetooth coexistence */
3876         memset(&bluetooth, 0, sizeof bluetooth);
3877         bluetooth.flags = 3;
3878         bluetooth.lead = 0xaa;
3879         bluetooth.kill = 1;
3880         DPRINTF(sc, IWN_DEBUG_RESET, "%s: config bluetooth coexistence\n",
3881             __func__);
3882         error = iwn_cmd(sc, IWN_CMD_BLUETOOTH, &bluetooth, sizeof bluetooth,
3883             0);
3884         if (error != 0) {
3885                 device_printf(sc->sc_dev,
3886                     "%s: could not configure bluetooth coexistence, error %d\n",
3887                     __func__, error);
3888                 return error;
3889         }
3890
3891         /* configure adapter */
3892         memset(&sc->config, 0, sizeof (struct iwn_config));
3893         IEEE80211_ADDR_COPY(sc->config.myaddr, IF_LLADDR(ifp));
3894         IEEE80211_ADDR_COPY(sc->config.wlap, IF_LLADDR(ifp));
3895         /* set default channel */
3896         sc->config.chan = htole16(ieee80211_chan2ieee(ic, ic->ic_curchan));
3897         sc->config.flags = htole32(IWN_CONFIG_TSF);
3898         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
3899                 sc->config.flags |= htole32(IWN_CONFIG_AUTO | IWN_CONFIG_24GHZ);
3900         sc->config.filter = 0;
3901         switch (ic->ic_opmode) {
3902         case IEEE80211_M_STA:
3903                 sc->config.mode = IWN_MODE_STA;
3904                 sc->config.filter |= htole32(IWN_FILTER_MULTICAST);
3905                 break;
3906         case IEEE80211_M_IBSS:
3907         case IEEE80211_M_AHDEMO:
3908                 sc->config.mode = IWN_MODE_IBSS;
3909                 break;
3910         case IEEE80211_M_HOSTAP:
3911                 sc->config.mode = IWN_MODE_HOSTAP;
3912                 break;
3913         case IEEE80211_M_MONITOR:
3914                 sc->config.mode = IWN_MODE_MONITOR;
3915                 sc->config.filter |= htole32(IWN_FILTER_MULTICAST |
3916                     IWN_FILTER_CTL | IWN_FILTER_PROMISC);
3917                 break;
3918         default:
3919                 device_printf(sc->sc_dev, "unknown opmode %d\n", ic->ic_opmode);
3920                 return EINVAL;
3921         }
3922         sc->config.cck_mask  = 0x0f;    /* not yet negotiated */
3923         sc->config.ofdm_mask = 0xff;    /* not yet negotiated */
3924         sc->config.ht_single_mask = 0xff;
3925         sc->config.ht_dual_mask = 0xff;
3926         sc->config.rxchain = htole16(0x2800 | (7 << IWN_RXCHAIN_VALID_S));
3927
3928         DPRINTF(sc, IWN_DEBUG_STATE,
3929            "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
3930            "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
3931            "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
3932            __func__,
3933            le16toh(sc->config.chan), sc->config.mode, le32toh(sc->config.flags),
3934            sc->config.cck_mask, sc->config.ofdm_mask,
3935            sc->config.ht_single_mask, sc->config.ht_dual_mask,
3936            le16toh(sc->config.rxchain),
3937            sc->config.myaddr, ":", sc->config.wlap, ":", sc->config.bssid, ":",
3938            le16toh(sc->config.associd), le32toh(sc->config.filter));
3939         error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->config,
3940             sizeof (struct iwn_config), 0);
3941         if (error != 0) {
3942                 device_printf(sc->sc_dev,
3943                     "%s: configure command failed, error %d\n",
3944                     __func__, error);
3945                 return error;
3946         }
3947         sc->sc_curchan = ic->ic_curchan;
3948
3949         /* configuration has changed, set Tx power accordingly */
3950         error = iwn_set_txpower(sc, ic->ic_curchan, 0);
3951         if (error != 0) {
3952                 device_printf(sc->sc_dev,
3953                     "%s: could not set Tx power, error %d\n", __func__, error);
3954                 return error;
3955         }
3956
3957         /* add broadcast node */
3958         memset(&node, 0, sizeof node);
3959         IEEE80211_ADDR_COPY(node.macaddr, ic->ic_ifp->if_broadcastaddr);
3960         node.id = IWN_ID_BROADCAST;
3961         node.rate = iwn_plcp_signal(2);
3962         DPRINTF(sc, IWN_DEBUG_RESET, "%s: add broadcast node\n", __func__);
3963         error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 0);
3964         if (error != 0) {
3965                 device_printf(sc->sc_dev,
3966                     "%s: could not add broadcast node, error %d\n",
3967                     __func__, error);
3968                 return error;
3969         }
3970         error = iwn_set_link_quality(sc, node.id, ic->ic_curchan, 0);
3971         if (error != 0) {
3972                 device_printf(sc->sc_dev,
3973                     "%s: could not setup MRR for node %d, error %d\n",
3974                     __func__, node.id, error);
3975                 return error;
3976         }
3977
3978         error = iwn_set_critical_temp(sc);
3979         if (error != 0) {
3980                 device_printf(sc->sc_dev,
3981                     "%s: could not set critical temperature, error %d\n",
3982                     __func__, error);
3983                 return error;
3984         }
3985         return 0;
3986 }
3987
3988 /*
3989  * Do post-alive initialization of the NIC (after firmware upload).
3990  */
3991 void
3992 iwn_post_alive(struct iwn_softc *sc)
3993 {
3994         uint32_t base;
3995         uint16_t offset;
3996         int qid;
3997
3998         iwn_mem_lock(sc);
3999
4000         /* clear SRAM */
4001         base = iwn_mem_read(sc, IWN_SRAM_BASE);
4002         for (offset = 0x380; offset < 0x520; offset += 4) {
4003                 IWN_WRITE(sc, IWN_MEM_WADDR, base + offset);
4004                 IWN_WRITE(sc, IWN_MEM_WDATA, 0);
4005         }
4006
4007         /* shared area is aligned on a 1K boundary */
4008         iwn_mem_write(sc, IWN_SRAM_BASE, sc->shared_dma.paddr >> 10);
4009         iwn_mem_write(sc, IWN_SELECT_QCHAIN, 0);
4010
4011         for (qid = 0; qid < IWN_NTXQUEUES; qid++) {
4012                 iwn_mem_write(sc, IWN_QUEUE_RIDX(qid), 0);
4013                 IWN_WRITE(sc, IWN_TX_WIDX, qid << 8 | 0);
4014
4015                 /* set sched. window size */
4016                 IWN_WRITE(sc, IWN_MEM_WADDR, base + IWN_QUEUE_OFFSET(qid));
4017                 IWN_WRITE(sc, IWN_MEM_WDATA, 64);
4018                 /* set sched. frame limit */
4019                 IWN_WRITE(sc, IWN_MEM_WADDR, base + IWN_QUEUE_OFFSET(qid) + 4);
4020                 IWN_WRITE(sc, IWN_MEM_WDATA, 10 << 16);
4021         }
4022
4023         /* enable interrupts for all 16 queues */
4024         iwn_mem_write(sc, IWN_QUEUE_INTR_MASK, 0xffff);
4025
4026         /* identify active Tx rings (0-7) */
4027         iwn_mem_write(sc, IWN_TX_ACTIVE, 0xff);
4028
4029         /* mark Tx rings (4 EDCA + cmd + 2 HCCA) as active */
4030         for (qid = 0; qid < 7; qid++) {
4031                 iwn_mem_write(sc, IWN_TXQ_STATUS(qid),
4032                     IWN_TXQ_STATUS_ACTIVE | qid << 1);
4033         }
4034
4035         iwn_mem_unlock(sc);
4036 }
4037
4038 void
4039 iwn_stop_master(struct iwn_softc *sc)
4040 {
4041         uint32_t tmp;
4042         int ntries;
4043
4044         tmp = IWN_READ(sc, IWN_RESET);
4045         IWN_WRITE(sc, IWN_RESET, tmp | IWN_STOP_MASTER);
4046
4047         tmp = IWN_READ(sc, IWN_GPIO_CTL);
4048         if ((tmp & IWN_GPIO_PWR_STATUS) == IWN_GPIO_PWR_SLEEP)
4049                 return; /* already asleep */
4050
4051         for (ntries = 0; ntries < 100; ntries++) {
4052                 if (IWN_READ(sc, IWN_RESET) & IWN_MASTER_DISABLED)
4053                         break;
4054                 DELAY(10);
4055         }
4056         if (ntries == 100)
4057                 device_printf(sc->sc_dev,
4058                     "%s: timeout waiting for master\n", __func__);
4059 }
4060
4061 int
4062 iwn_reset(struct iwn_softc *sc)
4063 {
4064         uint32_t tmp;
4065         int ntries;
4066
4067         /* clear any pending interrupts */
4068         IWN_WRITE(sc, IWN_INTR, 0xffffffff);
4069
4070         tmp = IWN_READ(sc, IWN_CHICKEN);
4071         IWN_WRITE(sc, IWN_CHICKEN, tmp | IWN_CHICKEN_DISLOS);
4072
4073         tmp = IWN_READ(sc, IWN_GPIO_CTL);
4074         IWN_WRITE(sc, IWN_GPIO_CTL, tmp | IWN_GPIO_INIT);
4075
4076         /* wait for clock stabilization */
4077         for (ntries = 0; ntries < 1000; ntries++) {
4078                 if (IWN_READ(sc, IWN_GPIO_CTL) & IWN_GPIO_CLOCK)
4079                         break;
4080                 DELAY(10);
4081         }
4082         if (ntries == 1000) {
4083                 device_printf(sc->sc_dev,
4084                     "%s: timeout waiting for clock stabilization\n", __func__);
4085                 return ETIMEDOUT;
4086         }
4087         return 0;
4088 }
4089
4090 void
4091 iwn_hw_config(struct iwn_softc *sc)
4092 {
4093         uint32_t tmp, hw;
4094
4095         /* enable interrupts mitigation */
4096         IWN_WRITE(sc, IWN_INTR_MIT, 512 / 32);
4097
4098         /* voodoo from the reference driver */
4099         tmp = pci_read_config(sc->sc_dev, PCIR_REVID,1);
4100         if ((tmp & 0x80) && (tmp & 0x7f) < 8) {
4101                 /* enable "no snoop" field */
4102                 tmp = pci_read_config(sc->sc_dev, 0xe8, 1);
4103                 tmp &= ~IWN_DIS_NOSNOOP;
4104                 /* clear device specific PCI configuration register 0x41 */
4105                 pci_write_config(sc->sc_dev, 0xe8, tmp, 1);
4106         }
4107
4108         /* disable L1 entry to work around a hardware bug */
4109         tmp = pci_read_config(sc->sc_dev, 0xf0, 1);
4110         tmp &= ~IWN_ENA_L1;
4111         pci_write_config(sc->sc_dev, 0xf0, tmp, 1 );
4112
4113         hw = IWN_READ(sc, IWN_HWCONFIG);
4114         IWN_WRITE(sc, IWN_HWCONFIG, hw | 0x310);
4115
4116         iwn_mem_lock(sc);
4117         tmp = iwn_mem_read(sc, IWN_MEM_POWER);
4118         iwn_mem_write(sc, IWN_MEM_POWER, tmp | IWN_POWER_RESET);
4119         DELAY(5);
4120         tmp = iwn_mem_read(sc, IWN_MEM_POWER);
4121         iwn_mem_write(sc, IWN_MEM_POWER, tmp & ~IWN_POWER_RESET);
4122         iwn_mem_unlock(sc);
4123 }
4124
4125 void
4126 iwn_init_locked(struct iwn_softc *sc)
4127 {
4128         struct ifnet *ifp = sc->sc_ifp;
4129         uint32_t tmp;
4130         int error, qid;
4131
4132         IWN_LOCK_ASSERT(sc);
4133
4134         /* load the firmware */
4135         if (sc->fw_fp == NULL && (error = iwn_load_firmware(sc)) != 0) {
4136                 device_printf(sc->sc_dev,
4137                     "%s: could not load firmware, error %d\n", __func__, error);
4138                 return;
4139         }
4140
4141         error = iwn_reset(sc);
4142         if (error != 0) {
4143                 device_printf(sc->sc_dev,
4144                     "%s: could not reset adapter, error %d\n", __func__, error);
4145                 return;
4146         }
4147
4148         iwn_mem_lock(sc);
4149         iwn_mem_read(sc, IWN_CLOCK_CTL);
4150         iwn_mem_write(sc, IWN_CLOCK_CTL, 0xa00);
4151         iwn_mem_read(sc, IWN_CLOCK_CTL);
4152         iwn_mem_unlock(sc);
4153
4154         DELAY(20);
4155
4156         iwn_mem_lock(sc);
4157         tmp = iwn_mem_read(sc, IWN_MEM_PCIDEV);
4158         iwn_mem_write(sc, IWN_MEM_PCIDEV, tmp | 0x800);
4159         iwn_mem_unlock(sc);
4160
4161         iwn_mem_lock(sc);
4162         tmp = iwn_mem_read(sc, IWN_MEM_POWER);
4163         iwn_mem_write(sc, IWN_MEM_POWER, tmp & ~0x03000000);
4164         iwn_mem_unlock(sc);
4165
4166         iwn_hw_config(sc);
4167
4168         /* init Rx ring */
4169         iwn_mem_lock(sc);
4170         IWN_WRITE(sc, IWN_RX_CONFIG, 0);
4171         IWN_WRITE(sc, IWN_RX_WIDX, 0);
4172         /* Rx ring is aligned on a 256-byte boundary */
4173         IWN_WRITE(sc, IWN_RX_BASE, sc->rxq.desc_dma.paddr >> 8);
4174         /* shared area is aligned on a 16-byte boundary */
4175         IWN_WRITE(sc, IWN_RW_WIDX_PTR, (sc->shared_dma.paddr +
4176             offsetof(struct iwn_shared, closed_count)) >> 4);
4177         IWN_WRITE(sc, IWN_RX_CONFIG, 0x80601000);
4178         iwn_mem_unlock(sc);
4179
4180         IWN_WRITE(sc, IWN_RX_WIDX, (IWN_RX_RING_COUNT - 1) & ~7);
4181
4182         iwn_mem_lock(sc);
4183         iwn_mem_write(sc, IWN_TX_ACTIVE, 0);
4184
4185         /* set physical address of "keep warm" page */
4186         IWN_WRITE(sc, IWN_KW_BASE, sc->kw_dma.paddr >> 4);
4187
4188         /* init Tx rings */
4189         for (qid = 0; qid < IWN_NTXQUEUES; qid++) {
4190                 struct iwn_tx_ring *txq = &sc->txq[qid];
4191                 IWN_WRITE(sc, IWN_TX_BASE(qid), txq->desc_dma.paddr >> 8);
4192                 IWN_WRITE(sc, IWN_TX_CONFIG(qid), 0x80000008);
4193         }
4194         iwn_mem_unlock(sc);
4195
4196         /* clear "radio off" and "disable command" bits (reversed logic) */
4197         IWN_WRITE(sc, IWN_UCODE_CLR, IWN_RADIO_OFF);
4198         IWN_WRITE(sc, IWN_UCODE_CLR, IWN_DISABLE_CMD);
4199
4200         /* clear any pending interrupts */
4201         IWN_WRITE(sc, IWN_INTR, 0xffffffff);
4202         /* enable interrupts */
4203         IWN_WRITE(sc, IWN_MASK, IWN_INTR_MASK);
4204
4205         /* not sure why/if this is necessary... */
4206         IWN_WRITE(sc, IWN_UCODE_CLR, IWN_RADIO_OFF);
4207         IWN_WRITE(sc, IWN_UCODE_CLR, IWN_RADIO_OFF);
4208
4209         /* check that the radio is not disabled by RF switch */
4210         if (!(IWN_READ(sc, IWN_GPIO_CTL) & IWN_GPIO_RF_ENABLED)) {
4211                 device_printf(sc->sc_dev,
4212                     "radio is disabled by hardware switch\n");
4213                 return;
4214         }
4215
4216         error = iwn_transfer_firmware(sc);
4217         if (error != 0) {
4218                 device_printf(sc->sc_dev,
4219                     "%s: could not load firmware, error %d\n", __func__, error);
4220                 return;
4221         }
4222
4223         /* firmware has notified us that it is alive.. */
4224         iwn_post_alive(sc);     /* ..do post alive initialization */
4225
4226         sc->rawtemp = sc->ucode_info.temp[3].chan20MHz;
4227         sc->temp = iwn_get_temperature(sc);
4228         DPRINTF(sc, IWN_DEBUG_RESET, "%s: temperature=%d\n",
4229            __func__, sc->temp);
4230
4231         error = iwn_config(sc);
4232         if (error != 0) {
4233                 device_printf(sc->sc_dev,
4234                     "%s: could not configure device, error %d\n",
4235                     __func__, error);
4236                 return;
4237         }
4238
4239         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4240         ifp->if_drv_flags |= IFF_DRV_RUNNING;
4241 }
4242
4243 void
4244 iwn_init(void *arg)
4245 {
4246         struct iwn_softc *sc = arg;
4247         struct ifnet *ifp = sc->sc_ifp;
4248         struct ieee80211com *ic = ifp->if_l2com;
4249
4250         IWN_LOCK(sc);
4251         iwn_init_locked(sc);
4252         IWN_UNLOCK(sc);
4253
4254         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
4255                 ieee80211_start_all(ic);
4256 }
4257
4258 void
4259 iwn_stop_locked(struct iwn_softc *sc)
4260 {
4261         struct ifnet *ifp = sc->sc_ifp;
4262         uint32_t tmp;
4263         int i;
4264
4265         IWN_LOCK_ASSERT(sc);
4266
4267         IWN_WRITE(sc, IWN_RESET, IWN_NEVO_RESET);
4268
4269         sc->sc_tx_timer = 0;
4270         callout_stop(&sc->sc_timer_to);
4271         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
4272
4273         /* disable interrupts */
4274         IWN_WRITE(sc, IWN_MASK, 0);
4275         IWN_WRITE(sc, IWN_INTR, 0xffffffff);
4276         IWN_WRITE(sc, IWN_INTR_STATUS, 0xffffffff);
4277
4278         /* reset all Tx rings */
4279         for (i = 0; i < IWN_NTXQUEUES; i++)
4280                 iwn_reset_tx_ring(sc, &sc->txq[i]);
4281
4282         /* reset Rx ring */
4283         iwn_reset_rx_ring(sc, &sc->rxq);
4284
4285         iwn_mem_lock(sc);
4286         iwn_mem_write(sc, IWN_MEM_CLOCK2, 0x200);
4287         iwn_mem_unlock(sc);
4288
4289         DELAY(5);
4290         iwn_stop_master(sc);
4291
4292         tmp = IWN_READ(sc, IWN_RESET);
4293         IWN_WRITE(sc, IWN_RESET, tmp | IWN_SW_RESET);
4294 }
4295
4296 void
4297 iwn_stop(struct iwn_softc *sc)
4298 {
4299         IWN_LOCK(sc);
4300         iwn_stop_locked(sc);
4301         IWN_UNLOCK(sc);
4302 }
4303
4304 /*
4305  * Callback from net80211 to start a scan.
4306  */
4307 static void
4308 iwn_scan_start(struct ieee80211com *ic)
4309 {
4310         struct ifnet *ifp = ic->ic_ifp;
4311         struct iwn_softc *sc = ifp->if_softc;
4312
4313         IWN_LOCK(sc);
4314         /* make the link LED blink while we're scanning */
4315         iwn_set_led(sc, IWN_LED_LINK, 20, 2);
4316         IWN_UNLOCK(sc);
4317 }
4318
4319 /*
4320  * Callback from net80211 to terminate a scan.
4321  */
4322 static void
4323 iwn_scan_end(struct ieee80211com *ic)
4324 {
4325         /* ignore */
4326 }
4327
4328 /*
4329  * Callback from net80211 to force a channel change.
4330  */
4331 static void
4332 iwn_set_channel(struct ieee80211com *ic)
4333 {
4334         struct ifnet *ifp = ic->ic_ifp;
4335         struct iwn_softc *sc = ifp->if_softc;
4336         struct ieee80211vap *vap;
4337         const struct ieee80211_channel *c = ic->ic_curchan;
4338         int error;
4339
4340         vap = TAILQ_FIRST(&ic->ic_vaps);        /* XXX */
4341
4342         IWN_LOCK(sc);
4343         if (c != sc->sc_curchan) {
4344                 sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq);
4345                 sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags);
4346                 sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq);
4347                 sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags);
4348
4349                 error = iwn_config(sc);
4350                 if (error != 0) {
4351                         DPRINTF(sc, IWN_DEBUG_STATE,
4352                             "%s: set chan failed, cancel scan\n",
4353                             __func__);
4354                         //XXX Handle failed scan correctly
4355                         ieee80211_cancel_scan(vap);
4356                 }
4357         }
4358         IWN_UNLOCK(sc);
4359 }
4360
4361 /*
4362  * Callback from net80211 to start scanning of the current channel.
4363  */
4364 static void
4365 iwn_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
4366 {
4367         struct ieee80211vap *vap = ss->ss_vap;
4368         struct iwn_softc *sc = vap->iv_ic->ic_ifp->if_softc;
4369         int error;
4370
4371         IWN_LOCK(sc);
4372         error = iwn_scan(sc);
4373         IWN_UNLOCK(sc);
4374         if (error != 0)
4375                 ieee80211_cancel_scan(vap);
4376 }
4377
4378 /*
4379  * Callback from net80211 to handle the minimum dwell time being met.
4380  * The intent is to terminate the scan but we just let the firmware
4381  * notify us when it's finished as we have no safe way to abort it.
4382  */
4383 static void
4384 iwn_scan_mindwell(struct ieee80211_scan_state *ss)
4385 {
4386         /* NB: don't try to abort scan; wait for firmware to finish */
4387 }
4388
4389 static void
4390 iwn_hwreset(void *arg0, int pending)
4391 {
4392         struct iwn_softc *sc = arg0;
4393         struct ifnet *ifp = sc->sc_ifp;
4394         struct ieee80211com *ic = ifp->if_l2com;
4395
4396         iwn_init(sc);
4397         ieee80211_notify_radio(ic, 1);
4398 }
4399
4400 static void
4401 iwn_radioon(void *arg0, int pending)
4402 {
4403         struct iwn_softc *sc = arg0;
4404
4405         iwn_init(sc);
4406 }
4407
4408 static void
4409 iwn_radiooff(void *arg0, int pending)
4410 {
4411         struct iwn_softc *sc = arg0;
4412         struct ifnet *ifp = sc->sc_ifp;
4413         struct ieee80211com *ic = ifp->if_l2com;
4414
4415         IWN_LOCK(sc);
4416         ieee80211_notify_radio(ic, 0);
4417         iwn_stop_locked(sc);
4418         IWN_UNLOCK(sc);
4419 }
4420
4421 static void
4422 iwn_sysctlattach(struct iwn_softc *sc)
4423 {
4424         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
4425         struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
4426
4427 #ifdef IWN_DEBUG
4428         sc->sc_debug = 0;
4429         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
4430             "debug", CTLFLAG_RW, &sc->sc_debug, 0, "control debugging printfs");
4431 #endif
4432 }
4433
4434 #ifdef IWN_DEBUG
4435 static const char *
4436 iwn_intr_str(uint8_t cmd)
4437 {
4438         switch (cmd) {
4439         /* Notifications */
4440         case IWN_UC_READY:              return "UC_READY";
4441         case IWN_ADD_NODE_DONE:         return "ADD_NODE_DONE";
4442         case IWN_TX_DONE:               return "TX_DONE";
4443         case IWN_START_SCAN:            return "START_SCAN";
4444         case IWN_STOP_SCAN:             return "STOP_SCAN";
4445         case IWN_RX_STATISTICS:         return "RX_STATS";
4446         case IWN_BEACON_STATISTICS:     return "BEACON_STATS";
4447         case IWN_STATE_CHANGED:         return "STATE_CHANGED";
4448         case IWN_BEACON_MISSED:         return "BEACON_MISSED";
4449         case IWN_AMPDU_RX_START:        return "AMPDU_RX_START";
4450         case IWN_AMPDU_RX_DONE:         return "AMPDU_RX_DONE";
4451         case IWN_RX_DONE:               return "RX_DONE";
4452
4453         /* Command Notifications */
4454         case IWN_CMD_CONFIGURE:         return "IWN_CMD_CONFIGURE";
4455         case IWN_CMD_ASSOCIATE:         return "IWN_CMD_ASSOCIATE";
4456         case IWN_CMD_EDCA_PARAMS:       return "IWN_CMD_EDCA_PARAMS";
4457         case IWN_CMD_TSF:               return "IWN_CMD_TSF";
4458         case IWN_CMD_TX_LINK_QUALITY:   return "IWN_CMD_TX_LINK_QUALITY";
4459         case IWN_CMD_SET_LED:           return "IWN_CMD_SET_LED";
4460         case IWN_CMD_SET_POWER_MODE:    return "IWN_CMD_SET_POWER_MODE";
4461         case IWN_CMD_SCAN:              return "IWN_CMD_SCAN";
4462         case IWN_CMD_TXPOWER:           return "IWN_CMD_TXPOWER";
4463         case IWN_CMD_BLUETOOTH:         return "IWN_CMD_BLUETOOTH";
4464         case IWN_CMD_SET_CRITICAL_TEMP: return "IWN_CMD_SET_CRITICAL_TEMP";
4465         case IWN_SENSITIVITY:           return "IWN_SENSITIVITY";
4466         case IWN_PHY_CALIB:             return "IWN_PHY_CALIB";
4467         }
4468         return "UNKNOWN INTR NOTIF/CMD";
4469 }
4470 #endif /* IWN_DEBUG */
4471
4472 static device_method_t iwn_methods[] = {
4473         /* Device interface */
4474         DEVMETHOD(device_probe,         iwn_probe),
4475         DEVMETHOD(device_attach,        iwn_attach),
4476         DEVMETHOD(device_detach,        iwn_detach),
4477         DEVMETHOD(device_shutdown,      iwn_shutdown),
4478         DEVMETHOD(device_suspend,       iwn_suspend),
4479         DEVMETHOD(device_resume,        iwn_resume),
4480
4481         { 0, 0 }
4482 };
4483
4484 static driver_t iwn_driver = {
4485         "iwn",
4486         iwn_methods,
4487         sizeof (struct iwn_softc)
4488 };
4489 static devclass_t iwn_devclass;
4490 DRIVER_MODULE(iwn, pci, iwn_driver, iwn_devclass, 0, 0);
4491 MODULE_DEPEND(iwn, pci, 1, 1, 1);
4492 MODULE_DEPEND(iwn, firmware, 1, 1, 1);
4493 MODULE_DEPEND(iwn, wlan, 1, 1, 1);
4494 MODULE_DEPEND(iwn, wlan_amrr, 1, 1, 1);