Sync usage with man page.
[netbsd-mini2440.git] / sys / dev / pci / if_iwn.c
blobe95e9764045ffec041ab9524b0bf12773d8c6b33
1 /* $NetBSD: if_iwn.c,v 1.34 2009/11/21 14:51:04 njoly Exp $ */
2 /* $OpenBSD: if_iwn.c,v 1.49 2009/03/29 21:53:52 sthen Exp $ */
4 /*-
5 * Copyright (c) 2007, 2008
6 * Damien Bergamini <damien.bergamini@free.fr>
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.
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.
22 * Driver for Intel Wireless WiFi Link 4965 and Intel WiFi Link 5000 Series
23 * 802.11 network adapters.
25 #include <sys/cdefs.h>
26 __KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.34 2009/11/21 14:51:04 njoly Exp $");
28 #include "bpfilter.h"
30 #include <sys/param.h>
31 #include <sys/sockio.h>
32 #include <sys/sysctl.h>
33 #include <sys/mbuf.h>
34 #include <sys/kernel.h>
35 #include <sys/socket.h>
36 #include <sys/systm.h>
37 #include <sys/malloc.h>
38 #include <sys/mutex.h>
39 #include <sys/conf.h>
40 #include <sys/kauth.h>
41 #include <sys/callout.h>
43 #include <machine/bus.h>
44 #include <machine/endian.h>
45 #include <machine/intr.h>
47 #include <dev/pci/pcireg.h>
48 #include <dev/pci/pcivar.h>
49 #include <dev/pci/pcidevs.h>
51 #if NBPFILTER > 0
52 #include <net/bpf.h>
53 #endif
54 #include <net/if.h>
55 #include <net/if_arp.h>
56 #include <net/if_dl.h>
57 #include <net/if_media.h>
58 #include <net/if_types.h>
60 #include <netinet/in.h>
61 #include <netinet/in_systm.h>
62 #include <netinet/in_var.h>
63 #include <net/if_ether.h>
64 #include <netinet/ip.h>
66 #include <net80211/ieee80211_var.h>
67 #include <net80211/ieee80211_amrr.h>
68 #include <net80211/ieee80211_radiotap.h>
70 #include <dev/firmload.h>
72 #include <dev/pci/if_iwnreg.h>
73 #include <dev/pci/if_iwnvar.h>
75 static const pci_product_id_t iwn_devices[] = {
76 PCI_PRODUCT_INTEL_PRO_WL_4965AGN_1,
77 PCI_PRODUCT_INTEL_PRO_WL_4965AGN_2,
78 PCI_PRODUCT_INTEL_PRO_WL_5100AGN_1,
79 PCI_PRODUCT_INTEL_PRO_WL_5100AGN_2,
80 #ifdef notyet
81 PCI_PRODUCT_INTEL_PRO_WL_5150AGN_1,
82 PCI_PRODUCT_INTEL_PRO_WL_5150AGN_2,
83 #endif
84 PCI_PRODUCT_INTEL_PRO_WL_5300AGN_1,
85 PCI_PRODUCT_INTEL_PRO_WL_5300AGN_2,
86 PCI_PRODUCT_INTEL_PRO_WL_5350AGN_1,
87 PCI_PRODUCT_INTEL_PRO_WL_5350AGN_2,
88 #ifdef notyet
89 PCI_PRODUCT_INTEL_WIFI_LINK_4965_1,
90 PCI_PRODUCT_INTEL_WIFI_LINK_4965_2,
91 PCI_PRODUCT_INTEL_WIFI_LINK_5100_1,
92 PCI_PRODUCT_INTEL_WIFI_LINK_5100_2,
93 PCI_PRODUCT_INTEL_WIFI_LINK_5150_1,
94 PCI_PRODUCT_INTEL_WIFI_LINK_5150_2,
95 PCI_PRODUCT_INTEL_WIFI_LINK_5300_1,
96 PCI_PRODUCT_INTEL_WIFI_LINK_5300_2,
97 PCI_PRODUCT_INTEL_WIFI_LINK_5350_1,
98 PCI_PRODUCT_INTEL_WIFI_LINK_5350_2,
99 PCI_PRODUCT_INTEL_WIFI_LINK_6000_1,
100 PCI_PRODUCT_INTEL_WIFI_LINK_6000_2,
101 PCI_PRODUCT_INTEL_WIFI_LINK_6000_3,
102 PCI_PRODUCT_INTEL_WIFI_LINK_6000_4,
103 PCI_PRODUCT_INTEL_WIFI_LINK_6050_1,
104 PCI_PRODUCT_INTEL_WIFI_LINK_6050_2,
105 PCI_PRODUCT_INTEL_WIFI_LINK_6050_3,
106 PCI_PRODUCT_INTEL_WIFI_LINK_6050_4,
107 PCI_PRODUCT_INTEL_WIFI_LINK_1000_1,
108 PCI_PRODUCT_INTEL_WIFI_LINK_1000_2,
109 #endif
113 * Supported rates for 802.11a/b/g modes (in 500Kbps unit).
115 static const struct ieee80211_rateset iwn_rateset_11a =
116 { 8, { 12, 18, 24, 36, 48, 72, 96, 108 } };
118 static const struct ieee80211_rateset iwn_rateset_11b =
119 { 4, { 2, 4, 11, 22 } };
121 static const struct ieee80211_rateset iwn_rateset_11g =
122 { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
125 static int iwn_match(device_t , struct cfdata *, void *);
126 static void iwn_attach(device_t , device_t, void *);
127 static int iwn_detach(device_t, int);
129 const struct iwn_hal *iwn_hal_attach(struct iwn_softc *);
130 static int iwn_nic_lock(struct iwn_softc *);
131 static int iwn_eeprom_lock(struct iwn_softc *);
132 static int iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
133 static void iwn_radiotap_attach(struct iwn_softc *);
134 static int iwn_dma_contig_alloc(bus_dma_tag_t, struct iwn_dma_info *,
135 void **, bus_size_t, bus_size_t, int);
136 static void iwn_dma_contig_free(struct iwn_dma_info *);
137 static int iwn_alloc_sched(struct iwn_softc *);
138 static void iwn_free_sched(struct iwn_softc *);
139 static int iwn_alloc_kw(struct iwn_softc *);
140 static void iwn_free_kw(struct iwn_softc *);
141 static int iwn_alloc_fwmem(struct iwn_softc *);
142 static void iwn_free_fwmem(struct iwn_softc *);
143 static struct iwn_rbuf *iwn_alloc_rbuf(struct iwn_softc *);
144 static void iwn_free_rbuf(struct mbuf *, void *, size_t, void *);
145 static int iwn_alloc_rpool(struct iwn_softc *);
146 static void iwn_free_rpool(struct iwn_softc *);
147 static int iwn_alloc_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
148 static void iwn_reset_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
149 static void iwn_free_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
150 static int iwn_alloc_tx_ring(struct iwn_softc *, struct iwn_tx_ring *,
151 int, int);
152 static void iwn_reset_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
153 static void iwn_free_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
154 static int iwn_read_eeprom(struct iwn_softc *);
155 static void iwn4965_read_eeprom(struct iwn_softc *);
156 static void iwn5000_read_eeprom(struct iwn_softc *);
157 static void iwn_read_eeprom_channels(struct iwn_softc *, int, uint32_t);
158 static struct ieee80211_node *iwn_node_alloc(struct ieee80211_node_table *);
159 static void iwn_newassoc(struct ieee80211_node *, int);
160 static int iwn_media_change(struct ifnet *);
161 static int iwn_newstate(struct ieee80211com *, enum ieee80211_state, int);
162 static void iwn_iter_func(void *, struct ieee80211_node *);
163 static void iwn_calib_timeout(void *);
164 #if 0
165 static int iwn_ccmp_decap(struct iwn_softc *, struct mbuf *,
166 struct ieee80211_key *);
167 #endif
168 static void iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *);
169 static void iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *,
170 struct iwn_rx_data *);
171 static void iwn5000_rx_calib_results(struct iwn_softc *,
172 struct iwn_rx_desc *, struct iwn_rx_data *);
173 static void iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *,
174 struct iwn_rx_data *);
175 static void iwn4965_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
176 struct iwn_rx_data *);
177 static void iwn5000_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
178 struct iwn_rx_data *);
179 static void iwn_tx_done(struct iwn_softc *, struct iwn_rx_desc *, int,
180 uint8_t);
181 static void iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *);
182 static void iwn_notif_intr(struct iwn_softc *);
183 static void iwn_wakeup_intr(struct iwn_softc *);
184 static void iwn_fatal_intr(struct iwn_softc *);
185 static int iwn_intr(void *);
186 static void iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t,
187 uint16_t);
188 static void iwn5000_update_sched(struct iwn_softc *, int, int, uint8_t,
189 uint16_t);
190 static void iwn5000_reset_sched(struct iwn_softc *, int, int);
191 static int iwn_tx(struct iwn_softc *, struct mbuf *,
192 struct ieee80211_node *, int);
193 static void iwn_start(struct ifnet *);
194 static void iwn_watchdog(struct ifnet *);
195 static int iwn_ioctl(struct ifnet *, u_long, void *);
196 static int iwn_cmd(struct iwn_softc *, int, const void *, int, int);
197 static int iwn_wme_update(struct ieee80211com *);
198 static int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
199 int);
200 static int iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *,
201 int);
202 static int iwn_set_link_quality(struct iwn_softc *,
203 struct ieee80211_node *);
204 static int iwn_add_broadcast_node(struct iwn_softc *, int);
205 static void iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
206 static int iwn_set_critical_temp(struct iwn_softc *);
207 static int iwn_set_timing(struct iwn_softc *, struct ieee80211_node *);
208 //static void iwn4965_power_calibration(struct iwn_softc *, int);
209 static int iwn4965_set_txpower(struct iwn_softc *, int);
210 static int iwn5000_set_txpower(struct iwn_softc *, int);
211 static int iwn4965_get_rssi(const struct iwn_rx_stat *);
212 static int iwn5000_get_rssi(const struct iwn_rx_stat *);
213 static int iwn_get_noise(const struct iwn_rx_general_stats *);
214 static int iwn4965_get_temperature(struct iwn_softc *);
215 static int iwn5000_get_temperature(struct iwn_softc *);
216 static int iwn_init_sensitivity(struct iwn_softc *);
217 static void iwn_collect_noise(struct iwn_softc *,
218 const struct iwn_rx_general_stats *);
219 static int iwn4965_init_gains(struct iwn_softc *);
220 static int iwn5000_init_gains(struct iwn_softc *);
221 static int iwn4965_set_gains(struct iwn_softc *);
222 static int iwn5000_set_gains(struct iwn_softc *);
223 static void iwn_tune_sensitivity(struct iwn_softc *,
224 const struct iwn_rx_stats *);
225 static int iwn_send_sensitivity(struct iwn_softc *);
226 // XXX static int iwn_set_pslevel(struct iwn_softc *, int, int, int);
227 static int iwn_config(struct iwn_softc *);
228 static int iwn_scan(struct iwn_softc *, uint16_t);
229 static int iwn_auth(struct iwn_softc *);
230 static int iwn_run(struct iwn_softc *);
231 #ifdef notyet
232 static void iwn_delete_key(struct ieee80211com *, struct ieee80211_node *,
233 struct ieee80211_key *);
234 #endif
235 #ifndef IEEE80211_NO_HT
236 static int iwn_ampdu_rx_start(struct ieee80211com *,
237 struct ieee80211_node *, uint8_t, uint16_t);
238 static void iwn_ampdu_rx_stop(struct ieee80211com *,
239 struct ieee80211_node *, uint8_t, uint16_t);
240 static int iwn_ampdu_tx_start(struct ieee80211com *,
241 struct ieee80211_node *, uint8_t, uint16_t);
242 static void iwn_ampdu_tx_stop(struct ieee80211com *,
243 struct ieee80211_node *, uint8_t, uint16_t);
244 static void iwn4965_ampdu_tx_start(struct iwn_softc *,
245 struct ieee80211_node *, uint8_t, uint16_t);
246 static void iwn4965_ampdu_tx_stop(struct iwn_softc *,
247 uint8_t, uint16_t);
248 static void iwn5000_ampdu_tx_start(struct iwn_softc *,
249 struct ieee80211_node *, uint8_t, uint16_t);
250 static void iwn5000_ampdu_tx_stop(struct iwn_softc *,
251 uint8_t, uint16_t);
252 #endif
253 static int iwn5000_query_calibration(struct iwn_softc *);
254 static int iwn5000_send_calibration(struct iwn_softc *);
255 static int iwn4965_post_alive(struct iwn_softc *);
256 static int iwn5000_post_alive(struct iwn_softc *);
257 static int iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *,
258 int);
259 static int iwn4965_load_firmware(struct iwn_softc *);
260 static int iwn5000_load_firmware_section(struct iwn_softc *, uint32_t,
261 const uint8_t *, int);
262 static int iwn5000_load_firmware(struct iwn_softc *);
263 static int iwn_read_firmware(struct iwn_softc *);
264 static int iwn_clock_wait(struct iwn_softc *);
265 static int iwn4965_apm_init(struct iwn_softc *);
266 static int iwn5000_apm_init(struct iwn_softc *);
267 static void iwn_apm_stop_master(struct iwn_softc *);
268 static void iwn_apm_stop(struct iwn_softc *);
269 static int iwn4965_nic_config(struct iwn_softc *);
270 static int iwn5000_nic_config(struct iwn_softc *);
271 static int iwn_hw_init(struct iwn_softc *);
272 static void iwn_hw_stop(struct iwn_softc *);
273 static int iwn_init(struct ifnet *);
274 static void iwn_stop(struct ifnet *, int);
275 static void iwn_fix_channel(struct ieee80211com *, struct mbuf *);
276 static bool iwn_resume(device_t, pmf_qual_t);
278 #define IWN_DEBUG
279 #ifdef IWN_DEBUG
280 #define DPRINTF(x) do { if (iwn_debug > 0) printf x; } while (0)
281 #define DPRINTFN(n, x) do { if (iwn_debug >= (n)) printf x; } while (0)
282 int iwn_debug = 0;
283 #else
284 #define DPRINTF(x)
285 #define DPRINTFN(n, x)
286 #endif
287 #ifdef IWN_DEBUG
288 static void iwn4965_print_power_group(struct iwn_softc *, int);
289 #endif
291 static const struct iwn_hal iwn4965_hal = {
292 iwn4965_load_firmware,
293 iwn4965_read_eeprom,
294 iwn4965_post_alive,
295 iwn4965_apm_init,
296 iwn4965_nic_config,
297 iwn4965_update_sched,
298 iwn4965_get_temperature,
299 iwn4965_get_rssi,
300 iwn4965_set_txpower,
301 iwn4965_init_gains,
302 iwn4965_set_gains,
303 iwn4965_add_node,
304 iwn4965_tx_done,
305 #ifndef IEEE80211_NO_HT
306 iwn4965_ampdu_tx_start,
307 iwn4965_ampdu_tx_stop,
308 #endif
309 &iwn4965_sensitivity_limits,
310 IWN4965_NTXQUEUES,
311 IWN4965_ID_BROADCAST,
312 IWN4965_RXONSZ,
313 IWN4965_SCHEDSZ,
314 IWN4965_FW_TEXT_MAXSZ,
315 IWN4965_FW_DATA_MAXSZ,
316 IWN4965_FWSZ,
317 IWN4965_SCHED_TXFACT
320 static const struct iwn_hal iwn5000_hal = {
321 iwn5000_load_firmware,
322 iwn5000_read_eeprom,
323 iwn5000_post_alive,
324 iwn5000_apm_init,
325 iwn5000_nic_config,
326 iwn5000_update_sched,
327 iwn5000_get_temperature,
328 iwn5000_get_rssi,
329 iwn5000_set_txpower,
330 iwn5000_init_gains,
331 iwn5000_set_gains,
332 iwn5000_add_node,
333 iwn5000_tx_done,
334 #ifndef IEEE80211_NO_HT
335 iwn5000_ampdu_tx_start,
336 iwn5000_ampdu_tx_stop,
337 #endif
338 &iwn5000_sensitivity_limits,
339 IWN5000_NTXQUEUES,
340 IWN5000_ID_BROADCAST,
341 IWN5000_RXONSZ,
342 IWN5000_SCHEDSZ,
343 IWN5000_FW_TEXT_MAXSZ,
344 IWN5000_FW_DATA_MAXSZ,
345 IWN5000_FWSZ,
346 IWN5000_SCHED_TXFACT
349 CFATTACH_DECL_NEW(iwn, sizeof(struct iwn_softc), iwn_match, iwn_attach,
350 iwn_detach, NULL);
353 static int
354 iwn_match(device_t parent, cfdata_t match __unused, void *aux)
356 struct pci_attach_args *pa = aux;
357 size_t i;
359 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
360 return 0;
362 for (i = 0; i < __arraycount(iwn_devices); i++)
363 if (PCI_PRODUCT(pa->pa_id) == iwn_devices[i])
364 return 1;
366 return 0;
369 static void
370 iwn_attach(device_t parent __unused, device_t self, void *aux)
372 struct iwn_softc *sc = device_private(self);
373 struct ieee80211com *ic = &sc->sc_ic;
374 struct ifnet *ifp = &sc->sc_ec.ec_if;
375 struct pci_attach_args *pa = aux;
376 const struct iwn_hal *hal;
377 const char *intrstr;
378 char devinfo[256];
379 pci_intr_handle_t ih;
380 pcireg_t memtype, reg;
381 int i, error, revision;
383 sc->sc_dev = self;
384 sc->sc_pct = pa->pa_pc;
385 sc->sc_pcitag = pa->pa_tag;
387 callout_init(&sc->calib_to, 0);
388 callout_setfunc(&sc->calib_to, iwn_calib_timeout, sc);
390 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof devinfo);
391 revision = PCI_REVISION(pa->pa_class);
392 aprint_normal(": %s (rev. 0x%02x)\n", devinfo, revision);
395 * Get the offset of the PCI Express Capability Structure in PCI
396 * Configuration Space (the vendor driver hard-codes it as E0h.)
398 error = pci_get_capability(sc->sc_pct, sc->sc_pcitag,
399 PCI_CAP_PCIEXPRESS, &sc->sc_cap_off, NULL);
400 if (error == 0) {
401 aprint_error_dev(self, "PCIe capability structure not found!\n");
402 return;
405 /* Clear device-specific "PCI retry timeout" register (41h). */
406 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
407 reg &= ~0xff00;
408 pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg);
410 /* enable bus-mastering */
411 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
412 reg |= PCI_COMMAND_MASTER_ENABLE;
413 pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
415 /* map the register window */
416 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, IWN_PCI_BAR0);
417 error = pci_mapreg_map(pa, IWN_PCI_BAR0, memtype, 0, &sc->sc_st,
418 &sc->sc_sh, NULL, &sc->sc_sz);
419 if (error != 0) {
420 aprint_error_dev(self, "could not map memory space\n");
421 return;
423 #if 1
424 sc->sc_dmat = pa->pa_dmat;
425 #else
426 /* XXX may not be needed */
427 if (bus_dmatag_subregion(pa->pa_dmat, 0, 3 << 30,
428 &(sc->sc_dmat), BUS_DMA_NOWAIT) != 0) {
429 aprint_error_dev(self,
430 "WARNING: failed to restrict dma range, "
431 "falling back to parent bus dma range\n");
432 sc->sc_dmat = pa->pa_dmat;
434 #endif
436 /* Install interrupt handler. */
437 if (pci_intr_map(pa, &ih) != 0) {
438 aprint_error_dev(self, "could not map interrupt\n");
439 return;
441 intrstr = pci_intr_string(sc->sc_pct, ih);
442 sc->sc_ih = pci_intr_establish(sc->sc_pct, ih, IPL_NET, iwn_intr, sc);
444 if (sc->sc_ih == NULL) {
445 aprint_error_dev(self, "could not establish interrupt");
446 if (intrstr != NULL)
447 aprint_error(" at %s", intrstr);
448 aprint_error("\n");
449 return;
451 aprint_normal_dev(self, "interrupting at %s\n", intrstr);
453 /* Attach Hardware Abstraction Layer. */
454 if ((hal = iwn_hal_attach(sc)) == NULL)
455 return;
457 /* Power ON adapter. */
458 if ((error = hal->apm_init(sc)) != 0) {
459 aprint_error_dev(self, "could not power ON adapter\n");
460 return;
463 /* Read MAC address, channels, etc from EEPROM. */
464 if ((error = iwn_read_eeprom(sc)) != 0) {
465 aprint_error_dev(self, "could not read EEPROM\n");
466 return;
469 /* Allocate DMA memory for firmware transfers. */
470 if ((error = iwn_alloc_fwmem(sc)) != 0) {
471 aprint_error_dev(self,
472 "could not allocate memory for firmware\n");
473 return;
476 /* Allocate "Keep Warm" page. */
477 if ((error = iwn_alloc_kw(sc)) != 0) {
478 aprint_error_dev(self, "could not allocate keep warm page\n");
479 goto fail1;
482 /* Allocate TX scheduler "rings". */
483 if ((error = iwn_alloc_sched(sc)) != 0) {
484 aprint_error_dev(self,
485 "could not allocate TX scheduler rings\n");
486 goto fail2;
489 /* Allocate RX buffers. */
490 if ((error = iwn_alloc_rpool(sc)) != 0) {
491 aprint_error_dev(self, "could not allocate RX buffers\n");
492 goto fail3;
495 /* Allocate TX rings (16 on 4965AGN, 20 on 5000.) */
496 for (i = 0; i < hal->ntxqs; i++) {
497 struct iwn_tx_ring *txq = &sc->txq[i];
498 error = iwn_alloc_tx_ring(sc, txq, IWN_TX_RING_COUNT, i);
499 if (error != 0) {
500 aprint_error_dev(self,
501 "could not allocate TX ring %d\n", i);
502 goto fail4;
506 /* Allocate RX ring. */
507 if (iwn_alloc_rx_ring(sc, &sc->rxq) != 0) {
508 aprint_error_dev(self, "could not allocate RX ring\n");
509 goto fail4;
512 /* Power OFF adapter. */
513 iwn_apm_stop(sc);
514 /* Clear pending interrupts. */
515 IWN_WRITE(sc, IWN_INT, 0xffffffff);
517 aprint_normal_dev(self, "MIMO %dT%dR, %.4s, address %s\n", sc->ntxchains,
518 sc->nrxchains, sc->eeprom_domain, ether_sprintf(ic->ic_myaddr));
520 /* Initialization firmware has not been loaded yet. */
521 sc->sc_flags |= IWN_FLAG_FIRST_BOOT;
523 /* Set the state of the RF kill switch */
524 sc->sc_radio = (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL);
526 ic->ic_ifp = ifp;
527 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
528 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
529 ic->ic_state = IEEE80211_S_INIT;
531 /* Set device capabilities. */
532 ic->ic_caps =
533 IEEE80211_C_IBSS | /* IBSS mode support */
534 IEEE80211_C_WPA | /* 802.11i */
535 IEEE80211_C_MONITOR | /* monitor mode supported */
536 IEEE80211_C_TXPMGT | /* tx power management */
537 IEEE80211_C_SHSLOT | /* short slot time supported */
538 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
539 IEEE80211_C_WME; /* 802.11e */
541 /* Set supported rates. */
542 ic->ic_sup_rates[IEEE80211_MODE_11B] = iwn_rateset_11b;
543 ic->ic_sup_rates[IEEE80211_MODE_11G] = iwn_rateset_11g;
544 if (sc->sc_flags & IWN_FLAG_HAS_5GHZ) {
545 ic->ic_sup_rates[IEEE80211_MODE_11A] = iwn_rateset_11a;
548 /* IBSS channel undefined for now. */
549 ic->ic_ibss_chan = &ic->ic_channels[0];
551 memset(ic->ic_des_essid, 0, IEEE80211_NWID_LEN);
552 ic->ic_des_esslen = 0;
554 ifp->if_softc = sc;
555 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
556 ifp->if_stop = iwn_stop;
557 ifp->if_init = iwn_init;
558 ifp->if_ioctl = iwn_ioctl;
559 ifp->if_start = iwn_start;
560 ifp->if_watchdog = iwn_watchdog;
561 IFQ_SET_READY(&ifp->if_snd);
562 memcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
564 if_attach(ifp);
565 ieee80211_ifattach(ic);
566 ic->ic_node_alloc = iwn_node_alloc;
567 ic->ic_newassoc = iwn_newassoc;
568 ic->ic_wme.wme_update = iwn_wme_update;
569 #ifdef notyet
570 ic->ic_updateedca = iwn_updateedca;
571 ic->ic_set_key = iwn_set_key;
572 ic->ic_delete_key = iwn_delete_key;
573 #endif
574 #ifndef IEEE80211_NO_HT
575 ic->ic_ampdu_rx_start = iwn_ampdu_rx_start;
576 ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop;
577 ic->ic_ampdu_tx_start = iwn_ampdu_tx_start;
578 ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop;
579 #endif
581 /* Override 802.11 state transition machine. */
582 sc->sc_newstate = ic->ic_newstate;
583 ic->ic_newstate = iwn_newstate;
584 ieee80211_media_init(ic, iwn_media_change, ieee80211_media_status);
586 sc->amrr.amrr_min_success_threshold = 1;
587 sc->amrr.amrr_max_success_threshold = 15;
589 if (pmf_device_register(self, NULL, iwn_resume))
590 pmf_class_network_register(self, ifp);
591 else
592 aprint_error_dev(self, "couldn't establish power handler\n");
594 iwn_radiotap_attach(sc);
596 ieee80211_announce(ic);
598 return;
600 /* Free allocated memory if something failed during attachment. */
601 fail4: while (--i >= 0)
602 iwn_free_tx_ring(sc, &sc->txq[i]);
603 iwn_free_rpool(sc);
604 fail3: iwn_free_sched(sc);
605 fail2: iwn_free_kw(sc);
606 fail1: iwn_free_fwmem(sc);
609 static int
610 iwn_detach(device_t self, int flags __unused)
612 struct iwn_softc *sc = device_private(self);
613 struct ifnet *ifp = sc->sc_ic.ic_ifp;
614 int ac;
616 iwn_stop(ifp, 1);
617 #if NBPFILTER > 0
618 if (ifp != NULL)
619 bpfdetach(ifp);
620 #endif
621 ieee80211_ifdetach(&sc->sc_ic);
622 if (ifp != NULL)
623 if_detach(ifp);
625 for (ac = 0; ac < sc->sc_hal->ntxqs; ac++)
626 iwn_free_tx_ring(sc, &sc->txq[ac]);
627 iwn_free_rx_ring(sc, &sc->rxq);
628 iwn_free_rpool(sc);
629 iwn_free_sched(sc);
631 if (sc->sc_ih != NULL) {
632 pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
633 sc->sc_ih = NULL;
636 bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
638 return 0;
641 const struct iwn_hal *
642 iwn_hal_attach(struct iwn_softc *sc)
644 sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf;
646 switch (sc->hw_type) {
647 case IWN_HW_REV_TYPE_4965:
648 sc->sc_hal = &iwn4965_hal;
649 sc->fwname = "iwlwifi-4965-1.ucode";
650 sc->critical_temp = IWN_CTOK(110);
651 sc->txantmsk = IWN_ANT_A | IWN_ANT_B;
652 sc->rxantmsk = IWN_ANT_ABC;
653 sc->ntxchains = 2;
654 sc->nrxchains = 3;
655 break;
656 case IWN_HW_REV_TYPE_5100:
657 sc->sc_hal = &iwn5000_hal;
658 sc->fwname = "iwlwifi-5000-1.ucode";
659 sc->critical_temp = 110;
660 sc->txantmsk = IWN_ANT_B;
661 sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
662 sc->ntxchains = 1;
663 sc->nrxchains = 2;
664 break;
665 case IWN_HW_REV_TYPE_5150:
666 sc->sc_hal = &iwn5000_hal;
667 sc->fwname = "iwlwifi-5150-1.ucode";
668 /* NB: critical temperature will be read from EEPROM. */
669 sc->txantmsk = IWN_ANT_A;
670 sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
671 sc->ntxchains = 1;
672 sc->nrxchains = 2;
673 break;
674 case IWN_HW_REV_TYPE_5300:
675 case IWN_HW_REV_TYPE_5350:
676 sc->sc_hal = &iwn5000_hal;
677 sc->fwname = "iwlwifi-5000-1.ucode";
678 sc->critical_temp = 110;
679 sc->txantmsk = sc->rxantmsk = IWN_ANT_ABC;
680 sc->ntxchains = sc->nrxchains = 3;
681 break;
682 #ifdef notyet
683 case IWN_HW_REV_TYPE_1000:
684 sc->sc_hal = &iwn5000_hal;
685 sc->fwname = "iwn-1000";
686 sc->critical_temp = 110;
687 sc->txantmsk = IWN_ANT_A;
688 sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
689 sc->ntxchains = 1;
690 sc->nrxchains = 2;
691 break;
692 case IWN_HW_REV_TYPE_6000:
693 sc->sc_hal = &iwn5000_hal;
694 sc->fwname = "iwn-6000";
695 sc->critical_temp = 110;
696 sc->txantmsk = IWN_ANT_ABC;
697 sc->rxantmsk = IWN_ANT_ABC;
698 sc->ntxchains = 3;
699 sc->nrxchains = 3;
700 break;
701 case IWN_HW_REV_TYPE_6050:
702 sc->sc_hal = &iwn5000_hal;
703 sc->fwname = "iwn-6050";
704 sc->critical_temp = 110;
705 sc->txantmsk = IWN_ANT_ABC;
706 sc->rxantmsk = IWN_ANT_ABC;
707 sc->ntxchains = 3;
708 sc->nrxchains = 3;
709 break;
710 #endif
711 default:
712 printf(": adapter type %d not supported\n", sc->hw_type);
713 return NULL;
715 return sc->sc_hal;
718 #if 0
720 * Attach the adapter's on-board thermal sensor to the sensors framework.
722 void
723 iwn_sensor_attach(struct iwn_softc *sc)
725 strlcpy(sc->sensordev.xname, sc->sc_dev.dv_xname,
726 sizeof sc->sensordev.xname);
727 sc->sensor.type = SENSOR_TEMP;
728 /* Temperature is not valid unless interface is up. */
729 sc->sensor.value = 0;
730 sc->sensor.flags = SENSOR_FINVALID;
731 sensor_attach(&sc->sensordev, &sc->sensor);
732 sensordev_install(&sc->sensordev);
734 #endif /* 0 */
737 * Attach the interface to 802.11 radiotap.
739 static void
740 iwn_radiotap_attach(struct iwn_softc *sc)
742 struct ifnet *ifp = sc->sc_ic.ic_ifp;
743 #if NBPFILTER > 0
744 bpfattach2(ifp, DLT_IEEE802_11_RADIO,
745 sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
746 &sc->sc_drvbpf);
748 sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
749 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
750 sc->sc_rxtap.wr_ihdr.it_present = htole32(IWN_RX_RADIOTAP_PRESENT);
752 sc->sc_txtap_len = sizeof sc->sc_txtapu;
753 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
754 sc->sc_txtap.wt_ihdr.it_present = htole32(IWN_TX_RADIOTAP_PRESENT);
755 #endif
758 #if 0 /* XXX */
760 * Build a beacon frame that the firmware will broadcast periodically in
761 * IBSS or HostAP modes.
763 static int
764 iwn_setup_beacon(struct iwn_softc *sc, struct ieee80211_node *ni)
766 struct ieee80211com *ic = &sc->sc_ic;
767 struct iwn_tx_ring *ring = &sc->txq[4];
768 struct iwn_tx_desc *desc;
769 struct iwn_tx_data *data;
770 struct iwn_tx_cmd *cmd;
771 struct iwn_cmd_beacon *bcn;
772 struct ieee80211_beacon_offsets bo;
773 struct mbuf *m0;
774 bus_addr_t paddr;
775 int error;
777 desc = &ring->desc[ring->cur];
778 data = &ring->data[ring->cur];
779 m0 = ieee80211_beacon_alloc(ic, ni, &bo);
780 if (m0 == NULL) {
781 aprint_error_dev(sc->sc_dev, "could not allocate beacon frame\n"
783 return ENOMEM;
785 cmd = &ring->cmd[ring->cur];
786 cmd->code = IWN_CMD_SET_BEACON;
787 cmd->flags = 0;
788 cmd->qid = ring->qid;
789 cmd->idx = ring->cur;
791 bcn = (struct iwn_cmd_beacon *)cmd->data;
792 memset(bcn, 0, sizeof (struct iwn_cmd_beacon));
793 bcn->id = sc->sc_hal->broadcast_id;
794 bcn->lifetime = htole32(IWN_LIFETIME_INFINITE);
795 bcn->len = htole16(m0->m_pkthdr.len);
796 #if 0
798 bcn->rate = (ic->ic_curmode == IEEE80211_MODE_11A) ?
799 iwn_plcp_signal(12) : iwn_plcp_signal(2);
800 #endif
801 bcn->flags2 = 0x2; /* RATE_MCS_CCK_MSK */
802 bcn->flags = htole32(IWN_TX_AUTO_SEQ | IWN_TX_INSERT_TSTAMP;
803 // XXX | IWN_TX_USE_NODE_RATE);
805 /* save and trim IEEE802.11 header */
806 m_copydata(m0, 0, sizeof (struct ieee80211_frame), (void *)&bcn->wh);
807 m_adj(m0, sizeof (struct ieee80211_frame));
809 /* assume beacon frame is contiguous */
810 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
811 BUS_DMA_READ | BUS_DMA_NOWAIT);
812 if (error) {
813 aprint_error_dev(sc->sc_dev, "could not map beacon\n");
814 m_freem(m0);
815 return error;
818 data->m = m0;
820 /* first scatter/gather segment is used by the beacon command */
821 paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
823 IWN_SET_DESC_NSEGS(desc, 2);
824 IWN_SET_DESC_SEG(desc, 0, paddr , 4 + sizeof(struct iwn_cmd_beacon));
825 IWN_SET_DESC_SEG(desc, 1, data->map->dm_segs[0].ds_addr,
826 data->map->dm_segs[1].ds_len);
828 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
829 data->map->dm_mapsize /* calc? */, BUS_DMASYNC_PREWRITE);
831 /* kick cmd ring */
832 ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
833 IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
834 return 0;
836 #endif
838 static int
839 iwn_nic_lock(struct iwn_softc *sc)
841 int ntries;
843 /* Request exclusive access to NIC. */
844 IWN_SETBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ);
846 /* Spin until we actually get the lock. */
847 for (ntries = 0; ntries < 1000; ntries++) {
848 if ((IWN_READ(sc, IWN_GP_CNTRL) &
849 (IWN_GP_CNTRL_MAC_ACCESS_ENA | IWN_GP_CNTRL_SLEEP)) ==
850 IWN_GP_CNTRL_MAC_ACCESS_ENA)
851 return 0;
852 DELAY(10);
854 return ETIMEDOUT;
857 static __inline void
858 iwn_nic_unlock(struct iwn_softc *sc)
860 IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ);
863 static __inline uint32_t
864 iwn_prph_read(struct iwn_softc *sc, uint32_t addr)
866 IWN_WRITE(sc, IWN_PRPH_RADDR, IWN_PRPH_DWORD | addr);
867 return IWN_READ(sc, IWN_PRPH_RDATA);
870 static __inline void
871 iwn_prph_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
873 IWN_WRITE(sc, IWN_PRPH_WADDR, IWN_PRPH_DWORD | addr);
874 IWN_WRITE(sc, IWN_PRPH_WDATA, data);
877 static __inline void
878 iwn_prph_setbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask)
880 iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) | mask);
883 static __inline void
884 iwn_prph_clrbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask)
886 iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) & ~mask);
889 static __inline void
890 iwn_prph_write_region_4(struct iwn_softc *sc, uint32_t addr,
891 const uint32_t *data, int count)
893 for (; count > 0; count--, data++, addr += 4)
894 iwn_prph_write(sc, addr, *data);
897 static __inline uint32_t
898 iwn_mem_read(struct iwn_softc *sc, uint32_t addr)
900 IWN_WRITE(sc, IWN_MEM_RADDR, addr);
901 return IWN_READ(sc, IWN_MEM_RDATA);
904 static __inline void
905 iwn_mem_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
907 IWN_WRITE(sc, IWN_MEM_WADDR, addr);
908 IWN_WRITE(sc, IWN_MEM_WDATA, data);
911 static __inline void
912 iwn_mem_write_2(struct iwn_softc *sc, uint32_t addr, uint16_t data)
914 uint32_t tmp;
916 tmp = iwn_mem_read(sc, addr & ~3);
917 if (addr & 3)
918 tmp = (tmp & 0x0000ffff) | data << 16;
919 else
920 tmp = (tmp & 0xffff0000) | data;
921 iwn_mem_write(sc, addr & ~3, tmp);
924 static __inline void
925 iwn_mem_read_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t *data,
926 int count)
928 for (; count > 0; count--, addr += 4)
929 *data++ = iwn_mem_read(sc, addr);
932 static __inline void
933 iwn_mem_set_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t val,
934 int count)
936 for (; count > 0; count--, addr += 4)
937 iwn_mem_write(sc, addr, val);
940 static int
941 iwn_eeprom_lock(struct iwn_softc *sc)
943 int i, ntries;
945 for (i = 0; i < 100; i++) {
946 /* Request exclusive access to EEPROM. */
947 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
948 IWN_HW_IF_CONFIG_EEPROM_LOCKED);
950 /* Spin until we actually get the lock. */
951 for (ntries = 0; ntries < 100; ntries++) {
952 if (IWN_READ(sc, IWN_HW_IF_CONFIG) &
953 IWN_HW_IF_CONFIG_EEPROM_LOCKED)
954 return 0;
955 DELAY(10);
958 return ETIMEDOUT;
961 static __inline void
962 iwn_eeprom_unlock(struct iwn_softc *sc)
964 IWN_CLRBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_EEPROM_LOCKED);
967 static int
968 iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count)
970 uint8_t *out = data;
971 uint32_t val;
972 int ntries;
974 for (; count > 0; count -= 2, addr++) {
975 IWN_WRITE(sc, IWN_EEPROM, addr << 2);
976 IWN_CLRBITS(sc, IWN_EEPROM, IWN_EEPROM_CMD);
978 for (ntries = 0; ntries < 10; ntries++) {
979 val = IWN_READ(sc, IWN_EEPROM);
980 if (val & IWN_EEPROM_READ_VALID)
981 break;
982 DELAY(5);
984 if (ntries == 10) {
985 aprint_error_dev(sc->sc_dev, "could not read EEPROM\n");
986 return ETIMEDOUT;
988 *out++ = val >> 16;
989 if (count > 1)
990 *out++ = val >> 24;
992 return 0;
995 static int
996 iwn_dma_contig_alloc(bus_dma_tag_t tag, struct iwn_dma_info *dma, void **kvap,
997 bus_size_t size, bus_size_t alignment, int flags)
999 int nsegs, error;
1001 dma->tag = tag;
1002 dma->size = size;
1004 error = bus_dmamap_create(tag, size, 1, size, 0, flags, &dma->map);
1005 if (error != 0)
1006 goto fail;
1008 error = bus_dmamem_alloc(tag, size, alignment, 0, &dma->seg, 1, &nsegs,
1009 flags);
1010 if (error != 0)
1011 goto fail;
1013 error = bus_dmamem_map(tag, &dma->seg, 1, size, &dma->vaddr, flags);
1014 if (error != 0)
1015 goto fail;
1017 error = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL, flags);
1018 if (error != 0)
1019 goto fail;
1021 memset(dma->vaddr, 0, size);
1022 bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
1024 dma->paddr = dma->map->dm_segs[0].ds_addr;
1025 if (kvap != NULL)
1026 *kvap = dma->vaddr;
1028 return 0;
1030 fail: iwn_dma_contig_free(dma);
1031 return error;
1034 static void
1035 iwn_dma_contig_free(struct iwn_dma_info *dma)
1037 if (dma->map != NULL) {
1038 if (dma->vaddr != NULL) {
1039 bus_dmamap_sync(dma->tag, dma->map, 0, dma->size,
1040 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1041 bus_dmamap_unload(dma->tag, dma->map);
1042 bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size);
1043 bus_dmamem_free(dma->tag, &dma->seg, 1);
1044 dma->vaddr = NULL;
1046 bus_dmamap_destroy(dma->tag, dma->map);
1047 dma->map = NULL;
1051 static int
1052 iwn_alloc_sched(struct iwn_softc *sc)
1054 int error;
1055 /* TX scheduler rings must be aligned on a 1KB boundary. */
1056 error = iwn_dma_contig_alloc(sc->sc_dmat, &sc->sched_dma,
1057 (void **)&sc->sched, sc->sc_hal->schedsz, 1024, BUS_DMA_NOWAIT);
1058 if (error != 0)
1059 aprint_error_dev(sc->sc_dev,
1060 "could not allocate shared area DMA memory\n");
1061 return error;
1064 static void
1065 iwn_free_sched(struct iwn_softc *sc)
1067 iwn_dma_contig_free(&sc->sched_dma);
1070 static int
1071 iwn_alloc_kw(struct iwn_softc *sc)
1073 /* "Keep Warm" page must be aligned on a 16-byte boundary. */
1074 return iwn_dma_contig_alloc(sc->sc_dmat, &sc->kw_dma, NULL, 4096,
1075 4096, BUS_DMA_NOWAIT);
1078 static void
1079 iwn_free_kw(struct iwn_softc *sc)
1081 iwn_dma_contig_free(&sc->kw_dma);
1084 static int
1085 iwn_alloc_fwmem(struct iwn_softc *sc)
1087 int error;
1088 /* Must be aligned on a 16-byte boundary. */
1089 error = iwn_dma_contig_alloc(sc->sc_dmat, &sc->fw_dma, NULL,
1090 sc->sc_hal->fwsz, 16, BUS_DMA_NOWAIT);
1091 if (error != 0) {
1092 aprint_error_dev(sc->sc_dev,
1093 "could not allocate firmware transfer area DMA memory\n");
1095 return error;
1098 static void
1099 iwn_free_fwmem(struct iwn_softc *sc)
1101 iwn_dma_contig_free(&sc->fw_dma);
1104 static struct iwn_rbuf *
1105 iwn_alloc_rbuf(struct iwn_softc *sc)
1107 struct iwn_rbuf *rbuf;
1108 mutex_enter(&sc->rxq.freelist_mtx);
1110 rbuf = SLIST_FIRST(&sc->rxq.freelist);
1111 if (rbuf != NULL) {
1112 SLIST_REMOVE_HEAD(&sc->rxq.freelist, next);
1113 sc->rxq.nb_free_entries --;
1115 mutex_exit(&sc->rxq.freelist_mtx);
1116 return rbuf;
1120 * This is called automatically by the network stack when the mbuf to which
1121 * our RX buffer is attached is freed.
1123 static void
1124 iwn_free_rbuf(struct mbuf* m, void *buf, size_t size, void *arg)
1126 struct iwn_rbuf *rbuf = arg;
1127 struct iwn_softc *sc = rbuf->sc;
1129 /* Put the RX buffer back in the free list. */
1130 mutex_enter(&sc->rxq.freelist_mtx);
1131 SLIST_INSERT_HEAD(&sc->rxq.freelist, rbuf, next);
1132 mutex_exit(&sc->rxq.freelist_mtx);
1134 sc->rxq.nb_free_entries ++;
1135 if (__predict_true(m != NULL))
1136 pool_cache_put(mb_cache, m);
1139 static int
1140 iwn_alloc_rpool(struct iwn_softc *sc)
1142 struct iwn_rx_ring *ring = &sc->rxq;
1143 struct iwn_rbuf *rbuf;
1144 int i, error;
1146 mutex_init(&ring->freelist_mtx, MUTEX_DEFAULT, IPL_NET);
1148 /* Allocate a big chunk of DMA'able memory... */
1149 error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->buf_dma, NULL,
1150 IWN_RBUF_COUNT * IWN_RBUF_SIZE, PAGE_SIZE, BUS_DMA_NOWAIT);
1151 if (error != 0) {
1152 aprint_error_dev(sc->sc_dev,
1153 "could not allocate RX buffers DMA memory\n");
1154 return error;
1156 /* ...and split it into chunks of IWN_RBUF_SIZE bytes. */
1157 SLIST_INIT(&ring->freelist);
1158 for (i = 0; i < IWN_RBUF_COUNT; i++) {
1159 rbuf = &ring->rbuf[i];
1161 rbuf->sc = sc; /* Backpointer for callbacks. */
1162 rbuf->vaddr = (void *)((vaddr_t)ring->buf_dma.vaddr + i * IWN_RBUF_SIZE);
1163 rbuf->paddr = ring->buf_dma.paddr + i * IWN_RBUF_SIZE;
1165 SLIST_INSERT_HEAD(&ring->freelist, rbuf, next);
1167 ring->nb_free_entries = IWN_RBUF_COUNT;
1168 return 0;
1171 static void
1172 iwn_free_rpool(struct iwn_softc *sc)
1174 iwn_dma_contig_free(&sc->rxq.buf_dma);
1177 static int
1178 iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
1180 struct iwn_rx_data *data;
1181 bus_size_t size;
1182 struct iwn_rbuf *rbuf;
1183 int i, error;
1185 ring->cur = 0;
1187 /* Allocate RX descriptors (256-byte aligned.) */
1188 size = IWN_RX_RING_COUNT * sizeof (struct iwn_rx_desc);
1189 error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma,
1190 (void **)&ring->desc, size, 256, BUS_DMA_NOWAIT);
1191 if (error != 0) {
1192 aprint_error_dev(sc->sc_dev,
1193 "could not allocate RX ring DMA memory\n");
1194 goto fail;
1197 /* Allocate RX status area (16-byte aligned.) */
1198 error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma,
1199 (void **)&ring->stat, sizeof (struct iwn_rx_status), 16,
1200 BUS_DMA_NOWAIT);
1201 if (error != 0) {
1202 aprint_error_dev(sc->sc_dev,
1203 "could not allocate RX status DMA memory\n");
1204 goto fail;
1208 * Allocate and map RX buffers.
1210 for (i = 0; i < IWN_RX_RING_COUNT; i++) {
1211 data = &ring->data[i];
1213 error = bus_dmamap_create(sc->sc_dmat, IWN_RBUF_SIZE, 1,
1214 IWN_RBUF_SIZE, 0, BUS_DMA_NOWAIT, &data->map);
1215 if (error != 0) {
1216 aprint_error_dev(sc->sc_dev,
1217 "could not create RX buf DMA map\n");
1218 goto fail;
1220 MGETHDR(data->m, M_DONTWAIT, MT_DATA);
1221 if (data->m == NULL) {
1222 aprint_error_dev(sc->sc_dev,
1223 "could not allocate RX mbuf\n");
1224 error = ENOMEM;
1225 goto fail;
1227 if ((rbuf = iwn_alloc_rbuf(sc)) == NULL) {
1228 m_freem(data->m);
1229 data->m = NULL;
1230 aprint_error_dev(sc->sc_dev,
1231 "could not allocate RX buffer\n");
1232 error = ENOMEM;
1233 goto fail;
1235 /* Attach RX buffer to mbuf header. */
1236 MEXTADD(data->m, rbuf->vaddr, IWN_RBUF_SIZE, 0, iwn_free_rbuf,
1237 rbuf);
1238 data->m->m_flags |= M_EXT_RW;
1239 error = bus_dmamap_load(sc->sc_dmat, data->map,
1240 data->m->m_ext.ext_buf, IWN_RBUF_SIZE, NULL,
1241 BUS_DMA_NOWAIT);
1242 if (error != 0) {
1243 aprint_error_dev(sc->sc_dev, "can't not map mbuf"
1244 " (error %d)\n", error);
1245 goto fail;
1248 /* Set physical address of RX buffer (256-byte aligned.) */
1249 ring->desc[i] = htole32(data->map->dm_segs[0].ds_addr >> 8);
1252 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
1253 0, ring->desc_dma.size, BUS_DMASYNC_PREWRITE);
1255 return 0;
1257 fail: iwn_free_rx_ring(sc, ring);
1258 return error;
1261 static void
1262 iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
1264 int ntries;
1266 if (iwn_nic_lock(sc) == 0) {
1267 IWN_WRITE(sc, IWN_FH_RX_CONFIG, 0);
1268 for (ntries = 0; ntries < 1000; ntries++) {
1269 if (IWN_READ(sc, IWN_FH_RX_STATUS) &
1270 IWN_FH_RX_STATUS_IDLE)
1271 break;
1272 DELAY(10);
1274 iwn_nic_unlock(sc);
1276 ring->cur = 0;
1277 sc->last_rx_valid = 0;
1280 static void
1281 iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
1283 int i;
1285 iwn_dma_contig_free(&ring->desc_dma);
1286 iwn_dma_contig_free(&ring->stat_dma);
1288 for (i = 0; i < IWN_RX_RING_COUNT; i++) {
1289 struct iwn_rx_data *data = &ring->data[i];
1291 if (data->m != NULL) {
1292 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1293 data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
1294 bus_dmamap_unload(sc->sc_dmat, data->map);
1295 m_freem(data->m);
1297 if (data->map != NULL)
1298 bus_dmamap_destroy(sc->sc_dmat, data->map);
1302 static int
1303 iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int count,
1304 int qid)
1306 bus_addr_t paddr;
1307 struct iwn_tx_data *data;
1308 int i, error, size;
1310 ring->qid = qid;
1311 ring->count = count;
1312 ring->queued = 0;
1313 ring->cur = 0;
1315 /* Allocate TX descriptors (256-byte aligned.) */
1316 size = count * sizeof (struct iwn_tx_desc);
1317 error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma,
1318 (void **)&ring->desc, size, 256, BUS_DMA_NOWAIT);
1319 if (error != 0) {
1320 aprint_error_dev(sc->sc_dev,
1321 "could not allocate TX ring DMA memory\n");
1322 goto fail;
1325 * We only use rings 0 through 4 (4 EDCA + cmd) so there is no need
1326 * to allocate commands space for other rings.
1327 * XXX Do we really need to allocate descriptors for other rings?
1329 if (qid > 4)
1330 return 0;
1332 size = count * sizeof (struct iwn_tx_cmd);
1333 error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->cmd_dma,
1334 (void **)&ring->cmd, size, 4, BUS_DMA_NOWAIT);
1335 if (error != 0) {
1336 aprint_error_dev(sc->sc_dev,
1337 "could not allocate TX cmd DMA memory\n");
1338 goto fail;
1341 paddr = ring->cmd_dma.paddr;
1343 for (i = 0; i < count; i++) {
1344 data = &ring->data[i];
1346 data->cmd_paddr = paddr;
1347 data->scratch_paddr = paddr + 12;
1348 paddr += sizeof (struct iwn_tx_cmd);
1350 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
1351 IWN_MAX_SCATTER - 1, MCLBYTES, 0, BUS_DMA_NOWAIT,
1352 &data->map);
1353 if (error != 0) {
1354 aprint_error_dev(sc->sc_dev,
1355 "could not create TX buf DMA map\n");
1356 goto fail;
1359 return 0;
1361 fail: iwn_free_tx_ring(sc, ring);
1362 return error;
1365 static void
1366 iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
1368 struct iwn_tx_data *data;
1369 uint32_t tmp;
1370 int i, ntries;
1372 if (iwn_nic_lock(sc) == 0) {
1373 IWN_WRITE(sc, IWN_FH_TX_CONFIG(ring->qid), 0);
1374 for (ntries = 0; ntries < 200; ntries++) {
1375 tmp = IWN_READ(sc, IWN_FH_TX_STATUS);
1376 if ((tmp & IWN_FH_TX_STATUS_IDLE(ring->qid)) ==
1377 IWN_FH_TX_STATUS_IDLE(ring->qid))
1378 break;
1379 DELAY(10);
1381 iwn_nic_unlock(sc);
1383 for (i = 0; i < ring->count; i++) {
1384 data = &ring->data[i];
1386 if (data->m != NULL) {
1387 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1388 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1389 bus_dmamap_unload(sc->sc_dmat, data->map);
1390 m_freem(data->m);
1391 data->m = NULL;
1394 /* Clear TX descriptors. */
1395 memset(ring->desc, 0, ring->desc_dma.size);
1396 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0,
1397 ring->desc_dma.size, BUS_DMASYNC_PREWRITE);
1398 sc->qfullmsk &= ~(1 << ring->qid);
1399 ring->queued = 0;
1400 ring->cur = 0;
1403 static void
1404 iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
1406 struct iwn_tx_data *data;
1407 int i;
1409 iwn_dma_contig_free(&ring->desc_dma);
1410 iwn_dma_contig_free(&ring->cmd_dma);
1412 if (ring->data != NULL) {
1413 for (i = 0; i < ring->count; i++) {
1414 data = &ring->data[i];
1416 if (data->m != NULL) {
1417 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1418 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1419 bus_dmamap_unload(sc->sc_dmat, data->map);
1420 m_freem(data->m);
1422 if (data->map != NULL)
1423 bus_dmamap_destroy(sc->sc_dmat, data->map);
1425 free(ring->data, M_DEVBUF);
1429 static int
1430 iwn_read_eeprom(struct iwn_softc *sc)
1432 const struct iwn_hal *hal = sc->sc_hal;
1433 struct ieee80211com *ic = &sc->sc_ic;
1434 uint16_t val;
1435 int error;
1437 if ((IWN_READ(sc, IWN_EEPROM_GP) & 0x6) == 0) {
1438 aprint_error_dev(sc->sc_dev, "bad EEPROM signature\n");
1439 return EIO;
1441 if ((error = iwn_eeprom_lock(sc)) != 0) {
1442 aprint_error_dev(sc->sc_dev,
1443 "could not lock EEPROM (error=%d)\n", error);
1444 return error;
1447 iwn_read_prom_data(sc, IWN_EEPROM_RFCFG, &val, 2);
1448 sc->rfcfg = le16toh(val);
1449 DPRINTF(("radio config=0x%04x\n", sc->rfcfg));
1451 /* Read MAC address. */
1452 iwn_read_prom_data(sc, IWN_EEPROM_MAC, ic->ic_myaddr, 6);
1454 /* Read adapter-specific information from EEPROM. */
1455 hal->read_eeprom(sc);
1457 iwn_eeprom_unlock(sc);
1458 return 0;
1461 static void
1462 iwn4965_read_eeprom(struct iwn_softc *sc)
1464 uint32_t addr;
1465 uint16_t val;
1466 int i;
1468 /* Read regulatory domain (4 ASCII characters.) */
1469 iwn_read_prom_data(sc, IWN4965_EEPROM_DOMAIN, sc->eeprom_domain, 4);
1471 /* Read the list of authorized channels (20MHz ones only.) */
1472 for (i = 0; i < 5; i++) {
1473 addr = iwn4965_regulatory_bands[i];
1474 iwn_read_eeprom_channels(sc, i, addr);
1477 /* Read maximum allowed TX power for 2GHz and 5GHz bands. */
1478 iwn_read_prom_data(sc, IWN4965_EEPROM_MAXPOW, &val, 2);
1479 sc->maxpwr2GHz = val & 0xff;
1480 sc->maxpwr5GHz = val >> 8;
1481 /* Check that EEPROM values are within valid range. */
1482 if (sc->maxpwr5GHz < 20 || sc->maxpwr5GHz > 50)
1483 sc->maxpwr5GHz = 38;
1484 if (sc->maxpwr2GHz < 20 || sc->maxpwr2GHz > 50)
1485 sc->maxpwr2GHz = 38;
1486 DPRINTF(("maxpwr 2GHz=%d 5GHz=%d\n", sc->maxpwr2GHz, sc->maxpwr5GHz));
1488 /* Read samples for each TX power group. */
1489 iwn_read_prom_data(sc, IWN4965_EEPROM_BANDS, sc->bands,
1490 sizeof sc->bands);
1492 /* Read voltage at which samples were taken. */
1493 iwn_read_prom_data(sc, IWN4965_EEPROM_VOLTAGE, &val, 2);
1494 sc->eeprom_voltage = (int16_t)le16toh(val);
1495 DPRINTF(("voltage=%d (in 0.3V)\n", sc->eeprom_voltage));
1497 #ifdef IWN_DEBUG
1498 /* Print samples. */
1499 if (iwn_debug > 0) {
1500 for (i = 0; i < IWN_NBANDS; i++)
1501 iwn4965_print_power_group(sc, i);
1503 #endif
1506 #ifdef IWN_DEBUG
1507 static void
1508 iwn4965_print_power_group(struct iwn_softc *sc, int i)
1510 struct iwn4965_eeprom_band *band = &sc->bands[i];
1511 struct iwn4965_eeprom_chan_samples *chans = band->chans;
1512 int j, c;
1514 printf("===band %d===\n", i);
1515 printf("chan lo=%d, chan hi=%d\n", band->lo, band->hi);
1516 printf("chan1 num=%d\n", chans[0].num);
1517 for (c = 0; c < 2; c++) {
1518 for (j = 0; j < IWN_NSAMPLES; j++) {
1519 printf("chain %d, sample %d: temp=%d gain=%d "
1520 "power=%d pa_det=%d\n", c, j,
1521 chans[0].samples[c][j].temp,
1522 chans[0].samples[c][j].gain,
1523 chans[0].samples[c][j].power,
1524 chans[0].samples[c][j].pa_det);
1527 printf("chan2 num=%d\n", chans[1].num);
1528 for (c = 0; c < 2; c++) {
1529 for (j = 0; j < IWN_NSAMPLES; j++) {
1530 printf("chain %d, sample %d: temp=%d gain=%d "
1531 "power=%d pa_det=%d\n", c, j,
1532 chans[1].samples[c][j].temp,
1533 chans[1].samples[c][j].gain,
1534 chans[1].samples[c][j].power,
1535 chans[1].samples[c][j].pa_det);
1539 #endif
1541 static void
1542 iwn5000_read_eeprom(struct iwn_softc *sc)
1544 int32_t temp, volt, delta;
1545 uint32_t base, addr;
1546 uint16_t val;
1547 int i;
1549 /* Read regulatory domain (4 ASCII characters.) */
1550 iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
1551 base = le16toh(val);
1552 iwn_read_prom_data(sc, base + IWN5000_EEPROM_DOMAIN,
1553 sc->eeprom_domain, 4);
1555 /* Read the list of authorized channels (20MHz ones only.) */
1556 for (i = 0; i < 5; i++) {
1557 addr = base + iwn5000_regulatory_bands[i];
1558 iwn_read_eeprom_channels(sc, i, addr);
1561 iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2);
1562 base = le16toh(val);
1563 if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
1564 /* Compute critical temperature (in Kelvin.) */
1565 iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
1566 temp = le16toh(val);
1567 iwn_read_prom_data(sc, base + IWN5000_EEPROM_VOLT, &val, 2);
1568 volt = le16toh(val);
1569 delta = temp - (volt / -5);
1570 sc->critical_temp = (IWN_CTOK(110) - delta) * -5;
1571 DPRINTF(("temp=%d volt=%d delta=%dK\n",
1572 temp, volt, delta));
1573 } else {
1574 /* Read crystal calibration. */
1575 iwn_read_prom_data(sc, base + IWN5000_EEPROM_CRYSTAL,
1576 &sc->eeprom_crystal, sizeof (uint32_t));
1577 DPRINTF(("crystal calibration 0x%08x\n",
1578 le32toh(sc->eeprom_crystal)));
1582 static void
1583 iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
1585 struct ieee80211com *ic = &sc->sc_ic;
1586 const struct iwn_chan_band *band = &iwn_bands[n];
1587 struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
1588 uint8_t chan;
1589 int i;
1591 iwn_read_prom_data(sc, addr, channels,
1592 band->nchan * sizeof (struct iwn_eeprom_chan));
1594 for (i = 0; i < band->nchan; i++) {
1595 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID))
1596 continue;
1598 chan = band->chan[i];
1600 if (n == 0) { /* 2GHz band */
1601 ic->ic_channels[chan].ic_freq =
1602 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
1603 ic->ic_channels[chan].ic_flags =
1604 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
1605 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
1607 } else { /* 5GHz band */
1609 * Some adapters support channels 7, 8, 11 and 12
1610 * both in the 2GHz and 4.9GHz bands.
1611 * Because of limitations in our net80211 layer,
1612 * we don't support them in the 4.9GHz band.
1614 if (chan <= 14)
1615 continue;
1617 ic->ic_channels[chan].ic_freq =
1618 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ);
1619 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A;
1620 /* We have at least one valid 5GHz channel. */
1621 sc->sc_flags |= IWN_FLAG_HAS_5GHZ;
1624 /* Is active scan allowed on this channel? */
1625 if (!(channels[i].flags & IWN_EEPROM_CHAN_ACTIVE)) {
1626 ic->ic_channels[chan].ic_flags |=
1627 IEEE80211_CHAN_PASSIVE;
1630 /* Save maximum allowed TX power for this channel. */
1631 sc->maxpwr[chan] = channels[i].maxpwr;
1633 DPRINTF(("adding chan %d flags=0x%x maxpwr=%d\n",
1634 chan, channels[i].flags, sc->maxpwr[chan]));
1638 /*ARGUSED*/
1639 static struct ieee80211_node *
1640 iwn_node_alloc(struct ieee80211_node_table *nt __unused)
1642 struct iwn_node *wn;
1644 wn = malloc(sizeof (struct iwn_node), M_80211_NODE, M_NOWAIT | M_ZERO);
1645 return (struct ieee80211_node *)wn;
1648 static void
1649 iwn_newassoc(struct ieee80211_node *ni, int isnew)
1651 struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
1652 struct iwn_node *wn = (void *)ni;
1653 uint8_t rate;
1654 int ridx, i;
1656 ieee80211_amrr_node_init(&sc->amrr, &wn->amn);
1658 for (i = 0; i < ni->ni_rates.rs_nrates; i++) {
1659 rate = ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL;
1660 /* Map 802.11 rate to HW rate index. */
1661 for (ridx = 0; ridx <= IWN_RIDX_MAX; ridx++)
1662 if (iwn_rates[ridx].rate == rate)
1663 break;
1664 wn->ridx[i] = ridx;
1665 /* Initial TX rate <= 24Mbps. */
1666 if (rate <= 48)
1667 ni->ni_txrate = i;
1671 static int
1672 iwn_media_change(struct ifnet *ifp)
1674 struct iwn_softc *sc = ifp->if_softc;
1675 struct ieee80211com *ic = &sc->sc_ic;
1676 uint8_t rate, ridx;
1677 int error;
1679 error = ieee80211_media_change(ifp);
1680 if (error != ENETRESET)
1681 return error;
1683 if (ic->ic_fixed_rate != -1) {
1684 rate = ic->ic_sup_rates[ic->ic_curmode].
1685 rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
1686 /* Map 802.11 rate to HW rate index. */
1687 for (ridx = 0; ridx <= IWN_RIDX_MAX; ridx++)
1688 if (iwn_rates[ridx].rate == rate)
1689 break;
1690 sc->fixed_ridx = ridx;
1693 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
1694 (IFF_UP | IFF_RUNNING)) {
1695 iwn_stop(ifp, 0);
1696 error = iwn_init(ifp);
1698 return error;
1701 static int
1702 iwn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1704 struct ifnet *ifp = ic->ic_ifp;
1705 struct iwn_softc *sc = ifp->if_softc;
1706 int error;
1708 callout_stop(&sc->calib_to);
1710 switch (nstate) {
1711 case IEEE80211_S_SCAN:
1712 if (sc->is_scanning)
1713 break;
1715 sc->is_scanning = true;
1716 ieee80211_node_table_reset(&ic->ic_scan);
1717 ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN;
1719 /* Make the link LED blink while we're scanning. */
1720 iwn_set_led(sc, IWN_LED_LINK, 10, 10);
1722 if ((error = iwn_scan(sc, IEEE80211_CHAN_2GHZ)) != 0) {
1723 aprint_error_dev(sc->sc_dev,
1724 "could not initiate scan\n");
1725 return error;
1727 ic->ic_state = nstate;
1728 return 0;
1730 case IEEE80211_S_ASSOC:
1731 if (ic->ic_state != IEEE80211_S_RUN)
1732 break;
1733 /* FALLTHROUGH */
1734 case IEEE80211_S_AUTH:
1735 /* Reset state to handle reassociations correctly. */
1736 sc->rxon.associd = 0;
1737 sc->rxon.filter &= ~htole32(IWN_FILTER_BSS);
1738 sc->calib.state = IWN_CALIB_STATE_INIT;
1740 if ((error = iwn_auth(sc)) != 0) {
1741 aprint_error_dev(sc->sc_dev,
1742 "could not move to auth state\n");
1743 return error;
1745 break;
1747 case IEEE80211_S_RUN:
1748 if ((error = iwn_run(sc)) != 0) {
1749 aprint_error_dev(sc->sc_dev,
1750 "could not move to run state\n");
1751 return error;
1753 break;
1755 case IEEE80211_S_INIT:
1756 sc->is_scanning = false;
1757 sc->calib.state = IWN_CALIB_STATE_INIT;
1758 break;
1761 return sc->sc_newstate(ic, nstate, arg);
1764 static void
1765 iwn_iter_func(void *arg, struct ieee80211_node *ni)
1767 struct iwn_softc *sc = arg;
1768 struct iwn_node *wn = (struct iwn_node *)ni;
1770 ieee80211_amrr_choose(&sc->amrr, ni, &wn->amn);
1773 static void
1774 iwn_calib_timeout(void *arg)
1776 struct iwn_softc *sc = arg;
1777 struct ieee80211com *ic = &sc->sc_ic;
1778 int s;
1780 if (ic->ic_fixed_rate == -1) {
1781 s = splnet();
1782 if (ic->ic_opmode == IEEE80211_M_STA)
1783 iwn_iter_func(sc, ic->ic_bss);
1784 else
1785 ieee80211_iterate_nodes(&ic->ic_sta, iwn_iter_func, sc);
1786 splx(s);
1788 /* Force automatic TX power calibration every 60 secs. */
1789 if (++sc->calib_cnt >= 120) {
1790 uint32_t flags = 0;
1792 DPRINTF(("sending request for statistics\n"));
1793 (void)iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags,
1794 sizeof flags, 1);
1795 sc->calib_cnt = 0;
1797 /* Automatic rate control triggered every 500ms. */
1798 callout_schedule(&sc->calib_to, hz/2);
1801 #if 0
1802 static int
1803 iwn_ccmp_decap(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_key *k)
1805 struct ieee80211_frame *wh;
1806 uint64_t pn, *prsc;
1807 uint8_t *ivp;
1808 uint8_t tid;
1809 int hdrlen;
1811 wh = mtod(m, struct ieee80211_frame *);
1812 hdrlen = ieee80211_get_hdrlen(wh);
1813 ivp = (uint8_t *)wh + hdrlen;
1815 /* Check that ExtIV bit is be set. */
1816 if (!(ivp[3] & IEEE80211_WEP_EXTIV)) {
1817 DPRINTF(("CCMP decap ExtIV not set\n"));
1818 return 1;
1820 tid = ieee80211_has_qos(wh) ?
1821 ieee80211_get_qos(wh) & IEEE80211_QOS_TID : 0;
1822 prsc = &k->k_rsc[tid];
1824 /* Extract the 48-bit PN from the CCMP header. */
1825 pn = (uint64_t)ivp[0] |
1826 (uint64_t)ivp[1] << 8 |
1827 (uint64_t)ivp[4] << 16 |
1828 (uint64_t)ivp[5] << 24 |
1829 (uint64_t)ivp[6] << 32 |
1830 (uint64_t)ivp[7] << 40;
1831 if (pn <= *prsc) {
1833 * Not necessarily a replayed frame since we did not check
1834 * the sequence number of the 802.11 header yet.
1836 DPRINTF(("CCMP replayed\n"));
1837 return 1;
1839 /* Update last seen packet number. */
1840 *prsc = pn;
1842 /* Clear Protected bit and strip IV. */
1843 wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
1844 memmove(mtod(m, char *) + IEEE80211_CCMP_HDRLEN, wh, hdrlen);
1845 m_adj(m, IEEE80211_CCMP_HDRLEN);
1846 /* Strip MIC. */
1847 m_adj(m, -IEEE80211_CCMP_MICLEN);
1848 return 0;
1850 #endif
1853 * Process an RX_PHY firmware notification. This is usually immediately
1854 * followed by an MPDU_RX_DONE notification.
1856 void
1857 iwn_rx_phy(struct iwn_softc *sc, struct iwn_rx_desc *desc)
1859 struct iwn_rx_stat *stat = (struct iwn_rx_stat *)(desc + 1);
1861 DPRINTFN(2, ("received PHY stats\n"));
1862 bus_dmamap_sync(sc->sc_dmat, sc->rxq.buf_dma.map,
1863 (vaddr_t)stat - (vaddr_t)sc->rxq.buf_dma.vaddr, sizeof (*stat),
1864 BUS_DMASYNC_POSTREAD);
1866 /* Save RX statistics, they will be used on MPDU_RX_DONE. */
1867 memcpy(&sc->last_rx_stat, stat, sizeof (*stat));
1868 sc->last_rx_valid = 1;
1872 * Process an RX_DONE (4965AGN only) or MPDU_RX_DONE firmware notification.
1873 * Each MPDU_RX_DONE notification must be preceded by an RX_PHY one.
1875 void
1876 iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
1877 struct iwn_rx_data *data)
1879 const struct iwn_hal *hal = sc->sc_hal;
1880 struct ieee80211com *ic = &sc->sc_ic;
1881 struct ifnet *ifp = ic->ic_ifp;
1882 struct iwn_rx_ring *ring = &sc->rxq;
1883 struct iwn_rbuf *rbuf;
1884 struct ieee80211_frame *wh;
1885 struct ieee80211_node *ni;
1886 struct mbuf *m, *m1;
1887 struct iwn_rx_stat *stat;
1888 char * head;
1889 uint32_t flags;
1890 int len, rssi, error;
1892 if (desc->type == IWN_MPDU_RX_DONE) {
1893 /* Check for prior RX_PHY notification. */
1894 if (!sc->last_rx_valid) {
1895 DPRINTF(("missing RX_PHY\n"));
1896 ifp->if_ierrors++;
1897 return;
1899 sc->last_rx_valid = 0;
1900 stat = &sc->last_rx_stat;
1901 } else
1902 stat = (struct iwn_rx_stat *)(desc + 1);
1904 bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWN_RBUF_SIZE,
1905 BUS_DMASYNC_POSTREAD);
1907 if (stat->cfg_phy_len > IWN_STAT_MAXLEN) {
1908 aprint_error_dev(sc->sc_dev, "invalid RX statistic header\n");
1909 ifp->if_ierrors++;
1910 return;
1912 if (desc->type == IWN_MPDU_RX_DONE) {
1913 struct iwn_rx_mpdu *mpdu =
1914 (struct iwn_rx_mpdu *)(desc + 1);
1915 head = (char *)(mpdu + 1);
1916 len = le16toh(mpdu->len);
1917 } else {
1918 head = (char *)(stat + 1) + stat->cfg_phy_len;
1919 len = le16toh(stat->len);
1922 flags = le32toh(*(uint32_t *)(head + len));
1924 /* Discard frames with a bad FCS early. */
1925 if ((flags & IWN_RX_NOERROR) != IWN_RX_NOERROR) {
1926 DPRINTFN(2, ("RX flags error %x\n", flags));
1927 ifp->if_ierrors++;
1928 return;
1930 /* Discard frames that are too short. */
1931 if (len < sizeof (struct ieee80211_frame)) {
1932 DPRINTF(("frame too short: %d\n", len));
1933 ic->ic_stats.is_rx_tooshort++;
1934 ifp->if_ierrors++;
1935 return;
1939 * See comment in if_wpi.c:wpi_rx_intr() about locking
1940 * nb_free_entries here. In short: it's not required.
1942 MGETHDR(m1, M_DONTWAIT, MT_DATA);
1943 if (m1 == NULL) {
1944 ic->ic_stats.is_rx_nobuf++;
1945 ifp->if_ierrors++;
1946 return;
1948 if (sc->rxq.nb_free_entries <= 0) {
1949 ic->ic_stats.is_rx_nobuf++;
1950 ifp->if_ierrors++;
1951 m_freem(m1);
1952 return;
1954 rbuf = iwn_alloc_rbuf(sc);
1955 /* Attach RX buffer to mbuf header. */
1956 MEXTADD(m1, rbuf->vaddr, IWN_RBUF_SIZE, 0, iwn_free_rbuf,
1957 rbuf);
1958 m1->m_flags |= M_EXT_RW;
1959 bus_dmamap_unload(sc->sc_dmat, data->map);
1961 error = bus_dmamap_load(sc->sc_dmat, data->map, m1->m_ext.ext_buf,
1962 IWN_RBUF_SIZE, NULL, BUS_DMA_NOWAIT);
1963 if (error != 0) {
1964 m_freem(m1);
1966 /* Try to reload the old mbuf. */
1967 error = bus_dmamap_load(sc->sc_dmat, data->map,
1968 data->m->m_ext.ext_buf, IWN_RBUF_SIZE, NULL,
1969 BUS_DMA_NOWAIT);
1970 if (error != 0) {
1971 panic("%s: could not load old RX mbuf",
1972 device_xname(sc->sc_dev));
1974 /* Physical address may have changed. */
1975 ring->desc[ring->cur] =
1976 htole32(data->map->dm_segs[0].ds_addr >> 8);
1977 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
1978 ring->cur * sizeof (uint32_t), sizeof (uint32_t),
1979 BUS_DMASYNC_PREWRITE);
1980 ifp->if_ierrors++;
1981 return;
1983 m = data->m;
1984 data->m = m1;
1986 /* Update RX descriptor. */
1987 ring->desc[ring->cur] = htole32(data->map->dm_segs[0].ds_addr >> 8);
1988 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
1989 ring->cur * sizeof (uint32_t), sizeof (uint32_t),
1990 BUS_DMASYNC_PREWRITE);
1992 /* Finalize mbuf. */
1993 m->m_pkthdr.rcvif = ifp;
1994 m->m_data = head;
1995 m->m_pkthdr.len = m->m_len = len;
1997 /* Grab a reference to the source node. */
1998 wh = mtod(m, struct ieee80211_frame *);
1999 ni = ieee80211_find_rxnode(ic,(struct ieee80211_frame_min *)wh);
2001 #if 0
2002 rxi.rxi_flags = 0;
2003 if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
2004 !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
2005 (ni->ni_flags & IEEE80211_NODE_RXPROT) &&
2006 ni->ni_pairwise_key.k_cipher == IEEE80211_CIPHER_CCMP) {
2007 if ((flags & IWN_RX_CIPHER_MASK) != IWN_RX_CIPHER_CCMP) {
2008 ic->ic_stats.is_ccmp_dec_errs++;
2009 ifp->if_ierrors++;
2010 return;
2012 /* Check whether decryption was successful or not. */
2013 if ((desc->type == IWN_MPDU_RX_DONE &&
2014 (flags & (IWN_RX_MPDU_DEC | IWN_RX_MPDU_MIC_OK)) !=
2015 (IWN_RX_MPDU_DEC | IWN_RX_MPDU_MIC_OK)) ||
2016 (desc->type != IWN_MPDU_RX_DONE &&
2017 (flags & IWN_RX_DECRYPT_MASK) != IWN_RX_DECRYPT_OK)) {
2018 DPRINTF(("CCMP decryption failed 0x%x\n", flags));
2019 ic->ic_stats.is_ccmp_dec_errs++;
2020 ifp->if_ierrors++;
2021 return;
2023 if (iwn_ccmp_decap(sc, m, &ni->ni_pairwise_key) != 0) {
2024 ifp->if_ierrors++;
2025 return;
2027 rxi.rxi_flags |= IEEE80211_RXI_HWDEC;
2029 #endif
2031 rssi = hal->get_rssi(stat);
2032 if (ic->ic_state == IEEE80211_S_SCAN)
2033 iwn_fix_channel(ic, m);
2035 #if NBPFILTER > 0
2036 if (sc->sc_drvbpf != NULL) {
2037 struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
2039 tap->wr_flags = 0;
2040 if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE))
2041 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
2042 tap->wr_chan_freq =
2043 htole16(ic->ic_channels[stat->chan].ic_freq);
2044 tap->wr_chan_flags =
2045 htole16(ic->ic_channels[stat->chan].ic_flags);
2046 tap->wr_dbm_antsignal = (int8_t)rssi;
2047 tap->wr_dbm_antnoise = (int8_t)sc->noise;
2048 tap->wr_tsft = stat->tstamp;
2049 switch (stat->rate) {
2050 /* CCK rates. */
2051 case 10: tap->wr_rate = 2; break;
2052 case 20: tap->wr_rate = 4; break;
2053 case 55: tap->wr_rate = 11; break;
2054 case 110: tap->wr_rate = 22; break;
2055 /* OFDM rates. */
2056 case 0xd: tap->wr_rate = 12; break;
2057 case 0xf: tap->wr_rate = 18; break;
2058 case 0x5: tap->wr_rate = 24; break;
2059 case 0x7: tap->wr_rate = 36; break;
2060 case 0x9: tap->wr_rate = 48; break;
2061 case 0xb: tap->wr_rate = 72; break;
2062 case 0x1: tap->wr_rate = 96; break;
2063 case 0x3: tap->wr_rate = 108; break;
2064 /* Unknown rate: should not happen. */
2065 default: tap->wr_rate = 0;
2068 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
2070 #endif
2072 /* Send the frame to the 802.11 layer. */
2073 ieee80211_input(ic, m, ni, rssi, 0);
2075 /* Node is no longer needed. */
2076 ieee80211_free_node(ni);
2080 * Process a CALIBRATION_RESULT notification sent by the initialization
2081 * firmware on response to a CMD_CALIB_CONFIG command (5000 only.)
2083 void
2084 iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
2085 struct iwn_rx_data *data)
2087 struct iwn_phy_calib *calib = (struct iwn_phy_calib *)(desc + 1);
2088 int len, idx = -1;
2090 /* Runtime firmware should not send such a notification. */
2091 if (!(sc->sc_flags & IWN_FLAG_FIRST_BOOT))
2092 return;
2094 len = (le32toh(desc->len) & 0x3fff) - 4;
2095 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc), len,
2096 BUS_DMASYNC_POSTREAD);
2098 switch (calib->code) {
2099 case IWN5000_PHY_CALIB_DC:
2100 if (sc->hw_type == IWN_HW_REV_TYPE_5150)
2101 idx = 0;
2102 break;
2103 case IWN5000_PHY_CALIB_LO:
2104 idx = 1;
2105 break;
2106 case IWN5000_PHY_CALIB_TX_IQ:
2107 idx = 2;
2108 break;
2109 case IWN5000_PHY_CALIB_TX_IQ_PERD:
2110 if (sc->hw_type != IWN_HW_REV_TYPE_5150)
2111 idx = 3;
2112 break;
2113 case IWN5000_PHY_CALIB_BASE_BAND:
2114 idx = 4;
2115 break;
2117 if (idx == -1) /* Ignore other results. */
2118 return;
2120 /* Save calibration result. */
2121 if (sc->calibcmd[idx].buf != NULL)
2122 free(sc->calibcmd[idx].buf, M_DEVBUF);
2123 sc->calibcmd[idx].buf = malloc(len, M_DEVBUF, M_NOWAIT);
2124 if (sc->calibcmd[idx].buf == NULL) {
2125 DPRINTF(("not enough memory for calibration result %d\n",
2126 calib->code));
2127 return;
2129 DPRINTF(("saving calibration result code=%d len=%d\n",
2130 calib->code, len));
2131 sc->calibcmd[idx].len = len;
2132 memcpy(sc->calibcmd[idx].buf, calib, len);
2137 * XXX: Hack to set the current channel to the value advertised in beacons or
2138 * probe responses. Only used during AP detection.
2139 * XXX: Duplicated from if_iwi.c
2141 static void
2142 iwn_fix_channel(struct ieee80211com *ic, struct mbuf *m)
2144 struct ieee80211_frame *wh;
2145 uint8_t subtype;
2146 uint8_t *frm, *efrm;
2148 wh = mtod(m, struct ieee80211_frame *);
2150 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT)
2151 return;
2153 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
2155 if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
2156 subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP)
2157 return;
2159 frm = (uint8_t *)(wh + 1);
2160 efrm = mtod(m, uint8_t *) + m->m_len;
2162 frm += 12; /* skip tstamp, bintval and capinfo fields */
2163 while (frm < efrm) {
2164 if (*frm == IEEE80211_ELEMID_DSPARMS)
2165 #if IEEE80211_CHAN_MAX < 255
2166 if (frm[2] <= IEEE80211_CHAN_MAX)
2167 #endif
2168 ic->ic_curchan = &ic->ic_channels[frm[2]];
2170 frm += frm[1] + 2;
2176 * Process an RX_STATISTICS or BEACON_STATISTICS firmware notification.
2177 * The latter is sent by the firmware after each received beacon.
2179 static void
2180 iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,
2181 struct iwn_rx_data *data)
2183 struct ieee80211com *ic = &sc->sc_ic;
2184 struct iwn_calib_state *calib = &sc->calib;
2185 struct iwn_stats *stats = (struct iwn_stats *)(desc + 1);
2187 /* Ignore statistics received during a scan. */
2188 if (ic->ic_state != IEEE80211_S_RUN)
2189 return;
2191 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
2192 sizeof (*stats), BUS_DMASYNC_POSTREAD);
2194 DPRINTFN(3, ("received statistics (cmd=%d)\n", desc->type));
2195 sc->calib_cnt = 0; /* Reset TX power calibration timeout. */
2197 #if 0
2198 /* Test if temperature has changed. */
2199 if (stats->general.temp != sc->rawtemp) {
2200 /* Convert "raw" temperature to degC. */
2201 sc->rawtemp = stats->general.temp;
2202 temp = hal->get_temperature(sc);
2203 DPRINTFN(2, ("temperature=%dC\n", temp));
2205 /* Update temperature sensor. */
2206 sc->sensor.value = IWN_CTOMUK(temp);
2207 sc->sensor.flags &= ~SENSOR_FINVALID;
2209 /* Update TX power if need be (4965AGN only.) */
2210 if (sc->hw_type == IWN_HW_REV_TYPE_4965)
2211 iwn4965_power_calibration(sc, temp);
2213 #endif
2215 if (desc->type != IWN_BEACON_STATISTICS)
2216 return; /* Reply to a statistics request. */
2218 sc->noise = iwn_get_noise(&stats->rx.general);
2220 /* Test that RSSI and noise are present in stats report. */
2221 if (le32toh(stats->rx.general.flags) != 1) {
2222 DPRINTF(("received statistics without RSSI\n"));
2223 return;
2226 if (calib->state == IWN_CALIB_STATE_ASSOC)
2227 iwn_collect_noise(sc, &stats->rx.general);
2228 else if (calib->state == IWN_CALIB_STATE_RUN)
2229 iwn_tune_sensitivity(sc, &stats->rx);
2233 * Process a TX_DONE firmware notification. Unfortunately, the 4965AGN
2234 * and 5000 adapters have different incompatible TX status formats.
2236 static void
2237 iwn4965_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
2238 struct iwn_rx_data *data)
2240 struct iwn4965_tx_stat *stat = (struct iwn4965_tx_stat *)(desc + 1);
2242 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
2243 sizeof (*stat), BUS_DMASYNC_POSTREAD);
2244 iwn_tx_done(sc, desc, stat->retrycnt, le32toh(stat->status) & 0xff);
2247 static void
2248 iwn5000_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
2249 struct iwn_rx_data *data)
2251 struct iwn5000_tx_stat *stat = (struct iwn5000_tx_stat *)(desc + 1);
2253 /* Reset TX scheduler slot. */
2254 iwn5000_reset_sched(sc, desc->qid & 0xf, desc->idx);
2256 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
2257 sizeof (*stat), BUS_DMASYNC_POSTREAD);
2258 iwn_tx_done(sc, desc, stat->retrycnt, le16toh(stat->status) & 0xff);
2262 * Adapter-independent backend for TX_DONE firmware notifications.
2264 static void
2265 iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int retrycnt,
2266 uint8_t status)
2268 struct ifnet *ifp = sc->sc_ic.ic_ifp;
2269 struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
2270 struct iwn_tx_data *data = &ring->data[desc->idx];
2271 struct iwn_node *wn = (struct iwn_node *)data->ni;
2273 /* Update rate control statistics. */
2274 wn->amn.amn_txcnt++;
2275 if (retrycnt > 0)
2276 wn->amn.amn_retrycnt++;
2278 if (status != 1 && status != 2)
2279 ifp->if_oerrors++;
2280 else
2281 ifp->if_opackets++;
2283 /* Unmap and free mbuf. */
2284 bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
2285 BUS_DMASYNC_POSTWRITE);
2286 bus_dmamap_unload(sc->sc_dmat, data->map);
2287 m_freem(data->m);
2288 data->m = NULL;
2289 ieee80211_free_node(data->ni);
2290 data->ni = NULL;
2292 sc->sc_tx_timer = 0;
2293 if (--ring->queued < IWN_TX_RING_LOMARK) {
2294 sc->qfullmsk &= ~(1 << ring->qid);
2295 if (sc->qfullmsk == 0 && (ifp->if_flags & IFF_OACTIVE)) {
2296 ifp->if_flags &= ~IFF_OACTIVE;
2297 iwn_start(ifp);
2303 * Process a "command done" firmware notification. This is where we wakeup
2304 * processes waiting for a synchronous command completion.
2306 static void
2307 iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc)
2309 struct iwn_tx_ring *ring = &sc->txq[4];
2310 struct iwn_tx_data *data;
2312 if ((desc->qid & 0xf) != 4)
2313 return; /* Not a command ack. */
2315 data = &ring->data[desc->idx];
2317 /* If the command was mapped in an mbuf, free it. */
2318 if (data->m != NULL) {
2319 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
2320 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
2321 bus_dmamap_unload(sc->sc_dmat, data->map);
2322 m_freem(data->m);
2323 data->m = NULL;
2325 wakeup(&ring->desc[desc->idx]);
2329 * Process an INT_FH_RX or INT_SW_RX interrupt.
2331 static void
2332 iwn_microcode_ready(struct iwn_softc *sc, struct iwn_ucode_info *uc)
2335 /* The microcontroller is ready */
2336 DPRINTF(("microcode alive notification version=%d.%d "
2337 "subtype=%x alive=%x\n", uc->major, uc->minor,
2338 uc->subtype, le32toh(uc->valid)));
2341 if (le32toh(uc->valid) != 1) {
2342 aprint_error_dev(sc->sc_dev, "microcontroller initialization "
2343 "failed\n");
2344 return;
2346 if (uc->subtype == IWN_UCODE_INIT) {
2347 /* save microcontroller's report */
2348 memcpy(&sc->ucode_info, uc, sizeof (*uc));
2350 /* Save the address of the error log in SRAM. */
2351 sc->errptr = le32toh(uc->errptr);
2354 static void
2355 iwn_notif_intr(struct iwn_softc *sc)
2357 struct ieee80211com *ic = &sc->sc_ic;
2358 struct ifnet *ifp = ic->ic_ifp;
2359 struct iwn_rx_data *data;
2360 struct iwn_rx_desc *desc;
2361 uint16_t hw;
2363 bus_dmamap_sync(sc->sc_dmat, sc->rxq.stat_dma.map,
2364 0, sc->rxq.stat_dma.size, BUS_DMASYNC_POSTREAD);
2366 hw = le16toh(sc->rxq.stat->closed_count) & 0xfff;
2369 * If the radio is disabled then down the interface and stop
2370 * processing - scan the queue for a microcode load command
2371 * result. It is the only thing that we can do with the radio
2372 * off.
2374 if (!sc->sc_radio) {
2375 while (sc->rxq.cur != hw) {
2376 data = &sc->rxq.data[sc->rxq.cur];
2377 desc = (void *)data->m->m_ext.ext_buf;
2378 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
2379 sizeof(*desc), BUS_DMASYNC_POSTREAD);
2380 if (desc->type == IWN_UC_READY) {
2381 iwn_microcode_ready(sc,
2382 (struct iwn_ucode_info *)(desc + 1));
2383 } else if (desc->type == IWN_STATE_CHANGED) {
2384 uint32_t *status = (uint32_t *)(desc + 1);
2386 /* enabled/disabled notification */
2387 DPRINTF(("state changed to %x\n",
2388 le32toh(*status)));
2390 sc->sc_radio = !(le32toh(*status) & 1);
2393 sc->rxq.cur = (sc->rxq.cur + 1) % IWN_RX_RING_COUNT;
2396 if (!sc->sc_radio) {
2397 iwn_stop(ifp, 1);
2400 return;
2403 bus_dmamap_sync(sc->sc_dmat, sc->rxq.stat_dma.map,
2404 0, sc->rxq.stat_dma.size, BUS_DMASYNC_POSTREAD);
2406 hw = le16toh(sc->rxq.stat->closed_count) & 0xfff;
2407 while (sc->rxq.cur != hw) {
2408 data = &sc->rxq.data[sc->rxq.cur];
2409 desc = (void *)data->m->m_ext.ext_buf;
2411 bus_dmamap_sync(sc->sc_dmat, data->map, 0, sizeof (*desc),
2412 BUS_DMASYNC_POSTREAD);
2414 DPRINTFN(4, ("notification qid=%d idx=%d flags=%x type=%d\n",
2415 desc->qid & 0xf, desc->idx, desc->flags, desc->type));
2417 if (!(desc->qid & 0x80)) /* Reply to a command. */
2418 iwn_cmd_done(sc, desc);
2420 switch (desc->type) {
2421 case IWN_RX_PHY:
2422 iwn_rx_phy(sc, desc);
2423 break;
2425 case IWN_RX_DONE: /* 4965AGN only. */
2426 case IWN_MPDU_RX_DONE:
2427 /* An 802.11 frame has been received. */
2428 iwn_rx_done(sc, desc, data);
2429 break;
2431 case IWN_TX_DONE:
2432 /* An 802.11 frame has been transmitted. */
2433 sc->sc_hal->tx_done(sc, desc, data);
2434 break;
2436 case IWN_RX_STATISTICS:
2437 case IWN_BEACON_STATISTICS:
2438 iwn_rx_statistics(sc, desc, data);
2439 break;
2441 case IWN_BEACON_MISSED:
2443 struct iwn_beacon_missed *miss =
2444 (struct iwn_beacon_missed *)(desc + 1);
2446 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
2447 sizeof (*miss), BUS_DMASYNC_POSTREAD);
2449 * If more than 5 consecutive beacons are missed,
2450 * reinitialize the sensitivity state machine.
2452 DPRINTF(("beacons missed %d/%d\n",
2453 le32toh(miss->consecutive), le32toh(miss->total)));
2454 if (ic->ic_state == IEEE80211_S_RUN &&
2455 le32toh(miss->consecutive) > 5)
2456 (void)iwn_init_sensitivity(sc);
2457 break;
2459 case IWN_UC_READY:
2461 iwn_microcode_ready(sc,
2462 (struct iwn_ucode_info *)(desc + 1));
2463 break;
2465 case IWN_STATE_CHANGED:
2467 uint32_t *status = (uint32_t *)(desc + 1);
2469 /* Enabled/disabled notification. */
2470 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
2471 sizeof (*status), BUS_DMASYNC_POSTREAD);
2472 DPRINTF(("state changed to %x\n", le32toh(*status)));
2474 sc->sc_radio = !(le32toh(*status) & 1);
2476 if (le32toh(*status) & 1) {
2477 /* The radio button has to be pushed. */
2478 aprint_error_dev(sc->sc_dev,
2479 "Radio transmitter is off\n");
2480 /* Turn the interface down. */
2481 iwn_stop(ifp, 1);
2482 return; /* No further processing. */
2484 break;
2486 case IWN_START_SCAN:
2488 struct iwn_start_scan *scan =
2489 (struct iwn_start_scan *)(desc + 1);
2491 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
2492 sizeof (*scan), BUS_DMASYNC_POSTREAD);
2493 DPRINTFN(2, ("scanning channel %d status %x\n",
2494 scan->chan, le32toh(scan->status)));
2496 /* Fix current channel. */
2497 ic->ic_bss->ni_chan = &ic->ic_channels[scan->chan];
2498 break;
2500 case IWN_STOP_SCAN:
2502 struct iwn_stop_scan *scan =
2503 (struct iwn_stop_scan *)(desc + 1);
2505 bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
2506 sizeof (*scan), BUS_DMASYNC_POSTREAD);
2507 DPRINTF(("scan finished nchan=%d status=%d chan=%d\n",
2508 scan->nchan, scan->status, scan->chan));
2510 if (scan->status == 1 && scan->chan <= 14 &&
2511 (sc->sc_flags & IWN_FLAG_HAS_5GHZ)) {
2513 * We just finished scanning 2GHz channels,
2514 * start scanning 5GHz ones.
2516 if (iwn_scan(sc, IEEE80211_CHAN_5GHZ) == 0)
2517 break;
2519 sc->is_scanning = false;
2520 ieee80211_end_scan(ic);
2521 break;
2523 case IWN5000_CALIBRATION_RESULT:
2524 iwn5000_rx_calib_results(sc, desc, data);
2525 break;
2527 case IWN5000_CALIBRATION_DONE:
2528 wakeup(sc);
2529 break;
2532 sc->rxq.cur = (sc->rxq.cur + 1) % IWN_RX_RING_COUNT;
2535 /* Tell the firmware what we have processed. */
2536 hw = (hw == 0) ? IWN_RX_RING_COUNT - 1 : hw - 1;
2537 IWN_WRITE(sc, IWN_FH_RX_WPTR, hw & ~7);
2541 * Process an INT_WAKEUP interrupt raised when the microcontroller wakes up
2542 * from power-down sleep mode.
2544 static void
2545 iwn_wakeup_intr(struct iwn_softc *sc)
2547 int qid;
2549 DPRINTF(("ucode wakeup from power-down sleep\n"));
2551 /* Wakeup RX and TX rings. */
2552 IWN_WRITE(sc, IWN_FH_RX_WPTR, sc->rxq.cur & ~7);
2553 for (qid = 0; qid < 6; qid++) {
2554 struct iwn_tx_ring *ring = &sc->txq[qid];
2555 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | ring->cur);
2560 * Dump the error log of the firmware when a firmware panic occurs. Although
2561 * we can't debug the firmware because it is neither open source nor free, it
2562 * can help us to identify certain classes of problems.
2564 void
2565 iwn_fatal_intr(struct iwn_softc *sc)
2567 const struct iwn_hal *hal = sc->sc_hal;
2568 struct iwn_fw_dump dump;
2569 int i;
2571 /* Check that the error log address is valid. */
2572 if (sc->errptr < IWN_FW_DATA_BASE ||
2573 sc->errptr + sizeof (dump) >
2574 IWN_FW_DATA_BASE + hal->fw_data_maxsz) {
2575 aprint_error_dev(sc->sc_dev,
2576 "bad firmware error log address 0x%08x\n", sc->errptr);
2577 return;
2579 if (iwn_nic_lock(sc) != 0) {
2580 aprint_error_dev(sc->sc_dev,
2581 "could not read firmware error log\n");
2582 return;
2584 /* Read firmware error log from SRAM. */
2585 iwn_mem_read_region_4(sc, sc->errptr, (uint32_t *)&dump,
2586 sizeof (dump) / sizeof (uint32_t));
2587 iwn_nic_unlock(sc);
2589 if (dump.valid == 0) {
2590 aprint_error_dev(sc->sc_dev, "firmware error log is empty\n");
2591 return;
2593 printf("firmware error log:\n");
2594 #if 0
2595 printf(" error type = \"%s\" (0x%08X)\n",
2596 (dump.id < nitems(iwn_fw_errmsg)) ?
2597 iwn_fw_errmsg[dump.id] : "UNKNOWN",
2598 dump.id);
2599 #endif
2600 printf(" program counter = 0x%08X\n", dump.pc);
2601 printf(" source line = 0x%08X\n", dump.src_line);
2602 printf(" error data = 0x%08X%08X\n",
2603 dump.error_data[0], dump.error_data[1]);
2604 printf(" branch link = 0x%08X%08X\n",
2605 dump.branch_link[0], dump.branch_link[1]);
2606 printf(" interrupt link = 0x%08X%08X\n",
2607 dump.interrupt_link[0], dump.interrupt_link[1]);
2608 printf(" time = %u\n", dump.time[0]);
2610 /* Dump driver status (TX and RX rings) while we're here. */
2611 printf("driver status:\n");
2612 for (i = 0; i < hal->ntxqs; i++) {
2613 struct iwn_tx_ring *ring = &sc->txq[i];
2614 printf(" tx ring %2d: qid=%-2d cur=%-3d queued=%-3d\n",
2615 i, ring->qid, ring->cur, ring->queued);
2617 printf(" rx ring: cur=%d\n", sc->rxq.cur);
2618 printf(" 802.11 state %d\n", sc->sc_ic.ic_state);
2621 static int
2622 iwn_intr(void *arg)
2624 struct iwn_softc *sc = arg;
2625 struct ifnet *ifp = sc->sc_ic.ic_ifp;
2626 uint32_t r1, r2;
2628 /* Disable interrupts. */
2629 IWN_WRITE(sc, IWN_MASK, 0);
2631 r1 = IWN_READ(sc, IWN_INT);
2632 r2 = IWN_READ(sc, IWN_FH_INT);
2634 if (r1 == 0 && r2 == 0) {
2635 if (ifp->if_flags & IFF_UP)
2636 IWN_WRITE(sc, IWN_MASK, IWN_INT_MASK);
2637 return 0; /* Interrupt not for us. */
2639 if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
2640 return 0; /* Hardware gone! */
2642 /* Acknowledge interrupts. */
2643 IWN_WRITE(sc, IWN_INT, r1);
2644 IWN_WRITE(sc, IWN_FH_INT, r2);
2646 if (r1 & IWN_INT_RF_TOGGLED) {
2647 uint32_t tmp = IWN_READ(sc, IWN_GP_CNTRL);
2648 aprint_error_dev(sc->sc_dev, "RF switch: radio %s\n",
2649 (tmp & IWN_GP_CNTRL_RFKILL) ? "enabled" : "disabled");
2650 sc->sc_radio = (tmp & IWN_GP_CNTRL_RFKILL);
2652 if (r1 & IWN_INT_CT_REACHED) {
2653 aprint_error_dev(sc->sc_dev, "critical temperature reached!\n");
2654 /* XXX Reduce TX power? */
2656 if (r1 & (IWN_INT_SW_ERR | IWN_INT_HW_ERR)) {
2657 aprint_error_dev(sc->sc_dev, "fatal firmware error\n");
2658 /* Dump firmware error log and stop. */
2659 iwn_fatal_intr(sc);
2660 iwn_stop(sc->sc_ic.ic_ifp, 1);
2661 return 1;
2663 if ((r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX)) ||
2664 (r2 & IWN_FH_INT_RX))
2665 iwn_notif_intr(sc);
2667 if ((r1 & IWN_INT_FH_TX) || (r2 & IWN_FH_INT_TX))
2668 wakeup(sc); /* FH DMA transfer completed. */
2670 if (r1 & IWN_INT_ALIVE)
2671 wakeup(sc); /* Firmware is alive. */
2673 if (r1 & IWN_INT_WAKEUP)
2674 iwn_wakeup_intr(sc);
2676 /* Re-enable interrupts. */
2677 if (ifp->if_flags & IFF_UP)
2678 IWN_WRITE(sc, IWN_MASK, IWN_INT_MASK);
2680 return 1;
2684 * Update TX scheduler ring when transmitting an 802.11 frame (4965AGN and
2685 * 5000 adapters use a slightly different format.)
2687 static void
2688 iwn4965_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
2689 uint16_t len)
2691 uint16_t *w = &sc->sched[qid * IWN4965_SCHED_COUNT + idx];
2693 *w = htole16(len + 8);
2694 bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
2695 (char *)(void *)w - (char *)(void *)sc->sched_dma.vaddr,
2696 sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
2697 if (idx < IWN_SCHED_WINSZ) {
2698 *(w + IWN_TX_RING_COUNT) = *w;
2699 bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
2700 (char *)(void *)(w + IWN_TX_RING_COUNT) -
2701 (char *)(void *)sc->sched_dma.vaddr,
2702 sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
2706 static void
2707 iwn5000_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
2708 uint16_t len)
2710 uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx];
2712 *w = htole16(id << 12 | (len + 8));
2713 bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
2714 (char *)(void *)w - (char *)(void *)sc->sched_dma.vaddr,
2715 sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
2716 if (idx < IWN_SCHED_WINSZ) {
2717 *(w + IWN_TX_RING_COUNT) = *w;
2718 bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
2719 (char *)(void *)(w + IWN_TX_RING_COUNT) -
2720 (char *)(void *)sc->sched_dma.vaddr,
2721 sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
2725 static void
2726 iwn5000_reset_sched(struct iwn_softc *sc, int qid, int idx)
2728 uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx];
2730 *w = (*w & htole16(0xf000)) | htole16(1);
2731 bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
2732 (char *)(void *)w - (char *)(void *)sc->sched_dma.vaddr,
2733 sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
2734 if (idx < IWN_SCHED_WINSZ) {
2735 *(w + IWN_TX_RING_COUNT) = *w;
2736 bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
2737 (char *)(void *)(w + IWN_TX_RING_COUNT) -
2738 (char *)(void *)sc->sched_dma.vaddr,
2739 sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
2743 static int
2744 iwn_tx(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
2746 const struct iwn_hal *hal = sc->sc_hal;
2747 struct ieee80211com *ic = &sc->sc_ic;
2748 struct iwn_node *wn = (void *)ni;
2749 struct iwn_tx_ring *ring;
2750 struct iwn_tx_desc *desc;
2751 struct iwn_tx_data *data;
2752 struct iwn_tx_cmd *cmd;
2753 struct iwn_cmd_data *tx;
2754 const struct iwn_rate *rinfo;
2755 struct ieee80211_frame *wh;
2756 struct ieee80211_key *k = NULL;
2757 const struct chanAccParams *cap;
2758 struct mbuf *m1;
2759 uint32_t flags;
2760 u_int hdrlen;
2761 bus_dma_segment_t *seg;
2762 uint8_t ridx, txant, type;
2763 int i, totlen, error, pad, noack;
2765 wh = mtod(m, struct ieee80211_frame *);
2766 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
2768 /* JAF XXX two lines above were not in wpi. check we don't duplicate this */
2770 if (IEEE80211_QOS_HAS_SEQ(wh)) {
2771 hdrlen = sizeof (struct ieee80211_qosframe);
2772 cap = &ic->ic_wme.wme_chanParams;
2773 noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
2774 } else {
2775 hdrlen = sizeof (struct ieee80211_frame);
2776 noack = 0;
2779 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
2780 k = ieee80211_crypto_encap(ic, ni, m);
2781 if (k == NULL) {
2782 m_freem(m);
2783 return ENOBUFS;
2785 /* packet header may have moved, reset our local pointer */
2786 wh = mtod(m, struct ieee80211_frame *);
2789 ring = &sc->txq[ac];
2790 desc = &ring->desc[ring->cur];
2791 data = &ring->data[ring->cur];
2793 /* Choose a TX rate index. */
2794 if (type == IEEE80211_FC0_TYPE_MGT) {
2795 /* mgmt frames are sent at the lowest available bit-rate */
2796 ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
2797 IWN_RIDX_OFDM6 : IWN_RIDX_CCK1;
2798 } else {
2799 if (ic->ic_fixed_rate != -1) {
2800 ridx = sc->fixed_ridx;
2801 } else
2802 ridx = wn->ridx[ni->ni_txrate];
2804 rinfo = &iwn_rates[ridx];
2806 #if NBPFILTER > 0
2807 if (sc->sc_drvbpf != NULL) {
2808 struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
2810 tap->wt_flags = 0;
2811 tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
2812 tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
2813 tap->wt_rate = rinfo->rate;
2814 tap->wt_hwqueue = ac;
2815 if (wh->i_fc[1] & IEEE80211_FC1_WEP)
2816 tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
2818 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m);
2820 #endif
2822 totlen = m->m_pkthdr.len;
2824 /* Encrypt the frame if need be. */
2825 #ifdef IEEE80211_FC1_PROTECTED
2826 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
2827 /* Retrieve key for TX. */
2828 k = ieee80211_get_txkey(ic, wh, ni);
2829 if (k->k_cipher != IEEE80211_CIPHER_CCMP) {
2830 /* Do software encryption. */
2831 if ((m = ieee80211_encrypt(ic, m, k)) == NULL)
2832 return ENOBUFS;
2833 /* 802.11 header may have moved. */
2834 wh = mtod(m, struct ieee80211_frame *);
2835 totlen = m->m_pkthdr.len;
2837 } else /* HW appends CCMP MIC. */
2838 totlen += IEEE80211_CCMP_HDRLEN;
2840 #endif
2842 /* Prepare TX firmware command. */
2843 cmd = &ring->cmd[ring->cur];
2844 cmd->code = IWN_CMD_TX_DATA;
2845 cmd->flags = 0;
2846 cmd->qid = ring->qid;
2847 cmd->idx = ring->cur;
2849 tx = (struct iwn_cmd_data *)cmd->data;
2850 /* NB: No need to clear tx, all fields are reinitialized here. */
2851 tx->scratch = 0; /* clear "scratch" area */
2853 flags = 0;
2854 if (!noack && !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2855 flags |= IWN_TX_NEED_ACK;
2856 } else if (m->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold)
2857 flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
2859 #ifdef notyet
2860 if ((wh->i_fc[0] &
2861 (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
2862 (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR))
2863 flags |= IWN_TX_IMM_BA; /* Cannot happen yet. */
2864 #endif
2866 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
2867 flags |= IWN_TX_MORE_FRAG; /* Cannot happen yet. */
2869 /* Check if frame must be protected using RTS/CTS or CTS-to-self. */
2870 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2871 /* NB: Group frames are sent using CCK in 802.11b/g. */
2872 if (totlen + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) {
2873 flags |= IWN_TX_NEED_RTS;
2874 } else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
2875 ridx >= IWN_RIDX_OFDM6) {
2876 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
2877 flags |= IWN_TX_NEED_CTS;
2878 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
2879 flags |= IWN_TX_NEED_RTS;
2881 if (flags & (IWN_TX_NEED_RTS | IWN_TX_NEED_CTS)) {
2882 if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
2883 /* 5000 autoselects RTS/CTS or CTS-to-self. */
2884 flags &= ~(IWN_TX_NEED_RTS | IWN_TX_NEED_CTS);
2885 flags |= IWN_TX_NEED_PROTECTION;
2886 } else
2887 flags |= IWN_TX_FULL_TXOP;
2891 if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
2892 type != IEEE80211_FC0_TYPE_DATA)
2893 tx->id = hal->broadcast_id;
2894 else
2895 tx->id = wn->id;
2897 if (type == IEEE80211_FC0_TYPE_MGT) {
2898 uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
2900 #ifndef IEEE80211_STA_ONLY
2901 /* Tell HW to set timestamp in probe responses. */
2902 if ((subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) ||
2903 (subtype == IEEE80211_FC0_SUBTYPE_PROBE_REQ))
2904 flags |= IWN_TX_INSERT_TSTAMP;
2905 #endif
2906 if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
2907 subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ ||
2908 subtype == IEEE80211_FC0_SUBTYPE_AUTH ||
2909 subtype == IEEE80211_FC0_SUBTYPE_DEAUTH) {
2910 flags &= ~IWN_TX_NEED_RTS;
2911 flags |= IWN_TX_NEED_CTS;
2912 tx->timeout = htole16(3);
2913 } else
2914 tx->timeout = htole16(2);
2915 } else
2916 tx->timeout = htole16(0);
2918 if (hdrlen & 3) {
2919 /* First segment's length must be a multiple of 4. */
2920 flags |= IWN_TX_NEED_PADDING;
2921 pad = 4 - (hdrlen & 3);
2922 } else
2923 pad = 0;
2925 #if 0
2926 if (type == IEEE80211_FC0_TYPE_CTL) {
2927 uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
2929 /* tell h/w to set timestamp in probe responses */
2930 if (subtype == 0x0080) /* linux says this is "back request" */
2931 /* linux says (1 << 6) is IMM_BA_RSP_MASK */
2932 flags |= (IWN_TX_NEED_ACK | (1 << 6));
2934 #endif
2936 tx->len = htole16(totlen);
2937 tx->tid = 0/* tid */;
2938 tx->rts_ntries = 60;
2939 tx->data_ntries = 15;
2940 tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
2941 tx->plcp = rinfo->plcp;
2942 tx->rflags = rinfo->flags;
2943 if (tx->id == hal->broadcast_id) {
2944 /* Group or management frame. */
2945 tx->linkq = 0;
2946 /* XXX Alternate between antenna A and B? */
2947 txant = IWN_LSB(sc->txantmsk);
2948 tx->rflags |= IWN_RFLAG_ANT(txant);
2949 } else {
2950 tx->linkq = ni->ni_rates.rs_nrates - ni->ni_txrate - 1;
2951 flags |= IWN_TX_LINKQ; /* enable MRR */
2953 /* Set physical address of "scratch area". */
2954 tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr));
2955 tx->hiaddr = IWN_HIADDR(data->scratch_paddr);
2957 /* Copy 802.11 header in TX command. */
2958 memcpy(((uint8_t *)tx) + sizeof(*tx), wh, hdrlen);
2960 /* Trim 802.11 header. */
2961 m_adj(m, hdrlen);
2962 tx->security = 0;
2964 #ifdef notyet
2965 if (k != NULL && k->k_cipher == IEEE80211_CIPHER_CCMP) {
2966 /* Trim 802.11 header and prepend CCMP IV. */
2967 m_adj(m, hdrlen - IEEE80211_CCMP_HDRLEN);
2968 ivp = mtod(m, uint8_t *);
2969 k->k_tsc++;
2970 ivp[0] = k->k_tsc;
2971 ivp[1] = k->k_tsc >> 8;
2972 ivp[2] = 0;
2973 ivp[3] = k->k_id << 6 | IEEE80211_WEP_EXTIV;
2974 ivp[4] = k->k_tsc >> 16;
2975 ivp[5] = k->k_tsc >> 24;
2976 ivp[6] = k->k_tsc >> 32;
2977 ivp[7] = k->k_tsc >> 40;
2979 tx->security = IWN_CIPHER_CCMP;
2980 /* XXX flags |= IWN_TX_AMPDU_CCMP; */
2981 memcpy(tx->key, k->k_key, k->k_len);
2983 /* TX scheduler includes CCMP MIC len w/5000 Series. */
2984 if (sc->hw_type != IWN_HW_REV_TYPE_4965)
2985 totlen += IEEE80211_CCMP_MICLEN;
2986 } else {
2987 /* Trim 802.11 header. */
2988 m_adj(m, hdrlen);
2989 tx->security = 0;
2991 #endif
2992 tx->flags = htole32(flags);
2994 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
2995 BUS_DMA_WRITE | BUS_DMA_NOWAIT);
2996 if (error != 0 && error != EFBIG) {
2997 aprint_error_dev(sc->sc_dev, "could not map mbuf (error %d)\n",
2998 error);
2999 m_freem(m);
3000 return error;
3002 if (error != 0) {
3003 /* Too many DMA segments, linearize mbuf. */
3004 MGETHDR(m1, M_DONTWAIT, MT_DATA);
3005 if (m1 == NULL) {
3006 m_freem(m);
3007 return ENOBUFS;
3009 if (m->m_pkthdr.len > MHLEN) {
3010 MCLGET(m1, M_DONTWAIT);
3011 if (!(m1->m_flags & M_EXT)) {
3012 m_freem(m);
3013 m_freem(m1);
3014 return ENOBUFS;
3017 m_copydata(m, 0, m->m_pkthdr.len, mtod(m1, void *));
3018 m1->m_pkthdr.len = m1->m_len = m->m_pkthdr.len;
3019 m_freem(m);
3020 m = m1;
3022 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
3023 BUS_DMA_WRITE | BUS_DMA_NOWAIT);
3024 if (error != 0) {
3025 aprint_error_dev(sc->sc_dev,
3026 "could not map mbuf (error %d)\n", error);
3027 m_freem(m);
3028 return error;
3032 data->m = m;
3033 data->ni = ni;
3035 DPRINTFN(4, ("sending data: qid=%d idx=%d len=%d nsegs=%d\n",
3036 ring->qid, ring->cur, m->m_pkthdr.len, data->map->dm_nsegs));
3038 /* Fill TX descriptor. */
3039 desc->nsegs = 1 + data->map->dm_nsegs;
3040 /* First DMA segment is used by the TX command. */
3041 desc->segs[0].addr = htole32(IWN_LOADDR(data->cmd_paddr));
3042 desc->segs[0].len = htole16(IWN_HIADDR(data->cmd_paddr) |
3043 (4 + sizeof (*tx) + hdrlen + pad) << 4);
3044 /* Other DMA segments are for data payload. */
3045 seg = data->map->dm_segs;
3046 for (i = 1; i <= data->map->dm_nsegs; i++) {
3047 desc->segs[i].addr = htole32(IWN_LOADDR(seg->ds_addr));
3048 desc->segs[i].len = htole16(IWN_HIADDR(seg->ds_addr) |
3049 seg->ds_len << 4);
3050 seg++;
3053 bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
3054 BUS_DMASYNC_PREWRITE);
3055 bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
3056 (char *)(void *)cmd - (char *)(void *)ring->cmd_dma.vaddr,
3057 sizeof (*cmd), BUS_DMASYNC_PREWRITE);
3058 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
3059 (char *)(void *)desc - (char *)(void *)ring->desc_dma.vaddr,
3060 sizeof (*desc), BUS_DMASYNC_PREWRITE);
3062 /* Update TX scheduler. */
3063 hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
3065 /* Kick TX ring. */
3066 ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
3067 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
3069 /* Mark TX ring as full if we reach a certain threshold. */
3070 if (++ring->queued > IWN_TX_RING_HIMARK)
3071 sc->qfullmsk |= 1 << ring->qid;
3073 return 0;
3076 static void
3077 iwn_start(struct ifnet *ifp)
3079 struct iwn_softc *sc = ifp->if_softc;
3080 struct ieee80211com *ic = &sc->sc_ic;
3081 struct ieee80211_node *ni;
3082 struct ether_header *eh;
3083 struct mbuf *m;
3084 int ac;
3086 DPRINTFN(5, ("iwn_start enter\n"));
3089 * net80211 may still try to send management frames even if the
3090 * IFF_RUNNING flag is not set... Also, don't bother if the radio
3091 * is not enabled.
3093 if (((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) ||
3094 !sc->sc_radio)
3095 return;
3097 for (;;) {
3098 if (sc->qfullmsk != 0) {
3099 ifp->if_flags |= IFF_OACTIVE;
3100 break;
3102 /* Send pending management frames first. */
3103 IF_DEQUEUE(&ic->ic_mgtq, m);
3104 if (m != NULL) {
3105 ni = (void *)m->m_pkthdr.rcvif;
3106 ac = 0;
3107 goto sendit;
3109 if (ic->ic_state != IEEE80211_S_RUN)
3110 break;
3112 /* Encapsulate and send data frames. */
3113 IFQ_DEQUEUE(&ifp->if_snd, m);
3114 if (m == NULL)
3115 break;
3116 if (m->m_len < sizeof (*eh) &&
3117 (m = m_pullup(m, sizeof (*eh))) == NULL) {
3118 ifp->if_oerrors++;
3119 continue;
3121 eh = mtod(m, struct ether_header *);
3122 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
3123 if (ni == NULL) {
3124 m_freem(m);
3125 ifp->if_oerrors++;
3126 continue;
3128 /* classify mbuf so we can find which tx ring to use */
3129 if (ieee80211_classify(ic, m, ni) != 0) {
3130 m_freem(m);
3131 ieee80211_free_node(ni);
3132 ifp->if_oerrors++;
3133 continue;
3136 /* no QoS encapsulation for EAPOL frames */
3137 ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
3138 M_WME_GETAC(m) : WME_AC_BE;
3139 #if NBPFILTER > 0
3140 if (ifp->if_bpf != NULL)
3141 bpf_mtap(ifp->if_bpf, m);
3142 #endif
3143 if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
3144 ieee80211_free_node(ni);
3145 ifp->if_oerrors++;
3146 continue;
3148 sendit:
3149 #if NBPFILTER > 0
3150 if (ic->ic_rawbpf != NULL)
3151 bpf_mtap(ic->ic_rawbpf, m);
3152 #endif
3153 if (iwn_tx(sc, m, ni, ac) != 0) {
3154 ieee80211_free_node(ni);
3155 ifp->if_oerrors++;
3156 continue;
3159 sc->sc_tx_timer = 5;
3160 ifp->if_timer = 1;
3164 static void
3165 iwn_watchdog(struct ifnet *ifp)
3167 struct iwn_softc *sc = ifp->if_softc;
3169 ifp->if_timer = 0;
3171 if (sc->sc_tx_timer > 0) {
3172 if (--sc->sc_tx_timer == 0) {
3173 aprint_error_dev(sc->sc_dev, "device timeout\n");
3174 iwn_stop(ifp, 1);
3175 ifp->if_oerrors++;
3176 return;
3178 ifp->if_timer = 1;
3181 ieee80211_watchdog(&sc->sc_ic);
3184 static int
3185 iwn_ioctl(struct ifnet *ifp, u_long cmd, void* data)
3187 #define IS_RUNNING(ifp) \
3188 ((ifp->if_flags & IFF_UP) && (ifp->if_flags & IFF_RUNNING))
3190 struct iwn_softc *sc = ifp->if_softc;
3191 struct ieee80211com *ic = &sc->sc_ic;
3192 int s, error = 0;
3194 s = splnet();
3196 switch (cmd) {
3197 case SIOCSIFADDR:
3198 /* FALLTHROUGH */
3199 case SIOCSIFFLAGS:
3200 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
3201 break;
3202 if (ifp->if_flags & IFF_UP) {
3204 * resync the radio state just in case we missed
3205 * and event.
3207 sc->sc_radio =
3208 (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL);
3210 if (!sc->sc_radio) {
3211 error = EBUSY; /* XXX not really but same as els
3212 ewhere in driver */
3213 if (ifp->if_flags & IFF_RUNNING)
3214 iwn_stop(ifp, 1);
3215 } else if (!(ifp->if_flags & IFF_RUNNING))
3216 error = iwn_init(ifp);
3217 } else {
3218 if (ifp->if_flags & IFF_RUNNING)
3219 iwn_stop(ifp, 1);
3221 break;
3223 case SIOCADDMULTI:
3224 case SIOCDELMULTI:
3225 /* XXX no h/w multicast filter? --dyoung */
3226 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
3227 /* setup multicast filter, etc */
3228 error = 0;
3230 break;
3232 #if 0
3233 case SIOCS80211POWER:
3234 error = ieee80211_ioctl(ifp, cmd, data);
3235 if (error != ENETRESET)
3236 break;
3237 if (ic->ic_state == IEEE80211_S_RUN &&
3238 sc->calib.state == IWN_CALIB_STATE_RUN) {
3239 if (ic->ic_flags & IEEE80211_F_PMGTON)
3240 error = iwn_set_pslevel(sc, 0, 3, 0);
3241 else /* back to CAM */
3242 error = iwn_set_pslevel(sc, 0, 0, 0);
3243 } else {
3244 /* Defer until transition to IWN_CALIB_STATE_RUN. */
3245 error = 0;
3247 break;
3248 #endif
3250 default:
3251 error = ieee80211_ioctl(ic, cmd, data);
3254 if (error == ENETRESET) {
3255 error = 0;
3256 if (IS_RUNNING(ifp) &&
3257 (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)) {
3258 iwn_stop(ifp, 0);
3259 error = iwn_init(ifp);
3262 splx(s);
3263 return error;
3264 #undef IS_RUNNING
3268 * Send a command to the firmware.
3270 static int
3271 iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
3273 const struct iwn_hal *hal = sc->sc_hal;
3274 struct iwn_tx_ring *ring = &sc->txq[4];
3275 struct iwn_tx_desc *desc;
3276 struct iwn_tx_data *data;
3277 struct iwn_tx_cmd *cmd;
3278 struct mbuf *m;
3279 bus_addr_t paddr;
3280 int totlen, error;
3282 desc = &ring->desc[ring->cur];
3283 data = &ring->data[ring->cur];
3284 totlen = 4 + size;
3286 if (size > sizeof cmd->data) {
3287 /* Command is too large to fit in a descriptor. */
3288 if (totlen > MCLBYTES)
3289 return EINVAL;
3290 MGETHDR(m, M_DONTWAIT, MT_DATA);
3291 if (m == NULL)
3292 return ENOMEM;
3293 if (totlen > MHLEN) {
3294 MCLGET(m, M_DONTWAIT);
3295 if (!(m->m_flags & M_EXT)) {
3296 m_freem(m);
3297 return ENOMEM;
3300 cmd = mtod(m, struct iwn_tx_cmd *);
3301 error = bus_dmamap_load(sc->sc_dmat, data->map, cmd, totlen,
3302 NULL, BUS_DMA_NOWAIT);
3303 if (error != 0) {
3304 m_freem(m);
3305 return error;
3307 data->m = m;
3308 paddr = data->map->dm_segs[0].ds_addr;
3309 } else {
3310 cmd = &ring->cmd[ring->cur];
3311 paddr = data->cmd_paddr;
3314 cmd->code = code;
3315 cmd->flags = 0;
3316 cmd->qid = ring->qid;
3317 cmd->idx = ring->cur;
3318 memcpy(cmd->data, buf, size);
3320 desc->nsegs = 1;
3321 desc->segs[0].addr = htole32(IWN_LOADDR(paddr));
3322 desc->segs[0].len = htole16(IWN_HIADDR(paddr) | totlen << 4);
3324 if (size > sizeof cmd->data) {
3325 bus_dmamap_sync(sc->sc_dmat, data->map, 0, totlen,
3326 BUS_DMASYNC_PREWRITE);
3327 } else {
3328 bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
3329 (char *)(void *)cmd - (char *)(void *)ring->cmd_dma.vaddr,
3330 totlen, BUS_DMASYNC_PREWRITE);
3332 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
3333 (char *)(void *)desc - (char *)(void *)ring->desc_dma.vaddr,
3334 sizeof (*desc), BUS_DMASYNC_PREWRITE);
3336 /* Update TX scheduler. */
3337 hal->update_sched(sc, ring->qid, ring->cur, 0, 0);
3339 /* Kick command ring. */
3340 ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
3341 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
3343 return async ? 0 : tsleep(desc, PCATCH, "iwncmd", hz);
3346 static int
3347 iwn_add_node(struct iwn_softc *sc, struct ieee80211_node *ni, bool broadcast,
3348 bool async, uint32_t htflags)
3350 const struct iwn_hal *hal = sc->sc_hal;
3351 struct iwn_node_info node;
3352 int error;
3354 error = 0;
3356 memset(&node, 0, sizeof node);
3357 if (broadcast == true) {
3358 IEEE80211_ADDR_COPY(node.macaddr, etherbroadcastaddr);
3359 node.id = hal->broadcast_id;
3360 DPRINTF(("adding broadcast node\n"));
3361 } else {
3362 IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
3363 node.id = IWN_ID_BSS;
3364 node.htflags = htole32(htflags);
3365 DPRINTF(("adding BSS node\n"));
3367 if ((error = hal->add_node(sc, &node, async)) != 0) {
3368 aprint_error_dev(sc->sc_dev, "could not add %s node\n",
3369 (broadcast == 1)? "broadcast" : "BSS");
3370 return error;
3372 DPRINTF(("setting link quality for node %d\n", node.id));
3373 if ((error = iwn_set_link_quality(sc, ni)) != 0) {
3374 aprint_error_dev(sc->sc_dev,
3375 "could not setup MRR for %s node\n",
3376 (broadcast == 1)? "broadcast" : "BSS");
3377 return error;
3379 if ((error = iwn_init_sensitivity(sc)) != 0) {
3380 aprint_error_dev(sc->sc_dev, "could not set sensitivity\n");
3381 return error;
3384 return error;
3388 static int
3389 iwn4965_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
3391 struct iwn4965_node_info hnode;
3392 char *src, *dst;
3395 * We use the node structure for 5000 Series internally (it is
3396 * a superset of the one for 4965AGN). We thus copy the common
3397 * fields before sending the command.
3399 src = (char *)node;
3400 dst = (char *)&hnode;
3401 memcpy(dst, src, 48);
3402 /* Skip TSC, RX MIC and TX MIC fields from ``src''. */
3403 memcpy(dst + 48, src + 72, 20);
3404 return iwn_cmd(sc, IWN_CMD_ADD_NODE, &hnode, sizeof hnode, async);
3407 static int
3408 iwn5000_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
3410 /* Direct mapping. */
3411 return iwn_cmd(sc, IWN_CMD_ADD_NODE, node, sizeof (*node), async);
3414 static int
3415 iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni)
3417 struct iwn_node *wn = (void *)ni;
3418 struct ieee80211_rateset *rs = &ni->ni_rates;
3419 struct iwn_cmd_link_quality linkq;
3420 const struct iwn_rate *rinfo;
3421 uint8_t txant;
3422 int i, txrate;
3424 /* Use the first valid TX antenna. */
3425 txant = IWN_LSB(sc->txantmsk);
3427 memset(&linkq, 0, sizeof linkq);
3428 linkq.id = wn->id;
3429 linkq.antmsk_1stream = txant;
3430 linkq.antmsk_2stream = IWN_ANT_A | IWN_ANT_B;
3431 linkq.ampdu_max = 64;
3432 linkq.ampdu_threshold = 3;
3433 linkq.ampdu_limit = htole16(4000); /* 4ms */
3435 /* Start at highest available bit-rate. */
3436 txrate = rs->rs_nrates - 1;
3437 for (i = 0; i < IWN_MAX_TX_RETRIES; i++) {
3438 rinfo = &iwn_rates[wn->ridx[txrate]];
3439 linkq.retry[i].plcp = rinfo->plcp;
3440 linkq.retry[i].rflags = rinfo->flags;
3441 linkq.retry[i].rflags |= IWN_RFLAG_ANT(txant);
3442 /* Next retry at immediate lower bit-rate. */
3443 if (txrate > 0)
3444 txrate--;
3446 return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, 1);
3450 * Broadcast node is used to send group-addressed and management frames.
3452 static int
3453 iwn_add_broadcast_node(struct iwn_softc *sc, int async)
3455 const struct iwn_hal *hal = sc->sc_hal;
3456 struct iwn_node_info node;
3457 struct iwn_cmd_link_quality linkq;
3458 const struct iwn_rate *rinfo;
3459 uint8_t txant;
3460 int i, error;
3462 memset(&node, 0, sizeof node);
3463 IEEE80211_ADDR_COPY(node.macaddr, etherbroadcastaddr);
3464 node.id = hal->broadcast_id;
3465 DPRINTF(("adding broadcast node\n"));
3466 if ((error = hal->add_node(sc, &node, async)) != 0)
3467 return error;
3469 /* Use the first valid TX antenna. */
3470 txant = IWN_LSB(sc->txantmsk);
3472 memset(&linkq, 0, sizeof linkq);
3473 linkq.id = hal->broadcast_id;
3474 linkq.antmsk_1stream = txant;
3475 linkq.antmsk_2stream = IWN_ANT_A | IWN_ANT_B;
3476 linkq.ampdu_max = 64;
3477 linkq.ampdu_threshold = 3;
3478 linkq.ampdu_limit = htole16(4000); /* 4ms */
3480 /* Use lowest mandatory bit-rate. */
3481 rinfo = (sc->sc_ic.ic_curmode != IEEE80211_MODE_11A) ?
3482 &iwn_rates[IWN_RIDX_CCK1] : &iwn_rates[IWN_RIDX_OFDM6];
3483 linkq.retry[0].plcp = rinfo->plcp;
3484 linkq.retry[0].rflags = rinfo->flags;
3485 linkq.retry[0].rflags |= IWN_RFLAG_ANT(txant);
3486 /* Use same bit-rate for all TX retries. */
3487 for (i = 1; i < IWN_MAX_TX_RETRIES; i++) {
3488 linkq.retry[i].plcp = linkq.retry[0].plcp;
3489 linkq.retry[i].rflags = linkq.retry[0].rflags;
3491 return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async);
3494 #ifdef notyet
3495 static void
3496 iwn_updateedca(struct ieee80211com *ic)
3498 #define IWN_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */
3499 struct iwn_softc *sc = ic->ic_softc;
3500 struct iwn_edca_params cmd;
3501 int aci;
3503 memset(&cmd, 0, sizeof cmd);
3504 cmd.flags = htole32(IWN_EDCA_UPDATE);
3505 for (aci = 0; aci < EDCA_NUM_AC; aci++) {
3506 const struct ieee80211_edca_ac_params *ac =
3507 &ic->ic_edca_ac[aci];
3508 cmd.ac[aci].aifsn = ac->ac_aifsn;
3509 cmd.ac[aci].cwmin = htole16(IWN_EXP2(ac->ac_ecwmin));
3510 cmd.ac[aci].cwmax = htole16(IWN_EXP2(ac->ac_ecwmax));
3511 cmd.ac[aci].txoplimit =
3512 htole16(IEEE80211_TXOP_TO_US(ac->ac_txoplimit));
3514 (void)iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1);
3515 #undef IWN_EXP2
3517 #endif
3519 static void
3520 iwn_set_led(struct iwn_softc *sc, uint8_t which, uint8_t off, uint8_t on)
3522 struct iwn_cmd_led led;
3524 /* Clear microcode LED ownership. */
3525 IWN_CLRBITS(sc, IWN_LED, IWN_LED_BSM_CTRL);
3527 led.which = which;
3528 led.unit = htole32(10000); /* on/off in unit of 100ms */
3529 led.off = off;
3530 led.on = on;
3531 (void)iwn_cmd(sc, IWN_CMD_SET_LED, &led, sizeof led, 1);
3535 * Set the critical temperature at which the firmware will notify us.
3537 static int
3538 iwn_set_critical_temp(struct iwn_softc *sc)
3540 struct iwn_critical_temp crit;
3542 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_CTEMP_STOP_RF);
3544 memset(&crit, 0, sizeof crit);
3545 crit.tempR = htole32(sc->critical_temp);
3546 DPRINTF(("setting critical temperature to %u\n", sc->critical_temp));
3547 return iwn_cmd(sc, IWN_CMD_SET_CRITICAL_TEMP, &crit, sizeof crit, 0);
3550 static int
3551 iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni)
3553 struct iwn_cmd_timing cmd;
3554 uint64_t val, mod;
3556 memset(&cmd, 0, sizeof cmd);
3557 memcpy(&cmd.tstamp, ni->ni_tstamp.data, sizeof (uint64_t));
3558 cmd.bintval = htole16(ni->ni_intval);
3559 cmd.lintval = htole16(10);
3561 /* Compute remaining time until next beacon. */
3562 val = (uint64_t)ni->ni_intval * 1024; /* msecs -> usecs */
3563 mod = le64toh(cmd.tstamp) % val;
3564 cmd.binitval = htole32((uint32_t)(val - mod));
3566 DPRINTF(("timing bintval=%u, tstamp=%llu, init=%u\n",
3567 ni->ni_intval, (unsigned long long)le64toh(cmd.tstamp),
3568 (uint32_t)(val - mod)));
3570 return iwn_cmd(sc, IWN_CMD_TIMING, &cmd, sizeof cmd, 1);
3573 #if 0
3574 static void
3575 iwn4965_power_calibration(struct iwn_softc *sc, int temp)
3577 /* Adjust TX power if need be (delta >= 3 degC.) */
3578 DPRINTF(("temperature %d->%d\n", sc->temp, temp));
3579 if (abs(temp - sc->temp) >= 3) {
3580 /* Record temperature of last calibration. */
3581 sc->temp = temp;
3582 (void)iwn4965_set_txpower(sc, 1);
3585 #endif
3588 * Set TX power for current channel (each rate has its own power settings).
3589 * This function takes into account the regulatory information from EEPROM,
3590 * the current temperature and the current voltage.
3592 static int
3593 iwn4965_set_txpower(struct iwn_softc *sc, int async)
3595 /* Fixed-point arithmetic division using a n-bit fractional part. */
3596 #define fdivround(a, b, n) \
3597 ((((1 << n) * (a)) / (b) + (1 << n) / 2) / (1 << n))
3598 /* Linear interpolation. */
3599 #define interpolate(x, x1, y1, x2, y2, n) \
3600 ((y1) + fdivround(((int)(x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n))
3602 static const int tdiv[IWN_NATTEN_GROUPS] = { 9, 8, 8, 8, 6 };
3603 struct ieee80211com *ic = &sc->sc_ic;
3604 struct iwn_ucode_info *uc = &sc->ucode_info;
3605 struct ieee80211_channel *ch;
3606 struct iwn4965_cmd_txpower cmd;
3607 struct iwn4965_eeprom_chan_samples *chans;
3608 const uint8_t *rf_gain, *dsp_gain;
3609 int32_t vdiff, tdiff;
3610 int i, c, grp, maxpwr;
3611 uint8_t chan;
3613 /* Retrieve current channel from last RXON. */
3614 chan = sc->rxon.chan;
3615 DPRINTF(("setting TX power for channel %d\n", chan));
3616 ch = &ic->ic_channels[chan];
3618 memset(&cmd, 0, sizeof cmd);
3619 cmd.band = IEEE80211_IS_CHAN_5GHZ(ch) ? 0 : 1;
3620 cmd.chan = chan;
3622 if (IEEE80211_IS_CHAN_5GHZ(ch)) {
3623 maxpwr = sc->maxpwr5GHz;
3624 rf_gain = iwn4965_rf_gain_5ghz;
3625 dsp_gain = iwn4965_dsp_gain_5ghz;
3626 } else {
3627 maxpwr = sc->maxpwr2GHz;
3628 rf_gain = iwn4965_rf_gain_2ghz;
3629 dsp_gain = iwn4965_dsp_gain_2ghz;
3632 /* Compute voltage compensation. */
3633 vdiff = ((int32_t)le32toh(uc->volt) - sc->eeprom_voltage) / 7;
3634 if (vdiff > 0)
3635 vdiff *= 2;
3636 if (abs(vdiff) > 2)
3637 vdiff = 0;
3638 DPRINTF(("voltage compensation=%d (UCODE=%d, EEPROM=%d)\n",
3639 vdiff, le32toh(uc->volt), sc->eeprom_voltage));
3641 /* Get channel's attenuation group. */
3642 if (chan <= 20) /* 1-20 */
3643 grp = 4;
3644 else if (chan <= 43) /* 34-43 */
3645 grp = 0;
3646 else if (chan <= 70) /* 44-70 */
3647 grp = 1;
3648 else if (chan <= 124) /* 71-124 */
3649 grp = 2;
3650 else /* 125-200 */
3651 grp = 3;
3652 DPRINTF(("chan %d, attenuation group=%d\n", chan, grp));
3654 /* Get channel's sub-band. */
3655 for (i = 0; i < IWN_NBANDS; i++)
3656 if (sc->bands[i].lo != 0 &&
3657 sc->bands[i].lo <= chan && chan <= sc->bands[i].hi)
3658 break;
3659 chans = sc->bands[i].chans;
3660 DPRINTF(("chan %d sub-band=%d\n", chan, i));
3662 for (c = 0; c < 2; c++) {
3663 uint8_t power, gain, temp;
3664 int maxchpwr, pwr, ridx, idx;
3666 power = interpolate(chan,
3667 chans[0].num, chans[0].samples[c][1].power,
3668 chans[1].num, chans[1].samples[c][1].power, 1);
3669 gain = interpolate(chan,
3670 chans[0].num, chans[0].samples[c][1].gain,
3671 chans[1].num, chans[1].samples[c][1].gain, 1);
3672 temp = interpolate(chan,
3673 chans[0].num, chans[0].samples[c][1].temp,
3674 chans[1].num, chans[1].samples[c][1].temp, 1);
3675 DPRINTF(("TX chain %d: power=%d gain=%d temp=%d\n",
3676 c, power, gain, temp));
3678 /* Compute temperature compensation. */
3679 tdiff = ((sc->temp - temp) * 2) / tdiv[grp];
3680 DPRINTF(("temperature compensation=%d (current=%d, "
3681 "EEPROM=%d)\n", tdiff, sc->temp, temp));
3683 for (ridx = 0; ridx <= IWN_RIDX_MAX; ridx++) {
3684 maxchpwr = sc->maxpwr[chan] * 2;
3685 if ((ridx / 8) & 1)
3686 maxchpwr -= 6; /* MIMO 2T: -3dB */
3688 pwr = maxpwr;
3690 /* Adjust TX power based on rate. */
3691 if ((ridx % 8) == 5)
3692 pwr -= 15; /* OFDM48: -7.5dB */
3693 else if ((ridx % 8) == 6)
3694 pwr -= 17; /* OFDM54: -8.5dB */
3695 else if ((ridx % 8) == 7)
3696 pwr -= 20; /* OFDM60: -10dB */
3697 else
3698 pwr -= 10; /* Others: -5dB */
3700 /* Do not exceed channel's max TX power. */
3701 if (pwr > maxchpwr)
3702 pwr = maxchpwr;
3704 idx = gain - (pwr - power) - tdiff - vdiff;
3705 if ((ridx / 8) & 1) /* MIMO */
3706 idx += (int32_t)le32toh(uc->atten[grp][c]);
3708 if (cmd.band == 0)
3709 idx += 9; /* 5GHz */
3710 if (ridx == IWN_RIDX_MAX)
3711 idx += 5; /* CCK */
3713 /* Make sure idx stays in a valid range. */
3714 if (idx < 0)
3715 idx = 0;
3716 else if (idx > IWN4965_MAX_PWR_INDEX)
3717 idx = IWN4965_MAX_PWR_INDEX;
3719 DPRINTF(("TX chain %d, rate idx %d: power=%d\n",
3720 c, ridx, idx));
3721 cmd.power[ridx].rf_gain[c] = rf_gain[idx];
3722 cmd.power[ridx].dsp_gain[c] = dsp_gain[idx];
3726 DPRINTF(("setting TX power for chan %d\n", chan));
3727 return iwn_cmd(sc, IWN_CMD_TXPOWER, &cmd, sizeof cmd, async);
3729 #undef interpolate
3730 #undef fdivround
3733 static int
3734 iwn5000_set_txpower(struct iwn_softc *sc, int async)
3736 struct iwn5000_cmd_txpower cmd;
3739 * TX power calibration is handled automatically by the firmware
3740 * for 5000 Series.
3742 memset(&cmd, 0, sizeof cmd);
3743 cmd.global_limit = 2 * IWN5000_TXPOWER_MAX_DBM; /* 16 dBm */
3744 cmd.flags = IWN5000_TXPOWER_NO_CLOSED;
3745 cmd.srv_limit = IWN5000_TXPOWER_AUTO;
3746 DPRINTF(("setting TX power\n"));
3747 return iwn_cmd(sc, IWN_CMD_TXPOWER_DBM, &cmd, sizeof cmd, async);
3751 * Retrieve the maximum RSSI (in dBm) among receivers.
3753 static int
3754 iwn4965_get_rssi(const struct iwn_rx_stat *stat)
3756 const struct iwn4965_rx_phystat *phy = (const void *)stat->phybuf;
3757 uint8_t mask, agc;
3758 int rssi;
3760 mask = (le16toh(phy->antenna) >> 4) & 0x7;
3761 agc = (le16toh(phy->agc) >> 7) & 0x7f;
3763 rssi = 0;
3764 if (mask & IWN_ANT_A)
3765 rssi = MAX(rssi, phy->rssi[0]);
3766 if (mask & IWN_ANT_B)
3767 rssi = MAX(rssi, phy->rssi[2]);
3768 if (mask & IWN_ANT_C)
3769 rssi = MAX(rssi, phy->rssi[4]);
3771 return rssi - agc - IWN_RSSI_TO_DBM;
3774 static int
3775 iwn5000_get_rssi(const struct iwn_rx_stat *stat)
3777 const struct iwn5000_rx_phystat *phy = (const void *)stat->phybuf;
3778 uint8_t agc;
3779 int rssi;
3781 agc = (le32toh(phy->agc) >> 9) & 0x7f;
3783 rssi = MAX(le16toh(phy->rssi[0]) & 0xff,
3784 le16toh(phy->rssi[1]) & 0xff);
3785 rssi = MAX(le16toh(phy->rssi[2]) & 0xff, rssi);
3787 return rssi - agc - IWN_RSSI_TO_DBM;
3791 * Retrieve the average noise (in dBm) among receivers.
3793 static int
3794 iwn_get_noise(const struct iwn_rx_general_stats *stats)
3796 int i, total, nbant, noise;
3798 total = nbant = 0;
3799 for (i = 0; i < 3; i++) {
3800 if ((noise = le32toh(stats->noise[i]) & 0xff) == 0)
3801 continue;
3802 total += noise;
3803 nbant++;
3805 /* There should be at least one antenna but check anyway. */
3806 return (nbant == 0) ? -127 : (total / nbant) - 107;
3810 * Compute temperature (in degC) from last received statistics.
3812 static int
3813 iwn4965_get_temperature(struct iwn_softc *sc)
3815 struct iwn_ucode_info *uc = &sc->ucode_info;
3816 int32_t r1, r2, r3, r4, temp;
3818 r1 = le32toh(uc->temp[0].chan20MHz);
3819 r2 = le32toh(uc->temp[1].chan20MHz);
3820 r3 = le32toh(uc->temp[2].chan20MHz);
3821 r4 = le32toh(sc->rawtemp);
3823 if (r1 == r3) /* Prevents division by 0 (should not happen.) */
3824 return 0;
3826 /* Sign-extend 23-bit R4 value to 32-bit. */
3827 r4 = (r4 << 8) >> 8;
3828 /* Compute temperature in Kelvin. */
3829 temp = (259 * (r4 - r2)) / (r3 - r1);
3830 temp = (temp * 97) / 100 + 8;
3832 DPRINTF(("temperature %dK/%dC\n", temp, IWN_KTOC(temp)));
3833 return IWN_KTOC(temp);
3836 static int
3837 iwn5000_get_temperature(struct iwn_softc *sc)
3840 * Temperature is not used by the driver for 5000 Series because
3841 * TX power calibration is handled by firmware. We export it to
3842 * users through the sensor framework though.
3844 return le32toh(sc->rawtemp);
3848 * Initialize sensitivity calibration state machine.
3850 static int
3851 iwn_init_sensitivity(struct iwn_softc *sc)
3853 const struct iwn_hal *hal = sc->sc_hal;
3854 struct iwn_calib_state *calib = &sc->calib;
3855 uint32_t flags;
3856 int error;
3858 /* Reset calibration state machine. */
3859 memset(calib, 0, sizeof (*calib));
3860 calib->state = IWN_CALIB_STATE_INIT;
3861 calib->cck_state = IWN_CCK_STATE_HIFA;
3862 /* Set initial correlation values. */
3863 calib->ofdm_x1 = hal->limits->min_ofdm_x1;
3864 calib->ofdm_mrc_x1 = hal->limits->min_ofdm_mrc_x1;
3865 calib->ofdm_x4 = 90;
3866 calib->ofdm_mrc_x4 = hal->limits->min_ofdm_mrc_x4;
3867 calib->cck_x4 = 125;
3868 calib->cck_mrc_x4 = hal->limits->min_cck_mrc_x4;
3869 calib->energy_cck = hal->limits->energy_cck;
3871 /* Write initial sensitivity. */
3872 if ((error = iwn_send_sensitivity(sc)) != 0)
3873 return error;
3875 /* Write initial gains. */
3876 if ((error = hal->init_gains(sc)) != 0)
3877 return error;
3879 /* Request statistics at each beacon interval. */
3880 flags = 0;
3881 DPRINTF(("sending request for statistics\n"));
3882 return iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags, sizeof flags, 1);
3886 * Collect noise and RSSI statistics for the first 20 beacons received
3887 * after association and use them to determine connected antennas and
3888 * to set differential gains.
3890 static void
3891 iwn_collect_noise(struct iwn_softc *sc,
3892 const struct iwn_rx_general_stats *stats)
3894 const struct iwn_hal *hal = sc->sc_hal;
3895 struct iwn_calib_state *calib = &sc->calib;
3896 uint32_t val;
3897 int i;
3899 /* Accumulate RSSI and noise for all 3 antennas. */
3900 for (i = 0; i < 3; i++) {
3901 calib->rssi[i] += le32toh(stats->rssi[i]) & 0xff;
3902 calib->noise[i] += le32toh(stats->noise[i]) & 0xff;
3904 /* NB: We update differential gains only once after 20 beacons. */
3905 if (++calib->nbeacons < 20)
3906 return;
3908 /* Determine highest average RSSI. */
3909 val = MAX(calib->rssi[0], calib->rssi[1]);
3910 val = MAX(calib->rssi[2], val);
3912 /* Determine which antennas are connected. */
3913 sc->antmsk = 0;
3914 for (i = 0; i < 3; i++)
3915 if (val - calib->rssi[i] <= 15 * 20)
3916 sc->antmsk |= 1 << i;
3917 /* If none of the TX antennas are connected, keep at least one. */
3918 if ((sc->antmsk & sc->txantmsk) == 0)
3919 sc->antmsk |= IWN_LSB(sc->txantmsk);
3921 (void)hal->set_gains(sc);
3922 calib->state = IWN_CALIB_STATE_RUN;
3924 #ifdef notyet
3925 /* XXX Disable RX chains with no antennas connected. */
3926 sc->rxon.rxchain = htole16(IWN_RXCHAIN_SEL(sc->antmsk));
3927 (void)iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->rxon, hal->rxonsz, 1);
3929 /* Enable power-saving mode if requested by user. */
3930 if (sc->sc_ic.ic_flags & IEEE80211_F_PMGTON)
3931 (void)iwn_set_pslevel(sc, 0, 3, 1);
3932 #endif
3935 static int
3936 iwn4965_init_gains(struct iwn_softc *sc)
3938 struct iwn_phy_calib_gain cmd;
3940 memset(&cmd, 0, sizeof cmd);
3941 cmd.code = IWN4965_PHY_CALIB_DIFF_GAIN;
3942 /* Differential gains initially set to 0 for all 3 antennas. */
3943 DPRINTF(("setting initial differential gains\n"));
3944 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
3947 static int
3948 iwn5000_init_gains(struct iwn_softc *sc)
3950 struct iwn_phy_calib cmd;
3952 if (sc->hw_type == IWN_HW_REV_TYPE_6000 ||
3953 sc->hw_type == IWN_HW_REV_TYPE_6050)
3954 return 0;
3956 memset(&cmd, 0, sizeof cmd);
3957 cmd.code = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
3958 cmd.ngroups = 1;
3959 cmd.isvalid = 1;
3960 DPRINTF(("setting initial differential gains\n"));
3961 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
3964 static int
3965 iwn4965_set_gains(struct iwn_softc *sc)
3967 struct iwn_calib_state *calib = &sc->calib;
3968 struct iwn_phy_calib_gain cmd;
3969 int i, delta, noise;
3971 /* Get minimal noise among connected antennas. */
3972 noise = INT_MAX; /* NB: There's at least one antenna. */
3973 for (i = 0; i < 3; i++)
3974 if (sc->antmsk & (1 << i))
3975 noise = MIN(calib->noise[i], noise);
3977 memset(&cmd, 0, sizeof cmd);
3978 cmd.code = IWN4965_PHY_CALIB_DIFF_GAIN;
3979 /* Set differential gains for connected antennas. */
3980 for (i = 0; i < 3; i++) {
3981 if (sc->antmsk & (1 << i)) {
3982 /* Compute attenuation (in unit of 1.5dB). */
3983 delta = (noise - (int32_t)calib->noise[i]) / 30;
3984 /* NB: delta <= 0 */
3985 /* Limit to [-4.5dB,0]. */
3986 cmd.gain[i] = MIN(abs(delta), 3);
3987 if (delta < 0)
3988 cmd.gain[i] |= 1 << 2; /* sign bit */
3991 DPRINTF(("setting differential gains Ant A/B/C: %x/%x/%x (%x)\n",
3992 cmd.gain[0], cmd.gain[1], cmd.gain[2], sc->antmsk));
3993 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
3996 static int
3997 iwn5000_set_gains(struct iwn_softc *sc)
3999 struct iwn_calib_state *calib = &sc->calib;
4000 struct iwn_phy_calib_gain cmd;
4001 int i, delta;
4003 if (sc->hw_type == IWN_HW_REV_TYPE_6000 ||
4004 sc->hw_type == IWN_HW_REV_TYPE_6050)
4005 return 0;
4007 memset(&cmd, 0, sizeof cmd);
4008 cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN;
4009 cmd.ngroups = 1;
4010 cmd.isvalid = 1;
4011 /* Set differential gains for antennas B and C. */
4012 for (i = 1; i < 3; i++) {
4013 if (sc->antmsk & (1 << i)) {
4014 /* The delta is relative to antenna A. */
4015 delta = ((int32_t)calib->noise[0] -
4016 (int32_t)calib->noise[i]) / 30;
4017 /* Limit to [-4.5dB,+4.5dB]. */
4018 cmd.gain[i - 1] = MIN(abs(delta), 3);
4019 if (delta < 0)
4020 cmd.gain[i - 1] |= 1 << 2; /* sign bit */
4023 DPRINTF(("setting differential gains Ant B/C: %x/%x (%x)\n",
4024 cmd.gain[0], cmd.gain[1], sc->antmsk));
4025 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
4029 * Tune RF RX sensitivity based on the number of false alarms detected
4030 * during the last beacon period.
4032 static void
4033 iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
4035 #define inc(val, inc, max) \
4036 if ((val) < (max)) { \
4037 if ((val) < (max) - (inc)) \
4038 (val) += (inc); \
4039 else \
4040 (val) = (max); \
4041 needs_update = 1; \
4043 #define dec(val, dec, min) \
4044 if ((val) > (min)) { \
4045 if ((val) > (min) + (dec)) \
4046 (val) -= (dec); \
4047 else \
4048 (val) = (min); \
4049 needs_update = 1; \
4052 const struct iwn_hal *hal = sc->sc_hal;
4053 const struct iwn_sensitivity_limits *limits = hal->limits;
4054 struct iwn_calib_state *calib = &sc->calib;
4055 uint32_t val, rxena, fa;
4056 uint32_t energy[3], energy_min;
4057 uint8_t noise[3], noise_ref;
4058 int i, needs_update = 0;
4060 /* Check that we've been enabled long enough. */
4061 if ((rxena = le32toh(stats->general.load)) == 0)
4062 return;
4064 /* Compute number of false alarms since last call for OFDM. */
4065 fa = le32toh(stats->ofdm.bad_plcp) - calib->bad_plcp_ofdm;
4066 fa += le32toh(stats->ofdm.fa) - calib->fa_ofdm;
4067 fa *= 200 * 1024; /* 200TU */
4069 /* Save counters values for next call. */
4070 calib->bad_plcp_ofdm = le32toh(stats->ofdm.bad_plcp);
4071 calib->fa_ofdm = le32toh(stats->ofdm.fa);
4073 if (fa > 50 * rxena) {
4074 /* High false alarm count, decrease sensitivity. */
4075 DPRINTFN(2, ("OFDM high false alarm count: %u\n", fa));
4076 inc(calib->ofdm_x1, 1, limits->max_ofdm_x1);
4077 inc(calib->ofdm_mrc_x1, 1, limits->max_ofdm_mrc_x1);
4078 inc(calib->ofdm_x4, 1, limits->max_ofdm_x4);
4079 inc(calib->ofdm_mrc_x4, 1, limits->max_ofdm_mrc_x4);
4081 } else if (fa < 5 * rxena) {
4082 /* Low false alarm count, increase sensitivity. */
4083 DPRINTFN(2, ("OFDM low false alarm count: %u\n", fa));
4084 dec(calib->ofdm_x1, 1, limits->min_ofdm_x1);
4085 dec(calib->ofdm_mrc_x1, 1, limits->min_ofdm_mrc_x1);
4086 dec(calib->ofdm_x4, 1, limits->min_ofdm_x4);
4087 dec(calib->ofdm_mrc_x4, 1, limits->min_ofdm_mrc_x4);
4090 /* Compute maximum noise among 3 receivers. */
4091 for (i = 0; i < 3; i++)
4092 noise[i] = (le32toh(stats->general.noise[i]) >> 8) & 0xff;
4093 val = MAX(noise[0], noise[1]);
4094 val = MAX(noise[2], val);
4095 /* Insert it into our samples table. */
4096 calib->noise_samples[calib->cur_noise_sample] = val;
4097 calib->cur_noise_sample = (calib->cur_noise_sample + 1) % 20;
4099 /* Compute maximum noise among last 20 samples. */
4100 noise_ref = calib->noise_samples[0];
4101 for (i = 1; i < 20; i++)
4102 noise_ref = MAX(noise_ref, calib->noise_samples[i]);
4104 /* Compute maximum energy among 3 receivers. */
4105 for (i = 0; i < 3; i++)
4106 energy[i] = le32toh(stats->general.energy[i]);
4107 val = MIN(energy[0], energy[1]);
4108 val = MIN(energy[2], val);
4109 /* Insert it into our samples table. */
4110 calib->energy_samples[calib->cur_energy_sample] = val;
4111 calib->cur_energy_sample = (calib->cur_energy_sample + 1) % 10;
4113 /* Compute minimum energy among last 10 samples. */
4114 energy_min = calib->energy_samples[0];
4115 for (i = 1; i < 10; i++)
4116 energy_min = MAX(energy_min, calib->energy_samples[i]);
4117 energy_min += 6;
4119 /* Compute number of false alarms since last call for CCK. */
4120 fa = le32toh(stats->cck.bad_plcp) - calib->bad_plcp_cck;
4121 fa += le32toh(stats->cck.fa) - calib->fa_cck;
4122 fa *= 200 * 1024; /* 200TU */
4124 /* Save counters values for next call. */
4125 calib->bad_plcp_cck = le32toh(stats->cck.bad_plcp);
4126 calib->fa_cck = le32toh(stats->cck.fa);
4128 if (fa > 50 * rxena) {
4129 /* High false alarm count, decrease sensitivity. */
4130 DPRINTFN(2, ("CCK high false alarm count: %u\n", fa));
4131 calib->cck_state = IWN_CCK_STATE_HIFA;
4132 calib->low_fa = 0;
4134 if (calib->cck_x4 > 160) {
4135 calib->noise_ref = noise_ref;
4136 if (calib->energy_cck > 2)
4137 dec(calib->energy_cck, 2, energy_min);
4139 if (calib->cck_x4 < 160) {
4140 calib->cck_x4 = 161;
4141 needs_update = 1;
4142 } else
4143 inc(calib->cck_x4, 3, limits->max_cck_x4);
4145 inc(calib->cck_mrc_x4, 3, limits->max_cck_mrc_x4);
4147 } else if (fa < 5 * rxena) {
4148 /* Low false alarm count, increase sensitivity. */
4149 DPRINTFN(2, ("CCK low false alarm count: %u\n", fa));
4150 calib->cck_state = IWN_CCK_STATE_LOFA;
4151 calib->low_fa++;
4153 if (calib->cck_state != IWN_CCK_STATE_INIT &&
4154 (((int32_t)calib->noise_ref - (int32_t)noise_ref) > 2 ||
4155 calib->low_fa > 100)) {
4156 inc(calib->energy_cck, 2, limits->min_energy_cck);
4157 dec(calib->cck_x4, 3, limits->min_cck_x4);
4158 dec(calib->cck_mrc_x4, 3, limits->min_cck_mrc_x4);
4160 } else {
4161 /* Not worth to increase or decrease sensitivity. */
4162 DPRINTFN(2, ("CCK normal false alarm count: %u\n", fa));
4163 calib->low_fa = 0;
4164 calib->noise_ref = noise_ref;
4166 if (calib->cck_state == IWN_CCK_STATE_HIFA) {
4167 /* Previous interval had many false alarms. */
4168 dec(calib->energy_cck, 8, energy_min);
4170 calib->cck_state = IWN_CCK_STATE_INIT;
4173 if (needs_update)
4174 (void)iwn_send_sensitivity(sc);
4175 #undef dec
4176 #undef inc
4179 static int
4180 iwn_send_sensitivity(struct iwn_softc *sc)
4182 const struct iwn_hal *hal = sc->sc_hal;
4183 struct iwn_calib_state *calib = &sc->calib;
4184 struct iwn_sensitivity_cmd cmd;
4186 memset(&cmd, 0, sizeof cmd);
4187 cmd.which = IWN_SENSITIVITY_WORKTBL;
4188 /* OFDM modulation. */
4189 cmd.corr_ofdm_x1 = htole16(calib->ofdm_x1);
4190 cmd.corr_ofdm_mrc_x1 = htole16(calib->ofdm_mrc_x1);
4191 cmd.corr_ofdm_x4 = htole16(calib->ofdm_x4);
4192 cmd.corr_ofdm_mrc_x4 = htole16(calib->ofdm_mrc_x4);
4193 cmd.energy_ofdm = htole16(hal->limits->energy_ofdm);
4194 cmd.energy_ofdm_th = htole16(62);
4195 /* CCK modulation. */
4196 cmd.corr_cck_x4 = htole16(calib->cck_x4);
4197 cmd.corr_cck_mrc_x4 = htole16(calib->cck_mrc_x4);
4198 cmd.energy_cck = htole16(calib->energy_cck);
4199 /* Barker modulation: use default values. */
4200 cmd.corr_barker = htole16(190);
4201 cmd.corr_barker_mrc = htole16(390);
4203 DPRINTFN(2, ("setting sensitivity %d/%d/%d/%d/%d/%d/%d\n",
4204 calib->ofdm_x1, calib->ofdm_mrc_x1, calib->ofdm_x4,
4205 calib->ofdm_mrc_x4, calib->cck_x4, calib->cck_mrc_x4,
4206 calib->energy_cck));
4207 return iwn_cmd(sc, IWN_CMD_SET_SENSITIVITY, &cmd, sizeof cmd, 1);
4210 #if 0
4212 * Set STA mode power saving level (between 0 and 5).
4213 * Level 0 is CAM (Continuously Aware Mode), 5 is for maximum power saving.
4215 static int
4216 iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async)
4218 struct iwn_pmgt_cmd cmd;
4219 const struct iwn_pmgt *pmgt;
4220 uint32_t umax, skip_dtim;
4221 pcireg_t reg;
4222 int i;
4224 /* Select which PS parameters to use. */
4225 if (dtim <= 2)
4226 pmgt = &iwn_pmgt[0][level];
4227 else if (dtim <= 10)
4228 pmgt = &iwn_pmgt[1][level];
4229 else
4230 pmgt = &iwn_pmgt[2][level];
4232 memset(&cmd, 0, sizeof cmd);
4233 if (level != 0) /* not CAM */
4234 cmd.flags |= htole16(IWN_PS_ALLOW_SLEEP);
4235 if (level == 5)
4236 cmd.flags |= htole16(IWN_PS_FAST_PD);
4237 /* Retrieve PCIe Active State Power Management (ASPM). */
4238 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
4239 sc->sc_cap_off + PCI_PCIE_LCSR);
4240 if (!(reg & PCI_PCIE_LCSR_ASPM_L0S)) /* L0s Entry disabled. */
4241 cmd.flags |= htole16(IWN_PS_PCI_PMGT);
4242 cmd.rxtimeout = htole32(pmgt->rxtimeout * 1024);
4243 cmd.txtimeout = htole32(pmgt->txtimeout * 1024);
4245 if (dtim == 0) {
4246 dtim = 1;
4247 skip_dtim = 0;
4248 } else
4249 skip_dtim = pmgt->skip_dtim;
4250 if (skip_dtim != 0) {
4251 cmd.flags |= htole16(IWN_PS_SLEEP_OVER_DTIM);
4252 umax = pmgt->intval[4];
4253 if (umax == (uint32_t)-1)
4254 umax = dtim * (skip_dtim + 1);
4255 else if (umax > dtim)
4256 umax = (umax / dtim) * dtim;
4257 } else
4258 umax = dtim;
4259 for (i = 0; i < 5; i++)
4260 cmd.intval[i] = htole32(MIN(umax, pmgt->intval[i]));
4262 DPRINTF(("setting power saving level to %d\n", level));
4263 return iwn_cmd(sc, IWN_CMD_SET_POWER_MODE, &cmd, sizeof cmd, async);
4265 #endif
4267 static int
4268 iwn_config(struct iwn_softc *sc)
4270 const struct iwn_hal *hal = sc->sc_hal;
4271 struct ieee80211com *ic = &sc->sc_ic;
4272 struct ifnet *ifp = ic->ic_ifp;
4273 struct iwn_bluetooth bluetooth;
4274 uint16_t rxchain;
4275 int error;
4276 struct iwn_pmgt_cmd power;
4279 #if 0
4280 /* Set power saving level to CAM during initialization. */
4281 if ((error = iwn_set_pslevel(sc, 0, 0, 0)) != 0) {
4282 aprint_error_dev(sc->sc_dev,
4283 "could not set power saving level\n");
4284 return error;
4286 #else
4287 /* set power mode */
4288 memset(&power, 0, sizeof power);
4289 power.flags = htole16(/*IWN_POWER_CAM*/0 | 0x8);
4290 DPRINTF(("setting power mode\n"));
4291 error = iwn_cmd(sc, IWN_CMD_SET_POWER_MODE, &power, sizeof power, 0);
4292 if (error != 0) {
4293 aprint_error_dev(sc->sc_dev, "could not set power mode\n");
4294 return error;
4296 #endif
4298 /* Configure bluetooth coexistence. */
4299 memset(&bluetooth, 0, sizeof bluetooth);
4300 bluetooth.flags = 3;
4301 bluetooth.lead = 0xaa;
4302 bluetooth.kill = 1;
4303 DPRINTF(("configuring bluetooth coexistence\n"));
4304 error = iwn_cmd(sc, IWN_CMD_BT_COEX, &bluetooth, sizeof bluetooth, 0);
4305 if (error != 0) {
4306 aprint_error_dev(sc->sc_dev,
4307 "could not configure bluetooth coexistence\n");
4308 return error;
4311 /* Configure adapter. */
4312 memset(&sc->rxon, 0, sizeof (struct iwn_rxon));
4313 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
4314 IEEE80211_ADDR_COPY(sc->rxon.myaddr, ic->ic_myaddr);
4315 IEEE80211_ADDR_COPY(sc->rxon.wlap, ic->ic_myaddr);
4316 /* Set default channel. */
4317 sc->rxon.chan = htole16(ieee80211_chan2ieee(ic, ic->ic_ibss_chan));
4318 sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
4319 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_ibss_chan))
4320 sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
4321 switch (ic->ic_opmode) {
4322 case IEEE80211_M_STA:
4323 sc->rxon.mode = IWN_MODE_STA;
4324 sc->rxon.filter = htole32(IWN_FILTER_MULTICAST);
4325 break;
4326 case IEEE80211_M_MONITOR:
4327 sc->rxon.mode = IWN_MODE_MONITOR;
4328 sc->rxon.filter = htole32(IWN_FILTER_MULTICAST |
4329 IWN_FILTER_CTL | IWN_FILTER_PROMISC);
4330 break;
4331 default:
4332 /* Should not get there. */
4333 break;
4335 sc->rxon.cck_mask = 0x0f; /* not yet negotiated */
4336 sc->rxon.ofdm_mask = 0xff; /* not yet negotiated */
4337 sc->rxon.ht_single_mask = 0xff;
4338 sc->rxon.ht_dual_mask = 0xff;
4339 rxchain = IWN_RXCHAIN_VALID(IWN_ANT_ABC) | IWN_RXCHAIN_IDLE_COUNT(2) |
4340 IWN_RXCHAIN_MIMO_COUNT(2);
4341 sc->rxon.rxchain = htole16(rxchain);
4342 DPRINTF(("setting configuration\n"));
4343 #ifdef notdef
4344 if (ic->ic_flags & IEEE80211_F_SHSLOT)
4345 sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
4346 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
4347 sc->rxon.flags |= htole32(IWN_RXON_SHPREAMBLE);
4348 sc->rxon.filter &= ~htole32(IWN_FILTER_BSS);
4349 #endif
4350 DPRINTF(("rxon chan %d flags %x cck %x ofdm %x\n", sc->rxon.chan,
4351 sc->rxon.flags, sc->rxon.cck_mask, sc->rxon.ofdm_mask));
4352 error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->rxon, hal->rxonsz, 0);
4353 if (error != 0) {
4354 aprint_error_dev(sc->sc_dev, "configure command failed\n");
4355 return error;
4358 /* Configuration has changed, set TX power accordingly. */
4359 if ((error = hal->set_txpower(sc, 0)) != 0) {
4360 aprint_error_dev(sc->sc_dev, "could not set TX power\n");
4361 return error;
4364 if ((error = iwn_add_broadcast_node(sc, 0)) != 0) {
4365 aprint_error_dev(sc->sc_dev, "could not add broadcast node\n");
4366 return error;
4369 if ((error = iwn_set_critical_temp(sc)) != 0) {
4370 aprint_error_dev(sc->sc_dev,
4371 "could not set critical temperature\n");
4372 return error;
4374 return 0;
4377 static int
4378 iwn_scan(struct iwn_softc *sc, uint16_t flags)
4380 struct ieee80211com *ic = &sc->sc_ic;
4381 struct iwn_scan_hdr *hdr;
4382 struct iwn_cmd_data *tx;
4383 struct iwn_scan_chan *chan;
4384 struct ieee80211_frame *wh;
4385 struct ieee80211_rateset *rs;
4386 struct ieee80211_channel *c;
4387 enum ieee80211_phymode mode;
4388 uint8_t *buf, *frm;
4389 uint16_t rxchain;
4390 uint8_t txant;
4391 int buflen, error, nrates;
4393 buf = malloc(IWN_SCAN_MAXSZ, M_DEVBUF, M_NOWAIT | M_ZERO);
4394 if (buf == NULL) {
4395 aprint_error_dev(sc->sc_dev,
4396 "could not allocate buffer for scan command\n");
4397 return ENOMEM;
4399 hdr = (struct iwn_scan_hdr *)buf;
4401 * Move to the next channel if no frames are received within 10ms
4402 * after sending the probe request.
4404 hdr->quiet_time = htole16(10); /* timeout in milliseconds */
4405 hdr->quiet_threshold = htole16(1); /* min # of packets */
4407 /* Select antennas for scanning. */
4408 rxchain = IWN_RXCHAIN_FORCE | IWN_RXCHAIN_VALID(IWN_ANT_ABC) |
4409 IWN_RXCHAIN_MIMO(IWN_ANT_ABC);
4410 if ((flags & IEEE80211_CHAN_5GHZ) &&
4411 sc->hw_type == IWN_HW_REV_TYPE_4965) {
4412 /* Ant A must be avoided in 5GHz because of an HW bug. */
4413 rxchain |= IWN_RXCHAIN_SEL(IWN_ANT_B | IWN_ANT_C);
4414 } else /* Use all available RX antennas. */
4415 rxchain |= IWN_RXCHAIN_SEL(IWN_ANT_ABC);
4416 hdr->rxchain = htole16(rxchain);
4417 hdr->filter = htole32(IWN_FILTER_MULTICAST | IWN_FILTER_BEACON);
4419 tx = &(hdr->tx_cmd);
4420 tx->flags = htole32(IWN_TX_AUTO_SEQ);
4421 tx->id = sc->sc_hal->broadcast_id;
4422 tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
4424 if (flags & IEEE80211_CHAN_5GHZ) {
4425 hdr->crc_threshold = htole16(1);
4426 /* Send probe requests at 6Mbps. */
4427 tx->plcp = iwn_rates[IWN_RIDX_OFDM6].plcp;
4428 rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
4429 } else {
4430 hdr->flags = htole32(IWN_RXON_24GHZ | IWN_RXON_AUTO);
4431 /* Send probe requests at 1Mbps. */
4432 tx->plcp = iwn_rates[IWN_RIDX_CCK1].plcp;
4433 tx->rflags = IWN_RFLAG_CCK;
4434 rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
4436 /* Use the first valid TX antenna. */
4437 txant = IWN_LSB(sc->txantmsk);
4438 tx->rflags |= IWN_RFLAG_ANT(txant);
4440 if (ic->ic_des_esslen != 0) {
4441 hdr->scan_essid[0].id = IEEE80211_ELEMID_SSID;
4442 hdr->scan_essid[0].len = ic->ic_des_esslen;
4443 memcpy(hdr->scan_essid[0].data, ic->ic_des_essid, ic->ic_des_esslen);
4446 * Build a probe request frame. Most of the following code is a
4447 * copy & paste of what is done in net80211.
4449 wh = &(hdr->wh);
4450 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
4451 IEEE80211_FC0_SUBTYPE_PROBE_REQ;
4452 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
4453 IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr);
4454 IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
4455 IEEE80211_ADDR_COPY(wh->i_addr3, etherbroadcastaddr);
4456 *(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */
4457 *(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */
4459 frm = &(hdr->data[0]);
4460 /* add empty SSID IE */
4461 *frm++ = IEEE80211_ELEMID_SSID;
4462 *frm++ = 0;
4464 mode = ieee80211_chan2mode(ic, ic->ic_ibss_chan);
4465 rs = &ic->ic_sup_rates[mode];
4467 /* add supported rates IE */
4468 *frm++ = IEEE80211_ELEMID_RATES;
4469 nrates = rs->rs_nrates;
4470 if (nrates > IEEE80211_RATE_SIZE)
4471 nrates = IEEE80211_RATE_SIZE;
4472 *frm++ = nrates;
4473 memcpy(frm, rs->rs_rates, nrates);
4474 frm += nrates;
4476 if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
4477 nrates = rs->rs_nrates - IEEE80211_RATE_SIZE;
4478 *frm++ = IEEE80211_ELEMID_XRATES;
4479 *frm++ = nrates;
4480 memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates);
4481 frm += nrates;
4484 /* Set length of probe request. */
4485 tx->len = htole16(frm - (uint8_t *)wh);
4487 chan = (struct iwn_scan_chan *)frm;
4488 for (c = &ic->ic_channels[1];
4489 c <= &ic->ic_channels[IEEE80211_CHAN_MAX]; c++) {
4490 if ((c->ic_flags & flags) != flags)
4491 continue;
4493 chan->chan = htole16(ieee80211_chan2ieee(ic, c));
4494 DPRINTFN(2, ("adding channel %d\n", chan->chan));
4495 chan->flags = 0;
4496 if (!(c->ic_flags & IEEE80211_CHAN_PASSIVE))
4497 chan->flags |= htole32(IWN_CHAN_ACTIVE);
4498 if (ic->ic_des_esslen != 0)
4499 chan->flags |= htole32(IWN_CHAN_NPBREQS(1));
4500 chan->dsp_gain = 0x6e;
4501 if (IEEE80211_IS_CHAN_5GHZ(c)) {
4502 chan->rf_gain = 0x3b;
4503 chan->active = htole16(24);
4504 chan->passive = htole16(110);
4505 } else {
4506 chan->rf_gain = 0x28;
4507 chan->active = htole16(36);
4508 chan->passive = htole16(120);
4510 hdr->nchan++;
4511 chan++;
4514 buflen = (uint8_t *)chan - buf;
4515 hdr->len = htole16(buflen);
4517 DPRINTF(("sending scan command nchan=%d\n", hdr->nchan));
4518 error = iwn_cmd(sc, IWN_CMD_SCAN, buf, buflen, 1);
4519 free(buf, M_DEVBUF);
4520 return error;
4523 static int
4524 iwn_auth(struct iwn_softc *sc)
4526 const struct iwn_hal *hal = sc->sc_hal;
4527 struct ieee80211com *ic = &sc->sc_ic;
4528 struct ieee80211_node *ni = ic->ic_bss;
4529 int error;
4531 sc->calib.state = IWN_CALIB_STATE_INIT;
4533 /* Update adapter's configuration. */
4534 sc->rxon.associd = 0;
4535 IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid);
4536 sc->rxon.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));
4537 sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
4538 if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
4539 sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
4540 if (ic->ic_flags & IEEE80211_F_SHSLOT)
4541 sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
4542 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
4543 sc->rxon.flags |= htole32(IWN_RXON_SHPREAMBLE);
4544 switch (ic->ic_curmode) {
4545 case IEEE80211_MODE_11A:
4546 sc->rxon.cck_mask = 0;
4547 sc->rxon.ofdm_mask = 0x15;
4548 break;
4549 case IEEE80211_MODE_11B:
4550 sc->rxon.cck_mask = 0x03;
4551 sc->rxon.ofdm_mask = 0;
4552 break;
4553 default: /* Assume 802.11b/g. */
4554 sc->rxon.cck_mask = 0x0f;
4555 sc->rxon.ofdm_mask = 0x15;
4556 break;
4558 #if 1
4559 DPRINTF(("rxon chan %d flags %x cck %x ofdm %x\n", sc->rxon.chan,
4560 sc->rxon.flags, sc->rxon.cck_mask, sc->rxon.ofdm_mask));
4561 error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->rxon, hal->rxonsz, 1);
4562 if (error != 0) {
4563 aprint_error_dev(sc->sc_dev, "could not configure\n");
4564 return error;
4567 /* Configuration has changed, set TX power accordingly. */
4568 if ((error = hal->set_txpower(sc, 1)) != 0) {
4569 aprint_error_dev(sc->sc_dev, "could not set TX power\n");
4570 return error;
4573 * Reconfiguring RXON clears the firmware's nodes table so we must
4574 * add the broadcast node again.
4576 if ((error = iwn_add_broadcast_node(sc, 1)) != 0) {
4577 aprint_error_dev(sc->sc_dev, "could not add broadcast node\n");
4578 return error;
4580 #else
4581 /* iwn_enable_tsf(sc, ni);*/
4582 if (ic->ic_flags & IEEE80211_F_SHSLOT)
4583 sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
4584 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
4585 sc->rxon.flags |= htole32(IWN_RXON_SHPREAMBLE);
4586 sc->rxon.filter &= ~htole32(IWN_FILTER_BSS);
4588 DPRINTF(("rxon chan %d flags %x cck %x ofdm %x\n", sc->rxon.chan,
4589 sc->rxon.flags, sc->rxon.cck_mask, sc->rxon.ofdm_mask));
4590 error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->rxon, hal->rxonsz, 1);
4591 if (error != 0) {
4592 aprint_error_dev(sc->sc_dev, "could not configure\n");
4593 return error;
4596 /* Configuration has changed, set TX power accordingly. */
4597 if ((error = hal->set_txpower(sc, 1)) != 0) {
4598 aprint_error_dev(sc->sc_dev, "could not set TX power\n");
4599 return error;
4602 * Reconfiguring RXON clears the firmware's nodes table so we must
4603 * add the broadcast node again.
4605 if ((error = iwn_add_broadcast_node(sc, 1)) != 0) {
4606 aprint_error_dev(sc->sc_dev, "could not add broadcast node\n");
4607 return error;
4609 /* add BSS node */
4610 DPRINTF(("adding BSS node from auth\n"));
4611 if ((error = iwn_add_node(sc, ni, false, true, 0)) != 0)
4612 return error;
4614 if (ic->ic_opmode == IEEE80211_M_STA) {
4615 /* fake a join to init the tx rate */
4616 iwn_newassoc(ni, 1);
4619 if ((error = iwn_init_sensitivity(sc)) != 0) {
4620 aprint_error_dev(sc->sc_dev, "could not set sensitivity\n");
4621 return error;
4623 #endif
4624 return 0;
4627 static int
4628 iwn_run(struct iwn_softc *sc)
4630 const struct iwn_hal *hal = sc->sc_hal;
4631 struct ieee80211com *ic = &sc->sc_ic;
4632 struct ieee80211_node *ni = ic->ic_bss;
4633 int error;
4635 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
4636 /* Link LED blinks while monitoring. */
4637 iwn_set_led(sc, IWN_LED_LINK, 5, 5);
4638 return 0;
4640 if ((error = iwn_set_timing(sc, ni)) != 0) {
4641 aprint_error_dev(sc->sc_dev, "could not set timing\n");
4642 return error;
4645 /* Update adapter's configuration. */
4646 sc->rxon.associd = htole16(IEEE80211_AID(ni->ni_associd));
4647 /* Short preamble and slot time are negotiated when associating. */
4648 sc->rxon.flags &= ~htole32(IWN_RXON_SHPREAMBLE | IWN_RXON_SHSLOT);
4649 if (ic->ic_flags & IEEE80211_F_SHSLOT)
4650 sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
4651 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
4652 sc->rxon.flags |= htole32(IWN_RXON_SHPREAMBLE);
4653 sc->rxon.filter |= htole32(IWN_FILTER_BSS);
4654 DPRINTF(("rxon chan %d flags %x\n", sc->rxon.chan, sc->rxon.flags));
4655 error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->rxon, hal->rxonsz, 1);
4656 if (error != 0) {
4657 aprint_error_dev(sc->sc_dev,
4658 "could not update configuration\n");
4659 return error;
4662 /* Configuration has changed, set TX power accordingly. */
4663 if ((error = hal->set_txpower(sc, 1)) != 0) {
4664 aprint_error_dev(sc->sc_dev, "could not set TX power\n");
4665 return error;
4668 /* Fake a join to initialize the TX rate. */
4669 ((struct iwn_node *)ni)->id = IWN_ID_BSS;
4670 iwn_newassoc(ni, 1);
4672 /* Add BSS node. */
4673 iwn_add_node(sc, ni, false, true, 0);
4674 /* Start periodic calibration timer. */
4675 sc->calib.state = IWN_CALIB_STATE_ASSOC;
4676 sc->calib_cnt = 0;
4677 callout_schedule(&sc->calib_to, hz / 2);
4679 /* Link LED always on while associated. */
4680 iwn_set_led(sc, IWN_LED_LINK, 0, 1);
4681 return 0;
4684 static int
4685 iwn_wme_update(struct ieee80211com *ic)
4687 #define IWN_EXP2(v) htole16((1 << (v)) - 1)
4688 #define IWN_USEC(v) htole16(IEEE80211_TXOP_TO_US(v))
4689 struct iwn_softc *sc = ic->ic_ifp->if_softc;
4690 const struct wmeParams *wmep;
4691 struct iwn_edca_params cmd;
4692 int ac;
4694 /* don't override default WME values if WME is not actually enabled */
4695 if (!(ic->ic_flags & IEEE80211_F_WME))
4696 return 0;
4697 cmd.flags = 0;
4698 for (ac = 0; ac < WME_NUM_AC; ac++) {
4699 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
4700 cmd.ac[ac].aifsn = wmep->wmep_aifsn;
4701 cmd.ac[ac].cwmin = IWN_EXP2(wmep->wmep_logcwmin);
4702 cmd.ac[ac].cwmax = IWN_EXP2(wmep->wmep_logcwmax);
4703 cmd.ac[ac].txoplimit = IWN_USEC(wmep->wmep_txopLimit);
4705 DPRINTF(("setting WME for queue %d aifsn=%d cwmin=%d cwmax=%d "
4706 "txop=%d\n", ac, cmd.ac[ac].aifsn,
4707 cmd.ac[ac].cwmin,
4708 cmd.ac[ac].cwmax, cmd.ac[ac].txoplimit));
4710 return iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1);
4711 #undef IWN_USEC
4712 #undef IWN_EXP2
4715 #if 0
4717 * We support CCMP hardware encryption/decryption of unicast frames only.
4718 * HW support for TKIP really sucks. We should let TKIP die anyway.
4720 static int
4721 iwn_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
4722 struct ieee80211_key *k)
4724 struct iwn_softc *sc = ic->ic_softc;
4725 const struct iwn_hal *hal = sc->sc_hal;
4726 struct iwn_node *wn = (void *)ni;
4727 struct iwn_node_info node;
4728 uint16_t kflags;
4730 if ((k->k_flags & IEEE80211_KEY_GROUP) ||
4731 k->k_cipher != IEEE80211_CIPHER_CCMP)
4732 return ieee80211_set_key(ic, ni, k);
4734 kflags = IWN_KFLAG_CCMP | IWN_KFLAG_MAP | IWN_KFLAG_KID(k->k_id);
4735 if (k->k_flags & IEEE80211_KEY_GROUP)
4736 kflags |= IWN_KFLAG_GROUP;
4738 memset(&node, 0, sizeof node);
4739 node.id = (k->k_flags & IEEE80211_KEY_GROUP) ?
4740 hal->broadcast_id : wn->id;
4741 node.control = IWN_NODE_UPDATE;
4742 node.flags = IWN_FLAG_SET_KEY;
4743 node.kflags = htole16(kflags);
4744 node.kid = k->k_id;
4745 memcpy(node.key, k->k_key, k->k_len);
4746 DPRINTF(("set key id=%d for node %d\n", k->k_id, node.id));
4747 return hal->add_node(sc, &node, 1);
4750 static void
4751 iwn_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
4752 struct ieee80211_key *k)
4754 struct iwn_softc *sc = ic->ic_softc;
4755 const struct iwn_hal *hal = sc->sc_hal;
4756 struct iwn_node *wn = (void *)ni;
4757 struct iwn_node_info node;
4759 if ((k->k_flags & IEEE80211_KEY_GROUP) ||
4760 k->k_cipher != IEEE80211_CIPHER_CCMP) {
4761 /* See comment about other ciphers above. */
4762 ieee80211_delete_key(ic, ni, k);
4763 return;
4765 if (ic->ic_state != IEEE80211_S_RUN)
4766 return; /* Nothing to do. */
4767 memset(&node, 0, sizeof node);
4768 node.id = (k->k_flags & IEEE80211_KEY_GROUP) ?
4769 hal->broadcast_id : wn->id;
4770 node.control = IWN_NODE_UPDATE;
4771 node.flags = IWN_FLAG_SET_KEY;
4772 node.kflags = htole16(IWN_KFLAG_INVALID);
4773 node.kid = 0xff;
4774 DPRINTF(("delete keys for node %d\n", node.id));
4775 (void)hal->add_node(sc, &node, 1);
4777 #endif
4779 #ifndef IEEE80211_NO_HT
4781 * This function is called by upper layer when a ADDBA request is received
4782 * from another STA and before the ADDBA response is sent.
4784 static int
4785 iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
4786 uint8_t tid, uint16_t ssn)
4788 struct iwn_softc *sc = ic->ic_softc;
4789 struct iwn_node *wn = (void *)ni;
4790 struct iwn_node_info node;
4792 memset(&node, 0, sizeof node);
4793 node.id = wn->id;
4794 node.control = IWN_NODE_UPDATE;
4795 node.flags = IWN_FLAG_SET_ADDBA;
4796 node.addba_tid = tid;
4797 node.addba_ssn = htole16(ssn);
4798 DPRINTFN(2, ("ADDBA RA=%d TID=%d SSN=%d\n", wn->id, tid, ssn));
4799 return sc->sc_hal->add_node(sc, &node, 1);
4803 * This function is called by upper layer on teardown of an HT-immediate
4804 * Block Ack (eg. uppon receipt of a DELBA frame.)
4806 static void
4807 iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
4808 uint8_t tid, uint16_t ssn)
4810 struct iwn_softc *sc = ic->ic_softc;
4811 struct iwn_node *wn = (void *)ni;
4812 struct iwn_node_info node;
4814 memset(&node, 0, sizeof node);
4815 node.id = wn->id;
4816 node.control = IWN_NODE_UPDATE;
4817 node.flags = IWN_FLAG_SET_DELBA;
4818 node.delba_tid = tid;
4819 DPRINTFN(2, ("DELBA RA=%d TID=%d\n", wn->id, tid));
4820 (void)sc->sc_hal->add_node(sc, &node, 1);
4824 * This function is called by upper layer when a ADDBA response is received
4825 * from another STA.
4827 static int
4828 iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
4829 uint8_t tid, uint16_t ssn)
4831 struct iwn_softc *sc = ic->ic_softc;
4832 const struct iwn_hal *hal = sc->sc_hal;
4833 struct iwn_node *wn = (void *)ni;
4834 struct iwn_node_info node;
4835 int error;
4837 /* Enable TX for the specified RA/TID. */
4838 wn->disable_tid &= ~(1 << tid);
4839 memset(&node, 0, sizeof node);
4840 node.id = wn->id;
4841 node.control = IWN_NODE_UPDATE;
4842 node.flags = IWN_FLAG_SET_DISABLE_TID;
4843 node.disable_tid = htole16(wn->disable_tid);
4844 error = hal->add_node(sc, &node, 1);
4845 if (error != 0)
4846 return error;
4848 if ((error = iwn_nic_lock(sc)) != 0)
4849 return error;
4850 hal->ampdu_tx_start(sc, ni, tid, ssn);
4851 iwn_nic_unlock(sc);
4852 return 0;
4855 static void
4856 iwn_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
4857 uint8_t tid, uint16_t ssn)
4859 struct iwn_softc *sc = ic->ic_softc;
4861 if (iwn_nic_lock(sc) != 0)
4862 return;
4863 sc->sc_hal->ampdu_tx_stop(sc, tid, ssn);
4864 iwn_nic_unlock(sc);
4867 static void
4868 iwn4965_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
4869 uint8_t tid, uint16_t ssn)
4871 struct iwn_node *wn = (void *)ni;
4872 int qid = 7 + tid;
4874 /* Stop TX scheduler while we're changing its configuration. */
4875 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
4876 IWN4965_TXQ_STATUS_CHGACT);
4878 /* Assign RA/TID translation to the queue. */
4879 iwn_mem_write_2(sc, sc->sched_base + IWN4965_SCHED_TRANS_TBL(qid),
4880 wn->id << 4 | tid);
4882 /* Enable chain mode for the queue. */
4883 iwn_prph_setbits(sc, IWN4965_SCHED_QCHAIN_SEL, 1 << qid);
4885 /* Set starting sequence number from the ADDBA request. */
4886 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ssn);
4887 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), ssn);
4889 /* Set scheduler window size. */
4890 iwn_mem_write(sc, sc->sched_base + IWN4965_SCHED_QUEUE_OFFSET(qid),
4891 IWN_SCHED_WINSZ);
4892 /* Set scheduler frame limit. */
4893 iwn_mem_write(sc, sc->sched_base + IWN4965_SCHED_QUEUE_OFFSET(qid) + 4,
4894 IWN_SCHED_LIMIT << 16);
4896 /* Enable interrupts for the queue. */
4897 iwn_prph_setbits(sc, IWN4965_SCHED_INTR_MASK, 1 << qid);
4899 /* Mark the queue as active. */
4900 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
4901 IWN4965_TXQ_STATUS_ACTIVE | IWN4965_TXQ_STATUS_AGGR_ENA |
4902 iwn_tid2fifo[tid] << 1);
4905 static void
4906 iwn4965_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
4908 int qid = 7 + tid;
4910 /* Stop TX scheduler while we're changing its configuration. */
4911 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
4912 IWN4965_TXQ_STATUS_CHGACT);
4914 /* Set starting sequence number from the ADDBA request. */
4915 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ssn);
4916 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), ssn);
4918 /* Disable interrupts for the queue. */
4919 iwn_prph_clrbits(sc, IWN4965_SCHED_INTR_MASK, 1 << qid);
4921 /* Mark the queue as inactive. */
4922 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
4923 IWN4965_TXQ_STATUS_INACTIVE | iwn_tid2fifo[tid] << 1);
4926 static void
4927 iwn5000_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
4928 uint8_t tid, uint16_t ssn)
4930 struct iwn_node *wn = (void *)ni;
4931 int qid = 10 + tid;
4933 /* Stop TX scheduler while we're changing its configuration. */
4934 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
4935 IWN5000_TXQ_STATUS_CHGACT);
4937 /* Assign RA/TID translation to the queue. */
4938 iwn_mem_write_2(sc, sc->sched_base + IWN5000_SCHED_TRANS_TBL(qid),
4939 wn->id << 4 | tid);
4941 /* Enable chain mode for the queue. */
4942 iwn_prph_setbits(sc, IWN5000_SCHED_QCHAIN_SEL, 1 << qid);
4944 /* Enable aggregation for the queue. */
4945 iwn_prph_setbits(sc, IWN5000_SCHED_AGGR_SEL, 1 << qid);
4947 /* Set starting sequence number from the ADDBA request. */
4948 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ssn);
4949 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), ssn);
4951 /* Set scheduler window size and frame limit. */
4952 iwn_mem_write(sc, sc->sched_base + IWN5000_SCHED_QUEUE_OFFSET(qid) + 4,
4953 IWN_SCHED_LIMIT << 16 | IWN_SCHED_WINSZ);
4955 /* Enable interrupts for the queue. */
4956 iwn_prph_setbits(sc, IWN5000_SCHED_INTR_MASK, 1 << qid);
4958 /* Mark the queue as active. */
4959 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
4960 IWN5000_TXQ_STATUS_ACTIVE | iwn_tid2fifo[tid]);
4963 static void
4964 iwn5000_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
4966 int qid = 10 + tid;
4968 /* Stop TX scheduler while we're changing its configuration. */
4969 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
4970 IWN5000_TXQ_STATUS_CHGACT);
4972 /* Disable aggregation for the queue. */
4973 iwn_prph_clrbits(sc, IWN5000_SCHED_AGGR_SEL, 1 << qid);
4975 /* Set starting sequence number from the ADDBA request. */
4976 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ssn);
4977 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), ssn);
4979 /* Disable interrupts for the queue. */
4980 iwn_prph_clrbits(sc, IWN5000_SCHED_INTR_MASK, 1 << qid);
4982 /* Mark the queue as inactive. */
4983 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
4984 IWN5000_TXQ_STATUS_INACTIVE | iwn_tid2fifo[tid]);
4986 #endif /* 0 */
4989 * Query calibration tables from the initialization firmware. We do this
4990 * only once at first boot. Called from a process context.
4992 static int
4993 iwn5000_query_calibration(struct iwn_softc *sc)
4995 struct iwn5000_calib_config cmd;
4996 int error;
4998 memset(&cmd, 0, sizeof cmd);
4999 cmd.ucode.once.enable = 0xffffffff;
5000 cmd.ucode.once.start = 0xffffffff;
5001 cmd.ucode.once.send = 0xffffffff;
5002 cmd.ucode.flags = 0xffffffff;
5003 DPRINTF(("sending calibration query\n"));
5004 error = iwn_cmd(sc, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof cmd, 0);
5005 if (error != 0)
5006 return error;
5008 /* Wait at most two seconds for calibration to complete. */
5009 return tsleep(sc, PCATCH, "iwncal", 2 * hz);
5013 * Send calibration results to the runtime firmware. These results were
5014 * obtained on first boot from the initialization firmware.
5016 static int
5017 iwn5000_send_calibration(struct iwn_softc *sc)
5019 int idx, error;
5021 for (idx = 0; idx < 5; idx++) {
5022 if (sc->calibcmd[idx].buf == NULL)
5023 continue; /* No results available. */
5024 DPRINTF(("send calibration result idx=%d len=%d\n",
5025 idx, sc->calibcmd[idx].len));
5026 error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, sc->calibcmd[idx].buf,
5027 sc->calibcmd[idx].len, 0);
5028 if (error != 0) {
5029 aprint_error_dev(sc->sc_dev,
5030 "could not send calibration result\n");
5031 return error;
5034 return 0;
5038 * This function is called after the runtime firmware notifies us of its
5039 * readiness (called in a process context.)
5041 static int
5042 iwn4965_post_alive(struct iwn_softc *sc)
5044 int error, qid;
5046 if ((error = iwn_nic_lock(sc)) != 0)
5047 return error;
5049 /* Clear TX scheduler's state in SRAM. */
5050 sc->sched_base = iwn_prph_read(sc, IWN_SCHED_SRAM_ADDR);
5051 iwn_mem_set_region_4(sc, sc->sched_base + IWN4965_SCHED_CTX_OFF, 0,
5052 IWN4965_SCHED_CTX_LEN);
5054 /* Set physical address of TX scheduler rings (1KB aligned.) */
5055 iwn_prph_write(sc, IWN4965_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
5057 IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
5059 /* Disable chain mode for all our 16 queues. */
5060 iwn_prph_write(sc, IWN4965_SCHED_QCHAIN_SEL, 0);
5062 for (qid = 0; qid < IWN4965_NTXQUEUES; qid++) {
5063 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), 0);
5064 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | 0);
5066 /* Set scheduler window size. */
5067 iwn_mem_write(sc, sc->sched_base +
5068 IWN4965_SCHED_QUEUE_OFFSET(qid), IWN_SCHED_WINSZ);
5069 /* Set scheduler frame limit. */
5070 iwn_mem_write(sc, sc->sched_base +
5071 IWN4965_SCHED_QUEUE_OFFSET(qid) + 4,
5072 IWN_SCHED_LIMIT << 16);
5075 /* Enable interrupts for all our 16 queues. */
5076 iwn_prph_write(sc, IWN4965_SCHED_INTR_MASK, 0xffff);
5077 /* Identify TX FIFO rings (0-7). */
5078 iwn_prph_write(sc, IWN4965_SCHED_TXFACT, 0xff);
5080 /* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */
5081 for (qid = 0; qid < 7; qid++) {
5082 static uint8_t qid2fifo[] = { 3, 2, 1, 0, 4, 5, 6 };
5083 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
5084 IWN4965_TXQ_STATUS_ACTIVE | qid2fifo[qid] << 1);
5086 iwn_nic_unlock(sc);
5087 return 0;
5091 * This function is called after the initialization or runtime firmware
5092 * notifies us of its readiness (called in a process context.)
5094 static int
5095 iwn5000_post_alive(struct iwn_softc *sc)
5097 struct iwn5000_wimax_coex wimax;
5098 int error, qid;
5100 if ((error = iwn_nic_lock(sc)) != 0)
5101 return error;
5103 /* Clear TX scheduler's state in SRAM. */
5104 sc->sched_base = iwn_prph_read(sc, IWN_SCHED_SRAM_ADDR);
5105 iwn_mem_set_region_4(sc, sc->sched_base + IWN5000_SCHED_CTX_OFF, 0,
5106 IWN5000_SCHED_CTX_LEN);
5108 /* Set physical address of TX scheduler rings (1KB aligned.) */
5109 iwn_prph_write(sc, IWN5000_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
5111 IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
5113 /* Enable chain mode for all our 20 queues. */
5114 iwn_prph_write(sc, IWN5000_SCHED_QCHAIN_SEL, 0xfffff);
5115 iwn_prph_write(sc, IWN5000_SCHED_AGGR_SEL, 0);
5117 for (qid = 0; qid < IWN5000_NTXQUEUES; qid++) {
5118 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), 0);
5119 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | 0);
5121 iwn_mem_write(sc, sc->sched_base +
5122 IWN5000_SCHED_QUEUE_OFFSET(qid), 0);
5123 /* Set scheduler window size and frame limit. */
5124 iwn_mem_write(sc, sc->sched_base +
5125 IWN5000_SCHED_QUEUE_OFFSET(qid) + 4,
5126 IWN_SCHED_LIMIT << 16 | IWN_SCHED_WINSZ);
5129 /* Enable interrupts for all our 20 queues. */
5130 iwn_prph_write(sc, IWN5000_SCHED_INTR_MASK, 0xfffff);
5131 /* Identify TX FIFO rings (0-7). */
5132 iwn_prph_write(sc, IWN5000_SCHED_TXFACT, 0xff);
5134 /* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */
5135 for (qid = 0; qid < 7; qid++) {
5136 static uint8_t qid2fifo[] = { 3, 2, 1, 0, 7, 5, 6 };
5137 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
5138 IWN5000_TXQ_STATUS_ACTIVE | qid2fifo[qid]);
5140 iwn_nic_unlock(sc);
5142 /* Configure WiMAX (IEEE 802.16e) coexistence. */
5143 memset(&wimax, 0, sizeof wimax);
5144 DPRINTF(("Configuring WiMAX coexistence\n"));
5145 error = iwn_cmd(sc, IWN5000_CMD_WIMAX_COEX, &wimax, sizeof wimax, 0);
5146 if (error != 0) {
5147 aprint_error_dev(sc->sc_dev,
5148 "could not configure WiMAX coexistence\n");
5149 return error;
5152 if (sc->hw_type != IWN_HW_REV_TYPE_5150) {
5153 struct iwn5000_phy_calib_crystal cmd;
5155 /* Perform crystal calibration. */
5156 memset(&cmd, 0, sizeof cmd);
5157 cmd.code = IWN5000_PHY_CALIB_CRYSTAL;
5158 cmd.ngroups = 1;
5159 cmd.isvalid = 1;
5160 cmd.cap_pin[0] = le32toh(sc->eeprom_crystal) & 0xff;
5161 cmd.cap_pin[1] = (le32toh(sc->eeprom_crystal) >> 16) & 0xff;
5162 DPRINTF(("sending crystal calibration %d, %d\n",
5163 cmd.cap_pin[0], cmd.cap_pin[1]));
5164 error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
5165 if (error != 0) {
5166 aprint_error_dev(sc->sc_dev,
5167 "crystal calibration failed\n");
5168 return error;
5171 if (sc->sc_flags & IWN_FLAG_FIRST_BOOT) {
5172 /* Query calibration from the initialization firmware. */
5173 if ((error = iwn5000_query_calibration(sc)) != 0) {
5174 aprint_error_dev(sc->sc_dev,
5175 "could not query calibration\n");
5176 return error;
5179 * We have the calibration results now so we can skip
5180 * loading the initialization firmware next time.
5182 sc->sc_flags &= ~IWN_FLAG_FIRST_BOOT;
5184 /* Reboot (call ourselves recursively!) */
5185 iwn_hw_stop(sc);
5186 error = iwn_hw_init(sc);
5187 } else {
5188 /* Send calibration results to runtime firmware. */
5189 error = iwn5000_send_calibration(sc);
5191 return error;
5195 * The firmware boot code is small and is intended to be copied directly into
5196 * the NIC internal memory (no DMA transfer.)
5198 static int
5199 iwn4965_load_bootcode(struct iwn_softc *sc, const uint8_t *ucode, int size)
5201 int error, ntries;
5203 size /= sizeof (uint32_t);
5205 if ((error = iwn_nic_lock(sc)) != 0)
5206 return error;
5208 /* Copy microcode image into NIC memory. */
5209 iwn_prph_write_region_4(sc, IWN_BSM_SRAM_BASE,
5210 (const uint32_t *)ucode, size);
5212 iwn_prph_write(sc, IWN_BSM_WR_MEM_SRC, 0);
5213 iwn_prph_write(sc, IWN_BSM_WR_MEM_DST, IWN_FW_TEXT_BASE);
5214 iwn_prph_write(sc, IWN_BSM_WR_DWCOUNT, size);
5216 /* Start boot load now. */
5217 iwn_prph_write(sc, IWN_BSM_WR_CTRL, IWN_BSM_WR_CTRL_START);
5219 /* Wait for transfer to complete. */
5220 for (ntries = 0; ntries < 1000; ntries++) {
5221 if (!(iwn_prph_read(sc, IWN_BSM_WR_CTRL) &
5222 IWN_BSM_WR_CTRL_START))
5223 break;
5224 DELAY(10);
5226 if (ntries == 1000) {
5227 aprint_error_dev(sc->sc_dev, "could not load boot firmware\n");
5228 iwn_nic_unlock(sc);
5229 return ETIMEDOUT;
5232 /* Enable boot after power up. */
5233 iwn_prph_write(sc, IWN_BSM_WR_CTRL, IWN_BSM_WR_CTRL_START_EN);
5235 iwn_nic_unlock(sc);
5236 return 0;
5239 static int
5240 iwn4965_load_firmware(struct iwn_softc *sc)
5242 struct iwn_fw_info *fw = &sc->fw;
5243 struct iwn_dma_info *dma = &sc->fw_dma;
5244 int error;
5246 /* Copy initialization sections into pre-allocated DMA-safe memory. */
5247 memcpy(dma->vaddr, fw->init.data, fw->init.datasz);
5248 bus_dmamap_sync(sc->sc_dmat, dma->map, 0, fw->init.datasz,
5249 BUS_DMASYNC_PREWRITE);
5250 memcpy((char *)dma->vaddr + IWN4965_FW_DATA_MAXSZ,
5251 fw->init.text, fw->init.textsz);
5252 bus_dmamap_sync(sc->sc_dmat, dma->map, IWN4965_FW_DATA_MAXSZ,
5253 fw->init.textsz, BUS_DMASYNC_PREWRITE);
5255 /* Tell adapter where to find initialization sections. */
5256 if ((error = iwn_nic_lock(sc)) != 0)
5257 return error;
5258 iwn_prph_write(sc, IWN_BSM_DRAM_DATA_ADDR, dma->paddr >> 4);
5259 iwn_prph_write(sc, IWN_BSM_DRAM_DATA_SIZE, fw->init.datasz);
5260 iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_ADDR,
5261 (dma->paddr + IWN4965_FW_DATA_MAXSZ) >> 4);
5262 iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_SIZE, fw->init.textsz);
5263 iwn_nic_unlock(sc);
5265 /* Load firmware boot code. */
5266 error = iwn4965_load_bootcode(sc, fw->boot.text, fw->boot.textsz);
5267 if (error != 0) {
5268 aprint_error_dev(sc->sc_dev, "could not load boot firmware\n");
5269 return error;
5271 /* Now press "execute". */
5272 IWN_WRITE(sc, IWN_RESET, 0);
5274 /* Wait at most one second for first alive notification. */
5275 if ((error = tsleep(sc, PCATCH, "iwninit", hz)) != 0) {
5276 aprint_error_dev(sc->sc_dev,
5277 "timeout waiting for adapter to initialize %d\n", error);
5278 return error;
5281 /* Retrieve current temperature for initial TX power calibration. */
5282 sc->rawtemp = sc->ucode_info.temp[3].chan20MHz;
5283 sc->temp = iwn4965_get_temperature(sc);
5285 /* Copy runtime sections into pre-allocated DMA-safe memory. */
5286 memcpy(dma->vaddr, fw->main.data, fw->main.datasz);
5287 bus_dmamap_sync(sc->sc_dmat, dma->map, 0, fw->main.datasz,
5288 BUS_DMASYNC_PREWRITE);
5289 memcpy((char *)dma->vaddr + IWN4965_FW_DATA_MAXSZ,
5290 fw->main.text, fw->main.textsz);
5291 bus_dmamap_sync(sc->sc_dmat, dma->map, IWN4965_FW_DATA_MAXSZ,
5292 fw->main.textsz, BUS_DMASYNC_PREWRITE);
5294 /* Tell adapter where to find runtime sections. */
5295 if ((error = iwn_nic_lock(sc)) != 0)
5296 return error;
5297 iwn_prph_write(sc, IWN_BSM_DRAM_DATA_ADDR, dma->paddr >> 4);
5298 iwn_prph_write(sc, IWN_BSM_DRAM_DATA_SIZE, fw->main.datasz);
5299 iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_ADDR,
5300 (dma->paddr + IWN4965_FW_DATA_MAXSZ) >> 4);
5301 iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_SIZE,
5302 IWN_FW_UPDATED | fw->main.textsz);
5303 iwn_nic_unlock(sc);
5305 return 0;
5308 static int
5309 iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst,
5310 const uint8_t *section, int size)
5312 struct iwn_dma_info *dma = &sc->fw_dma;
5313 int error;
5315 /* Copy firmware section into pre-allocated DMA-safe memory. */
5316 memcpy(dma->vaddr, section, size);
5317 bus_dmamap_sync(sc->sc_dmat, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
5319 if ((error = iwn_nic_lock(sc)) != 0)
5320 return error;
5322 IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_CHNL),
5323 IWN_FH_TX_CONFIG_DMA_PAUSE);
5325 IWN_WRITE(sc, IWN_FH_SRAM_ADDR(IWN_SRVC_CHNL), dst);
5326 IWN_WRITE(sc, IWN_FH_TFBD_CTRL0(IWN_SRVC_CHNL),
5327 IWN_LOADDR(dma->paddr));
5328 IWN_WRITE(sc, IWN_FH_TFBD_CTRL1(IWN_SRVC_CHNL),
5329 IWN_HIADDR(dma->paddr) << 28 | size);
5330 IWN_WRITE(sc, IWN_FH_TXBUF_STATUS(IWN_SRVC_CHNL),
5331 IWN_FH_TXBUF_STATUS_TBNUM(1) |
5332 IWN_FH_TXBUF_STATUS_TBIDX(1) |
5333 IWN_FH_TXBUF_STATUS_TFBD_VALID);
5335 /* Kick Flow Handler to start DMA transfer. */
5336 IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_CHNL),
5337 IWN_FH_TX_CONFIG_DMA_ENA | IWN_FH_TX_CONFIG_CIRQ_HOST_ENDTFD);
5339 iwn_nic_unlock(sc);
5341 /* Wait at most five seconds for FH DMA transfer to complete. */
5342 return tsleep(sc, PCATCH, "iwninit", 5 * hz);
5345 static int
5346 iwn5000_load_firmware(struct iwn_softc *sc)
5348 struct iwn_fw_part *fw;
5349 int error;
5351 /* Load the initialization firmware on first boot only. */
5352 fw = (sc->sc_flags & IWN_FLAG_FIRST_BOOT) ?
5353 &sc->fw.init : &sc->fw.main;
5355 error = iwn5000_load_firmware_section(sc, IWN_FW_TEXT_BASE,
5356 fw->text, fw->textsz);
5357 if (error != 0) {
5358 aprint_error_dev(sc->sc_dev,
5359 "could not load firmware %s section\n",
5360 ".text");
5361 return error;
5363 error = iwn5000_load_firmware_section(sc, IWN_FW_DATA_BASE,
5364 fw->data, fw->datasz);
5365 if (error != 0) {
5366 aprint_error_dev(sc->sc_dev,
5367 "could not load firmware %s section\n",
5368 ".data");
5369 return error;
5372 /* Now press "execute". */
5373 IWN_WRITE(sc, IWN_RESET, 0);
5374 return 0;
5377 static int
5378 iwn_read_firmware(struct iwn_softc *sc)
5380 const struct iwn_hal *hal = sc->sc_hal;
5381 struct iwn_fw_info *fw = &sc->fw;
5382 struct iwn_firmware_hdr hdr;
5383 firmware_handle_t fwh;
5384 size_t size;
5385 int error;
5387 /* Read firmware image from filesystem. */
5388 if ((error = firmware_open("if_iwn", sc->fwname, &fwh)) != 0) {
5389 aprint_error_dev(sc->sc_dev,
5390 "could not read firmware file %s\n", sc->fwname);
5391 return error;
5393 size = firmware_get_size(fwh);
5394 if (size < sizeof (hdr)) {
5395 aprint_error_dev(sc->sc_dev,
5396 "truncated firmware header: %zu bytes\n", size);
5397 error = EINVAL;
5398 goto fail2;
5400 /* Extract firmware header information. */
5401 if ((error = firmware_read(fwh, 0, &hdr,
5402 sizeof (struct iwn_firmware_hdr))) != 0) {
5403 aprint_error_dev(sc->sc_dev, "can't get firmware header\n");
5404 goto fail2;
5406 fw->main.textsz = le32toh(hdr.main_textsz);
5407 fw->main.datasz = le32toh(hdr.main_datasz);
5408 fw->init.textsz = le32toh(hdr.init_textsz);
5409 fw->init.datasz = le32toh(hdr.init_datasz);
5410 fw->boot.textsz = le32toh(hdr.boot_textsz);
5411 fw->boot.datasz = 0;
5413 /* Sanity-check firmware header. */
5414 if (fw->main.textsz > hal->fw_text_maxsz ||
5415 fw->main.datasz > hal->fw_data_maxsz ||
5416 fw->init.textsz > hal->fw_text_maxsz ||
5417 fw->init.datasz > hal->fw_data_maxsz ||
5418 fw->boot.textsz > IWN_FW_BOOT_TEXT_MAXSZ ||
5419 (fw->boot.textsz & 3) != 0) {
5420 aprint_error_dev(sc->sc_dev, "invalid firmware header\n");
5421 error = EINVAL;
5422 goto fail2;
5425 /* Check that all firmware sections fit. */
5426 if (size < sizeof (hdr) + fw->main.textsz + fw->main.datasz +
5427 fw->init.textsz + fw->init.datasz + fw->boot.textsz) {
5428 aprint_error_dev(sc->sc_dev,
5429 "firmware file too short: %zu bytes\n", size);
5430 error = EINVAL;
5431 goto fail2;
5433 fw->data = firmware_malloc(size);
5434 if (fw->data == NULL) {
5435 aprint_error_dev(sc->sc_dev,
5436 "not enough memory to stock firmware\n");
5437 error = ENOMEM;
5438 goto fail2;
5440 if ((error = firmware_read(fwh, 0, fw->data, size)) != 0) {
5441 aprint_error_dev(sc->sc_dev, "can't get firmware\n");
5442 goto fail3;
5445 /* Get pointers to firmware sections. */
5446 fw->main.text = fw->data + sizeof (struct iwn_firmware_hdr);
5447 fw->main.data = fw->main.text + fw->main.textsz;
5448 fw->init.text = fw->main.data + fw->main.datasz;
5449 fw->init.data = fw->init.text + fw->init.textsz;
5450 fw->boot.text = fw->init.data + fw->init.datasz;
5452 return 0;
5453 fail3: firmware_free(fw->data, size);
5454 fail2: firmware_close(fwh);
5455 return error;
5458 static int
5459 iwn_clock_wait(struct iwn_softc *sc)
5461 int ntries;
5463 /* Set "initialization complete" bit. */
5464 IWN_SETBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
5466 /* Wait for clock stabilization. */
5467 for (ntries = 0; ntries < 25000; ntries++) {
5468 if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_MAC_CLOCK_READY)
5469 return 0;
5470 DELAY(100);
5472 aprint_error_dev(sc->sc_dev,
5473 "timeout waiting for clock stabilization\n");
5474 return ETIMEDOUT;
5477 static int
5478 iwn4965_apm_init(struct iwn_softc *sc)
5480 int error;
5482 /* Disable L0s. */
5483 IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_DIS_L0S_TIMER);
5484 IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_L1A_NO_L0S_RX);
5486 if ((error = iwn_clock_wait(sc)) != 0)
5487 return error;
5489 if ((error = iwn_nic_lock(sc)) != 0)
5490 return error;
5491 /* Enable DMA. */
5492 iwn_prph_write(sc, IWN_APMG_CLK_CTRL,
5493 IWN_APMG_CLK_CTRL_DMA_CLK_RQT | IWN_APMG_CLK_CTRL_BSM_CLK_RQT);
5494 DELAY(20);
5495 /* Disable L1. */
5496 iwn_prph_setbits(sc, IWN_APMG_PCI_STT, IWN_APMG_PCI_STT_L1A_DIS);
5497 iwn_nic_unlock(sc);
5499 return 0;
5502 static int
5503 iwn5000_apm_init(struct iwn_softc *sc)
5505 int error;
5507 /* Disable L0s. */
5508 IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_DIS_L0S_TIMER);
5509 IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_L1A_NO_L0S_RX);
5511 /* Set Flow Handler wait threshold to the maximum. */
5512 IWN_SETBITS(sc, IWN_DBG_HPET_MEM, 0xffff0000);
5514 /* Enable HAP to move adapter from L1a to L0s. */
5515 IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_HAP_WAKE_L1A);
5517 if (sc->hw_type != IWN_HW_REV_TYPE_6000 &&
5518 sc->hw_type != IWN_HW_REV_TYPE_6050)
5519 IWN_SETBITS(sc, IWN_ANA_PLL, IWN_ANA_PLL_INIT);
5521 if ((error = iwn_clock_wait(sc)) != 0)
5522 return error;
5524 if ((error = iwn_nic_lock(sc)) != 0)
5525 return error;
5526 /* Enable DMA. */
5527 iwn_prph_write(sc, IWN_APMG_CLK_CTRL, IWN_APMG_CLK_CTRL_DMA_CLK_RQT);
5528 DELAY(20);
5529 /* Disable L1. */
5530 iwn_prph_setbits(sc, IWN_APMG_PCI_STT, IWN_APMG_PCI_STT_L1A_DIS);
5531 iwn_nic_unlock(sc);
5533 return 0;
5536 static void
5537 iwn_apm_stop_master(struct iwn_softc *sc)
5539 int ntries;
5541 IWN_SETBITS(sc, IWN_RESET, IWN_RESET_STOP_MASTER);
5542 for (ntries = 0; ntries < 100; ntries++) {
5543 if (IWN_READ(sc, IWN_RESET) & IWN_RESET_MASTER_DISABLED)
5544 return;
5545 DELAY(10);
5547 aprint_error_dev(sc->sc_dev, "timeout waiting for master\n");
5550 static void
5551 iwn_apm_stop(struct iwn_softc *sc)
5553 iwn_apm_stop_master(sc);
5555 IWN_SETBITS(sc, IWN_RESET, IWN_RESET_SW);
5556 DELAY(10);
5557 /* Clear "initialization complete" bit. */
5558 IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
5561 static int
5562 iwn4965_nic_config(struct iwn_softc *sc)
5564 pcireg_t reg;
5566 /* Retrieve PCIe Active State Power Management (ASPM). */
5567 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
5568 sc->sc_cap_off + PCI_PCIE_LCSR);
5569 if (reg & PCI_PCIE_LCSR_ASPM_L1) /* L1 Entry enabled. */
5570 IWN_SETBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
5571 else
5572 IWN_CLRBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
5574 if (IWN_RFCFG_TYPE(sc->rfcfg) == 1) {
5576 * I don't believe this to be correct but this is what the
5577 * vendor driver is doing. Probably the bits should not be
5578 * shifted in IWN_RFCFG_*.
5580 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
5581 IWN_RFCFG_TYPE(sc->rfcfg) |
5582 IWN_RFCFG_STEP(sc->rfcfg) |
5583 IWN_RFCFG_DASH(sc->rfcfg));
5585 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
5586 IWN_HW_IF_CONFIG_RADIO_SI | IWN_HW_IF_CONFIG_MAC_SI);
5587 return 0;
5590 static int
5591 iwn5000_nic_config(struct iwn_softc *sc)
5593 int error;
5594 pcireg_t reg;
5596 /* Retrieve PCIe Active State Power Management (ASPM). */
5597 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
5598 sc->sc_cap_off + PCI_PCIE_LCSR);
5599 if (reg & PCI_PCIE_LCSR_ASPM_L1) /* L1 Entry enabled. */
5600 IWN_SETBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
5601 else
5602 IWN_CLRBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
5604 if (IWN_RFCFG_TYPE(sc->rfcfg) < 3) {
5605 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
5606 IWN_RFCFG_TYPE(sc->rfcfg) |
5607 IWN_RFCFG_STEP(sc->rfcfg) |
5608 IWN_RFCFG_DASH(sc->rfcfg));
5610 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
5611 IWN_HW_IF_CONFIG_RADIO_SI | IWN_HW_IF_CONFIG_MAC_SI);
5613 if ((error = iwn_nic_lock(sc)) != 0)
5614 return error;
5615 iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_EARLY_PWROFF_DIS);
5616 iwn_nic_unlock(sc);
5617 return 0;
5620 static int
5621 iwn_hw_init(struct iwn_softc *sc)
5623 const struct iwn_hal *hal = sc->sc_hal;
5624 int error, qid;
5626 /* Clear pending interrupts. */
5627 IWN_WRITE(sc, IWN_INT, 0xffffffff);
5629 if ((error = hal->apm_init(sc)) != 0) {
5630 aprint_error_dev(sc->sc_dev, "could not power ON adapter\n");
5631 return error;
5634 /* Select VMAIN power source. */
5635 if ((error = iwn_nic_lock(sc)) != 0)
5636 return error;
5637 iwn_prph_clrbits(sc, IWN_APMG_PS, IWN_APMG_PS_PWR_SRC_MASK);
5638 iwn_nic_unlock(sc);
5640 /* Perform adapter-specific initialization. */
5641 if ((error = hal->nic_config(sc)) != 0)
5642 return error;
5644 /* Initialize RX ring. */
5645 if ((error = iwn_nic_lock(sc)) != 0)
5646 return error;
5647 IWN_WRITE(sc, IWN_FH_RX_CONFIG, 0);
5648 IWN_WRITE(sc, IWN_FH_RX_WPTR, 0);
5649 /* Set physical address of RX ring (256-byte aligned.) */
5650 IWN_WRITE(sc, IWN_FH_RX_BASE, sc->rxq.desc_dma.paddr >> 8);
5651 /* Set physical address of RX status (16-byte aligned.) */
5652 IWN_WRITE(sc, IWN_FH_STATUS_WPTR, sc->rxq.stat_dma.paddr >> 4);
5653 /* Enable RX. */
5654 IWN_WRITE(sc, IWN_FH_RX_CONFIG,
5655 IWN_FH_RX_CONFIG_ENA |
5656 IWN_FH_RX_CONFIG_IGN_RXF_EMPTY | /* HW bug workaround */
5657 IWN_FH_RX_CONFIG_IRQ_DST_HOST |
5658 IWN_FH_RX_CONFIG_SINGLE_FRAME |
5659 IWN_FH_RX_CONFIG_RB_TIMEOUT(0) |
5660 IWN_FH_RX_CONFIG_NRBD(IWN_RX_RING_COUNT_LOG));
5661 iwn_nic_unlock(sc);
5662 IWN_WRITE(sc, IWN_FH_RX_WPTR, (IWN_RX_RING_COUNT - 1) & ~7);
5664 if ((error = iwn_nic_lock(sc)) != 0)
5665 return error;
5667 /* Initialize TX scheduler. */
5668 iwn_prph_write(sc, hal->sched_txfact_addr, 0);
5670 /* Set physical address of "keep warm" page (16-byte aligned.) */
5671 IWN_WRITE(sc, IWN_FH_KW_ADDR, sc->kw_dma.paddr >> 4);
5673 /* Initialize TX rings. */
5674 for (qid = 0; qid < hal->ntxqs; qid++) {
5675 struct iwn_tx_ring *txq = &sc->txq[qid];
5677 /* Set physical address of TX ring (256-byte aligned.) */
5678 IWN_WRITE(sc, IWN_FH_CBBC_QUEUE(qid),
5679 txq->desc_dma.paddr >> 8);
5680 /* Enable TX for this ring. */
5681 IWN_WRITE(sc, IWN_FH_TX_CONFIG(qid),
5682 IWN_FH_TX_CONFIG_DMA_ENA |
5683 IWN_FH_TX_CONFIG_DMA_CREDIT_ENA);
5685 iwn_nic_unlock(sc);
5687 /* Clear "radio off" and "commands blocked" bits. */
5688 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
5689 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_CMD_BLOCKED);
5691 /* Clear pending interrupts. */
5692 IWN_WRITE(sc, IWN_INT, 0xffffffff);
5693 /* Enable interrupt coalescing. */
5694 IWN_WRITE(sc, IWN_INT_COALESCING, 512 / 8);
5695 /* Enable interrupts. */
5696 IWN_WRITE(sc, IWN_MASK, IWN_INT_MASK);
5698 /* _Really_ make sure "radio off" bit is cleared! */
5699 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
5700 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
5702 if ((error = hal->load_firmware(sc)) != 0) {
5703 aprint_error_dev(sc->sc_dev, "could not load firmware\n");
5704 return error;
5706 /* Wait at most one second for firmware alive notification. */
5707 if ((error = tsleep(sc, PCATCH, "iwninit", hz)) != 0) {
5708 aprint_error_dev(sc->sc_dev,
5709 "timeout waiting for adapter to initialize %d\n" ,error);
5710 return error;
5712 /* Do post-firmware initialization. */
5713 return hal->post_alive(sc);
5716 static void
5717 iwn_hw_stop(struct iwn_softc *sc)
5719 const struct iwn_hal *hal = sc->sc_hal;
5720 int qid;
5722 IWN_WRITE(sc, IWN_RESET, IWN_RESET_NEVO);
5724 /* Disable interrupts. */
5725 IWN_WRITE(sc, IWN_MASK, 0);
5726 IWN_WRITE(sc, IWN_INT, 0xffffffff);
5727 IWN_WRITE(sc, IWN_FH_INT, 0xffffffff);
5729 /* Make sure we no longer hold the NIC lock. */
5730 iwn_nic_unlock(sc);
5732 /* Stop TX scheduler. */
5733 iwn_prph_write(sc, hal->sched_txfact_addr, 0);
5735 /* Stop all TX rings. */
5736 for (qid = 0; qid < hal->ntxqs; qid++)
5737 iwn_reset_tx_ring(sc, &sc->txq[qid]);
5739 /* Stop RX ring. */
5740 iwn_reset_rx_ring(sc, &sc->rxq);
5742 if (iwn_nic_lock(sc) == 0) {
5743 iwn_prph_write(sc, IWN_APMG_CLK_DIS, IWN_APMG_CLK_DMA_RQT);
5744 iwn_nic_unlock(sc);
5746 DELAY(5);
5747 /* Power OFF adapter. */
5748 iwn_apm_stop(sc);
5751 static int
5752 iwn_init(struct ifnet *ifp)
5754 struct iwn_softc *sc = ifp->if_softc;
5755 struct ieee80211com *ic = &sc->sc_ic;
5756 int error;
5758 /* Check that the radio is not disabled by hardware switch. */
5759 if (!(IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)) {
5760 aprint_error_dev(sc->sc_dev,
5761 "radio is disabled by hardware switch\n");
5762 sc->sc_radio = false;
5763 error = EPERM; /* :-) */
5764 goto fail;
5766 sc->sc_radio = true;
5768 /* Read firmware images from the filesystem. */
5769 if ((error = iwn_read_firmware(sc)) != 0) {
5770 aprint_error_dev(sc->sc_dev, "could not read firmware\n");
5771 goto fail;
5774 /* Initialize hardware and upload firmware. */
5775 error = iwn_hw_init(sc);
5776 free(sc->fw.data, M_DEVBUF);
5777 if (error != 0) {
5778 aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
5779 goto fail;
5782 /* Configure adapter now that it is ready. */
5783 if ((error = iwn_config(sc)) != 0) {
5784 aprint_error_dev(sc->sc_dev, "could not configure device\n");
5785 goto fail;
5788 ifp->if_flags &= ~IFF_OACTIVE;
5789 ifp->if_flags |= IFF_RUNNING;
5791 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
5792 if (ic->ic_opmode != IEEE80211_ROAMING_MANUAL)
5793 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
5794 } else
5795 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
5797 return 0;
5799 fail: iwn_stop(ifp, 1);
5800 return error;
5803 static void
5804 iwn_stop(struct ifnet *ifp, int disable)
5806 struct iwn_softc *sc = ifp->if_softc;
5807 struct ieee80211com *ic = &sc->sc_ic;
5809 ifp->if_timer = sc->sc_tx_timer = 0;
5810 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
5812 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
5814 /* Power OFF hardware. */
5815 iwn_hw_stop(sc);
5817 #if 0
5818 /* Temperature sensor is no longer valid. */
5819 sc->sensor.value = 0;
5820 sc->sensor.flags |= SENSOR_FINVALID;
5821 #endif
5824 static bool
5825 iwn_resume(device_t dv, pmf_qual_t qual)
5827 #if 0
5828 struct iwn_softc *sc = device_private(dv);
5830 (void)iwn_reset(sc);
5831 #endif
5833 return true;