Deleted Added
full compact
if_iwn.c (198439) if_iwn.c (201209)
1/*-
2 * Copyright (c) 2007-2009
3 * Damien Bergamini <damien.bergamini@free.fr>
4 * Copyright (c) 2008
5 * Benjamin Close <benjsc@FreeBSD.org>
6 * Copyright (c) 2008 Sam Leffler, Errno Consulting
7 *
8 * Permission to use, copy, modify, and distribute this software for any

--- 5 unchanged lines hidden (view full) ---

14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21/*
1/*-
2 * Copyright (c) 2007-2009
3 * Damien Bergamini <damien.bergamini@free.fr>
4 * Copyright (c) 2008
5 * Benjamin Close <benjsc@FreeBSD.org>
6 * Copyright (c) 2008 Sam Leffler, Errno Consulting
7 *
8 * Permission to use, copy, modify, and distribute this software for any

--- 5 unchanged lines hidden (view full) ---

14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21/*
22 * Driver for Intel Wireless WiFi Link 4965 and Intel WiFi Link 5000 Series
23 * 802.11 network adapters.
22 * Driver for Intel WiFi Link 4965 and 1000/5000/6000 Series 802.11 network
23 * adapters.
24 */
25
26#include <sys/cdefs.h>
24 */
25
26#include <sys/cdefs.h>
27__FBSDID("$FreeBSD: head/sys/dev/iwn/if_iwn.c 198439 2009-10-24 09:55:11Z rpaulo $");
27__FBSDID("$FreeBSD: head/sys/dev/iwn/if_iwn.c 201209 2009-12-29 19:47:34Z rpaulo $");
28
29#include <sys/param.h>
30#include <sys/sockio.h>
31#include <sys/sysctl.h>
32#include <sys/mbuf.h>
33#include <sys/kernel.h>
34#include <sys/socket.h>
35#include <sys/systm.h>

--- 53 unchanged lines hidden (view full) ---

89int iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
90static int iwn_dma_contig_alloc(struct iwn_softc *, struct iwn_dma_info *,
91 void **, bus_size_t, bus_size_t, int);
92static void iwn_dma_contig_free(struct iwn_dma_info *);
93int iwn_alloc_sched(struct iwn_softc *);
94void iwn_free_sched(struct iwn_softc *);
95int iwn_alloc_kw(struct iwn_softc *);
96void iwn_free_kw(struct iwn_softc *);
28
29#include <sys/param.h>
30#include <sys/sockio.h>
31#include <sys/sysctl.h>
32#include <sys/mbuf.h>
33#include <sys/kernel.h>
34#include <sys/socket.h>
35#include <sys/systm.h>

--- 53 unchanged lines hidden (view full) ---

89int iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
90static int iwn_dma_contig_alloc(struct iwn_softc *, struct iwn_dma_info *,
91 void **, bus_size_t, bus_size_t, int);
92static void iwn_dma_contig_free(struct iwn_dma_info *);
93int iwn_alloc_sched(struct iwn_softc *);
94void iwn_free_sched(struct iwn_softc *);
95int iwn_alloc_kw(struct iwn_softc *);
96void iwn_free_kw(struct iwn_softc *);
97int iwn_alloc_ict(struct iwn_softc *);
98void iwn_free_ict(struct iwn_softc *);
97int iwn_alloc_fwmem(struct iwn_softc *);
98void iwn_free_fwmem(struct iwn_softc *);
99int iwn_alloc_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
100void iwn_reset_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
101void iwn_free_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
102int iwn_alloc_tx_ring(struct iwn_softc *, struct iwn_tx_ring *,
103 int);
104void iwn_reset_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
105void iwn_free_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
99int iwn_alloc_fwmem(struct iwn_softc *);
100void iwn_free_fwmem(struct iwn_softc *);
101int iwn_alloc_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
102void iwn_reset_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
103void iwn_free_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
104int iwn_alloc_tx_ring(struct iwn_softc *, struct iwn_tx_ring *,
105 int);
106void iwn_reset_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
107void iwn_free_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
108void iwn5000_ict_reset(struct iwn_softc *);
106int iwn_read_eeprom(struct iwn_softc *,
107 uint8_t macaddr[IEEE80211_ADDR_LEN]);
108void iwn4965_read_eeprom(struct iwn_softc *);
109void iwn4965_print_power_group(struct iwn_softc *, int);
110void iwn5000_read_eeprom(struct iwn_softc *);
109int iwn_read_eeprom(struct iwn_softc *,
110 uint8_t macaddr[IEEE80211_ADDR_LEN]);
111void iwn4965_read_eeprom(struct iwn_softc *);
112void iwn4965_print_power_group(struct iwn_softc *, int);
113void iwn5000_read_eeprom(struct iwn_softc *);
111static void iwn_read_eeprom_channels(struct iwn_softc *, uint32_t, int);
114static void iwn_read_eeprom_channels(struct iwn_softc *, int,
115 uint32_t);
116void iwn_read_eeprom_enhinfo(struct iwn_softc *);
112struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
113 const uint8_t mac[IEEE80211_ADDR_LEN]);
114void iwn_newassoc(struct ieee80211_node *, int);
115int iwn_media_change(struct ifnet *);
116int iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
117void iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *,
118 struct iwn_rx_data *);
119static void iwn_timer_timeout(void *);
120static void iwn_calib_reset(struct iwn_softc *);
121void iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *,
122 struct iwn_rx_data *);
117struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
118 const uint8_t mac[IEEE80211_ADDR_LEN]);
119void iwn_newassoc(struct ieee80211_node *, int);
120int iwn_media_change(struct ifnet *);
121int iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
122void iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *,
123 struct iwn_rx_data *);
124static void iwn_timer_timeout(void *);
125static void iwn_calib_reset(struct iwn_softc *);
126void iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *,
127 struct iwn_rx_data *);
128#if 0 /* HT */
129void iwn_rx_compressed_ba(struct iwn_softc *, struct iwn_rx_desc *,
130 struct iwn_rx_data *);
131#endif
123void iwn5000_rx_calib_results(struct iwn_softc *,
124 struct iwn_rx_desc *, struct iwn_rx_data *);
125void iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *,
126 struct iwn_rx_data *);
127void iwn4965_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
128 struct iwn_rx_data *);
129void iwn5000_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
130 struct iwn_rx_data *);
131void iwn_tx_done(struct iwn_softc *, struct iwn_rx_desc *, int,
132 uint8_t);
133void iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *);
134void iwn_notif_intr(struct iwn_softc *);
135void iwn_wakeup_intr(struct iwn_softc *);
136void iwn_rftoggle_intr(struct iwn_softc *);
132void iwn5000_rx_calib_results(struct iwn_softc *,
133 struct iwn_rx_desc *, struct iwn_rx_data *);
134void iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *,
135 struct iwn_rx_data *);
136void iwn4965_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
137 struct iwn_rx_data *);
138void iwn5000_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
139 struct iwn_rx_data *);
140void iwn_tx_done(struct iwn_softc *, struct iwn_rx_desc *, int,
141 uint8_t);
142void iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *);
143void iwn_notif_intr(struct iwn_softc *);
144void iwn_wakeup_intr(struct iwn_softc *);
145void iwn_rftoggle_intr(struct iwn_softc *);
137void iwn_fatal_intr(struct iwn_softc *, uint32_t, uint32_t);
146void iwn_fatal_intr(struct iwn_softc *);
138void iwn_intr(void *);
139void iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t,
140 uint16_t);
141void iwn5000_update_sched(struct iwn_softc *, int, int, uint8_t,
142 uint16_t);
143void iwn5000_reset_sched(struct iwn_softc *, int, int);
144int iwn_tx_data(struct iwn_softc *, struct mbuf *,
145 struct ieee80211_node *, struct iwn_tx_ring *);
146static int iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
147 const struct ieee80211_bpf_params *);
148void iwn_start(struct ifnet *);
149void iwn_start_locked(struct ifnet *);
150static void iwn_watchdog(struct iwn_softc *sc);
151int iwn_ioctl(struct ifnet *, u_long, caddr_t);
152int iwn_cmd(struct iwn_softc *, int, const void *, int, int);
153int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
154 int);
155int iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *,
156 int);
147void iwn_intr(void *);
148void iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t,
149 uint16_t);
150void iwn5000_update_sched(struct iwn_softc *, int, int, uint8_t,
151 uint16_t);
152void iwn5000_reset_sched(struct iwn_softc *, int, int);
153int iwn_tx_data(struct iwn_softc *, struct mbuf *,
154 struct ieee80211_node *, struct iwn_tx_ring *);
155static int iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
156 const struct ieee80211_bpf_params *);
157void iwn_start(struct ifnet *);
158void iwn_start_locked(struct ifnet *);
159static void iwn_watchdog(struct iwn_softc *sc);
160int iwn_ioctl(struct ifnet *, u_long, caddr_t);
161int iwn_cmd(struct iwn_softc *, int, const void *, int, int);
162int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
163 int);
164int iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *,
165 int);
157int iwn_set_link_quality(struct iwn_softc *, uint8_t,
158 const struct ieee80211_channel *, int);
159int iwn_add_broadcast_node(struct iwn_softc *,
160 const struct ieee80211_channel *, int);
166int iwn_set_link_quality(struct iwn_softc *, uint8_t, int);
167int iwn_add_broadcast_node(struct iwn_softc *, int);
161int iwn_wme_update(struct ieee80211com *);
168int iwn_wme_update(struct ieee80211com *);
169static void iwn_update_mcast(struct ifnet *);
162void iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
163int iwn_set_critical_temp(struct iwn_softc *);
164int iwn_set_timing(struct iwn_softc *, struct ieee80211_node *);
165void iwn4965_power_calibration(struct iwn_softc *, int);
170void iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
171int iwn_set_critical_temp(struct iwn_softc *);
172int iwn_set_timing(struct iwn_softc *, struct ieee80211_node *);
173void iwn4965_power_calibration(struct iwn_softc *, int);
166int iwn4965_set_txpower(struct iwn_softc *,
167 struct ieee80211_channel *, int);
168int iwn5000_set_txpower(struct iwn_softc *,
169 struct ieee80211_channel *, int);
174int iwn4965_set_txpower(struct iwn_softc *, int);
175int iwn5000_set_txpower(struct iwn_softc *, int);
170int iwn4965_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
171int iwn5000_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
172int iwn_get_noise(const struct iwn_rx_general_stats *);
173int iwn4965_get_temperature(struct iwn_softc *);
174int iwn5000_get_temperature(struct iwn_softc *);
175int iwn_init_sensitivity(struct iwn_softc *);
176void iwn_collect_noise(struct iwn_softc *,
177 const struct iwn_rx_general_stats *);

--- 6 unchanged lines hidden (view full) ---

184int iwn_send_sensitivity(struct iwn_softc *);
185int iwn_set_pslevel(struct iwn_softc *, int, int, int);
186int iwn_config(struct iwn_softc *);
187int iwn_scan(struct iwn_softc *);
188int iwn_auth(struct iwn_softc *, struct ieee80211vap *vap);
189int iwn_run(struct iwn_softc *, struct ieee80211vap *vap);
190int iwn5000_query_calibration(struct iwn_softc *);
191int iwn5000_send_calibration(struct iwn_softc *);
176int iwn4965_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
177int iwn5000_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
178int iwn_get_noise(const struct iwn_rx_general_stats *);
179int iwn4965_get_temperature(struct iwn_softc *);
180int iwn5000_get_temperature(struct iwn_softc *);
181int iwn_init_sensitivity(struct iwn_softc *);
182void iwn_collect_noise(struct iwn_softc *,
183 const struct iwn_rx_general_stats *);

--- 6 unchanged lines hidden (view full) ---

190int iwn_send_sensitivity(struct iwn_softc *);
191int iwn_set_pslevel(struct iwn_softc *, int, int, int);
192int iwn_config(struct iwn_softc *);
193int iwn_scan(struct iwn_softc *);
194int iwn_auth(struct iwn_softc *, struct ieee80211vap *vap);
195int iwn_run(struct iwn_softc *, struct ieee80211vap *vap);
196int iwn5000_query_calibration(struct iwn_softc *);
197int iwn5000_send_calibration(struct iwn_softc *);
198int iwn5000_send_wimax_coex(struct iwn_softc *);
192int iwn4965_post_alive(struct iwn_softc *);
193int iwn5000_post_alive(struct iwn_softc *);
194int iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *,
195 int);
196int iwn4965_load_firmware(struct iwn_softc *);
197int iwn5000_load_firmware_section(struct iwn_softc *, uint32_t,
198 const uint8_t *, int);
199int iwn5000_load_firmware(struct iwn_softc *);
200int iwn_read_firmware(struct iwn_softc *);
199int iwn4965_post_alive(struct iwn_softc *);
200int iwn5000_post_alive(struct iwn_softc *);
201int iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *,
202 int);
203int iwn4965_load_firmware(struct iwn_softc *);
204int iwn5000_load_firmware_section(struct iwn_softc *, uint32_t,
205 const uint8_t *, int);
206int iwn5000_load_firmware(struct iwn_softc *);
207int iwn_read_firmware(struct iwn_softc *);
201void iwn_unload_firmware(struct iwn_softc *);
202int iwn_clock_wait(struct iwn_softc *);
208int iwn_clock_wait(struct iwn_softc *);
203int iwn4965_apm_init(struct iwn_softc *);
204int iwn5000_apm_init(struct iwn_softc *);
209int iwn_apm_init(struct iwn_softc *);
205void iwn_apm_stop_master(struct iwn_softc *);
206void iwn_apm_stop(struct iwn_softc *);
207int iwn4965_nic_config(struct iwn_softc *);
208int iwn5000_nic_config(struct iwn_softc *);
210void iwn_apm_stop_master(struct iwn_softc *);
211void iwn_apm_stop(struct iwn_softc *);
212int iwn4965_nic_config(struct iwn_softc *);
213int iwn5000_nic_config(struct iwn_softc *);
209int iwn_hw_prepare(struct iwn_softc *sc);
214int iwn_hw_prepare(struct iwn_softc *);
210int iwn_hw_init(struct iwn_softc *);
211void iwn_hw_stop(struct iwn_softc *);
212void iwn_init_locked(struct iwn_softc *);
213void iwn_init(void *);
214void iwn_stop_locked(struct iwn_softc *);
215void iwn_stop(struct iwn_softc *);
216static void iwn_scan_start(struct ieee80211com *);
217static void iwn_scan_end(struct ieee80211com *);
218static void iwn_set_channel(struct ieee80211com *);
219static void iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long);
220static void iwn_scan_mindwell(struct ieee80211_scan_state *);
215int iwn_hw_init(struct iwn_softc *);
216void iwn_hw_stop(struct iwn_softc *);
217void iwn_init_locked(struct iwn_softc *);
218void iwn_init(void *);
219void iwn_stop_locked(struct iwn_softc *);
220void iwn_stop(struct iwn_softc *);
221static void iwn_scan_start(struct ieee80211com *);
222static void iwn_scan_end(struct ieee80211com *);
223static void iwn_set_channel(struct ieee80211com *);
224static void iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long);
225static void iwn_scan_mindwell(struct ieee80211_scan_state *);
226static int iwn_setregdomain(struct ieee80211com *,
227 struct ieee80211_regdomain *, int,
228 struct ieee80211_channel []);
221static void iwn_hw_reset(void *, int);
222static void iwn_radio_on(void *, int);
223static void iwn_radio_off(void *, int);
224static void iwn_sysctlattach(struct iwn_softc *);
225static int iwn_shutdown(device_t);
226static int iwn_suspend(device_t);
227static int iwn_resume(device_t);
228

--- 50 unchanged lines hidden (view full) ---

279 { 0x8086, 0x0083, "Intel(R) PRO/Wireless 1000" },
280 { 0x8086, 0x0084, "Intel(R) PRO/Wireless 1000" },
281 { 0x8086, 0x008D, "Intel(R) PRO/Wireless 6000" },
282 { 0x8086, 0x008E, "Intel(R) PRO/Wireless 6000" },
283 { 0x8086, 0x4238, "Intel(R) PRO/Wireless 6000" },
284 { 0x8086, 0x4239, "Intel(R) PRO/Wireless 6000" },
285 { 0x8086, 0x422B, "Intel(R) PRO/Wireless 6000" },
286 { 0x8086, 0x422C, "Intel(R) PRO/Wireless 6000" },
229static void iwn_hw_reset(void *, int);
230static void iwn_radio_on(void *, int);
231static void iwn_radio_off(void *, int);
232static void iwn_sysctlattach(struct iwn_softc *);
233static int iwn_shutdown(device_t);
234static int iwn_suspend(device_t);
235static int iwn_resume(device_t);
236

--- 50 unchanged lines hidden (view full) ---

287 { 0x8086, 0x0083, "Intel(R) PRO/Wireless 1000" },
288 { 0x8086, 0x0084, "Intel(R) PRO/Wireless 1000" },
289 { 0x8086, 0x008D, "Intel(R) PRO/Wireless 6000" },
290 { 0x8086, 0x008E, "Intel(R) PRO/Wireless 6000" },
291 { 0x8086, 0x4238, "Intel(R) PRO/Wireless 6000" },
292 { 0x8086, 0x4239, "Intel(R) PRO/Wireless 6000" },
293 { 0x8086, 0x422B, "Intel(R) PRO/Wireless 6000" },
294 { 0x8086, 0x422C, "Intel(R) PRO/Wireless 6000" },
295 { 0x8086, 0x0086, "Intel(R) PRO/Wireless 6050" },
296 { 0x8086, 0x0087, "Intel(R) PRO/Wireless 6050" },
287 { 0, 0, NULL }
288};
289
290static const struct iwn_hal iwn4965_hal = {
291 iwn4965_load_firmware,
292 iwn4965_read_eeprom,
293 iwn4965_post_alive,
297 { 0, 0, NULL }
298};
299
300static const struct iwn_hal iwn4965_hal = {
301 iwn4965_load_firmware,
302 iwn4965_read_eeprom,
303 iwn4965_post_alive,
294 iwn4965_apm_init,
295 iwn4965_nic_config,
296 iwn4965_update_sched,
297 iwn4965_get_temperature,
298 iwn4965_get_rssi,
299 iwn4965_set_txpower,
300 iwn4965_init_gains,
301 iwn4965_set_gains,
302 iwn4965_add_node,
303 iwn4965_tx_done,
304 iwn4965_nic_config,
305 iwn4965_update_sched,
306 iwn4965_get_temperature,
307 iwn4965_get_rssi,
308 iwn4965_set_txpower,
309 iwn4965_init_gains,
310 iwn4965_set_gains,
311 iwn4965_add_node,
312 iwn4965_tx_done,
304 &iwn4965_sensitivity_limits,
313#if 0 /* HT */
314 iwn4965_ampdu_tx_start,
315 iwn4965_ampdu_tx_stop,
316#endif
305 IWN4965_NTXQUEUES,
306 IWN4965_NDMACHNLS,
307 IWN4965_ID_BROADCAST,
308 IWN4965_RXONSZ,
309 IWN4965_SCHEDSZ,
310 IWN4965_FW_TEXT_MAXSZ,
311 IWN4965_FW_DATA_MAXSZ,
312 IWN4965_FWSZ,
317 IWN4965_NTXQUEUES,
318 IWN4965_NDMACHNLS,
319 IWN4965_ID_BROADCAST,
320 IWN4965_RXONSZ,
321 IWN4965_SCHEDSZ,
322 IWN4965_FW_TEXT_MAXSZ,
323 IWN4965_FW_DATA_MAXSZ,
324 IWN4965_FWSZ,
313 IWN4965_SCHED_TXFACT,
325 IWN4965_SCHED_TXFACT
314};
315
316static const struct iwn_hal iwn5000_hal = {
317 iwn5000_load_firmware,
318 iwn5000_read_eeprom,
319 iwn5000_post_alive,
326};
327
328static const struct iwn_hal iwn5000_hal = {
329 iwn5000_load_firmware,
330 iwn5000_read_eeprom,
331 iwn5000_post_alive,
320 iwn5000_apm_init,
321 iwn5000_nic_config,
322 iwn5000_update_sched,
323 iwn5000_get_temperature,
324 iwn5000_get_rssi,
325 iwn5000_set_txpower,
326 iwn5000_init_gains,
327 iwn5000_set_gains,
328 iwn5000_add_node,
329 iwn5000_tx_done,
332 iwn5000_nic_config,
333 iwn5000_update_sched,
334 iwn5000_get_temperature,
335 iwn5000_get_rssi,
336 iwn5000_set_txpower,
337 iwn5000_init_gains,
338 iwn5000_set_gains,
339 iwn5000_add_node,
340 iwn5000_tx_done,
330 &iwn5000_sensitivity_limits,
341#if 0 /* HT */
342 iwn5000_ampdu_tx_start,
343 iwn5000_ampdu_tx_stop,
344#endif
331 IWN5000_NTXQUEUES,
332 IWN5000_NDMACHNLS,
333 IWN5000_ID_BROADCAST,
334 IWN5000_RXONSZ,
335 IWN5000_SCHEDSZ,
336 IWN5000_FW_TEXT_MAXSZ,
337 IWN5000_FW_DATA_MAXSZ,
338 IWN5000_FWSZ,
345 IWN5000_NTXQUEUES,
346 IWN5000_NDMACHNLS,
347 IWN5000_ID_BROADCAST,
348 IWN5000_RXONSZ,
349 IWN5000_SCHEDSZ,
350 IWN5000_FW_TEXT_MAXSZ,
351 IWN5000_FW_DATA_MAXSZ,
352 IWN5000_FWSZ,
339 IWN5000_SCHED_TXFACT,
353 IWN5000_SCHED_TXFACT
340};
341
342static int
343iwn_probe(device_t dev)
344{
345 const struct iwn_ident *ident;
346
347 for (ident = iwn_ident_table; ident->name != NULL; ident++) {

--- 81 unchanged lines hidden (view full) ---

429 }
430
431 error = iwn_hw_prepare(sc);
432 if (error != 0) {
433 device_printf(dev, "hardware not ready, error %d\n", error);
434 goto fail;
435 }
436
354};
355
356static int
357iwn_probe(device_t dev)
358{
359 const struct iwn_ident *ident;
360
361 for (ident = iwn_ident_table; ident->name != NULL; ident++) {

--- 81 unchanged lines hidden (view full) ---

443 }
444
445 error = iwn_hw_prepare(sc);
446 if (error != 0) {
447 device_printf(dev, "hardware not ready, error %d\n", error);
448 goto fail;
449 }
450
437 /* Power ON adapter. */
438 error = hal->apm_init(sc);
439 if (error != 0) {
440 device_printf(dev, "could not power ON adapter, error %d\n",
441 error);
442 goto fail;
443 }
444
445 /* Allocate DMA memory for firmware transfers. */
446 error = iwn_alloc_fwmem(sc);
447 if (error != 0) {
448 device_printf(dev,
449 "could not allocate memory for firmware, error %d\n",
450 error);
451 goto fail;
452 }
453
454 /* Allocate "Keep Warm" page. */
455 error = iwn_alloc_kw(sc);
456 if (error != 0) {
457 device_printf(dev,
458 "could not allocate \"Keep Warm\" page, error %d\n", error);
459 goto fail;
460 }
461
451 /* Allocate DMA memory for firmware transfers. */
452 error = iwn_alloc_fwmem(sc);
453 if (error != 0) {
454 device_printf(dev,
455 "could not allocate memory for firmware, error %d\n",
456 error);
457 goto fail;
458 }
459
460 /* Allocate "Keep Warm" page. */
461 error = iwn_alloc_kw(sc);
462 if (error != 0) {
463 device_printf(dev,
464 "could not allocate \"Keep Warm\" page, error %d\n", error);
465 goto fail;
466 }
467
468 /* Allocate ICT table for 5000 Series. */
469 if (sc->hw_type != IWN_HW_REV_TYPE_4965 &&
470 (error = iwn_alloc_ict(sc)) != 0) {
471 device_printf(dev,
472 "%s: could not allocate ICT table, error %d\n",
473 __func__, error);
474 goto fail;
475 }
476
462 /* Allocate TX scheduler "rings". */
463 error = iwn_alloc_sched(sc);
464 if (error != 0) {
465 device_printf(dev,
466 "could not allocate TX scheduler rings, error %d\n",
467 error);
468 goto fail;
469 }

--- 15 unchanged lines hidden (view full) ---

485 device_printf(dev,
486 "could not allocate Rx ring, error %d\n", error);
487 goto fail;
488 }
489
490 /* Clear pending interrupts. */
491 IWN_WRITE(sc, IWN_INT, 0xffffffff);
492
477 /* Allocate TX scheduler "rings". */
478 error = iwn_alloc_sched(sc);
479 if (error != 0) {
480 device_printf(dev,
481 "could not allocate TX scheduler rings, error %d\n",
482 error);
483 goto fail;
484 }

--- 15 unchanged lines hidden (view full) ---

500 device_printf(dev,
501 "could not allocate Rx ring, error %d\n", error);
502 goto fail;
503 }
504
505 /* Clear pending interrupts. */
506 IWN_WRITE(sc, IWN_INT, 0xffffffff);
507
493 /* Initialization firmware has not been loaded yet. */
494 sc->sc_flags |= IWN_FLAG_FIRST_BOOT;
508 /* Count the number of available chains. */
509 sc->ntxchains =
510 ((sc->txchainmask >> 2) & 1) +
511 ((sc->txchainmask >> 1) & 1) +
512 ((sc->txchainmask >> 0) & 1);
513 sc->nrxchains =
514 ((sc->rxchainmask >> 2) & 1) +
515 ((sc->rxchainmask >> 1) & 1) +
516 ((sc->rxchainmask >> 0) & 1);
495
496 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
497 if (ifp == NULL) {
498 device_printf(dev, "can not allocate ifnet structure\n");
499 goto fail;
500 }
501 ic = ifp->if_l2com;
502

--- 4 unchanged lines hidden (view full) ---

507 /* Set device capabilities. */
508 ic->ic_caps =
509 IEEE80211_C_STA /* station mode supported */
510 | IEEE80211_C_MONITOR /* monitor mode supported */
511 | IEEE80211_C_TXPMGT /* tx power management */
512 | IEEE80211_C_SHSLOT /* short slot time supported */
513 | IEEE80211_C_WPA
514 | IEEE80211_C_SHPREAMBLE /* short preamble supported */
517
518 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
519 if (ifp == NULL) {
520 device_printf(dev, "can not allocate ifnet structure\n");
521 goto fail;
522 }
523 ic = ifp->if_l2com;
524

--- 4 unchanged lines hidden (view full) ---

529 /* Set device capabilities. */
530 ic->ic_caps =
531 IEEE80211_C_STA /* station mode supported */
532 | IEEE80211_C_MONITOR /* monitor mode supported */
533 | IEEE80211_C_TXPMGT /* tx power management */
534 | IEEE80211_C_SHSLOT /* short slot time supported */
535 | IEEE80211_C_WPA
536 | IEEE80211_C_SHPREAMBLE /* short preamble supported */
515#if 0
516 | IEEE80211_C_BGSCAN /* background scanning */
537 | IEEE80211_C_BGSCAN /* background scanning */
538#if 0
517 | IEEE80211_C_IBSS /* ibss/adhoc mode */
518#endif
519 | IEEE80211_C_WME /* WME */
520 ;
539 | IEEE80211_C_IBSS /* ibss/adhoc mode */
540#endif
541 | IEEE80211_C_WME /* WME */
542 ;
521#if 0
543#if 0 /* HT */
522 /* XXX disable until HT channel setup works */
523 ic->ic_htcaps =
524 IEEE80211_HTCAP_SMPS_ENA /* SM PS mode enabled */
525 | IEEE80211_HTCAP_CHWIDTH40 /* 40MHz channel width */
526 | IEEE80211_HTCAP_SHORTGI20 /* short GI in 20MHz */
527 | IEEE80211_HTCAP_SHORTGI40 /* short GI in 40MHz */
528 | IEEE80211_HTCAP_RXSTBC_2STREAM/* 1-2 spatial streams */
529 | IEEE80211_HTCAP_MAXAMSDU_3839 /* max A-MSDU length */
530 /* s/w capabilities */
531 | IEEE80211_HTC_HT /* HT operation */
532 | IEEE80211_HTC_AMPDU /* tx A-MPDU */
533 | IEEE80211_HTC_AMSDU /* tx A-MSDU */
534 ;
544 /* XXX disable until HT channel setup works */
545 ic->ic_htcaps =
546 IEEE80211_HTCAP_SMPS_ENA /* SM PS mode enabled */
547 | IEEE80211_HTCAP_CHWIDTH40 /* 40MHz channel width */
548 | IEEE80211_HTCAP_SHORTGI20 /* short GI in 20MHz */
549 | IEEE80211_HTCAP_SHORTGI40 /* short GI in 40MHz */
550 | IEEE80211_HTCAP_RXSTBC_2STREAM/* 1-2 spatial streams */
551 | IEEE80211_HTCAP_MAXAMSDU_3839 /* max A-MSDU length */
552 /* s/w capabilities */
553 | IEEE80211_HTC_HT /* HT operation */
554 | IEEE80211_HTC_AMPDU /* tx A-MPDU */
555 | IEEE80211_HTC_AMSDU /* tx A-MSDU */
556 ;
557
558 /* Set HT capabilities. */
559 ic->ic_htcaps =
560#if IWN_RBUF_SIZE == 8192
561 IEEE80211_HTCAP_AMSDU7935 |
535#endif
562#endif
563 IEEE80211_HTCAP_SMPS_DIS |
564 IEEE80211_HTCAP_CBW20_40 |
565 IEEE80211_HTCAP_SGI20 |
566 IEEE80211_HTCAP_SGI40;
567 if (sc->hw_type != IWN_HW_REV_TYPE_4965)
568 ic->ic_htcaps |= IEEE80211_HTCAP_GF;
569#endif
536
537 /* Read MAC address, channels, etc from EEPROM. */
538 error = iwn_read_eeprom(sc, macaddr);
539 if (error != 0) {
540 device_printf(dev, "could not read EEPROM, error %d\n",
541 error);
542 goto fail;
543 }
544
570
571 /* Read MAC address, channels, etc from EEPROM. */
572 error = iwn_read_eeprom(sc, macaddr);
573 if (error != 0) {
574 device_printf(dev, "could not read EEPROM, error %d\n",
575 error);
576 goto fail;
577 }
578
545 /* Power OFF adapter. */
546 iwn_apm_stop(sc);
547
548 device_printf(sc->sc_dev, "MIMO %dT%dR, %.4s, address %6D\n",
549 sc->ntxchains, sc->nrxchains, sc->eeprom_domain,
550 macaddr, ":");
551
579 device_printf(sc->sc_dev, "MIMO %dT%dR, %.4s, address %6D\n",
580 sc->ntxchains, sc->nrxchains, sc->eeprom_domain,
581 macaddr, ":");
582
583#if 0 /* HT */
584 /* Set supported HT rates. */
585 ic->ic_sup_mcs[0] = 0xff;
586 if (sc->nrxchains > 1)
587 ic->ic_sup_mcs[1] = 0xff;
588 if (sc->nrxchains > 2)
589 ic->ic_sup_mcs[2] = 0xff;
590#endif
591
552 if_initname(ifp, device_get_name(dev), device_get_unit(dev));
553 ifp->if_softc = sc;
554 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
555 ifp->if_init = iwn_init;
556 ifp->if_ioctl = iwn_ioctl;
557 ifp->if_start = iwn_start;
558 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
559 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
560 IFQ_SET_READY(&ifp->if_snd);
561
562 ieee80211_ifattach(ic, macaddr);
563 ic->ic_vap_create = iwn_vap_create;
564 ic->ic_vap_delete = iwn_vap_delete;
565 ic->ic_raw_xmit = iwn_raw_xmit;
566 ic->ic_node_alloc = iwn_node_alloc;
567 ic->ic_newassoc = iwn_newassoc;
568 ic->ic_wme.wme_update = iwn_wme_update;
592 if_initname(ifp, device_get_name(dev), device_get_unit(dev));
593 ifp->if_softc = sc;
594 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
595 ifp->if_init = iwn_init;
596 ifp->if_ioctl = iwn_ioctl;
597 ifp->if_start = iwn_start;
598 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
599 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
600 IFQ_SET_READY(&ifp->if_snd);
601
602 ieee80211_ifattach(ic, macaddr);
603 ic->ic_vap_create = iwn_vap_create;
604 ic->ic_vap_delete = iwn_vap_delete;
605 ic->ic_raw_xmit = iwn_raw_xmit;
606 ic->ic_node_alloc = iwn_node_alloc;
607 ic->ic_newassoc = iwn_newassoc;
608 ic->ic_wme.wme_update = iwn_wme_update;
609 ic->ic_update_mcast = iwn_update_mcast;
569 ic->ic_scan_start = iwn_scan_start;
570 ic->ic_scan_end = iwn_scan_end;
571 ic->ic_set_channel = iwn_set_channel;
572 ic->ic_scan_curchan = iwn_scan_curchan;
573 ic->ic_scan_mindwell = iwn_scan_mindwell;
610 ic->ic_scan_start = iwn_scan_start;
611 ic->ic_scan_end = iwn_scan_end;
612 ic->ic_set_channel = iwn_set_channel;
613 ic->ic_scan_curchan = iwn_scan_curchan;
614 ic->ic_scan_mindwell = iwn_scan_mindwell;
615 ic->ic_setregdomain = iwn_setregdomain;
616#if 0 /* HT */
617 ic->ic_ampdu_rx_start = iwn_ampdu_rx_start;
618 ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop;
619 ic->ic_ampdu_tx_start = iwn_ampdu_tx_start;
620 ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop;
621#endif
574
575 iwn_radiotap_attach(sc);
576 iwn_sysctlattach(sc);
577
578 /*
579 * Hook our interrupt after all initialization is complete.
580 */
581 error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,

--- 14 unchanged lines hidden (view full) ---

596const struct iwn_hal *
597iwn_hal_attach(struct iwn_softc *sc)
598{
599 sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf;
600
601 switch (sc->hw_type) {
602 case IWN_HW_REV_TYPE_4965:
603 sc->sc_hal = &iwn4965_hal;
622
623 iwn_radiotap_attach(sc);
624 iwn_sysctlattach(sc);
625
626 /*
627 * Hook our interrupt after all initialization is complete.
628 */
629 error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,

--- 14 unchanged lines hidden (view full) ---

644const struct iwn_hal *
645iwn_hal_attach(struct iwn_softc *sc)
646{
647 sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf;
648
649 switch (sc->hw_type) {
650 case IWN_HW_REV_TYPE_4965:
651 sc->sc_hal = &iwn4965_hal;
652 sc->limits = &iwn4965_sensitivity_limits;
604 sc->fwname = "iwn4965fw";
653 sc->fwname = "iwn4965fw";
605 sc->critical_temp = IWN_CTOK(110);
606 sc->txantmsk = IWN_ANT_A | IWN_ANT_B;
607 sc->rxantmsk = IWN_ANT_ABC;
608 sc->ntxchains = 2;
609 sc->nrxchains = 3;
654 sc->txchainmask = IWN_ANT_AB;
655 sc->rxchainmask = IWN_ANT_ABC;
610 break;
611 case IWN_HW_REV_TYPE_5100:
612 sc->sc_hal = &iwn5000_hal;
656 break;
657 case IWN_HW_REV_TYPE_5100:
658 sc->sc_hal = &iwn5000_hal;
659 sc->limits = &iwn5000_sensitivity_limits;
613 sc->fwname = "iwn5000fw";
660 sc->fwname = "iwn5000fw";
614 sc->critical_temp = 110;
615 sc->txantmsk = IWN_ANT_B;
616 sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
617 sc->ntxchains = 1;
618 sc->nrxchains = 2;
661 sc->txchainmask = IWN_ANT_B;
662 sc->rxchainmask = IWN_ANT_AB;
619 break;
620 case IWN_HW_REV_TYPE_5150:
621 sc->sc_hal = &iwn5000_hal;
663 break;
664 case IWN_HW_REV_TYPE_5150:
665 sc->sc_hal = &iwn5000_hal;
666 sc->limits = &iwn5150_sensitivity_limits;
622 sc->fwname = "iwn5150fw";
667 sc->fwname = "iwn5150fw";
623 /* NB: critical temperature will be read from EEPROM. */
624 sc->txantmsk = IWN_ANT_A;
625 sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
626 sc->ntxchains = 1;
627 sc->nrxchains = 2;
668 sc->txchainmask = IWN_ANT_A;
669 sc->rxchainmask = IWN_ANT_AB;
628 break;
629 case IWN_HW_REV_TYPE_5300:
630 case IWN_HW_REV_TYPE_5350:
631 sc->sc_hal = &iwn5000_hal;
670 break;
671 case IWN_HW_REV_TYPE_5300:
672 case IWN_HW_REV_TYPE_5350:
673 sc->sc_hal = &iwn5000_hal;
674 sc->limits = &iwn5000_sensitivity_limits;
632 sc->fwname = "iwn5000fw";
675 sc->fwname = "iwn5000fw";
633 sc->critical_temp = 110;
634 sc->txantmsk = sc->rxantmsk = IWN_ANT_ABC;
635 sc->ntxchains = sc->nrxchains = 3;
676 sc->txchainmask = IWN_ANT_ABC;
677 sc->rxchainmask = IWN_ANT_ABC;
636 break;
637 case IWN_HW_REV_TYPE_1000:
638 sc->sc_hal = &iwn5000_hal;
678 break;
679 case IWN_HW_REV_TYPE_1000:
680 sc->sc_hal = &iwn5000_hal;
681 sc->limits = &iwn5000_sensitivity_limits;
639 sc->fwname = "iwn1000fw";
682 sc->fwname = "iwn1000fw";
640 sc->critical_temp = 110;
641 sc->txantmsk = IWN_ANT_A;
642 sc->rxantmsk = IWN_ANT_A | IWN_ANT_B;
643 sc->ntxchains = 1;
644 sc->nrxchains = 2;
683 sc->txchainmask = IWN_ANT_A;
684 sc->rxchainmask = IWN_ANT_AB;
645 break;
646 case IWN_HW_REV_TYPE_6000:
647 sc->sc_hal = &iwn5000_hal;
685 break;
686 case IWN_HW_REV_TYPE_6000:
687 sc->sc_hal = &iwn5000_hal;
688 sc->limits = &iwn6000_sensitivity_limits;
648 sc->fwname = "iwn6000fw";
689 sc->fwname = "iwn6000fw";
649 sc->critical_temp = 110;
650 sc->txantmsk = IWN_ANT_ABC;
651 sc->rxantmsk = IWN_ANT_ABC;
652 sc->ntxchains = 3;
653 sc->nrxchains = 3;
690 switch (pci_get_device(sc->sc_dev)) {
691 case 0x422C:
692 case 0x4239:
693 sc->sc_flags |= IWN_FLAG_INTERNAL_PA;
694 sc->txchainmask = IWN_ANT_BC;
695 sc->rxchainmask = IWN_ANT_BC;
696 break;
697 default:
698 sc->txchainmask = IWN_ANT_ABC;
699 sc->rxchainmask = IWN_ANT_ABC;
700 break;
701 }
654 break;
655 case IWN_HW_REV_TYPE_6050:
656 sc->sc_hal = &iwn5000_hal;
702 break;
703 case IWN_HW_REV_TYPE_6050:
704 sc->sc_hal = &iwn5000_hal;
657 sc->fwname = "iwn6050fw";
658 sc->critical_temp = 110;
659 sc->txantmsk = IWN_ANT_ABC;
660 sc->rxantmsk = IWN_ANT_ABC;
661 sc->ntxchains = 3;
662 sc->nrxchains = 3;
705 sc->limits = &iwn6000_sensitivity_limits;
706 sc->fwname = "iwn6000fw";
707 sc->txchainmask = IWN_ANT_AB;
708 sc->rxchainmask = IWN_ANT_AB;
663 break;
664 default:
665 device_printf(sc->sc_dev, "adapter type %d not supported\n",
666 sc->hw_type);
667 return NULL;
668 }
669 return sc->sc_hal;
670}

--- 73 unchanged lines hidden (view full) ---

744 ieee80211_draintask(ic, &sc->sc_radioon_task);
745 ieee80211_draintask(ic, &sc->sc_radiooff_task);
746
747 iwn_stop(sc);
748 callout_drain(&sc->sc_timer_to);
749 ieee80211_ifdetach(ic);
750 }
751
709 break;
710 default:
711 device_printf(sc->sc_dev, "adapter type %d not supported\n",
712 sc->hw_type);
713 return NULL;
714 }
715 return sc->sc_hal;
716}

--- 73 unchanged lines hidden (view full) ---

790 ieee80211_draintask(ic, &sc->sc_radioon_task);
791 ieee80211_draintask(ic, &sc->sc_radiooff_task);
792
793 iwn_stop(sc);
794 callout_drain(&sc->sc_timer_to);
795 ieee80211_ifdetach(ic);
796 }
797
752 iwn_unload_firmware(sc);
753
798 /* Free DMA resources. */
754 iwn_free_rx_ring(sc, &sc->rxq);
799 iwn_free_rx_ring(sc, &sc->rxq);
755
756 if (sc->sc_hal != NULL)
757 for (i = 0; i < sc->sc_hal->ntxqs; i++)
758 iwn_free_tx_ring(sc, &sc->txq[i]);
800 if (sc->sc_hal != NULL)
801 for (i = 0; i < sc->sc_hal->ntxqs; i++)
802 iwn_free_tx_ring(sc, &sc->txq[i]);
759
760 iwn_free_sched(sc);
761 iwn_free_kw(sc);
803 iwn_free_sched(sc);
804 iwn_free_kw(sc);
805 if (sc->ict != NULL)
806 iwn_free_ict(sc);
762 iwn_free_fwmem(sc);
763
764 if (sc->irq != NULL) {
765 bus_teardown_intr(dev, sc->irq, sc->sc_ih);
766 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
767 if (sc->irq_rid == 1)
768 pci_release_msi(dev);
769 }

--- 39 unchanged lines hidden (view full) ---

809{
810 IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ);
811}
812
813static __inline uint32_t
814iwn_prph_read(struct iwn_softc *sc, uint32_t addr)
815{
816 IWN_WRITE(sc, IWN_PRPH_RADDR, IWN_PRPH_DWORD | addr);
807 iwn_free_fwmem(sc);
808
809 if (sc->irq != NULL) {
810 bus_teardown_intr(dev, sc->irq, sc->sc_ih);
811 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
812 if (sc->irq_rid == 1)
813 pci_release_msi(dev);
814 }

--- 39 unchanged lines hidden (view full) ---

854{
855 IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ);
856}
857
858static __inline uint32_t
859iwn_prph_read(struct iwn_softc *sc, uint32_t addr)
860{
861 IWN_WRITE(sc, IWN_PRPH_RADDR, IWN_PRPH_DWORD | addr);
862 IWN_BARRIER_READ_WRITE(sc);
817 return IWN_READ(sc, IWN_PRPH_RDATA);
818}
819
820static __inline void
821iwn_prph_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
822{
823 IWN_WRITE(sc, IWN_PRPH_WADDR, IWN_PRPH_DWORD | addr);
863 return IWN_READ(sc, IWN_PRPH_RDATA);
864}
865
866static __inline void
867iwn_prph_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
868{
869 IWN_WRITE(sc, IWN_PRPH_WADDR, IWN_PRPH_DWORD | addr);
870 IWN_BARRIER_WRITE(sc);
824 IWN_WRITE(sc, IWN_PRPH_WDATA, data);
825}
826
827static __inline void
828iwn_prph_setbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask)
829{
830 iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) | mask);
831}

--- 11 unchanged lines hidden (view full) ---

843 for (; count > 0; count--, data++, addr += 4)
844 iwn_prph_write(sc, addr, *data);
845}
846
847static __inline uint32_t
848iwn_mem_read(struct iwn_softc *sc, uint32_t addr)
849{
850 IWN_WRITE(sc, IWN_MEM_RADDR, addr);
871 IWN_WRITE(sc, IWN_PRPH_WDATA, data);
872}
873
874static __inline void
875iwn_prph_setbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask)
876{
877 iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) | mask);
878}

--- 11 unchanged lines hidden (view full) ---

890 for (; count > 0; count--, data++, addr += 4)
891 iwn_prph_write(sc, addr, *data);
892}
893
894static __inline uint32_t
895iwn_mem_read(struct iwn_softc *sc, uint32_t addr)
896{
897 IWN_WRITE(sc, IWN_MEM_RADDR, addr);
898 IWN_BARRIER_READ_WRITE(sc);
851 return IWN_READ(sc, IWN_MEM_RDATA);
852}
853
854static __inline void
855iwn_mem_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
856{
857 IWN_WRITE(sc, IWN_MEM_WADDR, addr);
899 return IWN_READ(sc, IWN_MEM_RDATA);
900}
901
902static __inline void
903iwn_mem_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
904{
905 IWN_WRITE(sc, IWN_MEM_WADDR, addr);
906 IWN_BARRIER_WRITE(sc);
858 IWN_WRITE(sc, IWN_MEM_WDATA, data);
859}
860
861static __inline void
862iwn_mem_write_2(struct iwn_softc *sc, uint32_t addr, uint16_t data)
863{
864 uint32_t tmp;
865

--- 50 unchanged lines hidden (view full) ---

916
917/*
918 * Initialize access by host to One Time Programmable ROM.
919 * NB: This kind of ROM can be found on 1000 or 6000 Series only.
920 */
921int
922iwn_init_otprom(struct iwn_softc *sc)
923{
907 IWN_WRITE(sc, IWN_MEM_WDATA, data);
908}
909
910static __inline void
911iwn_mem_write_2(struct iwn_softc *sc, uint32_t addr, uint16_t data)
912{
913 uint32_t tmp;
914

--- 50 unchanged lines hidden (view full) ---

965
966/*
967 * Initialize access by host to One Time Programmable ROM.
968 * NB: This kind of ROM can be found on 1000 or 6000 Series only.
969 */
970int
971iwn_init_otprom(struct iwn_softc *sc)
972{
924 int error;
973 uint32_t base;
974 uint16_t next;
975 int count, error;
925
976
977 /* Wait for clock stabilization before accessing prph. */
926 error = iwn_clock_wait(sc);
927 if (error != 0)
928 return error;
929
930 error = iwn_nic_lock(sc);
931 if (error != 0)
932 return error;
933 iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ);
934 DELAY(5);
935 iwn_prph_clrbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ);
936 iwn_nic_unlock(sc);
937
978 error = iwn_clock_wait(sc);
979 if (error != 0)
980 return error;
981
982 error = iwn_nic_lock(sc);
983 if (error != 0)
984 return error;
985 iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ);
986 DELAY(5);
987 iwn_prph_clrbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ);
988 iwn_nic_unlock(sc);
989
990 /* Set auto clock gate disable bit for HW with OTP shadow RAM. */
991 if (sc->hw_type != IWN_HW_REV_TYPE_1000) {
992 IWN_SETBITS(sc, IWN_DBG_LINK_PWR_MGMT,
993 IWN_RESET_LINK_PWR_MGMT_DIS);
994 }
938 IWN_CLRBITS(sc, IWN_EEPROM_GP, IWN_EEPROM_GP_IF_OWNER);
939 /* Clear ECC status. */
940 IWN_SETBITS(sc, IWN_OTP_GP,
941 IWN_OTP_GP_ECC_CORR_STTS | IWN_OTP_GP_ECC_UNCORR_STTS);
942
995 IWN_CLRBITS(sc, IWN_EEPROM_GP, IWN_EEPROM_GP_IF_OWNER);
996 /* Clear ECC status. */
997 IWN_SETBITS(sc, IWN_OTP_GP,
998 IWN_OTP_GP_ECC_CORR_STTS | IWN_OTP_GP_ECC_UNCORR_STTS);
999
1000 /*
1001 * Find last valid OTP block (contains the EEPROM image) for HW
1002 * without OTP shadow RAM.
1003 */
1004 if (sc->hw_type == IWN_HW_REV_TYPE_1000) {
1005 /* Switch to absolute addressing mode. */
1006 IWN_CLRBITS(sc, IWN_OTP_GP, IWN_OTP_GP_RELATIVE_ACCESS);
1007 base = 0;
1008 for (count = 0; count < IWN1000_OTP_NBLOCKS; count++) {
1009 error = iwn_read_prom_data(sc, base, &next, 2);
1010 if (error != 0)
1011 return error;
1012 if (next == 0) /* End of linked-list. */
1013 break;
1014 base = le16toh(next);
1015 }
1016 if (base == 0 || count == IWN1000_OTP_NBLOCKS)
1017 return EIO;
1018 /* Skip "next" word. */
1019 sc->prom_base = base + 1;
1020 }
943 return 0;
944}
945
946int
947iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count)
948{
949 uint32_t val, tmp;
950 int ntries;
951 uint8_t *out = data;
952
1021 return 0;
1022}
1023
1024int
1025iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count)
1026{
1027 uint32_t val, tmp;
1028 int ntries;
1029 uint8_t *out = data;
1030
1031 addr += sc->prom_base;
953 for (; count > 0; count -= 2, addr++) {
954 IWN_WRITE(sc, IWN_EEPROM, addr << 2);
1032 for (; count > 0; count -= 2, addr++) {
1033 IWN_WRITE(sc, IWN_EEPROM, addr << 2);
955 for (ntries = 0; ntries < 100; ntries++) {
1034 for (ntries = 0; ntries < 10; ntries++) {
956 val = IWN_READ(sc, IWN_EEPROM);
957 if (val & IWN_EEPROM_READ_VALID)
958 break;
959 DELAY(5);
960 }
1035 val = IWN_READ(sc, IWN_EEPROM);
1036 if (val & IWN_EEPROM_READ_VALID)
1037 break;
1038 DELAY(5);
1039 }
961 if (ntries == 100) {
1040 if (ntries == 10) {
962 device_printf(sc->sc_dev,
963 "timeout reading ROM at 0x%x\n", addr);
964 return ETIMEDOUT;
965 }
966 if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) {
967 /* OTPROM, check for ECC errors. */
968 tmp = IWN_READ(sc, IWN_OTP_GP);
969 if (tmp & IWN_OTP_GP_ECC_UNCORR_STTS) {

--- 60 unchanged lines hidden (view full) ---

1030 if (kvap != NULL)
1031 *kvap = dma->vaddr;
1032 return 0;
1033fail:
1034 iwn_dma_contig_free(dma);
1035 return error;
1036}
1037
1041 device_printf(sc->sc_dev,
1042 "timeout reading ROM at 0x%x\n", addr);
1043 return ETIMEDOUT;
1044 }
1045 if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) {
1046 /* OTPROM, check for ECC errors. */
1047 tmp = IWN_READ(sc, IWN_OTP_GP);
1048 if (tmp & IWN_OTP_GP_ECC_UNCORR_STTS) {

--- 60 unchanged lines hidden (view full) ---

1109 if (kvap != NULL)
1110 *kvap = dma->vaddr;
1111 return 0;
1112fail:
1113 iwn_dma_contig_free(dma);
1114 return error;
1115}
1116
1038static void
1117void
1039iwn_dma_contig_free(struct iwn_dma_info *dma)
1040{
1041 if (dma->tag != NULL) {
1042 if (dma->map != NULL) {
1043 if (dma->paddr == 0) {
1044 bus_dmamap_sync(dma->tag, dma->map,
1045 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1046 bus_dmamap_unload(dma->tag, dma->map);

--- 28 unchanged lines hidden (view full) ---

1075
1076void
1077iwn_free_kw(struct iwn_softc *sc)
1078{
1079 iwn_dma_contig_free(&sc->kw_dma);
1080}
1081
1082int
1118iwn_dma_contig_free(struct iwn_dma_info *dma)
1119{
1120 if (dma->tag != NULL) {
1121 if (dma->map != NULL) {
1122 if (dma->paddr == 0) {
1123 bus_dmamap_sync(dma->tag, dma->map,
1124 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1125 bus_dmamap_unload(dma->tag, dma->map);

--- 28 unchanged lines hidden (view full) ---

1154
1155void
1156iwn_free_kw(struct iwn_softc *sc)
1157{
1158 iwn_dma_contig_free(&sc->kw_dma);
1159}
1160
1161int
1162iwn_alloc_ict(struct iwn_softc *sc)
1163{
1164 /* ICT table must be aligned on a 4KB boundary. */
1165 return iwn_dma_contig_alloc(sc, &sc->ict_dma,
1166 (void **)&sc->ict, IWN_ICT_SIZE, 4096, BUS_DMA_NOWAIT);
1167}
1168
1169void
1170iwn_free_ict(struct iwn_softc *sc)
1171{
1172 iwn_dma_contig_free(&sc->ict_dma);
1173}
1174
1175int
1083iwn_alloc_fwmem(struct iwn_softc *sc)
1084{
1085 /* Must be aligned on a 16-byte boundary. */
1086 return iwn_dma_contig_alloc(sc, &sc->fw_dma, NULL,
1087 sc->sc_hal->fwsz, 16, BUS_DMA_NOWAIT);
1088}
1089
1090void

--- 19 unchanged lines hidden (view full) ---

1110 "%s: could not allocate Rx ring DMA memory, error %d\n",
1111 __func__, error);
1112 goto fail;
1113 }
1114
1115 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
1116 BUS_SPACE_MAXADDR_32BIT,
1117 BUS_SPACE_MAXADDR, NULL, NULL, MJUMPAGESIZE, 1,
1176iwn_alloc_fwmem(struct iwn_softc *sc)
1177{
1178 /* Must be aligned on a 16-byte boundary. */
1179 return iwn_dma_contig_alloc(sc, &sc->fw_dma, NULL,
1180 sc->sc_hal->fwsz, 16, BUS_DMA_NOWAIT);
1181}
1182
1183void

--- 19 unchanged lines hidden (view full) ---

1203 "%s: could not allocate Rx ring DMA memory, error %d\n",
1204 __func__, error);
1205 goto fail;
1206 }
1207
1208 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
1209 BUS_SPACE_MAXADDR_32BIT,
1210 BUS_SPACE_MAXADDR, NULL, NULL, MJUMPAGESIZE, 1,
1118 MJUMPAGESIZE, BUS_DMA_NOWAIT, NULL, NULL, &ring->desc_dma.tag);
1211 MJUMPAGESIZE, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat);
1119 if (error != 0) {
1120 device_printf(sc->sc_dev,
1121 "%s: bus_dma_tag_create_failed, error %d\n",
1122 __func__, error);
1123 goto fail;
1124 }
1125
1126 /* Allocate RX status area (16-byte aligned). */
1127 error = iwn_dma_contig_alloc(sc, &ring->stat_dma,
1128 (void **)&ring->stat, sizeof (struct iwn_rx_status),
1129 16, BUS_DMA_NOWAIT);
1130 if (error != 0) {
1131 device_printf(sc->sc_dev,
1132 "%s: could not allocate Rx status DMA memory, error %d\n",
1133 __func__, error);
1134 goto fail;
1135 }
1136
1212 if (error != 0) {
1213 device_printf(sc->sc_dev,
1214 "%s: bus_dma_tag_create_failed, error %d\n",
1215 __func__, error);
1216 goto fail;
1217 }
1218
1219 /* Allocate RX status area (16-byte aligned). */
1220 error = iwn_dma_contig_alloc(sc, &ring->stat_dma,
1221 (void **)&ring->stat, sizeof (struct iwn_rx_status),
1222 16, BUS_DMA_NOWAIT);
1223 if (error != 0) {
1224 device_printf(sc->sc_dev,
1225 "%s: could not allocate Rx status DMA memory, error %d\n",
1226 __func__, error);
1227 goto fail;
1228 }
1229
1137 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
1138 BUS_SPACE_MAXADDR_32BIT,
1139 BUS_SPACE_MAXADDR, NULL, NULL, MJUMPAGESIZE, 1,
1140 MJUMPAGESIZE, BUS_DMA_NOWAIT, NULL, NULL, &ring->desc_dma.tag);
1141 if (error != 0) {
1142 device_printf(sc->sc_dev,
1143 "%s: bus_dma_tag_create_failed, error %d\n",
1144 __func__, error);
1145 goto fail;
1146 }
1147
1148 /*
1149 * Allocate and map RX buffers.
1150 */
1151 for (i = 0; i < IWN_RX_RING_COUNT; i++) {
1152 struct iwn_rx_data *data = &ring->data[i];
1153 bus_addr_t paddr;
1154
1230 /*
1231 * Allocate and map RX buffers.
1232 */
1233 for (i = 0; i < IWN_RX_RING_COUNT; i++) {
1234 struct iwn_rx_data *data = &ring->data[i];
1235 bus_addr_t paddr;
1236
1155 error = bus_dmamap_create(ring->desc_dma.tag, 0, &data->map);
1237 error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
1156 if (error != 0) {
1157 device_printf(sc->sc_dev,
1158 "%s: bus_dmamap_create failed, error %d\n",
1159 __func__, error);
1160 goto fail;
1161 }
1162
1163 data->m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
1164 if (data->m == NULL) {
1165 device_printf(sc->sc_dev,
1166 "%s: could not allocate rx mbuf\n", __func__);
1167 error = ENOMEM;
1168 goto fail;
1169 }
1170
1171 /* Map page. */
1238 if (error != 0) {
1239 device_printf(sc->sc_dev,
1240 "%s: bus_dmamap_create failed, error %d\n",
1241 __func__, error);
1242 goto fail;
1243 }
1244
1245 data->m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
1246 if (data->m == NULL) {
1247 device_printf(sc->sc_dev,
1248 "%s: could not allocate rx mbuf\n", __func__);
1249 error = ENOMEM;
1250 goto fail;
1251 }
1252
1253 /* Map page. */
1172 error = bus_dmamap_load(ring->desc_dma.tag, data->map,
1254 error = bus_dmamap_load(ring->data_dmat, data->map,
1173 mtod(data->m, caddr_t), MJUMPAGESIZE,
1174 iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
1175 if (error != 0 && error != EFBIG) {
1176 device_printf(sc->sc_dev,
1177 "%s: bus_dmamap_load failed, error %d\n",
1178 __func__, error);
1179 m_freem(data->m);
1180 error = ENOMEM; /* XXX unique code */
1181 goto fail;
1182 }
1255 mtod(data->m, caddr_t), MJUMPAGESIZE,
1256 iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
1257 if (error != 0 && error != EFBIG) {
1258 device_printf(sc->sc_dev,
1259 "%s: bus_dmamap_load failed, error %d\n",
1260 __func__, error);
1261 m_freem(data->m);
1262 error = ENOMEM; /* XXX unique code */
1263 goto fail;
1264 }
1265 bus_dmamap_sync(ring->data_dmat, data->map,
1266 BUS_DMASYNC_PREWRITE);
1183
1184 /* Set physical address of RX buffer (256-byte aligned). */
1185 ring->desc[i] = htole32(paddr >> 8);
1186 }
1187 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
1188 BUS_DMASYNC_PREWRITE);
1189 return 0;
1190fail:

--- 32 unchanged lines hidden (view full) ---

1223
1224 iwn_dma_contig_free(&ring->desc_dma);
1225 iwn_dma_contig_free(&ring->stat_dma);
1226
1227 for (i = 0; i < IWN_RX_RING_COUNT; i++) {
1228 struct iwn_rx_data *data = &ring->data[i];
1229
1230 if (data->m != NULL) {
1267
1268 /* Set physical address of RX buffer (256-byte aligned). */
1269 ring->desc[i] = htole32(paddr >> 8);
1270 }
1271 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
1272 BUS_DMASYNC_PREWRITE);
1273 return 0;
1274fail:

--- 32 unchanged lines hidden (view full) ---

1307
1308 iwn_dma_contig_free(&ring->desc_dma);
1309 iwn_dma_contig_free(&ring->stat_dma);
1310
1311 for (i = 0; i < IWN_RX_RING_COUNT; i++) {
1312 struct iwn_rx_data *data = &ring->data[i];
1313
1314 if (data->m != NULL) {
1231 bus_dmamap_sync(ring->desc_dma.tag, data->map,
1315 bus_dmamap_sync(ring->data_dmat, data->map,
1232 BUS_DMASYNC_POSTREAD);
1316 BUS_DMASYNC_POSTREAD);
1233 bus_dmamap_unload(ring->desc_dma.tag, data->map);
1317 bus_dmamap_unload(ring->data_dmat, data->map);
1234 m_freem(data->m);
1235 }
1318 m_freem(data->m);
1319 }
1320 if (data->map != NULL)
1321 bus_dmamap_destroy(ring->data_dmat, data->map);
1236 }
1237}
1238
1239int
1240iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)
1241{
1242 bus_size_t size;
1243 bus_addr_t paddr;

--- 29 unchanged lines hidden (view full) ---

1273 "%s: could not allocate TX cmd DMA memory, error %d\n",
1274 __func__, error);
1275 goto fail;
1276 }
1277
1278 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
1279 BUS_SPACE_MAXADDR_32BIT,
1280 BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, IWN_MAX_SCATTER - 1,
1322 }
1323}
1324
1325int
1326iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)
1327{
1328 bus_size_t size;
1329 bus_addr_t paddr;

--- 29 unchanged lines hidden (view full) ---

1359 "%s: could not allocate TX cmd DMA memory, error %d\n",
1360 __func__, error);
1361 goto fail;
1362 }
1363
1364 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
1365 BUS_SPACE_MAXADDR_32BIT,
1366 BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, IWN_MAX_SCATTER - 1,
1281 MCLBYTES, BUS_DMA_NOWAIT, NULL, NULL, &ring->desc_dma.tag);
1367 MCLBYTES, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat);
1282 if (error != 0) {
1283 device_printf(sc->sc_dev,
1284 "%s: bus_dma_tag_create_failed, error %d\n",
1285 __func__, error);
1286 goto fail;
1287 }
1288
1289 paddr = ring->cmd_dma.paddr;
1290 for (i = 0; i < IWN_TX_RING_COUNT; i++) {
1291 struct iwn_tx_data *data = &ring->data[i];
1292
1293 data->cmd_paddr = paddr;
1294 data->scratch_paddr = paddr + 12;
1295 paddr += sizeof (struct iwn_tx_cmd);
1296
1368 if (error != 0) {
1369 device_printf(sc->sc_dev,
1370 "%s: bus_dma_tag_create_failed, error %d\n",
1371 __func__, error);
1372 goto fail;
1373 }
1374
1375 paddr = ring->cmd_dma.paddr;
1376 for (i = 0; i < IWN_TX_RING_COUNT; i++) {
1377 struct iwn_tx_data *data = &ring->data[i];
1378
1379 data->cmd_paddr = paddr;
1380 data->scratch_paddr = paddr + 12;
1381 paddr += sizeof (struct iwn_tx_cmd);
1382
1297 error = bus_dmamap_create(ring->desc_dma.tag, 0, &data->map);
1383 error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
1298 if (error != 0) {
1299 device_printf(sc->sc_dev,
1300 "%s: bus_dmamap_create failed, error %d\n",
1301 __func__, error);
1302 goto fail;
1303 }
1384 if (error != 0) {
1385 device_printf(sc->sc_dev,
1386 "%s: bus_dmamap_create failed, error %d\n",
1387 __func__, error);
1388 goto fail;
1389 }
1390 bus_dmamap_sync(ring->data_dmat, data->map,
1391 BUS_DMASYNC_PREWRITE);
1304 }
1305 return 0;
1306fail:
1307 iwn_free_tx_ring(sc, ring);
1308 return error;
1309}
1310
1311void
1312iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
1313{
1314 int i;
1315
1316 for (i = 0; i < IWN_TX_RING_COUNT; i++) {
1317 struct iwn_tx_data *data = &ring->data[i];
1318
1319 if (data->m != NULL) {
1392 }
1393 return 0;
1394fail:
1395 iwn_free_tx_ring(sc, ring);
1396 return error;
1397}
1398
1399void
1400iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
1401{
1402 int i;
1403
1404 for (i = 0; i < IWN_TX_RING_COUNT; i++) {
1405 struct iwn_tx_data *data = &ring->data[i];
1406
1407 if (data->m != NULL) {
1320 bus_dmamap_sync(ring->desc_dma.tag, data->map,
1321 BUS_DMASYNC_POSTWRITE);
1322 bus_dmamap_unload(ring->desc_dma.tag, data->map);
1408 bus_dmamap_unload(ring->data_dmat, data->map);
1323 m_freem(data->m);
1324 data->m = NULL;
1325 }
1326 }
1327 /* Clear TX descriptors. */
1328 memset(ring->desc, 0, ring->desc_dma.size);
1329 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
1330 BUS_DMASYNC_PREWRITE);

--- 5 unchanged lines hidden (view full) ---

1336void
1337iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
1338{
1339 int i;
1340
1341 iwn_dma_contig_free(&ring->desc_dma);
1342 iwn_dma_contig_free(&ring->cmd_dma);
1343
1409 m_freem(data->m);
1410 data->m = NULL;
1411 }
1412 }
1413 /* Clear TX descriptors. */
1414 memset(ring->desc, 0, ring->desc_dma.size);
1415 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
1416 BUS_DMASYNC_PREWRITE);

--- 5 unchanged lines hidden (view full) ---

1422void
1423iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
1424{
1425 int i;
1426
1427 iwn_dma_contig_free(&ring->desc_dma);
1428 iwn_dma_contig_free(&ring->cmd_dma);
1429
1344 if (ring->data != NULL) {
1345 for (i = 0; i < IWN_TX_RING_COUNT; i++) {
1346 struct iwn_tx_data *data = &ring->data[i];
1430 for (i = 0; i < IWN_TX_RING_COUNT; i++) {
1431 struct iwn_tx_data *data = &ring->data[i];
1347
1432
1348 if (data->m != NULL) {
1349 bus_dmamap_sync(ring->desc_dma.tag, data->map,
1350 BUS_DMASYNC_POSTWRITE);
1351 bus_dmamap_unload(ring->desc_dma.tag,
1352 data->map);
1353 m_freem(data->m);
1354 }
1433 if (data->m != NULL) {
1434 bus_dmamap_sync(ring->data_dmat, data->map,
1435 BUS_DMASYNC_POSTWRITE);
1436 bus_dmamap_unload(ring->data_dmat, data->map);
1437 m_freem(data->m);
1355 }
1438 }
1439 if (data->map != NULL)
1440 bus_dmamap_destroy(ring->data_dmat, data->map);
1356 }
1357}
1358
1441 }
1442}
1443
1444void
1445iwn5000_ict_reset(struct iwn_softc *sc)
1446{
1447 /* Disable interrupts. */
1448 IWN_WRITE(sc, IWN_INT_MASK, 0);
1449
1450 /* Reset ICT table. */
1451 memset(sc->ict, 0, IWN_ICT_SIZE);
1452 sc->ict_cur = 0;
1453
1454 /* Set physical address of ICT table (4KB aligned.) */
1455 DPRINTF(sc, IWN_DEBUG_RESET, "%s: enabling ICT\n", __func__);
1456 IWN_WRITE(sc, IWN_DRAM_INT_TBL, IWN_DRAM_INT_TBL_ENABLE |
1457 IWN_DRAM_INT_TBL_WRAP_CHECK | sc->ict_dma.paddr >> 12);
1458
1459 /* Enable periodic RX interrupt. */
1460 sc->int_mask |= IWN_INT_RX_PERIODIC;
1461 /* Switch to ICT interrupt mode in driver. */
1462 sc->sc_flags |= IWN_FLAG_USE_ICT;
1463
1464 /* Re-enable interrupts. */
1465 IWN_WRITE(sc, IWN_INT, 0xffffffff);
1466 IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
1467}
1468
1359int
1360iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
1361{
1362 const struct iwn_hal *hal = sc->sc_hal;
1363 int error;
1364 uint16_t val;
1365
1366 /* Check whether adapter has an EEPROM or an OTPROM. */
1367 if (sc->hw_type >= IWN_HW_REV_TYPE_1000 &&
1368 (IWN_READ(sc, IWN_OTP_GP) & IWN_OTP_GP_DEV_SEL_OTP))
1369 sc->sc_flags |= IWN_FLAG_HAS_OTPROM;
1370 DPRINTF(sc, IWN_DEBUG_RESET, "%s found\n",
1371 (sc->sc_flags & IWN_FLAG_HAS_OTPROM) ? "OTPROM" : "EEPROM");
1372
1469int
1470iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
1471{
1472 const struct iwn_hal *hal = sc->sc_hal;
1473 int error;
1474 uint16_t val;
1475
1476 /* Check whether adapter has an EEPROM or an OTPROM. */
1477 if (sc->hw_type >= IWN_HW_REV_TYPE_1000 &&
1478 (IWN_READ(sc, IWN_OTP_GP) & IWN_OTP_GP_DEV_SEL_OTP))
1479 sc->sc_flags |= IWN_FLAG_HAS_OTPROM;
1480 DPRINTF(sc, IWN_DEBUG_RESET, "%s found\n",
1481 (sc->sc_flags & IWN_FLAG_HAS_OTPROM) ? "OTPROM" : "EEPROM");
1482
1483 /* Adapter has to be powered on for EEPROM access to work. */
1484 error = iwn_apm_init(sc);
1485 if (error != 0) {
1486 device_printf(sc->sc_dev,
1487 "%s: could not power ON adapter, error %d\n",
1488 __func__, error);
1489 return error;
1490 }
1491
1373 if ((IWN_READ(sc, IWN_EEPROM_GP) & 0x7) == 0) {
1374 device_printf(sc->sc_dev, "%s: bad ROM signature\n", __func__);
1375 return EIO;
1376 }
1377 error = iwn_eeprom_lock(sc);
1378 if (error != 0) {
1379 device_printf(sc->sc_dev,
1380 "%s: could not lock ROM, error %d\n",
1381 __func__, error);
1382 return error;
1383 }
1384
1492 if ((IWN_READ(sc, IWN_EEPROM_GP) & 0x7) == 0) {
1493 device_printf(sc->sc_dev, "%s: bad ROM signature\n", __func__);
1494 return EIO;
1495 }
1496 error = iwn_eeprom_lock(sc);
1497 if (error != 0) {
1498 device_printf(sc->sc_dev,
1499 "%s: could not lock ROM, error %d\n",
1500 __func__, error);
1501 return error;
1502 }
1503
1385 if ((sc->sc_flags & IWN_FLAG_HAS_OTPROM) &&
1386 ((error = iwn_init_otprom(sc)) != 0)) {
1387 device_printf(sc->sc_dev,
1388 "%s: could not initialize OTPROM, error %d\n",
1389 __func__, error);
1390 return error;
1504 if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) {
1505 error = iwn_init_otprom(sc);
1506 if (error != 0) {
1507 device_printf(sc->sc_dev,
1508 "%s: could not initialize OTPROM, error %d\n",
1509 __func__, error);
1510 return error;
1511 }
1391 }
1392
1393 iwn_read_prom_data(sc, IWN_EEPROM_RFCFG, &val, 2);
1394 sc->rfcfg = le16toh(val);
1395 DPRINTF(sc, IWN_DEBUG_RESET, "radio config=0x%04x\n", sc->rfcfg);
1396
1397 /* Read MAC address. */
1398 iwn_read_prom_data(sc, IWN_EEPROM_MAC, macaddr, 6);
1399
1400 /* Read adapter-specific information from EEPROM. */
1401 hal->read_eeprom(sc);
1402
1512 }
1513
1514 iwn_read_prom_data(sc, IWN_EEPROM_RFCFG, &val, 2);
1515 sc->rfcfg = le16toh(val);
1516 DPRINTF(sc, IWN_DEBUG_RESET, "radio config=0x%04x\n", sc->rfcfg);
1517
1518 /* Read MAC address. */
1519 iwn_read_prom_data(sc, IWN_EEPROM_MAC, macaddr, 6);
1520
1521 /* Read adapter-specific information from EEPROM. */
1522 hal->read_eeprom(sc);
1523
1524 iwn_apm_stop(sc); /* Power OFF adapter. */
1525
1403 iwn_eeprom_unlock(sc);
1404 return 0;
1405}
1406
1407void
1408iwn4965_read_eeprom(struct iwn_softc *sc)
1409{
1526 iwn_eeprom_unlock(sc);
1527 return 0;
1528}
1529
1530void
1531iwn4965_read_eeprom(struct iwn_softc *sc)
1532{
1533 uint32_t addr;
1410 int i;
1411 uint16_t val;
1412
1413 /* Read regulatory domain (4 ASCII characters.) */
1414 iwn_read_prom_data(sc, IWN4965_EEPROM_DOMAIN, sc->eeprom_domain, 4);
1415
1534 int i;
1535 uint16_t val;
1536
1537 /* Read regulatory domain (4 ASCII characters.) */
1538 iwn_read_prom_data(sc, IWN4965_EEPROM_DOMAIN, sc->eeprom_domain, 4);
1539
1416 /* Read the list of authorized channels. */
1417 for (i = 0; i < 7; i++)
1418 iwn_read_eeprom_channels(sc, iwn4965_regulatory_bands[i], i);
1540 /* Read the list of authorized channels (20MHz ones only.) */
1541 for (i = 0; i < 5; i++) {
1542 addr = iwn4965_regulatory_bands[i];
1543 iwn_read_eeprom_channels(sc, i, addr);
1544 }
1419
1420 /* Read maximum allowed TX power for 2GHz and 5GHz bands. */
1421 iwn_read_prom_data(sc, IWN4965_EEPROM_MAXPOW, &val, 2);
1422 sc->maxpwr2GHz = val & 0xff;
1423 sc->maxpwr5GHz = val >> 8;
1424 /* Check that EEPROM values are within valid range. */
1425 if (sc->maxpwr5GHz < 20 || sc->maxpwr5GHz > 50)
1426 sc->maxpwr5GHz = 38;

--- 9 unchanged lines hidden (view full) ---

1436 /* Read voltage at which samples were taken. */
1437 iwn_read_prom_data(sc, IWN4965_EEPROM_VOLTAGE, &val, 2);
1438 sc->eeprom_voltage = (int16_t)le16toh(val);
1439 DPRINTF(sc, IWN_DEBUG_RESET, "voltage=%d (in 0.3V)\n",
1440 sc->eeprom_voltage);
1441
1442#ifdef IWN_DEBUG
1443 /* Print samples. */
1545
1546 /* Read maximum allowed TX power for 2GHz and 5GHz bands. */
1547 iwn_read_prom_data(sc, IWN4965_EEPROM_MAXPOW, &val, 2);
1548 sc->maxpwr2GHz = val & 0xff;
1549 sc->maxpwr5GHz = val >> 8;
1550 /* Check that EEPROM values are within valid range. */
1551 if (sc->maxpwr5GHz < 20 || sc->maxpwr5GHz > 50)
1552 sc->maxpwr5GHz = 38;

--- 9 unchanged lines hidden (view full) ---

1562 /* Read voltage at which samples were taken. */
1563 iwn_read_prom_data(sc, IWN4965_EEPROM_VOLTAGE, &val, 2);
1564 sc->eeprom_voltage = (int16_t)le16toh(val);
1565 DPRINTF(sc, IWN_DEBUG_RESET, "voltage=%d (in 0.3V)\n",
1566 sc->eeprom_voltage);
1567
1568#ifdef IWN_DEBUG
1569 /* Print samples. */
1444 if (sc->sc_debug & IWN_DEBUG_ANY || 1) {
1570 if (sc->sc_debug & IWN_DEBUG_ANY) {
1445 for (i = 0; i < IWN_NBANDS; i++)
1446 iwn4965_print_power_group(sc, i);
1447 }
1448#endif
1449}
1450
1451#ifdef IWN_DEBUG
1452void

--- 28 unchanged lines hidden (view full) ---

1481 }
1482 }
1483}
1484#endif
1485
1486void
1487iwn5000_read_eeprom(struct iwn_softc *sc)
1488{
1571 for (i = 0; i < IWN_NBANDS; i++)
1572 iwn4965_print_power_group(sc, i);
1573 }
1574#endif
1575}
1576
1577#ifdef IWN_DEBUG
1578void

--- 28 unchanged lines hidden (view full) ---

1607 }
1608 }
1609}
1610#endif
1611
1612void
1613iwn5000_read_eeprom(struct iwn_softc *sc)
1614{
1489 int32_t temp, volt, delta;
1615 int32_t temp, volt;
1490 uint32_t addr, base;
1491 int i;
1492 uint16_t val;
1493
1494 /* Read regulatory domain (4 ASCII characters.) */
1495 iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
1496 base = le16toh(val);
1497 iwn_read_prom_data(sc, base + IWN5000_EEPROM_DOMAIN,
1498 sc->eeprom_domain, 4);
1499
1616 uint32_t addr, base;
1617 int i;
1618 uint16_t val;
1619
1620 /* Read regulatory domain (4 ASCII characters.) */
1621 iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
1622 base = le16toh(val);
1623 iwn_read_prom_data(sc, base + IWN5000_EEPROM_DOMAIN,
1624 sc->eeprom_domain, 4);
1625
1500 /* Read the list of authorized channels. */
1501 for (i = 0; i < 7; i++) {
1626 /* Read the list of authorized channels (20MHz ones only.) */
1627 for (i = 0; i < 5; i++) {
1502 addr = base + iwn5000_regulatory_bands[i];
1628 addr = base + iwn5000_regulatory_bands[i];
1503 iwn_read_eeprom_channels(sc, addr, i);
1629 iwn_read_eeprom_channels(sc, i, addr);
1504 }
1505
1630 }
1631
1632 /* Read enhanced TX power information for 6000 Series. */
1633 if (sc->hw_type >= IWN_HW_REV_TYPE_6000)
1634 iwn_read_eeprom_enhinfo(sc);
1635
1506 iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2);
1507 base = le16toh(val);
1508 if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
1636 iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2);
1637 base = le16toh(val);
1638 if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
1509 /* Compute critical temperature (in Kelvin.) */
1639 /* Compute temperature offset. */
1510 iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
1511 temp = le16toh(val);
1512 iwn_read_prom_data(sc, base + IWN5000_EEPROM_VOLT, &val, 2);
1513 volt = le16toh(val);
1640 iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
1641 temp = le16toh(val);
1642 iwn_read_prom_data(sc, base + IWN5000_EEPROM_VOLT, &val, 2);
1643 volt = le16toh(val);
1514 delta = temp - (volt / -5);
1515 sc->critical_temp = (IWN_CTOK(110) - delta) * -5;
1516 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "temp=%d volt=%d delta=%dK\n",
1517 temp, volt, delta);
1644 sc->temp_off = temp - (volt / -5);
1645 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "temp=%d volt=%d offset=%dK\n",
1646 temp, volt, sc->temp_off);
1518 } else {
1519 /* Read crystal calibration. */
1520 iwn_read_prom_data(sc, base + IWN5000_EEPROM_CRYSTAL,
1521 &sc->eeprom_crystal, sizeof (uint32_t));
1522 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "crystal calibration 0x%08x\n",
1523 le32toh(sc->eeprom_crystal));
1524 }
1525}
1526
1647 } else {
1648 /* Read crystal calibration. */
1649 iwn_read_prom_data(sc, base + IWN5000_EEPROM_CRYSTAL,
1650 &sc->eeprom_crystal, sizeof (uint32_t));
1651 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "crystal calibration 0x%08x\n",
1652 le32toh(sc->eeprom_crystal));
1653 }
1654}
1655
1656/*
1657 * Translate EEPROM flags to net80211.
1658 */
1659static uint32_t
1660iwn_eeprom_channel_flags(struct iwn_eeprom_chan *channel)
1661{
1662 uint32_t nflags;
1663
1664 nflags = 0;
1665 if ((channel->flags & IWN_EEPROM_CHAN_ACTIVE) == 0)
1666 nflags |= IEEE80211_CHAN_PASSIVE;
1667 if ((channel->flags & IWN_EEPROM_CHAN_IBSS) == 0)
1668 nflags |= IEEE80211_CHAN_NOADHOC;
1669 if (channel->flags & IWN_EEPROM_CHAN_RADAR) {
1670 nflags |= IEEE80211_CHAN_DFS;
1671 /* XXX apparently IBSS may still be marked */
1672 nflags |= IEEE80211_CHAN_NOADHOC;
1673 }
1674
1675 return nflags;
1676}
1677
1527static void
1678static void
1528iwn_read_eeprom_band(struct iwn_softc *sc, const struct iwn_chan_band *band,
1529 uint32_t flags, uint32_t addr)
1679iwn_read_eeprom_band(struct iwn_softc *sc, int n)
1530{
1531 struct ifnet *ifp = sc->sc_ifp;
1532 struct ieee80211com *ic = ifp->if_l2com;
1680{
1681 struct ifnet *ifp = sc->sc_ifp;
1682 struct ieee80211com *ic = ifp->if_l2com;
1533 struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
1683 struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
1684 const struct iwn_chan_band *band = &iwn_bands[n];
1534 struct ieee80211_channel *c;
1535 int i, chan, nflags;
1536
1685 struct ieee80211_channel *c;
1686 int i, chan, nflags;
1687
1537 iwn_read_prom_data(sc, addr, channels,
1538 band->nchan * sizeof (struct iwn_eeprom_chan));
1539
1540 for (i = 0; i < band->nchan; i++) {
1541 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
1542 DPRINTF(sc, IWN_DEBUG_RESET,
1543 "skip chan %d flags 0x%x maxpwr %d\n",
1544 band->chan[i], channels[i].flags,
1545 channels[i].maxpwr);
1546 continue;
1547 }
1548 chan = band->chan[i];
1688 for (i = 0; i < band->nchan; i++) {
1689 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
1690 DPRINTF(sc, IWN_DEBUG_RESET,
1691 "skip chan %d flags 0x%x maxpwr %d\n",
1692 band->chan[i], channels[i].flags,
1693 channels[i].maxpwr);
1694 continue;
1695 }
1696 chan = band->chan[i];
1697 nflags = iwn_eeprom_channel_flags(&channels[i]);
1549
1698
1550 /* Translate EEPROM flags to net80211 */
1551 nflags = 0;
1552 if ((channels[i].flags & IWN_EEPROM_CHAN_ACTIVE) == 0)
1553 nflags |= IEEE80211_CHAN_PASSIVE;
1554 if ((channels[i].flags & IWN_EEPROM_CHAN_IBSS) == 0)
1555 nflags |= IEEE80211_CHAN_NOADHOC;
1556 if (channels[i].flags & IWN_EEPROM_CHAN_RADAR) {
1557 nflags |= IEEE80211_CHAN_DFS;
1558 /* XXX apparently IBSS may still be marked */
1559 nflags |= IEEE80211_CHAN_NOADHOC;
1560 }
1561
1562 DPRINTF(sc, IWN_DEBUG_RESET,
1563 "add chan %d flags 0x%x maxpwr %d\n",
1564 chan, channels[i].flags, channels[i].maxpwr);
1565
1566 c = &ic->ic_channels[ic->ic_nchans++];
1567 c->ic_ieee = chan;
1699 DPRINTF(sc, IWN_DEBUG_RESET,
1700 "add chan %d flags 0x%x maxpwr %d\n",
1701 chan, channels[i].flags, channels[i].maxpwr);
1702
1703 c = &ic->ic_channels[ic->ic_nchans++];
1704 c->ic_ieee = chan;
1568 c->ic_freq = ieee80211_ieee2mhz(chan, flags);
1569 c->ic_maxregpower = channels[i].maxpwr;
1570 c->ic_maxpower = 2*c->ic_maxregpower;
1705 c->ic_maxregpower = channels[i].maxpwr;
1706 c->ic_maxpower = 2*c->ic_maxregpower;
1571 if (flags & IEEE80211_CHAN_2GHZ) {
1707 if (n == 0) { /* 2GHz band */
1708 c->ic_freq = ieee80211_ieee2mhz(chan,
1709 IEEE80211_CHAN_G);
1710
1572 /* G =>'s B is supported */
1573 c->ic_flags = IEEE80211_CHAN_B | nflags;
1574
1575 c = &ic->ic_channels[ic->ic_nchans++];
1576 c[0] = c[-1];
1577 c->ic_flags = IEEE80211_CHAN_G | nflags;
1578 } else { /* 5GHz band */
1711 /* G =>'s B is supported */
1712 c->ic_flags = IEEE80211_CHAN_B | nflags;
1713
1714 c = &ic->ic_channels[ic->ic_nchans++];
1715 c[0] = c[-1];
1716 c->ic_flags = IEEE80211_CHAN_G | nflags;
1717 } else { /* 5GHz band */
1718 c->ic_freq = ieee80211_ieee2mhz(chan,
1719 IEEE80211_CHAN_A);
1579 c->ic_flags = IEEE80211_CHAN_A | nflags;
1580 sc->sc_flags |= IWN_FLAG_HAS_5GHZ;
1581 }
1720 c->ic_flags = IEEE80211_CHAN_A | nflags;
1721 sc->sc_flags |= IWN_FLAG_HAS_5GHZ;
1722 }
1723#if 0 /* HT */
1582 /* XXX no constraints on using HT20 */
1583 /* add HT20, HT40 added separately */
1584 c = &ic->ic_channels[ic->ic_nchans++];
1585 c[0] = c[-1];
1586 c->ic_flags |= IEEE80211_CHAN_HT20;
1587 /* XXX NARROW =>'s 1/2 and 1/4 width? */
1724 /* XXX no constraints on using HT20 */
1725 /* add HT20, HT40 added separately */
1726 c = &ic->ic_channels[ic->ic_nchans++];
1727 c[0] = c[-1];
1728 c->ic_flags |= IEEE80211_CHAN_HT20;
1729 /* XXX NARROW =>'s 1/2 and 1/4 width? */
1730#endif
1588 }
1589}
1590
1731 }
1732}
1733
1734#if 0 /* HT */
1591static void
1735static void
1592iwn_read_eeprom_ht40(struct iwn_softc *sc, const struct iwn_chan_band *band,
1593 uint32_t flags, uint32_t addr)
1736iwn_read_eeprom_ht40(struct iwn_softc *sc, int n)
1594{
1595 struct ifnet *ifp = sc->sc_ifp;
1596 struct ieee80211com *ic = ifp->if_l2com;
1737{
1738 struct ifnet *ifp = sc->sc_ifp;
1739 struct ieee80211com *ic = ifp->if_l2com;
1597 struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
1740 struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
1741 const struct iwn_chan_band *band = &iwn_bands[n];
1598 struct ieee80211_channel *c, *cent, *extc;
1599 int i;
1600
1742 struct ieee80211_channel *c, *cent, *extc;
1743 int i;
1744
1601 iwn_read_prom_data(sc, addr, channels,
1602 band->nchan * sizeof (struct iwn_eeprom_chan));
1603
1604 for (i = 0; i < band->nchan; i++) {
1605 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID) ||
1606 !(channels[i].flags & IWN_EEPROM_CHAN_WIDE)) {
1607 DPRINTF(sc, IWN_DEBUG_RESET,
1608 "skip chan %d flags 0x%x maxpwr %d\n",
1609 band->chan[i], channels[i].flags,
1610 channels[i].maxpwr);
1611 continue;
1612 }
1613 /*
1614 * Each entry defines an HT40 channel pair; find the
1615 * center channel, then the extension channel above.
1616 */
1617 cent = ieee80211_find_channel_byieee(ic, band->chan[i],
1745 for (i = 0; i < band->nchan; i++) {
1746 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID) ||
1747 !(channels[i].flags & IWN_EEPROM_CHAN_WIDE)) {
1748 DPRINTF(sc, IWN_DEBUG_RESET,
1749 "skip chan %d flags 0x%x maxpwr %d\n",
1750 band->chan[i], channels[i].flags,
1751 channels[i].maxpwr);
1752 continue;
1753 }
1754 /*
1755 * Each entry defines an HT40 channel pair; find the
1756 * center channel, then the extension channel above.
1757 */
1758 cent = ieee80211_find_channel_byieee(ic, band->chan[i],
1618 flags & ~IEEE80211_CHAN_HT);
1759 band->flags & ~IEEE80211_CHAN_HT);
1619 if (cent == NULL) { /* XXX shouldn't happen */
1620 device_printf(sc->sc_dev,
1621 "%s: no entry for channel %d\n",
1622 __func__, band->chan[i]);
1623 continue;
1624 }
1625 extc = ieee80211_find_channel(ic, cent->ic_freq+20,
1760 if (cent == NULL) { /* XXX shouldn't happen */
1761 device_printf(sc->sc_dev,
1762 "%s: no entry for channel %d\n",
1763 __func__, band->chan[i]);
1764 continue;
1765 }
1766 extc = ieee80211_find_channel(ic, cent->ic_freq+20,
1626 flags & ~IEEE80211_CHAN_HT);
1767 band->flags & ~IEEE80211_CHAN_HT);
1627 if (extc == NULL) {
1628 DPRINTF(sc, IWN_DEBUG_RESET,
1629 "skip chan %d, extension channel not found\n",
1630 band->chan[i]);
1631 continue;
1632 }
1633
1634 DPRINTF(sc, IWN_DEBUG_RESET,

--- 7 unchanged lines hidden (view full) ---

1642 c->ic_flags |= IEEE80211_CHAN_HT40U;
1643 c = &ic->ic_channels[ic->ic_nchans++];
1644 c[0] = extc[0];
1645 c->ic_extieee = cent->ic_ieee;
1646 c->ic_flags &= ~IEEE80211_CHAN_HT;
1647 c->ic_flags |= IEEE80211_CHAN_HT40D;
1648 }
1649}
1768 if (extc == NULL) {
1769 DPRINTF(sc, IWN_DEBUG_RESET,
1770 "skip chan %d, extension channel not found\n",
1771 band->chan[i]);
1772 continue;
1773 }
1774
1775 DPRINTF(sc, IWN_DEBUG_RESET,

--- 7 unchanged lines hidden (view full) ---

1783 c->ic_flags |= IEEE80211_CHAN_HT40U;
1784 c = &ic->ic_channels[ic->ic_nchans++];
1785 c[0] = extc[0];
1786 c->ic_extieee = cent->ic_ieee;
1787 c->ic_flags &= ~IEEE80211_CHAN_HT;
1788 c->ic_flags |= IEEE80211_CHAN_HT40D;
1789 }
1790}
1791#endif
1650
1651static void
1792
1793static void
1652iwn_read_eeprom_channels(struct iwn_softc *sc, uint32_t addr, int n)
1794iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
1653{
1654 struct ifnet *ifp = sc->sc_ifp;
1655 struct ieee80211com *ic = ifp->if_l2com;
1795{
1796 struct ifnet *ifp = sc->sc_ifp;
1797 struct ieee80211com *ic = ifp->if_l2com;
1656 static const uint32_t iwnband_flags[] = {
1657 IEEE80211_CHAN_G,
1658 IEEE80211_CHAN_A,
1659 IEEE80211_CHAN_A,
1660 IEEE80211_CHAN_A,
1661 IEEE80211_CHAN_A,
1662 IEEE80211_CHAN_G | IEEE80211_CHAN_HT40,
1663 IEEE80211_CHAN_A | IEEE80211_CHAN_HT40
1664 };
1665
1798
1799 iwn_read_prom_data(sc, addr, &sc->eeprom_channels[n],
1800 iwn_bands[n].nchan * sizeof (struct iwn_eeprom_chan));
1801
1666 if (n < 5)
1802 if (n < 5)
1667 iwn_read_eeprom_band(sc, &iwn_bands[n], iwnband_flags[n], addr);
1803 iwn_read_eeprom_band(sc, n);
1804#if 0 /* HT */
1668 else
1805 else
1669 iwn_read_eeprom_ht40(sc, &iwn_bands[n], iwnband_flags[n], addr);
1806 iwn_read_eeprom_ht40(sc, n);
1807#endif
1670 ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
1671}
1672
1808 ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
1809}
1810
1811#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
1812
1813void
1814iwn_read_eeprom_enhinfo(struct iwn_softc *sc)
1815{
1816 struct iwn_eeprom_enhinfo enhinfo[35];
1817 uint16_t val, base;
1818 int8_t maxpwr;
1819 int i;
1820
1821 iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
1822 base = le16toh(val);
1823 iwn_read_prom_data(sc, base + IWN6000_EEPROM_ENHINFO,
1824 enhinfo, sizeof enhinfo);
1825
1826 memset(sc->enh_maxpwr, 0, sizeof sc->enh_maxpwr);
1827 for (i = 0; i < nitems(enhinfo); i++) {
1828 if (enhinfo[i].chan == 0 || enhinfo[i].reserved != 0)
1829 continue; /* Skip invalid entries. */
1830
1831 maxpwr = 0;
1832 if (sc->txchainmask & IWN_ANT_A)
1833 maxpwr = MAX(maxpwr, enhinfo[i].chain[0]);
1834 if (sc->txchainmask & IWN_ANT_B)
1835 maxpwr = MAX(maxpwr, enhinfo[i].chain[1]);
1836 if (sc->txchainmask & IWN_ANT_C)
1837 maxpwr = MAX(maxpwr, enhinfo[i].chain[2]);
1838 if (sc->ntxchains == 2)
1839 maxpwr = MAX(maxpwr, enhinfo[i].mimo2);
1840 else if (sc->ntxchains == 3)
1841 maxpwr = MAX(maxpwr, enhinfo[i].mimo3);
1842 maxpwr /= 2; /* Convert half-dBm to dBm. */
1843
1844 DPRINTF(sc, IWN_DEBUG_RESET, "enhinfo %d, maxpwr=%d\n", i,
1845 maxpwr);
1846 sc->enh_maxpwr[i] = maxpwr;
1847 }
1848}
1849
1673struct ieee80211_node *
1674iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
1675{
1676 return malloc(sizeof (struct iwn_node), M_80211_NODE,M_NOWAIT | M_ZERO);
1677}
1678
1679void
1680iwn_newassoc(struct ieee80211_node *ni, int isnew)
1681{
1682 struct ieee80211vap *vap = ni->ni_vap;
1850struct ieee80211_node *
1851iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
1852{
1853 return malloc(sizeof (struct iwn_node), M_80211_NODE,M_NOWAIT | M_ZERO);
1854}
1855
1856void
1857iwn_newassoc(struct ieee80211_node *ni, int isnew)
1858{
1859 struct ieee80211vap *vap = ni->ni_vap;
1860 struct iwn_node *wn = (void *)ni;
1683
1684 ieee80211_amrr_node_init(&IWN_VAP(vap)->iv_amrr,
1861
1862 ieee80211_amrr_node_init(&IWN_VAP(vap)->iv_amrr,
1685 &IWN_NODE(ni)->amn, ni);
1863 &wn->amn, ni);
1686}
1687
1688int
1689iwn_media_change(struct ifnet *ifp)
1690{
1691 int error = ieee80211_media_change(ifp);
1692 /* NB: only the fixed rate can change and that doesn't need a reset */
1693 return (error == ENETRESET ? 0 : error);

--- 58 unchanged lines hidden (view full) ---

1752 memcpy(&sc->last_rx_stat, stat, sizeof (*stat));
1753 sc->last_rx_valid = 1;
1754}
1755
1756static void
1757iwn_timer_timeout(void *arg)
1758{
1759 struct iwn_softc *sc = arg;
1864}
1865
1866int
1867iwn_media_change(struct ifnet *ifp)
1868{
1869 int error = ieee80211_media_change(ifp);
1870 /* NB: only the fixed rate can change and that doesn't need a reset */
1871 return (error == ENETRESET ? 0 : error);

--- 58 unchanged lines hidden (view full) ---

1930 memcpy(&sc->last_rx_stat, stat, sizeof (*stat));
1931 sc->last_rx_valid = 1;
1932}
1933
1934static void
1935iwn_timer_timeout(void *arg)
1936{
1937 struct iwn_softc *sc = arg;
1938 uint32_t flags = 0;
1760
1761 IWN_LOCK_ASSERT(sc);
1762
1763 if (sc->calib_cnt && --sc->calib_cnt == 0) {
1764 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s\n",
1765 "send statistics request");
1939
1940 IWN_LOCK_ASSERT(sc);
1941
1942 if (sc->calib_cnt && --sc->calib_cnt == 0) {
1943 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s\n",
1944 "send statistics request");
1766 (void) iwn_cmd(sc, IWN_CMD_GET_STATISTICS, NULL, 0, 1);
1945 (void) iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags,
1946 sizeof flags, 1);
1767 sc->calib_cnt = 60; /* do calibration every 60s */
1768 }
1769 iwn_watchdog(sc); /* NB: piggyback tx watchdog */
1770 callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
1771}
1772
1773static void
1774iwn_calib_reset(struct iwn_softc *sc)
1775{
1776 callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
1777 sc->calib_cnt = 60; /* do calibration every 60s */
1778}
1779
1947 sc->calib_cnt = 60; /* do calibration every 60s */
1948 }
1949 iwn_watchdog(sc); /* NB: piggyback tx watchdog */
1950 callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
1951}
1952
1953static void
1954iwn_calib_reset(struct iwn_softc *sc)
1955{
1956 callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
1957 sc->calib_cnt = 60; /* do calibration every 60s */
1958}
1959
1780static __inline int
1781maprate(int iwnrate)
1782{
1783 switch (iwnrate) {
1784 /* CCK rates */
1785 case 10: return 2;
1786 case 20: return 4;
1787 case 55: return 11;
1788 case 110: return 22;
1789 /* OFDM rates */
1790 case 0xd: return 12;
1791 case 0xf: return 18;
1792 case 0x5: return 24;
1793 case 0x7: return 36;
1794 case 0x9: return 48;
1795 case 0xb: return 72;
1796 case 0x1: return 96;
1797 case 0x3: return 108;
1798 /* XXX MCS */
1799 }
1800 /* unknown rate: should not happen */
1801 return 0;
1802}
1803
1804/*
1805 * Process an RX_DONE (4965AGN only) or MPDU_RX_DONE firmware notification.
1806 * Each MPDU_RX_DONE notification must be preceded by an RX_PHY one.
1807 */
1808void
1809iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
1810 struct iwn_rx_data *data)
1811{

--- 9 unchanged lines hidden (view full) ---

1821 bus_addr_t paddr;
1822 uint32_t flags;
1823 int error, len, rssi, nf;
1824
1825 if (desc->type == IWN_MPDU_RX_DONE) {
1826 /* Check for prior RX_PHY notification. */
1827 if (!sc->last_rx_valid) {
1828 DPRINTF(sc, IWN_DEBUG_ANY,
1960/*
1961 * Process an RX_DONE (4965AGN only) or MPDU_RX_DONE firmware notification.
1962 * Each MPDU_RX_DONE notification must be preceded by an RX_PHY one.
1963 */
1964void
1965iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
1966 struct iwn_rx_data *data)
1967{

--- 9 unchanged lines hidden (view full) ---

1977 bus_addr_t paddr;
1978 uint32_t flags;
1979 int error, len, rssi, nf;
1980
1981 if (desc->type == IWN_MPDU_RX_DONE) {
1982 /* Check for prior RX_PHY notification. */
1983 if (!sc->last_rx_valid) {
1984 DPRINTF(sc, IWN_DEBUG_ANY,
1829 "%s: missing AMPDU_RX_START\n", __func__);
1985 "%s: missing RX_PHY\n", __func__);
1830 ifp->if_ierrors++;
1831 return;
1832 }
1833 sc->last_rx_valid = 0;
1834 stat = &sc->last_rx_stat;
1835 } else
1836 stat = (struct iwn_rx_stat *)(desc + 1);
1837
1986 ifp->if_ierrors++;
1987 return;
1988 }
1989 sc->last_rx_valid = 0;
1990 stat = &sc->last_rx_stat;
1991 } else
1992 stat = (struct iwn_rx_stat *)(desc + 1);
1993
1838 bus_dmamap_sync(ring->desc_dma.tag, data->map, BUS_DMASYNC_POSTREAD);
1994 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD);
1839
1840 if (stat->cfg_phy_len > IWN_STAT_MAXLEN) {
1841 device_printf(sc->sc_dev,
1842 "%s: invalid rx statistic header, len %d\n",
1843 __func__, stat->cfg_phy_len);
1844 ifp->if_ierrors++;
1845 return;
1846 }

--- 26 unchanged lines hidden (view full) ---

1873 /* XXX don't need mbuf, just dma buffer */
1874 m1 = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
1875 if (m1 == NULL) {
1876 DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n",
1877 __func__);
1878 ifp->if_ierrors++;
1879 return;
1880 }
1995
1996 if (stat->cfg_phy_len > IWN_STAT_MAXLEN) {
1997 device_printf(sc->sc_dev,
1998 "%s: invalid rx statistic header, len %d\n",
1999 __func__, stat->cfg_phy_len);
2000 ifp->if_ierrors++;
2001 return;
2002 }

--- 26 unchanged lines hidden (view full) ---

2029 /* XXX don't need mbuf, just dma buffer */
2030 m1 = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
2031 if (m1 == NULL) {
2032 DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n",
2033 __func__);
2034 ifp->if_ierrors++;
2035 return;
2036 }
1881 error = bus_dmamap_load(ring->desc_dma.tag, data->map,
2037 bus_dmamap_unload(ring->data_dmat, data->map);
2038
2039 error = bus_dmamap_load(ring->data_dmat, data->map,
1882 mtod(m1, caddr_t), MJUMPAGESIZE,
1883 iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
1884 if (error != 0 && error != EFBIG) {
1885 device_printf(sc->sc_dev,
1886 "%s: bus_dmamap_load failed, error %d\n", __func__, error);
1887 m_freem(m1);
1888 ifp->if_ierrors++;
1889 return;
1890 }
1891
1892 m = data->m;
1893 data->m = m1;
1894 /* Update RX descriptor. */
1895 ring->desc[ring->cur] = htole32(paddr >> 8);
2040 mtod(m1, caddr_t), MJUMPAGESIZE,
2041 iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
2042 if (error != 0 && error != EFBIG) {
2043 device_printf(sc->sc_dev,
2044 "%s: bus_dmamap_load failed, error %d\n", __func__, error);
2045 m_freem(m1);
2046 ifp->if_ierrors++;
2047 return;
2048 }
2049
2050 m = data->m;
2051 data->m = m1;
2052 /* Update RX descriptor. */
2053 ring->desc[ring->cur] = htole32(paddr >> 8);
1896 bus_dmamap_sync(ring->desc_dma.tag, data->map, BUS_DMASYNC_PREWRITE);
2054 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
2055 BUS_DMASYNC_PREWRITE);
1897
1898 /* Finalize mbuf. */
1899 m->m_pkthdr.rcvif = ifp;
1900 m->m_data = head;
1901 m->m_pkthdr.len = m->m_len = len;
1902
1903 rssi = hal->get_rssi(sc, stat);
1904
1905 /* Grab a reference to the source node. */
1906 wh = mtod(m, struct ieee80211_frame *);
1907 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
1908 nf = (ni != NULL && ni->ni_vap->iv_state == IEEE80211_S_RUN &&
1909 (ic->ic_flags & IEEE80211_F_SCAN) == 0) ? sc->noise : -95;
1910
1911 if (ieee80211_radiotap_active(ic)) {
1912 struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
1913
1914 tap->wr_tsft = htole64(stat->tstamp);
1915 tap->wr_flags = 0;
2056
2057 /* Finalize mbuf. */
2058 m->m_pkthdr.rcvif = ifp;
2059 m->m_data = head;
2060 m->m_pkthdr.len = m->m_len = len;
2061
2062 rssi = hal->get_rssi(sc, stat);
2063
2064 /* Grab a reference to the source node. */
2065 wh = mtod(m, struct ieee80211_frame *);
2066 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
2067 nf = (ni != NULL && ni->ni_vap->iv_state == IEEE80211_S_RUN &&
2068 (ic->ic_flags & IEEE80211_F_SCAN) == 0) ? sc->noise : -95;
2069
2070 if (ieee80211_radiotap_active(ic)) {
2071 struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
2072
2073 tap->wr_tsft = htole64(stat->tstamp);
2074 tap->wr_flags = 0;
1916 if (stat->flags & htole16(IWN_RXON_SHPREAMBLE))
2075 if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE))
1917 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
2076 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
1918 tap->wr_rate = maprate(stat->rate);
2077 switch (stat->rate) {
2078 /* CCK rates. */
2079 case 10: tap->wr_rate = 2; break;
2080 case 20: tap->wr_rate = 4; break;
2081 case 55: tap->wr_rate = 11; break;
2082 case 110: tap->wr_rate = 22; break;
2083 /* OFDM rates. */
2084 case 0xd: tap->wr_rate = 12; break;
2085 case 0xf: tap->wr_rate = 18; break;
2086 case 0x5: tap->wr_rate = 24; break;
2087 case 0x7: tap->wr_rate = 36; break;
2088 case 0x9: tap->wr_rate = 48; break;
2089 case 0xb: tap->wr_rate = 72; break;
2090 case 0x1: tap->wr_rate = 96; break;
2091 case 0x3: tap->wr_rate = 108; break;
2092 /* Unknown rate: should not happen. */
2093 default: tap->wr_rate = 0;
2094 }
1919 tap->wr_dbm_antsignal = rssi;
1920 tap->wr_dbm_antnoise = nf;
1921 }
1922
1923 IWN_UNLOCK(sc);
1924
1925 /* Send the frame to the 802.11 layer. */
1926 if (ni != NULL) {
1927 (void) ieee80211_input(ni, m, rssi - nf, nf);
1928 /* Node is no longer needed. */
1929 ieee80211_free_node(ni);
1930 } else
1931 (void) ieee80211_input_all(ic, m, rssi - nf, nf);
1932
1933 IWN_LOCK(sc);
1934}
1935
2095 tap->wr_dbm_antsignal = rssi;
2096 tap->wr_dbm_antnoise = nf;
2097 }
2098
2099 IWN_UNLOCK(sc);
2100
2101 /* Send the frame to the 802.11 layer. */
2102 if (ni != NULL) {
2103 (void) ieee80211_input(ni, m, rssi - nf, nf);
2104 /* Node is no longer needed. */
2105 ieee80211_free_node(ni);
2106 } else
2107 (void) ieee80211_input_all(ic, m, rssi - nf, nf);
2108
2109 IWN_LOCK(sc);
2110}
2111
2112#if 0 /* HT */
2113/* Process an incoming Compressed BlockAck. */
2114void
2115iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,
2116 struct iwn_rx_data *data)
2117{
2118 struct iwn_compressed_ba *ba = (struct iwn_compressed_ba *)(desc + 1);
2119 struct iwn_tx_ring *txq;
2120
2121 txq = &sc->txq[letoh16(ba->qid)];
2122 /* XXX TBD */
2123}
2124#endif
2125
1936/*
1937 * Process a CALIBRATION_RESULT notification sent by the initialization
1938 * firmware on response to a CMD_CALIB_CONFIG command (5000 only.)
1939 */
1940void
1941iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
1942 struct iwn_rx_data *data)
1943{
1944 struct iwn_phy_calib *calib = (struct iwn_phy_calib *)(desc + 1);
1945 int len, idx = -1;
1946
1947 /* Runtime firmware should not send such a notification. */
2126/*
2127 * Process a CALIBRATION_RESULT notification sent by the initialization
2128 * firmware on response to a CMD_CALIB_CONFIG command (5000 only.)
2129 */
2130void
2131iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
2132 struct iwn_rx_data *data)
2133{
2134 struct iwn_phy_calib *calib = (struct iwn_phy_calib *)(desc + 1);
2135 int len, idx = -1;
2136
2137 /* Runtime firmware should not send such a notification. */
1948 if (!(sc->sc_flags & IWN_FLAG_FIRST_BOOT))
2138 if (sc->sc_flags & IWN_FLAG_CALIB_DONE)
1949 return;
1950
1951 len = (le32toh(desc->len) & 0x3fff) - 4;
1952
1953 switch (calib->code) {
1954 case IWN5000_PHY_CALIB_DC:
1955 if (sc->hw_type == IWN_HW_REV_TYPE_5150)
1956 idx = 0;
1957 break;
1958 case IWN5000_PHY_CALIB_LO:
1959 idx = 1;
1960 break;
1961 case IWN5000_PHY_CALIB_TX_IQ:
1962 idx = 2;
1963 break;
2139 return;
2140
2141 len = (le32toh(desc->len) & 0x3fff) - 4;
2142
2143 switch (calib->code) {
2144 case IWN5000_PHY_CALIB_DC:
2145 if (sc->hw_type == IWN_HW_REV_TYPE_5150)
2146 idx = 0;
2147 break;
2148 case IWN5000_PHY_CALIB_LO:
2149 idx = 1;
2150 break;
2151 case IWN5000_PHY_CALIB_TX_IQ:
2152 idx = 2;
2153 break;
1964 case IWN5000_PHY_CALIB_TX_IQ_PERD:
1965 if (sc->hw_type != IWN_HW_REV_TYPE_5150)
2154 case IWN5000_PHY_CALIB_TX_IQ_PERIODIC:
2155 if (sc->hw_type < IWN_HW_REV_TYPE_6000 &&
2156 sc->hw_type != IWN_HW_REV_TYPE_5150)
1966 idx = 3;
1967 break;
1968 case IWN5000_PHY_CALIB_BASE_BAND:
1969 idx = 4;
1970 break;
1971 }
1972 if (idx == -1) /* Ignore other results. */
1973 return;

--- 77 unchanged lines hidden (view full) ---

2051void
2052iwn4965_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
2053 struct iwn_rx_data *data)
2054{
2055 struct iwn4965_tx_stat *stat = (struct iwn4965_tx_stat *)(desc + 1);
2056
2057 DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
2058 "qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
2157 idx = 3;
2158 break;
2159 case IWN5000_PHY_CALIB_BASE_BAND:
2160 idx = 4;
2161 break;
2162 }
2163 if (idx == -1) /* Ignore other results. */
2164 return;

--- 77 unchanged lines hidden (view full) ---

2242void
2243iwn4965_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
2244 struct iwn_rx_data *data)
2245{
2246 struct iwn4965_tx_stat *stat = (struct iwn4965_tx_stat *)(desc + 1);
2247
2248 DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
2249 "qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
2059 __func__, desc->qid, desc->idx, stat->retrycnt,
2060 stat->killcnt, stat->rate, le16toh(stat->duration),
2250 __func__, desc->qid, desc->idx, stat->ackfailcnt,
2251 stat->btkillcnt, stat->rate, le16toh(stat->duration),
2061 le32toh(stat->status));
2252 le32toh(stat->status));
2062 iwn_tx_done(sc, desc, stat->retrycnt, le32toh(stat->status) & 0xff);
2253
2254 iwn_tx_done(sc, desc, stat->ackfailcnt, le32toh(stat->status) & 0xff);
2063}
2064
2065void
2066iwn5000_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
2067 struct iwn_rx_data *data)
2068{
2069 struct iwn5000_tx_stat *stat = (struct iwn5000_tx_stat *)(desc + 1);
2070
2071 DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
2072 "qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
2255}
2256
2257void
2258iwn5000_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
2259 struct iwn_rx_data *data)
2260{
2261 struct iwn5000_tx_stat *stat = (struct iwn5000_tx_stat *)(desc + 1);
2262
2263 DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
2264 "qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
2073 __func__, desc->qid, desc->idx, stat->retrycnt,
2074 stat->killcnt, stat->rate, le16toh(stat->duration),
2265 __func__, desc->qid, desc->idx, stat->ackfailcnt,
2266 stat->btkillcnt, stat->rate, le16toh(stat->duration),
2075 le32toh(stat->status));
2076
2267 le32toh(stat->status));
2268
2269#ifdef notyet
2077 /* Reset TX scheduler slot. */
2078 iwn5000_reset_sched(sc, desc->qid & 0xf, desc->idx);
2270 /* Reset TX scheduler slot. */
2271 iwn5000_reset_sched(sc, desc->qid & 0xf, desc->idx);
2079 iwn_tx_done(sc, desc, stat->retrycnt, le16toh(stat->status) & 0xff);
2272#endif
2273 iwn_tx_done(sc, desc, stat->ackfailcnt, le16toh(stat->status) & 0xff);
2080}
2081
2082/*
2083 * Adapter-independent backend for TX_DONE firmware notifications.
2084 */
2085void
2274}
2275
2276/*
2277 * Adapter-independent backend for TX_DONE firmware notifications.
2278 */
2279void
2086iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int retrycnt,
2280iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
2087 uint8_t status)
2088{
2089 struct ifnet *ifp = sc->sc_ifp;
2090 struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
2091 struct iwn_tx_data *data = &ring->data[desc->idx];
2281 uint8_t status)
2282{
2283 struct ifnet *ifp = sc->sc_ifp;
2284 struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
2285 struct iwn_tx_data *data = &ring->data[desc->idx];
2286 struct iwn_node *wn = (void *)data->ni;
2092 struct mbuf *m;
2093 struct ieee80211_node *ni;
2094
2095 KASSERT(data->ni != NULL, ("no node"));
2096
2097 /* Unmap and free mbuf. */
2287 struct mbuf *m;
2288 struct ieee80211_node *ni;
2289
2290 KASSERT(data->ni != NULL, ("no node"));
2291
2292 /* Unmap and free mbuf. */
2098 bus_dmamap_sync(ring->desc_dma.tag, data->map, BUS_DMASYNC_POSTWRITE);
2099 bus_dmamap_unload(ring->desc_dma.tag, data->map);
2293 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTWRITE);
2294 bus_dmamap_unload(ring->data_dmat, data->map);
2100 m = data->m, data->m = NULL;
2101 ni = data->ni, data->ni = NULL;
2102
2103 if (m->m_flags & M_TXCB) {
2104 /*
2105 * Channels marked for "radar" require traffic to be received
2106 * to unlock before we can transmit. Until traffic is seen
2107 * any attempt to transmit is returned immediately with status

--- 9 unchanged lines hidden (view full) ---

2117 */
2118 if (status == IWN_TX_FAIL_TX_LOCKED &&
2119 ni->ni_vap->iv_state == IEEE80211_S_AUTH)
2120 ieee80211_process_callback(ni, m, 0);
2121 else
2122 ieee80211_process_callback(ni, m,
2123 (status & IWN_TX_FAIL) != 0);
2124 }
2295 m = data->m, data->m = NULL;
2296 ni = data->ni, data->ni = NULL;
2297
2298 if (m->m_flags & M_TXCB) {
2299 /*
2300 * Channels marked for "radar" require traffic to be received
2301 * to unlock before we can transmit. Until traffic is seen
2302 * any attempt to transmit is returned immediately with status

--- 9 unchanged lines hidden (view full) ---

2312 */
2313 if (status == IWN_TX_FAIL_TX_LOCKED &&
2314 ni->ni_vap->iv_state == IEEE80211_S_AUTH)
2315 ieee80211_process_callback(ni, m, 0);
2316 else
2317 ieee80211_process_callback(ni, m,
2318 (status & IWN_TX_FAIL) != 0);
2319 }
2320
2321 /*
2322 * Update rate control statistics for the node.
2323 */
2324 if (status & 0x80) {
2325 ifp->if_oerrors++;
2326 ieee80211_amrr_tx_complete(&wn->amn,
2327 IEEE80211_AMRR_FAILURE, ackfailcnt);
2328 } else {
2329 ieee80211_amrr_tx_complete(&wn->amn,
2330 IEEE80211_AMRR_SUCCESS, ackfailcnt);
2331 }
2125 m_freem(m);
2126 ieee80211_free_node(ni);
2127
2128 sc->sc_tx_timer = 0;
2129 if (--ring->queued < IWN_TX_RING_LOMARK) {
2130 sc->qfullmsk &= ~(1 << ring->qid);
2131 if (sc->qfullmsk == 0 &&
2132 (ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
2332 m_freem(m);
2333 ieee80211_free_node(ni);
2334
2335 sc->sc_tx_timer = 0;
2336 if (--ring->queued < IWN_TX_RING_LOMARK) {
2337 sc->qfullmsk &= ~(1 << ring->qid);
2338 if (sc->qfullmsk == 0 &&
2339 (ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
2133 printf("hier :(\n");
2134 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
2135 iwn_start_locked(ifp);
2136 }
2137 }
2138}
2139
2140/*
2141 * Process a "command done" firmware notification. This is where we wakeup

--- 7 unchanged lines hidden (view full) ---

2149
2150 if ((desc->qid & 0xf) != 4)
2151 return; /* Not a command ack. */
2152
2153 data = &ring->data[desc->idx];
2154
2155 /* If the command was mapped in an mbuf, free it. */
2156 if (data->m != NULL) {
2340 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
2341 iwn_start_locked(ifp);
2342 }
2343 }
2344}
2345
2346/*
2347 * Process a "command done" firmware notification. This is where we wakeup

--- 7 unchanged lines hidden (view full) ---

2355
2356 if ((desc->qid & 0xf) != 4)
2357 return; /* Not a command ack. */
2358
2359 data = &ring->data[desc->idx];
2360
2361 /* If the command was mapped in an mbuf, free it. */
2362 if (data->m != NULL) {
2157 bus_dmamap_sync(ring->desc_dma.tag, data->map,
2158 BUS_DMASYNC_POSTWRITE);
2159 bus_dmamap_unload(ring->desc_dma.tag, data->map);
2363 bus_dmamap_unload(ring->data_dmat, data->map);
2160 m_freem(data->m);
2161 data->m = NULL;
2162 }
2163 wakeup(&ring->desc[desc->idx]);
2164}
2165
2166/*
2167 * Process an INT_FH_RX or INT_SW_RX interrupt.

--- 9 unchanged lines hidden (view full) ---

2177 bus_dmamap_sync(sc->rxq.stat_dma.tag, sc->rxq.stat_dma.map,
2178 BUS_DMASYNC_POSTREAD);
2179
2180 hw = le16toh(sc->rxq.stat->closed_count) & 0xfff;
2181 while (sc->rxq.cur != hw) {
2182 struct iwn_rx_data *data = &sc->rxq.data[sc->rxq.cur];
2183 struct iwn_rx_desc *desc;
2184
2364 m_freem(data->m);
2365 data->m = NULL;
2366 }
2367 wakeup(&ring->desc[desc->idx]);
2368}
2369
2370/*
2371 * Process an INT_FH_RX or INT_SW_RX interrupt.

--- 9 unchanged lines hidden (view full) ---

2381 bus_dmamap_sync(sc->rxq.stat_dma.tag, sc->rxq.stat_dma.map,
2382 BUS_DMASYNC_POSTREAD);
2383
2384 hw = le16toh(sc->rxq.stat->closed_count) & 0xfff;
2385 while (sc->rxq.cur != hw) {
2386 struct iwn_rx_data *data = &sc->rxq.data[sc->rxq.cur];
2387 struct iwn_rx_desc *desc;
2388
2185 bus_dmamap_sync(sc->rxq.stat_dma.tag, data->map,
2186 BUS_DMASYNC_PREWRITE);
2389 bus_dmamap_sync(sc->rxq.data_dmat, data->map,
2390 BUS_DMASYNC_POSTREAD);
2187 desc = mtod(data->m, struct iwn_rx_desc *);
2188
2189 DPRINTF(sc, IWN_DEBUG_RECV,
2190 "%s: qid %x idx %d flags %x type %d(%s) len %d\n",
2191 __func__, desc->qid & 0xf, desc->idx, desc->flags,
2192 desc->type, iwn_intr_str(desc->type),
2193 le16toh(desc->len));
2194

--- 6 unchanged lines hidden (view full) ---

2201 break;
2202
2203 case IWN_RX_DONE: /* 4965AGN only. */
2204 case IWN_MPDU_RX_DONE:
2205 /* An 802.11 frame has been received. */
2206 iwn_rx_done(sc, desc, data);
2207 break;
2208
2391 desc = mtod(data->m, struct iwn_rx_desc *);
2392
2393 DPRINTF(sc, IWN_DEBUG_RECV,
2394 "%s: qid %x idx %d flags %x type %d(%s) len %d\n",
2395 __func__, desc->qid & 0xf, desc->idx, desc->flags,
2396 desc->type, iwn_intr_str(desc->type),
2397 le16toh(desc->len));
2398

--- 6 unchanged lines hidden (view full) ---

2405 break;
2406
2407 case IWN_RX_DONE: /* 4965AGN only. */
2408 case IWN_MPDU_RX_DONE:
2409 /* An 802.11 frame has been received. */
2410 iwn_rx_done(sc, desc, data);
2411 break;
2412
2413#if 0 /* HT */
2414 case IWN_RX_COMPRESSED_BA:
2415 /* A Compressed BlockAck has been received. */
2416 iwn_rx_compressed_ba(sc, desc, data);
2417 break;
2418#endif
2419
2209 case IWN_TX_DONE:
2210 /* An 802.11 frame has been transmitted. */
2211 sc->sc_hal->tx_done(sc, desc, data);
2212 break;
2213
2214 case IWN_RX_STATISTICS:
2215 case IWN_BEACON_STATISTICS:
2216 iwn_rx_statistics(sc, desc, data);
2217 break;
2218
2219 case IWN_BEACON_MISSED:
2220 {
2221 struct iwn_beacon_missed *miss =
2222 (struct iwn_beacon_missed *)(desc + 1);
2223 int misses = le32toh(miss->consecutive);
2224
2420 case IWN_TX_DONE:
2421 /* An 802.11 frame has been transmitted. */
2422 sc->sc_hal->tx_done(sc, desc, data);
2423 break;
2424
2425 case IWN_RX_STATISTICS:
2426 case IWN_BEACON_STATISTICS:
2427 iwn_rx_statistics(sc, desc, data);
2428 break;
2429
2430 case IWN_BEACON_MISSED:
2431 {
2432 struct iwn_beacon_missed *miss =
2433 (struct iwn_beacon_missed *)(desc + 1);
2434 int misses = le32toh(miss->consecutive);
2435
2225 bus_dmamap_sync(sc->rxq.stat_dma.tag, data->map,
2226 BUS_DMASYNC_PREWRITE);
2436 bus_dmamap_sync(sc->rxq.data_dmat, data->map,
2437 BUS_DMASYNC_POSTREAD);
2438
2439 /* XXX not sure why we're notified w/ zero */
2440 if (misses == 0)
2441 break;
2227 DPRINTF(sc, IWN_DEBUG_STATE,
2228 "%s: beacons missed %d/%d\n", __func__,
2229 misses, le32toh(miss->total));
2230
2231 /*
2232 * If more than 5 consecutive beacons are missed,
2233 * reinitialize the sensitivity state machine.
2234 */
2235 if (vap->iv_state == IEEE80211_S_RUN && misses > 5)
2236 (void) iwn_init_sensitivity(sc);
2442 DPRINTF(sc, IWN_DEBUG_STATE,
2443 "%s: beacons missed %d/%d\n", __func__,
2444 misses, le32toh(miss->total));
2445
2446 /*
2447 * If more than 5 consecutive beacons are missed,
2448 * reinitialize the sensitivity state machine.
2449 */
2450 if (vap->iv_state == IEEE80211_S_RUN && misses > 5)
2451 (void) iwn_init_sensitivity(sc);
2237 if (misses >= vap->iv_bmissthreshold)
2452 if (misses >= vap->iv_bmissthreshold) {
2453 IWN_UNLOCK(sc);
2238 ieee80211_beacon_miss(ic);
2454 ieee80211_beacon_miss(ic);
2455 IWN_LOCK(sc);
2456 }
2239 break;
2240 }
2241 case IWN_UC_READY:
2242 {
2243 struct iwn_ucode_info *uc =
2244 (struct iwn_ucode_info *)(desc + 1);
2245
2246 /* The microcontroller is ready. */
2457 break;
2458 }
2459 case IWN_UC_READY:
2460 {
2461 struct iwn_ucode_info *uc =
2462 (struct iwn_ucode_info *)(desc + 1);
2463
2464 /* The microcontroller is ready. */
2247 bus_dmamap_sync(sc->rxq.stat_dma.tag, data->map,
2248 BUS_DMASYNC_PREWRITE);
2465 bus_dmamap_sync(sc->rxq.data_dmat, data->map,
2466 BUS_DMASYNC_POSTREAD);
2249 DPRINTF(sc, IWN_DEBUG_RESET,
2250 "microcode alive notification version=%d.%d "
2251 "subtype=%x alive=%x\n", uc->major, uc->minor,
2252 uc->subtype, le32toh(uc->valid));
2253
2254 if (le32toh(uc->valid) != 1) {
2255 device_printf(sc->sc_dev,
2256 "microcontroller initialization failed");
2257 break;
2258 }
2259 if (uc->subtype == IWN_UCODE_INIT) {
2467 DPRINTF(sc, IWN_DEBUG_RESET,
2468 "microcode alive notification version=%d.%d "
2469 "subtype=%x alive=%x\n", uc->major, uc->minor,
2470 uc->subtype, le32toh(uc->valid));
2471
2472 if (le32toh(uc->valid) != 1) {
2473 device_printf(sc->sc_dev,
2474 "microcontroller initialization failed");
2475 break;
2476 }
2477 if (uc->subtype == IWN_UCODE_INIT) {
2260 /* Save microcontroller's report. */
2478 /* Save microcontroller report. */
2261 memcpy(&sc->ucode_info, uc, sizeof (*uc));
2262 }
2263 /* Save the address of the error log in SRAM. */
2264 sc->errptr = le32toh(uc->errptr);
2265 break;
2266 }
2267 case IWN_STATE_CHANGED:
2268 {
2269 uint32_t *status = (uint32_t *)(desc + 1);
2270
2271 /*
2272 * State change allows hardware switch change to be
2273 * noted. However, we handle this in iwn_intr as we
2274 * get both the enable/disble intr.
2275 */
2479 memcpy(&sc->ucode_info, uc, sizeof (*uc));
2480 }
2481 /* Save the address of the error log in SRAM. */
2482 sc->errptr = le32toh(uc->errptr);
2483 break;
2484 }
2485 case IWN_STATE_CHANGED:
2486 {
2487 uint32_t *status = (uint32_t *)(desc + 1);
2488
2489 /*
2490 * State change allows hardware switch change to be
2491 * noted. However, we handle this in iwn_intr as we
2492 * get both the enable/disble intr.
2493 */
2276 bus_dmamap_sync(sc->rxq.stat_dma.tag, data->map,
2277 BUS_DMASYNC_PREWRITE);
2494 bus_dmamap_sync(sc->rxq.data_dmat, data->map,
2495 BUS_DMASYNC_POSTREAD);
2278 DPRINTF(sc, IWN_DEBUG_INTR, "state changed to %x\n",
2279 le32toh(*status));
2280 break;
2281 }
2282 case IWN_START_SCAN:
2283 {
2284 struct iwn_start_scan *scan =
2285 (struct iwn_start_scan *)(desc + 1);
2286
2496 DPRINTF(sc, IWN_DEBUG_INTR, "state changed to %x\n",
2497 le32toh(*status));
2498 break;
2499 }
2500 case IWN_START_SCAN:
2501 {
2502 struct iwn_start_scan *scan =
2503 (struct iwn_start_scan *)(desc + 1);
2504
2287 bus_dmamap_sync(sc->rxq.stat_dma.tag, data->map,
2288 BUS_DMASYNC_PREWRITE);
2505 bus_dmamap_sync(sc->rxq.data_dmat, data->map,
2506 BUS_DMASYNC_POSTREAD);
2289 DPRINTF(sc, IWN_DEBUG_ANY,
2290 "%s: scanning channel %d status %x\n",
2291 __func__, scan->chan, le32toh(scan->status));
2292 break;
2293 }
2294 case IWN_STOP_SCAN:
2295 {
2296 struct iwn_stop_scan *scan =
2297 (struct iwn_stop_scan *)(desc + 1);
2298
2507 DPRINTF(sc, IWN_DEBUG_ANY,
2508 "%s: scanning channel %d status %x\n",
2509 __func__, scan->chan, le32toh(scan->status));
2510 break;
2511 }
2512 case IWN_STOP_SCAN:
2513 {
2514 struct iwn_stop_scan *scan =
2515 (struct iwn_stop_scan *)(desc + 1);
2516
2299 bus_dmamap_sync(sc->rxq.stat_dma.tag, data->map,
2300 BUS_DMASYNC_PREWRITE);
2517 bus_dmamap_sync(sc->rxq.data_dmat, data->map,
2518 BUS_DMASYNC_POSTREAD);
2301 DPRINTF(sc, IWN_DEBUG_STATE,
2302 "scan finished nchan=%d status=%d chan=%d\n",
2303 scan->nchan, scan->status, scan->chan);
2304
2519 DPRINTF(sc, IWN_DEBUG_STATE,
2520 "scan finished nchan=%d status=%d chan=%d\n",
2521 scan->nchan, scan->status, scan->chan);
2522
2523 IWN_UNLOCK(sc);
2305 ieee80211_scan_next(vap);
2524 ieee80211_scan_next(vap);
2525 IWN_LOCK(sc);
2306 break;
2307 }
2308 case IWN5000_CALIBRATION_RESULT:
2309 iwn5000_rx_calib_results(sc, desc, data);
2310 break;
2311
2312 case IWN5000_CALIBRATION_DONE:
2526 break;
2527 }
2528 case IWN5000_CALIBRATION_RESULT:
2529 iwn5000_rx_calib_results(sc, desc, data);
2530 break;
2531
2532 case IWN5000_CALIBRATION_DONE:
2533 sc->sc_flags |= IWN_FLAG_CALIB_DONE;
2313 wakeup(sc);
2314 break;
2315 }
2316
2317 sc->rxq.cur = (sc->rxq.cur + 1) % IWN_RX_RING_COUNT;
2318 }
2319
2320 /* Tell the firmware what we have processed. */

--- 10 unchanged lines hidden (view full) ---

2331{
2332 int qid;
2333
2334 DPRINTF(sc, IWN_DEBUG_RESET, "%s: ucode wakeup from power-down sleep\n",
2335 __func__);
2336
2337 /* Wakeup RX and TX rings. */
2338 IWN_WRITE(sc, IWN_FH_RX_WPTR, sc->rxq.cur & ~7);
2534 wakeup(sc);
2535 break;
2536 }
2537
2538 sc->rxq.cur = (sc->rxq.cur + 1) % IWN_RX_RING_COUNT;
2539 }
2540
2541 /* Tell the firmware what we have processed. */

--- 10 unchanged lines hidden (view full) ---

2552{
2553 int qid;
2554
2555 DPRINTF(sc, IWN_DEBUG_RESET, "%s: ucode wakeup from power-down sleep\n",
2556 __func__);
2557
2558 /* Wakeup RX and TX rings. */
2559 IWN_WRITE(sc, IWN_FH_RX_WPTR, sc->rxq.cur & ~7);
2339 for (qid = 0; qid < 6; qid++) {
2560 for (qid = 0; qid < sc->sc_hal->ntxqs; qid++) {
2340 struct iwn_tx_ring *ring = &sc->txq[qid];
2341 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | ring->cur);
2342 }
2343}
2344
2345void
2346iwn_rftoggle_intr(struct iwn_softc *sc)
2347{

--- 12 unchanged lines hidden (view full) ---

2360}
2361
2362/*
2363 * Dump the error log of the firmware when a firmware panic occurs. Although
2364 * we can't debug the firmware because it is neither open source nor free, it
2365 * can help us to identify certain classes of problems.
2366 */
2367void
2561 struct iwn_tx_ring *ring = &sc->txq[qid];
2562 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | ring->cur);
2563 }
2564}
2565
2566void
2567iwn_rftoggle_intr(struct iwn_softc *sc)
2568{

--- 12 unchanged lines hidden (view full) ---

2581}
2582
2583/*
2584 * Dump the error log of the firmware when a firmware panic occurs. Although
2585 * we can't debug the firmware because it is neither open source nor free, it
2586 * can help us to identify certain classes of problems.
2587 */
2588void
2368iwn_fatal_intr(struct iwn_softc *sc, uint32_t r1, uint32_t r2)
2589iwn_fatal_intr(struct iwn_softc *sc)
2369{
2590{
2370#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
2371 const struct iwn_hal *hal = sc->sc_hal;
2591 const struct iwn_hal *hal = sc->sc_hal;
2372 struct ifnet *ifp = sc->sc_ifp;
2373 struct ieee80211com *ic = ifp->if_l2com;
2374 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
2375 struct iwn_fw_dump dump;
2376 int i;
2377
2378 IWN_LOCK_ASSERT(sc);
2379
2592 struct iwn_fw_dump dump;
2593 int i;
2594
2595 IWN_LOCK_ASSERT(sc);
2596
2597 /* Force a complete recalibration on next init. */
2598 sc->sc_flags &= ~IWN_FLAG_CALIB_DONE;
2599
2380 /* Check that the error log address is valid. */
2381 if (sc->errptr < IWN_FW_DATA_BASE ||
2382 sc->errptr + sizeof (dump) >
2383 IWN_FW_DATA_BASE + hal->fw_data_maxsz) {
2384 printf("%s: bad firmware error log address 0x%08x\n",
2385 __func__, sc->errptr);
2386 return;
2387 }

--- 30 unchanged lines hidden (view full) ---

2418 /* Dump driver status (TX and RX rings) while we're here. */
2419 printf("driver status:\n");
2420 for (i = 0; i < hal->ntxqs; i++) {
2421 struct iwn_tx_ring *ring = &sc->txq[i];
2422 printf(" tx ring %2d: qid=%-2d cur=%-3d queued=%-3d\n",
2423 i, ring->qid, ring->cur, ring->queued);
2424 }
2425 printf(" rx ring: cur=%d\n", sc->rxq.cur);
2600 /* Check that the error log address is valid. */
2601 if (sc->errptr < IWN_FW_DATA_BASE ||
2602 sc->errptr + sizeof (dump) >
2603 IWN_FW_DATA_BASE + hal->fw_data_maxsz) {
2604 printf("%s: bad firmware error log address 0x%08x\n",
2605 __func__, sc->errptr);
2606 return;
2607 }

--- 30 unchanged lines hidden (view full) ---

2638 /* Dump driver status (TX and RX rings) while we're here. */
2639 printf("driver status:\n");
2640 for (i = 0; i < hal->ntxqs; i++) {
2641 struct iwn_tx_ring *ring = &sc->txq[i];
2642 printf(" tx ring %2d: qid=%-2d cur=%-3d queued=%-3d\n",
2643 i, ring->qid, ring->cur, ring->queued);
2644 }
2645 printf(" rx ring: cur=%d\n", sc->rxq.cur);
2426
2427 if (vap != NULL)
2428 ieee80211_cancel_scan(vap);
2429 ieee80211_runtask(ic, &sc->sc_reinit_task);
2430}
2431
2432void
2433iwn_intr(void *arg)
2434{
2435 struct iwn_softc *sc = arg;
2436 struct ifnet *ifp = sc->sc_ifp;
2646}
2647
2648void
2649iwn_intr(void *arg)
2650{
2651 struct iwn_softc *sc = arg;
2652 struct ifnet *ifp = sc->sc_ifp;
2437 uint32_t r1, r2;
2653 uint32_t r1, r2, tmp;
2438
2439 IWN_LOCK(sc);
2440
2441 /* Disable interrupts. */
2654
2655 IWN_LOCK(sc);
2656
2657 /* Disable interrupts. */
2442 IWN_WRITE(sc, IWN_MASK, 0);
2658 IWN_WRITE(sc, IWN_INT_MASK, 0);
2443
2659
2444 r1 = IWN_READ(sc, IWN_INT);
2445 r2 = IWN_READ(sc, IWN_FH_INT);
2660 /* Read interrupts from ICT (fast) or from registers (slow). */
2661 if (sc->sc_flags & IWN_FLAG_USE_ICT) {
2662 tmp = 0;
2663 while (sc->ict[sc->ict_cur] != 0) {
2664 tmp |= sc->ict[sc->ict_cur];
2665 sc->ict[sc->ict_cur] = 0; /* Acknowledge. */
2666 sc->ict_cur = (sc->ict_cur + 1) % IWN_ICT_COUNT;
2667 }
2668 tmp = le32toh(tmp);
2669 if (tmp == 0xffffffff)
2670 tmp = 0; /* Shouldn't happen. */
2671 r1 = (tmp & 0xff00) << 16 | (tmp & 0xff);
2672 r2 = 0; /* Unused. */
2673 } else {
2674 r1 = IWN_READ(sc, IWN_INT);
2675 if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
2676 return; /* Hardware gone! */
2677 r2 = IWN_READ(sc, IWN_FH_INT);
2678 }
2446
2447 DPRINTF(sc, IWN_DEBUG_INTR, "interrupt reg1=%x reg2=%x\n", r1, r2);
2448
2679
2680 DPRINTF(sc, IWN_DEBUG_INTR, "interrupt reg1=%x reg2=%x\n", r1, r2);
2681
2449 if (r1 == 0 && r2 == 0) {
2450 if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
2451 IWN_WRITE(sc, IWN_MASK, IWN_INT_MASK);
2682 if (r1 == 0 && r2 == 0)
2452 goto done; /* Interrupt not for us. */
2683 goto done; /* Interrupt not for us. */
2453 }
2454 if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
2455 goto done; /* Hardware gone! */
2456
2457 /* Acknowledge interrupts. */
2458 IWN_WRITE(sc, IWN_INT, r1);
2684
2685 /* Acknowledge interrupts. */
2686 IWN_WRITE(sc, IWN_INT, r1);
2459 IWN_WRITE(sc, IWN_FH_INT, r2);
2687 if (!(sc->sc_flags & IWN_FLAG_USE_ICT))
2688 IWN_WRITE(sc, IWN_FH_INT, r2);
2460
2689
2461 DPRINTF(sc, IWN_DEBUG_INTR, "interrupt reg1=%x reg2=%x\n", r1, r2);
2462
2463 if (r1 & IWN_INT_RF_TOGGLED) {
2464 iwn_rftoggle_intr(sc);
2690 if (r1 & IWN_INT_RF_TOGGLED) {
2691 iwn_rftoggle_intr(sc);
2692 goto done;
2465 }
2466 if (r1 & IWN_INT_CT_REACHED) {
2467 device_printf(sc->sc_dev, "%s: critical temperature reached!\n",
2468 __func__);
2693 }
2694 if (r1 & IWN_INT_CT_REACHED) {
2695 device_printf(sc->sc_dev, "%s: critical temperature reached!\n",
2696 __func__);
2469 /* XXX Reduce TX power? */
2470 }
2471 if (r1 & (IWN_INT_SW_ERR | IWN_INT_HW_ERR)) {
2697 }
2698 if (r1 & (IWN_INT_SW_ERR | IWN_INT_HW_ERR)) {
2472 iwn_fatal_intr(sc, r1, r2);
2699 iwn_fatal_intr(sc);
2700 ifp->if_flags &= ~IFF_UP;
2701 iwn_stop_locked(sc);
2473 goto done;
2474 }
2702 goto done;
2703 }
2475 if ((r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX)) ||
2476 (r2 & IWN_FH_INT_RX))
2477 iwn_notif_intr(sc);
2704 if ((r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX | IWN_INT_RX_PERIODIC)) ||
2705 (r2 & IWN_FH_INT_RX)) {
2706 if (sc->sc_flags & IWN_FLAG_USE_ICT) {
2707 if (r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX))
2708 IWN_WRITE(sc, IWN_FH_INT, IWN_FH_INT_RX);
2709 IWN_WRITE_1(sc, IWN_INT_PERIODIC,
2710 IWN_INT_PERIODIC_DIS);
2711 iwn_notif_intr(sc);
2712 if (r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX)) {
2713 IWN_WRITE_1(sc, IWN_INT_PERIODIC,
2714 IWN_INT_PERIODIC_ENA);
2715 }
2716 } else
2717 iwn_notif_intr(sc);
2718 }
2478
2719
2479 if ((r1 & IWN_INT_FH_TX) || (r2 & IWN_FH_INT_TX))
2720 if ((r1 & IWN_INT_FH_TX) || (r2 & IWN_FH_INT_TX)) {
2721 if (sc->sc_flags & IWN_FLAG_USE_ICT)
2722 IWN_WRITE(sc, IWN_FH_INT, IWN_FH_INT_TX);
2480 wakeup(sc); /* FH DMA transfer completed. */
2723 wakeup(sc); /* FH DMA transfer completed. */
2724 }
2481
2482 if (r1 & IWN_INT_ALIVE)
2483 wakeup(sc); /* Firmware is alive. */
2484
2485 if (r1 & IWN_INT_WAKEUP)
2486 iwn_wakeup_intr(sc);
2487
2725
2726 if (r1 & IWN_INT_ALIVE)
2727 wakeup(sc); /* Firmware is alive. */
2728
2729 if (r1 & IWN_INT_WAKEUP)
2730 iwn_wakeup_intr(sc);
2731
2732done:
2488 /* Re-enable interrupts. */
2733 /* Re-enable interrupts. */
2489 IWN_WRITE(sc, IWN_MASK, IWN_INT_MASK);
2734 if (ifp->if_flags & IFF_UP)
2735 IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
2490
2736
2491done:
2492 IWN_UNLOCK(sc);
2493}
2494
2495/*
2496 * Update TX scheduler ring when transmitting an 802.11 frame (4965AGN and
2497 * 5000 adapters use a slightly different format.)
2498 */
2499void
2500iwn4965_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
2501 uint16_t len)
2502{
2503 uint16_t *w = &sc->sched[qid * IWN4965_SCHED_COUNT + idx];
2504
2505 *w = htole16(len + 8);
2506 bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
2507 BUS_DMASYNC_PREWRITE);
2737 IWN_UNLOCK(sc);
2738}
2739
2740/*
2741 * Update TX scheduler ring when transmitting an 802.11 frame (4965AGN and
2742 * 5000 adapters use a slightly different format.)
2743 */
2744void
2745iwn4965_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
2746 uint16_t len)
2747{
2748 uint16_t *w = &sc->sched[qid * IWN4965_SCHED_COUNT + idx];
2749
2750 *w = htole16(len + 8);
2751 bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
2752 BUS_DMASYNC_PREWRITE);
2508 if (idx < IWN4965_SCHEDSZ) {
2753 if (idx < IWN_SCHED_WINSZ) {
2509 *(w + IWN_TX_RING_COUNT) = *w;
2510 bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
2511 BUS_DMASYNC_PREWRITE);
2512 }
2513}
2514
2515void
2516iwn5000_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,

--- 22 unchanged lines hidden (view full) ---

2539 BUS_DMASYNC_PREWRITE);
2540 if (idx < IWN_SCHED_WINSZ) {
2541 *(w + IWN_TX_RING_COUNT) = *w;
2542 bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
2543 BUS_DMASYNC_PREWRITE);
2544 }
2545}
2546
2754 *(w + IWN_TX_RING_COUNT) = *w;
2755 bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
2756 BUS_DMASYNC_PREWRITE);
2757 }
2758}
2759
2760void
2761iwn5000_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,

--- 22 unchanged lines hidden (view full) ---

2784 BUS_DMASYNC_PREWRITE);
2785 if (idx < IWN_SCHED_WINSZ) {
2786 *(w + IWN_TX_RING_COUNT) = *w;
2787 bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
2788 BUS_DMASYNC_PREWRITE);
2789 }
2790}
2791
2547/* Determine if a given rate is CCK or OFDM. */
2548#define IWN_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
2549
2550static const struct iwn_rate *
2792static uint8_t
2551iwn_plcp_signal(int rate) {
2552 int i;
2553
2554 for (i = 0; i < IWN_RIDX_MAX + 1; i++) {
2555 if (rate == iwn_rates[i].rate)
2793iwn_plcp_signal(int rate) {
2794 int i;
2795
2796 for (i = 0; i < IWN_RIDX_MAX + 1; i++) {
2797 if (rate == iwn_rates[i].rate)
2556 return &iwn_rates[i];
2798 return i;
2557 }
2558
2799 }
2800
2559 return &iwn_rates[0];
2801 return 0;
2560}
2561
2562int
2563iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
2564 struct iwn_tx_ring *ring)
2565{
2566 const struct iwn_hal *hal = sc->sc_hal;
2567 const struct ieee80211_txparam *tp;
2568 const struct iwn_rate *rinfo;
2569 struct ieee80211vap *vap = ni->ni_vap;
2570 struct ieee80211com *ic = ni->ni_ic;
2571 struct iwn_node *wn = (void *)ni;
2572 struct iwn_tx_desc *desc;
2573 struct iwn_tx_data *data;
2574 struct iwn_tx_cmd *cmd;
2575 struct iwn_cmd_data *tx;
2576 struct ieee80211_frame *wh;
2577 struct ieee80211_key *k = NULL;
2578 struct mbuf *mnew;
2802}
2803
2804int
2805iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
2806 struct iwn_tx_ring *ring)
2807{
2808 const struct iwn_hal *hal = sc->sc_hal;
2809 const struct ieee80211_txparam *tp;
2810 const struct iwn_rate *rinfo;
2811 struct ieee80211vap *vap = ni->ni_vap;
2812 struct ieee80211com *ic = ni->ni_ic;
2813 struct iwn_node *wn = (void *)ni;
2814 struct iwn_tx_desc *desc;
2815 struct iwn_tx_data *data;
2816 struct iwn_tx_cmd *cmd;
2817 struct iwn_cmd_data *tx;
2818 struct ieee80211_frame *wh;
2819 struct ieee80211_key *k = NULL;
2820 struct mbuf *mnew;
2579 bus_addr_t paddr;
2580 bus_dma_segment_t segs[IWN_MAX_SCATTER];
2581 uint32_t flags;
2582 u_int hdrlen;
2821 bus_dma_segment_t segs[IWN_MAX_SCATTER];
2822 uint32_t flags;
2823 u_int hdrlen;
2583 int totlen, error, pad, nsegs, i, rate;
2584 uint8_t type, txant;
2824 int totlen, error, pad, nsegs = 0, i, rate;
2825 uint8_t ridx, type, txant;
2585
2586 IWN_LOCK_ASSERT(sc);
2587
2588 wh = mtod(m, struct ieee80211_frame *);
2589 hdrlen = ieee80211_anyhdrsize(wh);
2590 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
2591
2592 desc = &ring->desc[ring->cur];
2593 data = &ring->data[ring->cur];
2594
2595 /* Choose a TX rate index. */
2826
2827 IWN_LOCK_ASSERT(sc);
2828
2829 wh = mtod(m, struct ieee80211_frame *);
2830 hdrlen = ieee80211_anyhdrsize(wh);
2831 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
2832
2833 desc = &ring->desc[ring->cur];
2834 data = &ring->data[ring->cur];
2835
2836 /* Choose a TX rate index. */
2596 /* XXX ni_chan */
2597 tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
2837 tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
2598 if (type == IEEE80211_FC0_TYPE_MGT)
2599 rate = tp->mgmtrate;
2600 else if (IEEE80211_IS_MULTICAST(wh->i_addr1))
2601 rate = tp->mcastrate;
2602 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
2603 rate = tp->ucastrate;
2604 else {
2838 if (type == IEEE80211_FC0_TYPE_MGT)
2839 rate = tp->mgmtrate;
2840 else if (IEEE80211_IS_MULTICAST(wh->i_addr1))
2841 rate = tp->mcastrate;
2842 else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
2843 rate = tp->ucastrate;
2844 else {
2605 (void) ieee80211_amrr_choose(ni, &IWN_NODE(ni)->amn);
2845 (void) ieee80211_amrr_choose(ni, &wn->amn);
2606 rate = ni->ni_txrate;
2607 }
2846 rate = ni->ni_txrate;
2847 }
2608 rinfo = iwn_plcp_signal(rate);
2848 ridx = iwn_plcp_signal(rate);
2849 rinfo = &iwn_rates[ridx];
2609
2610 /* Encrypt the frame if need be. */
2611 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
2612 k = ieee80211_crypto_encap(ni, m);
2613 if (k == NULL) {
2614 m_freem(m);
2615 return ENOBUFS;
2616 }
2617 /* Packet header may have moved, reset our local pointer. */
2618 wh = mtod(m, struct ieee80211_frame *);
2619 }
2620 totlen = m->m_pkthdr.len;
2621
2622 if (ieee80211_radiotap_active_vap(vap)) {
2623 struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
2624
2625 tap->wt_flags = 0;
2850
2851 /* Encrypt the frame if need be. */
2852 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
2853 k = ieee80211_crypto_encap(ni, m);
2854 if (k == NULL) {
2855 m_freem(m);
2856 return ENOBUFS;
2857 }
2858 /* Packet header may have moved, reset our local pointer. */
2859 wh = mtod(m, struct ieee80211_frame *);
2860 }
2861 totlen = m->m_pkthdr.len;
2862
2863 if (ieee80211_radiotap_active_vap(vap)) {
2864 struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
2865
2866 tap->wt_flags = 0;
2626 tap->wt_rate = rate;
2867 tap->wt_rate = rinfo->rate;
2627 if (k != NULL)
2628 tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
2629
2630 ieee80211_radiotap_tx(vap, m);
2631 }
2632
2633 /* Prepare TX firmware command. */
2634 cmd = &ring->cmd[ring->cur];

--- 18 unchanged lines hidden (view full) ---

2653 flags |= IWN_TX_MORE_FRAG; /* Cannot happen yet. */
2654
2655 /* Check if frame must be protected using RTS/CTS or CTS-to-self. */
2656 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2657 /* NB: Group frames are sent using CCK in 802.11b/g. */
2658 if (totlen + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) {
2659 flags |= IWN_TX_NEED_RTS;
2660 } else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
2868 if (k != NULL)
2869 tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
2870
2871 ieee80211_radiotap_tx(vap, m);
2872 }
2873
2874 /* Prepare TX firmware command. */
2875 cmd = &ring->cmd[ring->cur];

--- 18 unchanged lines hidden (view full) ---

2894 flags |= IWN_TX_MORE_FRAG; /* Cannot happen yet. */
2895
2896 /* Check if frame must be protected using RTS/CTS or CTS-to-self. */
2897 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2898 /* NB: Group frames are sent using CCK in 802.11b/g. */
2899 if (totlen + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) {
2900 flags |= IWN_TX_NEED_RTS;
2901 } else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
2661 IWN_RATE_IS_OFDM(rate)) {
2902 ridx >= IWN_RIDX_OFDM6) {
2662 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
2663 flags |= IWN_TX_NEED_CTS;
2664 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
2665 flags |= IWN_TX_NEED_RTS;
2666 }
2667 if (flags & (IWN_TX_NEED_RTS | IWN_TX_NEED_CTS)) {
2668 if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
2669 /* 5000 autoselects RTS/CTS or CTS-to-self. */
2670 flags &= ~(IWN_TX_NEED_RTS | IWN_TX_NEED_CTS);
2671 flags |= IWN_TX_NEED_PROTECTION;
2672 } else
2673 flags |= IWN_TX_FULL_TXOP;
2674 }
2903 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
2904 flags |= IWN_TX_NEED_CTS;
2905 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
2906 flags |= IWN_TX_NEED_RTS;
2907 }
2908 if (flags & (IWN_TX_NEED_RTS | IWN_TX_NEED_CTS)) {
2909 if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
2910 /* 5000 autoselects RTS/CTS or CTS-to-self. */
2911 flags &= ~(IWN_TX_NEED_RTS | IWN_TX_NEED_CTS);
2912 flags |= IWN_TX_NEED_PROTECTION;
2913 } else
2914 flags |= IWN_TX_FULL_TXOP;
2915 }
2675 } else
2916 }
2676
2677 if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
2678 type != IEEE80211_FC0_TYPE_DATA)
2679 tx->id = hal->broadcast_id;
2680 else
2681 tx->id = wn->id;
2682
2683 if (type == IEEE80211_FC0_TYPE_MGT) {

--- 7 unchanged lines hidden (view full) ---

2691 subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
2692 tx->timeout = htole16(3);
2693 else
2694 tx->timeout = htole16(2);
2695 } else
2696 tx->timeout = htole16(0);
2697
2698 if (hdrlen & 3) {
2917
2918 if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
2919 type != IEEE80211_FC0_TYPE_DATA)
2920 tx->id = hal->broadcast_id;
2921 else
2922 tx->id = wn->id;
2923
2924 if (type == IEEE80211_FC0_TYPE_MGT) {

--- 7 unchanged lines hidden (view full) ---

2932 subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
2933 tx->timeout = htole16(3);
2934 else
2935 tx->timeout = htole16(2);
2936 } else
2937 tx->timeout = htole16(0);
2938
2939 if (hdrlen & 3) {
2699 /* First segment's length must be a multiple of 4. */
2940 /* First segment length must be a multiple of 4. */
2700 flags |= IWN_TX_NEED_PADDING;
2701 pad = 4 - (hdrlen & 3);
2702 } else
2703 pad = 0;
2704
2705 tx->len = htole16(totlen);
2706 tx->tid = 0;
2941 flags |= IWN_TX_NEED_PADDING;
2942 pad = 4 - (hdrlen & 3);
2943 } else
2944 pad = 0;
2945
2946 tx->len = htole16(totlen);
2947 tx->tid = 0;
2707 tx->rts_ntries = 60; /* XXX? */
2708 tx->data_ntries = 15; /* XXX? */
2948 tx->rts_ntries = 60;
2949 tx->data_ntries = 15;
2709 tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
2710 tx->plcp = rinfo->plcp;
2711 tx->rflags = rinfo->flags;
2712 if (tx->id == hal->broadcast_id) {
2950 tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
2951 tx->plcp = rinfo->plcp;
2952 tx->rflags = rinfo->flags;
2953 if (tx->id == hal->broadcast_id) {
2954 /* Group or management frame. */
2955 tx->linkq = 0;
2713 /* XXX Alternate between antenna A and B? */
2956 /* XXX Alternate between antenna A and B? */
2714 txant = IWN_LSB(sc->txantmsk);
2957 txant = IWN_LSB(sc->txchainmask);
2715 tx->rflags |= IWN_RFLAG_ANT(txant);
2958 tx->rflags |= IWN_RFLAG_ANT(txant);
2716 } else
2717 flags |= IWN_TX_LINKQ;
2959 } else {
2960 tx->linkq = 0;
2961 flags |= IWN_TX_LINKQ; /* enable MRR */
2962 }
2718
2719 /* Set physical address of "scratch area". */
2963
2964 /* Set physical address of "scratch area". */
2720 paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
2721 tx->loaddr = htole32(IWN_LOADDR(paddr));
2722 tx->hiaddr = IWN_HIADDR(paddr);
2965 tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr));
2966 tx->hiaddr = IWN_HIADDR(data->scratch_paddr);
2723
2724 /* Copy 802.11 header in TX command. */
2725 memcpy((uint8_t *)(tx + 1), wh, hdrlen);
2726
2727 /* Trim 802.11 header. */
2728 m_adj(m, hdrlen);
2729 tx->security = 0;
2730 tx->flags = htole32(flags);
2731
2967
2968 /* Copy 802.11 header in TX command. */
2969 memcpy((uint8_t *)(tx + 1), wh, hdrlen);
2970
2971 /* Trim 802.11 header. */
2972 m_adj(m, hdrlen);
2973 tx->security = 0;
2974 tx->flags = htole32(flags);
2975
2732 error = bus_dmamap_load_mbuf_sg(ring->desc_dma.tag, data->map, m, segs,
2733 &nsegs, BUS_DMA_NOWAIT);
2734 if (error != 0) {
2976 if (m->m_len > 0) {
2977 error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map,
2978 m, segs, &nsegs, BUS_DMA_NOWAIT);
2735 if (error == EFBIG) {
2736 /* too many fragments, linearize */
2737 mnew = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
2738 if (mnew == NULL) {
2979 if (error == EFBIG) {
2980 /* too many fragments, linearize */
2981 mnew = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
2982 if (mnew == NULL) {
2739 IWN_UNLOCK(sc);
2740 device_printf(sc->sc_dev,
2741 "%s: could not defrag mbuf\n", __func__);
2742 m_freem(m);
2743 return ENOBUFS;
2744 }
2745 m = mnew;
2983 device_printf(sc->sc_dev,
2984 "%s: could not defrag mbuf\n", __func__);
2985 m_freem(m);
2986 return ENOBUFS;
2987 }
2988 m = mnew;
2746 error = bus_dmamap_load_mbuf_sg(ring->desc_dma.tag,
2989 error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
2747 data->map, m, segs, &nsegs, BUS_DMA_NOWAIT);
2748 }
2749 if (error != 0) {
2990 data->map, m, segs, &nsegs, BUS_DMA_NOWAIT);
2991 }
2992 if (error != 0) {
2750 IWN_UNLOCK(sc);
2751 device_printf(sc->sc_dev,
2752 "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
2753 __func__, error);
2754 m_freem(m);
2755 return error;
2756 }
2757 }
2758
2759 data->m = m;
2760 data->ni = ni;
2761
2762 DPRINTF(sc, IWN_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
2763 __func__, ring->qid, ring->cur, m->m_pkthdr.len, nsegs);
2764
2765 /* Fill TX descriptor. */
2766 desc->nsegs = 1 + nsegs;
2767 /* First DMA segment is used by the TX command. */
2993 device_printf(sc->sc_dev,
2994 "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
2995 __func__, error);
2996 m_freem(m);
2997 return error;
2998 }
2999 }
3000
3001 data->m = m;
3002 data->ni = ni;
3003
3004 DPRINTF(sc, IWN_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
3005 __func__, ring->qid, ring->cur, m->m_pkthdr.len, nsegs);
3006
3007 /* Fill TX descriptor. */
3008 desc->nsegs = 1 + nsegs;
3009 /* First DMA segment is used by the TX command. */
2768 desc->segs[0].addr = htole32(IWN_LOADDR(paddr));
2769 desc->segs[0].len = htole16(IWN_HIADDR(paddr) |
3010 desc->segs[0].addr = htole32(IWN_LOADDR(data->cmd_paddr));
3011 desc->segs[0].len = htole16(IWN_HIADDR(data->cmd_paddr) |
2770 (4 + sizeof (*tx) + hdrlen + pad) << 4);
2771 /* Other DMA segments are for data payload. */
2772 for (i = 1; i <= nsegs; i++) {
2773 desc->segs[i].addr = htole32(IWN_LOADDR(segs[i - 1].ds_addr));
2774 desc->segs[i].len = htole16(IWN_HIADDR(segs[i - 1].ds_addr) |
2775 segs[i - 1].ds_len << 4);
2776 }
2777
3012 (4 + sizeof (*tx) + hdrlen + pad) << 4);
3013 /* Other DMA segments are for data payload. */
3014 for (i = 1; i <= nsegs; i++) {
3015 desc->segs[i].addr = htole32(IWN_LOADDR(segs[i - 1].ds_addr));
3016 desc->segs[i].len = htole16(IWN_HIADDR(segs[i - 1].ds_addr) |
3017 segs[i - 1].ds_len << 4);
3018 }
3019
2778 bus_dmamap_sync(ring->desc_dma.tag, data->map, BUS_DMASYNC_PREWRITE);
2779 bus_dmamap_sync(ring->desc_dma.tag, ring->cmd_dma.map,
3020 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
3021 bus_dmamap_sync(ring->data_dmat, ring->cmd_dma.map,
2780 BUS_DMASYNC_PREWRITE);
2781 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
2782 BUS_DMASYNC_PREWRITE);
2783
3022 BUS_DMASYNC_PREWRITE);
3023 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
3024 BUS_DMASYNC_PREWRITE);
3025
3026#ifdef notyet
2784 /* Update TX scheduler. */
2785 hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
3027 /* Update TX scheduler. */
3028 hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
3029#endif
2786
2787 /* Kick TX ring. */
2788 ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
2789 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
2790
2791 /* Mark TX ring as full if we reach a certain threshold. */
2792 if (++ring->queued > IWN_TX_RING_HIMARK)
2793 sc->qfullmsk |= 1 << ring->qid;
2794
2795 return 0;
2796}
2797
2798static int
3030
3031 /* Kick TX ring. */
3032 ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
3033 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
3034
3035 /* Mark TX ring as full if we reach a certain threshold. */
3036 if (++ring->queued > IWN_TX_RING_HIMARK)
3037 sc->qfullmsk |= 1 << ring->qid;
3038
3039 return 0;
3040}
3041
3042static int
2799iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m0,
3043iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,
2800 struct ieee80211_node *ni, struct iwn_tx_ring *ring,
2801 const struct ieee80211_bpf_params *params)
2802{
2803 const struct iwn_hal *hal = sc->sc_hal;
2804 const struct iwn_rate *rinfo;
2805 struct ifnet *ifp = sc->sc_ifp;
2806 struct ieee80211vap *vap = ni->ni_vap;
2807 struct ieee80211com *ic = ifp->if_l2com;
2808 struct iwn_tx_cmd *cmd;
2809 struct iwn_cmd_data *tx;
2810 struct ieee80211_frame *wh;
2811 struct iwn_tx_desc *desc;
2812 struct iwn_tx_data *data;
2813 struct mbuf *mnew;
2814 bus_addr_t paddr;
2815 bus_dma_segment_t segs[IWN_MAX_SCATTER];
2816 uint32_t flags;
2817 u_int hdrlen;
3044 struct ieee80211_node *ni, struct iwn_tx_ring *ring,
3045 const struct ieee80211_bpf_params *params)
3046{
3047 const struct iwn_hal *hal = sc->sc_hal;
3048 const struct iwn_rate *rinfo;
3049 struct ifnet *ifp = sc->sc_ifp;
3050 struct ieee80211vap *vap = ni->ni_vap;
3051 struct ieee80211com *ic = ifp->if_l2com;
3052 struct iwn_tx_cmd *cmd;
3053 struct iwn_cmd_data *tx;
3054 struct ieee80211_frame *wh;
3055 struct iwn_tx_desc *desc;
3056 struct iwn_tx_data *data;
3057 struct mbuf *mnew;
3058 bus_addr_t paddr;
3059 bus_dma_segment_t segs[IWN_MAX_SCATTER];
3060 uint32_t flags;
3061 u_int hdrlen;
2818 int totlen, error, pad, nsegs, i, rate;
2819 uint8_t type, txant;
3062 int totlen, error, pad, nsegs = 0, i, rate;
3063 uint8_t ridx, type, txant;
2820
2821 IWN_LOCK_ASSERT(sc);
2822
3064
3065 IWN_LOCK_ASSERT(sc);
3066
2823 wh = mtod(m0, struct ieee80211_frame *);
3067 wh = mtod(m, struct ieee80211_frame *);
2824 hdrlen = ieee80211_anyhdrsize(wh);
2825 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
2826
2827 desc = &ring->desc[ring->cur];
2828 data = &ring->data[ring->cur];
2829
2830 /* Choose a TX rate index. */
2831 rate = params->ibp_rate0;
2832 if (!ieee80211_isratevalid(ic->ic_rt, rate)) {
2833 /* XXX fall back to mcast/mgmt rate? */
3068 hdrlen = ieee80211_anyhdrsize(wh);
3069 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
3070
3071 desc = &ring->desc[ring->cur];
3072 data = &ring->data[ring->cur];
3073
3074 /* Choose a TX rate index. */
3075 rate = params->ibp_rate0;
3076 if (!ieee80211_isratevalid(ic->ic_rt, rate)) {
3077 /* XXX fall back to mcast/mgmt rate? */
2834 m_freem(m0);
3078 m_freem(m);
2835 return EINVAL;
2836 }
3079 return EINVAL;
3080 }
2837 rinfo = iwn_plcp_signal(rate);
3081 ridx = iwn_plcp_signal(rate);
3082 rinfo = &iwn_rates[ridx];
2838
3083
2839 totlen = m0->m_pkthdr.len;
3084 totlen = m->m_pkthdr.len;
2840
3085
3086 /* Prepare TX firmware command. */
2841 cmd = &ring->cmd[ring->cur];
2842 cmd->code = IWN_CMD_TX_DATA;
2843 cmd->flags = 0;
2844 cmd->qid = ring->qid;
2845 cmd->idx = ring->cur;
2846
2847 tx = (struct iwn_cmd_data *)cmd->data;
3087 cmd = &ring->cmd[ring->cur];
3088 cmd->code = IWN_CMD_TX_DATA;
3089 cmd->flags = 0;
3090 cmd->qid = ring->qid;
3091 cmd->idx = ring->cur;
3092
3093 tx = (struct iwn_cmd_data *)cmd->data;
2848 /* NB: no need to bzero tx, all fields are reinitialized here */
3094 /* NB: No need to clear tx, all fields are reinitialized here. */
2849 tx->scratch = 0; /* clear "scratch" area */
2850
2851 flags = 0;
2852 if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
2853 flags |= IWN_TX_NEED_ACK;
2854 if (params->ibp_flags & IEEE80211_BPF_RTS) {
2855 if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
2856 /* 5000 autoselects RTS/CTS or CTS-to-self. */

--- 20 unchanged lines hidden (view full) ---

2877 subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
2878 tx->timeout = htole16(3);
2879 else
2880 tx->timeout = htole16(2);
2881 } else
2882 tx->timeout = htole16(0);
2883
2884 if (hdrlen & 3) {
3095 tx->scratch = 0; /* clear "scratch" area */
3096
3097 flags = 0;
3098 if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
3099 flags |= IWN_TX_NEED_ACK;
3100 if (params->ibp_flags & IEEE80211_BPF_RTS) {
3101 if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
3102 /* 5000 autoselects RTS/CTS or CTS-to-self. */

--- 20 unchanged lines hidden (view full) ---

3123 subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
3124 tx->timeout = htole16(3);
3125 else
3126 tx->timeout = htole16(2);
3127 } else
3128 tx->timeout = htole16(0);
3129
3130 if (hdrlen & 3) {
2885 /* First segment's length must be a multiple of 4. */
3131 /* First segment length must be a multiple of 4. */
2886 flags |= IWN_TX_NEED_PADDING;
2887 pad = 4 - (hdrlen & 3);
2888 } else
2889 pad = 0;
2890
2891 if (ieee80211_radiotap_active_vap(vap)) {
2892 struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
2893
2894 tap->wt_flags = 0;
2895 tap->wt_rate = rate;
2896
3132 flags |= IWN_TX_NEED_PADDING;
3133 pad = 4 - (hdrlen & 3);
3134 } else
3135 pad = 0;
3136
3137 if (ieee80211_radiotap_active_vap(vap)) {
3138 struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
3139
3140 tap->wt_flags = 0;
3141 tap->wt_rate = rate;
3142
2897 ieee80211_radiotap_tx(vap, m0);
3143 ieee80211_radiotap_tx(vap, m);
2898 }
2899
2900 tx->len = htole16(totlen);
2901 tx->tid = 0;
2902 tx->id = hal->broadcast_id;
2903 tx->rts_ntries = params->ibp_try1;
2904 tx->data_ntries = params->ibp_try0;
2905 tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
2906 tx->plcp = rinfo->plcp;
2907 tx->rflags = rinfo->flags;
3144 }
3145
3146 tx->len = htole16(totlen);
3147 tx->tid = 0;
3148 tx->id = hal->broadcast_id;
3149 tx->rts_ntries = params->ibp_try1;
3150 tx->data_ntries = params->ibp_try0;
3151 tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
3152 tx->plcp = rinfo->plcp;
3153 tx->rflags = rinfo->flags;
2908 if (tx->id == hal->broadcast_id) {
2909 txant = IWN_LSB(sc->txantmsk);
2910 tx->rflags |= IWN_RFLAG_ANT(txant);
2911 } else {
2912 flags |= IWN_TX_LINKQ; /* enable MRR */
2913 }
3154 /* Group or management frame. */
3155 tx->linkq = 0;
3156 txant = IWN_LSB(sc->txchainmask);
3157 tx->rflags |= IWN_RFLAG_ANT(txant);
2914 /* Set physical address of "scratch area". */
2915 paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
2916 tx->loaddr = htole32(IWN_LOADDR(paddr));
2917 tx->hiaddr = IWN_HIADDR(paddr);
2918
2919 /* Copy 802.11 header in TX command. */
2920 memcpy((uint8_t *)(tx + 1), wh, hdrlen);
2921
2922 /* Trim 802.11 header. */
3158 /* Set physical address of "scratch area". */
3159 paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
3160 tx->loaddr = htole32(IWN_LOADDR(paddr));
3161 tx->hiaddr = IWN_HIADDR(paddr);
3162
3163 /* Copy 802.11 header in TX command. */
3164 memcpy((uint8_t *)(tx + 1), wh, hdrlen);
3165
3166 /* Trim 802.11 header. */
2923 m_adj(m0, hdrlen);
3167 m_adj(m, hdrlen);
2924 tx->security = 0;
2925 tx->flags = htole32(flags);
2926
3168 tx->security = 0;
3169 tx->flags = htole32(flags);
3170
2927 error = bus_dmamap_load_mbuf_sg(ring->desc_dma.tag, data->map, m0, segs,
2928 &nsegs, BUS_DMA_NOWAIT);
2929 if (error != 0) {
3171 if (m->m_len > 0) {
3172 error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map,
3173 m, segs, &nsegs, BUS_DMA_NOWAIT);
2930 if (error == EFBIG) {
2931 /* Too many fragments, linearize. */
3174 if (error == EFBIG) {
3175 /* Too many fragments, linearize. */
2932 mnew = m_collapse(m0, M_DONTWAIT, IWN_MAX_SCATTER);
3176 mnew = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
2933 if (mnew == NULL) {
3177 if (mnew == NULL) {
2934 IWN_UNLOCK(sc);
2935 device_printf(sc->sc_dev,
2936 "%s: could not defrag mbuf\n", __func__);
3178 device_printf(sc->sc_dev,
3179 "%s: could not defrag mbuf\n", __func__);
2937 m_freem(m0);
3180 m_freem(m);
2938 return ENOBUFS;
2939 }
3181 return ENOBUFS;
3182 }
2940 m0 = mnew;
2941 error = bus_dmamap_load_mbuf_sg(ring->desc_dma.tag,
2942 data->map, m0, segs, &nsegs, BUS_DMA_NOWAIT);
3183 m = mnew;
3184 error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
3185 data->map, m, segs, &nsegs, BUS_DMA_NOWAIT);
2943 }
2944 if (error != 0) {
3186 }
3187 if (error != 0) {
2945 IWN_UNLOCK(sc);
2946 device_printf(sc->sc_dev,
2947 "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
2948 __func__, error);
3188 device_printf(sc->sc_dev,
3189 "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
3190 __func__, error);
2949 m_freem(m0);
3191 m_freem(m);
2950 return error;
2951 }
2952 }
2953
3192 return error;
3193 }
3194 }
3195
2954 data->m = m0;
3196 data->m = m;
2955 data->ni = ni;
2956
2957 DPRINTF(sc, IWN_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
3197 data->ni = ni;
3198
3199 DPRINTF(sc, IWN_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
2958 __func__, ring->qid, ring->cur, m0->m_pkthdr.len, nsegs);
3200 __func__, ring->qid, ring->cur, m->m_pkthdr.len, nsegs);
2959
2960 /* Fill TX descriptor. */
2961 desc->nsegs = 1 + nsegs;
2962 /* First DMA segment is used by the TX command. */
3201
3202 /* Fill TX descriptor. */
3203 desc->nsegs = 1 + nsegs;
3204 /* First DMA segment is used by the TX command. */
2963 desc->segs[0].addr = htole32(IWN_LOADDR(paddr));
2964 desc->segs[0].len = htole16(IWN_HIADDR(paddr) |
3205 desc->segs[0].addr = htole32(IWN_LOADDR(data->cmd_paddr));
3206 desc->segs[0].len = htole16(IWN_HIADDR(data->cmd_paddr) |
2965 (4 + sizeof (*tx) + hdrlen + pad) << 4);
2966 /* Other DMA segments are for data payload. */
2967 for (i = 1; i <= nsegs; i++) {
2968 desc->segs[i].addr = htole32(IWN_LOADDR(segs[i - 1].ds_addr));
2969 desc->segs[i].len = htole16(IWN_HIADDR(segs[i - 1].ds_addr) |
2970 segs[i - 1].ds_len << 4);
2971 }
2972
3207 (4 + sizeof (*tx) + hdrlen + pad) << 4);
3208 /* Other DMA segments are for data payload. */
3209 for (i = 1; i <= nsegs; i++) {
3210 desc->segs[i].addr = htole32(IWN_LOADDR(segs[i - 1].ds_addr));
3211 desc->segs[i].len = htole16(IWN_HIADDR(segs[i - 1].ds_addr) |
3212 segs[i - 1].ds_len << 4);
3213 }
3214
3215 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
3216 bus_dmamap_sync(ring->data_dmat, ring->cmd_dma.map,
3217 BUS_DMASYNC_PREWRITE);
3218 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
3219 BUS_DMASYNC_PREWRITE);
3220
3221#ifdef notyet
2973 /* Update TX scheduler. */
2974 hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
3222 /* Update TX scheduler. */
3223 hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
3224#endif
2975
2976 /* Kick TX ring. */
2977 ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
2978 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
2979
2980 /* Mark TX ring as full if we reach a certain threshold. */
2981 if (++ring->queued > IWN_TX_RING_HIMARK)
2982 sc->qfullmsk |= 1 << ring->qid;

--- 98 unchanged lines hidden (view full) ---

3081 }
3082}
3083
3084int
3085iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
3086{
3087 struct iwn_softc *sc = ifp->if_softc;
3088 struct ieee80211com *ic = ifp->if_l2com;
3225
3226 /* Kick TX ring. */
3227 ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
3228 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
3229
3230 /* Mark TX ring as full if we reach a certain threshold. */
3231 if (++ring->queued > IWN_TX_RING_HIMARK)
3232 sc->qfullmsk |= 1 << ring->qid;

--- 98 unchanged lines hidden (view full) ---

3331 }
3332}
3333
3334int
3335iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
3336{
3337 struct iwn_softc *sc = ifp->if_softc;
3338 struct ieee80211com *ic = ifp->if_l2com;
3339 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
3089 struct ifreq *ifr = (struct ifreq *) data;
3340 struct ifreq *ifr = (struct ifreq *) data;
3090 int error = 0, startall = 0;
3341 int error = 0, startall = 0, stop = 0;
3091
3092 switch (cmd) {
3093 case SIOCSIFFLAGS:
3094 IWN_LOCK(sc);
3095 if (ifp->if_flags & IFF_UP) {
3096 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
3097 iwn_init_locked(sc);
3342
3343 switch (cmd) {
3344 case SIOCSIFFLAGS:
3345 IWN_LOCK(sc);
3346 if (ifp->if_flags & IFF_UP) {
3347 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
3348 iwn_init_locked(sc);
3098 startall = 1;
3349 if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)
3350 startall = 1;
3351 else
3352 stop = 1;
3099 }
3100 } else {
3101 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
3102 iwn_stop_locked(sc);
3103 }
3104 IWN_UNLOCK(sc);
3105 if (startall)
3106 ieee80211_start_all(ic);
3353 }
3354 } else {
3355 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
3356 iwn_stop_locked(sc);
3357 }
3358 IWN_UNLOCK(sc);
3359 if (startall)
3360 ieee80211_start_all(ic);
3361 else if (vap != NULL && stop)
3362 ieee80211_stop(vap);
3107 break;
3108 case SIOCGIFMEDIA:
3109 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
3110 break;
3111 case SIOCGIFADDR:
3112 error = ether_ioctl(ifp, cmd, data);
3113 break;
3114 default:

--- 4 unchanged lines hidden (view full) ---

3119}
3120
3121/*
3122 * Send a command to the firmware.
3123 */
3124int
3125iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
3126{
3363 break;
3364 case SIOCGIFMEDIA:
3365 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
3366 break;
3367 case SIOCGIFADDR:
3368 error = ether_ioctl(ifp, cmd, data);
3369 break;
3370 default:

--- 4 unchanged lines hidden (view full) ---

3375}
3376
3377/*
3378 * Send a command to the firmware.
3379 */
3380int
3381iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
3382{
3127 const struct iwn_hal *hal = sc->sc_hal;
3128 struct iwn_tx_ring *ring = &sc->txq[4];
3129 struct iwn_tx_desc *desc;
3130 struct iwn_tx_data *data;
3131 struct iwn_tx_cmd *cmd;
3132 struct mbuf *m;
3133 bus_addr_t paddr;
3134 int totlen, error;
3135
3136 IWN_LOCK_ASSERT(sc);
3137
3138 desc = &ring->desc[ring->cur];
3139 data = &ring->data[ring->cur];
3140 totlen = 4 + size;
3141
3142 if (size > sizeof cmd->data) {
3143 /* Command is too large to fit in a descriptor. */
3144 if (totlen > MCLBYTES)
3145 return EINVAL;
3383 struct iwn_tx_ring *ring = &sc->txq[4];
3384 struct iwn_tx_desc *desc;
3385 struct iwn_tx_data *data;
3386 struct iwn_tx_cmd *cmd;
3387 struct mbuf *m;
3388 bus_addr_t paddr;
3389 int totlen, error;
3390
3391 IWN_LOCK_ASSERT(sc);
3392
3393 desc = &ring->desc[ring->cur];
3394 data = &ring->data[ring->cur];
3395 totlen = 4 + size;
3396
3397 if (size > sizeof cmd->data) {
3398 /* Command is too large to fit in a descriptor. */
3399 if (totlen > MCLBYTES)
3400 return EINVAL;
3146 MGETHDR(m, M_DONTWAIT, MT_DATA);
3401 m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
3147 if (m == NULL)
3148 return ENOMEM;
3402 if (m == NULL)
3403 return ENOMEM;
3149 if (totlen > MHLEN) {
3150 MCLGET(m, M_DONTWAIT);
3151 if (!(m->m_flags & M_EXT)) {
3152 m_freem(m);
3153 return ENOMEM;
3154 }
3155 }
3156 cmd = mtod(m, struct iwn_tx_cmd *);
3404 cmd = mtod(m, struct iwn_tx_cmd *);
3157 error = bus_dmamap_load(ring->cmd_dma.tag, data->map, cmd,
3405 error = bus_dmamap_load(ring->data_dmat, data->map, cmd,
3158 totlen, iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
3159 if (error != 0) {
3160 m_freem(m);
3161 return error;
3162 }
3163 data->m = m;
3164 } else {
3165 cmd = &ring->cmd[ring->cur];

--- 10 unchanged lines hidden (view full) ---

3176 desc->segs[0].addr = htole32(IWN_LOADDR(paddr));
3177 desc->segs[0].len = htole16(IWN_HIADDR(paddr) | totlen << 4);
3178
3179 DPRINTF(sc, IWN_DEBUG_CMD, "%s: %s (0x%x) flags %d qid %d idx %d\n",
3180 __func__, iwn_intr_str(cmd->code), cmd->code,
3181 cmd->flags, cmd->qid, cmd->idx);
3182
3183 if (size > sizeof cmd->data) {
3406 totlen, iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
3407 if (error != 0) {
3408 m_freem(m);
3409 return error;
3410 }
3411 data->m = m;
3412 } else {
3413 cmd = &ring->cmd[ring->cur];

--- 10 unchanged lines hidden (view full) ---

3424 desc->segs[0].addr = htole32(IWN_LOADDR(paddr));
3425 desc->segs[0].len = htole16(IWN_HIADDR(paddr) | totlen << 4);
3426
3427 DPRINTF(sc, IWN_DEBUG_CMD, "%s: %s (0x%x) flags %d qid %d idx %d\n",
3428 __func__, iwn_intr_str(cmd->code), cmd->code,
3429 cmd->flags, cmd->qid, cmd->idx);
3430
3431 if (size > sizeof cmd->data) {
3184 bus_dmamap_sync(ring->cmd_dma.tag, data->map,
3432 bus_dmamap_sync(ring->data_dmat, data->map,
3185 BUS_DMASYNC_PREWRITE);
3186 } else {
3433 BUS_DMASYNC_PREWRITE);
3434 } else {
3187 bus_dmamap_sync(ring->cmd_dma.tag, ring->cmd_dma.map,
3435 bus_dmamap_sync(ring->data_dmat, ring->cmd_dma.map,
3188 BUS_DMASYNC_PREWRITE);
3189 }
3190 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
3191 BUS_DMASYNC_PREWRITE);
3192
3436 BUS_DMASYNC_PREWRITE);
3437 }
3438 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
3439 BUS_DMASYNC_PREWRITE);
3440
3441#ifdef notyet
3193 /* Update TX scheduler. */
3442 /* Update TX scheduler. */
3194 hal->update_sched(sc, ring->qid, ring->cur, 0, 0);
3443 sc->sc_hal->update_sched(sc, ring->qid, ring->cur, 0, 0);
3444#endif
3195
3196 /* Kick command ring. */
3197 ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
3198 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
3199
3200 return async ? 0 : msleep(desc, &sc->sc_mtx, PCATCH, "iwncmd", hz);
3201}
3202

--- 18 unchanged lines hidden (view full) ---

3221
3222int
3223iwn5000_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
3224{
3225 /* Direct mapping. */
3226 return iwn_cmd(sc, IWN_CMD_ADD_NODE, node, sizeof (*node), async);
3227}
3228
3445
3446 /* Kick command ring. */
3447 ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
3448 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
3449
3450 return async ? 0 : msleep(desc, &sc->sc_mtx, PCATCH, "iwncmd", hz);
3451}
3452

--- 18 unchanged lines hidden (view full) ---

3471
3472int
3473iwn5000_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
3474{
3475 /* Direct mapping. */
3476 return iwn_cmd(sc, IWN_CMD_ADD_NODE, node, sizeof (*node), async);
3477}
3478
3479#if 0 /* HT */
3229static const uint8_t iwn_ridx_to_plcp[] = {
3230 10, 20, 55, 110, /* CCK */
3231 0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */
3232};
3233static const uint8_t iwn_siso_mcs_to_plcp[] = {
3234 0, 0, 0, 0, /* CCK */
3235 0, 0, 1, 2, 3, 4, 5, 6, 7 /* HT */
3236};
3237static const uint8_t iwn_mimo_mcs_to_plcp[] = {
3238 0, 0, 0, 0, /* CCK */
3239 8, 8, 9, 10, 11, 12, 13, 14, 15 /* HT */
3240};
3480static const uint8_t iwn_ridx_to_plcp[] = {
3481 10, 20, 55, 110, /* CCK */
3482 0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */
3483};
3484static const uint8_t iwn_siso_mcs_to_plcp[] = {
3485 0, 0, 0, 0, /* CCK */
3486 0, 0, 1, 2, 3, 4, 5, 6, 7 /* HT */
3487};
3488static const uint8_t iwn_mimo_mcs_to_plcp[] = {
3489 0, 0, 0, 0, /* CCK */
3490 8, 8, 9, 10, 11, 12, 13, 14, 15 /* HT */
3491};
3492#endif
3241static const uint8_t iwn_prev_ridx[] = {
3242 /* NB: allow fallback from CCK11 to OFDM9 and from OFDM6 to CCK5 */
3243 0, 0, 1, 5, /* CCK */
3244 2, 4, 3, 6, 7, 8, 9, 10, 10 /* OFDM */
3245};
3246
3247/*
3248 * Configure hardware link parameters for the specified
3249 * node operating on the specified channel.
3250 */
3251int
3493static const uint8_t iwn_prev_ridx[] = {
3494 /* NB: allow fallback from CCK11 to OFDM9 and from OFDM6 to CCK5 */
3495 0, 0, 1, 5, /* CCK */
3496 2, 4, 3, 6, 7, 8, 9, 10, 10 /* OFDM */
3497};
3498
3499/*
3500 * Configure hardware link parameters for the specified
3501 * node operating on the specified channel.
3502 */
3503int
3252iwn_set_link_quality(struct iwn_softc *sc, uint8_t id,
3253 const struct ieee80211_channel *c, int async)
3504iwn_set_link_quality(struct iwn_softc *sc, uint8_t id, int async)
3254{
3505{
3506 struct ifnet *ifp = sc->sc_ifp;
3507 struct ieee80211com *ic = ifp->if_l2com;
3255 struct iwn_cmd_link_quality linkq;
3508 struct iwn_cmd_link_quality linkq;
3256 int ridx, i;
3257 uint8_t txant;
3509 const struct iwn_rate *rinfo;
3510 int i;
3511 uint8_t txant, ridx;
3258
3259 /* Use the first valid TX antenna. */
3512
3513 /* Use the first valid TX antenna. */
3260 txant = IWN_LSB(sc->txantmsk);
3514 txant = IWN_LSB(sc->txchainmask);
3261
3262 memset(&linkq, 0, sizeof linkq);
3263 linkq.id = id;
3264 linkq.antmsk_1stream = txant;
3515
3516 memset(&linkq, 0, sizeof linkq);
3517 linkq.id = id;
3518 linkq.antmsk_1stream = txant;
3265 linkq.antmsk_2stream = IWN_ANT_A | IWN_ANT_B;
3266 linkq.ampdu_max = 64;
3519 linkq.antmsk_2stream = IWN_ANT_AB;
3520 linkq.ampdu_max = 31;
3267 linkq.ampdu_threshold = 3;
3268 linkq.ampdu_limit = htole16(4000); /* 4ms */
3269
3521 linkq.ampdu_threshold = 3;
3522 linkq.ampdu_limit = htole16(4000); /* 4ms */
3523
3524#if 0 /* HT */
3270 if (IEEE80211_IS_CHAN_HT(c))
3271 linkq.mimo = 1;
3525 if (IEEE80211_IS_CHAN_HT(c))
3526 linkq.mimo = 1;
3527#endif
3272
3273 if (id == IWN_ID_BSS)
3274 ridx = IWN_RIDX_OFDM54;
3528
3529 if (id == IWN_ID_BSS)
3530 ridx = IWN_RIDX_OFDM54;
3275 else if (IEEE80211_IS_CHAN_A(c))
3531 else if (IEEE80211_IS_CHAN_A(ic->ic_curchan))
3276 ridx = IWN_RIDX_OFDM6;
3277 else
3278 ridx = IWN_RIDX_CCK1;
3279
3280 for (i = 0; i < IWN_MAX_TX_RETRIES; i++) {
3532 ridx = IWN_RIDX_OFDM6;
3533 else
3534 ridx = IWN_RIDX_CCK1;
3535
3536 for (i = 0; i < IWN_MAX_TX_RETRIES; i++) {
3537 rinfo = &iwn_rates[ridx];
3538#if 0 /* HT */
3281 if (IEEE80211_IS_CHAN_HT40(c)) {
3282 linkq.retry[i].plcp = iwn_mimo_mcs_to_plcp[ridx]
3283 | IWN_RIDX_MCS;
3284 linkq.retry[i].rflags = IWN_RFLAG_HT
3285 | IWN_RFLAG_HT40;
3286 /* XXX shortGI */
3287 } else if (IEEE80211_IS_CHAN_HT(c)) {
3288 linkq.retry[i].plcp = iwn_siso_mcs_to_plcp[ridx]
3289 | IWN_RIDX_MCS;
3290 linkq.retry[i].rflags = IWN_RFLAG_HT;
3291 /* XXX shortGI */
3539 if (IEEE80211_IS_CHAN_HT40(c)) {
3540 linkq.retry[i].plcp = iwn_mimo_mcs_to_plcp[ridx]
3541 | IWN_RIDX_MCS;
3542 linkq.retry[i].rflags = IWN_RFLAG_HT
3543 | IWN_RFLAG_HT40;
3544 /* XXX shortGI */
3545 } else if (IEEE80211_IS_CHAN_HT(c)) {
3546 linkq.retry[i].plcp = iwn_siso_mcs_to_plcp[ridx]
3547 | IWN_RIDX_MCS;
3548 linkq.retry[i].rflags = IWN_RFLAG_HT;
3549 /* XXX shortGI */
3292 } else {
3293 linkq.retry[i].plcp = iwn_ridx_to_plcp[ridx];
3294 if (ridx <= IWN_RIDX_CCK11)
3295 linkq.retry[i].rflags = IWN_RFLAG_CCK;
3550 } else
3551#endif
3552 {
3553 linkq.retry[i].plcp = rinfo->plcp;
3554 linkq.retry[i].rflags = rinfo->flags;
3296 }
3297 linkq.retry[i].rflags |= IWN_RFLAG_ANT(txant);
3298 ridx = iwn_prev_ridx[ridx];
3299 }
3555 }
3556 linkq.retry[i].rflags |= IWN_RFLAG_ANT(txant);
3557 ridx = iwn_prev_ridx[ridx];
3558 }
3300
3301#ifdef IWN_DEBUG
3302 if (sc->sc_debug & IWN_DEBUG_STATE) {
3303 printf("%s: set link quality for node %d, mimo %d ssmask %d\n",
3304 __func__, id, linkq.mimo, linkq.antmsk_1stream);
3305 printf("%s:", __func__);
3306 for (i = 0; i < IWN_MAX_TX_RETRIES; i++)
3307 printf(" %d:%x", linkq.retry[i].plcp,
3308 linkq.retry[i].rflags);
3309 printf("\n");
3310 }
3311#endif
3312 return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async);
3313}
3314
3315/*
3316 * Broadcast node is used to send group-addressed and management frames.
3317 */
3318int
3559#ifdef IWN_DEBUG
3560 if (sc->sc_debug & IWN_DEBUG_STATE) {
3561 printf("%s: set link quality for node %d, mimo %d ssmask %d\n",
3562 __func__, id, linkq.mimo, linkq.antmsk_1stream);
3563 printf("%s:", __func__);
3564 for (i = 0; i < IWN_MAX_TX_RETRIES; i++)
3565 printf(" %d:%x", linkq.retry[i].plcp,
3566 linkq.retry[i].rflags);
3567 printf("\n");
3568 }
3569#endif
3570 return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async);
3571}
3572
3573/*
3574 * Broadcast node is used to send group-addressed and management frames.
3575 */
3576int
3319iwn_add_broadcast_node(struct iwn_softc *sc, const struct ieee80211_channel *c,
3320 int async)
3577iwn_add_broadcast_node(struct iwn_softc *sc, int async)
3321{
3322 const struct iwn_hal *hal = sc->sc_hal;
3323 struct ifnet *ifp = sc->sc_ifp;
3324 struct iwn_node_info node;
3325 int error;
3326
3327 memset(&node, 0, sizeof node);
3328 IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr);
3329 node.id = hal->broadcast_id;
3330 DPRINTF(sc, IWN_DEBUG_RESET, "%s: adding broadcast node\n", __func__);
3331 error = hal->add_node(sc, &node, async);
3332 if (error != 0)
3333 return error;
3334
3578{
3579 const struct iwn_hal *hal = sc->sc_hal;
3580 struct ifnet *ifp = sc->sc_ifp;
3581 struct iwn_node_info node;
3582 int error;
3583
3584 memset(&node, 0, sizeof node);
3585 IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr);
3586 node.id = hal->broadcast_id;
3587 DPRINTF(sc, IWN_DEBUG_RESET, "%s: adding broadcast node\n", __func__);
3588 error = hal->add_node(sc, &node, async);
3589 if (error != 0)
3590 return error;
3591
3335 return iwn_set_link_quality(sc, node.id, c, async);
3592 error = iwn_set_link_quality(sc, hal->broadcast_id, async);
3593 return error;
3336}
3337
3338int
3339iwn_wme_update(struct ieee80211com *ic)
3340{
3341#define IWN_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */
3342#define IWN_TXOP_TO_US(v) (v<<5)
3343 struct iwn_softc *sc = ic->ic_ifp->if_softc;

--- 6 unchanged lines hidden (view full) ---

3350 const struct wmeParams *wmep =
3351 &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
3352 cmd.ac[i].aifsn = wmep->wmep_aifsn;
3353 cmd.ac[i].cwmin = htole16(IWN_EXP2(wmep->wmep_logcwmin));
3354 cmd.ac[i].cwmax = htole16(IWN_EXP2(wmep->wmep_logcwmax));
3355 cmd.ac[i].txoplimit =
3356 htole16(IWN_TXOP_TO_US(wmep->wmep_txopLimit));
3357 }
3594}
3595
3596int
3597iwn_wme_update(struct ieee80211com *ic)
3598{
3599#define IWN_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */
3600#define IWN_TXOP_TO_US(v) (v<<5)
3601 struct iwn_softc *sc = ic->ic_ifp->if_softc;

--- 6 unchanged lines hidden (view full) ---

3608 const struct wmeParams *wmep =
3609 &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
3610 cmd.ac[i].aifsn = wmep->wmep_aifsn;
3611 cmd.ac[i].cwmin = htole16(IWN_EXP2(wmep->wmep_logcwmin));
3612 cmd.ac[i].cwmax = htole16(IWN_EXP2(wmep->wmep_logcwmax));
3613 cmd.ac[i].txoplimit =
3614 htole16(IWN_TXOP_TO_US(wmep->wmep_txopLimit));
3615 }
3616 IEEE80211_UNLOCK(ic);
3358 IWN_LOCK(sc);
3359 (void) iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1 /*async*/);
3360 IWN_UNLOCK(sc);
3617 IWN_LOCK(sc);
3618 (void) iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1 /*async*/);
3619 IWN_UNLOCK(sc);
3620 IEEE80211_LOCK(ic);
3361 return 0;
3362#undef IWN_TXOP_TO_US
3363#undef IWN_EXP2
3364}
3365
3621 return 0;
3622#undef IWN_TXOP_TO_US
3623#undef IWN_EXP2
3624}
3625
3626static void
3627iwn_update_mcast(struct ifnet *ifp)
3628{
3629 /* Ignore */
3630}
3631
3366void
3367iwn_set_led(struct iwn_softc *sc, uint8_t which, uint8_t off, uint8_t on)
3368{
3369 struct iwn_cmd_led led;
3370
3371 /* Clear microcode LED ownership. */
3372 IWN_CLRBITS(sc, IWN_LED, IWN_LED_BSM_CTRL);
3373
3374 led.which = which;
3375 led.unit = htole32(10000); /* on/off in unit of 100ms */
3376 led.off = off;
3377 led.on = on;
3378 (void)iwn_cmd(sc, IWN_CMD_SET_LED, &led, sizeof led, 1);
3379}
3380
3381/*
3632void
3633iwn_set_led(struct iwn_softc *sc, uint8_t which, uint8_t off, uint8_t on)
3634{
3635 struct iwn_cmd_led led;
3636
3637 /* Clear microcode LED ownership. */
3638 IWN_CLRBITS(sc, IWN_LED, IWN_LED_BSM_CTRL);
3639
3640 led.which = which;
3641 led.unit = htole32(10000); /* on/off in unit of 100ms */
3642 led.off = off;
3643 led.on = on;
3644 (void)iwn_cmd(sc, IWN_CMD_SET_LED, &led, sizeof led, 1);
3645}
3646
3647/*
3382 * Set the critical temperature at which the firmware will notify us.
3648 * Set the critical temperature at which the firmware will stop the radio
3649 * and notify us.
3383 */
3384int
3385iwn_set_critical_temp(struct iwn_softc *sc)
3386{
3387 struct iwn_critical_temp crit;
3650 */
3651int
3652iwn_set_critical_temp(struct iwn_softc *sc)
3653{
3654 struct iwn_critical_temp crit;
3655 int32_t temp;
3388
3389 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_CTEMP_STOP_RF);
3390
3656
3657 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_CTEMP_STOP_RF);
3658
3659 if (sc->hw_type == IWN_HW_REV_TYPE_5150)
3660 temp = (IWN_CTOK(110) - sc->temp_off) * -5;
3661 else if (sc->hw_type == IWN_HW_REV_TYPE_4965)
3662 temp = IWN_CTOK(110);
3663 else
3664 temp = 110;
3391 memset(&crit, 0, sizeof crit);
3665 memset(&crit, 0, sizeof crit);
3392 crit.tempR = htole32(sc->critical_temp);
3393 DPRINTF(sc, IWN_DEBUG_RESET, "setting critical temp to %u\n",
3394 crit.tempR);
3666 crit.tempR = htole32(temp);
3667 DPRINTF(sc, IWN_DEBUG_RESET, "setting critical temp to %d\n",
3668 temp);
3395 return iwn_cmd(sc, IWN_CMD_SET_CRITICAL_TEMP, &crit, sizeof crit, 0);
3396}
3397
3398int
3399iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni)
3400{
3401 struct iwn_cmd_timing cmd;
3402 uint64_t val, mod;

--- 12 unchanged lines hidden (view full) ---

3415 ni->ni_intval, le64toh(cmd.tstamp), (uint32_t)(val - mod));
3416
3417 return iwn_cmd(sc, IWN_CMD_TIMING, &cmd, sizeof cmd, 1);
3418}
3419
3420void
3421iwn4965_power_calibration(struct iwn_softc *sc, int temp)
3422{
3669 return iwn_cmd(sc, IWN_CMD_SET_CRITICAL_TEMP, &crit, sizeof crit, 0);
3670}
3671
3672int
3673iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni)
3674{
3675 struct iwn_cmd_timing cmd;
3676 uint64_t val, mod;

--- 12 unchanged lines hidden (view full) ---

3689 ni->ni_intval, le64toh(cmd.tstamp), (uint32_t)(val - mod));
3690
3691 return iwn_cmd(sc, IWN_CMD_TIMING, &cmd, sizeof cmd, 1);
3692}
3693
3694void
3695iwn4965_power_calibration(struct iwn_softc *sc, int temp)
3696{
3423 struct ifnet *ifp = sc->sc_ifp;
3424 struct ieee80211com *ic = ifp->if_l2com;
3425
3426 /* Adjust TX power if need be (delta >= 3 degC.) */
3427 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d->%d\n",
3428 __func__, sc->temp, temp);
3429 if (abs(temp - sc->temp) >= 3) {
3430 /* Record temperature of last calibration. */
3431 sc->temp = temp;
3697 /* Adjust TX power if need be (delta >= 3 degC.) */
3698 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d->%d\n",
3699 __func__, sc->temp, temp);
3700 if (abs(temp - sc->temp) >= 3) {
3701 /* Record temperature of last calibration. */
3702 sc->temp = temp;
3432 (void)iwn4965_set_txpower(sc, ic->ic_bsschan, 1);
3703 (void)iwn4965_set_txpower(sc, 1);
3433 }
3434}
3435
3436/*
3437 * Set TX power for current channel (each rate has its own power settings).
3438 * This function takes into account the regulatory information from EEPROM,
3439 * the current temperature and the current voltage.
3440 */
3441int
3704 }
3705}
3706
3707/*
3708 * Set TX power for current channel (each rate has its own power settings).
3709 * This function takes into account the regulatory information from EEPROM,
3710 * the current temperature and the current voltage.
3711 */
3712int
3442iwn4965_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
3443 int async)
3713iwn4965_set_txpower(struct iwn_softc *sc, int async)
3444{
3445/* Fixed-point arithmetic division using a n-bit fractional part. */
3446#define fdivround(a, b, n) \
3447 ((((1 << n) * (a)) / (b) + (1 << n) / 2) / (1 << n))
3448/* Linear interpolation. */
3449#define interpolate(x, x1, y1, x2, y2, n) \
3450 ((y1) + fdivround(((int)(x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n))
3451
3452 static const int tdiv[IWN_NATTEN_GROUPS] = { 9, 8, 8, 8, 6 };
3453 struct ifnet *ifp = sc->sc_ifp;
3454 struct ieee80211com *ic = ifp->if_l2com;
3455 struct iwn_ucode_info *uc = &sc->ucode_info;
3714{
3715/* Fixed-point arithmetic division using a n-bit fractional part. */
3716#define fdivround(a, b, n) \
3717 ((((1 << n) * (a)) / (b) + (1 << n) / 2) / (1 << n))
3718/* Linear interpolation. */
3719#define interpolate(x, x1, y1, x2, y2, n) \
3720 ((y1) + fdivround(((int)(x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n))
3721
3722 static const int tdiv[IWN_NATTEN_GROUPS] = { 9, 8, 8, 8, 6 };
3723 struct ifnet *ifp = sc->sc_ifp;
3724 struct ieee80211com *ic = ifp->if_l2com;
3725 struct iwn_ucode_info *uc = &sc->ucode_info;
3726 struct ieee80211_channel *ch;
3456 struct iwn4965_cmd_txpower cmd;
3457 struct iwn4965_eeprom_chan_samples *chans;
3458 int32_t vdiff, tdiff;
3459 int i, c, grp, maxpwr;
3460 const uint8_t *rf_gain, *dsp_gain;
3461 uint8_t chan;
3462
3727 struct iwn4965_cmd_txpower cmd;
3728 struct iwn4965_eeprom_chan_samples *chans;
3729 int32_t vdiff, tdiff;
3730 int i, c, grp, maxpwr;
3731 const uint8_t *rf_gain, *dsp_gain;
3732 uint8_t chan;
3733
3463 /* Get channel number. */
3464 chan = ieee80211_chan2ieee(ic, ch);
3734 /* Retrieve current channel from last RXON. */
3735 chan = sc->rxon.chan;
3736 DPRINTF(sc, IWN_DEBUG_RESET, "setting TX power for channel %d\n",
3737 chan);
3738 ch = &ic->ic_channels[chan];
3465
3466 memset(&cmd, 0, sizeof cmd);
3467 cmd.band = IEEE80211_IS_CHAN_5GHZ(ch) ? 0 : 1;
3468 cmd.chan = chan;
3469
3470 if (IEEE80211_IS_CHAN_5GHZ(ch)) {
3471 maxpwr = sc->maxpwr5GHz;
3472 rf_gain = iwn4965_rf_gain_5ghz;

--- 9 unchanged lines hidden (view full) ---

3482 if (vdiff > 0)
3483 vdiff *= 2;
3484 if (abs(vdiff) > 2)
3485 vdiff = 0;
3486 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
3487 "%s: voltage compensation=%d (UCODE=%d, EEPROM=%d)\n",
3488 __func__, vdiff, le32toh(uc->volt), sc->eeprom_voltage);
3489
3739
3740 memset(&cmd, 0, sizeof cmd);
3741 cmd.band = IEEE80211_IS_CHAN_5GHZ(ch) ? 0 : 1;
3742 cmd.chan = chan;
3743
3744 if (IEEE80211_IS_CHAN_5GHZ(ch)) {
3745 maxpwr = sc->maxpwr5GHz;
3746 rf_gain = iwn4965_rf_gain_5ghz;

--- 9 unchanged lines hidden (view full) ---

3756 if (vdiff > 0)
3757 vdiff *= 2;
3758 if (abs(vdiff) > 2)
3759 vdiff = 0;
3760 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
3761 "%s: voltage compensation=%d (UCODE=%d, EEPROM=%d)\n",
3762 __func__, vdiff, le32toh(uc->volt), sc->eeprom_voltage);
3763
3490 /* Get channel's attenuation group. */
3764 /* Get channel attenuation group. */
3491 if (chan <= 20) /* 1-20 */
3492 grp = 4;
3493 else if (chan <= 43) /* 34-43 */
3494 grp = 0;
3495 else if (chan <= 70) /* 44-70 */
3496 grp = 1;
3497 else if (chan <= 124) /* 71-124 */
3498 grp = 2;
3499 else /* 125-200 */
3500 grp = 3;
3501 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
3502 "%s: chan %d, attenuation group=%d\n", __func__, chan, grp);
3503
3765 if (chan <= 20) /* 1-20 */
3766 grp = 4;
3767 else if (chan <= 43) /* 34-43 */
3768 grp = 0;
3769 else if (chan <= 70) /* 44-70 */
3770 grp = 1;
3771 else if (chan <= 124) /* 71-124 */
3772 grp = 2;
3773 else /* 125-200 */
3774 grp = 3;
3775 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
3776 "%s: chan %d, attenuation group=%d\n", __func__, chan, grp);
3777
3504 /* Get channel's sub-band. */
3778 /* Get channel sub-band. */
3505 for (i = 0; i < IWN_NBANDS; i++)
3506 if (sc->bands[i].lo != 0 &&
3507 sc->bands[i].lo <= chan && chan <= sc->bands[i].hi)
3508 break;
3509 if (i == IWN_NBANDS) /* Can't happen in real-life. */
3510 return EINVAL;
3511 chans = sc->bands[i].chans;
3512 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,

--- 18 unchanged lines hidden (view full) ---

3531
3532 /* Compute temperature compensation. */
3533 tdiff = ((sc->temp - temp) * 2) / tdiv[grp];
3534 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
3535 "%s: temperature compensation=%d (current=%d, EEPROM=%d)\n",
3536 __func__, tdiff, sc->temp, temp);
3537
3538 for (ridx = 0; ridx <= IWN_RIDX_MAX; ridx++) {
3779 for (i = 0; i < IWN_NBANDS; i++)
3780 if (sc->bands[i].lo != 0 &&
3781 sc->bands[i].lo <= chan && chan <= sc->bands[i].hi)
3782 break;
3783 if (i == IWN_NBANDS) /* Can't happen in real-life. */
3784 return EINVAL;
3785 chans = sc->bands[i].chans;
3786 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,

--- 18 unchanged lines hidden (view full) ---

3805
3806 /* Compute temperature compensation. */
3807 tdiff = ((sc->temp - temp) * 2) / tdiv[grp];
3808 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
3809 "%s: temperature compensation=%d (current=%d, EEPROM=%d)\n",
3810 __func__, tdiff, sc->temp, temp);
3811
3812 for (ridx = 0; ridx <= IWN_RIDX_MAX; ridx++) {
3813 /* Convert dBm to half-dBm. */
3539 maxchpwr = sc->maxpwr[chan] * 2;
3540 if ((ridx / 8) & 1)
3541 maxchpwr -= 6; /* MIMO 2T: -3dB */
3542
3543 pwr = maxpwr;
3544
3545 /* Adjust TX power based on rate. */
3546 if ((ridx % 8) == 5)
3547 pwr -= 15; /* OFDM48: -7.5dB */
3548 else if ((ridx % 8) == 6)
3549 pwr -= 17; /* OFDM54: -8.5dB */
3550 else if ((ridx % 8) == 7)
3551 pwr -= 20; /* OFDM60: -10dB */
3552 else
3553 pwr -= 10; /* Others: -5dB */
3554
3814 maxchpwr = sc->maxpwr[chan] * 2;
3815 if ((ridx / 8) & 1)
3816 maxchpwr -= 6; /* MIMO 2T: -3dB */
3817
3818 pwr = maxpwr;
3819
3820 /* Adjust TX power based on rate. */
3821 if ((ridx % 8) == 5)
3822 pwr -= 15; /* OFDM48: -7.5dB */
3823 else if ((ridx % 8) == 6)
3824 pwr -= 17; /* OFDM54: -8.5dB */
3825 else if ((ridx % 8) == 7)
3826 pwr -= 20; /* OFDM60: -10dB */
3827 else
3828 pwr -= 10; /* Others: -5dB */
3829
3555 /* Do not exceed channel's max TX power. */
3830 /* Do not exceed channel max TX power. */
3556 if (pwr > maxchpwr)
3557 pwr = maxchpwr;
3558
3559 idx = gain - (pwr - power) - tdiff - vdiff;
3560 if ((ridx / 8) & 1) /* MIMO */
3561 idx += (int32_t)le32toh(uc->atten[grp][c]);
3562
3563 if (cmd.band == 0)

--- 19 unchanged lines hidden (view full) ---

3583 "%s: set tx power for chan %d\n", __func__, chan);
3584 return iwn_cmd(sc, IWN_CMD_TXPOWER, &cmd, sizeof cmd, async);
3585
3586#undef interpolate
3587#undef fdivround
3588}
3589
3590int
3831 if (pwr > maxchpwr)
3832 pwr = maxchpwr;
3833
3834 idx = gain - (pwr - power) - tdiff - vdiff;
3835 if ((ridx / 8) & 1) /* MIMO */
3836 idx += (int32_t)le32toh(uc->atten[grp][c]);
3837
3838 if (cmd.band == 0)

--- 19 unchanged lines hidden (view full) ---

3858 "%s: set tx power for chan %d\n", __func__, chan);
3859 return iwn_cmd(sc, IWN_CMD_TXPOWER, &cmd, sizeof cmd, async);
3860
3861#undef interpolate
3862#undef fdivround
3863}
3864
3865int
3591iwn5000_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
3592 int async)
3866iwn5000_set_txpower(struct iwn_softc *sc, int async)
3593{
3594 struct iwn5000_cmd_txpower cmd;
3595
3596 /*
3597 * TX power calibration is handled automatically by the firmware
3598 * for 5000 Series.
3599 */
3600 memset(&cmd, 0, sizeof cmd);

--- 9 unchanged lines hidden (view full) ---

3610 */
3611int
3612iwn4965_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
3613{
3614 struct iwn4965_rx_phystat *phy = (void *)stat->phybuf;
3615 uint8_t mask, agc;
3616 int rssi;
3617
3867{
3868 struct iwn5000_cmd_txpower cmd;
3869
3870 /*
3871 * TX power calibration is handled automatically by the firmware
3872 * for 5000 Series.
3873 */
3874 memset(&cmd, 0, sizeof cmd);

--- 9 unchanged lines hidden (view full) ---

3884 */
3885int
3886iwn4965_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
3887{
3888 struct iwn4965_rx_phystat *phy = (void *)stat->phybuf;
3889 uint8_t mask, agc;
3890 int rssi;
3891
3618 mask = (le16toh(phy->antenna) >> 4) & 0x7;
3892 mask = (le16toh(phy->antenna) >> 4) & IWN_ANT_ABC;
3619 agc = (le16toh(phy->agc) >> 7) & 0x7f;
3620
3621 rssi = 0;
3622#if 0
3623 if (mask & IWN_ANT_A) /* Ant A */
3624 rssi = max(rssi, phy->rssi[0]);
3625 if (mask & IWN_ATH_B) /* Ant B */
3626 rssi = max(rssi, phy->rssi[2]);

--- 69 unchanged lines hidden (view full) ---

3696 return 0;
3697
3698 /* Sign-extend 23-bit R4 value to 32-bit. */
3699 r4 = (r4 << 8) >> 8;
3700 /* Compute temperature in Kelvin. */
3701 temp = (259 * (r4 - r2)) / (r3 - r1);
3702 temp = (temp * 97) / 100 + 8;
3703
3893 agc = (le16toh(phy->agc) >> 7) & 0x7f;
3894
3895 rssi = 0;
3896#if 0
3897 if (mask & IWN_ANT_A) /* Ant A */
3898 rssi = max(rssi, phy->rssi[0]);
3899 if (mask & IWN_ATH_B) /* Ant B */
3900 rssi = max(rssi, phy->rssi[2]);

--- 69 unchanged lines hidden (view full) ---

3970 return 0;
3971
3972 /* Sign-extend 23-bit R4 value to 32-bit. */
3973 r4 = (r4 << 8) >> 8;
3974 /* Compute temperature in Kelvin. */
3975 temp = (259 * (r4 - r2)) / (r3 - r1);
3976 temp = (temp * 97) / 100 + 8;
3977
3978 DPRINTF(sc, IWN_DEBUG_ANY, "temperature %dK/%dC\n", temp,
3979 IWN_KTOC(temp));
3704 return IWN_KTOC(temp);
3705}
3706
3707int
3708iwn5000_get_temperature(struct iwn_softc *sc)
3709{
3980 return IWN_KTOC(temp);
3981}
3982
3983int
3984iwn5000_get_temperature(struct iwn_softc *sc)
3985{
3986 int32_t temp;
3987
3710 /*
3711 * Temperature is not used by the driver for 5000 Series because
3712 * TX power calibration is handled by firmware. We export it to
3713 * users through the sensor framework though.
3714 */
3988 /*
3989 * Temperature is not used by the driver for 5000 Series because
3990 * TX power calibration is handled by firmware. We export it to
3991 * users through the sensor framework though.
3992 */
3715 return le32toh(sc->rawtemp);
3993 temp = le32toh(sc->rawtemp);
3994 if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
3995 temp = (temp / -5) + sc->temp_off;
3996 temp = IWN_KTOC(temp);
3997 }
3998 return temp;
3716}
3717
3718/*
3719 * Initialize sensitivity calibration state machine.
3720 */
3721int
3722iwn_init_sensitivity(struct iwn_softc *sc)
3723{
3724 const struct iwn_hal *hal = sc->sc_hal;
3725 struct iwn_calib_state *calib = &sc->calib;
3726 uint32_t flags;
3727 int error;
3728
3729 /* Reset calibration state machine. */
3730 memset(calib, 0, sizeof (*calib));
3731 calib->state = IWN_CALIB_STATE_INIT;
3732 calib->cck_state = IWN_CCK_STATE_HIFA;
3733 /* Set initial correlation values. */
3999}
4000
4001/*
4002 * Initialize sensitivity calibration state machine.
4003 */
4004int
4005iwn_init_sensitivity(struct iwn_softc *sc)
4006{
4007 const struct iwn_hal *hal = sc->sc_hal;
4008 struct iwn_calib_state *calib = &sc->calib;
4009 uint32_t flags;
4010 int error;
4011
4012 /* Reset calibration state machine. */
4013 memset(calib, 0, sizeof (*calib));
4014 calib->state = IWN_CALIB_STATE_INIT;
4015 calib->cck_state = IWN_CCK_STATE_HIFA;
4016 /* Set initial correlation values. */
3734 calib->ofdm_x1 = hal->limits->min_ofdm_x1;
3735 calib->ofdm_mrc_x1 = hal->limits->min_ofdm_mrc_x1;
4017 calib->ofdm_x1 = sc->limits->min_ofdm_x1;
4018 calib->ofdm_mrc_x1 = sc->limits->min_ofdm_mrc_x1;
3736 calib->ofdm_x4 = 90;
4019 calib->ofdm_x4 = 90;
3737 calib->ofdm_mrc_x4 = hal->limits->min_ofdm_mrc_x4;
4020 calib->ofdm_mrc_x4 = sc->limits->min_ofdm_mrc_x4;
3738 calib->cck_x4 = 125;
4021 calib->cck_x4 = 125;
3739 calib->cck_mrc_x4 = hal->limits->min_cck_mrc_x4;
3740 calib->energy_cck = hal->limits->energy_cck;
4022 calib->cck_mrc_x4 = sc->limits->min_cck_mrc_x4;
4023 calib->energy_cck = sc->limits->energy_cck;
3741
3742 /* Write initial sensitivity. */
3743 error = iwn_send_sensitivity(sc);
3744 if (error != 0)
3745 return error;
3746
3747 /* Write initial gains. */
3748 error = hal->init_gains(sc);

--- 29 unchanged lines hidden (view full) ---

3778 if (++calib->nbeacons < 20)
3779 return;
3780
3781 /* Determine highest average RSSI. */
3782 val = MAX(calib->rssi[0], calib->rssi[1]);
3783 val = MAX(calib->rssi[2], val);
3784
3785 /* Determine which antennas are connected. */
4024
4025 /* Write initial sensitivity. */
4026 error = iwn_send_sensitivity(sc);
4027 if (error != 0)
4028 return error;
4029
4030 /* Write initial gains. */
4031 error = hal->init_gains(sc);

--- 29 unchanged lines hidden (view full) ---

4061 if (++calib->nbeacons < 20)
4062 return;
4063
4064 /* Determine highest average RSSI. */
4065 val = MAX(calib->rssi[0], calib->rssi[1]);
4066 val = MAX(calib->rssi[2], val);
4067
4068 /* Determine which antennas are connected. */
3786 sc->antmsk = 0;
4069 sc->chainmask = 0;
3787 for (i = 0; i < 3; i++)
3788 if (val - calib->rssi[i] <= 15 * 20)
4070 for (i = 0; i < 3; i++)
4071 if (val - calib->rssi[i] <= 15 * 20)
3789 sc->antmsk |= 1 << i;
4072 sc->chainmask |= 1 << i;
3790 /* If none of the TX antennas are connected, keep at least one. */
4073 /* If none of the TX antennas are connected, keep at least one. */
3791 if ((sc->antmsk & sc->txantmsk) == 0)
3792 sc->antmsk |= IWN_LSB(sc->txantmsk);
4074 if ((sc->chainmask & sc->txchainmask) == 0)
4075 sc->chainmask |= IWN_LSB(sc->txchainmask);
3793
3794 (void)hal->set_gains(sc);
3795 calib->state = IWN_CALIB_STATE_RUN;
3796
3797#ifdef notyet
3798 /* XXX Disable RX chains with no antennas connected. */
4076
4077 (void)hal->set_gains(sc);
4078 calib->state = IWN_CALIB_STATE_RUN;
4079
4080#ifdef notyet
4081 /* XXX Disable RX chains with no antennas connected. */
3799 sc->rxon.rxchain = htole16(IWN_RXCHAIN_SEL(sc->antmsk));
3800 (void)iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->rxon, hal->rxonsz, 1);
4082 sc->rxon.rxchain = htole16(IWN_RXCHAIN_SEL(sc->chainmask));
4083 (void)iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1);
3801#endif
3802
3803#if 0
3804 /* XXX: not yet */
3805 /* Enable power-saving mode if requested by user. */
3806 if (sc->sc_ic.ic_flags & IEEE80211_F_PMGTON)
3807 (void)iwn_set_pslevel(sc, 0, 3, 1);
3808#endif

--- 12 unchanged lines hidden (view full) ---

3821 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
3822}
3823
3824int
3825iwn5000_init_gains(struct iwn_softc *sc)
3826{
3827 struct iwn_phy_calib cmd;
3828
4084#endif
4085
4086#if 0
4087 /* XXX: not yet */
4088 /* Enable power-saving mode if requested by user. */
4089 if (sc->sc_ic.ic_flags & IEEE80211_F_PMGTON)
4090 (void)iwn_set_pslevel(sc, 0, 3, 1);
4091#endif

--- 12 unchanged lines hidden (view full) ---

4104 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
4105}
4106
4107int
4108iwn5000_init_gains(struct iwn_softc *sc)
4109{
4110 struct iwn_phy_calib cmd;
4111
3829 if (sc->hw_type == IWN_HW_REV_TYPE_6000 ||
3830 sc->hw_type == IWN_HW_REV_TYPE_6050)
4112 if (sc->hw_type == IWN_HW_REV_TYPE_6050)
3831 return 0;
3832
3833 memset(&cmd, 0, sizeof cmd);
3834 cmd.code = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
3835 cmd.ngroups = 1;
3836 cmd.isvalid = 1;
3837 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
3838 "%s: setting initial differential gains\n", __func__);
3839 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
3840}
3841
3842int
3843iwn4965_set_gains(struct iwn_softc *sc)
3844{
3845 struct iwn_calib_state *calib = &sc->calib;
3846 struct iwn_phy_calib_gain cmd;
3847 int i, delta, noise;
3848
3849 /* Get minimal noise among connected antennas. */
4113 return 0;
4114
4115 memset(&cmd, 0, sizeof cmd);
4116 cmd.code = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
4117 cmd.ngroups = 1;
4118 cmd.isvalid = 1;
4119 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
4120 "%s: setting initial differential gains\n", __func__);
4121 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
4122}
4123
4124int
4125iwn4965_set_gains(struct iwn_softc *sc)
4126{
4127 struct iwn_calib_state *calib = &sc->calib;
4128 struct iwn_phy_calib_gain cmd;
4129 int i, delta, noise;
4130
4131 /* Get minimal noise among connected antennas. */
3850 noise = INT_MAX; /* NB: There's at least one antennaiwn. */
4132 noise = INT_MAX; /* NB: There's at least one antenna. */
3851 for (i = 0; i < 3; i++)
4133 for (i = 0; i < 3; i++)
3852 if (sc->antmsk & (1 << i))
4134 if (sc->chainmask & (1 << i))
3853 noise = MIN(calib->noise[i], noise);
3854
3855 memset(&cmd, 0, sizeof cmd);
3856 cmd.code = IWN4965_PHY_CALIB_DIFF_GAIN;
3857 /* Set differential gains for connected antennas. */
3858 for (i = 0; i < 3; i++) {
4135 noise = MIN(calib->noise[i], noise);
4136
4137 memset(&cmd, 0, sizeof cmd);
4138 cmd.code = IWN4965_PHY_CALIB_DIFF_GAIN;
4139 /* Set differential gains for connected antennas. */
4140 for (i = 0; i < 3; i++) {
3859 if (sc->antmsk & (1 << i)) {
4141 if (sc->chainmask & (1 << i)) {
3860 /* Compute attenuation (in unit of 1.5dB). */
3861 delta = (noise - (int32_t)calib->noise[i]) / 30;
3862 /* NB: delta <= 0 */
3863 /* Limit to [-4.5dB,0]. */
3864 cmd.gain[i] = MIN(abs(delta), 3);
3865 if (delta < 0)
3866 cmd.gain[i] |= 1 << 2; /* sign bit */
3867 }
3868 }
3869 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
3870 "setting differential gains Ant A/B/C: %x/%x/%x (%x)\n",
4142 /* Compute attenuation (in unit of 1.5dB). */
4143 delta = (noise - (int32_t)calib->noise[i]) / 30;
4144 /* NB: delta <= 0 */
4145 /* Limit to [-4.5dB,0]. */
4146 cmd.gain[i] = MIN(abs(delta), 3);
4147 if (delta < 0)
4148 cmd.gain[i] |= 1 << 2; /* sign bit */
4149 }
4150 }
4151 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
4152 "setting differential gains Ant A/B/C: %x/%x/%x (%x)\n",
3871 cmd.gain[0], cmd.gain[1], cmd.gain[2], sc->antmsk);
4153 cmd.gain[0], cmd.gain[1], cmd.gain[2], sc->chainmask);
3872 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
3873}
3874
3875int
3876iwn5000_set_gains(struct iwn_softc *sc)
3877{
3878 struct iwn_calib_state *calib = &sc->calib;
3879 struct iwn_phy_calib_gain cmd;
4154 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
4155}
4156
4157int
4158iwn5000_set_gains(struct iwn_softc *sc)
4159{
4160 struct iwn_calib_state *calib = &sc->calib;
4161 struct iwn_phy_calib_gain cmd;
3880 int i, delta;
4162 int i, ant, delta;
3881
4163
3882 if (sc->hw_type == IWN_HW_REV_TYPE_6000 ||
3883 sc->hw_type == IWN_HW_REV_TYPE_6050)
4164 if (sc->hw_type == IWN_HW_REV_TYPE_6050)
3884 return 0;
3885
3886 memset(&cmd, 0, sizeof cmd);
3887 cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN;
3888 cmd.ngroups = 1;
3889 cmd.isvalid = 1;
4165 return 0;
4166
4167 memset(&cmd, 0, sizeof cmd);
4168 cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN;
4169 cmd.ngroups = 1;
4170 cmd.isvalid = 1;
3890 /* Set differential gains for antennas B and C. */
3891 for (i = 1; i < 3; i++) {
3892 if (sc->antmsk & (1 << i)) {
3893 /* The delta is relative to antenna A. */
3894 delta = ((int32_t)calib->noise[0] -
4171 /* Get first available RX antenna as referential. */
4172 ant = IWN_LSB(sc->rxchainmask);
4173 /* Set differential gains for other antennas. */
4174 for (i = ant + 1; i < 3; i++) {
4175 if (sc->chainmask & (1 << i)) {
4176 /* The delta is relative to antenna "ant". */
4177 delta = ((int32_t)calib->noise[ant] -
3895 (int32_t)calib->noise[i]) / 30;
3896 /* Limit to [-4.5dB,+4.5dB]. */
3897 cmd.gain[i - 1] = MIN(abs(delta), 3);
3898 if (delta < 0)
3899 cmd.gain[i - 1] |= 1 << 2; /* sign bit */
3900 }
3901 }
3902 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
3903 "setting differential gains Ant B/C: %x/%x (%x)\n",
4178 (int32_t)calib->noise[i]) / 30;
4179 /* Limit to [-4.5dB,+4.5dB]. */
4180 cmd.gain[i - 1] = MIN(abs(delta), 3);
4181 if (delta < 0)
4182 cmd.gain[i - 1] |= 1 << 2; /* sign bit */
4183 }
4184 }
4185 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
4186 "setting differential gains Ant B/C: %x/%x (%x)\n",
3904 cmd.gain[0], cmd.gain[1], sc->antmsk);
4187 cmd.gain[0], cmd.gain[1], sc->chainmask);
3905 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
3906}
3907
3908/*
3909 * Tune RF RX sensitivity based on the number of false alarms detected
3910 * during the last beacon period.
3911 */
3912void

--- 11 unchanged lines hidden (view full) ---

3924 if ((val) > (min)) { \
3925 if ((val) > (min) + (dec)) \
3926 (val) -= (dec); \
3927 else \
3928 (val) = (min); \
3929 needs_update = 1; \
3930 }
3931
4188 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
4189}
4190
4191/*
4192 * Tune RF RX sensitivity based on the number of false alarms detected
4193 * during the last beacon period.
4194 */
4195void

--- 11 unchanged lines hidden (view full) ---

4207 if ((val) > (min)) { \
4208 if ((val) > (min) + (dec)) \
4209 (val) -= (dec); \
4210 else \
4211 (val) = (min); \
4212 needs_update = 1; \
4213 }
4214
3932 const struct iwn_hal *hal = sc->sc_hal;
3933 const struct iwn_sensitivity_limits *limits = hal->limits;
4215 const struct iwn_sensitivity_limits *limits = sc->limits;
3934 struct iwn_calib_state *calib = &sc->calib;
3935 uint32_t val, rxena, fa;
3936 uint32_t energy[3], energy_min;
3937 uint8_t noise[3], noise_ref;
3938 int i, needs_update = 0;
3939
3940 /* Check that we've been enabled long enough. */
3941 rxena = le32toh(stats->general.load);

--- 118 unchanged lines hidden (view full) ---

4060 (void)iwn_send_sensitivity(sc);
4061#undef dec
4062#undef inc
4063}
4064
4065int
4066iwn_send_sensitivity(struct iwn_softc *sc)
4067{
4216 struct iwn_calib_state *calib = &sc->calib;
4217 uint32_t val, rxena, fa;
4218 uint32_t energy[3], energy_min;
4219 uint8_t noise[3], noise_ref;
4220 int i, needs_update = 0;
4221
4222 /* Check that we've been enabled long enough. */
4223 rxena = le32toh(stats->general.load);

--- 118 unchanged lines hidden (view full) ---

4342 (void)iwn_send_sensitivity(sc);
4343#undef dec
4344#undef inc
4345}
4346
4347int
4348iwn_send_sensitivity(struct iwn_softc *sc)
4349{
4068 const struct iwn_hal *hal = sc->sc_hal;
4069 struct iwn_calib_state *calib = &sc->calib;
4070 struct iwn_sensitivity_cmd cmd;
4071
4072 memset(&cmd, 0, sizeof cmd);
4073 cmd.which = IWN_SENSITIVITY_WORKTBL;
4074 /* OFDM modulation. */
4075 cmd.corr_ofdm_x1 = htole16(calib->ofdm_x1);
4076 cmd.corr_ofdm_mrc_x1 = htole16(calib->ofdm_mrc_x1);
4077 cmd.corr_ofdm_x4 = htole16(calib->ofdm_x4);
4078 cmd.corr_ofdm_mrc_x4 = htole16(calib->ofdm_mrc_x4);
4350 struct iwn_calib_state *calib = &sc->calib;
4351 struct iwn_sensitivity_cmd cmd;
4352
4353 memset(&cmd, 0, sizeof cmd);
4354 cmd.which = IWN_SENSITIVITY_WORKTBL;
4355 /* OFDM modulation. */
4356 cmd.corr_ofdm_x1 = htole16(calib->ofdm_x1);
4357 cmd.corr_ofdm_mrc_x1 = htole16(calib->ofdm_mrc_x1);
4358 cmd.corr_ofdm_x4 = htole16(calib->ofdm_x4);
4359 cmd.corr_ofdm_mrc_x4 = htole16(calib->ofdm_mrc_x4);
4079 cmd.energy_ofdm = htole16(hal->limits->energy_ofdm);
4360 cmd.energy_ofdm = htole16(sc->limits->energy_ofdm);
4080 cmd.energy_ofdm_th = htole16(62);
4081 /* CCK modulation. */
4082 cmd.corr_cck_x4 = htole16(calib->cck_x4);
4083 cmd.corr_cck_mrc_x4 = htole16(calib->cck_mrc_x4);
4084 cmd.energy_cck = htole16(calib->energy_cck);
4085 /* Barker modulation: use default values. */
4086 cmd.corr_barker = htole16(190);
4087 cmd.corr_barker_mrc = htole16(390);

--- 27 unchanged lines hidden (view full) ---

4115 else
4116 pmgt = &iwn_pmgt[2][level];
4117
4118 memset(&cmd, 0, sizeof cmd);
4119 if (level != 0) /* not CAM */
4120 cmd.flags |= htole16(IWN_PS_ALLOW_SLEEP);
4121 if (level == 5)
4122 cmd.flags |= htole16(IWN_PS_FAST_PD);
4361 cmd.energy_ofdm_th = htole16(62);
4362 /* CCK modulation. */
4363 cmd.corr_cck_x4 = htole16(calib->cck_x4);
4364 cmd.corr_cck_mrc_x4 = htole16(calib->cck_mrc_x4);
4365 cmd.energy_cck = htole16(calib->energy_cck);
4366 /* Barker modulation: use default values. */
4367 cmd.corr_barker = htole16(190);
4368 cmd.corr_barker_mrc = htole16(390);

--- 27 unchanged lines hidden (view full) ---

4396 else
4397 pmgt = &iwn_pmgt[2][level];
4398
4399 memset(&cmd, 0, sizeof cmd);
4400 if (level != 0) /* not CAM */
4401 cmd.flags |= htole16(IWN_PS_ALLOW_SLEEP);
4402 if (level == 5)
4403 cmd.flags |= htole16(IWN_PS_FAST_PD);
4404 /* Retrieve PCIe Active State Power Management (ASPM). */
4123 tmp = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
4124 if (!(tmp & 0x1)) /* L0s Entry disabled. */
4125 cmd.flags |= htole16(IWN_PS_PCI_PMGT);
4126 cmd.rxtimeout = htole32(pmgt->rxtimeout * 1024);
4127 cmd.txtimeout = htole32(pmgt->txtimeout * 1024);
4128
4129 if (dtim == 0) {
4130 dtim = 1;

--- 19 unchanged lines hidden (view full) ---

4150
4151int
4152iwn_config(struct iwn_softc *sc)
4153{
4154 const struct iwn_hal *hal = sc->sc_hal;
4155 struct ifnet *ifp = sc->sc_ifp;
4156 struct ieee80211com *ic = ifp->if_l2com;
4157 struct iwn_bluetooth bluetooth;
4405 tmp = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
4406 if (!(tmp & 0x1)) /* L0s Entry disabled. */
4407 cmd.flags |= htole16(IWN_PS_PCI_PMGT);
4408 cmd.rxtimeout = htole32(pmgt->rxtimeout * 1024);
4409 cmd.txtimeout = htole32(pmgt->txtimeout * 1024);
4410
4411 if (dtim == 0) {
4412 dtim = 1;

--- 19 unchanged lines hidden (view full) ---

4432
4433int
4434iwn_config(struct iwn_softc *sc)
4435{
4436 const struct iwn_hal *hal = sc->sc_hal;
4437 struct ifnet *ifp = sc->sc_ifp;
4438 struct ieee80211com *ic = ifp->if_l2com;
4439 struct iwn_bluetooth bluetooth;
4440 uint32_t txmask;
4158 int error;
4159 uint16_t rxchain;
4160
4441 int error;
4442 uint16_t rxchain;
4443
4161 /* Set power saving level to CAM during initialization. */
4162 if ((error = iwn_set_pslevel(sc, 0, 0, 0)) != 0) {
4163 device_printf(sc->sc_dev,
4164 "%s: could not set power saving level, error %d\n",
4165 __func__, error);
4166 return error;
4444 /* Configure valid TX chains for 5000 Series. */
4445 if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
4446 txmask = htole32(sc->txchainmask);
4447 DPRINTF(sc, IWN_DEBUG_RESET,
4448 "%s: configuring valid TX chains 0x%x\n", __func__, txmask);
4449 error = iwn_cmd(sc, IWN5000_CMD_TX_ANT_CONFIG, &txmask,
4450 sizeof txmask, 0);
4451 if (error != 0) {
4452 device_printf(sc->sc_dev,
4453 "%s: could not configure valid TX chains, "
4454 "error %d\n", __func__, error);
4455 return error;
4456 }
4167 }
4168
4169 /* Configure bluetooth coexistence. */
4170 memset(&bluetooth, 0, sizeof bluetooth);
4457 }
4458
4459 /* Configure bluetooth coexistence. */
4460 memset(&bluetooth, 0, sizeof bluetooth);
4171 bluetooth.flags = 3;
4172 bluetooth.lead = 0xaa;
4173 bluetooth.kill = 1;
4461 bluetooth.flags = IWN_BT_COEX_MODE_4WIRE;
4462 bluetooth.lead_time = IWN_BT_LEAD_TIME_DEF;
4463 bluetooth.max_kill = IWN_BT_MAX_KILL_DEF;
4174 DPRINTF(sc, IWN_DEBUG_RESET, "%s: config bluetooth coexistence\n",
4175 __func__);
4176 error = iwn_cmd(sc, IWN_CMD_BT_COEX, &bluetooth, sizeof bluetooth, 0);
4177 if (error != 0) {
4178 device_printf(sc->sc_dev,
4179 "%s: could not configure bluetooth coexistence, error %d\n",
4180 __func__, error);
4181 return error;
4182 }
4183
4464 DPRINTF(sc, IWN_DEBUG_RESET, "%s: config bluetooth coexistence\n",
4465 __func__);
4466 error = iwn_cmd(sc, IWN_CMD_BT_COEX, &bluetooth, sizeof bluetooth, 0);
4467 if (error != 0) {
4468 device_printf(sc->sc_dev,
4469 "%s: could not configure bluetooth coexistence, error %d\n",
4470 __func__, error);
4471 return error;
4472 }
4473
4184 /* Configure adapter. */
4474 /* Set mode, channel, RX filter and enable RX. */
4185 memset(&sc->rxon, 0, sizeof (struct iwn_rxon));
4186 IEEE80211_ADDR_COPY(sc->rxon.myaddr, IF_LLADDR(ifp));
4187 IEEE80211_ADDR_COPY(sc->rxon.wlap, IF_LLADDR(ifp));
4475 memset(&sc->rxon, 0, sizeof (struct iwn_rxon));
4476 IEEE80211_ADDR_COPY(sc->rxon.myaddr, IF_LLADDR(ifp));
4477 IEEE80211_ADDR_COPY(sc->rxon.wlap, IF_LLADDR(ifp));
4188 /* Set default channel. */
4189 sc->rxon.chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
4190 sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
4191 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
4192 sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
4193 switch (ic->ic_opmode) {
4194 case IEEE80211_M_STA:
4195 sc->rxon.mode = IWN_MODE_STA;
4196 sc->rxon.filter = htole32(IWN_FILTER_MULTICAST);
4197 break;
4478 sc->rxon.chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
4479 sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
4480 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
4481 sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
4482 switch (ic->ic_opmode) {
4483 case IEEE80211_M_STA:
4484 sc->rxon.mode = IWN_MODE_STA;
4485 sc->rxon.filter = htole32(IWN_FILTER_MULTICAST);
4486 break;
4198 case IEEE80211_M_IBSS:
4199 case IEEE80211_M_AHDEMO:
4200 sc->rxon.mode = IWN_MODE_IBSS;
4201 break;
4202 case IEEE80211_M_HOSTAP:
4203 sc->rxon.mode = IWN_MODE_HOSTAP;
4204 break;
4205 case IEEE80211_M_MONITOR:
4206 sc->rxon.mode = IWN_MODE_MONITOR;
4207 sc->rxon.filter = htole32(IWN_FILTER_MULTICAST |
4208 IWN_FILTER_CTL | IWN_FILTER_PROMISC);
4209 break;
4210 default:
4211 /* Should not get there. */
4212 break;
4213 }
4214 sc->rxon.cck_mask = 0x0f; /* not yet negotiated */
4215 sc->rxon.ofdm_mask = 0xff; /* not yet negotiated */
4216 sc->rxon.ht_single_mask = 0xff;
4217 sc->rxon.ht_dual_mask = 0xff;
4487 case IEEE80211_M_MONITOR:
4488 sc->rxon.mode = IWN_MODE_MONITOR;
4489 sc->rxon.filter = htole32(IWN_FILTER_MULTICAST |
4490 IWN_FILTER_CTL | IWN_FILTER_PROMISC);
4491 break;
4492 default:
4493 /* Should not get there. */
4494 break;
4495 }
4496 sc->rxon.cck_mask = 0x0f; /* not yet negotiated */
4497 sc->rxon.ofdm_mask = 0xff; /* not yet negotiated */
4498 sc->rxon.ht_single_mask = 0xff;
4499 sc->rxon.ht_dual_mask = 0xff;
4218 rxchain = IWN_RXCHAIN_VALID(IWN_ANT_ABC) | IWN_RXCHAIN_IDLE_COUNT(2) |
4219 IWN_RXCHAIN_MIMO_COUNT(2);
4500 sc->rxon.ht_triple_mask = 0xff;
4501 rxchain =
4502 IWN_RXCHAIN_VALID(sc->rxchainmask) |
4503 IWN_RXCHAIN_MIMO_COUNT(2) |
4504 IWN_RXCHAIN_IDLE_COUNT(2);
4220 sc->rxon.rxchain = htole16(rxchain);
4221 DPRINTF(sc, IWN_DEBUG_RESET, "%s: setting configuration\n", __func__);
4505 sc->rxon.rxchain = htole16(rxchain);
4506 DPRINTF(sc, IWN_DEBUG_RESET, "%s: setting configuration\n", __func__);
4222 error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->rxon, hal->rxonsz, 0);
4507 error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 0);
4223 if (error != 0) {
4224 device_printf(sc->sc_dev,
4508 if (error != 0) {
4509 device_printf(sc->sc_dev,
4225 "%s: configure command failed\n", __func__);
4510 "%s: RXON command failed\n", __func__);
4226 return error;
4227 }
4511 return error;
4512 }
4228 sc->sc_curchan = ic->ic_curchan;
4229
4513
4514 error = iwn_add_broadcast_node(sc, 0);
4515 if (error != 0) {
4516 device_printf(sc->sc_dev,
4517 "%s: could not add broadcast node\n", __func__);
4518 return error;
4519 }
4520
4230 /* Configuration has changed, set TX power accordingly. */
4521 /* Configuration has changed, set TX power accordingly. */
4231 error = hal->set_txpower(sc, ic->ic_curchan, 0);
4522 error = hal->set_txpower(sc, 0);
4232 if (error != 0) {
4233 device_printf(sc->sc_dev,
4234 "%s: could not set TX power\n", __func__);
4235 return error;
4236 }
4237
4523 if (error != 0) {
4524 device_printf(sc->sc_dev,
4525 "%s: could not set TX power\n", __func__);
4526 return error;
4527 }
4528
4238 error = iwn_add_broadcast_node(sc, ic->ic_curchan, 0);
4529 error = iwn_set_critical_temp(sc);
4239 if (error != 0) {
4240 device_printf(sc->sc_dev,
4530 if (error != 0) {
4531 device_printf(sc->sc_dev,
4241 "%s: could not add broadcast node\n", __func__);
4532 "%s: ccould not set critical temperature\n", __func__);
4242 return error;
4243 }
4244
4533 return error;
4534 }
4535
4245 error = iwn_set_critical_temp(sc);
4536 /* Set power saving level to CAM during initialization. */
4537 error = iwn_set_pslevel(sc, 0, 0, 0);
4246 if (error != 0) {
4247 device_printf(sc->sc_dev,
4538 if (error != 0) {
4539 device_printf(sc->sc_dev,
4248 "%s: could not set critical temperature\n", __func__);
4540 "%s: could not set power saving level\n", __func__);
4249 return error;
4250 }
4251 return 0;
4252}
4253
4254int
4255iwn_scan(struct iwn_softc *sc)
4256{
4257 struct ifnet *ifp = sc->sc_ifp;
4258 struct ieee80211com *ic = ifp->if_l2com;
4259 struct ieee80211_scan_state *ss = ic->ic_scan; /*XXX*/
4260 struct iwn_scan_hdr *hdr;
4261 struct iwn_cmd_data *tx;
4262 struct iwn_scan_essid *essid;
4263 struct iwn_scan_chan *chan;
4264 struct ieee80211_frame *wh;
4265 struct ieee80211_rateset *rs;
4266 struct ieee80211_channel *c;
4541 return error;
4542 }
4543 return 0;
4544}
4545
4546int
4547iwn_scan(struct iwn_softc *sc)
4548{
4549 struct ifnet *ifp = sc->sc_ifp;
4550 struct ieee80211com *ic = ifp->if_l2com;
4551 struct ieee80211_scan_state *ss = ic->ic_scan; /*XXX*/
4552 struct iwn_scan_hdr *hdr;
4553 struct iwn_cmd_data *tx;
4554 struct iwn_scan_essid *essid;
4555 struct iwn_scan_chan *chan;
4556 struct ieee80211_frame *wh;
4557 struct ieee80211_rateset *rs;
4558 struct ieee80211_channel *c;
4267 enum ieee80211_phymode mode;
4268 int buflen, error, nrates;
4269 uint16_t rxchain;
4270 uint8_t *buf, *frm, txant;
4271
4272 buf = malloc(IWN_SCAN_MAXSZ, M_DEVBUF, M_NOWAIT | M_ZERO);
4273 if (buf == NULL) {
4274 device_printf(sc->sc_dev,
4275 "%s: could not allocate buffer for scan command\n",

--- 5 unchanged lines hidden (view full) ---

4281 /*
4282 * Move to the next channel if no frames are received within 10ms
4283 * after sending the probe request.
4284 */
4285 hdr->quiet_time = htole16(10); /* timeout in milliseconds */
4286 hdr->quiet_threshold = htole16(1); /* min # of packets */
4287
4288 /* Select antennas for scanning. */
4559 int buflen, error, nrates;
4560 uint16_t rxchain;
4561 uint8_t *buf, *frm, txant;
4562
4563 buf = malloc(IWN_SCAN_MAXSZ, M_DEVBUF, M_NOWAIT | M_ZERO);
4564 if (buf == NULL) {
4565 device_printf(sc->sc_dev,
4566 "%s: could not allocate buffer for scan command\n",

--- 5 unchanged lines hidden (view full) ---

4572 /*
4573 * Move to the next channel if no frames are received within 10ms
4574 * after sending the probe request.
4575 */
4576 hdr->quiet_time = htole16(10); /* timeout in milliseconds */
4577 hdr->quiet_threshold = htole16(1); /* min # of packets */
4578
4579 /* Select antennas for scanning. */
4289 rxchain = IWN_RXCHAIN_FORCE | IWN_RXCHAIN_VALID(IWN_ANT_ABC) |
4290 IWN_RXCHAIN_MIMO(IWN_ANT_ABC);
4580 rxchain =
4581 IWN_RXCHAIN_VALID(sc->rxchainmask) |
4582 IWN_RXCHAIN_FORCE_MIMO_SEL(sc->rxchainmask) |
4583 IWN_RXCHAIN_DRIVER_FORCE;
4291 if (IEEE80211_IS_CHAN_A(ic->ic_curchan) &&
4292 sc->hw_type == IWN_HW_REV_TYPE_4965) {
4293 /* Ant A must be avoided in 5GHz because of an HW bug. */
4584 if (IEEE80211_IS_CHAN_A(ic->ic_curchan) &&
4585 sc->hw_type == IWN_HW_REV_TYPE_4965) {
4586 /* Ant A must be avoided in 5GHz because of an HW bug. */
4294 rxchain |= IWN_RXCHAIN_SEL(IWN_ANT_B | IWN_ANT_C);
4587 rxchain |= IWN_RXCHAIN_FORCE_SEL(IWN_ANT_BC);
4295 } else /* Use all available RX antennas. */
4588 } else /* Use all available RX antennas. */
4296 rxchain |= IWN_RXCHAIN_SEL(IWN_ANT_ABC);
4589 rxchain |= IWN_RXCHAIN_FORCE_SEL(sc->rxchainmask);
4297 hdr->rxchain = htole16(rxchain);
4298 hdr->filter = htole32(IWN_FILTER_MULTICAST | IWN_FILTER_BEACON);
4299
4300 tx = (struct iwn_cmd_data *)(hdr + 1);
4301 tx->flags = htole32(IWN_TX_AUTO_SEQ);
4302 tx->id = sc->sc_hal->broadcast_id;
4303 tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
4304
4305 if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) {
4590 hdr->rxchain = htole16(rxchain);
4591 hdr->filter = htole32(IWN_FILTER_MULTICAST | IWN_FILTER_BEACON);
4592
4593 tx = (struct iwn_cmd_data *)(hdr + 1);
4594 tx->flags = htole32(IWN_TX_AUTO_SEQ);
4595 tx->id = sc->sc_hal->broadcast_id;
4596 tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
4597
4598 if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) {
4306 hdr->crc_threshold = htole16(1);
4307 /* Send probe requests at 6Mbps. */
4308 tx->plcp = iwn_rates[IWN_RIDX_OFDM6].plcp;
4599 /* Send probe requests at 6Mbps. */
4600 tx->plcp = iwn_rates[IWN_RIDX_OFDM6].plcp;
4601 rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
4309 } else {
4310 hdr->flags = htole32(IWN_RXON_24GHZ | IWN_RXON_AUTO);
4311 /* Send probe requests at 1Mbps. */
4312 tx->plcp = iwn_rates[IWN_RIDX_CCK1].plcp;
4313 tx->rflags = IWN_RFLAG_CCK;
4602 } else {
4603 hdr->flags = htole32(IWN_RXON_24GHZ | IWN_RXON_AUTO);
4604 /* Send probe requests at 1Mbps. */
4605 tx->plcp = iwn_rates[IWN_RIDX_CCK1].plcp;
4606 tx->rflags = IWN_RFLAG_CCK;
4607 rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
4314 }
4315 /* Use the first valid TX antenna. */
4608 }
4609 /* Use the first valid TX antenna. */
4316 txant = IWN_LSB(sc->txantmsk);
4610 txant = IWN_LSB(sc->txchainmask);
4317 tx->rflags |= IWN_RFLAG_ANT(txant);
4318
4319 essid = (struct iwn_scan_essid *)(tx + 1);
4320 if (ss->ss_ssid[0].len != 0) {
4321 essid[0].id = IEEE80211_ELEMID_SSID;
4322 essid[0].len = ss->ss_ssid[0].len;
4323 memcpy(essid[0].data, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
4324 }
4611 tx->rflags |= IWN_RFLAG_ANT(txant);
4612
4613 essid = (struct iwn_scan_essid *)(tx + 1);
4614 if (ss->ss_ssid[0].len != 0) {
4615 essid[0].id = IEEE80211_ELEMID_SSID;
4616 essid[0].len = ss->ss_ssid[0].len;
4617 memcpy(essid[0].data, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
4618 }
4619
4325 /*
4326 * Build a probe request frame. Most of the following code is a
4327 * copy & paste of what is done in net80211.
4328 */
4329 wh = (struct ieee80211_frame *)(essid + 20);
4330 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
4331 IEEE80211_FC0_SUBTYPE_PROBE_REQ;
4332 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;

--- 6 unchanged lines hidden (view full) ---

4339 frm = (uint8_t *)(wh + 1);
4340
4341 /* Add SSID IE. */
4342 *frm++ = IEEE80211_ELEMID_SSID;
4343 *frm++ = ss->ss_ssid[0].len;
4344 memcpy(frm, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
4345 frm += ss->ss_ssid[0].len;
4346
4620 /*
4621 * Build a probe request frame. Most of the following code is a
4622 * copy & paste of what is done in net80211.
4623 */
4624 wh = (struct ieee80211_frame *)(essid + 20);
4625 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
4626 IEEE80211_FC0_SUBTYPE_PROBE_REQ;
4627 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;

--- 6 unchanged lines hidden (view full) ---

4634 frm = (uint8_t *)(wh + 1);
4635
4636 /* Add SSID IE. */
4637 *frm++ = IEEE80211_ELEMID_SSID;
4638 *frm++ = ss->ss_ssid[0].len;
4639 memcpy(frm, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
4640 frm += ss->ss_ssid[0].len;
4641
4347 mode = ieee80211_chan2mode(ic->ic_curchan);
4348 rs = &ic->ic_sup_rates[mode];
4349
4350 /* Add supported rates IE. */
4351 *frm++ = IEEE80211_ELEMID_RATES;
4352 nrates = rs->rs_nrates;
4353 if (nrates > IEEE80211_RATE_SIZE)
4354 nrates = IEEE80211_RATE_SIZE;
4355 *frm++ = nrates;
4356 memcpy(frm, rs->rs_rates, nrates);
4357 frm += nrates;

--- 7 unchanged lines hidden (view full) ---

4365 frm += nrates;
4366 }
4367
4368 /* Set length of probe request. */
4369 tx->len = htole16(frm - (uint8_t *)wh);
4370
4371 c = ic->ic_curchan;
4372 chan = (struct iwn_scan_chan *)frm;
4642 /* Add supported rates IE. */
4643 *frm++ = IEEE80211_ELEMID_RATES;
4644 nrates = rs->rs_nrates;
4645 if (nrates > IEEE80211_RATE_SIZE)
4646 nrates = IEEE80211_RATE_SIZE;
4647 *frm++ = nrates;
4648 memcpy(frm, rs->rs_rates, nrates);
4649 frm += nrates;

--- 7 unchanged lines hidden (view full) ---

4657 frm += nrates;
4658 }
4659
4660 /* Set length of probe request. */
4661 tx->len = htole16(frm - (uint8_t *)wh);
4662
4663 c = ic->ic_curchan;
4664 chan = (struct iwn_scan_chan *)frm;
4373 chan->chan = ieee80211_chan2ieee(ic, c);
4665 chan->chan = htole16(ieee80211_chan2ieee(ic, c));
4374 chan->flags = 0;
4666 chan->flags = 0;
4375 if (!(c->ic_flags & IEEE80211_CHAN_PASSIVE))
4376 chan->flags |= htole32(IWN_CHAN_ACTIVE);
4377 if (ss->ss_nssid > 0)
4378 chan->flags |= htole32(IWN_CHAN_NPBREQS(1));
4379 chan->dsp_gain = 0x6e;
4667 if (ss->ss_nssid > 0)
4668 chan->flags |= htole32(IWN_CHAN_NPBREQS(1));
4669 chan->dsp_gain = 0x6e;
4380 if (IEEE80211_IS_CHAN_5GHZ(c)) {
4670 if (IEEE80211_IS_CHAN_5GHZ(c) &&
4671 !(c->ic_flags & IEEE80211_CHAN_PASSIVE)) {
4381 chan->rf_gain = 0x3b;
4382 chan->active = htole16(24);
4383 chan->passive = htole16(110);
4672 chan->rf_gain = 0x3b;
4673 chan->active = htole16(24);
4674 chan->passive = htole16(110);
4384 } else {
4675 chan->flags |= htole32(IWN_CHAN_ACTIVE);
4676 } else if (IEEE80211_IS_CHAN_5GHZ(c)) {
4677 chan->rf_gain = 0x3b;
4678 chan->active = htole16(24);
4679 if (sc->rxon.associd)
4680 chan->passive = htole16(78);
4681 else
4682 chan->passive = htole16(110);
4683 hdr->crc_threshold = htole16(1);
4684 } else if (!(c->ic_flags & IEEE80211_CHAN_PASSIVE)) {
4385 chan->rf_gain = 0x28;
4386 chan->active = htole16(36);
4387 chan->passive = htole16(120);
4685 chan->rf_gain = 0x28;
4686 chan->active = htole16(36);
4687 chan->passive = htole16(120);
4688 chan->flags |= htole32(IWN_CHAN_ACTIVE);
4689 } else {
4690 chan->rf_gain = 0x28;
4691 chan->active = htole16(36);
4692 if (sc->rxon.associd)
4693 chan->passive = htole16(88);
4694 else
4695 chan->passive = htole16(120);
4696 hdr->crc_threshold = htole16(1);
4388 }
4697 }
4389 hdr->nchan++;
4390 chan++;
4391
4698
4392 DPRINTF(sc, IWN_DEBUG_STATE, "%s: chan %u flags 0x%x rf_gain 0x%x "
4699 DPRINTF(sc, IWN_DEBUG_STATE,
4700 "%s: chan %u flags 0x%x rf_gain 0x%x "
4393 "dsp_gain 0x%x active 0x%x passive 0x%x\n", __func__,
4394 chan->chan, chan->flags, chan->rf_gain, chan->dsp_gain,
4395 chan->active, chan->passive);
4396
4701 "dsp_gain 0x%x active 0x%x passive 0x%x\n", __func__,
4702 chan->chan, chan->flags, chan->rf_gain, chan->dsp_gain,
4703 chan->active, chan->passive);
4704
4705 hdr->nchan++;
4706 chan++;
4397 buflen = (uint8_t *)chan - buf;
4398 hdr->len = htole16(buflen);
4399
4400 DPRINTF(sc, IWN_DEBUG_STATE, "sending scan command nchan=%d\n",
4401 hdr->nchan);
4402 error = iwn_cmd(sc, IWN_CMD_SCAN, buf, buflen, 1);
4403 free(buf, M_DEVBUF);
4404 return error;

--- 5 unchanged lines hidden (view full) ---

4410 const struct iwn_hal *hal = sc->sc_hal;
4411 struct ifnet *ifp = sc->sc_ifp;
4412 struct ieee80211com *ic = ifp->if_l2com;
4413 struct ieee80211_node *ni = vap->iv_bss;
4414 int error;
4415
4416 sc->calib.state = IWN_CALIB_STATE_INIT;
4417
4707 buflen = (uint8_t *)chan - buf;
4708 hdr->len = htole16(buflen);
4709
4710 DPRINTF(sc, IWN_DEBUG_STATE, "sending scan command nchan=%d\n",
4711 hdr->nchan);
4712 error = iwn_cmd(sc, IWN_CMD_SCAN, buf, buflen, 1);
4713 free(buf, M_DEVBUF);
4714 return error;

--- 5 unchanged lines hidden (view full) ---

4720 const struct iwn_hal *hal = sc->sc_hal;
4721 struct ifnet *ifp = sc->sc_ifp;
4722 struct ieee80211com *ic = ifp->if_l2com;
4723 struct ieee80211_node *ni = vap->iv_bss;
4724 int error;
4725
4726 sc->calib.state = IWN_CALIB_STATE_INIT;
4727
4418 /* Update adapter's configuration. */
4728 /* Update adapter configuration. */
4419 IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid);
4420 sc->rxon.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));
4421 sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
4422 if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
4423 sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
4424 if (ic->ic_flags & IEEE80211_F_SHSLOT)
4425 sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
4426 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)

--- 15 unchanged lines hidden (view full) ---

4442 "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
4443 __func__,
4444 le16toh(sc->rxon.chan), sc->rxon.mode, le32toh(sc->rxon.flags),
4445 sc->rxon.cck_mask, sc->rxon.ofdm_mask,
4446 sc->rxon.ht_single_mask, sc->rxon.ht_dual_mask,
4447 le16toh(sc->rxon.rxchain),
4448 sc->rxon.myaddr, ":", sc->rxon.wlap, ":", sc->rxon.bssid, ":",
4449 le16toh(sc->rxon.associd), le32toh(sc->rxon.filter));
4729 IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid);
4730 sc->rxon.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));
4731 sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
4732 if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
4733 sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
4734 if (ic->ic_flags & IEEE80211_F_SHSLOT)
4735 sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
4736 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)

--- 15 unchanged lines hidden (view full) ---

4752 "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
4753 __func__,
4754 le16toh(sc->rxon.chan), sc->rxon.mode, le32toh(sc->rxon.flags),
4755 sc->rxon.cck_mask, sc->rxon.ofdm_mask,
4756 sc->rxon.ht_single_mask, sc->rxon.ht_dual_mask,
4757 le16toh(sc->rxon.rxchain),
4758 sc->rxon.myaddr, ":", sc->rxon.wlap, ":", sc->rxon.bssid, ":",
4759 le16toh(sc->rxon.associd), le32toh(sc->rxon.filter));
4450 error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->rxon, hal->rxonsz, 1);
4760 error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1);
4451 if (error != 0) {
4452 device_printf(sc->sc_dev,
4761 if (error != 0) {
4762 device_printf(sc->sc_dev,
4453 "%s: could not configure, error %d\n", __func__, error);
4763 "%s: RXON command failed, error %d\n", __func__, error);
4454 return error;
4455 }
4764 return error;
4765 }
4456 sc->sc_curchan = ic->ic_curchan;
4457
4458 /* Configuration has changed, set TX power accordingly. */
4766
4767 /* Configuration has changed, set TX power accordingly. */
4459 if ((error = hal->set_txpower(sc, ni->ni_chan, 1)) != 0) {
4768 error = hal->set_txpower(sc, 1);
4769 if (error != 0) {
4460 device_printf(sc->sc_dev,
4461 "%s: could not set Tx power, error %d\n", __func__, error);
4462 return error;
4463 }
4464 /*
4770 device_printf(sc->sc_dev,
4771 "%s: could not set Tx power, error %d\n", __func__, error);
4772 return error;
4773 }
4774 /*
4465 * Reconfiguring RXON clears the firmware's nodes table so we must
4775 * Reconfiguring RXON clears the firmware nodes table so we must
4466 * add the broadcast node again.
4467 */
4776 * add the broadcast node again.
4777 */
4468 error = iwn_add_broadcast_node(sc, ic->ic_curchan, 1);
4778 error = iwn_add_broadcast_node(sc, 1);
4469 if (error != 0) {
4470 device_printf(sc->sc_dev,
4779 if (error != 0) {
4780 device_printf(sc->sc_dev,
4471 "%s: 1 could not add broadcast node, error %d\n",
4781 "%s: could not add broadcast node, error %d\n",
4472 __func__, error);
4473 return error;
4474 }
4475 return 0;
4476}
4477
4478/*
4479 * Configure the adapter for associated state.
4480 */
4481int
4482iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
4483{
4484#define MS(v,x) (((v) & x) >> x##_S)
4485 const struct iwn_hal *hal = sc->sc_hal;
4486 struct ifnet *ifp = sc->sc_ifp;
4487 struct ieee80211com *ic = ifp->if_l2com;
4488 struct ieee80211_node *ni = vap->iv_bss;
4489 struct iwn_node_info node;
4782 __func__, error);
4783 return error;
4784 }
4785 return 0;
4786}
4787
4788/*
4789 * Configure the adapter for associated state.
4790 */
4791int
4792iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
4793{
4794#define MS(v,x) (((v) & x) >> x##_S)
4795 const struct iwn_hal *hal = sc->sc_hal;
4796 struct ifnet *ifp = sc->sc_ifp;
4797 struct ieee80211com *ic = ifp->if_l2com;
4798 struct ieee80211_node *ni = vap->iv_bss;
4799 struct iwn_node_info node;
4490 int error, maxrxampdu, ampdudensity;
4800 int error;
4491
4492 sc->calib.state = IWN_CALIB_STATE_INIT;
4493
4494 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
4801
4802 sc->calib.state = IWN_CALIB_STATE_INIT;
4803
4804 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
4495 /* link LED blinks while monitoring */
4805 /* Link LED blinks while monitoring. */
4496 iwn_set_led(sc, IWN_LED_LINK, 5, 5);
4497 return 0;
4498 }
4499 error = iwn_set_timing(sc, ni);
4500 if (error != 0) {
4501 device_printf(sc->sc_dev,
4502 "%s: could not set timing, error %d\n", __func__, error);
4503 return error;
4504 }
4505
4806 iwn_set_led(sc, IWN_LED_LINK, 5, 5);
4807 return 0;
4808 }
4809 error = iwn_set_timing(sc, ni);
4810 if (error != 0) {
4811 device_printf(sc->sc_dev,
4812 "%s: could not set timing, error %d\n", __func__, error);
4813 return error;
4814 }
4815
4506 /* Update adapter's configuration. */
4816 /* Update adapter configuration. */
4817 IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid);
4818 sc->rxon.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));
4507 sc->rxon.associd = htole16(IEEE80211_AID(ni->ni_associd));
4508 /* Short preamble and slot time are negotiated when associating. */
4509 sc->rxon.flags &= ~htole32(IWN_RXON_SHPREAMBLE | IWN_RXON_SHSLOT);
4819 sc->rxon.associd = htole16(IEEE80211_AID(ni->ni_associd));
4820 /* Short preamble and slot time are negotiated when associating. */
4821 sc->rxon.flags &= ~htole32(IWN_RXON_SHPREAMBLE | IWN_RXON_SHSLOT);
4822 sc->rxon.flags |= htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
4823 if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
4824 sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
4825 else
4826 sc->rxon.flags &= ~htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
4510 if (ic->ic_flags & IEEE80211_F_SHSLOT)
4511 sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
4512 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
4513 sc->rxon.flags |= htole32(IWN_RXON_SHPREAMBLE);
4827 if (ic->ic_flags & IEEE80211_F_SHSLOT)
4828 sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
4829 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
4830 sc->rxon.flags |= htole32(IWN_RXON_SHPREAMBLE);
4831 if (IEEE80211_IS_CHAN_A(ni->ni_chan)) {
4832 sc->rxon.cck_mask = 0;
4833 sc->rxon.ofdm_mask = 0x15;
4834 } else if (IEEE80211_IS_CHAN_B(ni->ni_chan)) {
4835 sc->rxon.cck_mask = 0x03;
4836 sc->rxon.ofdm_mask = 0;
4837 } else {
4838 /* XXX assume 802.11b/g */
4839 sc->rxon.cck_mask = 0x0f;
4840 sc->rxon.ofdm_mask = 0x15;
4841 }
4842#if 0 /* HT */
4514 if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) {
4515 sc->rxon.flags &= ~htole32(IWN_RXON_HT);
4516 if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan))
4517 sc->rxon.flags |= htole32(IWN_RXON_HT40U);
4518 else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan))
4519 sc->rxon.flags |= htole32(IWN_RXON_HT40D);
4520 else
4521 sc->rxon.flags |= htole32(IWN_RXON_HT20);
4522 sc->rxon.rxchain = htole16(
4523 IWN_RXCHAIN_VALID(3)
4524 | IWN_RXCHAIN_MIMO_COUNT(3)
4525 | IWN_RXCHAIN_IDLE_COUNT(1)
4526 | IWN_RXCHAIN_MIMO_FORCE);
4527
4528 maxrxampdu = MS(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU);
4529 ampdudensity = MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
4530 } else
4531 maxrxampdu = ampdudensity = 0;
4843 if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) {
4844 sc->rxon.flags &= ~htole32(IWN_RXON_HT);
4845 if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan))
4846 sc->rxon.flags |= htole32(IWN_RXON_HT40U);
4847 else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan))
4848 sc->rxon.flags |= htole32(IWN_RXON_HT40D);
4849 else
4850 sc->rxon.flags |= htole32(IWN_RXON_HT20);
4851 sc->rxon.rxchain = htole16(
4852 IWN_RXCHAIN_VALID(3)
4853 | IWN_RXCHAIN_MIMO_COUNT(3)
4854 | IWN_RXCHAIN_IDLE_COUNT(1)
4855 | IWN_RXCHAIN_MIMO_FORCE);
4856
4857 maxrxampdu = MS(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU);
4858 ampdudensity = MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
4859 } else
4860 maxrxampdu = ampdudensity = 0;
4861#endif
4532 sc->rxon.filter |= htole32(IWN_FILTER_BSS);
4533
4534 DPRINTF(sc, IWN_DEBUG_STATE,
4535 "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
4536 "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
4537 "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
4538 __func__,
4539 le16toh(sc->rxon.chan), sc->rxon.mode, le32toh(sc->rxon.flags),
4540 sc->rxon.cck_mask, sc->rxon.ofdm_mask,
4541 sc->rxon.ht_single_mask, sc->rxon.ht_dual_mask,
4542 le16toh(sc->rxon.rxchain),
4543 sc->rxon.myaddr, ":", sc->rxon.wlap, ":", sc->rxon.bssid, ":",
4544 le16toh(sc->rxon.associd), le32toh(sc->rxon.filter));
4862 sc->rxon.filter |= htole32(IWN_FILTER_BSS);
4863
4864 DPRINTF(sc, IWN_DEBUG_STATE,
4865 "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
4866 "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
4867 "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
4868 __func__,
4869 le16toh(sc->rxon.chan), sc->rxon.mode, le32toh(sc->rxon.flags),
4870 sc->rxon.cck_mask, sc->rxon.ofdm_mask,
4871 sc->rxon.ht_single_mask, sc->rxon.ht_dual_mask,
4872 le16toh(sc->rxon.rxchain),
4873 sc->rxon.myaddr, ":", sc->rxon.wlap, ":", sc->rxon.bssid, ":",
4874 le16toh(sc->rxon.associd), le32toh(sc->rxon.filter));
4545 error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->rxon, hal->rxonsz, 1);
4875 error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1);
4546 if (error != 0) {
4547 device_printf(sc->sc_dev,
4548 "%s: could not update configuration, error %d\n",
4549 __func__, error);
4550 return error;
4551 }
4876 if (error != 0) {
4877 device_printf(sc->sc_dev,
4878 "%s: could not update configuration, error %d\n",
4879 __func__, error);
4880 return error;
4881 }
4552 sc->sc_curchan = ni->ni_chan;
4882
4553
4554 /* Configuration has changed, set TX power accordingly. */
4883
4884 /* Configuration has changed, set TX power accordingly. */
4555 error = hal->set_txpower(sc, ni->ni_chan, 1);
4885 error = hal->set_txpower(sc, 1);
4556 if (error != 0) {
4557 device_printf(sc->sc_dev,
4558 "%s: could not set Tx power, error %d\n", __func__, error);
4559 return error;
4560 }
4561
4562 /* Add BSS node. */
4563 memset(&node, 0, sizeof node);
4564 IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
4565 node.id = IWN_ID_BSS;
4886 if (error != 0) {
4887 device_printf(sc->sc_dev,
4888 "%s: could not set Tx power, error %d\n", __func__, error);
4889 return error;
4890 }
4891
4892 /* Add BSS node. */
4893 memset(&node, 0, sizeof node);
4894 IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
4895 node.id = IWN_ID_BSS;
4566 node.htflags = htole32(IWN_AMDPU_SIZE_FACTOR(maxrxampdu)
4567 | IWN_AMDPU_DENSITY(ampdudensity));
4896#ifdef notyet
4897 node.htflags = htole32(IWN_AMDPU_SIZE_FACTOR(3) |
4898 IWN_AMDPU_DENSITY(5)); /* 2us */
4899#endif
4568 DPRINTF(sc, IWN_DEBUG_STATE, "%s: add BSS node, id %d htflags 0x%x\n",
4569 __func__, node.id, le32toh(node.htflags));
4570 error = hal->add_node(sc, &node, 1);
4571 if (error != 0) {
4572 device_printf(sc->sc_dev, "could not add BSS node\n");
4573 return error;
4574 }
4900 DPRINTF(sc, IWN_DEBUG_STATE, "%s: add BSS node, id %d htflags 0x%x\n",
4901 __func__, node.id, le32toh(node.htflags));
4902 error = hal->add_node(sc, &node, 1);
4903 if (error != 0) {
4904 device_printf(sc->sc_dev, "could not add BSS node\n");
4905 return error;
4906 }
4575 error = iwn_set_link_quality(sc, node.id, ni->ni_chan, 1);
4907 DPRINTF(sc, IWN_DEBUG_STATE, "setting link quality for node %d\n",
4908 node.id);
4909 error = iwn_set_link_quality(sc, node.id, 1);
4576 if (error != 0) {
4577 device_printf(sc->sc_dev,
4578 "%s: could not setup MRR for node %d, error %d\n",
4579 __func__, node.id, error);
4580 return error;
4581 }
4582
4583 error = iwn_init_sensitivity(sc);

--- 10 unchanged lines hidden (view full) ---

4594
4595 /* Link LED always on while associated. */
4596 iwn_set_led(sc, IWN_LED_LINK, 0, 1);
4597
4598 return 0;
4599#undef MS
4600}
4601
4910 if (error != 0) {
4911 device_printf(sc->sc_dev,
4912 "%s: could not setup MRR for node %d, error %d\n",
4913 __func__, node.id, error);
4914 return error;
4915 }
4916
4917 error = iwn_init_sensitivity(sc);

--- 10 unchanged lines hidden (view full) ---

4928
4929 /* Link LED always on while associated. */
4930 iwn_set_led(sc, IWN_LED_LINK, 0, 1);
4931
4932 return 0;
4933#undef MS
4934}
4935
4936#if 0 /* HT */
4602/*
4937/*
4938 * This function is called by upper layer when an ADDBA request is received
4939 * from another STA and before the ADDBA response is sent.
4940 */
4941int
4942iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
4943 uint8_t tid)
4944{
4945 struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
4946 struct iwn_softc *sc = ic->ic_softc;
4947 struct iwn_node *wn = (void *)ni;
4948 struct iwn_node_info node;
4949
4950 memset(&node, 0, sizeof node);
4951 node.id = wn->id;
4952 node.control = IWN_NODE_UPDATE;
4953 node.flags = IWN_FLAG_SET_ADDBA;
4954 node.addba_tid = tid;
4955 node.addba_ssn = htole16(ba->ba_winstart);
4956 DPRINTF(sc, IWN_DEBUG_RECV, "ADDBA RA=%d TID=%d SSN=%d\n",
4957 wn->id, tid, ba->ba_winstart));
4958 return sc->sc_hal->add_node(sc, &node, 1);
4959}
4960
4961/*
4962 * This function is called by upper layer on teardown of an HT-immediate
4963 * Block Ack agreement (eg. uppon receipt of a DELBA frame.)
4964 */
4965void
4966iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
4967 uint8_t tid)
4968{
4969 struct iwn_softc *sc = ic->ic_softc;
4970 struct iwn_node *wn = (void *)ni;
4971 struct iwn_node_info node;
4972
4973 memset(&node, 0, sizeof node);
4974 node.id = wn->id;
4975 node.control = IWN_NODE_UPDATE;
4976 node.flags = IWN_FLAG_SET_DELBA;
4977 node.delba_tid = tid;
4978 DPRINTF(sc, IWN_DEBUG_RECV, "DELBA RA=%d TID=%d\n", wn->id, tid);
4979 (void)sc->sc_hal->add_node(sc, &node, 1);
4980}
4981
4982/*
4983 * This function is called by upper layer when an ADDBA response is received
4984 * from another STA.
4985 */
4986int
4987iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
4988 uint8_t tid)
4989{
4990 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
4991 struct iwn_softc *sc = ic->ic_softc;
4992 const struct iwn_hal *hal = sc->sc_hal;
4993 struct iwn_node *wn = (void *)ni;
4994 struct iwn_node_info node;
4995 int error;
4996
4997 /* Enable TX for the specified RA/TID. */
4998 wn->disable_tid &= ~(1 << tid);
4999 memset(&node, 0, sizeof node);
5000 node.id = wn->id;
5001 node.control = IWN_NODE_UPDATE;
5002 node.flags = IWN_FLAG_SET_DISABLE_TID;
5003 node.disable_tid = htole16(wn->disable_tid);
5004 error = hal->add_node(sc, &node, 1);
5005 if (error != 0)
5006 return error;
5007
5008 if ((error = iwn_nic_lock(sc)) != 0)
5009 return error;
5010 hal->ampdu_tx_start(sc, ni, tid, ba->ba_winstart);
5011 iwn_nic_unlock(sc);
5012 return 0;
5013}
5014
5015void
5016iwn_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
5017 uint8_t tid)
5018{
5019 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
5020 struct iwn_softc *sc = ic->ic_softc;
5021 int error;
5022
5023 error = iwn_nic_lock(sc);
5024 if (error != 0)
5025 return;
5026 sc->sc_hal->ampdu_tx_stop(sc, tid, ba->ba_winstart);
5027 iwn_nic_unlock(sc);
5028}
5029
5030void
5031iwn4965_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
5032 uint8_t tid, uint16_t ssn)
5033{
5034 struct iwn_node *wn = (void *)ni;
5035 int qid = 7 + tid;
5036
5037 /* Stop TX scheduler while we're changing its configuration. */
5038 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
5039 IWN4965_TXQ_STATUS_CHGACT);
5040
5041 /* Assign RA/TID translation to the queue. */
5042 iwn_mem_write_2(sc, sc->sched_base + IWN4965_SCHED_TRANS_TBL(qid),
5043 wn->id << 4 | tid);
5044
5045 /* Enable chain-building mode for the queue. */
5046 iwn_prph_setbits(sc, IWN4965_SCHED_QCHAIN_SEL, 1 << qid);
5047
5048 /* Set starting sequence number from the ADDBA request. */
5049 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
5050 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), ssn);
5051
5052 /* Set scheduler window size. */
5053 iwn_mem_write(sc, sc->sched_base + IWN4965_SCHED_QUEUE_OFFSET(qid),
5054 IWN_SCHED_WINSZ);
5055 /* Set scheduler frame limit. */
5056 iwn_mem_write(sc, sc->sched_base + IWN4965_SCHED_QUEUE_OFFSET(qid) + 4,
5057 IWN_SCHED_LIMIT << 16);
5058
5059 /* Enable interrupts for the queue. */
5060 iwn_prph_setbits(sc, IWN4965_SCHED_INTR_MASK, 1 << qid);
5061
5062 /* Mark the queue as active. */
5063 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
5064 IWN4965_TXQ_STATUS_ACTIVE | IWN4965_TXQ_STATUS_AGGR_ENA |
5065 iwn_tid2fifo[tid] << 1);
5066}
5067
5068void
5069iwn4965_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
5070{
5071 int qid = 7 + tid;
5072
5073 /* Stop TX scheduler while we're changing its configuration. */
5074 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
5075 IWN4965_TXQ_STATUS_CHGACT);
5076
5077 /* Set starting sequence number from the ADDBA request. */
5078 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
5079 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), ssn);
5080
5081 /* Disable interrupts for the queue. */
5082 iwn_prph_clrbits(sc, IWN4965_SCHED_INTR_MASK, 1 << qid);
5083
5084 /* Mark the queue as inactive. */
5085 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
5086 IWN4965_TXQ_STATUS_INACTIVE | iwn_tid2fifo[tid] << 1);
5087}
5088
5089void
5090iwn5000_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
5091 uint8_t tid, uint16_t ssn)
5092{
5093 struct iwn_node *wn = (void *)ni;
5094 int qid = 10 + tid;
5095
5096 /* Stop TX scheduler while we're changing its configuration. */
5097 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
5098 IWN5000_TXQ_STATUS_CHGACT);
5099
5100 /* Assign RA/TID translation to the queue. */
5101 iwn_mem_write_2(sc, sc->sched_base + IWN5000_SCHED_TRANS_TBL(qid),
5102 wn->id << 4 | tid);
5103
5104 /* Enable chain-building mode for the queue. */
5105 iwn_prph_setbits(sc, IWN5000_SCHED_QCHAIN_SEL, 1 << qid);
5106
5107 /* Enable aggregation for the queue. */
5108 iwn_prph_setbits(sc, IWN5000_SCHED_AGGR_SEL, 1 << qid);
5109
5110 /* Set starting sequence number from the ADDBA request. */
5111 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
5112 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), ssn);
5113
5114 /* Set scheduler window size and frame limit. */
5115 iwn_mem_write(sc, sc->sched_base + IWN5000_SCHED_QUEUE_OFFSET(qid) + 4,
5116 IWN_SCHED_LIMIT << 16 | IWN_SCHED_WINSZ);
5117
5118 /* Enable interrupts for the queue. */
5119 iwn_prph_setbits(sc, IWN5000_SCHED_INTR_MASK, 1 << qid);
5120
5121 /* Mark the queue as active. */
5122 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
5123 IWN5000_TXQ_STATUS_ACTIVE | iwn_tid2fifo[tid]);
5124}
5125
5126void
5127iwn5000_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
5128{
5129 int qid = 10 + tid;
5130
5131 /* Stop TX scheduler while we're changing its configuration. */
5132 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
5133 IWN5000_TXQ_STATUS_CHGACT);
5134
5135 /* Disable aggregation for the queue. */
5136 iwn_prph_clrbits(sc, IWN5000_SCHED_AGGR_SEL, 1 << qid);
5137
5138 /* Set starting sequence number from the ADDBA request. */
5139 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
5140 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), ssn);
5141
5142 /* Disable interrupts for the queue. */
5143 iwn_prph_clrbits(sc, IWN5000_SCHED_INTR_MASK, 1 << qid);
5144
5145 /* Mark the queue as inactive. */
5146 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
5147 IWN5000_TXQ_STATUS_INACTIVE | iwn_tid2fifo[tid]);
5148}
5149#endif
5150
5151/*
4603 * Query calibration tables from the initialization firmware. We do this
4604 * only once at first boot. Called from a process context.
4605 */
4606int
4607iwn5000_query_calibration(struct iwn_softc *sc)
4608{
4609 struct iwn5000_calib_config cmd;
4610 int error;

--- 5 unchanged lines hidden (view full) ---

4616 cmd.ucode.flags = 0xffffffff;
4617 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: sending calibration query\n",
4618 __func__);
4619 error = iwn_cmd(sc, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof cmd, 0);
4620 if (error != 0)
4621 return error;
4622
4623 /* Wait at most two seconds for calibration to complete. */
5152 * Query calibration tables from the initialization firmware. We do this
5153 * only once at first boot. Called from a process context.
5154 */
5155int
5156iwn5000_query_calibration(struct iwn_softc *sc)
5157{
5158 struct iwn5000_calib_config cmd;
5159 int error;

--- 5 unchanged lines hidden (view full) ---

5165 cmd.ucode.flags = 0xffffffff;
5166 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: sending calibration query\n",
5167 __func__);
5168 error = iwn_cmd(sc, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof cmd, 0);
5169 if (error != 0)
5170 return error;
5171
5172 /* Wait at most two seconds for calibration to complete. */
4624 return msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", 2 * hz);
5173 if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE))
5174 error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", 2 * hz);
5175 return error;
4625}
4626
4627/*
4628 * Send calibration results to the runtime firmware. These results were
4629 * obtained on first boot from the initialization firmware.
4630 */
4631int
4632iwn5000_send_calibration(struct iwn_softc *sc)

--- 13 unchanged lines hidden (view full) ---

4646 "%s: could not send calibration result, error %d\n",
4647 __func__, error);
4648 return error;
4649 }
4650 }
4651 return 0;
4652}
4653
5176}
5177
5178/*
5179 * Send calibration results to the runtime firmware. These results were
5180 * obtained on first boot from the initialization firmware.
5181 */
5182int
5183iwn5000_send_calibration(struct iwn_softc *sc)

--- 13 unchanged lines hidden (view full) ---

5197 "%s: could not send calibration result, error %d\n",
5198 __func__, error);
5199 return error;
5200 }
5201 }
5202 return 0;
5203}
5204
5205int
5206iwn5000_send_wimax_coex(struct iwn_softc *sc)
5207{
5208 struct iwn5000_wimax_coex wimax;
5209
5210#ifdef notyet
5211 if (sc->hw_type == IWN_HW_REV_TYPE_6050) {
5212 /* Enable WiMAX coexistence for combo adapters. */
5213 wimax.flags =
5214 IWN_WIMAX_COEX_ASSOC_WA_UNMASK |
5215 IWN_WIMAX_COEX_UNASSOC_WA_UNMASK |
5216 IWN_WIMAX_COEX_STA_TABLE_VALID |
5217 IWN_WIMAX_COEX_ENABLE;
5218 memcpy(wimax.events, iwn6050_wimax_events,
5219 sizeof iwn6050_wimax_events);
5220 } else
5221#endif
5222 {
5223 /* Disable WiMAX coexistence. */
5224 wimax.flags = 0;
5225 memset(wimax.events, 0, sizeof wimax.events);
5226 }
5227 DPRINTF(sc, IWN_DEBUG_RESET, "%s: Configuring WiMAX coexistence\n",
5228 __func__);
5229 return iwn_cmd(sc, IWN5000_CMD_WIMAX_COEX, &wimax, sizeof wimax, 0);
5230}
5231
4654/*
4655 * This function is called after the runtime firmware notifies us of its
4656 * readiness (called in a process context.)
4657 */
4658int
4659iwn4965_post_alive(struct iwn_softc *sc)
4660{
4661 int error, qid;
4662
4663 if ((error = iwn_nic_lock(sc)) != 0)
4664 return error;
4665
5232/*
5233 * This function is called after the runtime firmware notifies us of its
5234 * readiness (called in a process context.)
5235 */
5236int
5237iwn4965_post_alive(struct iwn_softc *sc)
5238{
5239 int error, qid;
5240
5241 if ((error = iwn_nic_lock(sc)) != 0)
5242 return error;
5243
4666 /* Clear TX scheduler's state in SRAM. */
5244 /* Clear TX scheduler state in SRAM. */
4667 sc->sched_base = iwn_prph_read(sc, IWN_SCHED_SRAM_ADDR);
4668 iwn_mem_set_region_4(sc, sc->sched_base + IWN4965_SCHED_CTX_OFF, 0,
5245 sc->sched_base = iwn_prph_read(sc, IWN_SCHED_SRAM_ADDR);
5246 iwn_mem_set_region_4(sc, sc->sched_base + IWN4965_SCHED_CTX_OFF, 0,
4669 IWN4965_SCHED_CTX_LEN);
5247 IWN4965_SCHED_CTX_LEN / sizeof (uint32_t));
4670
4671 /* Set physical address of TX scheduler rings (1KB aligned.) */
4672 iwn_prph_write(sc, IWN4965_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
4673
4674 IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
4675
4676 /* Disable chain mode for all our 16 queues. */
4677 iwn_prph_write(sc, IWN4965_SCHED_QCHAIN_SEL, 0);

--- 28 unchanged lines hidden (view full) ---

4706
4707/*
4708 * This function is called after the initialization or runtime firmware
4709 * notifies us of its readiness (called in a process context.)
4710 */
4711int
4712iwn5000_post_alive(struct iwn_softc *sc)
4713{
5248
5249 /* Set physical address of TX scheduler rings (1KB aligned.) */
5250 iwn_prph_write(sc, IWN4965_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
5251
5252 IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
5253
5254 /* Disable chain mode for all our 16 queues. */
5255 iwn_prph_write(sc, IWN4965_SCHED_QCHAIN_SEL, 0);

--- 28 unchanged lines hidden (view full) ---

5284
5285/*
5286 * This function is called after the initialization or runtime firmware
5287 * notifies us of its readiness (called in a process context.)
5288 */
5289int
5290iwn5000_post_alive(struct iwn_softc *sc)
5291{
4714 struct iwn5000_wimax_coex wimax;
4715 int error, qid;
4716
5292 int error, qid;
5293
4717 if ((error = iwn_nic_lock(sc)) != 0)
5294 /* Switch to using ICT interrupt mode. */
5295 iwn5000_ict_reset(sc);
5296
5297 error = iwn_nic_lock(sc);
5298 if (error != 0)
4718 return error;
4719
5299 return error;
5300
4720 /* Clear TX scheduler's state in SRAM. */
5301 /* Clear TX scheduler state in SRAM. */
4721 sc->sched_base = iwn_prph_read(sc, IWN_SCHED_SRAM_ADDR);
4722 iwn_mem_set_region_4(sc, sc->sched_base + IWN5000_SCHED_CTX_OFF, 0,
5302 sc->sched_base = iwn_prph_read(sc, IWN_SCHED_SRAM_ADDR);
5303 iwn_mem_set_region_4(sc, sc->sched_base + IWN5000_SCHED_CTX_OFF, 0,
4723 IWN5000_SCHED_CTX_LEN);
5304 IWN5000_SCHED_CTX_LEN / sizeof (uint32_t));
4724
4725 /* Set physical address of TX scheduler rings (1KB aligned.) */
4726 iwn_prph_write(sc, IWN5000_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
4727
4728 IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
4729
5305
5306 /* Set physical address of TX scheduler rings (1KB aligned.) */
5307 iwn_prph_write(sc, IWN5000_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
5308
5309 IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
5310
4730 /* Enable chain mode for all our 20 queues. */
4731 iwn_prph_write(sc, IWN5000_SCHED_QCHAIN_SEL, 0xfffff);
5311 /* Enable chain mode for all queues, except command queue. */
5312 iwn_prph_write(sc, IWN5000_SCHED_QCHAIN_SEL, 0xfffef);
4732 iwn_prph_write(sc, IWN5000_SCHED_AGGR_SEL, 0);
4733
4734 for (qid = 0; qid < IWN5000_NTXQUEUES; qid++) {
4735 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), 0);
4736 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | 0);
4737
4738 iwn_mem_write(sc, sc->sched_base +
4739 IWN5000_SCHED_QUEUE_OFFSET(qid), 0);

--- 11 unchanged lines hidden (view full) ---

4751 /* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */
4752 for (qid = 0; qid < 7; qid++) {
4753 static uint8_t qid2fifo[] = { 3, 2, 1, 0, 7, 5, 6 };
4754 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
4755 IWN5000_TXQ_STATUS_ACTIVE | qid2fifo[qid]);
4756 }
4757 iwn_nic_unlock(sc);
4758
5313 iwn_prph_write(sc, IWN5000_SCHED_AGGR_SEL, 0);
5314
5315 for (qid = 0; qid < IWN5000_NTXQUEUES; qid++) {
5316 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), 0);
5317 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | 0);
5318
5319 iwn_mem_write(sc, sc->sched_base +
5320 IWN5000_SCHED_QUEUE_OFFSET(qid), 0);

--- 11 unchanged lines hidden (view full) ---

5332 /* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */
5333 for (qid = 0; qid < 7; qid++) {
5334 static uint8_t qid2fifo[] = { 3, 2, 1, 0, 7, 5, 6 };
5335 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
5336 IWN5000_TXQ_STATUS_ACTIVE | qid2fifo[qid]);
5337 }
5338 iwn_nic_unlock(sc);
5339
4759 /* Configure WiMAX (IEEE 802.16e) coexistence. */
4760 memset(&wimax, 0, sizeof wimax);
4761 DPRINTF(sc, IWN_DEBUG_RESET, "%s: Configuring WiMAX coexistence\n",
4762 __func__);
4763 error = iwn_cmd(sc, IWN5000_CMD_WIMAX_COEX, &wimax, sizeof wimax, 0);
5340 /* Configure WiMAX coexistence for combo adapters. */
5341 error = iwn5000_send_wimax_coex(sc);
4764 if (error != 0) {
4765 device_printf(sc->sc_dev,
4766 "%s: could not configure WiMAX coexistence, error %d\n",
4767 __func__, error);
4768 return error;
4769 }
5342 if (error != 0) {
5343 device_printf(sc->sc_dev,
5344 "%s: could not configure WiMAX coexistence, error %d\n",
5345 __func__, error);
5346 return error;
5347 }
4770
4771 if (sc->hw_type != IWN_HW_REV_TYPE_5150) {
4772 struct iwn5000_phy_calib_crystal cmd;
4773
4774 /* Perform crystal calibration. */
4775 memset(&cmd, 0, sizeof cmd);
4776 cmd.code = IWN5000_PHY_CALIB_CRYSTAL;
4777 cmd.ngroups = 1;
4778 cmd.isvalid = 1;

--- 5 unchanged lines hidden (view full) ---

4784 error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
4785 if (error != 0) {
4786 device_printf(sc->sc_dev,
4787 "%s: crystal calibration failed, error %d\n",
4788 __func__, error);
4789 return error;
4790 }
4791 }
5348 if (sc->hw_type != IWN_HW_REV_TYPE_5150) {
5349 struct iwn5000_phy_calib_crystal cmd;
5350
5351 /* Perform crystal calibration. */
5352 memset(&cmd, 0, sizeof cmd);
5353 cmd.code = IWN5000_PHY_CALIB_CRYSTAL;
5354 cmd.ngroups = 1;
5355 cmd.isvalid = 1;

--- 5 unchanged lines hidden (view full) ---

5361 error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
5362 if (error != 0) {
5363 device_printf(sc->sc_dev,
5364 "%s: crystal calibration failed, error %d\n",
5365 __func__, error);
5366 return error;
5367 }
5368 }
4792 if (sc->sc_flags & IWN_FLAG_FIRST_BOOT) {
5369 if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE)) {
4793 /* Query calibration from the initialization firmware. */
5370 /* Query calibration from the initialization firmware. */
4794 if ((error = iwn5000_query_calibration(sc)) != 0) {
5371 error = iwn5000_query_calibration(sc);
5372 if (error != 0) {
4795 device_printf(sc->sc_dev,
4796 "%s: could not query calibration, error %d\n",
4797 __func__, error);
4798 return error;
4799 }
4800 /*
5373 device_printf(sc->sc_dev,
5374 "%s: could not query calibration, error %d\n",
5375 __func__, error);
5376 return error;
5377 }
5378 /*
4801 * We have the calibration results now so we can skip
4802 * loading the initialization firmware next time.
5379 * We have the calibration results now, reboot with the
5380 * runtime firmware (call ourselves recursively!)
4803 */
5381 */
4804 sc->sc_flags &= ~IWN_FLAG_FIRST_BOOT;
4805
4806 /* Reboot (call ourselves recursively!) */
4807 iwn_hw_stop(sc);
4808 error = iwn_hw_init(sc);
4809 } else {
4810 /* Send calibration results to runtime firmware. */
4811 error = iwn5000_send_calibration(sc);
4812 }
4813 return error;
4814}

--- 156 unchanged lines hidden (view full) ---

4971
4972int
4973iwn5000_load_firmware(struct iwn_softc *sc)
4974{
4975 struct iwn_fw_part *fw;
4976 int error;
4977
4978 /* Load the initialization firmware on first boot only. */
5382 iwn_hw_stop(sc);
5383 error = iwn_hw_init(sc);
5384 } else {
5385 /* Send calibration results to runtime firmware. */
5386 error = iwn5000_send_calibration(sc);
5387 }
5388 return error;
5389}

--- 156 unchanged lines hidden (view full) ---

5546
5547int
5548iwn5000_load_firmware(struct iwn_softc *sc)
5549{
5550 struct iwn_fw_part *fw;
5551 int error;
5552
5553 /* Load the initialization firmware on first boot only. */
4979 fw = (sc->sc_flags & IWN_FLAG_FIRST_BOOT) ?
4980 &sc->fw.init : &sc->fw.main;
5554 fw = (sc->sc_flags & IWN_FLAG_CALIB_DONE) ?
5555 &sc->fw.main : &sc->fw.init;
4981
4982 error = iwn5000_load_firmware_section(sc, IWN_FW_TEXT_BASE,
4983 fw->text, fw->textsz);
4984 if (error != 0) {
4985 device_printf(sc->sc_dev,
4986 "%s: could not load firmware %s section, error %d\n",
4987 __func__, ".text", error);
4988 return error;

--- 11 unchanged lines hidden (view full) ---

5000 IWN_WRITE(sc, IWN_RESET, 0);
5001 return 0;
5002}
5003
5004int
5005iwn_read_firmware(struct iwn_softc *sc)
5006{
5007 const struct iwn_hal *hal = sc->sc_hal;
5556
5557 error = iwn5000_load_firmware_section(sc, IWN_FW_TEXT_BASE,
5558 fw->text, fw->textsz);
5559 if (error != 0) {
5560 device_printf(sc->sc_dev,
5561 "%s: could not load firmware %s section, error %d\n",
5562 __func__, ".text", error);
5563 return error;

--- 11 unchanged lines hidden (view full) ---

5575 IWN_WRITE(sc, IWN_RESET, 0);
5576 return 0;
5577}
5578
5579int
5580iwn_read_firmware(struct iwn_softc *sc)
5581{
5582 const struct iwn_hal *hal = sc->sc_hal;
5008 const struct iwn_firmware_hdr *hdr;
5009 struct iwn_fw_info *fw = &sc->fw;
5583 struct iwn_fw_info *fw = &sc->fw;
5584 const uint32_t *ptr;
5585 uint32_t rev;
5010 size_t size;
5011
5012 IWN_UNLOCK(sc);
5013
5014 /* Read firmware image from filesystem. */
5015 sc->fw_fp = firmware_get(sc->fwname);
5016 if (sc->fw_fp == NULL) {
5017 device_printf(sc->sc_dev,
5018 "%s: could not load firmare image \"%s\"\n", __func__,
5019 sc->fwname);
5020 IWN_LOCK(sc);
5021 return EINVAL;
5022 }
5023 IWN_LOCK(sc);
5024
5025 size = sc->fw_fp->datasize;
5586 size_t size;
5587
5588 IWN_UNLOCK(sc);
5589
5590 /* Read firmware image from filesystem. */
5591 sc->fw_fp = firmware_get(sc->fwname);
5592 if (sc->fw_fp == NULL) {
5593 device_printf(sc->sc_dev,
5594 "%s: could not load firmare image \"%s\"\n", __func__,
5595 sc->fwname);
5596 IWN_LOCK(sc);
5597 return EINVAL;
5598 }
5599 IWN_LOCK(sc);
5600
5601 size = sc->fw_fp->datasize;
5026 if (size < sizeof (*hdr)) {
5602 if (size < 28) {
5027 device_printf(sc->sc_dev,
5028 "%s: truncated firmware header: %zu bytes\n",
5029 __func__, size);
5030 return EINVAL;
5031 }
5032
5603 device_printf(sc->sc_dev,
5604 "%s: truncated firmware header: %zu bytes\n",
5605 __func__, size);
5606 return EINVAL;
5607 }
5608
5033 /* Extract firmware header information. */
5034 hdr = (const struct iwn_firmware_hdr *)sc->fw_fp->data;
5035 fw->main.textsz = le32toh(hdr->main_textsz);
5036 fw->main.datasz = le32toh(hdr->main_datasz);
5037 fw->init.textsz = le32toh(hdr->init_textsz);
5038 fw->init.datasz = le32toh(hdr->init_datasz);
5039 fw->boot.textsz = le32toh(hdr->boot_textsz);
5040 fw->boot.datasz = 0;
5609 /* Process firmware header. */
5610 ptr = (const uint32_t *)sc->fw_fp->data;
5611 rev = le32toh(*ptr++);
5612 /* Check firmware API version. */
5613 if (IWN_FW_API(rev) <= 1) {
5614 device_printf(sc->sc_dev,
5615 "%s: bad firmware, need API version >=2\n", __func__);
5616 return EINVAL;
5617 }
5618 if (IWN_FW_API(rev) >= 3) {
5619 /* Skip build number (version 2 header). */
5620 size -= 4;
5621 ptr++;
5622 }
5623 fw->main.textsz = le32toh(*ptr++);
5624 fw->main.datasz = le32toh(*ptr++);
5625 fw->init.textsz = le32toh(*ptr++);
5626 fw->init.datasz = le32toh(*ptr++);
5627 fw->boot.textsz = le32toh(*ptr++);
5628 size -= 24;
5041
5042 /* Sanity-check firmware header. */
5043 if (fw->main.textsz > hal->fw_text_maxsz ||
5044 fw->main.datasz > hal->fw_data_maxsz ||
5045 fw->init.textsz > hal->fw_text_maxsz ||
5046 fw->init.datasz > hal->fw_data_maxsz ||
5047 fw->boot.textsz > IWN_FW_BOOT_TEXT_MAXSZ ||
5048 (fw->boot.textsz & 3) != 0) {
5049 device_printf(sc->sc_dev, "%s: invalid firmware header\n",
5050 __func__);
5051 return EINVAL;
5052 }
5053
5054 /* Check that all firmware sections fit. */
5629
5630 /* Sanity-check firmware header. */
5631 if (fw->main.textsz > hal->fw_text_maxsz ||
5632 fw->main.datasz > hal->fw_data_maxsz ||
5633 fw->init.textsz > hal->fw_text_maxsz ||
5634 fw->init.datasz > hal->fw_data_maxsz ||
5635 fw->boot.textsz > IWN_FW_BOOT_TEXT_MAXSZ ||
5636 (fw->boot.textsz & 3) != 0) {
5637 device_printf(sc->sc_dev, "%s: invalid firmware header\n",
5638 __func__);
5639 return EINVAL;
5640 }
5641
5642 /* Check that all firmware sections fit. */
5055 if (size < sizeof (*hdr) + fw->main.textsz + fw->main.datasz +
5056 fw->init.textsz + fw->init.datasz + fw->boot.textsz) {
5643 if (fw->main.textsz + fw->main.datasz + fw->init.textsz +
5644 fw->init.datasz + fw->boot.textsz > size) {
5057 device_printf(sc->sc_dev,
5058 "%s: firmware file too short: %zu bytes\n",
5059 __func__, size);
5060 return EINVAL;
5061 }
5062
5063 /* Get pointers to firmware sections. */
5645 device_printf(sc->sc_dev,
5646 "%s: firmware file too short: %zu bytes\n",
5647 __func__, size);
5648 return EINVAL;
5649 }
5650
5651 /* Get pointers to firmware sections. */
5064 fw->main.text = (const uint8_t *)(hdr + 1);
5652 fw->main.text = (const uint8_t *)ptr;
5065 fw->main.data = fw->main.text + fw->main.textsz;
5066 fw->init.text = fw->main.data + fw->main.datasz;
5067 fw->init.data = fw->init.text + fw->init.textsz;
5068 fw->boot.text = fw->init.data + fw->init.datasz;
5069
5070 return 0;
5071}
5072
5653 fw->main.data = fw->main.text + fw->main.textsz;
5654 fw->init.text = fw->main.data + fw->main.datasz;
5655 fw->init.data = fw->init.text + fw->init.textsz;
5656 fw->boot.text = fw->init.data + fw->init.datasz;
5657
5658 return 0;
5659}
5660
5073void
5074iwn_unload_firmware(struct iwn_softc *sc)
5075{
5076 if (sc->fw_fp != NULL) {
5077 firmware_put(sc->fw_fp, FIRMWARE_UNLOAD);
5078 sc->fw_fp = NULL;
5079 }
5080}
5081
5082int
5083iwn_clock_wait(struct iwn_softc *sc)
5084{
5085 int ntries;
5086
5087 /* Set "initialization complete" bit. */
5088 IWN_SETBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
5089
5090 /* Wait for clock stabilization. */
5661int
5662iwn_clock_wait(struct iwn_softc *sc)
5663{
5664 int ntries;
5665
5666 /* Set "initialization complete" bit. */
5667 IWN_SETBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
5668
5669 /* Wait for clock stabilization. */
5091 for (ntries = 0; ntries < 25000; ntries++) {
5670 for (ntries = 0; ntries < 2500; ntries++) {
5092 if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_MAC_CLOCK_READY)
5093 return 0;
5671 if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_MAC_CLOCK_READY)
5672 return 0;
5094 DELAY(100);
5673 DELAY(10);
5095 }
5096 device_printf(sc->sc_dev,
5097 "%s: timeout waiting for clock stabilization\n", __func__);
5098 return ETIMEDOUT;
5099}
5100
5101int
5674 }
5675 device_printf(sc->sc_dev,
5676 "%s: timeout waiting for clock stabilization\n", __func__);
5677 return ETIMEDOUT;
5678}
5679
5680int
5102iwn4965_apm_init(struct iwn_softc *sc)
5681iwn_apm_init(struct iwn_softc *sc)
5103{
5682{
5683 uint32_t tmp;
5104 int error;
5105
5684 int error;
5685
5106 /* Disable L0s. */
5686 /* Disable L0s exit timer (NMI bug workaround.) */
5107 IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_DIS_L0S_TIMER);
5687 IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_DIS_L0S_TIMER);
5688 /* Don't wait for ICH L0s (ICH bug workaround.) */
5108 IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_L1A_NO_L0S_RX);
5109
5689 IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_L1A_NO_L0S_RX);
5690
5110 error = iwn_clock_wait(sc);
5111 if (error != 0)
5112 return error;
5113
5114 error = iwn_nic_lock(sc);
5115 if (error != 0)
5116 return error;
5117
5118 /* Enable DMA. */
5119 iwn_prph_write(sc, IWN_APMG_CLK_CTRL,
5120 IWN_APMG_CLK_CTRL_DMA_CLK_RQT | IWN_APMG_CLK_CTRL_BSM_CLK_RQT);
5121 DELAY(20);
5122
5123 /* Disable L1. */
5124 iwn_prph_setbits(sc, IWN_APMG_PCI_STT, IWN_APMG_PCI_STT_L1A_DIS);
5125 iwn_nic_unlock(sc);
5126
5127 return 0;
5128}
5129
5130int
5131iwn5000_apm_init(struct iwn_softc *sc)
5132{
5133 int error;
5134
5135 /* Disable L0s. */
5136 IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_DIS_L0S_TIMER);
5137 IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_L1A_NO_L0S_RX);
5138
5139 /* Set Flow Handler wait threshold to the maximum. */
5691 /* Set FH wait threshold to max (HW bug under stress workaround.) */
5140 IWN_SETBITS(sc, IWN_DBG_HPET_MEM, 0xffff0000);
5141
5692 IWN_SETBITS(sc, IWN_DBG_HPET_MEM, 0xffff0000);
5693
5142 /* Enable HAP to move adapter from L1a to L0s. */
5694 /* Enable HAP INTA to move adapter from L1a to L0s. */
5143 IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_HAP_WAKE_L1A);
5144
5695 IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_HAP_WAKE_L1A);
5696
5145 if (sc->hw_type != IWN_HW_REV_TYPE_6000 &&
5697 /* Retrieve PCIe Active State Power Management (ASPM). */
5698 tmp = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
5699 /* Workaround for HW instability in PCIe L0->L0s->L1 transition. */
5700 if (tmp & 0x02) /* L1 Entry enabled. */
5701 IWN_SETBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
5702 else
5703 IWN_CLRBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
5704
5705 if (sc->hw_type != IWN_HW_REV_TYPE_4965 &&
5706 sc->hw_type != IWN_HW_REV_TYPE_6000 &&
5146 sc->hw_type != IWN_HW_REV_TYPE_6050)
5147 IWN_SETBITS(sc, IWN_ANA_PLL, IWN_ANA_PLL_INIT);
5148
5707 sc->hw_type != IWN_HW_REV_TYPE_6050)
5708 IWN_SETBITS(sc, IWN_ANA_PLL, IWN_ANA_PLL_INIT);
5709
5710 /* Wait for clock stabilization before accessing prph. */
5149 error = iwn_clock_wait(sc);
5150 if (error != 0)
5151 return error;
5152
5153 error = iwn_nic_lock(sc);
5154 if (error != 0)
5155 return error;
5156
5711 error = iwn_clock_wait(sc);
5712 if (error != 0)
5713 return error;
5714
5715 error = iwn_nic_lock(sc);
5716 if (error != 0)
5717 return error;
5718
5157 /* Enable DMA. */
5158 iwn_prph_write(sc, IWN_APMG_CLK_CTRL, IWN_APMG_CLK_CTRL_DMA_CLK_RQT);
5719 if (sc->hw_type == IWN_HW_REV_TYPE_4965) {
5720 /* Enable DMA and BSM (Bootstrap State Machine.) */
5721 iwn_prph_write(sc, IWN_APMG_CLK_EN,
5722 IWN_APMG_CLK_CTRL_DMA_CLK_RQT |
5723 IWN_APMG_CLK_CTRL_BSM_CLK_RQT);
5724 } else {
5725 /* Enable DMA. */
5726 iwn_prph_write(sc, IWN_APMG_CLK_EN,
5727 IWN_APMG_CLK_CTRL_DMA_CLK_RQT);
5728 }
5159 DELAY(20);
5160
5729 DELAY(20);
5730
5161 /* Disable L1. */
5731 /* Disable L1-Active. */
5162 iwn_prph_setbits(sc, IWN_APMG_PCI_STT, IWN_APMG_PCI_STT_L1A_DIS);
5163 iwn_nic_unlock(sc);
5164
5165 return 0;
5166}
5167
5168void
5169iwn_apm_stop_master(struct iwn_softc *sc)
5170{
5171 int ntries;
5172
5732 iwn_prph_setbits(sc, IWN_APMG_PCI_STT, IWN_APMG_PCI_STT_L1A_DIS);
5733 iwn_nic_unlock(sc);
5734
5735 return 0;
5736}
5737
5738void
5739iwn_apm_stop_master(struct iwn_softc *sc)
5740{
5741 int ntries;
5742
5743 /* Stop busmaster DMA activity. */
5173 IWN_SETBITS(sc, IWN_RESET, IWN_RESET_STOP_MASTER);
5174 for (ntries = 0; ntries < 100; ntries++) {
5175 if (IWN_READ(sc, IWN_RESET) & IWN_RESET_MASTER_DISABLED)
5176 return;
5177 DELAY(10);
5178 }
5179 device_printf(sc->sc_dev, "%s: timeout waiting for master\n",
5180 __func__);
5181}
5182
5183void
5184iwn_apm_stop(struct iwn_softc *sc)
5185{
5186 iwn_apm_stop_master(sc);
5187
5744 IWN_SETBITS(sc, IWN_RESET, IWN_RESET_STOP_MASTER);
5745 for (ntries = 0; ntries < 100; ntries++) {
5746 if (IWN_READ(sc, IWN_RESET) & IWN_RESET_MASTER_DISABLED)
5747 return;
5748 DELAY(10);
5749 }
5750 device_printf(sc->sc_dev, "%s: timeout waiting for master\n",
5751 __func__);
5752}
5753
5754void
5755iwn_apm_stop(struct iwn_softc *sc)
5756{
5757 iwn_apm_stop_master(sc);
5758
5759 /* Reset the entire device. */
5188 IWN_SETBITS(sc, IWN_RESET, IWN_RESET_SW);
5189 DELAY(10);
5190 /* Clear "initialization complete" bit. */
5191 IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
5192}
5193
5194int
5195iwn4965_nic_config(struct iwn_softc *sc)
5196{
5760 IWN_SETBITS(sc, IWN_RESET, IWN_RESET_SW);
5761 DELAY(10);
5762 /* Clear "initialization complete" bit. */
5763 IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
5764}
5765
5766int
5767iwn4965_nic_config(struct iwn_softc *sc)
5768{
5197 uint32_t tmp;
5198
5199 /* Retrieve PCIe Active State Power Management (ASPM). */
5200 tmp = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
5201 if (tmp & 0x02) /* L1 Entry enabled. */
5202 IWN_SETBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
5203 else
5204 IWN_CLRBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
5205
5206 if (IWN_RFCFG_TYPE(sc->rfcfg) == 1) {
5207 /*
5208 * I don't believe this to be correct but this is what the
5209 * vendor driver is doing. Probably the bits should not be
5210 * shifted in IWN_RFCFG_*.
5211 */
5212 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
5213 IWN_RFCFG_TYPE(sc->rfcfg) |

--- 6 unchanged lines hidden (view full) ---

5220}
5221
5222int
5223iwn5000_nic_config(struct iwn_softc *sc)
5224{
5225 uint32_t tmp;
5226 int error;
5227
5769 if (IWN_RFCFG_TYPE(sc->rfcfg) == 1) {
5770 /*
5771 * I don't believe this to be correct but this is what the
5772 * vendor driver is doing. Probably the bits should not be
5773 * shifted in IWN_RFCFG_*.
5774 */
5775 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
5776 IWN_RFCFG_TYPE(sc->rfcfg) |

--- 6 unchanged lines hidden (view full) ---

5783}
5784
5785int
5786iwn5000_nic_config(struct iwn_softc *sc)
5787{
5788 uint32_t tmp;
5789 int error;
5790
5228 /* Retrieve PCIe Active State Power Management (ASPM). */
5229 tmp = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
5230 if (tmp & 0x02) /* L1 Entry enabled. */
5231 IWN_SETBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
5232 else
5233 IWN_CLRBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
5234
5235 if (IWN_RFCFG_TYPE(sc->rfcfg) < 3) {
5236 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
5237 IWN_RFCFG_TYPE(sc->rfcfg) |
5238 IWN_RFCFG_STEP(sc->rfcfg) |
5239 IWN_RFCFG_DASH(sc->rfcfg));
5240 }
5241 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
5242 IWN_HW_IF_CONFIG_RADIO_SI | IWN_HW_IF_CONFIG_MAC_SI);
5243
5244 error = iwn_nic_lock(sc);
5245 if (error != 0)
5246 return error;
5247 iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_EARLY_PWROFF_DIS);
5791 if (IWN_RFCFG_TYPE(sc->rfcfg) < 3) {
5792 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
5793 IWN_RFCFG_TYPE(sc->rfcfg) |
5794 IWN_RFCFG_STEP(sc->rfcfg) |
5795 IWN_RFCFG_DASH(sc->rfcfg));
5796 }
5797 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
5798 IWN_HW_IF_CONFIG_RADIO_SI | IWN_HW_IF_CONFIG_MAC_SI);
5799
5800 error = iwn_nic_lock(sc);
5801 if (error != 0)
5802 return error;
5803 iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_EARLY_PWROFF_DIS);
5804
5805 if (sc->hw_type == IWN_HW_REV_TYPE_1000) {
5806 /*
5807 * Select first Switching Voltage Regulator (1.32V) to
5808 * solve a stability issue related to noisy DC2DC line
5809 * in the silicon of 1000 Series.
5810 */
5811 tmp = iwn_prph_read(sc, IWN_APMG_DIGITAL_SVR);
5812 tmp &= ~IWN_APMG_DIGITAL_SVR_VOLTAGE_MASK;
5813 tmp |= IWN_APMG_DIGITAL_SVR_VOLTAGE_1_32;
5814 iwn_prph_write(sc, IWN_APMG_DIGITAL_SVR, tmp);
5815 }
5248 iwn_nic_unlock(sc);
5816 iwn_nic_unlock(sc);
5817
5818 if (sc->sc_flags & IWN_FLAG_INTERNAL_PA) {
5819 /* Use internal power amplifier only. */
5820 IWN_WRITE(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_RADIO_2X2_IPA);
5821 }
5249 return 0;
5250}
5251
5252/*
5253 * Take NIC ownership over Intel Active Management Technology (AMT).
5254 */
5255int
5256iwn_hw_prepare(struct iwn_softc *sc)
5257{
5258 int ntries;
5259
5822 return 0;
5823}
5824
5825/*
5826 * Take NIC ownership over Intel Active Management Technology (AMT).
5827 */
5828int
5829iwn_hw_prepare(struct iwn_softc *sc)
5830{
5831 int ntries;
5832
5833 /* Check if hardware is ready. */
5834 IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_NIC_READY);
5835 for (ntries = 0; ntries < 5; ntries++) {
5836 if (IWN_READ(sc, IWN_HW_IF_CONFIG) &
5837 IWN_HW_IF_CONFIG_NIC_READY)
5838 return 0;
5839 DELAY(10);
5840 }
5841
5842 /* Hardware not ready, force into ready state. */
5260 IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_PREPARE);
5261 for (ntries = 0; ntries < 15000; ntries++) {
5262 if (!(IWN_READ(sc, IWN_HW_IF_CONFIG) &
5263 IWN_HW_IF_CONFIG_PREPARE_DONE))
5264 break;
5265 DELAY(10);
5266 }
5267 if (ntries == 15000)
5268 return ETIMEDOUT;
5269
5843 IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_PREPARE);
5844 for (ntries = 0; ntries < 15000; ntries++) {
5845 if (!(IWN_READ(sc, IWN_HW_IF_CONFIG) &
5846 IWN_HW_IF_CONFIG_PREPARE_DONE))
5847 break;
5848 DELAY(10);
5849 }
5850 if (ntries == 15000)
5851 return ETIMEDOUT;
5852
5853 /* Hardware should be ready now. */
5270 IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_NIC_READY);
5271 for (ntries = 0; ntries < 5; ntries++) {
5272 if (IWN_READ(sc, IWN_HW_IF_CONFIG) &
5273 IWN_HW_IF_CONFIG_NIC_READY)
5274 return 0;
5275 DELAY(10);
5276 }
5277 return ETIMEDOUT;
5278}
5279
5280int
5281iwn_hw_init(struct iwn_softc *sc)
5282{
5283 const struct iwn_hal *hal = sc->sc_hal;
5284 int error, chnl, qid;
5285
5286 /* Clear pending interrupts. */
5287 IWN_WRITE(sc, IWN_INT, 0xffffffff);
5288
5854 IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_NIC_READY);
5855 for (ntries = 0; ntries < 5; ntries++) {
5856 if (IWN_READ(sc, IWN_HW_IF_CONFIG) &
5857 IWN_HW_IF_CONFIG_NIC_READY)
5858 return 0;
5859 DELAY(10);
5860 }
5861 return ETIMEDOUT;
5862}
5863
5864int
5865iwn_hw_init(struct iwn_softc *sc)
5866{
5867 const struct iwn_hal *hal = sc->sc_hal;
5868 int error, chnl, qid;
5869
5870 /* Clear pending interrupts. */
5871 IWN_WRITE(sc, IWN_INT, 0xffffffff);
5872
5289 error = hal->apm_init(sc);
5873 error = iwn_apm_init(sc);
5290 if (error != 0) {
5291 device_printf(sc->sc_dev,
5292 "%s: could not power ON adapter, error %d\n",
5293 __func__, error);
5294 return error;
5295 }
5296
5297 /* Select VMAIN power source. */

--- 60 unchanged lines hidden (view full) ---

5358 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
5359 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_CMD_BLOCKED);
5360
5361 /* Clear pending interrupts. */
5362 IWN_WRITE(sc, IWN_INT, 0xffffffff);
5363 /* Enable interrupt coalescing. */
5364 IWN_WRITE(sc, IWN_INT_COALESCING, 512 / 8);
5365 /* Enable interrupts. */
5874 if (error != 0) {
5875 device_printf(sc->sc_dev,
5876 "%s: could not power ON adapter, error %d\n",
5877 __func__, error);
5878 return error;
5879 }
5880
5881 /* Select VMAIN power source. */

--- 60 unchanged lines hidden (view full) ---

5942 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
5943 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_CMD_BLOCKED);
5944
5945 /* Clear pending interrupts. */
5946 IWN_WRITE(sc, IWN_INT, 0xffffffff);
5947 /* Enable interrupt coalescing. */
5948 IWN_WRITE(sc, IWN_INT_COALESCING, 512 / 8);
5949 /* Enable interrupts. */
5366 IWN_WRITE(sc, IWN_MASK, IWN_INT_MASK);
5950 IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
5367
5368 /* _Really_ make sure "radio off" bit is cleared! */
5369 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
5370 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
5371
5372 error = hal->load_firmware(sc);
5373 if (error != 0) {
5374 device_printf(sc->sc_dev,

--- 18 unchanged lines hidden (view full) ---

5393{
5394 const struct iwn_hal *hal = sc->sc_hal;
5395 uint32_t tmp;
5396 int chnl, qid, ntries;
5397
5398 IWN_WRITE(sc, IWN_RESET, IWN_RESET_NEVO);
5399
5400 /* Disable interrupts. */
5951
5952 /* _Really_ make sure "radio off" bit is cleared! */
5953 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
5954 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
5955
5956 error = hal->load_firmware(sc);
5957 if (error != 0) {
5958 device_printf(sc->sc_dev,

--- 18 unchanged lines hidden (view full) ---

5977{
5978 const struct iwn_hal *hal = sc->sc_hal;
5979 uint32_t tmp;
5980 int chnl, qid, ntries;
5981
5982 IWN_WRITE(sc, IWN_RESET, IWN_RESET_NEVO);
5983
5984 /* Disable interrupts. */
5401 IWN_WRITE(sc, IWN_MASK, 0);
5985 IWN_WRITE(sc, IWN_INT_MASK, 0);
5402 IWN_WRITE(sc, IWN_INT, 0xffffffff);
5403 IWN_WRITE(sc, IWN_FH_INT, 0xffffffff);
5986 IWN_WRITE(sc, IWN_INT, 0xffffffff);
5987 IWN_WRITE(sc, IWN_FH_INT, 0xffffffff);
5988 sc->sc_flags &= ~IWN_FLAG_USE_ICT;
5404
5405 /* Make sure we no longer hold the NIC lock. */
5406 iwn_nic_unlock(sc);
5407
5408 /* Stop TX scheduler. */
5409 iwn_prph_write(sc, hal->sched_txfact_addr, 0);
5410
5411 /* Stop all DMA channels. */

--- 14 unchanged lines hidden (view full) ---

5426 /* Stop RX ring. */
5427 iwn_reset_rx_ring(sc, &sc->rxq);
5428
5429 /* Reset all TX rings. */
5430 for (qid = 0; qid < hal->ntxqs; qid++)
5431 iwn_reset_tx_ring(sc, &sc->txq[qid]);
5432
5433 if (iwn_nic_lock(sc) == 0) {
5989
5990 /* Make sure we no longer hold the NIC lock. */
5991 iwn_nic_unlock(sc);
5992
5993 /* Stop TX scheduler. */
5994 iwn_prph_write(sc, hal->sched_txfact_addr, 0);
5995
5996 /* Stop all DMA channels. */

--- 14 unchanged lines hidden (view full) ---

6011 /* Stop RX ring. */
6012 iwn_reset_rx_ring(sc, &sc->rxq);
6013
6014 /* Reset all TX rings. */
6015 for (qid = 0; qid < hal->ntxqs; qid++)
6016 iwn_reset_tx_ring(sc, &sc->txq[qid]);
6017
6018 if (iwn_nic_lock(sc) == 0) {
5434 iwn_prph_write(sc, IWN_APMG_CLK_DIS, IWN_APMG_CLK_DMA_RQT);
6019 iwn_prph_write(sc, IWN_APMG_CLK_DIS,
6020 IWN_APMG_CLK_CTRL_DMA_CLK_RQT);
5435 iwn_nic_unlock(sc);
5436 }
5437 DELAY(5);
5438
5439 /* Power OFF adapter. */
5440 iwn_apm_stop(sc);
5441}
5442
5443void
5444iwn_init_locked(struct iwn_softc *sc)
5445{
5446 struct ifnet *ifp = sc->sc_ifp;
5447 int error;
5448
5449 IWN_LOCK_ASSERT(sc);
5450
6021 iwn_nic_unlock(sc);
6022 }
6023 DELAY(5);
6024
6025 /* Power OFF adapter. */
6026 iwn_apm_stop(sc);
6027}
6028
6029void
6030iwn_init_locked(struct iwn_softc *sc)
6031{
6032 struct ifnet *ifp = sc->sc_ifp;
6033 int error;
6034
6035 IWN_LOCK_ASSERT(sc);
6036
5451 iwn_stop_locked(sc);
5452
5453 error = iwn_hw_prepare(sc);
5454 if (error != 0) {
5455 device_printf(sc->sc_dev, "%s: hardware not ready, eror %d\n",
5456 __func__, error);
5457 goto fail;
5458 }
5459
6037 error = iwn_hw_prepare(sc);
6038 if (error != 0) {
6039 device_printf(sc->sc_dev, "%s: hardware not ready, eror %d\n",
6040 __func__, error);
6041 goto fail;
6042 }
6043
6044 /* Initialize interrupt mask to default value. */
6045 sc->int_mask = IWN_INT_MASK_DEF;
6046 sc->sc_flags &= ~IWN_FLAG_USE_ICT;
6047
5460 /* Check that the radio is not disabled by hardware switch. */
5461 if (!(IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)) {
5462 device_printf(sc->sc_dev,
6048 /* Check that the radio is not disabled by hardware switch. */
6049 if (!(IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)) {
6050 device_printf(sc->sc_dev,
5463 "%s: radio is disabled by hardware switch\n",
5464 __func__);
5465 error = EPERM; /* :-) */
5466 goto fail;
6051 "radio is disabled by hardware switch\n");
6052
6053 /* Enable interrupts to get RF toggle notifications. */
6054 IWN_WRITE(sc, IWN_INT, 0xffffffff);
6055 IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
6056 return;
5467 }
5468
5469 /* Read firmware images from the filesystem. */
5470 error = iwn_read_firmware(sc);
5471 if (error != 0) {
5472 device_printf(sc->sc_dev,
5473 "%s: could not read firmware, error %d\n",
5474 __func__, error);
5475 goto fail;
5476 }
5477
5478 /* Initialize hardware and upload firmware. */
5479 error = iwn_hw_init(sc);
6057 }
6058
6059 /* Read firmware images from the filesystem. */
6060 error = iwn_read_firmware(sc);
6061 if (error != 0) {
6062 device_printf(sc->sc_dev,
6063 "%s: could not read firmware, error %d\n",
6064 __func__, error);
6065 goto fail;
6066 }
6067
6068 /* Initialize hardware and upload firmware. */
6069 error = iwn_hw_init(sc);
6070 firmware_put(sc->fw_fp, FIRMWARE_UNLOAD);
6071 sc->fw_fp = NULL;
5480 if (error != 0) {
5481 device_printf(sc->sc_dev,
5482 "%s: could not initialize hardware, error %d\n",
5483 __func__, error);
5484 goto fail;
5485 }
5486
5487 /* Configure adapter now that it is ready. */

--- 31 unchanged lines hidden (view full) ---

5519
5520void
5521iwn_stop_locked(struct iwn_softc *sc)
5522{
5523 struct ifnet *ifp = sc->sc_ifp;
5524
5525 IWN_LOCK_ASSERT(sc);
5526
6072 if (error != 0) {
6073 device_printf(sc->sc_dev,
6074 "%s: could not initialize hardware, error %d\n",
6075 __func__, error);
6076 goto fail;
6077 }
6078
6079 /* Configure adapter now that it is ready. */

--- 31 unchanged lines hidden (view full) ---

6111
6112void
6113iwn_stop_locked(struct iwn_softc *sc)
6114{
6115 struct ifnet *ifp = sc->sc_ifp;
6116
6117 IWN_LOCK_ASSERT(sc);
6118
5527 IWN_WRITE(sc, IWN_RESET, IWN_RESET_NEVO);
5528
5529 sc->sc_tx_timer = 0;
5530 callout_stop(&sc->sc_timer_to);
5531 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
5532
5533 /* Power OFF hardware. */
5534 iwn_hw_stop(sc);
5535}
5536
6119 sc->sc_tx_timer = 0;
6120 callout_stop(&sc->sc_timer_to);
6121 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
6122
6123 /* Power OFF hardware. */
6124 iwn_hw_stop(sc);
6125}
6126
5537
5538void
5539iwn_stop(struct iwn_softc *sc)
5540{
5541 IWN_LOCK(sc);
5542 iwn_stop_locked(sc);
5543 IWN_UNLOCK(sc);
5544}
5545

--- 13 unchanged lines hidden (view full) ---

5559}
5560
5561/*
5562 * Callback from net80211 to terminate a scan.
5563 */
5564static void
5565iwn_scan_end(struct ieee80211com *ic)
5566{
6127void
6128iwn_stop(struct iwn_softc *sc)
6129{
6130 IWN_LOCK(sc);
6131 iwn_stop_locked(sc);
6132 IWN_UNLOCK(sc);
6133}
6134

--- 13 unchanged lines hidden (view full) ---

6148}
6149
6150/*
6151 * Callback from net80211 to terminate a scan.
6152 */
6153static void
6154iwn_scan_end(struct ieee80211com *ic)
6155{
5567 /* ignore */
6156 struct ifnet *ifp = ic->ic_ifp;
6157 struct iwn_softc *sc = ifp->if_softc;
6158 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
6159
6160 IWN_LOCK(sc);
6161 if (vap->iv_state == IEEE80211_S_RUN) {
6162 /* Set link LED to ON status if we are associated */
6163 iwn_set_led(sc, IWN_LED_LINK, 0, 1);
6164 }
6165 IWN_UNLOCK(sc);
5568}
5569
5570/*
5571 * Callback from net80211 to force a channel change.
5572 */
5573static void
5574iwn_set_channel(struct ieee80211com *ic)
5575{
5576 const struct ieee80211_channel *c = ic->ic_curchan;
5577 struct ifnet *ifp = ic->ic_ifp;
5578 struct iwn_softc *sc = ifp->if_softc;
6166}
6167
6168/*
6169 * Callback from net80211 to force a channel change.
6170 */
6171static void
6172iwn_set_channel(struct ieee80211com *ic)
6173{
6174 const struct ieee80211_channel *c = ic->ic_curchan;
6175 struct ifnet *ifp = ic->ic_ifp;
6176 struct iwn_softc *sc = ifp->if_softc;
5579 struct ieee80211vap *vap;
5580 int error;
5581
6177
5582 vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */
5583
5584 IWN_LOCK(sc);
6178 IWN_LOCK(sc);
5585 if (c != sc->sc_curchan) {
5586 sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq);
5587 sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags);
5588 sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq);
5589 sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags);
5590
5591 error = iwn_config(sc);
5592 if (error != 0) {
5593 DPRINTF(sc, IWN_DEBUG_STATE,
5594 "%s: set chan failed, cancel scan\n",
5595 __func__);
5596 //XXX Handle failed scan correctly
5597 ieee80211_cancel_scan(vap);
5598 }
5599 }
6179 sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq);
6180 sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags);
6181 sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq);
6182 sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags);
5600 IWN_UNLOCK(sc);
5601}
5602
5603/*
5604 * Callback from net80211 to start scanning of the current channel.
5605 */
5606static void
5607iwn_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)

--- 15 unchanged lines hidden (view full) ---

5623 * notify us when it's finished as we have no safe way to abort it.
5624 */
5625static void
5626iwn_scan_mindwell(struct ieee80211_scan_state *ss)
5627{
5628 /* NB: don't try to abort scan; wait for firmware to finish */
5629}
5630
6183 IWN_UNLOCK(sc);
6184}
6185
6186/*
6187 * Callback from net80211 to start scanning of the current channel.
6188 */
6189static void
6190iwn_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)

--- 15 unchanged lines hidden (view full) ---

6206 * notify us when it's finished as we have no safe way to abort it.
6207 */
6208static void
6209iwn_scan_mindwell(struct ieee80211_scan_state *ss)
6210{
6211 /* NB: don't try to abort scan; wait for firmware to finish */
6212}
6213
6214static struct iwn_eeprom_chan *
6215iwn_find_eeprom_channel(struct iwn_softc *sc, struct ieee80211_channel *c)
6216{
6217 int i, j;
6218
6219 for (j = 0; j < 7; j++) {
6220 for (i = 0; i < iwn_bands[j].nchan; i++) {
6221 if (iwn_bands[j].chan[i] == c->ic_ieee)
6222 return &sc->eeprom_channels[j][i];
6223 }
6224 }
6225
6226 return NULL;
6227}
6228
6229/*
6230 * Enforce flags read from EEPROM.
6231 */
6232static int
6233iwn_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
6234 int nchan, struct ieee80211_channel chans[])
6235{
6236 struct iwn_softc *sc = ic->ic_ifp->if_softc;
6237 int i;
6238
6239 for (i = 0; i < nchan; i++) {
6240 struct ieee80211_channel *c = &chans[i];
6241 struct iwn_eeprom_chan *channel;
6242
6243 channel = iwn_find_eeprom_channel(sc, c);
6244 if (channel == NULL) {
6245 if_printf(ic->ic_ifp,
6246 "%s: invalid channel %u freq %u/0x%x\n",
6247 __func__, c->ic_ieee, c->ic_freq, c->ic_flags);
6248 return EINVAL;
6249 }
6250 c->ic_flags |= iwn_eeprom_channel_flags(channel);
6251 }
6252
6253 return 0;
6254}
6255
5631static void
5632iwn_hw_reset(void *arg0, int pending)
5633{
5634 struct iwn_softc *sc = arg0;
5635 struct ifnet *ifp = sc->sc_ifp;
5636 struct ieee80211com *ic = ifp->if_l2com;
5637
6256static void
6257iwn_hw_reset(void *arg0, int pending)
6258{
6259 struct iwn_softc *sc = arg0;
6260 struct ifnet *ifp = sc->sc_ifp;
6261 struct ieee80211com *ic = ifp->if_l2com;
6262
6263 iwn_stop(sc);
5638 iwn_init(sc);
5639 ieee80211_notify_radio(ic, 1);
5640}
5641
5642static void
5643iwn_radio_on(void *arg0, int pending)
5644{
5645 struct iwn_softc *sc = arg0;
6264 iwn_init(sc);
6265 ieee80211_notify_radio(ic, 1);
6266}
6267
6268static void
6269iwn_radio_on(void *arg0, int pending)
6270{
6271 struct iwn_softc *sc = arg0;
6272 struct ifnet *ifp = sc->sc_ifp;
6273 struct ieee80211com *ic = ifp->if_l2com;
6274 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
5646
6275
5647 iwn_init(sc);
6276 if (vap != NULL) {
6277 iwn_init(sc);
6278 ieee80211_init(vap);
6279 }
5648}
5649
5650static void
5651iwn_radio_off(void *arg0, int pending)
5652{
5653 struct iwn_softc *sc = arg0;
5654 struct ifnet *ifp = sc->sc_ifp;
5655 struct ieee80211com *ic = ifp->if_l2com;
6280}
6281
6282static void
6283iwn_radio_off(void *arg0, int pending)
6284{
6285 struct iwn_softc *sc = arg0;
6286 struct ifnet *ifp = sc->sc_ifp;
6287 struct ieee80211com *ic = ifp->if_l2com;
6288 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
5656
6289
6290 iwn_stop(sc);
6291 if (vap != NULL)
6292 ieee80211_stop(vap);
6293
6294 /* Enable interrupts to get RF toggle notification. */
5657 IWN_LOCK(sc);
6295 IWN_LOCK(sc);
5658 ieee80211_notify_radio(ic, 0);
5659 iwn_stop_locked(sc);
6296 IWN_WRITE(sc, IWN_INT, 0xffffffff);
6297 IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
5660 IWN_UNLOCK(sc);
5661}
5662
5663static void
5664iwn_sysctlattach(struct iwn_softc *sc)
5665{
5666 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
5667 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);

--- 13 unchanged lines hidden (view full) ---

5681 iwn_stop(sc);
5682 return 0;
5683}
5684
5685static int
5686iwn_suspend(device_t dev)
5687{
5688 struct iwn_softc *sc = device_get_softc(dev);
6298 IWN_UNLOCK(sc);
6299}
6300
6301static void
6302iwn_sysctlattach(struct iwn_softc *sc)
6303{
6304 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
6305 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);

--- 13 unchanged lines hidden (view full) ---

6319 iwn_stop(sc);
6320 return 0;
6321}
6322
6323static int
6324iwn_suspend(device_t dev)
6325{
6326 struct iwn_softc *sc = device_get_softc(dev);
6327 struct ifnet *ifp = sc->sc_ifp;
6328 struct ieee80211com *ic = ifp->if_l2com;
6329 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
5689
5690 iwn_stop(sc);
6330
6331 iwn_stop(sc);
6332 if (vap != NULL)
6333 ieee80211_stop(vap);
5691 return 0;
5692}
5693
5694static int
5695iwn_resume(device_t dev)
5696{
5697 struct iwn_softc *sc = device_get_softc(dev);
5698 struct ifnet *ifp = sc->sc_ifp;
6334 return 0;
6335}
6336
6337static int
6338iwn_resume(device_t dev)
6339{
6340 struct iwn_softc *sc = device_get_softc(dev);
6341 struct ifnet *ifp = sc->sc_ifp;
6342 struct ieee80211com *ic = ifp->if_l2com;
6343 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
5699
6344
6345 /* Clear device-specific "PCI retry timeout" register (41h). */
5700 pci_write_config(dev, 0x41, 0, 1);
5701
6346 pci_write_config(dev, 0x41, 0, 1);
6347
5702 if (ifp->if_flags & IFF_UP)
6348 if (ifp->if_flags & IFF_UP) {
5703 iwn_init(sc);
6349 iwn_init(sc);
6350 if (vap != NULL)
6351 ieee80211_init(vap);
6352 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
6353 iwn_start(ifp);
6354 }
5704 return 0;
5705}
5706
5707#ifdef IWN_DEBUG
5708static const char *
5709iwn_intr_str(uint8_t cmd)
5710{
5711 switch (cmd) {

--- 7 unchanged lines hidden (view full) ---

5719 case IWN_BEACON_STATISTICS: return "BEACON_STATS";
5720 case IWN_STATE_CHANGED: return "STATE_CHANGED";
5721 case IWN_BEACON_MISSED: return "BEACON_MISSED";
5722 case IWN_RX_PHY: return "RX_PHY";
5723 case IWN_MPDU_RX_DONE: return "MPDU_RX_DONE";
5724 case IWN_RX_DONE: return "RX_DONE";
5725
5726 /* Command Notifications */
6355 return 0;
6356}
6357
6358#ifdef IWN_DEBUG
6359static const char *
6360iwn_intr_str(uint8_t cmd)
6361{
6362 switch (cmd) {

--- 7 unchanged lines hidden (view full) ---

6370 case IWN_BEACON_STATISTICS: return "BEACON_STATS";
6371 case IWN_STATE_CHANGED: return "STATE_CHANGED";
6372 case IWN_BEACON_MISSED: return "BEACON_MISSED";
6373 case IWN_RX_PHY: return "RX_PHY";
6374 case IWN_MPDU_RX_DONE: return "MPDU_RX_DONE";
6375 case IWN_RX_DONE: return "RX_DONE";
6376
6377 /* Command Notifications */
5727 case IWN_CMD_CONFIGURE: return "IWN_CMD_CONFIGURE";
5728 case IWN_CMD_ASSOCIATE: return "IWN_CMD_ASSOCIATE";
6378 case IWN_CMD_RXON: return "IWN_CMD_RXON";
6379 case IWN_CMD_RXON_ASSOC: return "IWN_CMD_RXON_ASSOC";
5729 case IWN_CMD_EDCA_PARAMS: return "IWN_CMD_EDCA_PARAMS";
5730 case IWN_CMD_TIMING: return "IWN_CMD_TIMING";
5731 case IWN_CMD_LINK_QUALITY: return "IWN_CMD_LINK_QUALITY";
5732 case IWN_CMD_SET_LED: return "IWN_CMD_SET_LED";
5733 case IWN5000_CMD_WIMAX_COEX: return "IWN5000_CMD_WIMAX_COEX";
5734 case IWN5000_CMD_CALIB_CONFIG: return "IWN5000_CMD_CALIB_CONFIG";
5735 case IWN_CMD_SET_POWER_MODE: return "IWN_CMD_SET_POWER_MODE";
5736 case IWN_CMD_SCAN: return "IWN_CMD_SCAN";

--- 34 unchanged lines hidden ---
6380 case IWN_CMD_EDCA_PARAMS: return "IWN_CMD_EDCA_PARAMS";
6381 case IWN_CMD_TIMING: return "IWN_CMD_TIMING";
6382 case IWN_CMD_LINK_QUALITY: return "IWN_CMD_LINK_QUALITY";
6383 case IWN_CMD_SET_LED: return "IWN_CMD_SET_LED";
6384 case IWN5000_CMD_WIMAX_COEX: return "IWN5000_CMD_WIMAX_COEX";
6385 case IWN5000_CMD_CALIB_CONFIG: return "IWN5000_CMD_CALIB_CONFIG";
6386 case IWN_CMD_SET_POWER_MODE: return "IWN_CMD_SET_POWER_MODE";
6387 case IWN_CMD_SCAN: return "IWN_CMD_SCAN";

--- 34 unchanged lines hidden ---