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 --- |