Wed Apr 17 16:24:26 2024 UTC (47d)
Pull up following revision(s) (requested by riastradh in ticket #1825):

	sys/dev/pci/if_iwn.c: revision 1.100

if_iwn.c: pick up proper firmware for Centrino Wireless-N 130

Both variants should use iwlwifi-6000g2b-6 not iwlwifi-6000g2a-6. (It
seems only two specific product variants use iwlwifi-6000g2a-6. We
could simplify by reversing the sense of the test, as OpenBSD does, but
it doesn't seem to matter much, as what we now match seems to be the
full gamut possible, so the simpler diff was chosen here.)

Addresses PR kern/58105 from wandrien.dev%gmail.com@localhost, with the
PCI_PRODUCT_INTEL_WIFI_LINK_130_1 match tested by the reporter. Code
inspection of the FreeBSD driver indicates we should safely be able to
match PCI_PRODUCT_INTEL_WIFI_LINK_130_2 also.


(martin)
diff -r1.91 -r1.91.4.1 src/sys/dev/pci/if_iwn.c

cvs diff -r1.91 -r1.91.4.1 src/sys/dev/pci/if_iwn.c (switch to unified diff)

--- src/sys/dev/pci/if_iwn.c 2019/04/19 19:37:31 1.91
+++ src/sys/dev/pci/if_iwn.c 2024/04/17 16:24:26 1.91.4.1
@@ -1,1776 +1,1778 @@ @@ -1,1776 +1,1778 @@
1/* $NetBSD: if_iwn.c,v 1.91 2019/04/19 19:37:31 gutteridge Exp $ */ 1/* $NetBSD: if_iwn.c,v 1.91.4.1 2024/04/17 16:24:26 martin Exp $ */
2/* $OpenBSD: if_iwn.c,v 1.135 2014/09/10 07:22:09 dcoppa Exp $ */ 2/* $OpenBSD: if_iwn.c,v 1.135 2014/09/10 07:22:09 dcoppa Exp $ */
3 3
4/*- 4/*-
5 * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr> 5 * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */ 18 */
19 19
20/* 20/*
21 * Driver for Intel WiFi Link 4965 and 1000/5000/6000 Series 802.11 network 21 * Driver for Intel WiFi Link 4965 and 1000/5000/6000 Series 802.11 network
22 * adapters. 22 * adapters.
23 */ 23 */
24#include <sys/cdefs.h> 24#include <sys/cdefs.h>
25__KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.91 2019/04/19 19:37:31 gutteridge Exp $"); 25__KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.91.4.1 2024/04/17 16:24:26 martin Exp $");
26 26
27#define IWN_USE_RBUF /* Use local storage for RX */ 27#define IWN_USE_RBUF /* Use local storage for RX */
28#undef IWN_HWCRYPTO /* XXX does not even compile yet */ 28#undef IWN_HWCRYPTO /* XXX does not even compile yet */
29 29
30#include <sys/param.h> 30#include <sys/param.h>
31#include <sys/sockio.h> 31#include <sys/sockio.h>
32#include <sys/proc.h> 32#include <sys/proc.h>
33#include <sys/mbuf.h> 33#include <sys/mbuf.h>
34#include <sys/kernel.h> 34#include <sys/kernel.h>
35#include <sys/socket.h> 35#include <sys/socket.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/malloc.h> 37#include <sys/malloc.h>
38#ifdef notyetMODULE 38#ifdef notyetMODULE
39#include <sys/module.h> 39#include <sys/module.h>
40#endif 40#endif
41#include <sys/mutex.h> 41#include <sys/mutex.h>
42#include <sys/conf.h> 42#include <sys/conf.h>
43#include <sys/kauth.h> 43#include <sys/kauth.h>
44#include <sys/callout.h> 44#include <sys/callout.h>
45 45
46#include <dev/sysmon/sysmonvar.h> 46#include <dev/sysmon/sysmonvar.h>
47 47
48#include <sys/bus.h> 48#include <sys/bus.h>
49#include <machine/endian.h> 49#include <machine/endian.h>
50#include <sys/intr.h> 50#include <sys/intr.h>
51 51
52#include <dev/pci/pcireg.h> 52#include <dev/pci/pcireg.h>
53#include <dev/pci/pcivar.h> 53#include <dev/pci/pcivar.h>
54#include <dev/pci/pcidevs.h> 54#include <dev/pci/pcidevs.h>
55 55
56#include <net/bpf.h> 56#include <net/bpf.h>
57#include <net/if.h> 57#include <net/if.h>
58#include <net/if_arp.h> 58#include <net/if_arp.h>
59#include <net/if_dl.h> 59#include <net/if_dl.h>
60#include <net/if_media.h> 60#include <net/if_media.h>
61#include <net/if_types.h> 61#include <net/if_types.h>
62 62
63#include <netinet/in.h> 63#include <netinet/in.h>
64#include <netinet/in_systm.h> 64#include <netinet/in_systm.h>
65#include <netinet/in_var.h> 65#include <netinet/in_var.h>
66#include <net/if_ether.h> 66#include <net/if_ether.h>
67#include <netinet/ip.h> 67#include <netinet/ip.h>
68 68
69#include <net80211/ieee80211_var.h> 69#include <net80211/ieee80211_var.h>
70#include <net80211/ieee80211_amrr.h> 70#include <net80211/ieee80211_amrr.h>
71#include <net80211/ieee80211_radiotap.h> 71#include <net80211/ieee80211_radiotap.h>
72 72
73#include <dev/firmload.h> 73#include <dev/firmload.h>
74 74
75#include <dev/pci/if_iwnreg.h> 75#include <dev/pci/if_iwnreg.h>
76#include <dev/pci/if_iwnvar.h> 76#include <dev/pci/if_iwnvar.h>
77 77
78static const pci_product_id_t iwn_devices[] = { 78static const pci_product_id_t iwn_devices[] = {
79 PCI_PRODUCT_INTEL_WIFI_LINK_1030_1, 79 PCI_PRODUCT_INTEL_WIFI_LINK_1030_1,
80 PCI_PRODUCT_INTEL_WIFI_LINK_1030_2, 80 PCI_PRODUCT_INTEL_WIFI_LINK_1030_2,
81 PCI_PRODUCT_INTEL_WIFI_LINK_4965_1, 81 PCI_PRODUCT_INTEL_WIFI_LINK_4965_1,
82 PCI_PRODUCT_INTEL_WIFI_LINK_4965_2, 82 PCI_PRODUCT_INTEL_WIFI_LINK_4965_2,
83 PCI_PRODUCT_INTEL_WIFI_LINK_4965_3, 83 PCI_PRODUCT_INTEL_WIFI_LINK_4965_3,
84 PCI_PRODUCT_INTEL_WIFI_LINK_4965_4, 84 PCI_PRODUCT_INTEL_WIFI_LINK_4965_4,
85 PCI_PRODUCT_INTEL_WIFI_LINK_5100_1, 85 PCI_PRODUCT_INTEL_WIFI_LINK_5100_1,
86 PCI_PRODUCT_INTEL_WIFI_LINK_5100_2, 86 PCI_PRODUCT_INTEL_WIFI_LINK_5100_2,
87 PCI_PRODUCT_INTEL_WIFI_LINK_5150_1, 87 PCI_PRODUCT_INTEL_WIFI_LINK_5150_1,
88 PCI_PRODUCT_INTEL_WIFI_LINK_5150_2, 88 PCI_PRODUCT_INTEL_WIFI_LINK_5150_2,
89 PCI_PRODUCT_INTEL_WIFI_LINK_5300_1, 89 PCI_PRODUCT_INTEL_WIFI_LINK_5300_1,
90 PCI_PRODUCT_INTEL_WIFI_LINK_5300_2, 90 PCI_PRODUCT_INTEL_WIFI_LINK_5300_2,
91 PCI_PRODUCT_INTEL_WIFI_LINK_5350_1, 91 PCI_PRODUCT_INTEL_WIFI_LINK_5350_1,
92 PCI_PRODUCT_INTEL_WIFI_LINK_5350_2, 92 PCI_PRODUCT_INTEL_WIFI_LINK_5350_2,
93 PCI_PRODUCT_INTEL_WIFI_LINK_1000_1, 93 PCI_PRODUCT_INTEL_WIFI_LINK_1000_1,
94 PCI_PRODUCT_INTEL_WIFI_LINK_1000_2, 94 PCI_PRODUCT_INTEL_WIFI_LINK_1000_2,
95 PCI_PRODUCT_INTEL_WIFI_LINK_6000_3X3_1, 95 PCI_PRODUCT_INTEL_WIFI_LINK_6000_3X3_1,
96 PCI_PRODUCT_INTEL_WIFI_LINK_6000_3X3_2, 96 PCI_PRODUCT_INTEL_WIFI_LINK_6000_3X3_2,
97 PCI_PRODUCT_INTEL_WIFI_LINK_6000_IPA_1, 97 PCI_PRODUCT_INTEL_WIFI_LINK_6000_IPA_1,
98 PCI_PRODUCT_INTEL_WIFI_LINK_6000_IPA_2, 98 PCI_PRODUCT_INTEL_WIFI_LINK_6000_IPA_2,
99 PCI_PRODUCT_INTEL_WIFI_LINK_6050_2X2_1, 99 PCI_PRODUCT_INTEL_WIFI_LINK_6050_2X2_1,
100 PCI_PRODUCT_INTEL_WIFI_LINK_6050_2X2_2, 100 PCI_PRODUCT_INTEL_WIFI_LINK_6050_2X2_2,
101 PCI_PRODUCT_INTEL_WIFI_LINK_6005_2X2_1, 101 PCI_PRODUCT_INTEL_WIFI_LINK_6005_2X2_1,
102 PCI_PRODUCT_INTEL_WIFI_LINK_6005_2X2_2, 102 PCI_PRODUCT_INTEL_WIFI_LINK_6005_2X2_2,
103 PCI_PRODUCT_INTEL_WIFI_LINK_6230_1, 103 PCI_PRODUCT_INTEL_WIFI_LINK_6230_1,
104 PCI_PRODUCT_INTEL_WIFI_LINK_6230_2, 104 PCI_PRODUCT_INTEL_WIFI_LINK_6230_2,
105 PCI_PRODUCT_INTEL_WIFI_LINK_6235, 105 PCI_PRODUCT_INTEL_WIFI_LINK_6235,
106 PCI_PRODUCT_INTEL_WIFI_LINK_6235_2, 106 PCI_PRODUCT_INTEL_WIFI_LINK_6235_2,
107 PCI_PRODUCT_INTEL_WIFI_LINK_100_1, 107 PCI_PRODUCT_INTEL_WIFI_LINK_100_1,
108 PCI_PRODUCT_INTEL_WIFI_LINK_100_2, 108 PCI_PRODUCT_INTEL_WIFI_LINK_100_2,
109 PCI_PRODUCT_INTEL_WIFI_LINK_130_1, 109 PCI_PRODUCT_INTEL_WIFI_LINK_130_1,
110 PCI_PRODUCT_INTEL_WIFI_LINK_130_2, 110 PCI_PRODUCT_INTEL_WIFI_LINK_130_2,
111 PCI_PRODUCT_INTEL_WIFI_LINK_2230_1, 111 PCI_PRODUCT_INTEL_WIFI_LINK_2230_1,
112 PCI_PRODUCT_INTEL_WIFI_LINK_2230_2, 112 PCI_PRODUCT_INTEL_WIFI_LINK_2230_2,
113 PCI_PRODUCT_INTEL_WIFI_LINK_2200_1, 113 PCI_PRODUCT_INTEL_WIFI_LINK_2200_1,
114 PCI_PRODUCT_INTEL_WIFI_LINK_2200_2, 114 PCI_PRODUCT_INTEL_WIFI_LINK_2200_2,
115 PCI_PRODUCT_INTEL_WIFI_LINK_135_1, 115 PCI_PRODUCT_INTEL_WIFI_LINK_135_1,
116 PCI_PRODUCT_INTEL_WIFI_LINK_135_2, 116 PCI_PRODUCT_INTEL_WIFI_LINK_135_2,
117 PCI_PRODUCT_INTEL_WIFI_LINK_105_1, 117 PCI_PRODUCT_INTEL_WIFI_LINK_105_1,
118 PCI_PRODUCT_INTEL_WIFI_LINK_105_2, 118 PCI_PRODUCT_INTEL_WIFI_LINK_105_2,
119}; 119};
120 120
121static int iwn_match(device_t , struct cfdata *, void *); 121static int iwn_match(device_t , struct cfdata *, void *);
122static void iwn_attach(device_t , device_t , void *); 122static void iwn_attach(device_t , device_t , void *);
123static int iwn4965_attach(struct iwn_softc *, pci_product_id_t); 123static int iwn4965_attach(struct iwn_softc *, pci_product_id_t);
124static int iwn5000_attach(struct iwn_softc *, pci_product_id_t); 124static int iwn5000_attach(struct iwn_softc *, pci_product_id_t);
125static void iwn_radiotap_attach(struct iwn_softc *); 125static void iwn_radiotap_attach(struct iwn_softc *);
126static int iwn_detach(device_t , int); 126static int iwn_detach(device_t , int);
127#if 0 127#if 0
128static void iwn_power(int, void *); 128static void iwn_power(int, void *);
129#endif 129#endif
130static bool iwn_resume(device_t, const pmf_qual_t *); 130static bool iwn_resume(device_t, const pmf_qual_t *);
131static int iwn_nic_lock(struct iwn_softc *); 131static int iwn_nic_lock(struct iwn_softc *);
132static int iwn_eeprom_lock(struct iwn_softc *); 132static int iwn_eeprom_lock(struct iwn_softc *);
133static int iwn_init_otprom(struct iwn_softc *); 133static int iwn_init_otprom(struct iwn_softc *);
134static int iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int); 134static int iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
135static int iwn_dma_contig_alloc(bus_dma_tag_t, struct iwn_dma_info *, 135static int iwn_dma_contig_alloc(bus_dma_tag_t, struct iwn_dma_info *,
136 void **, bus_size_t, bus_size_t); 136 void **, bus_size_t, bus_size_t);
137static void iwn_dma_contig_free(struct iwn_dma_info *); 137static void iwn_dma_contig_free(struct iwn_dma_info *);
138static int iwn_alloc_sched(struct iwn_softc *); 138static int iwn_alloc_sched(struct iwn_softc *);
139static void iwn_free_sched(struct iwn_softc *); 139static void iwn_free_sched(struct iwn_softc *);
140static int iwn_alloc_kw(struct iwn_softc *); 140static int iwn_alloc_kw(struct iwn_softc *);
141static void iwn_free_kw(struct iwn_softc *); 141static void iwn_free_kw(struct iwn_softc *);
142static int iwn_alloc_ict(struct iwn_softc *); 142static int iwn_alloc_ict(struct iwn_softc *);
143static void iwn_free_ict(struct iwn_softc *); 143static void iwn_free_ict(struct iwn_softc *);
144static int iwn_alloc_fwmem(struct iwn_softc *); 144static int iwn_alloc_fwmem(struct iwn_softc *);
145static void iwn_free_fwmem(struct iwn_softc *); 145static void iwn_free_fwmem(struct iwn_softc *);
146static int iwn_alloc_rx_ring(struct iwn_softc *, struct iwn_rx_ring *); 146static int iwn_alloc_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
147static void iwn_reset_rx_ring(struct iwn_softc *, struct iwn_rx_ring *); 147static void iwn_reset_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
148static void iwn_free_rx_ring(struct iwn_softc *, struct iwn_rx_ring *); 148static void iwn_free_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
149static int iwn_alloc_tx_ring(struct iwn_softc *, struct iwn_tx_ring *, 149static int iwn_alloc_tx_ring(struct iwn_softc *, struct iwn_tx_ring *,
150 int); 150 int);
151static void iwn_reset_tx_ring(struct iwn_softc *, struct iwn_tx_ring *); 151static void iwn_reset_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
152static void iwn_free_tx_ring(struct iwn_softc *, struct iwn_tx_ring *); 152static void iwn_free_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
153static void iwn5000_ict_reset(struct iwn_softc *); 153static void iwn5000_ict_reset(struct iwn_softc *);
154static int iwn_read_eeprom(struct iwn_softc *); 154static int iwn_read_eeprom(struct iwn_softc *);
155static void iwn4965_read_eeprom(struct iwn_softc *); 155static void iwn4965_read_eeprom(struct iwn_softc *);
156 156
157#ifdef IWN_DEBUG 157#ifdef IWN_DEBUG
158static void iwn4965_print_power_group(struct iwn_softc *, int); 158static void iwn4965_print_power_group(struct iwn_softc *, int);
159#endif 159#endif
160static void iwn5000_read_eeprom(struct iwn_softc *); 160static void iwn5000_read_eeprom(struct iwn_softc *);
161static void iwn_read_eeprom_channels(struct iwn_softc *, int, uint32_t); 161static void iwn_read_eeprom_channels(struct iwn_softc *, int, uint32_t);
162static void iwn_read_eeprom_enhinfo(struct iwn_softc *); 162static void iwn_read_eeprom_enhinfo(struct iwn_softc *);
163static struct ieee80211_node *iwn_node_alloc(struct ieee80211_node_table *); 163static struct ieee80211_node *iwn_node_alloc(struct ieee80211_node_table *);
164static void iwn_newassoc(struct ieee80211_node *, int); 164static void iwn_newassoc(struct ieee80211_node *, int);
165static int iwn_media_change(struct ifnet *); 165static int iwn_media_change(struct ifnet *);
166static int iwn_newstate(struct ieee80211com *, enum ieee80211_state, int); 166static int iwn_newstate(struct ieee80211com *, enum ieee80211_state, int);
167static void iwn_iter_func(void *, struct ieee80211_node *); 167static void iwn_iter_func(void *, struct ieee80211_node *);
168static void iwn_calib_timeout(void *); 168static void iwn_calib_timeout(void *);
169static void iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *, 169static void iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *,
170 struct iwn_rx_data *); 170 struct iwn_rx_data *);
171static void iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *, 171static void iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *,
172 struct iwn_rx_data *); 172 struct iwn_rx_data *);
173#ifndef IEEE80211_NO_HT 173#ifndef IEEE80211_NO_HT
174static void iwn_rx_compressed_ba(struct iwn_softc *, struct iwn_rx_desc *, 174static void iwn_rx_compressed_ba(struct iwn_softc *, struct iwn_rx_desc *,
175 struct iwn_rx_data *); 175 struct iwn_rx_data *);
176#endif 176#endif
177static void iwn5000_rx_calib_results(struct iwn_softc *, 177static void iwn5000_rx_calib_results(struct iwn_softc *,
178 struct iwn_rx_desc *, struct iwn_rx_data *); 178 struct iwn_rx_desc *, struct iwn_rx_data *);
179static void iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *, 179static void iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *,
180 struct iwn_rx_data *); 180 struct iwn_rx_data *);
181static void iwn4965_tx_done(struct iwn_softc *, struct iwn_rx_desc *, 181static void iwn4965_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
182 struct iwn_rx_data *); 182 struct iwn_rx_data *);
183static void iwn5000_tx_done(struct iwn_softc *, struct iwn_rx_desc *, 183static void iwn5000_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
184 struct iwn_rx_data *); 184 struct iwn_rx_data *);
185static void iwn_tx_done(struct iwn_softc *, struct iwn_rx_desc *, int, 185static void iwn_tx_done(struct iwn_softc *, struct iwn_rx_desc *, int,
186 uint8_t); 186 uint8_t);
187static void iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *); 187static void iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *);
188static void iwn_notif_intr(struct iwn_softc *); 188static void iwn_notif_intr(struct iwn_softc *);
189static void iwn_wakeup_intr(struct iwn_softc *); 189static void iwn_wakeup_intr(struct iwn_softc *);
190static void iwn_fatal_intr(struct iwn_softc *); 190static void iwn_fatal_intr(struct iwn_softc *);
191static int iwn_intr(void *); 191static int iwn_intr(void *);
192static void iwn_softintr(void *); 192static void iwn_softintr(void *);
193static void iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t, 193static void iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t,
194 uint16_t); 194 uint16_t);
195static void iwn5000_update_sched(struct iwn_softc *, int, int, uint8_t, 195static void iwn5000_update_sched(struct iwn_softc *, int, int, uint8_t,
196 uint16_t); 196 uint16_t);
197#ifdef notyet 197#ifdef notyet
198static void iwn5000_reset_sched(struct iwn_softc *, int, int); 198static void iwn5000_reset_sched(struct iwn_softc *, int, int);
199#endif 199#endif
200static int iwn_tx(struct iwn_softc *, struct mbuf *, 200static int iwn_tx(struct iwn_softc *, struct mbuf *,
201 struct ieee80211_node *, int); 201 struct ieee80211_node *, int);
202static void iwn_start(struct ifnet *); 202static void iwn_start(struct ifnet *);
203static void iwn_watchdog(struct ifnet *); 203static void iwn_watchdog(struct ifnet *);
204static int iwn_ioctl(struct ifnet *, u_long, void *); 204static int iwn_ioctl(struct ifnet *, u_long, void *);
205static int iwn_cmd(struct iwn_softc *, int, const void *, int, int); 205static int iwn_cmd(struct iwn_softc *, int, const void *, int, int);
206static int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *, 206static int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
207 int); 207 int);
208static int iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *, 208static int iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *,
209 int); 209 int);
210static int iwn_set_link_quality(struct iwn_softc *, 210static int iwn_set_link_quality(struct iwn_softc *,
211 struct ieee80211_node *); 211 struct ieee80211_node *);
212static int iwn_add_broadcast_node(struct iwn_softc *, int); 212static int iwn_add_broadcast_node(struct iwn_softc *, int);
213static void iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t); 213static void iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
214static int iwn_set_critical_temp(struct iwn_softc *); 214static int iwn_set_critical_temp(struct iwn_softc *);
215static int iwn_set_timing(struct iwn_softc *, struct ieee80211_node *); 215static int iwn_set_timing(struct iwn_softc *, struct ieee80211_node *);
216static void iwn4965_power_calibration(struct iwn_softc *, int); 216static void iwn4965_power_calibration(struct iwn_softc *, int);
217static int iwn4965_set_txpower(struct iwn_softc *, int); 217static int iwn4965_set_txpower(struct iwn_softc *, int);
218static int iwn5000_set_txpower(struct iwn_softc *, int); 218static int iwn5000_set_txpower(struct iwn_softc *, int);
219static int iwn4965_get_rssi(const struct iwn_rx_stat *); 219static int iwn4965_get_rssi(const struct iwn_rx_stat *);
220static int iwn5000_get_rssi(const struct iwn_rx_stat *); 220static int iwn5000_get_rssi(const struct iwn_rx_stat *);
221static int iwn_get_noise(const struct iwn_rx_general_stats *); 221static int iwn_get_noise(const struct iwn_rx_general_stats *);
222static int iwn4965_get_temperature(struct iwn_softc *); 222static int iwn4965_get_temperature(struct iwn_softc *);
223static int iwn5000_get_temperature(struct iwn_softc *); 223static int iwn5000_get_temperature(struct iwn_softc *);
224static int iwn_init_sensitivity(struct iwn_softc *); 224static int iwn_init_sensitivity(struct iwn_softc *);
225static void iwn_collect_noise(struct iwn_softc *, 225static void iwn_collect_noise(struct iwn_softc *,
226 const struct iwn_rx_general_stats *); 226 const struct iwn_rx_general_stats *);
227static int iwn4965_init_gains(struct iwn_softc *); 227static int iwn4965_init_gains(struct iwn_softc *);
228static int iwn5000_init_gains(struct iwn_softc *); 228static int iwn5000_init_gains(struct iwn_softc *);
229static int iwn4965_set_gains(struct iwn_softc *); 229static int iwn4965_set_gains(struct iwn_softc *);
230static int iwn5000_set_gains(struct iwn_softc *); 230static int iwn5000_set_gains(struct iwn_softc *);
231static void iwn_tune_sensitivity(struct iwn_softc *, 231static void iwn_tune_sensitivity(struct iwn_softc *,
232 const struct iwn_rx_stats *); 232 const struct iwn_rx_stats *);
233static int iwn_send_sensitivity(struct iwn_softc *); 233static int iwn_send_sensitivity(struct iwn_softc *);
234static int iwn_set_pslevel(struct iwn_softc *, int, int, int); 234static int iwn_set_pslevel(struct iwn_softc *, int, int, int);
235static int iwn5000_runtime_calib(struct iwn_softc *); 235static int iwn5000_runtime_calib(struct iwn_softc *);
236 236
237static int iwn_config_bt_coex_bluetooth(struct iwn_softc *); 237static int iwn_config_bt_coex_bluetooth(struct iwn_softc *);
238static int iwn_config_bt_coex_prio_table(struct iwn_softc *); 238static int iwn_config_bt_coex_prio_table(struct iwn_softc *);
239static int iwn_config_bt_coex_adv1(struct iwn_softc *); 239static int iwn_config_bt_coex_adv1(struct iwn_softc *);
240static int iwn_config_bt_coex_adv2(struct iwn_softc *); 240static int iwn_config_bt_coex_adv2(struct iwn_softc *);
241 241
242static int iwn_config(struct iwn_softc *); 242static int iwn_config(struct iwn_softc *);
243static uint16_t iwn_get_active_dwell_time(struct iwn_softc *, uint16_t, 243static uint16_t iwn_get_active_dwell_time(struct iwn_softc *, uint16_t,
244 uint8_t); 244 uint8_t);
245static uint16_t iwn_limit_dwell(struct iwn_softc *, uint16_t); 245static uint16_t iwn_limit_dwell(struct iwn_softc *, uint16_t);
246static uint16_t iwn_get_passive_dwell_time(struct iwn_softc *, uint16_t); 246static uint16_t iwn_get_passive_dwell_time(struct iwn_softc *, uint16_t);
247static int iwn_scan(struct iwn_softc *, uint16_t); 247static int iwn_scan(struct iwn_softc *, uint16_t);
248static int iwn_auth(struct iwn_softc *); 248static int iwn_auth(struct iwn_softc *);
249static int iwn_run(struct iwn_softc *); 249static int iwn_run(struct iwn_softc *);
250#ifdef IWN_HWCRYPTO 250#ifdef IWN_HWCRYPTO
251static int iwn_set_key(struct ieee80211com *, struct ieee80211_node *, 251static int iwn_set_key(struct ieee80211com *, struct ieee80211_node *,
252 struct ieee80211_key *); 252 struct ieee80211_key *);
253static void iwn_delete_key(struct ieee80211com *, struct ieee80211_node *, 253static void iwn_delete_key(struct ieee80211com *, struct ieee80211_node *,
254 struct ieee80211_key *); 254 struct ieee80211_key *);
255#endif 255#endif
256static int iwn_wme_update(struct ieee80211com *); 256static int iwn_wme_update(struct ieee80211com *);
257#ifndef IEEE80211_NO_HT 257#ifndef IEEE80211_NO_HT
258static int iwn_ampdu_rx_start(struct ieee80211com *, 258static int iwn_ampdu_rx_start(struct ieee80211com *,
259 struct ieee80211_node *, uint8_t); 259 struct ieee80211_node *, uint8_t);
260static void iwn_ampdu_rx_stop(struct ieee80211com *, 260static void iwn_ampdu_rx_stop(struct ieee80211com *,
261 struct ieee80211_node *, uint8_t); 261 struct ieee80211_node *, uint8_t);
262static int iwn_ampdu_tx_start(struct ieee80211com *, 262static int iwn_ampdu_tx_start(struct ieee80211com *,
263 struct ieee80211_node *, uint8_t); 263 struct ieee80211_node *, uint8_t);
264static void iwn_ampdu_tx_stop(struct ieee80211com *, 264static void iwn_ampdu_tx_stop(struct ieee80211com *,
265 struct ieee80211_node *, uint8_t); 265 struct ieee80211_node *, uint8_t);
266static void iwn4965_ampdu_tx_start(struct iwn_softc *, 266static void iwn4965_ampdu_tx_start(struct iwn_softc *,
267 struct ieee80211_node *, uint8_t, uint16_t); 267 struct ieee80211_node *, uint8_t, uint16_t);
268static void iwn4965_ampdu_tx_stop(struct iwn_softc *, 268static void iwn4965_ampdu_tx_stop(struct iwn_softc *,
269 uint8_t, uint16_t); 269 uint8_t, uint16_t);
270static void iwn5000_ampdu_tx_start(struct iwn_softc *, 270static void iwn5000_ampdu_tx_start(struct iwn_softc *,
271 struct ieee80211_node *, uint8_t, uint16_t); 271 struct ieee80211_node *, uint8_t, uint16_t);
272static void iwn5000_ampdu_tx_stop(struct iwn_softc *, 272static void iwn5000_ampdu_tx_stop(struct iwn_softc *,
273 uint8_t, uint16_t); 273 uint8_t, uint16_t);
274#endif 274#endif
275static int iwn5000_query_calibration(struct iwn_softc *); 275static int iwn5000_query_calibration(struct iwn_softc *);
276static int iwn5000_send_calibration(struct iwn_softc *); 276static int iwn5000_send_calibration(struct iwn_softc *);
277static int iwn5000_send_wimax_coex(struct iwn_softc *); 277static int iwn5000_send_wimax_coex(struct iwn_softc *);
278static int iwn6000_temp_offset_calib(struct iwn_softc *); 278static int iwn6000_temp_offset_calib(struct iwn_softc *);
279static int iwn2000_temp_offset_calib(struct iwn_softc *); 279static int iwn2000_temp_offset_calib(struct iwn_softc *);
280static int iwn4965_post_alive(struct iwn_softc *); 280static int iwn4965_post_alive(struct iwn_softc *);
281static int iwn5000_post_alive(struct iwn_softc *); 281static int iwn5000_post_alive(struct iwn_softc *);
282static int iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *, 282static int iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *,
283 int); 283 int);
284static int iwn4965_load_firmware(struct iwn_softc *); 284static int iwn4965_load_firmware(struct iwn_softc *);
285static int iwn5000_load_firmware_section(struct iwn_softc *, uint32_t, 285static int iwn5000_load_firmware_section(struct iwn_softc *, uint32_t,
286 const uint8_t *, int); 286 const uint8_t *, int);
287static int iwn5000_load_firmware(struct iwn_softc *); 287static int iwn5000_load_firmware(struct iwn_softc *);
288static int iwn_read_firmware_leg(struct iwn_softc *, 288static int iwn_read_firmware_leg(struct iwn_softc *,
289 struct iwn_fw_info *); 289 struct iwn_fw_info *);
290static int iwn_read_firmware_tlv(struct iwn_softc *, 290static int iwn_read_firmware_tlv(struct iwn_softc *,
291 struct iwn_fw_info *, uint16_t); 291 struct iwn_fw_info *, uint16_t);
292static int iwn_read_firmware(struct iwn_softc *); 292static int iwn_read_firmware(struct iwn_softc *);
293static int iwn_clock_wait(struct iwn_softc *); 293static int iwn_clock_wait(struct iwn_softc *);
294static int iwn_apm_init(struct iwn_softc *); 294static int iwn_apm_init(struct iwn_softc *);
295static void iwn_apm_stop_master(struct iwn_softc *); 295static void iwn_apm_stop_master(struct iwn_softc *);
296static void iwn_apm_stop(struct iwn_softc *); 296static void iwn_apm_stop(struct iwn_softc *);
297static int iwn4965_nic_config(struct iwn_softc *); 297static int iwn4965_nic_config(struct iwn_softc *);
298static int iwn5000_nic_config(struct iwn_softc *); 298static int iwn5000_nic_config(struct iwn_softc *);
299static int iwn_hw_prepare(struct iwn_softc *); 299static int iwn_hw_prepare(struct iwn_softc *);
300static int iwn_hw_init(struct iwn_softc *); 300static int iwn_hw_init(struct iwn_softc *);
301static void iwn_hw_stop(struct iwn_softc *); 301static void iwn_hw_stop(struct iwn_softc *);
302static int iwn_init(struct ifnet *); 302static int iwn_init(struct ifnet *);
303static void iwn_stop(struct ifnet *, int); 303static void iwn_stop(struct ifnet *, int);
304 304
305/* XXX MCLGETI alternative */ 305/* XXX MCLGETI alternative */
306static struct mbuf *MCLGETIalt(struct iwn_softc *, int, 306static struct mbuf *MCLGETIalt(struct iwn_softc *, int,
307 struct ifnet *, u_int); 307 struct ifnet *, u_int);
308#ifdef IWN_USE_RBUF 308#ifdef IWN_USE_RBUF
309static struct iwn_rbuf *iwn_alloc_rbuf(struct iwn_softc *); 309static struct iwn_rbuf *iwn_alloc_rbuf(struct iwn_softc *);
310static void iwn_free_rbuf(struct mbuf *, void *, size_t, void *); 310static void iwn_free_rbuf(struct mbuf *, void *, size_t, void *);
311static int iwn_alloc_rpool(struct iwn_softc *); 311static int iwn_alloc_rpool(struct iwn_softc *);
312static void iwn_free_rpool(struct iwn_softc *); 312static void iwn_free_rpool(struct iwn_softc *);
313#endif 313#endif
314 314
315static void iwn_fix_channel(struct ieee80211com *, struct mbuf *, 315static void iwn_fix_channel(struct ieee80211com *, struct mbuf *,
316 struct iwn_rx_stat *); 316 struct iwn_rx_stat *);
317 317
318#ifdef IWN_DEBUG 318#ifdef IWN_DEBUG
319#define DPRINTF(x) do { if (iwn_debug > 0) printf x; } while (0) 319#define DPRINTF(x) do { if (iwn_debug > 0) printf x; } while (0)
320#define DPRINTFN(n, x) do { if (iwn_debug >= (n)) printf x; } while (0) 320#define DPRINTFN(n, x) do { if (iwn_debug >= (n)) printf x; } while (0)
321int iwn_debug = 0; 321int iwn_debug = 0;
322#else 322#else
323#define DPRINTF(x) 323#define DPRINTF(x)
324#define DPRINTFN(n, x) 324#define DPRINTFN(n, x)
325#endif 325#endif
326 326
327CFATTACH_DECL_NEW(iwn, sizeof(struct iwn_softc), iwn_match, iwn_attach, 327CFATTACH_DECL_NEW(iwn, sizeof(struct iwn_softc), iwn_match, iwn_attach,
328 iwn_detach, NULL); 328 iwn_detach, NULL);
329 329
330static int 330static int
331iwn_match(device_t parent, cfdata_t match __unused, void *aux) 331iwn_match(device_t parent, cfdata_t match __unused, void *aux)
332{ 332{
333 struct pci_attach_args *pa = aux; 333 struct pci_attach_args *pa = aux;
334 size_t i; 334 size_t i;
335 335
336 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL) 336 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
337 return 0; 337 return 0;
338 338
339 for (i = 0; i < __arraycount(iwn_devices); i++) 339 for (i = 0; i < __arraycount(iwn_devices); i++)
340 if (PCI_PRODUCT(pa->pa_id) == iwn_devices[i]) 340 if (PCI_PRODUCT(pa->pa_id) == iwn_devices[i])
341 return 1; 341 return 1;
342 342
343 return 0; 343 return 0;
344} 344}
345 345
346static void 346static void
347iwn_attach(device_t parent __unused, device_t self, void *aux) 347iwn_attach(device_t parent __unused, device_t self, void *aux)
348{ 348{
349 struct iwn_softc *sc = device_private(self); 349 struct iwn_softc *sc = device_private(self);
350 struct ieee80211com *ic = &sc->sc_ic; 350 struct ieee80211com *ic = &sc->sc_ic;
351 struct ifnet *ifp = &sc->sc_ec.ec_if; 351 struct ifnet *ifp = &sc->sc_ec.ec_if;
352 struct pci_attach_args *pa = aux; 352 struct pci_attach_args *pa = aux;
353 const char *intrstr; 353 const char *intrstr;
354 pcireg_t memtype, reg; 354 pcireg_t memtype, reg;
355 int i, error; 355 int i, error;
356 char intrbuf[PCI_INTRSTR_LEN]; 356 char intrbuf[PCI_INTRSTR_LEN];
357 357
358 sc->sc_dev = self; 358 sc->sc_dev = self;
359 sc->sc_pct = pa->pa_pc; 359 sc->sc_pct = pa->pa_pc;
360 sc->sc_pcitag = pa->pa_tag; 360 sc->sc_pcitag = pa->pa_tag;
361 sc->sc_dmat = pa->pa_dmat; 361 sc->sc_dmat = pa->pa_dmat;
362 mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE); 362 mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);
363 363
364 callout_init(&sc->calib_to, 0); 364 callout_init(&sc->calib_to, 0);
365 callout_setfunc(&sc->calib_to, iwn_calib_timeout, sc); 365 callout_setfunc(&sc->calib_to, iwn_calib_timeout, sc);
366 366
367 pci_aprint_devinfo(pa, NULL); 367 pci_aprint_devinfo(pa, NULL);
368 368
369 /* 369 /*
370 * Get the offset of the PCI Express Capability Structure in PCI 370 * Get the offset of the PCI Express Capability Structure in PCI
371 * Configuration Space. 371 * Configuration Space.
372 */ 372 */
373 error = pci_get_capability(sc->sc_pct, sc->sc_pcitag, 373 error = pci_get_capability(sc->sc_pct, sc->sc_pcitag,
374 PCI_CAP_PCIEXPRESS, &sc->sc_cap_off, NULL); 374 PCI_CAP_PCIEXPRESS, &sc->sc_cap_off, NULL);
375 if (error == 0) { 375 if (error == 0) {
376 aprint_error_dev(self, 376 aprint_error_dev(self,
377 "PCIe capability structure not found!\n"); 377 "PCIe capability structure not found!\n");
378 return; 378 return;
379 } 379 }
380 380
381 /* Clear device-specific "PCI retry timeout" register (41h). */ 381 /* Clear device-specific "PCI retry timeout" register (41h). */
382 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40); 382 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
383 if (reg & 0xff00) 383 if (reg & 0xff00)
384 pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00); 384 pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
385 385
386 /* Enable bus-mastering. */ 386 /* Enable bus-mastering. */
387 /* XXX verify the bus-mastering is really needed (not in OpenBSD) */ 387 /* XXX verify the bus-mastering is really needed (not in OpenBSD) */
388 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG); 388 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
389 reg |= PCI_COMMAND_MASTER_ENABLE; 389 reg |= PCI_COMMAND_MASTER_ENABLE;
390 pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg); 390 pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
391 391
392 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, IWN_PCI_BAR0); 392 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, IWN_PCI_BAR0);
393 error = pci_mapreg_map(pa, IWN_PCI_BAR0, memtype, 0, &sc->sc_st, 393 error = pci_mapreg_map(pa, IWN_PCI_BAR0, memtype, 0, &sc->sc_st,
394 &sc->sc_sh, NULL, &sc->sc_sz); 394 &sc->sc_sh, NULL, &sc->sc_sz);
395 if (error != 0) { 395 if (error != 0) {
396 aprint_error_dev(self, "can't map mem space\n"); 396 aprint_error_dev(self, "can't map mem space\n");
397 return; 397 return;
398 } 398 }
399 399
400 sc->sc_soft_ih = softint_establish(SOFTINT_NET, iwn_softintr, sc); 400 sc->sc_soft_ih = softint_establish(SOFTINT_NET, iwn_softintr, sc);
401 if (sc->sc_soft_ih == NULL) { 401 if (sc->sc_soft_ih == NULL) {
402 aprint_error_dev(self, "can't establish soft interrupt\n"); 402 aprint_error_dev(self, "can't establish soft interrupt\n");
403 goto unmap; 403 goto unmap;
404 } 404 }
405 405
406 /* Install interrupt handler. */ 406 /* Install interrupt handler. */
407 error = pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0); 407 error = pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0);
408 if (error) { 408 if (error) {
409 aprint_error_dev(self, "can't allocate interrupt\n"); 409 aprint_error_dev(self, "can't allocate interrupt\n");
410 goto failsi; 410 goto failsi;
411 } 411 }
412 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG); 412 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
413 if (pci_intr_type(sc->sc_pct, sc->sc_pihp[0]) == PCI_INTR_TYPE_INTX) 413 if (pci_intr_type(sc->sc_pct, sc->sc_pihp[0]) == PCI_INTR_TYPE_INTX)
414 CLR(reg, PCI_COMMAND_INTERRUPT_DISABLE); 414 CLR(reg, PCI_COMMAND_INTERRUPT_DISABLE);
415 else 415 else
416 SET(reg, PCI_COMMAND_INTERRUPT_DISABLE); 416 SET(reg, PCI_COMMAND_INTERRUPT_DISABLE);
417 pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg); 417 pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
418 intrstr = pci_intr_string(sc->sc_pct, sc->sc_pihp[0], intrbuf, 418 intrstr = pci_intr_string(sc->sc_pct, sc->sc_pihp[0], intrbuf,
419 sizeof(intrbuf)); 419 sizeof(intrbuf));
420 sc->sc_ih = pci_intr_establish_xname(sc->sc_pct, sc->sc_pihp[0], 420 sc->sc_ih = pci_intr_establish_xname(sc->sc_pct, sc->sc_pihp[0],
421 IPL_NET, iwn_intr, sc, device_xname(self)); 421 IPL_NET, iwn_intr, sc, device_xname(self));
422 if (sc->sc_ih == NULL) { 422 if (sc->sc_ih == NULL) {
423 aprint_error_dev(self, "can't establish interrupt"); 423 aprint_error_dev(self, "can't establish interrupt");
424 if (intrstr != NULL) 424 if (intrstr != NULL)
425 aprint_error(" at %s", intrstr); 425 aprint_error(" at %s", intrstr);
426 aprint_error("\n"); 426 aprint_error("\n");
427 goto failia; 427 goto failia;
428 } 428 }
429 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 429 aprint_normal_dev(self, "interrupting at %s\n", intrstr);
430 430
431 /* Read hardware revision and attach. */ 431 /* Read hardware revision and attach. */
432 sc->hw_type = 432 sc->hw_type =
433 (IWN_READ(sc, IWN_HW_REV) & IWN_HW_REV_TYPE_MASK) 433 (IWN_READ(sc, IWN_HW_REV) & IWN_HW_REV_TYPE_MASK)
434 >> IWN_HW_REV_TYPE_SHIFT; 434 >> IWN_HW_REV_TYPE_SHIFT;
435 if (sc->hw_type == IWN_HW_REV_TYPE_4965) 435 if (sc->hw_type == IWN_HW_REV_TYPE_4965)
436 error = iwn4965_attach(sc, PCI_PRODUCT(pa->pa_id)); 436 error = iwn4965_attach(sc, PCI_PRODUCT(pa->pa_id));
437 else 437 else
438 error = iwn5000_attach(sc, PCI_PRODUCT(pa->pa_id)); 438 error = iwn5000_attach(sc, PCI_PRODUCT(pa->pa_id));
439 if (error != 0) { 439 if (error != 0) {
440 aprint_error_dev(self, "could not attach device\n"); 440 aprint_error_dev(self, "could not attach device\n");
441 goto failih; 441 goto failih;
442 }  442 }
443 443
444 if ((error = iwn_hw_prepare(sc)) != 0) { 444 if ((error = iwn_hw_prepare(sc)) != 0) {
445 aprint_error_dev(self, "hardware not ready\n"); 445 aprint_error_dev(self, "hardware not ready\n");
446 goto failih; 446 goto failih;
447 } 447 }
448 448
449 /* Read MAC address, channels, etc from EEPROM. */ 449 /* Read MAC address, channels, etc from EEPROM. */
450 if ((error = iwn_read_eeprom(sc)) != 0) { 450 if ((error = iwn_read_eeprom(sc)) != 0) {
451 aprint_error_dev(self, "could not read EEPROM\n"); 451 aprint_error_dev(self, "could not read EEPROM\n");
452 goto failih; 452 goto failih;
453 } 453 }
454 454
455 /* Allocate DMA memory for firmware transfers. */ 455 /* Allocate DMA memory for firmware transfers. */
456 if ((error = iwn_alloc_fwmem(sc)) != 0) { 456 if ((error = iwn_alloc_fwmem(sc)) != 0) {
457 aprint_error_dev(self, 457 aprint_error_dev(self,
458 "could not allocate memory for firmware\n"); 458 "could not allocate memory for firmware\n");
459 goto failih; 459 goto failih;
460 } 460 }
461 461
462 /* Allocate "Keep Warm" page. */ 462 /* Allocate "Keep Warm" page. */
463 if ((error = iwn_alloc_kw(sc)) != 0) { 463 if ((error = iwn_alloc_kw(sc)) != 0) {
464 aprint_error_dev(self, "could not allocate keep warm page\n"); 464 aprint_error_dev(self, "could not allocate keep warm page\n");
465 goto fail1; 465 goto fail1;
466 } 466 }
467 467
468 /* Allocate ICT table for 5000 Series. */ 468 /* Allocate ICT table for 5000 Series. */
469 if (sc->hw_type != IWN_HW_REV_TYPE_4965 && 469 if (sc->hw_type != IWN_HW_REV_TYPE_4965 &&
470 (error = iwn_alloc_ict(sc)) != 0) { 470 (error = iwn_alloc_ict(sc)) != 0) {
471 aprint_error_dev(self, "could not allocate ICT table\n"); 471 aprint_error_dev(self, "could not allocate ICT table\n");
472 goto fail2; 472 goto fail2;
473 } 473 }
474 474
475 /* Allocate TX scheduler "rings". */ 475 /* Allocate TX scheduler "rings". */
476 if ((error = iwn_alloc_sched(sc)) != 0) { 476 if ((error = iwn_alloc_sched(sc)) != 0) {
477 aprint_error_dev(self, 477 aprint_error_dev(self,
478 "could not allocate TX scheduler rings\n"); 478 "could not allocate TX scheduler rings\n");
479 goto fail3; 479 goto fail3;
480 } 480 }
481 481
482#ifdef IWN_USE_RBUF 482#ifdef IWN_USE_RBUF
483 /* Allocate RX buffers. */ 483 /* Allocate RX buffers. */
484 if ((error = iwn_alloc_rpool(sc)) != 0) { 484 if ((error = iwn_alloc_rpool(sc)) != 0) {
485 aprint_error_dev(self, "could not allocate RX buffers\n"); 485 aprint_error_dev(self, "could not allocate RX buffers\n");
486 goto fail3; 486 goto fail3;
487 } 487 }
488#endif 488#endif
489 489
490 /* Allocate TX rings (16 on 4965AGN, 20 on >=5000). */ 490 /* Allocate TX rings (16 on 4965AGN, 20 on >=5000). */
491 for (i = 0; i < sc->ntxqs; i++) { 491 for (i = 0; i < sc->ntxqs; i++) {
492 if ((error = iwn_alloc_tx_ring(sc, &sc->txq[i], i)) != 0) { 492 if ((error = iwn_alloc_tx_ring(sc, &sc->txq[i], i)) != 0) {
493 aprint_error_dev(self, 493 aprint_error_dev(self,
494 "could not allocate TX ring %d\n", i); 494 "could not allocate TX ring %d\n", i);
495 goto fail4; 495 goto fail4;
496 } 496 }
497 } 497 }
498 498
499 /* Allocate RX ring. */ 499 /* Allocate RX ring. */
500 if ((error = iwn_alloc_rx_ring(sc, &sc->rxq)) != 0) { 500 if ((error = iwn_alloc_rx_ring(sc, &sc->rxq)) != 0) {
501 aprint_error_dev(self, "could not allocate RX ring\n"); 501 aprint_error_dev(self, "could not allocate RX ring\n");
502 goto fail4; 502 goto fail4;
503 } 503 }
504 504
505 /* Clear pending interrupts. */ 505 /* Clear pending interrupts. */
506 IWN_WRITE(sc, IWN_INT, 0xffffffff); 506 IWN_WRITE(sc, IWN_INT, 0xffffffff);
507 507
508 /* Count the number of available chains. */ 508 /* Count the number of available chains. */
509 sc->ntxchains = 509 sc->ntxchains =
510 ((sc->txchainmask >> 2) & 1) + 510 ((sc->txchainmask >> 2) & 1) +
511 ((sc->txchainmask >> 1) & 1) + 511 ((sc->txchainmask >> 1) & 1) +
512 ((sc->txchainmask >> 0) & 1); 512 ((sc->txchainmask >> 0) & 1);
513 sc->nrxchains = 513 sc->nrxchains =
514 ((sc->rxchainmask >> 2) & 1) + 514 ((sc->rxchainmask >> 2) & 1) +
515 ((sc->rxchainmask >> 1) & 1) + 515 ((sc->rxchainmask >> 1) & 1) +
516 ((sc->rxchainmask >> 0) & 1); 516 ((sc->rxchainmask >> 0) & 1);
517 aprint_normal_dev(self, "MIMO %dT%dR, %.4s, address %s\n", 517 aprint_normal_dev(self, "MIMO %dT%dR, %.4s, address %s\n",
518 sc->ntxchains, sc->nrxchains, sc->eeprom_domain, 518 sc->ntxchains, sc->nrxchains, sc->eeprom_domain,
519 ether_sprintf(ic->ic_myaddr)); 519 ether_sprintf(ic->ic_myaddr));
520 520
521 ic->ic_ifp = ifp; 521 ic->ic_ifp = ifp;
522 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 522 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
523 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ 523 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
524 ic->ic_state = IEEE80211_S_INIT; 524 ic->ic_state = IEEE80211_S_INIT;
525 525
526 /* 526 /*
527 * Set device capabilities. 527 * Set device capabilities.
528 * XXX OpenBSD has IEEE80211_C_WEP, IEEE80211_C_RSN, and 528 * XXX OpenBSD has IEEE80211_C_WEP, IEEE80211_C_RSN, and
529 * IEEE80211_C_PMGT too. 529 * IEEE80211_C_PMGT too.
530 */ 530 */
531 ic->ic_caps = 531 ic->ic_caps =
532 IEEE80211_C_IBSS | /* IBSS mode support */ 532 IEEE80211_C_IBSS | /* IBSS mode support */
533 IEEE80211_C_WPA | /* 802.11i */ 533 IEEE80211_C_WPA | /* 802.11i */
534 IEEE80211_C_MONITOR | /* monitor mode supported */ 534 IEEE80211_C_MONITOR | /* monitor mode supported */
535 IEEE80211_C_TXPMGT | /* tx power management */ 535 IEEE80211_C_TXPMGT | /* tx power management */
536 IEEE80211_C_SHSLOT | /* short slot time supported */ 536 IEEE80211_C_SHSLOT | /* short slot time supported */
537 IEEE80211_C_SHPREAMBLE | /* short preamble supported */ 537 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
538 IEEE80211_C_WME; /* 802.11e */ 538 IEEE80211_C_WME; /* 802.11e */
539 539
540#ifndef IEEE80211_NO_HT 540#ifndef IEEE80211_NO_HT
541 if (sc->sc_flags & IWN_FLAG_HAS_11N) { 541 if (sc->sc_flags & IWN_FLAG_HAS_11N) {
542 /* Set HT capabilities. */ 542 /* Set HT capabilities. */
543 ic->ic_htcaps = 543 ic->ic_htcaps =
544#if IWN_RBUF_SIZE == 8192 544#if IWN_RBUF_SIZE == 8192
545 IEEE80211_HTCAP_AMSDU7935 | 545 IEEE80211_HTCAP_AMSDU7935 |
546#endif 546#endif
547 IEEE80211_HTCAP_CBW20_40 | 547 IEEE80211_HTCAP_CBW20_40 |
548 IEEE80211_HTCAP_SGI20 | 548 IEEE80211_HTCAP_SGI20 |
549 IEEE80211_HTCAP_SGI40; 549 IEEE80211_HTCAP_SGI40;
550 if (sc->hw_type != IWN_HW_REV_TYPE_4965) 550 if (sc->hw_type != IWN_HW_REV_TYPE_4965)
551 ic->ic_htcaps |= IEEE80211_HTCAP_GF; 551 ic->ic_htcaps |= IEEE80211_HTCAP_GF;
552 if (sc->hw_type == IWN_HW_REV_TYPE_6050) 552 if (sc->hw_type == IWN_HW_REV_TYPE_6050)
553 ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DYN; 553 ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DYN;
554 else 554 else
555 ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DIS; 555 ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DIS;
556 } 556 }
557#endif /* !IEEE80211_NO_HT */ 557#endif /* !IEEE80211_NO_HT */
558 558
559 /* Set supported legacy rates. */ 559 /* Set supported legacy rates. */
560 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; 560 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
561 ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g; 561 ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
562 if (sc->sc_flags & IWN_FLAG_HAS_5GHZ) { 562 if (sc->sc_flags & IWN_FLAG_HAS_5GHZ) {
563 ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a; 563 ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a;
564 } 564 }
565#ifndef IEEE80211_NO_HT 565#ifndef IEEE80211_NO_HT
566 if (sc->sc_flags & IWN_FLAG_HAS_11N) { 566 if (sc->sc_flags & IWN_FLAG_HAS_11N) {
567 /* Set supported HT rates. */ 567 /* Set supported HT rates. */
568 ic->ic_sup_mcs[0] = 0xff; /* MCS 0-7 */ 568 ic->ic_sup_mcs[0] = 0xff; /* MCS 0-7 */
569 if (sc->nrxchains > 1) 569 if (sc->nrxchains > 1)
570 ic->ic_sup_mcs[1] = 0xff; /* MCS 7-15 */ 570 ic->ic_sup_mcs[1] = 0xff; /* MCS 7-15 */
571 if (sc->nrxchains > 2) 571 if (sc->nrxchains > 2)
572 ic->ic_sup_mcs[2] = 0xff; /* MCS 16-23 */ 572 ic->ic_sup_mcs[2] = 0xff; /* MCS 16-23 */
573 } 573 }
574#endif 574#endif
575 575
576 /* IBSS channel undefined for now. */ 576 /* IBSS channel undefined for now. */
577 ic->ic_ibss_chan = &ic->ic_channels[0]; 577 ic->ic_ibss_chan = &ic->ic_channels[0];
578 578
579 ifp->if_softc = sc; 579 ifp->if_softc = sc;
580 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 580 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
581 ifp->if_init = iwn_init; 581 ifp->if_init = iwn_init;
582 ifp->if_ioctl = iwn_ioctl; 582 ifp->if_ioctl = iwn_ioctl;
583 ifp->if_start = iwn_start; 583 ifp->if_start = iwn_start;
584 ifp->if_stop = iwn_stop; 584 ifp->if_stop = iwn_stop;
585 ifp->if_watchdog = iwn_watchdog; 585 ifp->if_watchdog = iwn_watchdog;
586 IFQ_SET_READY(&ifp->if_snd); 586 IFQ_SET_READY(&ifp->if_snd);
587 memcpy(ifp->if_xname, device_xname(self), IFNAMSIZ); 587 memcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
588 588
589 error = if_initialize(ifp); 589 error = if_initialize(ifp);
590 if (error != 0) { 590 if (error != 0) {
591 aprint_error_dev(sc->sc_dev, "if_initialize failed(%d)\n", 591 aprint_error_dev(sc->sc_dev, "if_initialize failed(%d)\n",
592 error); 592 error);
593 goto fail5; 593 goto fail5;
594 } 594 }
595 ieee80211_ifattach(ic); 595 ieee80211_ifattach(ic);
596 /* Use common softint-based if_input */ 596 /* Use common softint-based if_input */
597 ifp->if_percpuq = if_percpuq_create(ifp); 597 ifp->if_percpuq = if_percpuq_create(ifp);
598 if_register(ifp); 598 if_register(ifp);
599 599
600 ic->ic_node_alloc = iwn_node_alloc; 600 ic->ic_node_alloc = iwn_node_alloc;
601 ic->ic_newassoc = iwn_newassoc; 601 ic->ic_newassoc = iwn_newassoc;
602#ifdef IWN_HWCRYPTO 602#ifdef IWN_HWCRYPTO
603 ic->ic_crypto.cs_key_set = iwn_set_key; 603 ic->ic_crypto.cs_key_set = iwn_set_key;
604 ic->ic_crypto.cs_key_delete = iwn_delete_key; 604 ic->ic_crypto.cs_key_delete = iwn_delete_key;
605#endif 605#endif
606 ic->ic_wme.wme_update = iwn_wme_update; 606 ic->ic_wme.wme_update = iwn_wme_update;
607#ifndef IEEE80211_NO_HT 607#ifndef IEEE80211_NO_HT
608 ic->ic_ampdu_rx_start = iwn_ampdu_rx_start; 608 ic->ic_ampdu_rx_start = iwn_ampdu_rx_start;
609 ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop; 609 ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop;
610 ic->ic_ampdu_tx_start = iwn_ampdu_tx_start; 610 ic->ic_ampdu_tx_start = iwn_ampdu_tx_start;
611 ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop; 611 ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop;
612#endif 612#endif
613 613
614 /* Override 802.11 state transition machine. */ 614 /* Override 802.11 state transition machine. */
615 sc->sc_newstate = ic->ic_newstate; 615 sc->sc_newstate = ic->ic_newstate;
616 ic->ic_newstate = iwn_newstate; 616 ic->ic_newstate = iwn_newstate;
617 ieee80211_media_init(ic, iwn_media_change, ieee80211_media_status); 617 ieee80211_media_init(ic, iwn_media_change, ieee80211_media_status);
618 618
619 sc->amrr.amrr_min_success_threshold = 1; 619 sc->amrr.amrr_min_success_threshold = 1;
620 sc->amrr.amrr_max_success_threshold = 15; 620 sc->amrr.amrr_max_success_threshold = 15;
621 621
622 iwn_radiotap_attach(sc); 622 iwn_radiotap_attach(sc);
623 623
624 /* 624 /*
625 * XXX for NetBSD, OpenBSD timeout_set replaced by 625 * XXX for NetBSD, OpenBSD timeout_set replaced by
626 * callout_init and callout_setfunc, above. 626 * callout_init and callout_setfunc, above.
627 */ 627 */
628 628
629 if (pmf_device_register(self, NULL, iwn_resume)) 629 if (pmf_device_register(self, NULL, iwn_resume))
630 pmf_class_network_register(self, ifp); 630 pmf_class_network_register(self, ifp);
631 else 631 else
632 aprint_error_dev(self, "couldn't establish power handler\n"); 632 aprint_error_dev(self, "couldn't establish power handler\n");
633 633
634 /* XXX NetBSD add call to ieee80211_announce for dmesg. */ 634 /* XXX NetBSD add call to ieee80211_announce for dmesg. */
635 ieee80211_announce(ic); 635 ieee80211_announce(ic);
636 636
637 sc->sc_flags |= IWN_FLAG_ATTACHED; 637 sc->sc_flags |= IWN_FLAG_ATTACHED;
638 return; 638 return;
639 639
640 /* Free allocated memory if something failed during attachment. */ 640 /* Free allocated memory if something failed during attachment. */
641fail5: iwn_free_rx_ring(sc, &sc->rxq); 641fail5: iwn_free_rx_ring(sc, &sc->rxq);
642fail4: while (--i >= 0) 642fail4: while (--i >= 0)
643 iwn_free_tx_ring(sc, &sc->txq[i]); 643 iwn_free_tx_ring(sc, &sc->txq[i]);
644#ifdef IWN_USE_RBUF 644#ifdef IWN_USE_RBUF
645 iwn_free_rpool(sc); 645 iwn_free_rpool(sc);
646#endif 646#endif
647 iwn_free_sched(sc); 647 iwn_free_sched(sc);
648fail3: if (sc->ict != NULL) 648fail3: if (sc->ict != NULL)
649 iwn_free_ict(sc); 649 iwn_free_ict(sc);
650fail2: iwn_free_kw(sc); 650fail2: iwn_free_kw(sc);
651fail1: iwn_free_fwmem(sc); 651fail1: iwn_free_fwmem(sc);
652failih: pci_intr_disestablish(sc->sc_pct, sc->sc_ih); 652failih: pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
653 sc->sc_ih = NULL; 653 sc->sc_ih = NULL;
654failia: pci_intr_release(sc->sc_pct, sc->sc_pihp, 1); 654failia: pci_intr_release(sc->sc_pct, sc->sc_pihp, 1);
655 sc->sc_pihp = NULL; 655 sc->sc_pihp = NULL;
656failsi: softint_disestablish(sc->sc_soft_ih); 656failsi: softint_disestablish(sc->sc_soft_ih);
657 sc->sc_soft_ih = NULL; 657 sc->sc_soft_ih = NULL;
658unmap: bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz); 658unmap: bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
659} 659}
660 660
661int 661int
662iwn4965_attach(struct iwn_softc *sc, pci_product_id_t pid) 662iwn4965_attach(struct iwn_softc *sc, pci_product_id_t pid)
663{ 663{
664 struct iwn_ops *ops = &sc->ops; 664 struct iwn_ops *ops = &sc->ops;
665 665
666 ops->load_firmware = iwn4965_load_firmware; 666 ops->load_firmware = iwn4965_load_firmware;
667 ops->read_eeprom = iwn4965_read_eeprom; 667 ops->read_eeprom = iwn4965_read_eeprom;
668 ops->post_alive = iwn4965_post_alive; 668 ops->post_alive = iwn4965_post_alive;
669 ops->nic_config = iwn4965_nic_config; 669 ops->nic_config = iwn4965_nic_config;
670 ops->config_bt_coex = iwn_config_bt_coex_bluetooth; 670 ops->config_bt_coex = iwn_config_bt_coex_bluetooth;
671 ops->update_sched = iwn4965_update_sched; 671 ops->update_sched = iwn4965_update_sched;
672 ops->get_temperature = iwn4965_get_temperature; 672 ops->get_temperature = iwn4965_get_temperature;
673 ops->get_rssi = iwn4965_get_rssi; 673 ops->get_rssi = iwn4965_get_rssi;
674 ops->set_txpower = iwn4965_set_txpower; 674 ops->set_txpower = iwn4965_set_txpower;
675 ops->init_gains = iwn4965_init_gains; 675 ops->init_gains = iwn4965_init_gains;
676 ops->set_gains = iwn4965_set_gains; 676 ops->set_gains = iwn4965_set_gains;
677 ops->add_node = iwn4965_add_node; 677 ops->add_node = iwn4965_add_node;
678 ops->tx_done = iwn4965_tx_done; 678 ops->tx_done = iwn4965_tx_done;
679#ifndef IEEE80211_NO_HT 679#ifndef IEEE80211_NO_HT
680 ops->ampdu_tx_start = iwn4965_ampdu_tx_start; 680 ops->ampdu_tx_start = iwn4965_ampdu_tx_start;
681 ops->ampdu_tx_stop = iwn4965_ampdu_tx_stop; 681 ops->ampdu_tx_stop = iwn4965_ampdu_tx_stop;
682#endif 682#endif
683 sc->ntxqs = IWN4965_NTXQUEUES; 683 sc->ntxqs = IWN4965_NTXQUEUES;
684 sc->ndmachnls = IWN4965_NDMACHNLS; 684 sc->ndmachnls = IWN4965_NDMACHNLS;
685 sc->broadcast_id = IWN4965_ID_BROADCAST; 685 sc->broadcast_id = IWN4965_ID_BROADCAST;
686 sc->rxonsz = IWN4965_RXONSZ; 686 sc->rxonsz = IWN4965_RXONSZ;
687 sc->schedsz = IWN4965_SCHEDSZ; 687 sc->schedsz = IWN4965_SCHEDSZ;
688 sc->fw_text_maxsz = IWN4965_FW_TEXT_MAXSZ; 688 sc->fw_text_maxsz = IWN4965_FW_TEXT_MAXSZ;
689 sc->fw_data_maxsz = IWN4965_FW_DATA_MAXSZ; 689 sc->fw_data_maxsz = IWN4965_FW_DATA_MAXSZ;
690 sc->fwsz = IWN4965_FWSZ; 690 sc->fwsz = IWN4965_FWSZ;
691 sc->sched_txfact_addr = IWN4965_SCHED_TXFACT; 691 sc->sched_txfact_addr = IWN4965_SCHED_TXFACT;
692 sc->limits = &iwn4965_sensitivity_limits; 692 sc->limits = &iwn4965_sensitivity_limits;
693 sc->fwname = "iwlwifi-4965-2.ucode"; 693 sc->fwname = "iwlwifi-4965-2.ucode";
694 /* Override chains masks, ROM is known to be broken. */ 694 /* Override chains masks, ROM is known to be broken. */
695 sc->txchainmask = IWN_ANT_AB; 695 sc->txchainmask = IWN_ANT_AB;
696 sc->rxchainmask = IWN_ANT_ABC; 696 sc->rxchainmask = IWN_ANT_ABC;
697 697
698 return 0; 698 return 0;
699} 699}
700 700
701int 701int
702iwn5000_attach(struct iwn_softc *sc, pci_product_id_t pid) 702iwn5000_attach(struct iwn_softc *sc, pci_product_id_t pid)
703{ 703{
704 struct iwn_ops *ops = &sc->ops; 704 struct iwn_ops *ops = &sc->ops;
705 705
706 ops->load_firmware = iwn5000_load_firmware; 706 ops->load_firmware = iwn5000_load_firmware;
707 ops->read_eeprom = iwn5000_read_eeprom; 707 ops->read_eeprom = iwn5000_read_eeprom;
708 ops->post_alive = iwn5000_post_alive; 708 ops->post_alive = iwn5000_post_alive;
709 ops->nic_config = iwn5000_nic_config; 709 ops->nic_config = iwn5000_nic_config;
710 ops->config_bt_coex = iwn_config_bt_coex_bluetooth; 710 ops->config_bt_coex = iwn_config_bt_coex_bluetooth;
711 ops->update_sched = iwn5000_update_sched; 711 ops->update_sched = iwn5000_update_sched;
712 ops->get_temperature = iwn5000_get_temperature; 712 ops->get_temperature = iwn5000_get_temperature;
713 ops->get_rssi = iwn5000_get_rssi; 713 ops->get_rssi = iwn5000_get_rssi;
714 ops->set_txpower = iwn5000_set_txpower; 714 ops->set_txpower = iwn5000_set_txpower;
715 ops->init_gains = iwn5000_init_gains; 715 ops->init_gains = iwn5000_init_gains;
716 ops->set_gains = iwn5000_set_gains; 716 ops->set_gains = iwn5000_set_gains;
717 ops->add_node = iwn5000_add_node; 717 ops->add_node = iwn5000_add_node;
718 ops->tx_done = iwn5000_tx_done; 718 ops->tx_done = iwn5000_tx_done;
719#ifndef IEEE80211_NO_HT 719#ifndef IEEE80211_NO_HT
720 ops->ampdu_tx_start = iwn5000_ampdu_tx_start; 720 ops->ampdu_tx_start = iwn5000_ampdu_tx_start;
721 ops->ampdu_tx_stop = iwn5000_ampdu_tx_stop; 721 ops->ampdu_tx_stop = iwn5000_ampdu_tx_stop;
722#endif 722#endif
723 sc->ntxqs = IWN5000_NTXQUEUES; 723 sc->ntxqs = IWN5000_NTXQUEUES;
724 sc->ndmachnls = IWN5000_NDMACHNLS; 724 sc->ndmachnls = IWN5000_NDMACHNLS;
725 sc->broadcast_id = IWN5000_ID_BROADCAST; 725 sc->broadcast_id = IWN5000_ID_BROADCAST;
726 sc->rxonsz = IWN5000_RXONSZ; 726 sc->rxonsz = IWN5000_RXONSZ;
727 sc->schedsz = IWN5000_SCHEDSZ; 727 sc->schedsz = IWN5000_SCHEDSZ;
728 sc->fw_text_maxsz = IWN5000_FW_TEXT_MAXSZ; 728 sc->fw_text_maxsz = IWN5000_FW_TEXT_MAXSZ;
729 sc->fw_data_maxsz = IWN5000_FW_DATA_MAXSZ; 729 sc->fw_data_maxsz = IWN5000_FW_DATA_MAXSZ;
730 sc->fwsz = IWN5000_FWSZ; 730 sc->fwsz = IWN5000_FWSZ;
731 sc->sched_txfact_addr = IWN5000_SCHED_TXFACT; 731 sc->sched_txfact_addr = IWN5000_SCHED_TXFACT;
732 732
733 switch (sc->hw_type) { 733 switch (sc->hw_type) {
734 case IWN_HW_REV_TYPE_5100: 734 case IWN_HW_REV_TYPE_5100:
735 sc->limits = &iwn5000_sensitivity_limits; 735 sc->limits = &iwn5000_sensitivity_limits;
736 sc->fwname = "iwlwifi-5000-2.ucode"; 736 sc->fwname = "iwlwifi-5000-2.ucode";
737 /* Override chains masks, ROM is known to be broken. */ 737 /* Override chains masks, ROM is known to be broken. */
738 sc->txchainmask = IWN_ANT_B; 738 sc->txchainmask = IWN_ANT_B;
739 sc->rxchainmask = IWN_ANT_AB; 739 sc->rxchainmask = IWN_ANT_AB;
740 break; 740 break;
741 case IWN_HW_REV_TYPE_5150: 741 case IWN_HW_REV_TYPE_5150:
742 sc->limits = &iwn5150_sensitivity_limits; 742 sc->limits = &iwn5150_sensitivity_limits;
743 sc->fwname = "iwlwifi-5150-2.ucode"; 743 sc->fwname = "iwlwifi-5150-2.ucode";
744 break; 744 break;
745 case IWN_HW_REV_TYPE_5300: 745 case IWN_HW_REV_TYPE_5300:
746 case IWN_HW_REV_TYPE_5350: 746 case IWN_HW_REV_TYPE_5350:
747 sc->limits = &iwn5000_sensitivity_limits; 747 sc->limits = &iwn5000_sensitivity_limits;
748 sc->fwname = "iwlwifi-5000-2.ucode"; 748 sc->fwname = "iwlwifi-5000-2.ucode";
749 break; 749 break;
750 case IWN_HW_REV_TYPE_1000: 750 case IWN_HW_REV_TYPE_1000:
751 sc->limits = &iwn1000_sensitivity_limits; 751 sc->limits = &iwn1000_sensitivity_limits;
752 if (pid == PCI_PRODUCT_INTEL_WIFI_LINK_100_1 || 752 if (pid == PCI_PRODUCT_INTEL_WIFI_LINK_100_1 ||
753 pid == PCI_PRODUCT_INTEL_WIFI_LINK_100_2) 753 pid == PCI_PRODUCT_INTEL_WIFI_LINK_100_2)
754 sc->fwname = "iwlwifi-100-5.ucode"; 754 sc->fwname = "iwlwifi-100-5.ucode";
755 else 755 else
756 sc->fwname = "iwlwifi-1000-3.ucode"; 756 sc->fwname = "iwlwifi-1000-3.ucode";
757 break; 757 break;
758 case IWN_HW_REV_TYPE_6000: 758 case IWN_HW_REV_TYPE_6000:
759 sc->limits = &iwn6000_sensitivity_limits; 759 sc->limits = &iwn6000_sensitivity_limits;
760 sc->fwname = "iwlwifi-6000-4.ucode"; 760 sc->fwname = "iwlwifi-6000-4.ucode";
761 if (pid == PCI_PRODUCT_INTEL_WIFI_LINK_6000_IPA_1 || 761 if (pid == PCI_PRODUCT_INTEL_WIFI_LINK_6000_IPA_1 ||
762 pid == PCI_PRODUCT_INTEL_WIFI_LINK_6000_IPA_2) { 762 pid == PCI_PRODUCT_INTEL_WIFI_LINK_6000_IPA_2) {
763 sc->sc_flags |= IWN_FLAG_INTERNAL_PA; 763 sc->sc_flags |= IWN_FLAG_INTERNAL_PA;
764 /* Override chains masks, ROM is known to be broken. */ 764 /* Override chains masks, ROM is known to be broken. */
765 sc->txchainmask = IWN_ANT_BC; 765 sc->txchainmask = IWN_ANT_BC;
766 sc->rxchainmask = IWN_ANT_BC; 766 sc->rxchainmask = IWN_ANT_BC;
767 } 767 }
768 break; 768 break;
769 case IWN_HW_REV_TYPE_6050: 769 case IWN_HW_REV_TYPE_6050:
770 sc->limits = &iwn6000_sensitivity_limits; 770 sc->limits = &iwn6000_sensitivity_limits;
771 sc->fwname = "iwlwifi-6050-5.ucode"; 771 sc->fwname = "iwlwifi-6050-5.ucode";
772 break; 772 break;
773 case IWN_HW_REV_TYPE_6005: 773 case IWN_HW_REV_TYPE_6005:
774 sc->limits = &iwn6000_sensitivity_limits; 774 sc->limits = &iwn6000_sensitivity_limits;
775 /* Type 6030 cards return IWN_HW_REV_TYPE_6005 */ 775 /* Type 6030 cards return IWN_HW_REV_TYPE_6005 */
776 if (pid == PCI_PRODUCT_INTEL_WIFI_LINK_1030_1 || 776 if (pid == PCI_PRODUCT_INTEL_WIFI_LINK_1030_1 ||
777 pid == PCI_PRODUCT_INTEL_WIFI_LINK_1030_2 || 777 pid == PCI_PRODUCT_INTEL_WIFI_LINK_1030_2 ||
 778 pid == PCI_PRODUCT_INTEL_WIFI_LINK_130_1 ||
 779 pid == PCI_PRODUCT_INTEL_WIFI_LINK_130_2 ||
778 pid == PCI_PRODUCT_INTEL_WIFI_LINK_6230_1 || 780 pid == PCI_PRODUCT_INTEL_WIFI_LINK_6230_1 ||
779 pid == PCI_PRODUCT_INTEL_WIFI_LINK_6230_2 || 781 pid == PCI_PRODUCT_INTEL_WIFI_LINK_6230_2 ||
780 pid == PCI_PRODUCT_INTEL_WIFI_LINK_6235 || 782 pid == PCI_PRODUCT_INTEL_WIFI_LINK_6235 ||
781 pid == PCI_PRODUCT_INTEL_WIFI_LINK_6235_2) { 783 pid == PCI_PRODUCT_INTEL_WIFI_LINK_6235_2) {
782 sc->fwname = "iwlwifi-6000g2b-6.ucode"; 784 sc->fwname = "iwlwifi-6000g2b-6.ucode";
783 ops->config_bt_coex = iwn_config_bt_coex_adv1; 785 ops->config_bt_coex = iwn_config_bt_coex_adv1;
784 } 786 }
785 /* 787 /*
786 * This covers: 788 * This covers:
787 * PCI_PRODUCT_INTEL_WIFI_LINK_6005_2X2_1 789 * PCI_PRODUCT_INTEL_WIFI_LINK_6005_2X2_1
788 * PCI_PRODUCT_INTEL_WIFI_LINK_6005_2X2_2 790 * PCI_PRODUCT_INTEL_WIFI_LINK_6005_2X2_2
789 */ 791 */
790 else 792 else
791 sc->fwname = "iwlwifi-6000g2a-5.ucode"; 793 sc->fwname = "iwlwifi-6000g2a-5.ucode";
792 break; 794 break;
793 case IWN_HW_REV_TYPE_2030: 795 case IWN_HW_REV_TYPE_2030:
794 sc->limits = &iwn2030_sensitivity_limits; 796 sc->limits = &iwn2030_sensitivity_limits;
795 sc->fwname = "iwlwifi-2030-6.ucode"; 797 sc->fwname = "iwlwifi-2030-6.ucode";
796 ops->config_bt_coex = iwn_config_bt_coex_adv2; 798 ops->config_bt_coex = iwn_config_bt_coex_adv2;
797 break; 799 break;
798 case IWN_HW_REV_TYPE_2000: 800 case IWN_HW_REV_TYPE_2000:
799 sc->limits = &iwn2000_sensitivity_limits; 801 sc->limits = &iwn2000_sensitivity_limits;
800 sc->fwname = "iwlwifi-2000-6.ucode"; 802 sc->fwname = "iwlwifi-2000-6.ucode";
801 break; 803 break;
802 case IWN_HW_REV_TYPE_135: 804 case IWN_HW_REV_TYPE_135:
803 sc->limits = &iwn2000_sensitivity_limits; 805 sc->limits = &iwn2000_sensitivity_limits;
804 sc->fwname = "iwlwifi-135-6.ucode"; 806 sc->fwname = "iwlwifi-135-6.ucode";
805 ops->config_bt_coex = iwn_config_bt_coex_adv2; 807 ops->config_bt_coex = iwn_config_bt_coex_adv2;
806 break; 808 break;
807 case IWN_HW_REV_TYPE_105: 809 case IWN_HW_REV_TYPE_105:
808 sc->limits = &iwn2000_sensitivity_limits; 810 sc->limits = &iwn2000_sensitivity_limits;
809 sc->fwname = "iwlwifi-105-6.ucode"; 811 sc->fwname = "iwlwifi-105-6.ucode";
810 break; 812 break;
811 default: 813 default:
812 aprint_normal(": adapter type %d not supported\n", sc->hw_type); 814 aprint_normal(": adapter type %d not supported\n", sc->hw_type);
813 return ENOTSUP; 815 return ENOTSUP;
814 } 816 }
815 return 0; 817 return 0;
816} 818}
817 819
818/* 820/*
819 * Attach the interface to 802.11 radiotap. 821 * Attach the interface to 802.11 radiotap.
820 */ 822 */
821static void 823static void
822iwn_radiotap_attach(struct iwn_softc *sc) 824iwn_radiotap_attach(struct iwn_softc *sc)
823{ 825{
824 struct ifnet *ifp = sc->sc_ic.ic_ifp; 826 struct ifnet *ifp = sc->sc_ic.ic_ifp;
825 827
826 bpf_attach2(ifp, DLT_IEEE802_11_RADIO, 828 bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
827 sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, 829 sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
828 &sc->sc_drvbpf); 830 &sc->sc_drvbpf);
829 831
830 sc->sc_rxtap_len = sizeof sc->sc_rxtapu; 832 sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
831 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); 833 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
832 sc->sc_rxtap.wr_ihdr.it_present = htole32(IWN_RX_RADIOTAP_PRESENT); 834 sc->sc_rxtap.wr_ihdr.it_present = htole32(IWN_RX_RADIOTAP_PRESENT);
833 835
834 sc->sc_txtap_len = sizeof sc->sc_txtapu; 836 sc->sc_txtap_len = sizeof sc->sc_txtapu;
835 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); 837 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
836 sc->sc_txtap.wt_ihdr.it_present = htole32(IWN_TX_RADIOTAP_PRESENT); 838 sc->sc_txtap.wt_ihdr.it_present = htole32(IWN_TX_RADIOTAP_PRESENT);
837} 839}
838 840
839static int 841static int
840iwn_detach(device_t self, int flags __unused) 842iwn_detach(device_t self, int flags __unused)
841{ 843{
842 struct iwn_softc *sc = device_private(self); 844 struct iwn_softc *sc = device_private(self);
843 struct ifnet *ifp = sc->sc_ic.ic_ifp; 845 struct ifnet *ifp = sc->sc_ic.ic_ifp;
844 int qid; 846 int qid;
845 847
846 if (!(sc->sc_flags & IWN_FLAG_ATTACHED)) 848 if (!(sc->sc_flags & IWN_FLAG_ATTACHED))
847 return 0; 849 return 0;
848 850
849 callout_stop(&sc->calib_to); 851 callout_stop(&sc->calib_to);
850 852
851 /* Uninstall interrupt handler. */ 853 /* Uninstall interrupt handler. */
852 if (sc->sc_ih != NULL) 854 if (sc->sc_ih != NULL)
853 pci_intr_disestablish(sc->sc_pct, sc->sc_ih); 855 pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
854 if (sc->sc_pihp != NULL) 856 if (sc->sc_pihp != NULL)
855 pci_intr_release(sc->sc_pct, sc->sc_pihp, 1); 857 pci_intr_release(sc->sc_pct, sc->sc_pihp, 1);
856 if (sc->sc_soft_ih != NULL) 858 if (sc->sc_soft_ih != NULL)
857 softint_disestablish(sc->sc_soft_ih); 859 softint_disestablish(sc->sc_soft_ih);
858 860
859 /* Free DMA resources. */ 861 /* Free DMA resources. */
860 iwn_free_rx_ring(sc, &sc->rxq); 862 iwn_free_rx_ring(sc, &sc->rxq);
861 for (qid = 0; qid < sc->ntxqs; qid++) 863 for (qid = 0; qid < sc->ntxqs; qid++)
862 iwn_free_tx_ring(sc, &sc->txq[qid]); 864 iwn_free_tx_ring(sc, &sc->txq[qid]);
863#ifdef IWN_USE_RBUF 865#ifdef IWN_USE_RBUF
864 iwn_free_rpool(sc); 866 iwn_free_rpool(sc);
865#endif 867#endif
866 iwn_free_sched(sc); 868 iwn_free_sched(sc);
867 iwn_free_kw(sc); 869 iwn_free_kw(sc);
868 if (sc->ict != NULL) 870 if (sc->ict != NULL)
869 iwn_free_ict(sc); 871 iwn_free_ict(sc);
870 iwn_free_fwmem(sc); 872 iwn_free_fwmem(sc);
871 873
872 bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz); 874 bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
873 875
874 ieee80211_ifdetach(&sc->sc_ic); 876 ieee80211_ifdetach(&sc->sc_ic);
875 if_detach(ifp); 877 if_detach(ifp);
876 878
877 return 0; 879 return 0;
878} 880}
879 881
880#if 0 882#if 0
881/* 883/*
882 * XXX Investigate if clearing the PCI retry timeout could eliminate 884 * XXX Investigate if clearing the PCI retry timeout could eliminate
883 * the repeated scan calls. Also the calls to if_init and if_start 885 * the repeated scan calls. Also the calls to if_init and if_start
884 * are similar to the effect of adding the call to ifioctl_common . 886 * are similar to the effect of adding the call to ifioctl_common .
885 */ 887 */
886static void 888static void
887iwn_power(int why, void *arg) 889iwn_power(int why, void *arg)
888{ 890{
889 struct iwn_softc *sc = arg; 891 struct iwn_softc *sc = arg;
890 struct ifnet *ifp; 892 struct ifnet *ifp;
891 pcireg_t reg; 893 pcireg_t reg;
892 int s; 894 int s;
893 895
894 if (why != PWR_RESUME) 896 if (why != PWR_RESUME)
895 return; 897 return;
896 898
897 /* Clear device-specific "PCI retry timeout" register (41h). */ 899 /* Clear device-specific "PCI retry timeout" register (41h). */
898 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40); 900 reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
899 if (reg & 0xff00) 901 if (reg & 0xff00)
900 pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00); 902 pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
901 903
902 s = splnet(); 904 s = splnet();
903 ifp = &sc->sc_ic.ic_if; 905 ifp = &sc->sc_ic.ic_if;
904 if (ifp->if_flags & IFF_UP) { 906 if (ifp->if_flags & IFF_UP) {
905 ifp->if_init(ifp); 907 ifp->if_init(ifp);
906 if (ifp->if_flags & IFF_RUNNING) 908 if (ifp->if_flags & IFF_RUNNING)
907 ifp->if_start(ifp); 909 ifp->if_start(ifp);
908 } 910 }
909 splx(s); 911 splx(s);
910} 912}
911#endif 913#endif
912 914
913static bool 915static bool
914iwn_resume(device_t dv, const pmf_qual_t *qual) 916iwn_resume(device_t dv, const pmf_qual_t *qual)
915{ 917{
916 return true; 918 return true;
917} 919}
918 920
919static int 921static int
920iwn_nic_lock(struct iwn_softc *sc) 922iwn_nic_lock(struct iwn_softc *sc)
921{ 923{
922 int ntries; 924 int ntries;
923 925
924 /* Request exclusive access to NIC. */ 926 /* Request exclusive access to NIC. */
925 IWN_SETBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ); 927 IWN_SETBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ);
926 928
927 /* Spin until we actually get the lock. */ 929 /* Spin until we actually get the lock. */
928 for (ntries = 0; ntries < 1000; ntries++) { 930 for (ntries = 0; ntries < 1000; ntries++) {
929 if ((IWN_READ(sc, IWN_GP_CNTRL) & 931 if ((IWN_READ(sc, IWN_GP_CNTRL) &
930 (IWN_GP_CNTRL_MAC_ACCESS_ENA | IWN_GP_CNTRL_SLEEP)) == 932 (IWN_GP_CNTRL_MAC_ACCESS_ENA | IWN_GP_CNTRL_SLEEP)) ==
931 IWN_GP_CNTRL_MAC_ACCESS_ENA) 933 IWN_GP_CNTRL_MAC_ACCESS_ENA)
932 return 0; 934 return 0;
933 DELAY(10); 935 DELAY(10);
934 } 936 }
935 return ETIMEDOUT; 937 return ETIMEDOUT;
936} 938}
937 939
938static __inline void 940static __inline void
939iwn_nic_unlock(struct iwn_softc *sc) 941iwn_nic_unlock(struct iwn_softc *sc)
940{ 942{
941 IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ); 943 IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ);
942} 944}
943 945
944static __inline uint32_t 946static __inline uint32_t
945iwn_prph_read(struct iwn_softc *sc, uint32_t addr) 947iwn_prph_read(struct iwn_softc *sc, uint32_t addr)
946{ 948{
947 IWN_WRITE(sc, IWN_PRPH_RADDR, IWN_PRPH_DWORD | addr); 949 IWN_WRITE(sc, IWN_PRPH_RADDR, IWN_PRPH_DWORD | addr);
948 IWN_BARRIER_READ_WRITE(sc); 950 IWN_BARRIER_READ_WRITE(sc);
949 return IWN_READ(sc, IWN_PRPH_RDATA); 951 return IWN_READ(sc, IWN_PRPH_RDATA);
950} 952}
951 953
952static __inline void 954static __inline void
953iwn_prph_write(struct iwn_softc *sc, uint32_t addr, uint32_t data) 955iwn_prph_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
954{ 956{
955 IWN_WRITE(sc, IWN_PRPH_WADDR, IWN_PRPH_DWORD | addr); 957 IWN_WRITE(sc, IWN_PRPH_WADDR, IWN_PRPH_DWORD | addr);
956 IWN_BARRIER_WRITE(sc); 958 IWN_BARRIER_WRITE(sc);
957 IWN_WRITE(sc, IWN_PRPH_WDATA, data); 959 IWN_WRITE(sc, IWN_PRPH_WDATA, data);
958} 960}
959 961
960static __inline void 962static __inline void
961iwn_prph_setbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask) 963iwn_prph_setbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask)
962{ 964{
963 iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) | mask); 965 iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) | mask);
964} 966}
965 967
966static __inline void 968static __inline void
967iwn_prph_clrbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask) 969iwn_prph_clrbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask)
968{ 970{
969 iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) & ~mask); 971 iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) & ~mask);
970} 972}
971 973
972static __inline void 974static __inline void
973iwn_prph_write_region_4(struct iwn_softc *sc, uint32_t addr, 975iwn_prph_write_region_4(struct iwn_softc *sc, uint32_t addr,
974 const uint32_t *data, int count) 976 const uint32_t *data, int count)
975{ 977{
976 for (; count > 0; count--, data++, addr += 4) 978 for (; count > 0; count--, data++, addr += 4)
977 iwn_prph_write(sc, addr, *data); 979 iwn_prph_write(sc, addr, *data);
978} 980}
979 981
980static __inline uint32_t 982static __inline uint32_t
981iwn_mem_read(struct iwn_softc *sc, uint32_t addr) 983iwn_mem_read(struct iwn_softc *sc, uint32_t addr)
982{ 984{
983 IWN_WRITE(sc, IWN_MEM_RADDR, addr); 985 IWN_WRITE(sc, IWN_MEM_RADDR, addr);
984 IWN_BARRIER_READ_WRITE(sc); 986 IWN_BARRIER_READ_WRITE(sc);
985 return IWN_READ(sc, IWN_MEM_RDATA); 987 return IWN_READ(sc, IWN_MEM_RDATA);
986} 988}
987 989
988static __inline void 990static __inline void
989iwn_mem_write(struct iwn_softc *sc, uint32_t addr, uint32_t data) 991iwn_mem_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
990{ 992{
991 IWN_WRITE(sc, IWN_MEM_WADDR, addr); 993 IWN_WRITE(sc, IWN_MEM_WADDR, addr);
992 IWN_BARRIER_WRITE(sc); 994 IWN_BARRIER_WRITE(sc);
993 IWN_WRITE(sc, IWN_MEM_WDATA, data); 995 IWN_WRITE(sc, IWN_MEM_WDATA, data);
994} 996}
995 997
996#ifndef IEEE80211_NO_HT 998#ifndef IEEE80211_NO_HT
997static __inline void 999static __inline void
998iwn_mem_write_2(struct iwn_softc *sc, uint32_t addr, uint16_t data) 1000iwn_mem_write_2(struct iwn_softc *sc, uint32_t addr, uint16_t data)
999{ 1001{
1000 uint32_t tmp; 1002 uint32_t tmp;
1001 1003
1002 tmp = iwn_mem_read(sc, addr & ~3); 1004 tmp = iwn_mem_read(sc, addr & ~3);
1003 if (addr & 3) 1005 if (addr & 3)
1004 tmp = (tmp & 0x0000ffff) | data << 16; 1006 tmp = (tmp & 0x0000ffff) | data << 16;
1005 else 1007 else
1006 tmp = (tmp & 0xffff0000) | data; 1008 tmp = (tmp & 0xffff0000) | data;
1007 iwn_mem_write(sc, addr & ~3, tmp); 1009 iwn_mem_write(sc, addr & ~3, tmp);
1008} 1010}
1009#endif 1011#endif
1010 1012
1011static __inline void 1013static __inline void
1012iwn_mem_read_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t *data, 1014iwn_mem_read_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t *data,
1013 int count) 1015 int count)
1014{ 1016{
1015 for (; count > 0; count--, addr += 4) 1017 for (; count > 0; count--, addr += 4)
1016 *data++ = iwn_mem_read(sc, addr); 1018 *data++ = iwn_mem_read(sc, addr);
1017} 1019}
1018 1020
1019static __inline void 1021static __inline void
1020iwn_mem_set_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t val, 1022iwn_mem_set_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t val,
1021 int count) 1023 int count)
1022{ 1024{
1023 for (; count > 0; count--, addr += 4) 1025 for (; count > 0; count--, addr += 4)
1024 iwn_mem_write(sc, addr, val); 1026 iwn_mem_write(sc, addr, val);
1025} 1027}
1026 1028
1027static int 1029static int
1028iwn_eeprom_lock(struct iwn_softc *sc) 1030iwn_eeprom_lock(struct iwn_softc *sc)
1029{ 1031{
1030 int i, ntries; 1032 int i, ntries;
1031 1033
1032 for (i = 0; i < 100; i++) { 1034 for (i = 0; i < 100; i++) {
1033 /* Request exclusive access to EEPROM. */ 1035 /* Request exclusive access to EEPROM. */
1034 IWN_SETBITS(sc, IWN_HW_IF_CONFIG, 1036 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
1035 IWN_HW_IF_CONFIG_EEPROM_LOCKED); 1037 IWN_HW_IF_CONFIG_EEPROM_LOCKED);
1036 1038
1037 /* Spin until we actually get the lock. */ 1039 /* Spin until we actually get the lock. */
1038 for (ntries = 0; ntries < 100; ntries++) { 1040 for (ntries = 0; ntries < 100; ntries++) {
1039 if (IWN_READ(sc, IWN_HW_IF_CONFIG) & 1041 if (IWN_READ(sc, IWN_HW_IF_CONFIG) &
1040 IWN_HW_IF_CONFIG_EEPROM_LOCKED) 1042 IWN_HW_IF_CONFIG_EEPROM_LOCKED)
1041 return 0; 1043 return 0;
1042 DELAY(10); 1044 DELAY(10);
1043 } 1045 }
1044 } 1046 }
1045 return ETIMEDOUT; 1047 return ETIMEDOUT;
1046} 1048}
1047 1049
1048static __inline void 1050static __inline void
1049iwn_eeprom_unlock(struct iwn_softc *sc) 1051iwn_eeprom_unlock(struct iwn_softc *sc)
1050{ 1052{
1051 IWN_CLRBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_EEPROM_LOCKED); 1053 IWN_CLRBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_EEPROM_LOCKED);
1052} 1054}
1053 1055
1054/* 1056/*
1055 * Initialize access by host to One Time Programmable ROM. 1057 * Initialize access by host to One Time Programmable ROM.
1056 * NB: This kind of ROM can be found on 1000 or 6000 Series only. 1058 * NB: This kind of ROM can be found on 1000 or 6000 Series only.
1057 */ 1059 */
1058static int 1060static int
1059iwn_init_otprom(struct iwn_softc *sc) 1061iwn_init_otprom(struct iwn_softc *sc)
1060{ 1062{
1061 uint16_t prev = 0, base, next; 1063 uint16_t prev = 0, base, next;
1062 int count, error; 1064 int count, error;
1063 1065
1064 /* Wait for clock stabilization before accessing prph. */ 1066 /* Wait for clock stabilization before accessing prph. */
1065 if ((error = iwn_clock_wait(sc)) != 0) 1067 if ((error = iwn_clock_wait(sc)) != 0)
1066 return error; 1068 return error;
1067 1069
1068 if ((error = iwn_nic_lock(sc)) != 0) 1070 if ((error = iwn_nic_lock(sc)) != 0)
1069 return error; 1071 return error;
1070 iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ); 1072 iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ);
1071 DELAY(5); 1073 DELAY(5);
1072 iwn_prph_clrbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ); 1074 iwn_prph_clrbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ);
1073 iwn_nic_unlock(sc); 1075 iwn_nic_unlock(sc);
1074 1076
1075 /* Set auto clock gate disable bit for HW with OTP shadow RAM. */ 1077 /* Set auto clock gate disable bit for HW with OTP shadow RAM. */
1076 if (sc->hw_type != IWN_HW_REV_TYPE_1000) { 1078 if (sc->hw_type != IWN_HW_REV_TYPE_1000) {
1077 IWN_SETBITS(sc, IWN_DBG_LINK_PWR_MGMT, 1079 IWN_SETBITS(sc, IWN_DBG_LINK_PWR_MGMT,
1078 IWN_RESET_LINK_PWR_MGMT_DIS); 1080 IWN_RESET_LINK_PWR_MGMT_DIS);
1079 } 1081 }
1080 IWN_CLRBITS(sc, IWN_EEPROM_GP, IWN_EEPROM_GP_IF_OWNER); 1082 IWN_CLRBITS(sc, IWN_EEPROM_GP, IWN_EEPROM_GP_IF_OWNER);
1081 /* Clear ECC status. */ 1083 /* Clear ECC status. */
1082 IWN_SETBITS(sc, IWN_OTP_GP, 1084 IWN_SETBITS(sc, IWN_OTP_GP,
1083 IWN_OTP_GP_ECC_CORR_STTS | IWN_OTP_GP_ECC_UNCORR_STTS); 1085 IWN_OTP_GP_ECC_CORR_STTS | IWN_OTP_GP_ECC_UNCORR_STTS);
1084 1086
1085 /* 1087 /*
1086 * Find the block before last block (contains the EEPROM image) 1088 * Find the block before last block (contains the EEPROM image)
1087 * for HW without OTP shadow RAM. 1089 * for HW without OTP shadow RAM.
1088 */ 1090 */
1089 if (sc->hw_type == IWN_HW_REV_TYPE_1000) { 1091 if (sc->hw_type == IWN_HW_REV_TYPE_1000) {
1090 /* Switch to absolute addressing mode. */ 1092 /* Switch to absolute addressing mode. */
1091 IWN_CLRBITS(sc, IWN_OTP_GP, IWN_OTP_GP_RELATIVE_ACCESS); 1093 IWN_CLRBITS(sc, IWN_OTP_GP, IWN_OTP_GP_RELATIVE_ACCESS);
1092 base = 0; 1094 base = 0;
1093 for (count = 0; count < IWN1000_OTP_NBLOCKS; count++) { 1095 for (count = 0; count < IWN1000_OTP_NBLOCKS; count++) {
1094 error = iwn_read_prom_data(sc, base, &next, 2); 1096 error = iwn_read_prom_data(sc, base, &next, 2);
1095 if (error != 0) 1097 if (error != 0)
1096 return error; 1098 return error;
1097 if (next == 0) /* End of linked-list. */ 1099 if (next == 0) /* End of linked-list. */
1098 break; 1100 break;
1099 prev = base; 1101 prev = base;
1100 base = le16toh(next); 1102 base = le16toh(next);
1101 } 1103 }
1102 if (count == 0 || count == IWN1000_OTP_NBLOCKS) 1104 if (count == 0 || count == IWN1000_OTP_NBLOCKS)
1103 return EIO; 1105 return EIO;
1104 /* Skip "next" word. */ 1106 /* Skip "next" word. */
1105 sc->prom_base = prev + 1; 1107 sc->prom_base = prev + 1;
1106 } 1108 }
1107 return 0; 1109 return 0;
1108} 1110}
1109 1111
1110static int 1112static int
1111iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count) 1113iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count)
1112{ 1114{
1113 uint8_t *out = data; 1115 uint8_t *out = data;
1114 uint32_t val, tmp; 1116 uint32_t val, tmp;
1115 int ntries; 1117 int ntries;
1116 1118
1117 addr += sc->prom_base; 1119 addr += sc->prom_base;
1118 for (; count > 0; count -= 2, addr++) { 1120 for (; count > 0; count -= 2, addr++) {
1119 IWN_WRITE(sc, IWN_EEPROM, addr << 2); 1121 IWN_WRITE(sc, IWN_EEPROM, addr << 2);
1120 for (ntries = 0; ntries < 10; ntries++) { 1122 for (ntries = 0; ntries < 10; ntries++) {
1121 val = IWN_READ(sc, IWN_EEPROM); 1123 val = IWN_READ(sc, IWN_EEPROM);
1122 if (val & IWN_EEPROM_READ_VALID) 1124 if (val & IWN_EEPROM_READ_VALID)
1123 break; 1125 break;
1124 DELAY(5); 1126 DELAY(5);
1125 } 1127 }
1126 if (ntries == 10) { 1128 if (ntries == 10) {
1127 aprint_error_dev(sc->sc_dev, 1129 aprint_error_dev(sc->sc_dev,
1128 "timeout reading ROM at 0x%x\n", addr); 1130 "timeout reading ROM at 0x%x\n", addr);
1129 return ETIMEDOUT; 1131 return ETIMEDOUT;
1130 } 1132 }
1131 if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) { 1133 if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) {
1132 /* OTPROM, check for ECC errors. */ 1134 /* OTPROM, check for ECC errors. */
1133 tmp = IWN_READ(sc, IWN_OTP_GP); 1135 tmp = IWN_READ(sc, IWN_OTP_GP);
1134 if (tmp & IWN_OTP_GP_ECC_UNCORR_STTS) { 1136 if (tmp & IWN_OTP_GP_ECC_UNCORR_STTS) {
1135 aprint_error_dev(sc->sc_dev, 1137 aprint_error_dev(sc->sc_dev,
1136 "OTPROM ECC error at 0x%x\n", addr); 1138 "OTPROM ECC error at 0x%x\n", addr);
1137 return EIO; 1139 return EIO;
1138 } 1140 }
1139 if (tmp & IWN_OTP_GP_ECC_CORR_STTS) { 1141 if (tmp & IWN_OTP_GP_ECC_CORR_STTS) {
1140 /* Correctable ECC error, clear bit. */ 1142 /* Correctable ECC error, clear bit. */
1141 IWN_SETBITS(sc, IWN_OTP_GP, 1143 IWN_SETBITS(sc, IWN_OTP_GP,
1142 IWN_OTP_GP_ECC_CORR_STTS); 1144 IWN_OTP_GP_ECC_CORR_STTS);
1143 } 1145 }
1144 } 1146 }
1145 *out++ = val >> 16; 1147 *out++ = val >> 16;
1146 if (count > 1) 1148 if (count > 1)
1147 *out++ = val >> 24; 1149 *out++ = val >> 24;
1148 } 1150 }
1149 return 0; 1151 return 0;
1150} 1152}
1151 1153
1152static int 1154static int
1153iwn_dma_contig_alloc(bus_dma_tag_t tag, struct iwn_dma_info *dma, void **kvap, 1155iwn_dma_contig_alloc(bus_dma_tag_t tag, struct iwn_dma_info *dma, void **kvap,
1154 bus_size_t size, bus_size_t alignment) 1156 bus_size_t size, bus_size_t alignment)
1155{ 1157{
1156 int nsegs, error; 1158 int nsegs, error;
1157 1159
1158 dma->tag = tag; 1160 dma->tag = tag;
1159 dma->size = size; 1161 dma->size = size;
1160 1162
1161 error = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT, 1163 error = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT,
1162 &dma->map); 1164 &dma->map);
1163 if (error != 0) 1165 if (error != 0)
1164 goto fail; 1166 goto fail;
1165 1167
1166 error = bus_dmamem_alloc(tag, size, alignment, 0, &dma->seg, 1, &nsegs, 1168 error = bus_dmamem_alloc(tag, size, alignment, 0, &dma->seg, 1, &nsegs,
1167 BUS_DMA_NOWAIT); /* XXX OpenBSD adds BUS_DMA_ZERO */ 1169 BUS_DMA_NOWAIT); /* XXX OpenBSD adds BUS_DMA_ZERO */
1168 if (error != 0) 1170 if (error != 0)
1169 goto fail; 1171 goto fail;
1170 1172
1171 error = bus_dmamem_map(tag, &dma->seg, 1, size, &dma->vaddr, 1173 error = bus_dmamem_map(tag, &dma->seg, 1, size, &dma->vaddr,
1172 BUS_DMA_NOWAIT); /* XXX OpenBSD adds BUS_DMA_COHERENT */ 1174 BUS_DMA_NOWAIT); /* XXX OpenBSD adds BUS_DMA_COHERENT */
1173 if (error != 0) 1175 if (error != 0)
1174 goto fail; 1176 goto fail;
1175 1177
1176 error = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL, 1178 error = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL,
1177 BUS_DMA_NOWAIT); 1179 BUS_DMA_NOWAIT);
1178 if (error != 0) 1180 if (error != 0)
1179 goto fail; 1181 goto fail;
1180 1182
1181 /* XXX Presumably needed because of missing BUS_DMA_ZERO, above. */ 1183 /* XXX Presumably needed because of missing BUS_DMA_ZERO, above. */
1182 memset(dma->vaddr, 0, size); 1184 memset(dma->vaddr, 0, size);
1183 bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE); 1185 bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
1184 1186
1185 dma->paddr = dma->map->dm_segs[0].ds_addr; 1187 dma->paddr = dma->map->dm_segs[0].ds_addr;
1186 if (kvap != NULL) 1188 if (kvap != NULL)
1187 *kvap = dma->vaddr; 1189 *kvap = dma->vaddr;
1188 1190
1189 return 0; 1191 return 0;
1190 1192
1191fail: iwn_dma_contig_free(dma); 1193fail: iwn_dma_contig_free(dma);
1192 return error; 1194 return error;
1193} 1195}
1194 1196
1195static void 1197static void
1196iwn_dma_contig_free(struct iwn_dma_info *dma) 1198iwn_dma_contig_free(struct iwn_dma_info *dma)
1197{ 1199{
1198 if (dma->map != NULL) { 1200 if (dma->map != NULL) {
1199 if (dma->vaddr != NULL) { 1201 if (dma->vaddr != NULL) {
1200 bus_dmamap_sync(dma->tag, dma->map, 0, dma->size, 1202 bus_dmamap_sync(dma->tag, dma->map, 0, dma->size,
1201 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1203 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1202 bus_dmamap_unload(dma->tag, dma->map); 1204 bus_dmamap_unload(dma->tag, dma->map);
1203 bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size); 1205 bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size);
1204 bus_dmamem_free(dma->tag, &dma->seg, 1); 1206 bus_dmamem_free(dma->tag, &dma->seg, 1);
1205 dma->vaddr = NULL; 1207 dma->vaddr = NULL;
1206 } 1208 }
1207 bus_dmamap_destroy(dma->tag, dma->map); 1209 bus_dmamap_destroy(dma->tag, dma->map);
1208 dma->map = NULL; 1210 dma->map = NULL;
1209 } 1211 }
1210} 1212}
1211 1213
1212static int 1214static int
1213iwn_alloc_sched(struct iwn_softc *sc) 1215iwn_alloc_sched(struct iwn_softc *sc)
1214{ 1216{
1215 /* TX scheduler rings must be aligned on a 1KB boundary. */ 1217 /* TX scheduler rings must be aligned on a 1KB boundary. */
1216 return iwn_dma_contig_alloc(sc->sc_dmat, &sc->sched_dma, 1218 return iwn_dma_contig_alloc(sc->sc_dmat, &sc->sched_dma,
1217 (void **)&sc->sched, sc->schedsz, 1024); 1219 (void **)&sc->sched, sc->schedsz, 1024);
1218} 1220}
1219 1221
1220static void 1222static void
1221iwn_free_sched(struct iwn_softc *sc) 1223iwn_free_sched(struct iwn_softc *sc)
1222{ 1224{
1223 iwn_dma_contig_free(&sc->sched_dma); 1225 iwn_dma_contig_free(&sc->sched_dma);
1224} 1226}
1225 1227
1226static int 1228static int
1227iwn_alloc_kw(struct iwn_softc *sc) 1229iwn_alloc_kw(struct iwn_softc *sc)
1228{ 1230{
1229 /* "Keep Warm" page must be aligned on a 4KB boundary. */ 1231 /* "Keep Warm" page must be aligned on a 4KB boundary. */
1230 return iwn_dma_contig_alloc(sc->sc_dmat, &sc->kw_dma, NULL, 4096, 1232 return iwn_dma_contig_alloc(sc->sc_dmat, &sc->kw_dma, NULL, 4096,
1231 4096); 1233 4096);
1232} 1234}
1233 1235
1234static void 1236static void
1235iwn_free_kw(struct iwn_softc *sc) 1237iwn_free_kw(struct iwn_softc *sc)
1236{ 1238{
1237 iwn_dma_contig_free(&sc->kw_dma); 1239 iwn_dma_contig_free(&sc->kw_dma);
1238} 1240}
1239 1241
1240static int 1242static int
1241iwn_alloc_ict(struct iwn_softc *sc) 1243iwn_alloc_ict(struct iwn_softc *sc)
1242{ 1244{
1243 /* ICT table must be aligned on a 4KB boundary. */ 1245 /* ICT table must be aligned on a 4KB boundary. */
1244 return iwn_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma, 1246 return iwn_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma,
1245 (void **)&sc->ict, IWN_ICT_SIZE, 4096); 1247 (void **)&sc->ict, IWN_ICT_SIZE, 4096);
1246} 1248}
1247 1249
1248static void 1250static void
1249iwn_free_ict(struct iwn_softc *sc) 1251iwn_free_ict(struct iwn_softc *sc)
1250{ 1252{
1251 iwn_dma_contig_free(&sc->ict_dma); 1253 iwn_dma_contig_free(&sc->ict_dma);
1252} 1254}
1253 1255
1254static int 1256static int
1255iwn_alloc_fwmem(struct iwn_softc *sc) 1257iwn_alloc_fwmem(struct iwn_softc *sc)
1256{ 1258{
1257 /* Must be aligned on a 16-byte boundary. */ 1259 /* Must be aligned on a 16-byte boundary. */
1258 return iwn_dma_contig_alloc(sc->sc_dmat, &sc->fw_dma, NULL, 1260 return iwn_dma_contig_alloc(sc->sc_dmat, &sc->fw_dma, NULL,
1259 sc->fwsz, 16); 1261 sc->fwsz, 16);
1260} 1262}
1261 1263
1262static void 1264static void
1263iwn_free_fwmem(struct iwn_softc *sc) 1265iwn_free_fwmem(struct iwn_softc *sc)
1264{ 1266{
1265 iwn_dma_contig_free(&sc->fw_dma); 1267 iwn_dma_contig_free(&sc->fw_dma);
1266} 1268}
1267 1269
1268static int 1270static int
1269iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring) 1271iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
1270{ 1272{
1271 bus_size_t size; 1273 bus_size_t size;
1272 int i, error; 1274 int i, error;
1273 1275
1274 ring->cur = 0; 1276 ring->cur = 0;
1275 1277
1276 /* Allocate RX descriptors (256-byte aligned). */ 1278 /* Allocate RX descriptors (256-byte aligned). */
1277 size = IWN_RX_RING_COUNT * sizeof (uint32_t); 1279 size = IWN_RX_RING_COUNT * sizeof (uint32_t);
1278 error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, 1280 error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma,
1279 (void **)&ring->desc, size, 256); 1281 (void **)&ring->desc, size, 256);
1280 if (error != 0) { 1282 if (error != 0) {
1281 aprint_error_dev(sc->sc_dev, 1283 aprint_error_dev(sc->sc_dev,
1282 "could not allocate RX ring DMA memory\n"); 1284 "could not allocate RX ring DMA memory\n");
1283 goto fail; 1285 goto fail;
1284 } 1286 }
1285 1287
1286 /* Allocate RX status area (16-byte aligned). */ 1288 /* Allocate RX status area (16-byte aligned). */
1287 error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma, 1289 error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma,
1288 (void **)&ring->stat, sizeof (struct iwn_rx_status), 16); 1290 (void **)&ring->stat, sizeof (struct iwn_rx_status), 16);
1289 if (error != 0) { 1291 if (error != 0) {
1290 aprint_error_dev(sc->sc_dev, 1292 aprint_error_dev(sc->sc_dev,
1291 "could not allocate RX status DMA memory\n"); 1293 "could not allocate RX status DMA memory\n");
1292 goto fail; 1294 goto fail;
1293 } 1295 }
1294 1296
1295 /* 1297 /*
1296 * Allocate and map RX buffers. 1298 * Allocate and map RX buffers.
1297 */ 1299 */
1298 for (i = 0; i < IWN_RX_RING_COUNT; i++) { 1300 for (i = 0; i < IWN_RX_RING_COUNT; i++) {
1299 struct iwn_rx_data *data = &ring->data[i]; 1301 struct iwn_rx_data *data = &ring->data[i];
1300 1302
1301 error = bus_dmamap_create(sc->sc_dmat, IWN_RBUF_SIZE, 1, 1303 error = bus_dmamap_create(sc->sc_dmat, IWN_RBUF_SIZE, 1,
1302 IWN_RBUF_SIZE, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, 1304 IWN_RBUF_SIZE, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
1303 &data->map); 1305 &data->map);
1304 if (error != 0) { 1306 if (error != 0) {
1305 aprint_error_dev(sc->sc_dev, 1307 aprint_error_dev(sc->sc_dev,
1306 "could not create RX buf DMA map\n"); 1308 "could not create RX buf DMA map\n");
1307 goto fail; 1309 goto fail;
1308 } 1310 }
1309 1311
1310 data->m = MCLGETIalt(sc, M_DONTWAIT, NULL, IWN_RBUF_SIZE); 1312 data->m = MCLGETIalt(sc, M_DONTWAIT, NULL, IWN_RBUF_SIZE);
1311 if (data->m == NULL) { 1313 if (data->m == NULL) {
1312 aprint_error_dev(sc->sc_dev, 1314 aprint_error_dev(sc->sc_dev,
1313 "could not allocate RX mbuf\n"); 1315 "could not allocate RX mbuf\n");
1314 error = ENOBUFS; 1316 error = ENOBUFS;
1315 goto fail; 1317 goto fail;
1316 } 1318 }
1317 1319
1318 error = bus_dmamap_load(sc->sc_dmat, data->map, 1320 error = bus_dmamap_load(sc->sc_dmat, data->map,
1319 mtod(data->m, void *), IWN_RBUF_SIZE, NULL, 1321 mtod(data->m, void *), IWN_RBUF_SIZE, NULL,
1320 BUS_DMA_NOWAIT | BUS_DMA_READ); 1322 BUS_DMA_NOWAIT | BUS_DMA_READ);
1321 if (error != 0) { 1323 if (error != 0) {
1322 aprint_error_dev(sc->sc_dev, 1324 aprint_error_dev(sc->sc_dev,
1323 "can't not map mbuf (error %d)\n", error); 1325 "can't not map mbuf (error %d)\n", error);
1324 goto fail; 1326 goto fail;
1325 } 1327 }
1326 1328
1327 /* Set physical address of RX buffer (256-byte aligned). */ 1329 /* Set physical address of RX buffer (256-byte aligned). */
1328 ring->desc[i] = htole32(data->map->dm_segs[0].ds_addr >> 8); 1330 ring->desc[i] = htole32(data->map->dm_segs[0].ds_addr >> 8);
1329 } 1331 }
1330 1332
1331 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0, size, 1333 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0, size,
1332 BUS_DMASYNC_PREWRITE); 1334 BUS_DMASYNC_PREWRITE);
1333 1335
1334 return 0; 1336 return 0;
1335 1337
1336fail: iwn_free_rx_ring(sc, ring); 1338fail: iwn_free_rx_ring(sc, ring);
1337 return error; 1339 return error;
1338} 1340}
1339 1341
1340static void 1342static void
1341iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring) 1343iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
1342{ 1344{
1343 int ntries; 1345 int ntries;
1344 1346
1345 if (iwn_nic_lock(sc) == 0) { 1347 if (iwn_nic_lock(sc) == 0) {
1346 IWN_WRITE(sc, IWN_FH_RX_CONFIG, 0); 1348 IWN_WRITE(sc, IWN_FH_RX_CONFIG, 0);
1347 for (ntries = 0; ntries < 1000; ntries++) { 1349 for (ntries = 0; ntries < 1000; ntries++) {
1348 if (IWN_READ(sc, IWN_FH_RX_STATUS) & 1350 if (IWN_READ(sc, IWN_FH_RX_STATUS) &
1349 IWN_FH_RX_STATUS_IDLE) 1351 IWN_FH_RX_STATUS_IDLE)
1350 break; 1352 break;
1351 DELAY(10); 1353 DELAY(10);
1352 } 1354 }
1353 iwn_nic_unlock(sc); 1355 iwn_nic_unlock(sc);
1354 } 1356 }
1355 ring->cur = 0; 1357 ring->cur = 0;
1356 sc->last_rx_valid = 0; 1358 sc->last_rx_valid = 0;
1357} 1359}
1358 1360
1359static void 1361static void
1360iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring) 1362iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
1361{ 1363{
1362 int i; 1364 int i;
1363 1365
1364 iwn_dma_contig_free(&ring->desc_dma); 1366 iwn_dma_contig_free(&ring->desc_dma);
1365 iwn_dma_contig_free(&ring->stat_dma); 1367 iwn_dma_contig_free(&ring->stat_dma);
1366 1368
1367 for (i = 0; i < IWN_RX_RING_COUNT; i++) { 1369 for (i = 0; i < IWN_RX_RING_COUNT; i++) {
1368 struct iwn_rx_data *data = &ring->data[i]; 1370 struct iwn_rx_data *data = &ring->data[i];
1369 1371
1370 if (data->m != NULL) { 1372 if (data->m != NULL) {
1371 bus_dmamap_sync(sc->sc_dmat, data->map, 0, 1373 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1372 data->map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1374 data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
1373 bus_dmamap_unload(sc->sc_dmat, data->map); 1375 bus_dmamap_unload(sc->sc_dmat, data->map);
1374 m_freem(data->m); 1376 m_freem(data->m);
1375 } 1377 }
1376 if (data->map != NULL) 1378 if (data->map != NULL)
1377 bus_dmamap_destroy(sc->sc_dmat, data->map); 1379 bus_dmamap_destroy(sc->sc_dmat, data->map);
1378 } 1380 }
1379} 1381}
1380 1382
1381static int 1383static int
1382iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid) 1384iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)
1383{ 1385{
1384 bus_addr_t paddr; 1386 bus_addr_t paddr;
1385 bus_size_t size; 1387 bus_size_t size;
1386 int i, error; 1388 int i, error;
1387 1389
1388 ring->qid = qid; 1390 ring->qid = qid;
1389 ring->queued = 0; 1391 ring->queued = 0;
1390 ring->cur = 0; 1392 ring->cur = 0;
1391 1393
1392 /* Allocate TX descriptors (256-byte aligned). */ 1394 /* Allocate TX descriptors (256-byte aligned). */
1393 size = IWN_TX_RING_COUNT * sizeof (struct iwn_tx_desc); 1395 size = IWN_TX_RING_COUNT * sizeof (struct iwn_tx_desc);
1394 error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, 1396 error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma,
1395 (void **)&ring->desc, size, 256); 1397 (void **)&ring->desc, size, 256);
1396 if (error != 0) { 1398 if (error != 0) {
1397 aprint_error_dev(sc->sc_dev, 1399 aprint_error_dev(sc->sc_dev,
1398 "could not allocate TX ring DMA memory\n"); 1400 "could not allocate TX ring DMA memory\n");
1399 goto fail; 1401 goto fail;
1400 } 1402 }
1401 /* 1403 /*
1402 * We only use rings 0 through 4 (4 EDCA + cmd) so there is no need 1404 * We only use rings 0 through 4 (4 EDCA + cmd) so there is no need
1403 * to allocate commands space for other rings. 1405 * to allocate commands space for other rings.
1404 * XXX Do we really need to allocate descriptors for other rings? 1406 * XXX Do we really need to allocate descriptors for other rings?
1405 */ 1407 */
1406 if (qid > 4) 1408 if (qid > 4)
1407 return 0; 1409 return 0;
1408 1410
1409 size = IWN_TX_RING_COUNT * sizeof (struct iwn_tx_cmd); 1411 size = IWN_TX_RING_COUNT * sizeof (struct iwn_tx_cmd);
1410 error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->cmd_dma, 1412 error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->cmd_dma,
1411 (void **)&ring->cmd, size, 4); 1413 (void **)&ring->cmd, size, 4);
1412 if (error != 0) { 1414 if (error != 0) {
1413 aprint_error_dev(sc->sc_dev, 1415 aprint_error_dev(sc->sc_dev,
1414 "could not allocate TX cmd DMA memory\n"); 1416 "could not allocate TX cmd DMA memory\n");
1415 goto fail; 1417 goto fail;
1416 } 1418 }
1417 1419
1418 paddr = ring->cmd_dma.paddr; 1420 paddr = ring->cmd_dma.paddr;
1419 for (i = 0; i < IWN_TX_RING_COUNT; i++) { 1421 for (i = 0; i < IWN_TX_RING_COUNT; i++) {
1420 struct iwn_tx_data *data = &ring->data[i]; 1422 struct iwn_tx_data *data = &ring->data[i];
1421 1423
1422 data->cmd_paddr = paddr; 1424 data->cmd_paddr = paddr;
1423 data->scratch_paddr = paddr + 12; 1425 data->scratch_paddr = paddr + 12;
1424 paddr += sizeof (struct iwn_tx_cmd); 1426 paddr += sizeof (struct iwn_tx_cmd);
1425 1427
1426 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1428 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
1427 IWN_MAX_SCATTER - 1, MCLBYTES, 0, BUS_DMA_NOWAIT, 1429 IWN_MAX_SCATTER - 1, MCLBYTES, 0, BUS_DMA_NOWAIT,
1428 &data->map); 1430 &data->map);
1429 if (error != 0) { 1431 if (error != 0) {
1430 aprint_error_dev(sc->sc_dev, 1432 aprint_error_dev(sc->sc_dev,
1431 "could not create TX buf DMA map\n"); 1433 "could not create TX buf DMA map\n");
1432 goto fail; 1434 goto fail;
1433 } 1435 }
1434 } 1436 }
1435 return 0; 1437 return 0;
1436 1438
1437fail: iwn_free_tx_ring(sc, ring); 1439fail: iwn_free_tx_ring(sc, ring);
1438 return error; 1440 return error;
1439} 1441}
1440 1442
1441static void 1443static void
1442iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring) 1444iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
1443{ 1445{
1444 int i; 1446 int i;
1445 1447
1446 for (i = 0; i < IWN_TX_RING_COUNT; i++) { 1448 for (i = 0; i < IWN_TX_RING_COUNT; i++) {
1447 struct iwn_tx_data *data = &ring->data[i]; 1449 struct iwn_tx_data *data = &ring->data[i];
1448 1450
1449 if (data->m != NULL) { 1451 if (data->m != NULL) {
1450 bus_dmamap_sync(sc->sc_dmat, data->map, 0, 1452 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1451 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1453 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1452 bus_dmamap_unload(sc->sc_dmat, data->map); 1454 bus_dmamap_unload(sc->sc_dmat, data->map);
1453 m_freem(data->m); 1455 m_freem(data->m);
1454 data->m = NULL; 1456 data->m = NULL;
1455 } 1457 }
1456 } 1458 }
1457 /* Clear TX descriptors. */ 1459 /* Clear TX descriptors. */
1458 memset(ring->desc, 0, ring->desc_dma.size); 1460 memset(ring->desc, 0, ring->desc_dma.size);
1459 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0, 1461 bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0,
1460 ring->desc_dma.size, BUS_DMASYNC_PREWRITE); 1462 ring->desc_dma.size, BUS_DMASYNC_PREWRITE);
1461 sc->qfullmsk &= ~(1 << ring->qid); 1463 sc->qfullmsk &= ~(1 << ring->qid);
1462 ring->queued = 0; 1464 ring->queued = 0;
1463 ring->cur = 0; 1465 ring->cur = 0;
1464} 1466}
1465 1467
1466static void 1468static void
1467iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring) 1469iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
1468{ 1470{
1469 int i; 1471 int i;
1470 1472
1471 iwn_dma_contig_free(&ring->desc_dma); 1473 iwn_dma_contig_free(&ring->desc_dma);
1472 iwn_dma_contig_free(&ring->cmd_dma); 1474 iwn_dma_contig_free(&ring->cmd_dma);
1473 1475
1474 for (i = 0; i < IWN_TX_RING_COUNT; i++) { 1476 for (i = 0; i < IWN_TX_RING_COUNT; i++) {
1475 struct iwn_tx_data *data = &ring->data[i]; 1477 struct iwn_tx_data *data = &ring->data[i];
1476 1478
1477 if (data->m != NULL) { 1479 if (data->m != NULL) {
1478 bus_dmamap_sync(sc->sc_dmat, data->map, 0, 1480 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1479 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1481 data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1480 bus_dmamap_unload(sc->sc_dmat, data->map); 1482 bus_dmamap_unload(sc->sc_dmat, data->map);
1481 m_freem(data->m); 1483 m_freem(data->m);
1482 } 1484 }
1483 if (data->map != NULL) 1485 if (data->map != NULL)
1484 bus_dmamap_destroy(sc->sc_dmat, data->map); 1486 bus_dmamap_destroy(sc->sc_dmat, data->map);
1485 } 1487 }
1486} 1488}
1487 1489
1488static void 1490static void
1489iwn5000_ict_reset(struct iwn_softc *sc) 1491iwn5000_ict_reset(struct iwn_softc *sc)
1490{ 1492{
1491 /* Disable interrupts. */ 1493 /* Disable interrupts. */
1492 IWN_WRITE(sc, IWN_INT_MASK, 0); 1494 IWN_WRITE(sc, IWN_INT_MASK, 0);
1493 1495
1494 /* Reset ICT table. */ 1496 /* Reset ICT table. */
1495 memset(sc->ict, 0, IWN_ICT_SIZE); 1497 memset(sc->ict, 0, IWN_ICT_SIZE);
1496 bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map, 0, IWN_ICT_SIZE, 1498 bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map, 0, IWN_ICT_SIZE,
1497 BUS_DMASYNC_PREWRITE); 1499 BUS_DMASYNC_PREWRITE);
1498 sc->ict_cur = 0; 1500 sc->ict_cur = 0;
1499 1501
1500 /* Set physical address of ICT table (4KB aligned). */ 1502 /* Set physical address of ICT table (4KB aligned). */
1501 DPRINTF(("enabling ICT\n")); 1503 DPRINTF(("enabling ICT\n"));
1502 IWN_WRITE(sc, IWN_DRAM_INT_TBL, IWN_DRAM_INT_TBL_ENABLE | 1504 IWN_WRITE(sc, IWN_DRAM_INT_TBL, IWN_DRAM_INT_TBL_ENABLE |
1503 IWN_DRAM_INT_TBL_WRAP_CHECK | sc->ict_dma.paddr >> 12); 1505 IWN_DRAM_INT_TBL_WRAP_CHECK | sc->ict_dma.paddr >> 12);
1504 1506
1505 /* Enable periodic RX interrupt. */ 1507 /* Enable periodic RX interrupt. */
1506 sc->int_mask |= IWN_INT_RX_PERIODIC; 1508 sc->int_mask |= IWN_INT_RX_PERIODIC;
1507 /* Switch to ICT interrupt mode in driver. */ 1509 /* Switch to ICT interrupt mode in driver. */
1508 sc->sc_flags |= IWN_FLAG_USE_ICT; 1510 sc->sc_flags |= IWN_FLAG_USE_ICT;
1509 1511
1510 /* Re-enable interrupts. */ 1512 /* Re-enable interrupts. */
1511 IWN_WRITE(sc, IWN_INT, 0xffffffff); 1513 IWN_WRITE(sc, IWN_INT, 0xffffffff);
1512 IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask); 1514 IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
1513} 1515}
1514 1516
1515static int 1517static int
1516iwn_read_eeprom(struct iwn_softc *sc) 1518iwn_read_eeprom(struct iwn_softc *sc)
1517{ 1519{
1518 struct iwn_ops *ops = &sc->ops; 1520 struct iwn_ops *ops = &sc->ops;
1519 struct ieee80211com *ic = &sc->sc_ic; 1521 struct ieee80211com *ic = &sc->sc_ic;
1520 uint16_t val; 1522 uint16_t val;
1521 int error; 1523 int error;
1522 1524
1523 /* Check whether adapter has an EEPROM or an OTPROM. */ 1525 /* Check whether adapter has an EEPROM or an OTPROM. */
1524 if (sc->hw_type >= IWN_HW_REV_TYPE_1000 && 1526 if (sc->hw_type >= IWN_HW_REV_TYPE_1000 &&
1525 (IWN_READ(sc, IWN_OTP_GP) & IWN_OTP_GP_DEV_SEL_OTP)) 1527 (IWN_READ(sc, IWN_OTP_GP) & IWN_OTP_GP_DEV_SEL_OTP))
1526 sc->sc_flags |= IWN_FLAG_HAS_OTPROM; 1528 sc->sc_flags |= IWN_FLAG_HAS_OTPROM;
1527 DPRINTF(("%s found\n", (sc->sc_flags & IWN_FLAG_HAS_OTPROM) ? 1529 DPRINTF(("%s found\n", (sc->sc_flags & IWN_FLAG_HAS_OTPROM) ?
1528 "OTPROM" : "EEPROM")); 1530 "OTPROM" : "EEPROM"));
1529 1531
1530 /* Adapter has to be powered on for EEPROM access to work. */ 1532 /* Adapter has to be powered on for EEPROM access to work. */
1531 if ((error = iwn_apm_init(sc)) != 0) { 1533 if ((error = iwn_apm_init(sc)) != 0) {
1532 aprint_error_dev(sc->sc_dev, 1534 aprint_error_dev(sc->sc_dev,
1533 "could not power ON adapter\n"); 1535 "could not power ON adapter\n");
1534 return error; 1536 return error;
1535 } 1537 }
1536 1538
1537 if ((IWN_READ(sc, IWN_EEPROM_GP) & 0x7) == 0) { 1539 if ((IWN_READ(sc, IWN_EEPROM_GP) & 0x7) == 0) {
1538 aprint_error_dev(sc->sc_dev, 1540 aprint_error_dev(sc->sc_dev,
1539 "bad ROM signature\n"); 1541 "bad ROM signature\n");
1540 return EIO; 1542 return EIO;
1541 } 1543 }
1542 if ((error = iwn_eeprom_lock(sc)) != 0) { 1544 if ((error = iwn_eeprom_lock(sc)) != 0) {
1543 aprint_error_dev(sc->sc_dev, 1545 aprint_error_dev(sc->sc_dev,
1544 "could not lock ROM (error=%d)\n", error); 1546 "could not lock ROM (error=%d)\n", error);
1545 return error; 1547 return error;
1546 } 1548 }
1547 if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) { 1549 if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) {
1548 if ((error = iwn_init_otprom(sc)) != 0) { 1550 if ((error = iwn_init_otprom(sc)) != 0) {
1549 aprint_error_dev(sc->sc_dev, 1551 aprint_error_dev(sc->sc_dev,
1550 "could not initialize OTPROM\n"); 1552 "could not initialize OTPROM\n");
1551 return error; 1553 return error;
1552 } 1554 }
1553 } 1555 }
1554 1556
1555 iwn_read_prom_data(sc, IWN_EEPROM_SKU_CAP, &val, 2); 1557 iwn_read_prom_data(sc, IWN_EEPROM_SKU_CAP, &val, 2);
1556 DPRINTF(("SKU capabilities=0x%04x\n", le16toh(val))); 1558 DPRINTF(("SKU capabilities=0x%04x\n", le16toh(val)));
1557 /* Check if HT support is bonded out. */ 1559 /* Check if HT support is bonded out. */
1558 if (val & htole16(IWN_EEPROM_SKU_CAP_11N)) 1560 if (val & htole16(IWN_EEPROM_SKU_CAP_11N))
1559 sc->sc_flags |= IWN_FLAG_HAS_11N; 1561 sc->sc_flags |= IWN_FLAG_HAS_11N;
1560 1562
1561 iwn_read_prom_data(sc, IWN_EEPROM_RFCFG, &val, 2); 1563 iwn_read_prom_data(sc, IWN_EEPROM_RFCFG, &val, 2);
1562 sc->rfcfg = le16toh(val); 1564 sc->rfcfg = le16toh(val);
1563 DPRINTF(("radio config=0x%04x\n", sc->rfcfg)); 1565 DPRINTF(("radio config=0x%04x\n", sc->rfcfg));
1564 /* Read Tx/Rx chains from ROM unless it's known to be broken. */ 1566 /* Read Tx/Rx chains from ROM unless it's known to be broken. */
1565 if (sc->txchainmask == 0) 1567 if (sc->txchainmask == 0)
1566 sc->txchainmask = IWN_RFCFG_TXANTMSK(sc->rfcfg); 1568 sc->txchainmask = IWN_RFCFG_TXANTMSK(sc->rfcfg);
1567 if (sc->rxchainmask == 0) 1569 if (sc->rxchainmask == 0)
1568 sc->rxchainmask = IWN_RFCFG_RXANTMSK(sc->rfcfg); 1570 sc->rxchainmask = IWN_RFCFG_RXANTMSK(sc->rfcfg);
1569 1571
1570 /* Read MAC address. */ 1572 /* Read MAC address. */
1571 iwn_read_prom_data(sc, IWN_EEPROM_MAC, ic->ic_myaddr, 6); 1573 iwn_read_prom_data(sc, IWN_EEPROM_MAC, ic->ic_myaddr, 6);
1572 1574
1573 /* Read adapter-specific information from EEPROM. */ 1575 /* Read adapter-specific information from EEPROM. */
1574 ops->read_eeprom(sc); 1576 ops->read_eeprom(sc);
1575 1577
1576 iwn_apm_stop(sc); /* Power OFF adapter. */ 1578 iwn_apm_stop(sc); /* Power OFF adapter. */
1577 1579
1578 iwn_eeprom_unlock(sc); 1580 iwn_eeprom_unlock(sc);
1579 return 0; 1581 return 0;
1580} 1582}
1581 1583
1582static void 1584static void
1583iwn4965_read_eeprom(struct iwn_softc *sc) 1585iwn4965_read_eeprom(struct iwn_softc *sc)
1584{ 1586{
1585 uint32_t addr; 1587 uint32_t addr;
1586 uint16_t val; 1588 uint16_t val;
1587 int i; 1589 int i;
1588 1590
1589 /* Read regulatory domain (4 ASCII characters). */ 1591 /* Read regulatory domain (4 ASCII characters). */
1590 iwn_read_prom_data(sc, IWN4965_EEPROM_DOMAIN, sc->eeprom_domain, 4); 1592 iwn_read_prom_data(sc, IWN4965_EEPROM_DOMAIN, sc->eeprom_domain, 4);
1591 1593
1592 /* Read the list of authorized channels (20MHz ones only). */ 1594 /* Read the list of authorized channels (20MHz ones only). */
1593 for (i = 0; i < 5; i++) { 1595 for (i = 0; i < 5; i++) {
1594 addr = iwn4965_regulatory_bands[i]; 1596 addr = iwn4965_regulatory_bands[i];
1595 iwn_read_eeprom_channels(sc, i, addr); 1597 iwn_read_eeprom_channels(sc, i, addr);
1596 } 1598 }
1597 1599
1598 /* Read maximum allowed TX power for 2GHz and 5GHz bands. */ 1600 /* Read maximum allowed TX power for 2GHz and 5GHz bands. */
1599 iwn_read_prom_data(sc, IWN4965_EEPROM_MAXPOW, &val, 2); 1601 iwn_read_prom_data(sc, IWN4965_EEPROM_MAXPOW, &val, 2);
1600 sc->maxpwr2GHz = val & 0xff; 1602 sc->maxpwr2GHz = val & 0xff;
1601 sc->maxpwr5GHz = val >> 8; 1603 sc->maxpwr5GHz = val >> 8;
1602 /* Check that EEPROM values are within valid range. */ 1604 /* Check that EEPROM values are within valid range. */
1603 if (sc->maxpwr5GHz < 20 || sc->maxpwr5GHz > 50) 1605 if (sc->maxpwr5GHz < 20 || sc->maxpwr5GHz > 50)
1604 sc->maxpwr5GHz = 38; 1606 sc->maxpwr5GHz = 38;
1605 if (sc->maxpwr2GHz < 20 || sc->maxpwr2GHz > 50) 1607 if (sc->maxpwr2GHz < 20 || sc->maxpwr2GHz > 50)
1606 sc->maxpwr2GHz = 38; 1608 sc->maxpwr2GHz = 38;
1607 DPRINTF(("maxpwr 2GHz=%d 5GHz=%d\n", sc->maxpwr2GHz, sc->maxpwr5GHz)); 1609 DPRINTF(("maxpwr 2GHz=%d 5GHz=%d\n", sc->maxpwr2GHz, sc->maxpwr5GHz));
1608 1610
1609 /* Read samples for each TX power group. */ 1611 /* Read samples for each TX power group. */
1610 iwn_read_prom_data(sc, IWN4965_EEPROM_BANDS, sc->bands, 1612 iwn_read_prom_data(sc, IWN4965_EEPROM_BANDS, sc->bands,
1611 sizeof sc->bands); 1613 sizeof sc->bands);
1612 1614
1613 /* Read voltage at which samples were taken. */ 1615 /* Read voltage at which samples were taken. */
1614 iwn_read_prom_data(sc, IWN4965_EEPROM_VOLTAGE, &val, 2); 1616 iwn_read_prom_data(sc, IWN4965_EEPROM_VOLTAGE, &val, 2);
1615 sc->eeprom_voltage = (int16_t)le16toh(val); 1617 sc->eeprom_voltage = (int16_t)le16toh(val);
1616 DPRINTF(("voltage=%d (in 0.3V)\n", sc->eeprom_voltage)); 1618 DPRINTF(("voltage=%d (in 0.3V)\n", sc->eeprom_voltage));
1617 1619
1618#ifdef IWN_DEBUG 1620#ifdef IWN_DEBUG
1619 /* Print samples. */ 1621 /* Print samples. */
1620 if (iwn_debug > 0) { 1622 if (iwn_debug > 0) {
1621 for (i = 0; i < IWN_NBANDS; i++) 1623 for (i = 0; i < IWN_NBANDS; i++)
1622 iwn4965_print_power_group(sc, i); 1624 iwn4965_print_power_group(sc, i);
1623 } 1625 }
1624#endif 1626#endif
1625} 1627}
1626 1628
1627#ifdef IWN_DEBUG 1629#ifdef IWN_DEBUG
1628static void 1630static void
1629iwn4965_print_power_group(struct iwn_softc *sc, int i) 1631iwn4965_print_power_group(struct iwn_softc *sc, int i)
1630{ 1632{
1631 struct iwn4965_eeprom_band *band = &sc->bands[i]; 1633 struct iwn4965_eeprom_band *band = &sc->bands[i];
1632 struct iwn4965_eeprom_chan_samples *chans = band->chans; 1634 struct iwn4965_eeprom_chan_samples *chans = band->chans;
1633 int j, c; 1635 int j, c;
1634 1636
1635 aprint_normal("===band %d===\n", i); 1637 aprint_normal("===band %d===\n", i);
1636 aprint_normal("chan lo=%d, chan hi=%d\n", band->lo, band->hi); 1638 aprint_normal("chan lo=%d, chan hi=%d\n", band->lo, band->hi);
1637 aprint_normal("chan1 num=%d\n", chans[0].num); 1639 aprint_normal("chan1 num=%d\n", chans[0].num);
1638 for (c = 0; c < 2; c++) { 1640 for (c = 0; c < 2; c++) {
1639 for (j = 0; j < IWN_NSAMPLES; j++) { 1641 for (j = 0; j < IWN_NSAMPLES; j++) {
1640 aprint_normal("chain %d, sample %d: temp=%d gain=%d " 1642 aprint_normal("chain %d, sample %d: temp=%d gain=%d "
1641 "power=%d pa_det=%d\n", c, j, 1643 "power=%d pa_det=%d\n", c, j,
1642 chans[0].samples[c][j].temp, 1644 chans[0].samples[c][j].temp,
1643 chans[0].samples[c][j].gain, 1645 chans[0].samples[c][j].gain,
1644 chans[0].samples[c][j].power, 1646 chans[0].samples[c][j].power,
1645 chans[0].samples[c][j].pa_det); 1647 chans[0].samples[c][j].pa_det);
1646 } 1648 }
1647 } 1649 }
1648 aprint_normal("chan2 num=%d\n", chans[1].num); 1650 aprint_normal("chan2 num=%d\n", chans[1].num);
1649 for (c = 0; c < 2; c++) { 1651 for (c = 0; c < 2; c++) {
1650 for (j = 0; j < IWN_NSAMPLES; j++) { 1652 for (j = 0; j < IWN_NSAMPLES; j++) {
1651 aprint_normal("chain %d, sample %d: temp=%d gain=%d " 1653 aprint_normal("chain %d, sample %d: temp=%d gain=%d "
1652 "power=%d pa_det=%d\n", c, j, 1654 "power=%d pa_det=%d\n", c, j,
1653 chans[1].samples[c][j].temp, 1655 chans[1].samples[c][j].temp,
1654 chans[1].samples[c][j].gain, 1656 chans[1].samples[c][j].gain,
1655 chans[1].samples[c][j].power, 1657 chans[1].samples[c][j].power,
1656 chans[1].samples[c][j].pa_det); 1658 chans[1].samples[c][j].pa_det);
1657 } 1659 }
1658 } 1660 }
1659} 1661}
1660#endif 1662#endif
1661 1663
1662static void 1664static void
1663iwn5000_read_eeprom(struct iwn_softc *sc) 1665iwn5000_read_eeprom(struct iwn_softc *sc)
1664{ 1666{
1665 struct iwn5000_eeprom_calib_hdr hdr; 1667 struct iwn5000_eeprom_calib_hdr hdr;
1666 int32_t volt; 1668 int32_t volt;
1667 uint32_t base, addr; 1669 uint32_t base, addr;
1668 uint16_t val; 1670 uint16_t val;
1669 int i; 1671 int i;
1670 1672
1671 /* Read regulatory domain (4 ASCII characters). */ 1673 /* Read regulatory domain (4 ASCII characters). */
1672 iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2); 1674 iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
1673 base = le16toh(val); 1675 base = le16toh(val);
1674 iwn_read_prom_data(sc, base + IWN5000_EEPROM_DOMAIN, 1676 iwn_read_prom_data(sc, base + IWN5000_EEPROM_DOMAIN,
1675 sc->eeprom_domain, 4); 1677 sc->eeprom_domain, 4);
1676 1678
1677 /* Read the list of authorized channels (20MHz ones only). */ 1679 /* Read the list of authorized channels (20MHz ones only). */
1678 for (i = 0; i < 5; i++) { 1680 for (i = 0; i < 5; i++) {
1679 addr = base + iwn5000_regulatory_bands[i]; 1681 addr = base + iwn5000_regulatory_bands[i];
1680 iwn_read_eeprom_channels(sc, i, addr); 1682 iwn_read_eeprom_channels(sc, i, addr);
1681 } 1683 }
1682 1684
1683 /* Read enhanced TX power information for 6000 Series. */ 1685 /* Read enhanced TX power information for 6000 Series. */
1684 if (sc->hw_type >= IWN_HW_REV_TYPE_6000) 1686 if (sc->hw_type >= IWN_HW_REV_TYPE_6000)
1685 iwn_read_eeprom_enhinfo(sc); 1687 iwn_read_eeprom_enhinfo(sc);
1686 1688
1687 iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2); 1689 iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2);
1688 base = le16toh(val); 1690 base = le16toh(val);
1689 iwn_read_prom_data(sc, base, &hdr, sizeof hdr); 1691 iwn_read_prom_data(sc, base, &hdr, sizeof hdr);
1690 DPRINTF(("calib version=%u pa type=%u voltage=%u\n", 1692 DPRINTF(("calib version=%u pa type=%u voltage=%u\n",
1691 hdr.version, hdr.pa_type, le16toh(hdr.volt))); 1693 hdr.version, hdr.pa_type, le16toh(hdr.volt)));
1692 sc->calib_ver = hdr.version; 1694 sc->calib_ver = hdr.version;
1693 1695
1694 if (sc->hw_type == IWN_HW_REV_TYPE_2030 || 1696 if (sc->hw_type == IWN_HW_REV_TYPE_2030 ||
1695 sc->hw_type == IWN_HW_REV_TYPE_2000 || 1697 sc->hw_type == IWN_HW_REV_TYPE_2000 ||
1696 sc->hw_type == IWN_HW_REV_TYPE_135 || 1698 sc->hw_type == IWN_HW_REV_TYPE_135 ||
1697 sc->hw_type == IWN_HW_REV_TYPE_105) { 1699 sc->hw_type == IWN_HW_REV_TYPE_105) {
1698 sc->eeprom_voltage = le16toh(hdr.volt); 1700 sc->eeprom_voltage = le16toh(hdr.volt);
1699 iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2); 1701 iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
1700 sc->eeprom_temp = le16toh(val); 1702 sc->eeprom_temp = le16toh(val);
1701 iwn_read_prom_data(sc, base + IWN2000_EEPROM_RAWTEMP, &val, 2); 1703 iwn_read_prom_data(sc, base + IWN2000_EEPROM_RAWTEMP, &val, 2);
1702 sc->eeprom_rawtemp = le16toh(val); 1704 sc->eeprom_rawtemp = le16toh(val);
1703 } 1705 }
1704 1706
1705 if (sc->hw_type == IWN_HW_REV_TYPE_5150) { 1707 if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
1706 /* Compute temperature offset. */ 1708 /* Compute temperature offset. */
1707 iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2); 1709 iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
1708 sc->eeprom_temp = le16toh(val); 1710 sc->eeprom_temp = le16toh(val);
1709 iwn_read_prom_data(sc, base + IWN5000_EEPROM_VOLT, &val, 2); 1711 iwn_read_prom_data(sc, base + IWN5000_EEPROM_VOLT, &val, 2);
1710 volt = le16toh(val); 1712 volt = le16toh(val);
1711 sc->temp_off = sc->eeprom_temp - (volt / -5); 1713 sc->temp_off = sc->eeprom_temp - (volt / -5);
1712 DPRINTF(("temp=%d volt=%d offset=%dK\n", 1714 DPRINTF(("temp=%d volt=%d offset=%dK\n",
1713 sc->eeprom_temp, volt, sc->temp_off)); 1715 sc->eeprom_temp, volt, sc->temp_off));
1714 } else { 1716 } else {
1715 /* Read crystal calibration. */ 1717 /* Read crystal calibration. */
1716 iwn_read_prom_data(sc, base + IWN5000_EEPROM_CRYSTAL, 1718 iwn_read_prom_data(sc, base + IWN5000_EEPROM_CRYSTAL,
1717 &sc->eeprom_crystal, sizeof (uint32_t)); 1719 &sc->eeprom_crystal, sizeof (uint32_t));
1718 DPRINTF(("crystal calibration 0x%08x\n", 1720 DPRINTF(("crystal calibration 0x%08x\n",
1719 le32toh(sc->eeprom_crystal))); 1721 le32toh(sc->eeprom_crystal)));
1720 } 1722 }
1721} 1723}
1722 1724
1723static void 1725static void
1724iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr) 1726iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
1725{ 1727{
1726 struct ieee80211com *ic = &sc->sc_ic; 1728 struct ieee80211com *ic = &sc->sc_ic;
1727 const struct iwn_chan_band *band = &iwn_bands[n]; 1729 const struct iwn_chan_band *band = &iwn_bands[n];
1728 struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND]; 1730 struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
1729 uint8_t chan; 1731 uint8_t chan;
1730 int i; 1732 int i;
1731 1733
1732 iwn_read_prom_data(sc, addr, channels, 1734 iwn_read_prom_data(sc, addr, channels,
1733 band->nchan * sizeof (struct iwn_eeprom_chan)); 1735 band->nchan * sizeof (struct iwn_eeprom_chan));
1734 1736
1735 for (i = 0; i < band->nchan; i++) { 1737 for (i = 0; i < band->nchan; i++) {
1736 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) 1738 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID))
1737 continue; 1739 continue;
1738 1740
1739 chan = band->chan[i]; 1741 chan = band->chan[i];
1740 1742
1741 if (n == 0) { /* 2GHz band */ 1743 if (n == 0) { /* 2GHz band */
1742 ic->ic_channels[chan].ic_freq = 1744 ic->ic_channels[chan].ic_freq =
1743 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ); 1745 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
1744 ic->ic_channels[chan].ic_flags = 1746 ic->ic_channels[chan].ic_flags =
1745 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | 1747 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
1746 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; 1748 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
1747 1749
1748 } else { /* 5GHz band */ 1750 } else { /* 5GHz band */
1749 /* 1751 /*
1750 * Some adapters support channels 7, 8, 11 and 12 1752 * Some adapters support channels 7, 8, 11 and 12
1751 * both in the 2GHz and 4.9GHz bands. 1753 * both in the 2GHz and 4.9GHz bands.
1752 * Because of limitations in our net80211 layer, 1754 * Because of limitations in our net80211 layer,
1753 * we don't support them in the 4.9GHz band. 1755 * we don't support them in the 4.9GHz band.
1754 */ 1756 */
1755 if (chan <= 14) 1757 if (chan <= 14)
1756 continue; 1758 continue;
1757 1759
1758 ic->ic_channels[chan].ic_freq = 1760 ic->ic_channels[chan].ic_freq =
1759 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ); 1761 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ);
1760 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A; 1762 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A;
1761 /* We have at least one valid 5GHz channel. */ 1763 /* We have at least one valid 5GHz channel. */
1762 sc->sc_flags |= IWN_FLAG_HAS_5GHZ; 1764 sc->sc_flags |= IWN_FLAG_HAS_5GHZ;
1763 } 1765 }
1764 1766
1765 /* Is active scan allowed on this channel? */ 1767 /* Is active scan allowed on this channel? */
1766 if (!(channels[i].flags & IWN_EEPROM_CHAN_ACTIVE)) { 1768 if (!(channels[i].flags & IWN_EEPROM_CHAN_ACTIVE)) {
1767 ic->ic_channels[chan].ic_flags |= 1769 ic->ic_channels[chan].ic_flags |=
1768 IEEE80211_CHAN_PASSIVE; 1770 IEEE80211_CHAN_PASSIVE;
1769 } 1771 }
1770 1772
1771 /* Save maximum allowed TX power for this channel. */ 1773 /* Save maximum allowed TX power for this channel. */
1772 sc->maxpwr[chan] = channels[i].maxpwr; 1774 sc->maxpwr[chan] = channels[i].maxpwr;
1773 1775
1774 DPRINTF(("adding chan %d flags=0x%x maxpwr=%d\n", 1776 DPRINTF(("adding chan %d flags=0x%x maxpwr=%d\n",
1775 chan, channels[i].flags, sc->maxpwr[chan])); 1777 chan, channels[i].flags, sc->maxpwr[chan]));
1776 } 1778 }