Ticket #10729: iwn.patch
File iwn.patch, 200.6 KB (added by , 10 years ago) |
---|
-
src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c
diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c index 72cf415..65df8d3 100644
a b __FBSDID("$FreeBSD$"); 72 72 #include <dev/iwn/if_iwnreg.h> 73 73 #include <dev/iwn/if_iwnvar.h> 74 74 75 struct iwn_ident { 76 uint16_t vendor; 77 uint16_t device; 78 const char *name; 79 }; 80 81 static const struct iwn_ident iwn_ident_table[] = { 82 { 0x8086, 0x0082, "Intel Centrino Advanced-N 6205" }, 83 { 0x8086, 0x0083, "Intel Centrino Wireless-N 1000" }, 84 { 0x8086, 0x0084, "Intel Centrino Wireless-N 1000" }, 85 { 0x8086, 0x0085, "Intel Centrino Advanced-N 6205" }, 86 { 0x8086, 0x0087, "Intel Centrino Advanced-N + WiMAX 6250" }, 87 { 0x8086, 0x0089, "Intel Centrino Advanced-N + WiMAX 6250" }, 88 { 0x8086, 0x008a, "Intel Centrino Wireless-N 1030" }, 89 { 0x8086, 0x008b, "Intel Centrino Wireless-N 1030" }, 90 { 0x8086, 0x0090, "Intel Centrino Advanced-N 6230" }, 91 { 0x8086, 0x0091, "Intel Centrino Advanced-N 6230" }, 92 { 0x8086, 0x0885, "Intel Centrino Wireless-N + WiMAX 6150" }, 93 { 0x8086, 0x0886, "Intel Centrino Wireless-N + WiMAX 6150" }, 94 { 0x8086, 0x0896, "Intel Centrino Wireless-N 130" }, 95 { 0x8086, 0x0887, "Intel Centrino Wireless-N 130" }, 96 { 0x8086, 0x08ae, "Intel Centrino Wireless-N 100" }, 97 { 0x8086, 0x08af, "Intel Centrino Wireless-N 100" }, 98 { 0x8086, 0x4229, "Intel Wireless WiFi Link 4965" }, 99 { 0x8086, 0x422b, "Intel Centrino Ultimate-N 6300" }, 100 { 0x8086, 0x422c, "Intel Centrino Advanced-N 6200" }, 101 { 0x8086, 0x422d, "Intel Wireless WiFi Link 4965" }, 102 { 0x8086, 0x4230, "Intel Wireless WiFi Link 4965" }, 103 { 0x8086, 0x4232, "Intel WiFi Link 5100" }, 104 { 0x8086, 0x4233, "Intel Wireless WiFi Link 4965" }, 105 { 0x8086, 0x4235, "Intel Ultimate N WiFi Link 5300" }, 106 { 0x8086, 0x4236, "Intel Ultimate N WiFi Link 5300" }, 107 { 0x8086, 0x4237, "Intel WiFi Link 5100" }, 108 { 0x8086, 0x4238, "Intel Centrino Ultimate-N 6300" }, 109 { 0x8086, 0x4239, "Intel Centrino Advanced-N 6200" }, 110 { 0x8086, 0x423a, "Intel WiMAX/WiFi Link 5350" }, 111 { 0x8086, 0x423b, "Intel WiMAX/WiFi Link 5350" }, 112 { 0x8086, 0x423c, "Intel WiMAX/WiFi Link 5150" }, 113 { 0x8086, 0x423d, "Intel WiMAX/WiFi Link 5150" }, 114 { 0, 0, NULL } 115 }; 116 75 117 static int iwn_probe(device_t); 76 118 static int iwn_attach(device_t); 77 static const struct iwn_hal *iwn_hal_attach(struct iwn_softc *); 119 static int iwn4965_attach(struct iwn_softc *, uint16_t); 120 static int iwn5000_attach(struct iwn_softc *, uint16_t); 78 121 static void iwn_radiotap_attach(struct iwn_softc *); 122 static void iwn_sysctlattach(struct iwn_softc *); 79 123 static struct ieee80211vap *iwn_vap_create(struct ieee80211com *, 80 const char name[IFNAMSIZ], int unit, intopmode,124 const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode, 81 125 int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], 82 126 const uint8_t mac[IEEE80211_ADDR_LEN]); 83 127 static void iwn_vap_delete(struct ieee80211vap *); 84 static int iwn_cleanup(device_t);85 128 static int iwn_detach(device_t); 129 static int iwn_shutdown(device_t); 130 static int iwn_suspend(device_t); 131 static int iwn_resume(device_t); 86 132 static int iwn_nic_lock(struct iwn_softc *); 87 133 static int iwn_eeprom_lock(struct iwn_softc *); 88 134 static int iwn_init_otprom(struct iwn_softc *); 89 135 static int iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int); 90 136 static void iwn_dma_map_addr(void *, bus_dma_segment_t *, int, int); 91 137 static int iwn_dma_contig_alloc(struct iwn_softc *, struct iwn_dma_info *, 92 void **, bus_size_t, bus_size_t , int);138 void **, bus_size_t, bus_size_t); 93 139 static void iwn_dma_contig_free(struct iwn_dma_info *); 94 140 static int iwn_alloc_sched(struct iwn_softc *); 95 141 static void iwn_free_sched(struct iwn_softc *); … … static void iwn_read_eeprom_band(struct iwn_softc *, int); 117 163 #if 0 /* HT */ 118 164 static void iwn_read_eeprom_ht40(struct iwn_softc *, int); 119 165 #endif 120 static void iwn_read_eeprom_channels(struct iwn_softc *, int, 121 uint32_t); 166 static void iwn_read_eeprom_channels(struct iwn_softc *, int, uint32_t); 167 static struct iwn_eeprom_chan *iwn_find_eeprom_channel(struct iwn_softc *, 168 struct ieee80211_channel *); 169 static int iwn_setregdomain(struct ieee80211com *, 170 struct ieee80211_regdomain *, int, 171 struct ieee80211_channel[]); 122 172 static void iwn_read_eeprom_enhinfo(struct iwn_softc *); 123 173 static struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *, 124 174 const uint8_t mac[IEEE80211_ADDR_LEN]); 175 static void iwn_newassoc(struct ieee80211_node *, int); 125 176 static int iwn_media_change(struct ifnet *); 126 177 static int iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); 178 static void iwn_calib_timeout(void *); 127 179 static void iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *, 128 180 struct iwn_rx_data *); 129 static void iwn_timer_timeout(void *);130 static void iwn_calib_reset(struct iwn_softc *);131 181 static void iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *, 132 182 struct iwn_rx_data *); 133 183 #if 0 /* HT */ 134 184 static void iwn_rx_compressed_ba(struct iwn_softc *, struct iwn_rx_desc *, 135 185 struct iwn_rx_data *); 136 186 #endif 187 static void iwn5000_rx_calib_results(struct iwn_softc *, 188 struct iwn_rx_desc *, struct iwn_rx_data *); 137 189 static void iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *, 138 190 struct iwn_rx_data *); 139 191 static void iwn4965_tx_done(struct iwn_softc *, struct iwn_rx_desc *, … … static void iwn5000_reset_sched(struct iwn_softc *, int, int); 157 209 #endif 158 210 static uint8_t iwn_plcp_signal(int); 159 211 static int iwn_tx_data(struct iwn_softc *, struct mbuf *, 160 struct ieee80211_node *, struct iwn_tx_ring *); 212 struct ieee80211_node *); 213 static int iwn_tx_data_raw(struct iwn_softc *, struct mbuf *, 214 struct ieee80211_node *, 215 const struct ieee80211_bpf_params *params); 161 216 static int iwn_raw_xmit(struct ieee80211_node *, struct mbuf *, 162 217 const struct ieee80211_bpf_params *); 163 218 static void iwn_start(struct ifnet *); 164 219 static void iwn_start_locked(struct ifnet *); 165 static void iwn_watchdog( struct iwn_softc *sc);220 static void iwn_watchdog(void *); 166 221 static int iwn_ioctl(struct ifnet *, u_long, caddr_t); 167 222 static int iwn_cmd(struct iwn_softc *, int, const void *, int, int); 168 223 static int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *, 169 224 int); 170 225 static int iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *, 171 226 int); 172 static int iwn_set_link_quality(struct iwn_softc *, uint8_t, int); 227 static int iwn_set_link_quality(struct iwn_softc *, 228 struct ieee80211_node *); 173 229 static int iwn_add_broadcast_node(struct iwn_softc *, int); 174 static int iwn_ wme_update(struct ieee80211com *);230 static int iwn_updateedca(struct ieee80211com *); 175 231 static void iwn_update_mcast(struct ifnet *); 176 232 static void iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t); 177 233 static int iwn_set_critical_temp(struct iwn_softc *); … … static void iwn_tune_sensitivity(struct iwn_softc *, 197 253 const struct iwn_rx_stats *); 198 254 static int iwn_send_sensitivity(struct iwn_softc *); 199 255 static int iwn_set_pslevel(struct iwn_softc *, int, int, int); 256 static int iwn_send_btcoex(struct iwn_softc *); 257 static int iwn_send_advanced_btcoex(struct iwn_softc *); 200 258 static int iwn_config(struct iwn_softc *); 259 static uint8_t *ieee80211_add_ssid(uint8_t *, const uint8_t *, u_int); 201 260 static int iwn_scan(struct iwn_softc *); 202 261 static int iwn_auth(struct iwn_softc *, struct ieee80211vap *vap); 203 262 static int iwn_run(struct iwn_softc *, struct ieee80211vap *vap); … … static void iwn_ampdu_tx_stop(struct ieee80211com *, 212 271 struct ieee80211_node *, uint8_t); 213 272 static void iwn4965_ampdu_tx_start(struct iwn_softc *, 214 273 struct ieee80211_node *, uint8_t, uint16_t); 215 static void iwn4965_ampdu_tx_stop(struct iwn_softc *, uint8_t, uint16_t); 274 static void iwn4965_ampdu_tx_stop(struct iwn_softc *, 275 uint8_t, uint16_t); 216 276 static void iwn5000_ampdu_tx_start(struct iwn_softc *, 217 277 struct ieee80211_node *, uint8_t, uint16_t); 218 static void iwn5000_ampdu_tx_stop(struct iwn_softc *, uint8_t, uint16_t); 278 static void iwn5000_ampdu_tx_stop(struct iwn_softc *, 279 uint8_t, uint16_t); 219 280 #endif 220 static int iwn5000_send_calib_results(struct iwn_softc *); 221 static int iwn5000_save_calib_result(struct iwn_softc *, 222 struct iwn_phy_calib *, int, int); 223 static void iwn5000_free_calib_results(struct iwn_softc *); 224 static int iwn5000_chrystal_calib(struct iwn_softc *); 225 static int iwn5000_send_calib_query(struct iwn_softc *, uint32_t); 226 static int iwn5000_rx_calib_result(struct iwn_softc *, 227 struct iwn_rx_desc *, struct iwn_rx_data *); 281 static int iwn5000_query_calibration(struct iwn_softc *); 282 static int iwn5000_send_calibration(struct iwn_softc *); 228 283 static int iwn5000_send_wimax_coex(struct iwn_softc *); 284 static int iwn5000_crystal_calib(struct iwn_softc *); 285 static int iwn5000_temp_offset_calib(struct iwn_softc *); 229 286 static int iwn4965_post_alive(struct iwn_softc *); 230 287 static int iwn5000_post_alive(struct iwn_softc *); 231 288 static int iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *, … … static int iwn5000_nic_config(struct iwn_softc *); 248 305 static int iwn_hw_prepare(struct iwn_softc *); 249 306 static int iwn_hw_init(struct iwn_softc *); 250 307 static void iwn_hw_stop(struct iwn_softc *); 308 static void iwn_radio_on(void *, int); 309 static void iwn_radio_off(void *, int); 251 310 static void iwn_init_locked(struct iwn_softc *); 252 311 static void iwn_init(void *); 253 312 static void iwn_stop_locked(struct iwn_softc *); 254 313 static void iwn_stop(struct iwn_softc *); 255 static void iwn_scan_start(struct ieee80211com *); 256 static void iwn_scan_end(struct ieee80211com *); 257 static void iwn_set_channel(struct ieee80211com *); 258 static void iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long); 259 static void iwn_scan_mindwell(struct ieee80211_scan_state *); 260 static struct iwn_eeprom_chan *iwn_find_eeprom_channel(struct iwn_softc *, 261 struct ieee80211_channel *); 262 static int iwn_setregdomain(struct ieee80211com *, 263 struct ieee80211_regdomain *, int, 264 struct ieee80211_channel []); 314 static void iwn_scan_start(struct ieee80211com *); 315 static void iwn_scan_end(struct ieee80211com *); 316 static void iwn_set_channel(struct ieee80211com *); 317 static void iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long); 318 static void iwn_scan_mindwell(struct ieee80211_scan_state *); 265 319 static void iwn_hw_reset(void *, int); 266 static void iwn_radio_on(void *, int);267 static void iwn_radio_off(void *, int);268 static void iwn_sysctlattach(struct iwn_softc *);269 static int iwn_shutdown(device_t);270 static int iwn_suspend(device_t);271 static int iwn_resume(device_t);272 320 273 321 #define IWN_DEBUG 274 322 #ifdef IWN_DEBUG … … enum { 295 343 printf(fmt, __VA_ARGS__); \ 296 344 } while (0) 297 345 298 static const char *iwn_intr_str(uint8_t); 346 static const char * 347 iwn_intr_str(uint8_t cmd) 348 { 349 switch (cmd) { 350 /* Notifications */ 351 case IWN_UC_READY: return "UC_READY"; 352 case IWN_ADD_NODE_DONE: return "ADD_NODE_DONE"; 353 case IWN_TX_DONE: return "TX_DONE"; 354 case IWN_START_SCAN: return "START_SCAN"; 355 case IWN_STOP_SCAN: return "STOP_SCAN"; 356 case IWN_RX_STATISTICS: return "RX_STATS"; 357 case IWN_BEACON_STATISTICS: return "BEACON_STATS"; 358 case IWN_STATE_CHANGED: return "STATE_CHANGED"; 359 case IWN_BEACON_MISSED: return "BEACON_MISSED"; 360 case IWN_RX_PHY: return "RX_PHY"; 361 case IWN_MPDU_RX_DONE: return "MPDU_RX_DONE"; 362 case IWN_RX_DONE: return "RX_DONE"; 363 364 /* Command Notifications */ 365 case IWN_CMD_RXON: return "IWN_CMD_RXON"; 366 case IWN_CMD_RXON_ASSOC: return "IWN_CMD_RXON_ASSOC"; 367 case IWN_CMD_EDCA_PARAMS: return "IWN_CMD_EDCA_PARAMS"; 368 case IWN_CMD_TIMING: return "IWN_CMD_TIMING"; 369 case IWN_CMD_LINK_QUALITY: return "IWN_CMD_LINK_QUALITY"; 370 case IWN_CMD_SET_LED: return "IWN_CMD_SET_LED"; 371 case IWN5000_CMD_WIMAX_COEX: return "IWN5000_CMD_WIMAX_COEX"; 372 case IWN5000_CMD_CALIB_CONFIG: return "IWN5000_CMD_CALIB_CONFIG"; 373 case IWN5000_CMD_CALIB_RESULT: return "IWN5000_CMD_CALIB_RESULT"; 374 case IWN5000_CMD_CALIB_COMPLETE: return "IWN5000_CMD_CALIB_COMPLETE"; 375 case IWN_CMD_SET_POWER_MODE: return "IWN_CMD_SET_POWER_MODE"; 376 case IWN_CMD_SCAN: return "IWN_CMD_SCAN"; 377 case IWN_CMD_SCAN_RESULTS: return "IWN_CMD_SCAN_RESULTS"; 378 case IWN_CMD_TXPOWER: return "IWN_CMD_TXPOWER"; 379 case IWN_CMD_TXPOWER_DBM: return "IWN_CMD_TXPOWER_DBM"; 380 case IWN5000_CMD_TX_ANT_CONFIG: return "IWN5000_CMD_TX_ANT_CONFIG"; 381 case IWN_CMD_BT_COEX: return "IWN_CMD_BT_COEX"; 382 case IWN_CMD_SET_CRITICAL_TEMP: return "IWN_CMD_SET_CRITICAL_TEMP"; 383 case IWN_CMD_SET_SENSITIVITY: return "IWN_CMD_SET_SENSITIVITY"; 384 case IWN_CMD_PHY_CALIB: return "IWN_CMD_PHY_CALIB"; 385 } 386 return "UNKNOWN INTR NOTIF/CMD"; 387 } 299 388 #else 300 389 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0) 301 390 #endif 302 391 303 struct iwn_ident { 304 uint16_t vendor; 305 uint16_t device; 306 const char *name; 392 static device_method_t iwn_methods[] = { 393 /* Device interface */ 394 DEVMETHOD(device_probe, iwn_probe), 395 DEVMETHOD(device_attach, iwn_attach), 396 DEVMETHOD(device_detach, iwn_detach), 397 DEVMETHOD(device_shutdown, iwn_shutdown), 398 DEVMETHOD(device_suspend, iwn_suspend), 399 DEVMETHOD(device_resume, iwn_resume), 400 { 0, 0 } 307 401 }; 308 402 309 static const struct iwn_ident iwn_ident_table [] = { 310 { 0x8086, 0x4229, "Intel(R) PRO/Wireless 4965BGN" }, 311 { 0x8086, 0x422D, "Intel(R) PRO/Wireless 4965BGN" }, 312 { 0x8086, 0x4230, "Intel(R) PRO/Wireless 4965BGN" }, 313 { 0x8086, 0x4233, "Intel(R) PRO/Wireless 4965BGN" }, 314 { 0x8086, 0x4232, "Intel(R) PRO/Wireless 5100" }, 315 { 0x8086, 0x4237, "Intel(R) PRO/Wireless 5100" }, 316 { 0x8086, 0x423C, "Intel(R) PRO/Wireless 5150" }, 317 { 0x8086, 0x423D, "Intel(R) PRO/Wireless 5150" }, 318 { 0x8086, 0x4235, "Intel(R) PRO/Wireless 5300" }, 319 { 0x8086, 0x4236, "Intel(R) PRO/Wireless 5300" }, 320 { 0x8086, 0x423A, "Intel(R) PRO/Wireless 5350" }, 321 { 0x8086, 0x423B, "Intel(R) PRO/Wireless 5350" }, 322 { 0x8086, 0x0083, "Intel(R) PRO/Wireless 1000" }, 323 { 0x8086, 0x0084, "Intel(R) PRO/Wireless 1000" }, 324 { 0x8086, 0x008D, "Intel(R) PRO/Wireless 6000" }, 325 { 0x8086, 0x008E, "Intel(R) PRO/Wireless 6000" }, 326 { 0x8086, 0x4238, "Intel(R) PRO/Wireless 6000" }, 327 { 0x8086, 0x4239, "Intel(R) PRO/Wireless 6000" }, 328 { 0x8086, 0x422B, "Intel(R) PRO/Wireless 6000" }, 329 { 0x8086, 0x422C, "Intel(R) PRO/Wireless 6000" }, 330 { 0x8086, 0x0087, "Intel(R) PRO/Wireless 6250" }, 331 { 0x8086, 0x0089, "Intel(R) PRO/Wireless 6250" }, 332 { 0x8086, 0x0082, "Intel(R) PRO/Wireless 6205a" }, 333 { 0x8086, 0x0085, "Intel(R) PRO/Wireless 6205a" }, 334 #ifdef notyet 335 { 0x8086, 0x008a, "Intel(R) PRO/Wireless 6205b" }, 336 { 0x8086, 0x008b, "Intel(R) PRO/Wireless 6205b" }, 337 { 0x8086, 0x008f, "Intel(R) PRO/Wireless 6205b" }, 338 { 0x8086, 0x0090, "Intel(R) PRO/Wireless 6205b" }, 339 { 0x8086, 0x0091, "Intel(R) PRO/Wireless 6205b" }, 340 #endif 341 { 0, 0, NULL } 403 static driver_t iwn_driver = { 404 "iwn", 405 iwn_methods, 406 sizeof(struct iwn_softc) 342 407 }; 408 static devclass_t iwn_devclass; 343 409 344 static const struct iwn_hal iwn4965_hal = { 345 iwn4965_load_firmware, 346 iwn4965_read_eeprom, 347 iwn4965_post_alive, 348 iwn4965_nic_config, 349 iwn4965_update_sched, 350 iwn4965_get_temperature, 351 iwn4965_get_rssi, 352 iwn4965_set_txpower, 353 iwn4965_init_gains, 354 iwn4965_set_gains, 355 iwn4965_add_node, 356 iwn4965_tx_done, 357 #if 0 /* HT */ 358 iwn4965_ampdu_tx_start, 359 iwn4965_ampdu_tx_stop, 360 #endif 361 IWN4965_NTXQUEUES, 362 IWN4965_NDMACHNLS, 363 IWN4965_ID_BROADCAST, 364 IWN4965_RXONSZ, 365 IWN4965_SCHEDSZ, 366 IWN4965_FW_TEXT_MAXSZ, 367 IWN4965_FW_DATA_MAXSZ, 368 IWN4965_FWSZ, 369 IWN4965_SCHED_TXFACT 370 }; 410 DRIVER_MODULE(iwn, pci, iwn_driver, iwn_devclass, 0, 0); 371 411 372 static const struct iwn_hal iwn5000_hal = { 373 iwn5000_load_firmware, 374 iwn5000_read_eeprom, 375 iwn5000_post_alive, 376 iwn5000_nic_config, 377 iwn5000_update_sched, 378 iwn5000_get_temperature, 379 iwn5000_get_rssi, 380 iwn5000_set_txpower, 381 iwn5000_init_gains, 382 iwn5000_set_gains, 383 iwn5000_add_node, 384 iwn5000_tx_done, 385 #if 0 /* HT */ 386 iwn5000_ampdu_tx_start, 387 iwn5000_ampdu_tx_stop, 388 #endif 389 IWN5000_NTXQUEUES, 390 IWN5000_NDMACHNLS, 391 IWN5000_ID_BROADCAST, 392 IWN5000_RXONSZ, 393 IWN5000_SCHEDSZ, 394 IWN5000_FW_TEXT_MAXSZ, 395 IWN5000_FW_DATA_MAXSZ, 396 IWN5000_FWSZ, 397 IWN5000_SCHED_TXFACT 398 }; 412 MODULE_DEPEND(iwn, firmware, 1, 1, 1); 413 MODULE_DEPEND(iwn, pci, 1, 1, 1); 414 MODULE_DEPEND(iwn, wlan, 1, 1, 1); 399 415 400 416 static int 401 417 iwn_probe(device_t dev) … … iwn_attach(device_t dev) 418 434 struct iwn_softc *sc = (struct iwn_softc *)device_get_softc(dev); 419 435 struct ieee80211com *ic; 420 436 struct ifnet *ifp; 421 const struct iwn_hal *hal; 422 uint32_t tmp; 437 uint32_t reg; 423 438 int i, error, result; 424 439 uint8_t macaddr[IEEE80211_ADDR_LEN]; 425 440 … … iwn_attach(device_t dev) 439 454 pci_write_config(dev, 0x41, 0, 1); 440 455 441 456 /* Hardware bug workaround. */ 442 tmp= pci_read_config(dev, PCIR_COMMAND, 1);443 if ( tmp& PCIM_CMD_INTxDIS) {457 reg = pci_read_config(dev, PCIR_COMMAND, 1); 458 if (reg & PCIM_CMD_INTxDIS) { 444 459 DPRINTF(sc, IWN_DEBUG_RESET, "%s: PCIe INTx Disable set\n", 445 460 __func__); 446 tmp&= ~PCIM_CMD_INTxDIS;447 pci_write_config(dev, PCIR_COMMAND, tmp, 1);461 reg &= ~PCIM_CMD_INTxDIS; 462 pci_write_config(dev, PCIR_COMMAND, reg, 1); 448 463 } 449 464 450 465 /* Enable bus-mastering. */ … … iwn_attach(device_t dev) 453 468 sc->mem_rid = PCIR_BAR(0); 454 469 sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, 455 470 RF_ACTIVE); 456 if (sc->mem == NULL 457 device_printf(dev, "c ould not allocate memory resources\n");471 if (sc->mem == NULL) { 472 device_printf(dev, "can't map mem space\n"); 458 473 error = ENOMEM; 459 474 return error; 460 475 } 461 462 476 sc->sc_st = rman_get_bustag(sc->mem); 463 477 sc->sc_sh = rman_get_bushandle(sc->mem); 478 464 479 sc->irq_rid = 0; 465 480 if ((result = pci_msi_count(dev)) == 1 && 466 481 pci_alloc_msi(dev, &result) == 0) 467 482 sc->irq_rid = 1; 483 /* Install interrupt handler. */ 468 484 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, 469 485 RF_ACTIVE | RF_SHAREABLE); 470 486 if (sc->irq == NULL) { 471 device_printf(dev, "c ould not allocate interrupt resource\n");487 device_printf(dev, "can't map interrupt\n"); 472 488 error = ENOMEM; 473 489 goto fail; 474 490 } 475 491 476 492 IWN_LOCK_INIT(sc); 477 callout_init_mtx(&sc->sc_timer_to, &sc->sc_mtx, 0); 478 TASK_INIT(&sc->sc_reinit_task, 0, iwn_hw_reset, sc ); 479 TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc ); 480 TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc ); 481 482 /* Attach Hardware Abstraction Layer. */ 483 hal = iwn_hal_attach(sc); 484 if (hal == NULL) { 485 error = ENXIO; /* XXX: Wrong error code? */ 493 494 /* Read hardware revision and attach. */ 495 sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf; 496 if (sc->hw_type == IWN_HW_REV_TYPE_4965) 497 error = iwn4965_attach(sc, pci_get_device(dev)); 498 else 499 error = iwn5000_attach(sc, pci_get_device(dev)); 500 if (error != 0) { 501 device_printf(dev, "could not attach device, error %d\n", 502 error); 486 503 goto fail; 487 504 } 488 505 489 error = iwn_hw_prepare(sc); 490 if (error != 0) { 506 if ((error = iwn_hw_prepare(sc)) != 0) { 491 507 device_printf(dev, "hardware not ready, error %d\n", error); 492 508 goto fail; 493 509 } 494 510 495 511 /* Allocate DMA memory for firmware transfers. */ 496 error = iwn_alloc_fwmem(sc); 497 if (error != 0) { 512 if ((error = iwn_alloc_fwmem(sc)) != 0) { 498 513 device_printf(dev, 499 514 "could not allocate memory for firmware, error %d\n", 500 515 error); … … iwn_attach(device_t dev) 502 517 } 503 518 504 519 /* Allocate "Keep Warm" page. */ 505 error = iwn_alloc_kw(sc); 506 if (error != 0) { 520 if ((error = iwn_alloc_kw(sc)) != 0) { 507 521 device_printf(dev, 508 "could not allocate \"Keep Warm\"page, error %d\n", error);522 "could not allocate keep warm page, error %d\n", error); 509 523 goto fail; 510 524 } 511 525 512 526 /* Allocate ICT table for 5000 Series. */ 513 527 if (sc->hw_type != IWN_HW_REV_TYPE_4965 && 514 528 (error = iwn_alloc_ict(sc)) != 0) { 515 device_printf(dev, 516 "%s: could not allocate ICT table, error %d\n", 517 __func__, error); 529 device_printf(dev, "could not allocate ICT table, error %d\n", 530 error); 518 531 goto fail; 519 532 } 520 533 521 534 /* Allocate TX scheduler "rings". */ 522 error = iwn_alloc_sched(sc); 523 if (error != 0) { 535 if ((error = iwn_alloc_sched(sc)) != 0) { 524 536 device_printf(dev, 525 "could not allocate TX scheduler rings, error %d\n", 526 error); 537 "could not allocate TX scheduler rings, error %d\n", error); 527 538 goto fail; 528 539 } 529 540 530 /* Allocate TX rings (16 on 4965AGN, 20 on 5000). */ 531 for (i = 0; i < hal->ntxqs; i++) { 532 error = iwn_alloc_tx_ring(sc, &sc->txq[i], i); 533 if (error != 0) { 541 /* Allocate TX rings (16 on 4965AGN, 20 on >=5000). */ 542 for (i = 0; i < sc->ntxqs; i++) { 543 if ((error = iwn_alloc_tx_ring(sc, &sc->txq[i], i)) != 0) { 534 544 device_printf(dev, 535 "could not allocate T x ring %d, error %d\n",536 i,error);545 "could not allocate TX ring %d, error %d\n", i, 546 error); 537 547 goto fail; 538 548 } 539 549 } 540 550 541 551 /* Allocate RX ring. */ 542 error = iwn_alloc_rx_ring(sc, &sc->rxq); 543 if (error != 0 ){ 544 device_printf(dev, 545 "could not allocate Rx ring, error %d\n", error); 552 if ((error = iwn_alloc_rx_ring(sc, &sc->rxq)) != 0) { 553 device_printf(dev, "could not allocate RX ring, error %d\n", 554 error); 546 555 goto fail; 547 556 } 548 557 … … iwn_attach(device_t dev) 558 567 ((sc->rxchainmask >> 2) & 1) + 559 568 ((sc->rxchainmask >> 1) & 1) + 560 569 ((sc->rxchainmask >> 0) & 1); 570 if (bootverbose) { 571 device_printf(dev, "MIMO %dT%dR, %.4s, address %6D\n", 572 sc->ntxchains, sc->nrxchains, sc->eeprom_domain, 573 macaddr, ":"); 574 } 561 575 562 576 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 563 577 if (ifp == NULL) { 564 578 device_printf(dev, "can not allocate ifnet structure\n"); 565 579 goto fail; 566 580 } 567 ic = ifp->if_l2com;568 581 582 ic = ifp->if_l2com; 569 583 ic->ic_ifp = ifp; 570 584 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 571 585 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ … … iwn_attach(device_t dev) 616 630 #endif 617 631 618 632 /* Read MAC address, channels, etc from EEPROM. */ 619 error = iwn_read_eeprom(sc, macaddr); 620 if (error != 0) { 633 if ((error = iwn_read_eeprom(sc, macaddr)) != 0) { 621 634 device_printf(dev, "could not read EEPROM, error %d\n", 622 635 error); 623 636 goto fail; 624 637 } 625 638 626 device_printf(sc->sc_dev, "MIMO %dT%dR, %.4s, address %6D\n",627 sc->ntxchains, sc->nrxchains, sc->eeprom_domain,628 macaddr, ":");629 630 639 #if 0 /* HT */ 631 640 /* Set supported HT rates. */ 632 641 ic->ic_sup_mcs[0] = 0xff; … … iwn_attach(device_t dev) 651 660 ic->ic_vap_delete = iwn_vap_delete; 652 661 ic->ic_raw_xmit = iwn_raw_xmit; 653 662 ic->ic_node_alloc = iwn_node_alloc; 654 ic->ic_wme.wme_update = iwn_wme_update; 663 #if 0 /* HT */ 664 ic->ic_ampdu_rx_start = iwn_ampdu_rx_start; 665 ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop; 666 ic->ic_ampdu_tx_start = iwn_ampdu_tx_start; 667 ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop; 668 #endif 669 ic->ic_newassoc = iwn_newassoc; 670 ic->ic_wme.wme_update = iwn_updateedca; 655 671 ic->ic_update_mcast = iwn_update_mcast; 656 672 ic->ic_scan_start = iwn_scan_start; 657 673 ic->ic_scan_end = iwn_scan_end; … … iwn_attach(device_t dev) 659 675 ic->ic_scan_curchan = iwn_scan_curchan; 660 676 ic->ic_scan_mindwell = iwn_scan_mindwell; 661 677 ic->ic_setregdomain = iwn_setregdomain; 662 #if 0 /* HT */663 ic->ic_ampdu_rx_start = iwn_ampdu_rx_start;664 ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop;665 ic->ic_ampdu_tx_start = iwn_ampdu_tx_start;666 ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop;667 #endif668 678 669 679 iwn_radiotap_attach(sc); 680 681 callout_init_mtx(&sc->calib_to, &sc->sc_mtx, 0); 682 callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0); 683 TASK_INIT(&sc->sc_reinit_task, 0, iwn_hw_reset, sc); 684 TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc); 685 TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc); 686 670 687 iwn_sysctlattach(sc); 671 688 672 689 /* … … iwn_attach(device_t dev) 675 692 error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, 676 693 NULL, iwn_intr, sc, &sc->sc_ih); 677 694 if (error != 0) { 678 device_printf(dev, "c ould not set upinterrupt, error %d\n",695 device_printf(dev, "can't establish interrupt, error %d\n", 679 696 error); 680 697 goto fail; 681 698 } 682 699 683 ieee80211_announce(ic); 700 if (bootverbose) 701 ieee80211_announce(ic); 684 702 return 0; 685 703 fail: 686 iwn_ cleanup(dev);704 iwn_detach(dev); 687 705 return error; 688 706 } 689 707 690 static const struct iwn_hal * 691 iwn_hal_attach(struct iwn_softc *sc) 692 { 693 sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf; 708 static int 709 iwn4965_attach(struct iwn_softc *sc, uint16_t pid) 710 { 711 struct iwn_ops *ops = &sc->ops; 712 713 ops->load_firmware = iwn4965_load_firmware; 714 ops->read_eeprom = iwn4965_read_eeprom; 715 ops->post_alive = iwn4965_post_alive; 716 ops->nic_config = iwn4965_nic_config; 717 ops->update_sched = iwn4965_update_sched; 718 ops->get_temperature = iwn4965_get_temperature; 719 ops->get_rssi = iwn4965_get_rssi; 720 ops->set_txpower = iwn4965_set_txpower; 721 ops->init_gains = iwn4965_init_gains; 722 ops->set_gains = iwn4965_set_gains; 723 ops->add_node = iwn4965_add_node; 724 ops->tx_done = iwn4965_tx_done; 725 #if 0 /* HT */ 726 ops->ampdu_tx_start = iwn4965_ampdu_tx_start; 727 ops->ampdu_tx_stop = iwn4965_ampdu_tx_stop; 728 #endif 729 sc->ntxqs = IWN4965_NTXQUEUES; 730 sc->ndmachnls = IWN4965_NDMACHNLS; 731 sc->broadcast_id = IWN4965_ID_BROADCAST; 732 sc->rxonsz = IWN4965_RXONSZ; 733 sc->schedsz = IWN4965_SCHEDSZ; 734 sc->fw_text_maxsz = IWN4965_FW_TEXT_MAXSZ; 735 sc->fw_data_maxsz = IWN4965_FW_DATA_MAXSZ; 736 sc->fwsz = IWN4965_FWSZ; 737 sc->sched_txfact_addr = IWN4965_SCHED_TXFACT; 738 sc->limits = &iwn4965_sensitivity_limits; 739 sc->fwname = "iwn4965fw"; 740 /* Override chains masks, ROM is known to be broken. */ 741 sc->txchainmask = IWN_ANT_AB; 742 sc->rxchainmask = IWN_ANT_ABC; 743 744 return 0; 745 } 746 747 static int 748 iwn5000_attach(struct iwn_softc *sc, uint16_t pid) 749 { 750 struct iwn_ops *ops = &sc->ops; 751 752 ops->load_firmware = iwn5000_load_firmware; 753 ops->read_eeprom = iwn5000_read_eeprom; 754 ops->post_alive = iwn5000_post_alive; 755 ops->nic_config = iwn5000_nic_config; 756 ops->update_sched = iwn5000_update_sched; 757 ops->get_temperature = iwn5000_get_temperature; 758 ops->get_rssi = iwn5000_get_rssi; 759 ops->set_txpower = iwn5000_set_txpower; 760 ops->init_gains = iwn5000_init_gains; 761 ops->set_gains = iwn5000_set_gains; 762 ops->add_node = iwn5000_add_node; 763 ops->tx_done = iwn5000_tx_done; 764 #if 0 /* HT */ 765 ops->ampdu_tx_start = iwn5000_ampdu_tx_start; 766 ops->ampdu_tx_stop = iwn5000_ampdu_tx_stop; 767 #endif 768 sc->ntxqs = IWN5000_NTXQUEUES; 769 sc->ndmachnls = IWN5000_NDMACHNLS; 770 sc->broadcast_id = IWN5000_ID_BROADCAST; 771 sc->rxonsz = IWN5000_RXONSZ; 772 sc->schedsz = IWN5000_SCHEDSZ; 773 sc->fw_text_maxsz = IWN5000_FW_TEXT_MAXSZ; 774 sc->fw_data_maxsz = IWN5000_FW_DATA_MAXSZ; 775 sc->fwsz = IWN5000_FWSZ; 776 sc->sched_txfact_addr = IWN5000_SCHED_TXFACT; 777 sc->reset_noise_gain = IWN5000_PHY_CALIB_RESET_NOISE_GAIN; 778 sc->noise_gain = IWN5000_PHY_CALIB_NOISE_GAIN; 694 779 695 780 switch (sc->hw_type) { 696 case IWN_HW_REV_TYPE_4965:697 sc->sc_hal = &iwn4965_hal;698 sc->limits = &iwn4965_sensitivity_limits;699 sc->fwname = "iwn4965fw";700 sc->txchainmask = IWN_ANT_AB;701 sc->rxchainmask = IWN_ANT_ABC;702 break;703 781 case IWN_HW_REV_TYPE_5100: 704 sc->sc_hal = &iwn5000_hal;705 782 sc->limits = &iwn5000_sensitivity_limits; 706 783 sc->fwname = "iwn5000fw"; 784 /* Override chains masks, ROM is known to be broken. */ 707 785 sc->txchainmask = IWN_ANT_B; 708 786 sc->rxchainmask = IWN_ANT_AB; 709 sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |710 IWN_CALIB_TX_IQ | IWN_CALIB_TX_IQ_PERIODIC |711 IWN_CALIB_BASE_BAND;712 787 break; 713 788 case IWN_HW_REV_TYPE_5150: 714 sc->sc_hal = &iwn5000_hal;715 789 sc->limits = &iwn5150_sensitivity_limits; 716 790 sc->fwname = "iwn5150fw"; 717 sc->txchainmask = IWN_ANT_A;718 sc->rxchainmask = IWN_ANT_AB;719 sc->calib_init = IWN_CALIB_DC | IWN_CALIB_LO |720 IWN_CALIB_TX_IQ | IWN_CALIB_BASE_BAND;721 791 break; 722 792 case IWN_HW_REV_TYPE_5300: 723 793 case IWN_HW_REV_TYPE_5350: 724 sc->sc_hal = &iwn5000_hal;725 794 sc->limits = &iwn5000_sensitivity_limits; 726 795 sc->fwname = "iwn5000fw"; 727 sc->txchainmask = IWN_ANT_ABC;728 sc->rxchainmask = IWN_ANT_ABC;729 sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |730 IWN_CALIB_TX_IQ | IWN_CALIB_TX_IQ_PERIODIC |731 IWN_CALIB_BASE_BAND;732 796 break; 733 797 case IWN_HW_REV_TYPE_1000: 734 sc->sc_hal = &iwn5000_hal;735 798 sc->limits = &iwn1000_sensitivity_limits; 736 799 sc->fwname = "iwn1000fw"; 737 sc->txchainmask = IWN_ANT_A;738 sc->rxchainmask = IWN_ANT_AB;739 sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |740 IWN_CALIB_TX_IQ | IWN_CALIB_TX_IQ_PERIODIC |741 IWN_CALIB_BASE_BAND;742 800 break; 743 801 case IWN_HW_REV_TYPE_6000: 744 sc->sc_hal = &iwn5000_hal;745 802 sc->limits = &iwn6000_sensitivity_limits; 746 803 sc->fwname = "iwn6000fw"; 747 switch (pci_get_device(sc->sc_dev)) { 748 case 0x422C: 749 case 0x4239: 804 if (pid == 0x422c || pid == 0x4239) { 750 805 sc->sc_flags |= IWN_FLAG_INTERNAL_PA; 806 /* Override chains masks, ROM is known to be broken. */ 751 807 sc->txchainmask = IWN_ANT_BC; 752 808 sc->rxchainmask = IWN_ANT_BC; 753 break;754 default:755 sc->txchainmask = IWN_ANT_ABC;756 sc->rxchainmask = IWN_ANT_ABC;757 sc->calib_runtime = IWN_CALIB_DC;758 break;759 809 } 760 sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |761 IWN_CALIB_TX_IQ | IWN_CALIB_BASE_BAND;762 810 break; 763 811 case IWN_HW_REV_TYPE_6050: 764 sc->sc_hal = &iwn5000_hal;765 812 sc->limits = &iwn6000_sensitivity_limits; 766 813 sc->fwname = "iwn6050fw"; 814 /* Override chains masks, ROM is known to be broken. */ 767 815 sc->txchainmask = IWN_ANT_AB; 768 816 sc->rxchainmask = IWN_ANT_AB; 769 sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |770 IWN_CALIB_TX_IQ | IWN_CALIB_BASE_BAND;771 sc->calib_runtime = IWN_CALIB_DC;772 817 break; 773 818 case IWN_HW_REV_TYPE_6005: 774 sc->sc_hal = &iwn5000_hal;775 819 sc->limits = &iwn6000_sensitivity_limits; 776 sc->fwname = "iwn6005fw"; 777 sc->txchainmask = IWN_ANT_AB; 778 sc->rxchainmask = IWN_ANT_AB; 779 sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO | 780 IWN_CALIB_TX_IQ | IWN_CALIB_BASE_BAND; 781 sc->calib_runtime = IWN_CALIB_DC; 820 if (pid != 0x0082 && pid != 0x0085) { 821 sc->fwname = "iwn6000g2bfw"; 822 sc->sc_flags |= IWN_FLAG_ADV_BTCOEX; 823 } else 824 sc->fwname = "iwn6000g2afw"; 782 825 break; 783 826 default: 784 827 device_printf(sc->sc_dev, "adapter type %d not supported\n", 785 828 sc->hw_type); 786 return NULL;829 return ENOTSUP; 787 830 } 788 return sc->sc_hal;831 return 0; 789 832 } 790 833 791 834 /* … … iwn_radiotap_attach(struct iwn_softc *sc) 804 847 IWN_RX_RADIOTAP_PRESENT); 805 848 } 806 849 850 static void 851 iwn_sysctlattach(struct iwn_softc *sc) 852 { 853 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev); 854 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev); 855 856 #ifdef IWN_DEBUG 857 sc->sc_debug = 0; 858 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 859 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "control debugging printfs"); 860 #endif 861 } 862 807 863 static struct ieee80211vap * 808 864 iwn_vap_create(struct ieee80211com *ic, 809 const char name[IFNAMSIZ], int unit, intopmode, int flags,810 811 865 const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode, int flags, 866 const uint8_t bssid[IEEE80211_ADDR_LEN], 867 const uint8_t mac[IEEE80211_ADDR_LEN]) 812 868 { 813 869 struct iwn_vap *ivp; 814 870 struct ieee80211vap *vap; … … iwn_vap_delete(struct ieee80211vap *vap) 844 900 } 845 901 846 902 static int 847 iwn_ cleanup(device_t dev)903 iwn_detach(device_t dev) 848 904 { 849 905 struct iwn_softc *sc = device_get_softc(dev); 850 906 struct ifnet *ifp = sc->sc_ifp; 851 907 struct ieee80211com *ic; 852 int i;908 int qid; 853 909 854 910 if (ifp != NULL) { 855 911 ic = ifp->if_l2com; … … iwn_cleanup(device_t dev) 859 915 ieee80211_draintask(ic, &sc->sc_radiooff_task); 860 916 861 917 iwn_stop(sc); 862 callout_drain(&sc->sc_timer_to); 918 callout_drain(&sc->watchdog_to); 919 callout_drain(&sc->calib_to); 863 920 ieee80211_ifdetach(ic); 864 921 } 865 922 866 iwn5000_free_calib_results(sc); 923 /* Uninstall interrupt handler. */ 924 if (sc->irq != NULL) { 925 bus_teardown_intr(dev, sc->irq, sc->sc_ih); 926 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); 927 if (sc->irq_rid == 1) 928 pci_release_msi(dev); 929 } 867 930 868 931 /* Free DMA resources. */ 869 932 iwn_free_rx_ring(sc, &sc->rxq); 870 if (sc->sc_hal != NULL) 871 for (i = 0; i < sc->sc_hal->ntxqs; i++) 872 iwn_free_tx_ring(sc, &sc->txq[i]); 933 for (qid = 0; qid < sc->ntxqs; qid++) 934 iwn_free_tx_ring(sc, &sc->txq[qid]); 873 935 iwn_free_sched(sc); 874 936 iwn_free_kw(sc); 875 937 if (sc->ict != NULL) 876 938 iwn_free_ict(sc); 877 939 iwn_free_fwmem(sc); 878 940 879 if (sc->irq != NULL) {880 bus_teardown_intr(dev, sc->irq, sc->sc_ih);881 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);882 if (sc->irq_rid == 1)883 pci_release_msi(dev);884 }885 886 941 if (sc->mem != NULL) 887 942 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); 888 943 … … iwn_cleanup(device_t dev) 894 949 } 895 950 896 951 static int 897 iwn_detach(device_t dev) 952 iwn_shutdown(device_t dev) 953 { 954 struct iwn_softc *sc = device_get_softc(dev); 955 956 iwn_stop(sc); 957 return 0; 958 } 959 960 static int 961 iwn_suspend(device_t dev) 898 962 { 899 iwn_cleanup(dev); 963 struct iwn_softc *sc = device_get_softc(dev); 964 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 965 966 ieee80211_suspend_all(ic); 967 return 0; 968 } 969 970 static int 971 iwn_resume(device_t dev) 972 { 973 struct iwn_softc *sc = device_get_softc(dev); 974 struct ieee80211com *ic = sc->sc_ifp->if_l2com; 975 976 /* Clear device-specific "PCI retry timeout" register (41h). */ 977 pci_write_config(dev, 0x41, 0, 1); 978 979 ieee80211_resume_all(ic); 900 980 return 0; 901 981 } 902 982 … … iwn_nic_lock(struct iwn_softc *sc) 911 991 /* Spin until we actually get the lock. */ 912 992 for (ntries = 0; ntries < 1000; ntries++) { 913 993 if ((IWN_READ(sc, IWN_GP_CNTRL) & 914 (IWN_GP_CNTRL_MAC_ACCESS_ENA | IWN_GP_CNTRL_SLEEP)) ==994 (IWN_GP_CNTRL_MAC_ACCESS_ENA | IWN_GP_CNTRL_SLEEP)) == 915 995 IWN_GP_CNTRL_MAC_ACCESS_ENA) 916 996 return 0; 917 997 DELAY(10); … … iwn_init_otprom(struct iwn_softc *sc) 1044 1124 int count, error; 1045 1125 1046 1126 /* Wait for clock stabilization before accessing prph. */ 1047 error = iwn_clock_wait(sc); 1048 if (error != 0) 1127 if ((error = iwn_clock_wait(sc)) != 0) 1049 1128 return error; 1050 1129 1051 error = iwn_nic_lock(sc); 1052 if (error != 0) 1130 if ((error = iwn_nic_lock(sc)) != 0) 1053 1131 return error; 1054 1132 iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ); 1055 1133 DELAY(5); … … iwn_init_otprom(struct iwn_softc *sc) 1094 1172 static int 1095 1173 iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count) 1096 1174 { 1175 uint8_t *out = data; 1097 1176 uint32_t val, tmp; 1098 1177 int ntries; 1099 uint8_t *out = data;1100 1178 1101 1179 addr += sc->prom_base; 1102 1180 for (; count > 0; count -= 2, addr++) { … … iwn_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 1144 1222 1145 1223 static int 1146 1224 iwn_dma_contig_alloc(struct iwn_softc *sc, struct iwn_dma_info *dma, 1147 void **kvap, bus_size_t size, bus_size_t alignment, int flags)1225 void **kvap, bus_size_t size, bus_size_t alignment) 1148 1226 { 1149 1227 int error; 1150 1228 1151 dma->size = size;1152 1229 dma->tag = NULL; 1230 dma->size = size; 1153 1231 1154 1232 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), alignment, 1155 1233 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size, 1156 1, size, flags, NULL, NULL, &dma->tag); 1157 if (error != 0) { 1158 device_printf(sc->sc_dev, 1159 "%s: bus_dma_tag_create failed, error %d\n", 1160 __func__, error); 1234 1, size, BUS_DMA_NOWAIT, NULL, NULL, &dma->tag); 1235 if (error != 0) 1161 1236 goto fail; 1162 } 1237 1163 1238 error = bus_dmamem_alloc(dma->tag, (void **)&dma->vaddr, 1164 flags | BUS_DMA_ZERO, &dma->map); 1165 if (error != 0) { 1166 device_printf(sc->sc_dev, 1167 "%s: bus_dmamem_alloc failed, error %d\n", __func__, error); 1239 BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &dma->map); 1240 if (error != 0) 1168 1241 goto fail; 1169 } 1170 error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr, 1171 size, iwn_dma_map_addr, &dma->paddr, flags); 1172 if (error != 0) { 1173 device_printf(sc->sc_dev, 1174 "%s: bus_dmamap_load failed, error %d\n", __func__, error); 1242 1243 error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr, size, 1244 iwn_dma_map_addr, &dma->paddr, BUS_DMA_NOWAIT); 1245 if (error != 0) 1175 1246 goto fail; 1176 } 1247 1248 bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE); 1177 1249 1178 1250 if (kvap != NULL) 1179 1251 *kvap = dma->vaddr; 1252 1180 1253 return 0; 1181 fail: 1182 iwn_dma_contig_free(dma);1254 1255 fail: iwn_dma_contig_free(dma); 1183 1256 return error; 1184 1257 } 1185 1258 1186 1259 static void 1187 1260 iwn_dma_contig_free(struct iwn_dma_info *dma) 1188 1261 { 1189 if (dma->tag != NULL) { 1190 if (dma->map != NULL) { 1191 if (dma->paddr == 0) { 1192 bus_dmamap_sync(dma->tag, dma->map, 1193 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1194 bus_dmamap_unload(dma->tag, dma->map); 1195 } 1262 if (dma->map != NULL) { 1263 if (dma->vaddr != NULL) { 1264 bus_dmamap_sync(dma->tag, dma->map, 1265 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1266 bus_dmamap_unload(dma->tag, dma->map); 1196 1267 bus_dmamem_free(dma->tag, &dma->vaddr, dma->map); 1268 dma->vaddr = NULL; 1197 1269 } 1270 bus_dmamap_destroy(dma->tag, dma->map); 1271 dma->map = NULL; 1272 } 1273 if (dma->tag != NULL) { 1198 1274 bus_dma_tag_destroy(dma->tag); 1275 dma->tag = NULL; 1199 1276 } 1200 1277 } 1201 1278 … … static int 1203 1280 iwn_alloc_sched(struct iwn_softc *sc) 1204 1281 { 1205 1282 /* TX scheduler rings must be aligned on a 1KB boundary. */ 1206 return iwn_dma_contig_alloc(sc, &sc->sched_dma, 1207 (void **)&sc->sched, sc->sc_hal->schedsz, 1024, BUS_DMA_NOWAIT);1283 return iwn_dma_contig_alloc(sc, &sc->sched_dma, (void **)&sc->sched, 1284 sc->schedsz, 1024); 1208 1285 } 1209 1286 1210 1287 static void … … static int 1217 1294 iwn_alloc_kw(struct iwn_softc *sc) 1218 1295 { 1219 1296 /* "Keep Warm" page must be aligned on a 4KB boundary. */ 1220 return iwn_dma_contig_alloc(sc, &sc->kw_dma, NULL, 4096, 4096, 1221 BUS_DMA_NOWAIT); 1297 return iwn_dma_contig_alloc(sc, &sc->kw_dma, NULL, 4096, 4096); 1222 1298 } 1223 1299 1224 1300 static void … … static int 1231 1307 iwn_alloc_ict(struct iwn_softc *sc) 1232 1308 { 1233 1309 /* ICT table must be aligned on a 4KB boundary. */ 1234 return iwn_dma_contig_alloc(sc, &sc->ict_dma, 1235 (void **)&sc->ict, IWN_ICT_SIZE, 4096, BUS_DMA_NOWAIT);1310 return iwn_dma_contig_alloc(sc, &sc->ict_dma, (void **)&sc->ict, 1311 IWN_ICT_SIZE, 4096); 1236 1312 } 1237 1313 1238 1314 static void … … static int 1245 1321 iwn_alloc_fwmem(struct iwn_softc *sc) 1246 1322 { 1247 1323 /* Must be aligned on a 16-byte boundary. */ 1248 return iwn_dma_contig_alloc(sc, &sc->fw_dma, NULL, 1249 sc->sc_hal->fwsz, 16, BUS_DMA_NOWAIT); 1324 return iwn_dma_contig_alloc(sc, &sc->fw_dma, NULL, sc->fwsz, 16); 1250 1325 } 1251 1326 1252 1327 static void … … iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring) 1265 1340 1266 1341 /* Allocate RX descriptors (256-byte aligned). */ 1267 1342 size = IWN_RX_RING_COUNT * sizeof (uint32_t); 1268 error = iwn_dma_contig_alloc(sc, &ring->desc_dma, 1269 (void **)&ring->desc, size, 256, BUS_DMA_NOWAIT);1343 error = iwn_dma_contig_alloc(sc, &ring->desc_dma, (void **)&ring->desc, 1344 size, 256); 1270 1345 if (error != 0) { 1271 1346 device_printf(sc->sc_dev, 1272 "%s: could not allocate R xring DMA memory, error %d\n",1347 "%s: could not allocate RX ring DMA memory, error %d\n", 1273 1348 __func__, error); 1274 1349 goto fail; 1275 1350 } 1276 1351 1277 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 1278 BUS_SPACE_MAXADDR_32BIT, 1279 BUS_SPACE_MAXADDR, NULL, NULL, MJUMPAGESIZE, 1, 1280 MJUMPAGESIZE, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat); 1352 /* Allocate RX status area (16-byte aligned). */ 1353 error = iwn_dma_contig_alloc(sc, &ring->stat_dma, (void **)&ring->stat, 1354 sizeof (struct iwn_rx_status), 16); 1281 1355 if (error != 0) { 1282 1356 device_printf(sc->sc_dev, 1283 "%s: bus_dma_tag_create_failed, error %d\n",1357 "%s: could not allocate RX status DMA memory, error %d\n", 1284 1358 __func__, error); 1285 1359 goto fail; 1286 1360 } 1287 1361 1288 /* Allocate RX status area (16-byte aligned). */ 1289 error = iwn_dma_contig_alloc(sc, &ring->stat_dma, 1290 (void **)&ring->stat, sizeof (struct iwn_rx_status), 1291 16, BUS_DMA_NOWAIT); 1362 /* Create RX buffer DMA tag. */ 1363 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 1364 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 1365 IWN_RBUF_SIZE, 1, IWN_RBUF_SIZE, BUS_DMA_NOWAIT, NULL, NULL, 1366 &ring->data_dmat); 1292 1367 if (error != 0) { 1293 1368 device_printf(sc->sc_dev, 1294 "%s: could not allocate Rx status DMA memory, error %d\n",1369 "%s: could not create RX buf DMA tag, error %d\n", 1295 1370 __func__, error); 1296 1371 goto fail; 1297 1372 } … … iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring) 1306 1381 error = bus_dmamap_create(ring->data_dmat, 0, &data->map); 1307 1382 if (error != 0) { 1308 1383 device_printf(sc->sc_dev, 1309 "%s: bus_dmamap_create failed, error %d\n",1384 "%s: could not create RX buf DMA map, error %d\n", 1310 1385 __func__, error); 1311 1386 goto fail; 1312 1387 } 1313 1388 1314 data->m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE); 1389 data->m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, 1390 IWN_RBUF_SIZE); 1315 1391 if (data->m == NULL) { 1316 1392 device_printf(sc->sc_dev, 1317 "%s: could not allocate rxmbuf\n", __func__);1318 error = ENO MEM;1393 "%s: could not allocate RX mbuf\n", __func__); 1394 error = ENOBUFS; 1319 1395 goto fail; 1320 1396 } 1321 1397 1322 /* Map page. */1323 1398 error = bus_dmamap_load(ring->data_dmat, data->map, 1324 mtod(data->m, caddr_t), MJUMPAGESIZE,1325 iwn_dma_map_addr,&paddr, BUS_DMA_NOWAIT);1399 mtod(data->m, void *), IWN_RBUF_SIZE, iwn_dma_map_addr, 1400 &paddr, BUS_DMA_NOWAIT); 1326 1401 if (error != 0 && error != EFBIG) { 1327 1402 device_printf(sc->sc_dev, 1328 "%s: bus_dmamap_load failed, error %d\n", 1329 __func__, error); 1330 m_freem(data->m); 1331 error = ENOMEM; /* XXX unique code */ 1403 "%s: can't not map mbuf, error %d\n", __func__, 1404 error); 1332 1405 goto fail; 1333 1406 } 1334 bus_dmamap_sync(ring->data_dmat, data->map,1335 BUS_DMASYNC_PREWRITE);1336 1407 1337 1408 /* Set physical address of RX buffer (256-byte aligned). */ 1338 1409 ring->desc[i] = htole32(paddr >> 8); 1339 1410 } 1411 1340 1412 bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map, 1341 1413 BUS_DMASYNC_PREWRITE); 1414 1342 1415 return 0; 1343 fail: 1344 iwn_free_rx_ring(sc, ring);1416 1417 fail: iwn_free_rx_ring(sc, ring); 1345 1418 return error; 1346 1419 } 1347 1420 … … iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring) 1359 1432 DELAY(10); 1360 1433 } 1361 1434 iwn_nic_unlock(sc); 1362 #ifdef IWN_DEBUG1363 if (ntries == 1000)1364 DPRINTF(sc, IWN_DEBUG_ANY, "%s\n",1365 "timeout resetting Rx ring");1366 #endif1367 1435 } 1368 1436 ring->cur = 0; 1369 1437 sc->last_rx_valid = 0; … … iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring) 1385 1453 BUS_DMASYNC_POSTREAD); 1386 1454 bus_dmamap_unload(ring->data_dmat, data->map); 1387 1455 m_freem(data->m); 1456 data->m = NULL; 1388 1457 } 1389 1458 if (data->map != NULL) 1390 1459 bus_dmamap_destroy(ring->data_dmat, data->map); 1391 1460 } 1461 if (ring->data_dmat != NULL) { 1462 bus_dma_tag_destroy(ring->data_dmat); 1463 ring->data_dmat = NULL; 1464 } 1392 1465 } 1393 1466 1394 1467 static int 1395 1468 iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid) 1396 1469 { 1397 bus_size_t size;1398 1470 bus_addr_t paddr; 1471 bus_size_t size; 1399 1472 int i, error; 1400 1473 1401 1474 ring->qid = qid; 1402 1475 ring->queued = 0; 1403 1476 ring->cur = 0; 1404 1477 1405 /* Allocate TX descriptors (256-byte aligned .)*/1406 size = IWN_TX_RING_COUNT * sizeof (struct iwn_tx_desc);1407 error = iwn_dma_contig_alloc(sc, &ring->desc_dma, 1408 (void **)&ring->desc, size, 256, BUS_DMA_NOWAIT);1478 /* Allocate TX descriptors (256-byte aligned). */ 1479 size = IWN_TX_RING_COUNT * sizeof (struct iwn_tx_desc); 1480 error = iwn_dma_contig_alloc(sc, &ring->desc_dma, (void **)&ring->desc, 1481 size, 256); 1409 1482 if (error != 0) { 1410 1483 device_printf(sc->sc_dev, 1411 1484 "%s: could not allocate TX ring DMA memory, error %d\n", 1412 1485 __func__, error); 1413 1486 goto fail; 1414 1487 } 1415 1416 1488 /* 1417 1489 * We only use rings 0 through 4 (4 EDCA + cmd) so there is no need 1418 1490 * to allocate commands space for other rings. 1491 * XXX Do we really need to allocate descriptors for other rings? 1419 1492 */ 1420 1493 if (qid > 4) 1421 1494 return 0; 1422 1495 1423 size = IWN_TX_RING_COUNT * sizeof (struct iwn_tx_cmd);1424 error = iwn_dma_contig_alloc(sc, &ring->cmd_dma, 1425 (void **)&ring->cmd, size, 4, BUS_DMA_NOWAIT);1496 size = IWN_TX_RING_COUNT * sizeof (struct iwn_tx_cmd); 1497 error = iwn_dma_contig_alloc(sc, &ring->cmd_dma, (void **)&ring->cmd, 1498 size, 4); 1426 1499 if (error != 0) { 1427 1500 device_printf(sc->sc_dev, 1428 1501 "%s: could not allocate TX cmd DMA memory, error %d\n", … … iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid) 1431 1504 } 1432 1505 1433 1506 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 1434 BUS_SPACE_MAXADDR_32BIT, 1435 BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, IWN_MAX_SCATTER - 1,1436 MCLBYTES, BUS_DMA_NOWAIT, NULL, NULL,&ring->data_dmat);1507 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, 1508 IWN_MAX_SCATTER - 1, MCLBYTES, BUS_DMA_NOWAIT, NULL, NULL, 1509 &ring->data_dmat); 1437 1510 if (error != 0) { 1438 1511 device_printf(sc->sc_dev, 1439 "%s: bus_dma_tag_create_failed, error %d\n",1512 "%s: could not create TX buf DMA tag, error %d\n", 1440 1513 __func__, error); 1441 1514 goto fail; 1442 1515 } … … iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid) 1452 1525 error = bus_dmamap_create(ring->data_dmat, 0, &data->map); 1453 1526 if (error != 0) { 1454 1527 device_printf(sc->sc_dev, 1455 "%s: bus_dmamap_create failed, error %d\n",1528 "%s: could not create TX buf DMA map, error %d\n", 1456 1529 __func__, error); 1457 1530 goto fail; 1458 1531 } 1459 bus_dmamap_sync(ring->data_dmat, data->map,1460 BUS_DMASYNC_PREWRITE);1461 1532 } 1462 1533 return 0; 1463 fail: 1464 iwn_free_tx_ring(sc, ring);1534 1535 fail: iwn_free_tx_ring(sc, ring); 1465 1536 return error; 1466 1537 } 1467 1538 … … iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring) 1474 1545 struct iwn_tx_data *data = &ring->data[i]; 1475 1546 1476 1547 if (data->m != NULL) { 1548 bus_dmamap_sync(ring->data_dmat, data->map, 1549 BUS_DMASYNC_POSTWRITE); 1477 1550 bus_dmamap_unload(ring->data_dmat, data->map); 1478 1551 m_freem(data->m); 1479 1552 data->m = NULL; … … iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring) 1508 1581 if (data->map != NULL) 1509 1582 bus_dmamap_destroy(ring->data_dmat, data->map); 1510 1583 } 1584 if (ring->data_dmat != NULL) { 1585 bus_dma_tag_destroy(ring->data_dmat); 1586 ring->data_dmat = NULL; 1587 } 1511 1588 } 1512 1589 1513 1590 static void … … iwn5000_ict_reset(struct iwn_softc *sc) 1520 1597 memset(sc->ict, 0, IWN_ICT_SIZE); 1521 1598 sc->ict_cur = 0; 1522 1599 1523 /* Set physical address of ICT table (4KB aligned .)*/1600 /* Set physical address of ICT table (4KB aligned). */ 1524 1601 DPRINTF(sc, IWN_DEBUG_RESET, "%s: enabling ICT\n", __func__); 1525 1602 IWN_WRITE(sc, IWN_DRAM_INT_TBL, IWN_DRAM_INT_TBL_ENABLE | 1526 1603 IWN_DRAM_INT_TBL_WRAP_CHECK | sc->ict_dma.paddr >> 12); … … iwn5000_ict_reset(struct iwn_softc *sc) 1538 1615 static int 1539 1616 iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN]) 1540 1617 { 1541 const struct iwn_hal *hal = sc->sc_hal; 1542 int error; 1618 struct iwn_ops *ops = &sc->ops; 1543 1619 uint16_t val; 1620 int error; 1544 1621 1545 1622 /* Check whether adapter has an EEPROM or an OTPROM. */ 1546 1623 if (sc->hw_type >= IWN_HW_REV_TYPE_1000 && … … iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN]) 1550 1627 (sc->sc_flags & IWN_FLAG_HAS_OTPROM) ? "OTPROM" : "EEPROM"); 1551 1628 1552 1629 /* Adapter has to be powered on for EEPROM access to work. */ 1553 error = iwn_apm_init(sc); 1554 if (error != 0) { 1630 if ((error = iwn_apm_init(sc)) != 0) { 1555 1631 device_printf(sc->sc_dev, 1556 "%s: could not power ON adapter, error %d\n", 1557 __func__,error);1632 "%s: could not power ON adapter, error %d\n", __func__, 1633 error); 1558 1634 return error; 1559 1635 } 1560 1636 … … iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN]) 1562 1638 device_printf(sc->sc_dev, "%s: bad ROM signature\n", __func__); 1563 1639 return EIO; 1564 1640 } 1565 error = iwn_eeprom_lock(sc); 1566 if (error != 0) { 1567 device_printf(sc->sc_dev, 1568 "%s: could not lock ROM, error %d\n", 1641 if ((error = iwn_eeprom_lock(sc)) != 0) { 1642 device_printf(sc->sc_dev, "%s: could not lock ROM, error %d\n", 1569 1643 __func__, error); 1570 1644 return error; 1571 1645 } 1572 1573 1646 if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) { 1574 error = iwn_init_otprom(sc); 1575 if (error != 0) { 1647 if ((error = iwn_init_otprom(sc)) != 0) { 1576 1648 device_printf(sc->sc_dev, 1577 1649 "%s: could not initialize OTPROM, error %d\n", 1578 1650 __func__, error); … … iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN]) 1580 1652 } 1581 1653 } 1582 1654 1655 iwn_read_prom_data(sc, IWN_EEPROM_SKU_CAP, &val, 2); 1656 DPRINTF(sc, IWN_DEBUG_RESET, "SKU capabilities=0x%04x\n", le16toh(val)); 1657 /* Check if HT support is bonded out. */ 1658 if (val & htole16(IWN_EEPROM_SKU_CAP_11N)) 1659 sc->sc_flags |= IWN_FLAG_HAS_11N; 1660 1583 1661 iwn_read_prom_data(sc, IWN_EEPROM_RFCFG, &val, 2); 1584 1662 sc->rfcfg = le16toh(val); 1585 1663 DPRINTF(sc, IWN_DEBUG_RESET, "radio config=0x%04x\n", sc->rfcfg); 1664 /* Read Tx/Rx chains from ROM unless it's known to be broken. */ 1665 if (sc->txchainmask == 0) 1666 sc->txchainmask = IWN_RFCFG_TXANTMSK(sc->rfcfg); 1667 if (sc->rxchainmask == 0) 1668 sc->rxchainmask = IWN_RFCFG_RXANTMSK(sc->rfcfg); 1586 1669 1587 1670 /* Read MAC address. */ 1588 1671 iwn_read_prom_data(sc, IWN_EEPROM_MAC, macaddr, 6); 1589 1672 1590 1673 /* Read adapter-specific information from EEPROM. */ 1591 hal->read_eeprom(sc);1674 ops->read_eeprom(sc); 1592 1675 1593 1676 iwn_apm_stop(sc); /* Power OFF adapter. */ 1594 1677 … … static void 1600 1683 iwn4965_read_eeprom(struct iwn_softc *sc) 1601 1684 { 1602 1685 uint32_t addr; 1603 int i;1604 1686 uint16_t val; 1687 int i; 1605 1688 1606 /* Read regulatory domain (4 ASCII characters .)*/1689 /* Read regulatory domain (4 ASCII characters). */ 1607 1690 iwn_read_prom_data(sc, IWN4965_EEPROM_DOMAIN, sc->eeprom_domain, 4); 1608 1691 1609 /* Read the list of authorized channels (20MHz ones only .)*/1692 /* Read the list of authorized channels (20MHz ones only). */ 1610 1693 for (i = 0; i < 5; i++) { 1611 1694 addr = iwn4965_regulatory_bands[i]; 1612 1695 iwn_read_eeprom_channels(sc, i, addr); … … static void 1682 1765 iwn5000_read_eeprom(struct iwn_softc *sc) 1683 1766 { 1684 1767 struct iwn5000_eeprom_calib_hdr hdr; 1685 int32_t temp, volt; 1686 uint32_t addr, base; 1687 int i; 1768 int32_t volt; 1769 uint32_t base, addr; 1688 1770 uint16_t val; 1771 int i; 1689 1772 1690 /* Read regulatory domain (4 ASCII characters .)*/1773 /* Read regulatory domain (4 ASCII characters). */ 1691 1774 iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2); 1692 1775 base = le16toh(val); 1693 1776 iwn_read_prom_data(sc, base + IWN5000_EEPROM_DOMAIN, 1694 1777 sc->eeprom_domain, 4); 1695 1778 1696 /* Read the list of authorized channels (20MHz ones only .)*/1779 /* Read the list of authorized channels (20MHz ones only). */ 1697 1780 for (i = 0; i < 5; i++) { 1698 1781 addr = base + iwn5000_regulatory_bands[i]; 1699 1782 iwn_read_eeprom_channels(sc, i, addr); … … iwn5000_read_eeprom(struct iwn_softc *sc) 1707 1790 base = le16toh(val); 1708 1791 iwn_read_prom_data(sc, base, &hdr, sizeof hdr); 1709 1792 DPRINTF(sc, IWN_DEBUG_CALIBRATE, 1710 "%s: calib version=%u pa type=%u voltage=%u\n", 1711 __func__,hdr.version, hdr.pa_type, le16toh(hdr.volt));1793 "%s: calib version=%u pa type=%u voltage=%u\n", __func__, 1794 hdr.version, hdr.pa_type, le16toh(hdr.volt)); 1712 1795 sc->calib_ver = hdr.version; 1713 1796 1714 1797 if (sc->hw_type == IWN_HW_REV_TYPE_5150) { 1715 1798 /* Compute temperature offset. */ 1716 1799 iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2); 1717 temp = le16toh(val);1800 sc->eeprom_temp = le16toh(val); 1718 1801 iwn_read_prom_data(sc, base + IWN5000_EEPROM_VOLT, &val, 2); 1719 1802 volt = le16toh(val); 1720 sc->temp_off = temp - (volt / -5);1803 sc->temp_off = sc->eeprom_temp - (volt / -5); 1721 1804 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "temp=%d volt=%d offset=%dK\n", 1722 temp, volt, sc->temp_off); 1805 sc->eeprom_temp, volt, sc->temp_off); 1806 } else { 1807 /* Read crystal calibration. */ 1808 iwn_read_prom_data(sc, base + IWN5000_EEPROM_CRYSTAL, 1809 &sc->eeprom_crystal, sizeof (uint32_t)); 1810 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "crystal calibration 0x%08x\n", 1811 le32toh(sc->eeprom_crystal)); 1723 1812 } 1724 1813 } 1725 1814 … … iwn_read_eeprom_band(struct iwn_softc *sc, int n) 1753 1842 struct iwn_eeprom_chan *channels = sc->eeprom_channels[n]; 1754 1843 const struct iwn_chan_band *band = &iwn_bands[n]; 1755 1844 struct ieee80211_channel *c; 1756 int i, chan, nflags; 1845 uint8_t chan; 1846 int i, nflags; 1757 1847 1758 1848 for (i = 0; i < band->nchan; i++) { 1759 1849 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) { … … iwn_read_eeprom_band(struct iwn_softc *sc, int n) 1766 1856 chan = band->chan[i]; 1767 1857 nflags = iwn_eeprom_channel_flags(&channels[i]); 1768 1858 1769 DPRINTF(sc, IWN_DEBUG_RESET,1770 "add chan %d flags 0x%x maxpwr %d\n",1771 chan, channels[i].flags, channels[i].maxpwr);1772 1773 1859 c = &ic->ic_channels[ic->ic_nchans++]; 1774 1860 c->ic_ieee = chan; 1775 1861 c->ic_maxregpower = channels[i].maxpwr; 1776 1862 c->ic_maxpower = 2*c->ic_maxregpower; 1777 1863 1778 /* Save maximum allowed TX power for this channel. */1779 sc->maxpwr[chan] = channels[i].maxpwr;1780 1781 1864 if (n == 0) { /* 2GHz band */ 1782 c->ic_freq = ieee80211_ieee2mhz(chan, 1783 IEEE80211_CHAN_G); 1784 1865 c->ic_freq = ieee80211_ieee2mhz(chan, IEEE80211_CHAN_G); 1785 1866 /* G =>'s B is supported */ 1786 1867 c->ic_flags = IEEE80211_CHAN_B | nflags; 1787 1788 1868 c = &ic->ic_channels[ic->ic_nchans++]; 1789 1869 c[0] = c[-1]; 1790 1870 c->ic_flags = IEEE80211_CHAN_G | nflags; 1791 1871 } else { /* 5GHz band */ 1792 c->ic_freq = ieee80211_ieee2mhz(chan, 1793 IEEE80211_CHAN_A); 1872 c->ic_freq = ieee80211_ieee2mhz(chan, IEEE80211_CHAN_A); 1794 1873 c->ic_flags = IEEE80211_CHAN_A | nflags; 1795 sc->sc_flags |= IWN_FLAG_HAS_5GHZ;1796 1874 } 1875 1876 /* Save maximum allowed TX power for this channel. */ 1877 sc->maxpwr[chan] = channels[i].maxpwr; 1878 1879 DPRINTF(sc, IWN_DEBUG_RESET, 1880 "add chan %d flags 0x%x maxpwr %d\n", chan, 1881 channels[i].flags, channels[i].maxpwr); 1882 1797 1883 #if 0 /* HT */ 1798 1884 /* XXX no constraints on using HT20 */ 1799 1885 /* add HT20, HT40 added separately */ … … iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr) 1882 1968 ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans); 1883 1969 } 1884 1970 1885 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 1971 static struct iwn_eeprom_chan * 1972 iwn_find_eeprom_channel(struct iwn_softc *sc, struct ieee80211_channel *c) 1973 { 1974 int i, j; 1975 1976 for (j = 0; j < 7; j++) { 1977 for (i = 0; i < iwn_bands[j].nchan; i++) { 1978 if (iwn_bands[j].chan[i] == c->ic_ieee) 1979 return &sc->eeprom_channels[j][i]; 1980 } 1981 } 1982 1983 return NULL; 1984 } 1985 1986 /* 1987 * Enforce flags read from EEPROM. 1988 */ 1989 static int 1990 iwn_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd, 1991 int nchan, struct ieee80211_channel chans[]) 1992 { 1993 struct iwn_softc *sc = ic->ic_ifp->if_softc; 1994 int i; 1995 1996 for (i = 0; i < nchan; i++) { 1997 struct ieee80211_channel *c = &chans[i]; 1998 struct iwn_eeprom_chan *channel; 1999 2000 channel = iwn_find_eeprom_channel(sc, c); 2001 if (channel == NULL) { 2002 if_printf(ic->ic_ifp, 2003 "%s: invalid channel %u freq %u/0x%x\n", 2004 __func__, c->ic_ieee, c->ic_freq, c->ic_flags); 2005 return EINVAL; 2006 } 2007 c->ic_flags |= iwn_eeprom_channel_flags(channel); 2008 } 2009 2010 return 0; 2011 } 1886 2012 1887 2013 static void 1888 2014 iwn_read_eeprom_enhinfo(struct iwn_softc *sc) … … iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) 1927 2053 return malloc(sizeof (struct iwn_node), M_80211_NODE,M_NOWAIT | M_ZERO); 1928 2054 } 1929 2055 2056 static void 2057 iwn_newassoc(struct ieee80211_node *ni, int isnew) 2058 { 2059 struct iwn_node *wn = (void *)ni; 2060 int ridx, i; 2061 2062 for (i = 0; i < ni->ni_rates.rs_nrates; i++) { 2063 ridx = iwn_plcp_signal(ni->ni_rates.rs_rates[i]); 2064 wn->ridx[i] = ridx; 2065 } 2066 } 2067 1930 2068 static int 1931 2069 iwn_media_change(struct ifnet *ifp) 1932 2070 { 1933 int error = ieee80211_media_change(ifp); 2071 int error; 2072 2073 error = ieee80211_media_change(ifp); 1934 2074 /* NB: only the fixed rate can change and that doesn't need a reset */ 1935 2075 return (error == ENETRESET ? 0 : error); 1936 2076 } … … iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1941 2081 struct iwn_vap *ivp = IWN_VAP(vap); 1942 2082 struct ieee80211com *ic = vap->iv_ic; 1943 2083 struct iwn_softc *sc = ic->ic_ifp->if_softc; 1944 int error ;2084 int error = 0; 1945 2085 1946 2086 DPRINTF(sc, IWN_DEBUG_STATE, "%s: %s -> %s\n", __func__, 1947 ieee80211_state_name[vap->iv_state], 1948 ieee80211_state_name[nstate]); 2087 ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate]); 1949 2088 1950 2089 IEEE80211_UNLOCK(ic); 1951 2090 IWN_LOCK(sc); 1952 callout_stop(&sc-> sc_timer_to);2091 callout_stop(&sc->calib_to); 1953 2092 1954 2093 switch (nstate) { 1955 2094 case IEEE80211_S_ASSOC: … … iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1966 2105 */ 1967 2106 sc->rxon.associd = 0; 1968 2107 sc->rxon.filter &= ~htole32(IWN_FILTER_BSS); 1969 iwn_calib_reset(sc); 1970 error = iwn_auth(sc, vap); 2108 sc->calib.state = IWN_CALIB_STATE_INIT; 2109 2110 if ((error = iwn_auth(sc, vap)) != 0) { 2111 device_printf(sc->sc_dev, 2112 "%s: could not move to auth state\n", __func__); 2113 } 1971 2114 break; 1972 2115 1973 2116 case IEEE80211_S_RUN: 1974 2117 /* 1975 2118 * RUN -> RUN transition; Just restart the timers. 1976 2119 */ 1977 if (vap->iv_state == IEEE80211_S_RUN && 1978 vap->iv_opmode != IEEE80211_M_MONITOR) { 1979 iwn_calib_reset(sc); 2120 if (vap->iv_state == IEEE80211_S_RUN) { 2121 sc->calib_cnt = 0; 1980 2122 break; 1981 2123 } 1982 2124 … … iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1985 2127 * which is done with a firmware cmd. We also defer 1986 2128 * starting the timers until that work is done. 1987 2129 */ 1988 error = iwn_run(sc, vap); 2130 if ((error = iwn_run(sc, vap)) != 0) { 2131 device_printf(sc->sc_dev, 2132 "%s: could not move to run state\n", __func__); 2133 } 2134 break; 2135 2136 case IEEE80211_S_INIT: 2137 sc->calib.state = IWN_CALIB_STATE_INIT; 1989 2138 break; 1990 2139 1991 2140 default: … … iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1993 2142 } 1994 2143 IWN_UNLOCK(sc); 1995 2144 IEEE80211_LOCK(ic); 2145 if (error != 0) 2146 return error; 1996 2147 return ivp->iv_newstate(vap, nstate, arg); 1997 2148 } 1998 2149 2150 static void 2151 iwn_calib_timeout(void *arg) 2152 { 2153 struct iwn_softc *sc = arg; 2154 2155 IWN_LOCK_ASSERT(sc); 2156 2157 /* Force automatic TX power calibration every 60 secs. */ 2158 if (++sc->calib_cnt >= 120) { 2159 uint32_t flags = 0; 2160 2161 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s\n", 2162 "sending request for statistics"); 2163 (void)iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags, 2164 sizeof flags, 1); 2165 sc->calib_cnt = 0; 2166 } 2167 callout_reset(&sc->calib_to, msecs_to_ticks(500), iwn_calib_timeout, 2168 sc); 2169 } 2170 1999 2171 /* 2000 2172 * Process an RX_PHY firmware notification. This is usually immediately 2001 2173 * followed by an MPDU_RX_DONE notification. … … iwn_rx_phy(struct iwn_softc *sc, struct iwn_rx_desc *desc, 2014 2186 sc->last_rx_valid = 1; 2015 2187 } 2016 2188 2017 static void2018 iwn_timer_timeout(void *arg)2019 {2020 struct iwn_softc *sc = arg;2021 uint32_t flags = 0;2022 2023 IWN_LOCK_ASSERT(sc);2024 2025 if (sc->calib_cnt && --sc->calib_cnt == 0) {2026 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s\n",2027 "send statistics request");2028 (void) iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags,2029 sizeof flags, 1);2030 sc->calib_cnt = 60; /* do calibration every 60s */2031 }2032 iwn_watchdog(sc); /* NB: piggyback tx watchdog */2033 callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);2034 }2035 2036 static void2037 iwn_calib_reset(struct iwn_softc *sc)2038 {2039 callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);2040 sc->calib_cnt = 60; /* do calibration every 60s */2041 }2042 2043 2189 /* 2044 2190 * Process an RX_DONE (4965AGN only) or MPDU_RX_DONE firmware notification. 2045 2191 * Each MPDU_RX_DONE notification must be preceded by an RX_PHY one. … … static void 2048 2194 iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, 2049 2195 struct iwn_rx_data *data) 2050 2196 { 2051 const struct iwn_hal *hal = sc->sc_hal;2197 struct iwn_ops *ops = &sc->ops; 2052 2198 struct ifnet *ifp = sc->sc_ifp; 2053 2199 struct ieee80211com *ic = ifp->if_l2com; 2054 2200 struct iwn_rx_ring *ring = &sc->rxq; … … iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, 2066 2212 if (!sc->last_rx_valid) { 2067 2213 DPRINTF(sc, IWN_DEBUG_ANY, 2068 2214 "%s: missing RX_PHY\n", __func__); 2069 ifp->if_ierrors++;2070 2215 return; 2071 2216 } 2072 2217 sc->last_rx_valid = 0; … … iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, 2078 2223 2079 2224 if (stat->cfg_phy_len > IWN_STAT_MAXLEN) { 2080 2225 device_printf(sc->sc_dev, 2081 "%s: invalid rx statistic header, len %d\n", 2082 __func__, stat->cfg_phy_len); 2083 ifp->if_ierrors++; 2226 "%s: invalid RX statistic header, len %d\n", __func__, 2227 stat->cfg_phy_len); 2084 2228 return; 2085 2229 } 2086 2230 if (desc->type == IWN_MPDU_RX_DONE) { … … iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, 2096 2240 2097 2241 /* Discard frames with a bad FCS early. */ 2098 2242 if ((flags & IWN_RX_NOERROR) != IWN_RX_NOERROR) { 2099 DPRINTF(sc, IWN_DEBUG_RECV, "%s: rxflags error %x\n",2243 DPRINTF(sc, IWN_DEBUG_RECV, "%s: RX flags error %x\n", 2100 2244 __func__, flags); 2101 2245 ifp->if_ierrors++; 2102 2246 return; … … iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, 2109 2253 return; 2110 2254 } 2111 2255 2112 /* XXX don't need mbuf, just dma buffer */ 2113 m1 = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE); 2256 m1 = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, IWN_RBUF_SIZE); 2114 2257 if (m1 == NULL) { 2115 2258 DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n", 2116 2259 __func__); … … iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, 2119 2262 } 2120 2263 bus_dmamap_unload(ring->data_dmat, data->map); 2121 2264 2122 error = bus_dmamap_load(ring->data_dmat, data->map, 2123 mtod(m1, caddr_t), MJUMPAGESIZE, 2124 iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT); 2265 error = bus_dmamap_load(ring->data_dmat, data->map, mtod(m1, void *), 2266 IWN_RBUF_SIZE, iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT); 2125 2267 if (error != 0 && error != EFBIG) { 2126 2268 device_printf(sc->sc_dev, 2127 2269 "%s: bus_dmamap_load failed, error %d\n", __func__, error); 2128 2270 m_freem(m1); 2271 2272 /* Try to reload the old mbuf. */ 2273 error = bus_dmamap_load(ring->data_dmat, data->map, 2274 mtod(data->m, void *), IWN_RBUF_SIZE, iwn_dma_map_addr, 2275 &paddr, BUS_DMA_NOWAIT); 2276 if (error != 0 && error != EFBIG) { 2277 panic("%s: could not load old RX mbuf", __func__); 2278 } 2279 /* Physical address may have changed. */ 2280 ring->desc[ring->cur] = htole32(paddr >> 8); 2281 bus_dmamap_sync(ring->data_dmat, ring->desc_dma.map, 2282 BUS_DMASYNC_PREWRITE); 2129 2283 ifp->if_ierrors++; 2130 2284 return; 2131 2285 } … … iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, 2142 2296 m->m_data = head; 2143 2297 m->m_pkthdr.len = m->m_len = len; 2144 2298 2145 rssi = hal->get_rssi(sc, stat);2146 2147 2299 /* Grab a reference to the source node. */ 2148 2300 wh = mtod(m, struct ieee80211_frame *); 2149 2301 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); 2150 2302 nf = (ni != NULL && ni->ni_vap->iv_state == IEEE80211_S_RUN && 2151 2303 (ic->ic_flags & IEEE80211_F_SCAN) == 0) ? sc->noise : -95; 2152 2304 2305 rssi = ops->get_rssi(sc, stat); 2306 2153 2307 if (ieee80211_radiotap_active(ic)) { 2154 2308 struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap; 2155 2309 2156 tap->wr_tsft = htole64(stat->tstamp);2157 2310 tap->wr_flags = 0; 2158 2311 if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE)) 2159 2312 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 2313 tap->wr_dbm_antsignal = (int8_t)rssi; 2314 tap->wr_dbm_antnoise = (int8_t)nf; 2315 tap->wr_tsft = stat->tstamp; 2160 2316 switch (stat->rate) { 2161 2317 /* CCK rates. */ 2162 2318 case 10: tap->wr_rate = 2; break; … … iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, 2175 2331 /* Unknown rate: should not happen. */ 2176 2332 default: tap->wr_rate = 0; 2177 2333 } 2178 tap->wr_dbm_antsignal = rssi;2179 tap->wr_dbm_antnoise = nf;2180 2334 } 2181 2335 2182 2336 IWN_UNLOCK(sc); 2183 2337 2184 2338 /* Send the frame to the 802.11 layer. */ 2185 2339 if (ni != NULL) { 2186 (void) 2340 (void)ieee80211_input(ni, m, rssi - nf, nf); 2187 2341 /* Node is no longer needed. */ 2188 2342 ieee80211_free_node(ni); 2189 2343 } else 2190 (void) 2344 (void)ieee80211_input_all(ic, m, rssi - nf, nf); 2191 2345 2192 2346 IWN_LOCK(sc); 2193 2347 } … … iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc, 2201 2355 struct iwn_compressed_ba *ba = (struct iwn_compressed_ba *)(desc + 1); 2202 2356 struct iwn_tx_ring *txq; 2203 2357 2358 bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); 2359 2204 2360 txq = &sc->txq[letoh16(ba->qid)]; 2205 2361 /* XXX TBD */ 2206 2362 } 2207 2363 #endif 2208 2364 2209 2365 /* 2366 * Process a CALIBRATION_RESULT notification sent by the initialization 2367 * firmware on response to a CMD_CALIB_CONFIG command (5000 only). 2368 */ 2369 static void 2370 iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc, 2371 struct iwn_rx_data *data) 2372 { 2373 struct iwn_phy_calib *calib = (struct iwn_phy_calib *)(desc + 1); 2374 int len, idx = -1; 2375 2376 /* Runtime firmware should not send such a notification. */ 2377 if (sc->sc_flags & IWN_FLAG_CALIB_DONE) 2378 return; 2379 2380 len = (le32toh(desc->len) & 0x3fff) - 4; 2381 bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); 2382 2383 switch (calib->code) { 2384 case IWN5000_PHY_CALIB_DC: 2385 if ((sc->sc_flags & IWN_FLAG_INTERNAL_PA) == 0 && 2386 (sc->hw_type == IWN_HW_REV_TYPE_5150 || 2387 sc->hw_type >= IWN_HW_REV_TYPE_6000)) 2388 idx = 0; 2389 break; 2390 case IWN5000_PHY_CALIB_LO: 2391 idx = 1; 2392 break; 2393 case IWN5000_PHY_CALIB_TX_IQ: 2394 idx = 2; 2395 break; 2396 case IWN5000_PHY_CALIB_TX_IQ_PERIODIC: 2397 if (sc->hw_type < IWN_HW_REV_TYPE_6000 && 2398 sc->hw_type != IWN_HW_REV_TYPE_5150) 2399 idx = 3; 2400 break; 2401 case IWN5000_PHY_CALIB_BASE_BAND: 2402 idx = 4; 2403 break; 2404 } 2405 if (idx == -1) /* Ignore other results. */ 2406 return; 2407 2408 /* Save calibration result. */ 2409 if (sc->calibcmd[idx].buf != NULL) 2410 free(sc->calibcmd[idx].buf, M_DEVBUF); 2411 sc->calibcmd[idx].buf = malloc(len, M_DEVBUF, M_NOWAIT); 2412 if (sc->calibcmd[idx].buf == NULL) { 2413 DPRINTF(sc, IWN_DEBUG_CALIBRATE, 2414 "not enough memory for calibration result %d\n", 2415 calib->code); 2416 return; 2417 } 2418 DPRINTF(sc, IWN_DEBUG_CALIBRATE, 2419 "saving calibration result code=%d len=%d\n", calib->code, len); 2420 sc->calibcmd[idx].len = len; 2421 memcpy(sc->calibcmd[idx].buf, calib, len); 2422 } 2423 2424 /* 2210 2425 * Process an RX_STATISTICS or BEACON_STATISTICS firmware notification. 2211 2426 * The latter is sent by the firmware after each received beacon. 2212 2427 */ … … static void 2214 2429 iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc, 2215 2430 struct iwn_rx_data *data) 2216 2431 { 2217 const struct iwn_hal *hal = sc->sc_hal;2432 struct iwn_ops *ops = &sc->ops; 2218 2433 struct ifnet *ifp = sc->sc_ifp; 2219 2434 struct ieee80211com *ic = ifp->if_l2com; 2220 2435 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); … … iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc, 2222 2437 struct iwn_stats *stats = (struct iwn_stats *)(desc + 1); 2223 2438 int temp; 2224 2439 2225 /* Beacon stats are meaningful only when associated and not scanning. */2440 /* Ignore statistics received during a scan. */ 2226 2441 if (vap->iv_state != IEEE80211_S_RUN || 2227 2442 (ic->ic_flags & IEEE80211_F_SCAN)) 2228 2443 return; 2229 2444 2230 2445 bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); 2231 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: cmd %d\n", __func__, desc->type); 2232 iwn_calib_reset(sc); /* Reset TX power calibration timeout. */ 2446 2447 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: received statistics, cmd %d\n", 2448 __func__, desc->type); 2449 sc->calib_cnt = 0; /* Reset TX power calibration timeout. */ 2233 2450 2234 2451 /* Test if temperature has changed. */ 2235 2452 if (stats->general.temp != sc->rawtemp) { 2236 2453 /* Convert "raw" temperature to degC. */ 2237 2454 sc->rawtemp = stats->general.temp; 2238 temp = hal->get_temperature(sc);2455 temp = ops->get_temperature(sc); 2239 2456 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d\n", 2240 2457 __func__, temp); 2241 2458 2242 /* Update TX power if need be (4965AGN only .)*/2459 /* Update TX power if need be (4965AGN only). */ 2243 2460 if (sc->hw_type == IWN_HW_REV_TYPE_4965) 2244 2461 iwn4965_power_calibration(sc, temp); 2245 2462 } … … iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt, 2355 2572 /* 2356 2573 * Update rate control statistics for the node. 2357 2574 */ 2358 if (status & 0x80) {2575 if (status & IWN_TX_FAIL) { 2359 2576 ifp->if_oerrors++; 2360 2577 ieee80211_ratectl_tx_complete(vap, ni, 2361 2578 IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL); 2362 2579 } else { 2580 ifp->if_opackets++; 2363 2581 ieee80211_ratectl_tx_complete(vap, ni, 2364 2582 IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL); 2365 2583 } … … iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc) 2394 2612 2395 2613 /* If the command was mapped in an mbuf, free it. */ 2396 2614 if (data->m != NULL) { 2615 bus_dmamap_sync(ring->data_dmat, data->map, 2616 BUS_DMASYNC_POSTWRITE); 2397 2617 bus_dmamap_unload(ring->data_dmat, data->map); 2398 2618 m_freem(data->m); 2399 2619 data->m = NULL; … … iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc) 2407 2627 static void 2408 2628 iwn_notif_intr(struct iwn_softc *sc) 2409 2629 { 2630 struct iwn_ops *ops = &sc->ops; 2410 2631 struct ifnet *ifp = sc->sc_ifp; 2411 2632 struct ieee80211com *ic = ifp->if_l2com; 2412 2633 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); … … iwn_notif_intr(struct iwn_softc *sc) 2453 2674 2454 2675 case IWN_TX_DONE: 2455 2676 /* An 802.11 frame has been transmitted. */ 2456 sc->sc_hal->tx_done(sc, desc, data);2677 ops->tx_done(sc, desc, data); 2457 2678 break; 2458 2679 2459 2680 case IWN_RX_STATISTICS: … … iwn_notif_intr(struct iwn_softc *sc) 2471 2692 BUS_DMASYNC_POSTREAD); 2472 2693 misses = le32toh(miss->consecutive); 2473 2694 2474 /* XXX not sure why we're notified w/ zero */2475 if (misses == 0)2476 break;2477 2695 DPRINTF(sc, IWN_DEBUG_STATE, 2478 2696 "%s: beacons missed %d/%d\n", __func__, 2479 2697 misses, le32toh(miss->total)); 2480 2481 2698 /* 2482 2699 * If more than 5 consecutive beacons are missed, 2483 2700 * reinitialize the sensitivity state machine. 2484 2701 */ 2485 if (vap->iv_state == IEEE80211_S_RUN && misses > 5) 2486 (void) iwn_init_sensitivity(sc); 2487 if (misses >= vap->iv_bmissthreshold) { 2488 IWN_UNLOCK(sc); 2489 ieee80211_beacon_miss(ic); 2490 IWN_LOCK(sc); 2702 if (vap->iv_state == IEEE80211_S_RUN && 2703 (ic->ic_flags & IEEE80211_F_SCAN) == 0) { 2704 if (misses > 5) 2705 (void)iwn_init_sensitivity(sc); 2706 if (misses >= vap->iv_bmissthreshold) { 2707 IWN_UNLOCK(sc); 2708 ieee80211_beacon_miss(ic); 2709 IWN_LOCK(sc); 2710 } 2491 2711 } 2492 2712 break; 2493 2713 } … … iwn_notif_intr(struct iwn_softc *sc) 2561 2781 break; 2562 2782 } 2563 2783 case IWN5000_CALIBRATION_RESULT: 2564 iwn5000_rx_calib_result (sc, desc, data);2784 iwn5000_rx_calib_results(sc, desc, data); 2565 2785 break; 2566 2786 2567 2787 case IWN5000_CALIBRATION_DONE: … … iwn_wakeup_intr(struct iwn_softc *sc) 2592 2812 2593 2813 /* Wakeup RX and TX rings. */ 2594 2814 IWN_WRITE(sc, IWN_FH_RX_WPTR, sc->rxq.cur & ~7); 2595 for (qid = 0; qid < sc-> sc_hal->ntxqs; qid++) {2815 for (qid = 0; qid < sc->ntxqs; qid++) { 2596 2816 struct iwn_tx_ring *ring = &sc->txq[qid]; 2597 2817 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | ring->cur); 2598 2818 } … … iwn_rftoggle_intr(struct iwn_softc *sc) 2623 2843 static void 2624 2844 iwn_fatal_intr(struct iwn_softc *sc) 2625 2845 { 2626 const struct iwn_hal *hal = sc->sc_hal;2627 2846 struct iwn_fw_dump dump; 2628 2847 int i; 2629 2848 … … iwn_fatal_intr(struct iwn_softc *sc) 2635 2854 /* Check that the error log address is valid. */ 2636 2855 if (sc->errptr < IWN_FW_DATA_BASE || 2637 2856 sc->errptr + sizeof (dump) > 2638 IWN_FW_DATA_BASE + hal->fw_data_maxsz) {2639 printf("%s: bad firmware error log address 0x%08x\n", 2640 __func__,sc->errptr);2857 IWN_FW_DATA_BASE + sc->fw_data_maxsz) { 2858 printf("%s: bad firmware error log address 0x%08x\n", __func__, 2859 sc->errptr); 2641 2860 return; 2642 2861 } 2643 2862 if (iwn_nic_lock(sc) != 0) { 2644 printf("%s: could not read firmware error log\n", 2645 __func__); 2863 printf("%s: could not read firmware error log\n", __func__); 2646 2864 return; 2647 2865 } 2648 2866 /* Read firmware error log from SRAM. */ … … iwn_fatal_intr(struct iwn_softc *sc) 2651 2869 iwn_nic_unlock(sc); 2652 2870 2653 2871 if (dump.valid == 0) { 2654 printf("%s: firmware error log is empty\n", 2655 __func__); 2872 printf("%s: firmware error log is empty\n", __func__); 2656 2873 return; 2657 2874 } 2658 2875 printf("firmware error log:\n"); … … iwn_fatal_intr(struct iwn_softc *sc) 2672 2889 2673 2890 /* Dump driver status (TX and RX rings) while we're here. */ 2674 2891 printf("driver status:\n"); 2675 for (i = 0; i < hal->ntxqs; i++) {2892 for (i = 0; i < sc->ntxqs; i++) { 2676 2893 struct iwn_tx_ring *ring = &sc->txq[i]; 2677 2894 printf(" tx ring %2d: qid=%-2d cur=%-3d queued=%-3d\n", 2678 2895 i, ring->qid, ring->cur, ring->queued); … … iwn_intr(void *arg) 2733 2950 __func__); 2734 2951 } 2735 2952 if (r1 & (IWN_INT_SW_ERR | IWN_INT_HW_ERR)) { 2953 device_printf(sc->sc_dev, "%s: fatal firmware error\n", 2954 __func__); 2955 /* Dump firmware error log and stop. */ 2736 2956 iwn_fatal_intr(sc); 2737 2957 ifp->if_flags &= ~IFF_UP; 2738 2958 iwn_stop_locked(sc); … … done: 2776 2996 2777 2997 /* 2778 2998 * Update TX scheduler ring when transmitting an 802.11 frame (4965AGN and 2779 * 5000 adapters use a slightly different format .)2999 * 5000 adapters use a slightly different format). 2780 3000 */ 2781 3001 static void 2782 3002 iwn4965_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id, … … iwn5000_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id, 2801 3021 uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx]; 2802 3022 2803 3023 *w = htole16(id << 12 | (len + 8)); 2804 2805 3024 bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map, 2806 3025 BUS_DMASYNC_PREWRITE); 2807 3026 if (idx < IWN_SCHED_WINSZ) { … … iwn_plcp_signal(int rate) { 2833 3052 int i; 2834 3053 2835 3054 for (i = 0; i < IWN_RIDX_MAX + 1; i++) { 2836 if ( rate== iwn_rates[i].rate)3055 if ((rate & IEEE80211_RATE_VAL) == iwn_rates[i].rate) 2837 3056 return i; 2838 3057 } 2839 3058 … … iwn_plcp_signal(int rate) { 2841 3060 } 2842 3061 2843 3062 static int 2844 iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 2845 struct iwn_tx_ring *ring) 3063 iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) 2846 3064 { 2847 const struct iwn_hal *hal = sc->sc_hal;2848 3065 const struct ieee80211_txparam *tp; 2849 const struct iwn_rate *rinfo;2850 3066 struct ieee80211vap *vap = ni->ni_vap; 2851 3067 struct ieee80211com *ic = ni->ni_ic; 2852 3068 struct iwn_node *wn = (void *)ni; 3069 struct iwn_tx_ring *ring; 2853 3070 struct iwn_tx_desc *desc; 2854 3071 struct iwn_tx_data *data; 2855 3072 struct iwn_tx_cmd *cmd; 2856 3073 struct iwn_cmd_data *tx; 3074 const struct iwn_rate *rinfo; 2857 3075 struct ieee80211_frame *wh; 2858 3076 struct ieee80211_key *k = NULL; 2859 struct mbuf *mnew; 2860 bus_dma_segment_t segs[IWN_MAX_SCATTER]; 3077 struct mbuf *m1; 2861 3078 uint32_t flags; 3079 uint16_t qos; 2862 3080 u_int hdrlen; 2863 int totlen, error, pad, nsegs = 0, i, rate; 2864 uint8_t ridx, type, txant; 3081 bus_dma_segment_t *seg, segs[IWN_MAX_SCATTER]; 3082 uint8_t tid, ridx, txant, type; 3083 int ac, i, totlen, error, pad, nsegs = 0, rate; 2865 3084 2866 3085 IWN_LOCK_ASSERT(sc); 2867 3086 … … iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 2869 3088 hdrlen = ieee80211_anyhdrsize(wh); 2870 3089 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 2871 3090 3091 /* Select EDCA Access Category and TX ring for this frame. */ 3092 if (IEEE80211_QOS_HAS_SEQ(wh)) { 3093 qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0]; 3094 tid = qos & IEEE80211_QOS_TID; 3095 } else { 3096 qos = 0; 3097 tid = 0; 3098 } 3099 ac = M_WME_GETAC(m); 3100 3101 ring = &sc->txq[ac]; 2872 3102 desc = &ring->desc[ring->cur]; 2873 3103 data = &ring->data[ring->cur]; 2874 3104 … … iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 2890 3120 2891 3121 /* Encrypt the frame if need be. */ 2892 3122 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 3123 /* Retrieve key for TX. */ 2893 3124 k = ieee80211_crypto_encap(ni, m); 2894 3125 if (k == NULL) { 2895 3126 m_freem(m); 2896 3127 return ENOBUFS; 2897 3128 } 2898 /* Packet header may have moved, reset our local pointer. */3129 /* 802.11 header may have moved. */ 2899 3130 wh = mtod(m, struct ieee80211_frame *); 2900 3131 } 2901 3132 totlen = m->m_pkthdr.len; … … iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 2923 3154 tx->scratch = 0; /* clear "scratch" area */ 2924 3155 2925 3156 flags = 0; 2926 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) 2927 flags |= IWN_TX_NEED_ACK; 3157 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 3158 /* Unicast frame, check if an ACK is expected. */ 3159 if (!qos || (qos & IEEE80211_QOS_ACKPOLICY) != 3160 IEEE80211_QOS_ACKPOLICY_NOACK) 3161 flags |= IWN_TX_NEED_ACK; 3162 } 2928 3163 if ((wh->i_fc[0] & 2929 3164 (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == 2930 3165 (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR)) … … iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 2957 3192 2958 3193 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 2959 3194 type != IEEE80211_FC0_TYPE_DATA) 2960 tx->id = hal->broadcast_id;3195 tx->id = sc->broadcast_id; 2961 3196 else 2962 3197 tx->id = wn->id; 2963 3198 … … iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 2967 3202 /* Tell HW to set timestamp in probe responses. */ 2968 3203 if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) 2969 3204 flags |= IWN_TX_INSERT_TSTAMP; 2970 2971 3205 if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ || 2972 3206 subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) 2973 3207 tx->timeout = htole16(3); … … iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 2984 3218 pad = 0; 2985 3219 2986 3220 tx->len = htole16(totlen); 2987 tx->tid = 0;3221 tx->tid = tid; 2988 3222 tx->rts_ntries = 60; 2989 3223 tx->data_ntries = 15; 2990 3224 tx->lifetime = htole32(IWN_LIFETIME_INFINITE); 2991 3225 tx->plcp = rinfo->plcp; 2992 3226 tx->rflags = rinfo->flags; 2993 if (tx->id == hal->broadcast_id) {3227 if (tx->id == sc->broadcast_id) { 2994 3228 /* Group or management frame. */ 2995 3229 tx->linkq = 0; 2996 3230 /* XXX Alternate between antenna A and B? */ 2997 3231 txant = IWN_LSB(sc->txchainmask); 2998 3232 tx->rflags |= IWN_RFLAG_ANT(txant); 2999 3233 } else { 3000 tx->linkq = IWN_RIDX_OFDM54 - ridx;3234 tx->linkq = ni->ni_rates.rs_nrates - ridx - 1; 3001 3235 flags |= IWN_TX_LINKQ; /* enable MRR */ 3002 3236 } 3003 3004 3237 /* Set physical address of "scratch area". */ 3005 3238 tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr)); 3006 3239 tx->hiaddr = IWN_HIADDR(data->scratch_paddr); … … iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 3013 3246 tx->security = 0; 3014 3247 tx->flags = htole32(flags); 3015 3248 3016 if (m->m_len > 0) { 3017 error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, 3018 m, segs, &nsegs, BUS_DMA_NOWAIT); 3019 if (error == EFBIG) { 3020 /* too many fragments, linearize */ 3021 mnew = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER); 3022 if (mnew == NULL) { 3023 device_printf(sc->sc_dev, 3024 "%s: could not defrag mbuf\n", __func__); 3025 m_freem(m); 3026 return ENOBUFS; 3027 } 3028 m = mnew; 3029 error = bus_dmamap_load_mbuf_sg(ring->data_dmat, 3030 data->map, m, segs, &nsegs, BUS_DMA_NOWAIT); 3249 error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, segs, 3250 &nsegs, BUS_DMA_NOWAIT); 3251 if (error != 0) { 3252 if (error != EFBIG) { 3253 device_printf(sc->sc_dev, 3254 "%s: can't map mbuf (error %d)\n", __func__, error); 3255 m_freem(m); 3256 return error; 3257 } 3258 /* Too many DMA segments, linearize mbuf. */ 3259 m1 = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER); 3260 if (m1 == NULL) { 3261 device_printf(sc->sc_dev, 3262 "%s: could not defrag mbuf\n", __func__); 3263 m_freem(m); 3264 return ENOBUFS; 3031 3265 } 3266 m = m1; 3267 3268 error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, 3269 segs, &nsegs, BUS_DMA_NOWAIT); 3032 3270 if (error != 0) { 3033 3271 device_printf(sc->sc_dev, 3034 "%s: bus_dmamap_load_mbuf_sg failed, error %d\n", 3035 __func__, error); 3272 "%s: can't map mbuf (error %d)\n", __func__, error); 3036 3273 m_freem(m); 3037 3274 return error; 3038 3275 } … … iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 3045 3282 __func__, ring->qid, ring->cur, m->m_pkthdr.len, nsegs); 3046 3283 3047 3284 /* Fill TX descriptor. */ 3048 desc->nsegs = 1 + nsegs; 3285 desc->nsegs = 1; 3286 if (m->m_len != 0) 3287 desc->nsegs += nsegs; 3049 3288 /* First DMA segment is used by the TX command. */ 3050 3289 desc->segs[0].addr = htole32(IWN_LOADDR(data->cmd_paddr)); 3051 3290 desc->segs[0].len = htole16(IWN_HIADDR(data->cmd_paddr) | 3052 3291 (4 + sizeof (*tx) + hdrlen + pad) << 4); 3053 3292 /* Other DMA segments are for data payload. */ 3293 seg = &segs[0]; 3054 3294 for (i = 1; i <= nsegs; i++) { 3055 desc->segs[i].addr = htole32(IWN_LOADDR(segs[i - 1].ds_addr)); 3056 desc->segs[i].len = htole16(IWN_HIADDR(segs[i - 1].ds_addr) | 3057 segs[i - 1].ds_len << 4); 3295 desc->segs[i].addr = htole32(IWN_LOADDR(seg->ds_addr)); 3296 desc->segs[i].len = htole16(IWN_HIADDR(seg->ds_addr) | 3297 seg->ds_len << 4); 3298 seg++; 3058 3299 } 3059 3300 3060 3301 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE); … … iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 3065 3306 3066 3307 #ifdef notyet 3067 3308 /* Update TX scheduler. */ 3068 hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);3309 ops->update_sched(sc, ring->qid, ring->cur, tx->id, totlen); 3069 3310 #endif 3070 3311 3071 3312 /* Kick TX ring. */ … … iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 3081 3322 3082 3323 static int 3083 3324 iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m, 3084 struct ieee80211_node *ni, struct iwn_tx_ring *ring, 3085 const struct ieee80211_bpf_params *params) 3325 struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) 3086 3326 { 3087 const struct iwn_hal *hal = sc->sc_hal;3088 3327 const struct iwn_rate *rinfo; 3089 3328 struct ifnet *ifp = sc->sc_ifp; 3090 3329 struct ieee80211vap *vap = ni->ni_vap; … … iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m, 3092 3331 struct iwn_tx_cmd *cmd; 3093 3332 struct iwn_cmd_data *tx; 3094 3333 struct ieee80211_frame *wh; 3334 struct iwn_tx_ring *ring; 3095 3335 struct iwn_tx_desc *desc; 3096 3336 struct iwn_tx_data *data; 3097 struct mbuf *mnew; 3098 bus_addr_t paddr; 3099 bus_dma_segment_t segs[IWN_MAX_SCATTER]; 3337 struct mbuf *m1; 3338 bus_dma_segment_t *seg, segs[IWN_MAX_SCATTER]; 3100 3339 uint32_t flags; 3101 3340 u_int hdrlen; 3102 int totlen, error, pad, nsegs = 0, i, rate;3341 int ac, totlen, error, pad, nsegs = 0, i, rate; 3103 3342 uint8_t ridx, type, txant; 3104 3343 3105 3344 IWN_LOCK_ASSERT(sc); … … iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m, 3108 3347 hdrlen = ieee80211_anyhdrsize(wh); 3109 3348 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 3110 3349 3350 ac = params->ibp_pri & 3; 3351 3352 ring = &sc->txq[ac]; 3111 3353 desc = &ring->desc[ring->cur]; 3112 3354 data = &ring->data[ring->cur]; 3113 3355 … … iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m, 3156 3398 if (type == IEEE80211_FC0_TYPE_MGT) { 3157 3399 uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 3158 3400 3401 /* Tell HW to set timestamp in probe responses. */ 3159 3402 if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) 3160 3403 flags |= IWN_TX_INSERT_TSTAMP; 3161 3404 … … iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m, 3185 3428 3186 3429 tx->len = htole16(totlen); 3187 3430 tx->tid = 0; 3188 tx->id = hal->broadcast_id;3431 tx->id = sc->broadcast_id; 3189 3432 tx->rts_ntries = params->ibp_try1; 3190 3433 tx->data_ntries = params->ibp_try0; 3191 3434 tx->lifetime = htole32(IWN_LIFETIME_INFINITE); … … iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m, 3196 3439 txant = IWN_LSB(sc->txchainmask); 3197 3440 tx->rflags |= IWN_RFLAG_ANT(txant); 3198 3441 /* Set physical address of "scratch area". */ 3199 paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd); 3200 tx->loaddr = htole32(IWN_LOADDR(paddr)); 3201 tx->hiaddr = IWN_HIADDR(paddr); 3442 tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr)); 3443 tx->hiaddr = IWN_HIADDR(data->scratch_paddr); 3202 3444 3203 3445 /* Copy 802.11 header in TX command. */ 3204 3446 memcpy((uint8_t *)(tx + 1), wh, hdrlen); … … iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m, 3208 3450 tx->security = 0; 3209 3451 tx->flags = htole32(flags); 3210 3452 3211 if (m->m_len > 0) { 3212 error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, 3213 m, segs, &nsegs, BUS_DMA_NOWAIT); 3214 if (error == EFBIG) { 3215 /* Too many fragments, linearize. */ 3216 mnew = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER); 3217 if (mnew == NULL) { 3218 device_printf(sc->sc_dev, 3219 "%s: could not defrag mbuf\n", __func__); 3220 m_freem(m); 3221 return ENOBUFS; 3222 } 3223 m = mnew; 3224 error = bus_dmamap_load_mbuf_sg(ring->data_dmat, 3225 data->map, m, segs, &nsegs, BUS_DMA_NOWAIT); 3453 error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, segs, 3454 &nsegs, BUS_DMA_NOWAIT); 3455 if (error != 0) { 3456 if (error != EFBIG) { 3457 device_printf(sc->sc_dev, 3458 "%s: can't map mbuf (error %d)\n", __func__, error); 3459 m_freem(m); 3460 return error; 3461 } 3462 /* Too many DMA segments, linearize mbuf. */ 3463 m1 = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER); 3464 if (m1 == NULL) { 3465 device_printf(sc->sc_dev, 3466 "%s: could not defrag mbuf\n", __func__); 3467 m_freem(m); 3468 return ENOBUFS; 3226 3469 } 3470 m = m1; 3471 3472 error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, 3473 segs, &nsegs, BUS_DMA_NOWAIT); 3227 3474 if (error != 0) { 3228 3475 device_printf(sc->sc_dev, 3229 "%s: bus_dmamap_load_mbuf_sg failed, error %d\n", 3230 __func__, error); 3476 "%s: can't map mbuf (error %d)\n", __func__, error); 3231 3477 m_freem(m); 3232 3478 return error; 3233 3479 } … … iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m, 3240 3486 __func__, ring->qid, ring->cur, m->m_pkthdr.len, nsegs); 3241 3487 3242 3488 /* Fill TX descriptor. */ 3243 desc->nsegs = 1 + nsegs; 3489 desc->nsegs = 1; 3490 if (m->m_len != 0) 3491 desc->nsegs += nsegs; 3244 3492 /* First DMA segment is used by the TX command. */ 3245 3493 desc->segs[0].addr = htole32(IWN_LOADDR(data->cmd_paddr)); 3246 3494 desc->segs[0].len = htole16(IWN_HIADDR(data->cmd_paddr) | 3247 3495 (4 + sizeof (*tx) + hdrlen + pad) << 4); 3248 3496 /* Other DMA segments are for data payload. */ 3497 seg = &segs[0]; 3249 3498 for (i = 1; i <= nsegs; i++) { 3250 desc->segs[i].addr = htole32(IWN_LOADDR(segs[i - 1].ds_addr)); 3251 desc->segs[i].len = htole16(IWN_HIADDR(segs[i - 1].ds_addr) | 3252 segs[i - 1].ds_len << 4); 3499 desc->segs[i].addr = htole32(IWN_LOADDR(seg->ds_addr)); 3500 desc->segs[i].len = htole16(IWN_HIADDR(seg->ds_addr) | 3501 seg->ds_len << 4); 3502 seg++; 3253 3503 } 3254 3504 3255 3505 bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE); … … iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m, 3260 3510 3261 3511 #ifdef notyet 3262 3512 /* Update TX scheduler. */ 3263 hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);3513 ops->update_sched(sc, ring->qid, ring->cur, tx->id, totlen); 3264 3514 #endif 3265 3515 3266 3516 /* Kick TX ring. */ … … iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m, 3276 3526 3277 3527 static int 3278 3528 iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 3279 3529 const struct ieee80211_bpf_params *params) 3280 3530 { 3281 3531 struct ieee80211com *ic = ni->ni_ic; 3282 3532 struct ifnet *ifp = ic->ic_ifp; 3283 3533 struct iwn_softc *sc = ifp->if_softc; 3284 struct iwn_tx_ring *txq;3285 3534 int error = 0; 3286 3535 3287 3536 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { … … iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 3291 3540 } 3292 3541 3293 3542 IWN_LOCK(sc); 3294 if (params == NULL)3295 txq = &sc->txq[M_WME_GETAC(m)];3296 else3297 txq = &sc->txq[params->ibp_pri & 3];3298 3299 3543 if (params == NULL) { 3300 3544 /* 3301 3545 * Legacy path; interpret frame contents to decide 3302 3546 * precisely how to send the frame. 3303 3547 */ 3304 error = iwn_tx_data(sc, m, ni , txq);3548 error = iwn_tx_data(sc, m, ni); 3305 3549 } else { 3306 3550 /* 3307 3551 * Caller supplied explicit parameters to use in 3308 3552 * sending the frame. 3309 3553 */ 3310 error = iwn_tx_data_raw(sc, m, ni, txq,params);3554 error = iwn_tx_data_raw(sc, m, ni, params); 3311 3555 } 3312 3556 if (error != 0) { 3313 3557 /* NB: m is reclaimed on tx failure */ 3314 3558 ieee80211_free_node(ni); 3315 3559 ifp->if_oerrors++; 3316 3560 } 3561 sc->sc_tx_timer = 5; 3562 3317 3563 IWN_UNLOCK(sc); 3318 3564 return error; 3319 3565 } … … iwn_start_locked(struct ifnet *ifp) 3333 3579 { 3334 3580 struct iwn_softc *sc = ifp->if_softc; 3335 3581 struct ieee80211_node *ni; 3336 struct iwn_tx_ring *txq;3337 3582 struct mbuf *m; 3338 int pri;3339 3583 3340 3584 IWN_LOCK_ASSERT(sc); 3341 3585 3586 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 3587 (ifp->if_drv_flags & IFF_DRV_OACTIVE)) 3588 return; 3589 3342 3590 for (;;) { 3343 3591 if (sc->qfullmsk != 0) { 3344 3592 ifp->if_drv_flags |= IFF_DRV_OACTIVE; … … iwn_start_locked(struct ifnet *ifp) 3348 3596 if (m == NULL) 3349 3597 break; 3350 3598 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 3351 pri = M_WME_GETAC(m); 3352 txq = &sc->txq[pri]; 3353 if (iwn_tx_data(sc, m, ni, txq) != 0) { 3354 ifp->if_oerrors++; 3599 if (iwn_tx_data(sc, m, ni) != 0) { 3355 3600 ieee80211_free_node(ni); 3356 break; 3601 ifp->if_oerrors++; 3602 continue; 3357 3603 } 3358 3604 sc->sc_tx_timer = 5; 3359 3605 } 3360 3606 } 3361 3607 3362 3608 static void 3363 iwn_watchdog( struct iwn_softc *sc)3609 iwn_watchdog(void *arg) 3364 3610 { 3365 if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { 3366 struct ifnet *ifp = sc->sc_ifp; 3367 struct ieee80211com *ic = ifp->if_l2com; 3611 struct iwn_softc *sc = arg; 3612 struct ifnet *ifp = sc->sc_ifp; 3613 struct ieee80211com *ic = ifp->if_l2com; 3614 3615 IWN_LOCK_ASSERT(sc); 3616 3617 KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); 3368 3618 3369 if_printf(ifp, "device timeout\n"); 3370 ieee80211_runtask(ic, &sc->sc_reinit_task); 3619 if (sc->sc_tx_timer > 0) { 3620 if (--sc->sc_tx_timer == 0) { 3621 if_printf(ifp, "device timeout\n"); 3622 ieee80211_runtask(ic, &sc->sc_reinit_task); 3623 return; 3624 } 3371 3625 } 3626 callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc); 3372 3627 } 3373 3628 3374 3629 static int … … iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 3381 3636 int error = 0, startall = 0, stop = 0; 3382 3637 3383 3638 switch (cmd) { 3639 case SIOCGIFADDR: 3640 error = ether_ioctl(ifp, cmd, data); 3641 break; 3384 3642 case SIOCSIFFLAGS: 3385 3643 IWN_LOCK(sc); 3386 3644 if (ifp->if_flags & IFF_UP) { … … iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 3404 3662 case SIOCGIFMEDIA: 3405 3663 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 3406 3664 break; 3407 case SIOCGIFADDR:3408 error = ether_ioctl(ifp, cmd, data);3409 break;3410 3665 default: 3411 3666 error = EINVAL; 3412 3667 break; … … iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async) 3480 3735 3481 3736 #ifdef notyet 3482 3737 /* Update TX scheduler. */ 3483 sc->sc_hal->update_sched(sc, ring->qid, ring->cur, 0, 0);3738 ops->update_sched(sc, ring->qid, ring->cur, 0, 0); 3484 3739 #endif 3485 3740 3486 3741 /* Kick command ring. */ … … iwn5000_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async) 3516 3771 return iwn_cmd(sc, IWN_CMD_ADD_NODE, node, sizeof (*node), async); 3517 3772 } 3518 3773 3519 #if 0 /* HT */3520 static const uint8_t iwn_ridx_to_plcp[] = {3521 10, 20, 55, 110, /* CCK */3522 0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */3523 };3524 static const uint8_t iwn_siso_mcs_to_plcp[] = {3525 0, 0, 0, 0, /* CCK */3526 0, 0, 1, 2, 3, 4, 5, 6, 7 /* HT */3527 };3528 static const uint8_t iwn_mimo_mcs_to_plcp[] = {3529 0, 0, 0, 0, /* CCK */3530 8, 8, 9, 10, 11, 12, 13, 14, 15 /* HT */3531 };3532 #endif3533 static const uint8_t iwn_prev_ridx[] = {3534 /* NB: allow fallback from CCK11 to OFDM9 and from OFDM6 to CCK5 */3535 0, 0, 1, 5, /* CCK */3536 2, 4, 3, 6, 7, 8, 9, 10, 10 /* OFDM */3537 };3538 3539 /*3540 * Configure hardware link parameters for the specified3541 * node operating on the specified channel.3542 */3543 3774 static int 3544 iwn_set_link_quality(struct iwn_softc *sc, uint8_t id, int async)3775 iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni) 3545 3776 { 3546 struct i fnet *ifp = sc->sc_ifp;3547 struct ieee80211 com *ic = ifp->if_l2com;3777 struct iwn_node *wn = (void *)ni; 3778 struct ieee80211_rateset *rs = &ni->ni_rates; 3548 3779 struct iwn_cmd_link_quality linkq; 3549 3780 const struct iwn_rate *rinfo; 3550 int i;3551 uint8_t txant, ridx;3781 uint8_t txant; 3782 int i, txrate; 3552 3783 3553 3784 /* Use the first valid TX antenna. */ 3554 3785 txant = IWN_LSB(sc->txchainmask); 3555 3786 3556 3787 memset(&linkq, 0, sizeof linkq); 3557 linkq.id = id;3788 linkq.id = wn->id; 3558 3789 linkq.antmsk_1stream = txant; 3559 3790 linkq.antmsk_2stream = IWN_ANT_AB; 3560 3791 linkq.ampdu_max = 31; 3561 3792 linkq.ampdu_threshold = 3; 3562 3793 linkq.ampdu_limit = htole16(4000); /* 4ms */ 3563 3794 3564 #if 0 /* HT */ 3565 if (IEEE80211_IS_CHAN_HT(c)) 3566 linkq.mimo = 1; 3567 #endif 3568 3569 if (id == IWN_ID_BSS) 3570 ridx = IWN_RIDX_OFDM54; 3571 else if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) 3572 ridx = IWN_RIDX_OFDM6; 3573 else 3574 ridx = IWN_RIDX_CCK1; 3575 3795 /* Start at highest available bit-rate. */ 3796 txrate = rs->rs_nrates - 1; 3576 3797 for (i = 0; i < IWN_MAX_TX_RETRIES; i++) { 3577 rinfo = &iwn_rates[ridx]; 3578 #if 0 /* HT */ 3579 if (IEEE80211_IS_CHAN_HT40(c)) { 3580 linkq.retry[i].plcp = iwn_mimo_mcs_to_plcp[ridx] 3581 | IWN_RIDX_MCS; 3582 linkq.retry[i].rflags = IWN_RFLAG_HT 3583 | IWN_RFLAG_HT40; 3584 /* XXX shortGI */ 3585 } else if (IEEE80211_IS_CHAN_HT(c)) { 3586 linkq.retry[i].plcp = iwn_siso_mcs_to_plcp[ridx] 3587 | IWN_RIDX_MCS; 3588 linkq.retry[i].rflags = IWN_RFLAG_HT; 3589 /* XXX shortGI */ 3590 } else 3591 #endif 3592 { 3593 linkq.retry[i].plcp = rinfo->plcp; 3594 linkq.retry[i].rflags = rinfo->flags; 3595 } 3798 rinfo = &iwn_rates[wn->ridx[txrate]]; 3799 linkq.retry[i].plcp = rinfo->plcp; 3800 linkq.retry[i].rflags = rinfo->flags; 3596 3801 linkq.retry[i].rflags |= IWN_RFLAG_ANT(txant); 3597 ridx = iwn_prev_ridx[ridx]; 3598 } 3599 #ifdef IWN_DEBUG 3600 if (sc->sc_debug & IWN_DEBUG_STATE) { 3601 printf("%s: set link quality for node %d, mimo %d ssmask %d\n", 3602 __func__, id, linkq.mimo, linkq.antmsk_1stream); 3603 printf("%s:", __func__); 3604 for (i = 0; i < IWN_MAX_TX_RETRIES; i++) 3605 printf(" %d:%x", linkq.retry[i].plcp, 3606 linkq.retry[i].rflags); 3607 printf("\n"); 3802 /* Next retry at immediate lower bit-rate. */ 3803 if (txrate > 0) 3804 txrate--; 3608 3805 } 3609 #endif 3610 return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async); 3806 return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, 1); 3611 3807 } 3612 3808 3613 3809 /* … … iwn_set_link_quality(struct iwn_softc *sc, uint8_t id, int async) 3616 3812 static int 3617 3813 iwn_add_broadcast_node(struct iwn_softc *sc, int async) 3618 3814 { 3619 const struct iwn_hal *hal = sc->sc_hal;3815 struct iwn_ops *ops = &sc->ops; 3620 3816 struct ifnet *ifp = sc->sc_ifp; 3817 struct ieee80211com *ic = ifp->if_l2com; 3621 3818 struct iwn_node_info node; 3622 int error; 3819 struct iwn_cmd_link_quality linkq; 3820 const struct iwn_rate *rinfo; 3821 uint8_t txant; 3822 int i, error; 3623 3823 3624 3824 memset(&node, 0, sizeof node); 3625 3825 IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr); 3626 node.id = hal->broadcast_id;3826 node.id = sc->broadcast_id; 3627 3827 DPRINTF(sc, IWN_DEBUG_RESET, "%s: adding broadcast node\n", __func__); 3628 error = hal->add_node(sc, &node, async); 3629 if (error != 0) 3828 if ((error = ops->add_node(sc, &node, async)) != 0) 3630 3829 return error; 3631 3830 3632 error = iwn_set_link_quality(sc, hal->broadcast_id, async); 3633 return error; 3831 /* Use the first valid TX antenna. */ 3832 txant = IWN_LSB(sc->txchainmask); 3833 3834 memset(&linkq, 0, sizeof linkq); 3835 linkq.id = sc->broadcast_id; 3836 linkq.antmsk_1stream = txant; 3837 linkq.antmsk_2stream = IWN_ANT_AB; 3838 linkq.ampdu_max = 64; 3839 linkq.ampdu_threshold = 3; 3840 linkq.ampdu_limit = htole16(4000); /* 4ms */ 3841 3842 /* Use lowest mandatory bit-rate. */ 3843 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) 3844 rinfo = &iwn_rates[IWN_RIDX_OFDM6]; 3845 else 3846 rinfo = &iwn_rates[IWN_RIDX_CCK1]; 3847 linkq.retry[0].plcp = rinfo->plcp; 3848 linkq.retry[0].rflags = rinfo->flags; 3849 linkq.retry[0].rflags |= IWN_RFLAG_ANT(txant); 3850 /* Use same bit-rate for all TX retries. */ 3851 for (i = 1; i < IWN_MAX_TX_RETRIES; i++) { 3852 linkq.retry[i].plcp = linkq.retry[0].plcp; 3853 linkq.retry[i].rflags = linkq.retry[0].rflags; 3854 } 3855 return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async); 3634 3856 } 3635 3857 3636 3858 static int 3637 iwn_ wme_update(struct ieee80211com *ic)3859 iwn_updateedca(struct ieee80211com *ic) 3638 3860 { 3639 3861 #define IWN_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */ 3640 #define IWN_TXOP_TO_US(v) (v<<5)3641 3862 struct iwn_softc *sc = ic->ic_ifp->if_softc; 3642 3863 struct iwn_edca_params cmd; 3643 int i;3864 int aci; 3644 3865 3645 3866 memset(&cmd, 0, sizeof cmd); 3646 3867 cmd.flags = htole32(IWN_EDCA_UPDATE); 3647 for ( i = 0; i < WME_NUM_AC;i++) {3648 const struct wmeParams * wmep=3649 &ic->ic_wme.wme_chanParams.cap_wmeParams[ i];3650 cmd.ac[ i].aifsn = wmep->wmep_aifsn;3651 cmd.ac[ i].cwmin = htole16(IWN_EXP2(wmep->wmep_logcwmin));3652 cmd.ac[ i].cwmax = htole16(IWN_EXP2(wmep->wmep_logcwmax));3653 cmd.ac[ i].txoplimit =3654 htole16(I WN_TXOP_TO_US(wmep->wmep_txopLimit));3868 for (aci = 0; aci < WME_NUM_AC; aci++) { 3869 const struct wmeParams *ac = 3870 &ic->ic_wme.wme_chanParams.cap_wmeParams[aci]; 3871 cmd.ac[aci].aifsn = ac->wmep_aifsn; 3872 cmd.ac[aci].cwmin = htole16(IWN_EXP2(ac->wmep_logcwmin)); 3873 cmd.ac[aci].cwmax = htole16(IWN_EXP2(ac->wmep_logcwmax)); 3874 cmd.ac[aci].txoplimit = 3875 htole16(IEEE80211_TXOP_TO_US(ac->wmep_txopLimit)); 3655 3876 } 3656 3877 IEEE80211_UNLOCK(ic); 3657 3878 IWN_LOCK(sc); 3658 (void) iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1 /*async*/);3879 (void)iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1); 3659 3880 IWN_UNLOCK(sc); 3660 3881 IEEE80211_LOCK(ic); 3661 3882 return 0; 3662 #undef IWN_TXOP_TO_US3663 3883 #undef IWN_EXP2 3664 3884 } 3665 3885 … … iwn_set_critical_temp(struct iwn_softc *sc) 3704 3924 temp = 110; 3705 3925 memset(&crit, 0, sizeof crit); 3706 3926 crit.tempR = htole32(temp); 3707 DPRINTF(sc, IWN_DEBUG_RESET, "setting critical temp to %d\n", 3708 temp); 3927 DPRINTF(sc, IWN_DEBUG_RESET, "setting critical temp to %d\n", temp); 3709 3928 return iwn_cmd(sc, IWN_CMD_SET_CRITICAL_TEMP, &crit, sizeof crit, 0); 3710 3929 } 3711 3930 … … iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni) 3721 3940 cmd.lintval = htole16(10); 3722 3941 3723 3942 /* Compute remaining time until next beacon. */ 3724 val = (uint64_t)ni->ni_intval * 1024; /* msecs -> usecs */3943 val = (uint64_t)ni->ni_intval * IEEE80211_DUR_TU; 3725 3944 mod = le64toh(cmd.tstamp) % val; 3726 3945 cmd.binitval = htole32((uint32_t)(val - mod)); 3727 3946 … … iwn4965_power_calibration(struct iwn_softc *sc, int temp) 3737 3956 struct ifnet *ifp = sc->sc_ifp; 3738 3957 struct ieee80211com *ic = ifp->if_l2com; 3739 3958 3740 /* Adjust TX power if need be (delta >= 3 degC .)*/3959 /* Adjust TX power if need be (delta >= 3 degC). */ 3741 3960 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d->%d\n", 3742 3961 __func__, sc->temp, temp); 3743 3962 if (abs(temp - sc->temp) >= 3) { … … iwn4965_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch, 3764 3983 ((y1) + fdivround(((int)(x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n)) 3765 3984 3766 3985 static const int tdiv[IWN_NATTEN_GROUPS] = { 9, 8, 8, 8, 6 }; 3767 struct ifnet *ifp = sc->sc_ifp;3768 struct ieee80211com *ic = ifp->if_l2com;3769 3986 struct iwn_ucode_info *uc = &sc->ucode_info; 3770 3987 struct iwn4965_cmd_txpower cmd; 3771 3988 struct iwn4965_eeprom_chan_samples *chans; 3989 const uint8_t *rf_gain, *dsp_gain; 3772 3990 int32_t vdiff, tdiff; 3773 3991 int i, c, grp, maxpwr; 3774 const uint8_t *rf_gain, *dsp_gain;3775 3992 uint8_t chan; 3776 3993 3777 /* Retrieve c hannel number. */3778 chan = ieee80211_chan2ieee(ic, ch);3994 /* Retrieve current channel from last RXON. */ 3995 chan = sc->rxon.chan; 3779 3996 DPRINTF(sc, IWN_DEBUG_RESET, "setting TX power for channel %d\n", 3780 3997 chan); 3781 3998 … … iwn4965_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat) 3936 4153 agc = (le16toh(phy->agc) >> 7) & 0x7f; 3937 4154 3938 4155 rssi = 0; 3939 #if 0 3940 if (mask & IWN_ANT_A) /* Ant A */ 3941 rssi = max(rssi, phy->rssi[0]); 3942 if (mask & IWN_ATH_B) /* Ant B */ 3943 rssi = max(rssi, phy->rssi[2]); 3944 if (mask & IWN_ANT_C) /* Ant C */ 3945 rssi = max(rssi, phy->rssi[4]); 3946 #else 3947 rssi = max(rssi, phy->rssi[0]); 3948 rssi = max(rssi, phy->rssi[2]); 3949 rssi = max(rssi, phy->rssi[4]); 3950 #endif 3951 3952 DPRINTF(sc, IWN_DEBUG_RECV, "%s: agc %d mask 0x%x rssi %d %d %d " 3953 "result %d\n", __func__, agc, mask, 3954 phy->rssi[0], phy->rssi[2], phy->rssi[4], 4156 if (mask & IWN_ANT_A) 4157 rssi = MAX(rssi, phy->rssi[0]); 4158 if (mask & IWN_ANT_B) 4159 rssi = MAX(rssi, phy->rssi[2]); 4160 if (mask & IWN_ANT_C) 4161 rssi = MAX(rssi, phy->rssi[4]); 4162 4163 DPRINTF(sc, IWN_DEBUG_RECV, 4164 "%s: agc %d mask 0x%x rssi %d %d %d result %d\n", __func__, agc, 4165 mask, phy->rssi[0], phy->rssi[2], phy->rssi[4], 3955 4166 rssi - agc - IWN_RSSI_TO_DBM); 3956 4167 return rssi - agc - IWN_RSSI_TO_DBM; 3957 4168 } … … static int 3960 4171 iwn5000_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat) 3961 4172 { 3962 4173 struct iwn5000_rx_phystat *phy = (void *)stat->phybuf; 3963 int rssi;3964 4174 uint8_t agc; 4175 int rssi; 3965 4176 3966 4177 agc = (le32toh(phy->agc) >> 9) & 0x7f; 3967 4178 … … iwn5000_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat) 3969 4180 le16toh(phy->rssi[1]) & 0xff); 3970 4181 rssi = MAX(le16toh(phy->rssi[2]) & 0xff, rssi); 3971 4182 3972 DPRINTF(sc, IWN_DEBUG_RECV, "%s: agc %d rssi %d %d %d "3973 " result %d\n", __func__, agc,4183 DPRINTF(sc, IWN_DEBUG_RECV, 4184 "%s: agc %d rssi %d %d %d result %d\n", __func__, agc, 3974 4185 phy->rssi[0], phy->rssi[1], phy->rssi[2], 3975 4186 rssi - agc - IWN_RSSI_TO_DBM); 3976 4187 return rssi - agc - IWN_RSSI_TO_DBM; … … iwn4965_get_temperature(struct iwn_softc *sc) 4009 4220 r3 = le32toh(uc->temp[2].chan20MHz); 4010 4221 r4 = le32toh(sc->rawtemp); 4011 4222 4012 if (r1 == r3) /* Prevents division by 0 (should not happen .)*/4223 if (r1 == r3) /* Prevents division by 0 (should not happen). */ 4013 4224 return 0; 4014 4225 4015 4226 /* Sign-extend 23-bit R4 value to 32-bit. */ 4016 r4 = ( r4 << 8) >> 8;4227 r4 = ((r4 & 0xffffff) ^ 0x800000) - 0x800000; 4017 4228 /* Compute temperature in Kelvin. */ 4018 4229 temp = (259 * (r4 - r2)) / (r3 - r1); 4019 4230 temp = (temp * 97) / 100 + 8; … … iwn5000_get_temperature(struct iwn_softc *sc) 4030 4241 4031 4242 /* 4032 4243 * Temperature is not used by the driver for 5000 Series because 4033 * TX power calibration is handled by firmware. We export it to 4034 * users through the sensor framework though. 4244 * TX power calibration is handled by firmware. 4035 4245 */ 4036 4246 temp = le32toh(sc->rawtemp); 4037 4247 if (sc->hw_type == IWN_HW_REV_TYPE_5150) { … … iwn5000_get_temperature(struct iwn_softc *sc) 4047 4257 static int 4048 4258 iwn_init_sensitivity(struct iwn_softc *sc) 4049 4259 { 4050 const struct iwn_hal *hal = sc->sc_hal;4260 struct iwn_ops *ops = &sc->ops; 4051 4261 struct iwn_calib_state *calib = &sc->calib; 4052 4262 uint32_t flags; 4053 4263 int error; … … iwn_init_sensitivity(struct iwn_softc *sc) 4066 4276 calib->energy_cck = sc->limits->energy_cck; 4067 4277 4068 4278 /* Write initial sensitivity. */ 4069 error = iwn_send_sensitivity(sc); 4070 if (error != 0) 4279 if ((error = iwn_send_sensitivity(sc)) != 0) 4071 4280 return error; 4072 4281 4073 4282 /* Write initial gains. */ 4074 error = hal->init_gains(sc); 4075 if (error != 0) 4283 if ((error = ops->init_gains(sc)) != 0) 4076 4284 return error; 4077 4285 4078 4286 /* Request statistics at each beacon interval. */ 4079 4287 flags = 0; 4080 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: calibrate phy\n", __func__); 4288 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: sending request for statistics\n", 4289 __func__); 4081 4290 return iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags, sizeof flags, 1); 4082 4291 } 4083 4292 … … static void 4090 4299 iwn_collect_noise(struct iwn_softc *sc, 4091 4300 const struct iwn_rx_general_stats *stats) 4092 4301 { 4093 const struct iwn_hal *hal = sc->sc_hal;4302 struct iwn_ops *ops = &sc->ops; 4094 4303 struct iwn_calib_state *calib = &sc->calib; 4095 4304 uint32_t val; 4096 4305 int i; … … iwn_collect_noise(struct iwn_softc *sc, 4121 4330 if ((sc->chainmask & sc->txchainmask) == 0) 4122 4331 sc->chainmask |= IWN_LSB(sc->txchainmask); 4123 4332 4124 (void) hal->set_gains(sc);4333 (void)ops->set_gains(sc); 4125 4334 calib->state = IWN_CALIB_STATE_RUN; 4126 4335 4127 4336 #ifdef notyet 4128 4337 /* XXX Disable RX chains with no antennas connected. */ 4129 4338 sc->rxon.rxchain = htole16(IWN_RXCHAIN_SEL(sc->chainmask)); 4130 (void)iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1);4339 (void)iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1); 4131 4340 #endif 4132 4341 4133 4342 #if 0 … … iwn5000_init_gains(struct iwn_softc *sc) 4157 4366 struct iwn_phy_calib cmd; 4158 4367 4159 4368 memset(&cmd, 0, sizeof cmd); 4160 cmd.code = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;4369 cmd.code = sc->reset_noise_gain; 4161 4370 cmd.ngroups = 1; 4162 4371 cmd.isvalid = 1; 4163 4372 DPRINTF(sc, IWN_DEBUG_CALIBRATE, … … iwn5000_set_gains(struct iwn_softc *sc) 4203 4412 { 4204 4413 struct iwn_calib_state *calib = &sc->calib; 4205 4414 struct iwn_phy_calib_gain cmd; 4206 int i, ant, d elta, div;4415 int i, ant, div, delta; 4207 4416 4208 4417 /* We collected 20 beacons and !=6050 need a 1.5 factor. */ 4209 4418 div = (sc->hw_type == IWN_HW_REV_TYPE_6050) ? 20 : 30; 4210 4419 4211 4420 memset(&cmd, 0, sizeof cmd); 4212 cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN;4421 cmd.code = sc->noise_gain; 4213 4422 cmd.ngroups = 1; 4214 4423 cmd.isvalid = 1; 4215 4424 /* Get first available RX antenna as referential. */ … … iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats) 4264 4473 int i, needs_update = 0; 4265 4474 4266 4475 /* Check that we've been enabled long enough. */ 4267 rxena = le32toh(stats->general.load); 4268 if (rxena == 0) 4476 if ((rxena = le32toh(stats->general.load)) == 0) 4269 4477 return; 4270 4478 4271 4479 /* Compute number of false alarms since last call for OFDM. */ 4272 4480 fa = le32toh(stats->ofdm.bad_plcp) - calib->bad_plcp_ofdm; 4273 4481 fa += le32toh(stats->ofdm.fa) - calib->fa_ofdm; 4274 fa *= 200 * 1024; /* 200TU */4482 fa *= 200 * IEEE80211_DUR_TU; /* 200TU */ 4275 4483 4276 4484 /* Save counters values for next call. */ 4277 4485 calib->bad_plcp_ofdm = le32toh(stats->ofdm.bad_plcp); … … iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats) 4328 4536 /* Compute number of false alarms since last call for CCK. */ 4329 4537 fa = le32toh(stats->cck.bad_plcp) - calib->bad_plcp_cck; 4330 4538 fa += le32toh(stats->cck.fa) - calib->fa_cck; 4331 fa *= 200 * 1024; /* 200TU */4539 fa *= 200 * IEEE80211_DUR_TU; /* 200TU */ 4332 4540 4333 4541 /* Save counters values for next call. */ 4334 4542 calib->bad_plcp_cck = le32toh(stats->cck.bad_plcp); … … iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats) 4363 4571 4364 4572 if (calib->cck_state != IWN_CCK_STATE_INIT && 4365 4573 (((int32_t)calib->noise_ref - (int32_t)noise_ref) > 2 || 4366 calib->low_fa > 100)) {4574 calib->low_fa > 100)) { 4367 4575 inc(calib->energy_cck, 2, limits->min_energy_cck); 4368 4576 dec(calib->cck_x4, 3, limits->min_cck_x4); 4369 4577 dec(calib->cck_mrc_x4, 3, limits->min_cck_mrc_x4); … … static int 4392 4600 iwn_send_sensitivity(struct iwn_softc *sc) 4393 4601 { 4394 4602 struct iwn_calib_state *calib = &sc->calib; 4395 struct iwn_sensitivity_cmd cmd; 4603 struct iwn_enhanced_sensitivity_cmd cmd; 4604 int len; 4396 4605 4397 4606 memset(&cmd, 0, sizeof cmd); 4607 len = sizeof (struct iwn_sensitivity_cmd); 4398 4608 cmd.which = IWN_SENSITIVITY_WORKTBL; 4399 4609 /* OFDM modulation. */ 4400 cmd.corr_ofdm_x1 = htole16(calib->ofdm_x1);4401 cmd.corr_ofdm_mrc_x1 = htole16(calib->ofdm_mrc_x1);4402 cmd.corr_ofdm_x4 = htole16(calib->ofdm_x4);4403 cmd.corr_ofdm_mrc_x4 = htole16(calib->ofdm_mrc_x4);4404 cmd.energy_ofdm = htole16(sc->limits->energy_ofdm);4405 cmd.energy_ofdm_th = htole16(62);4610 cmd.corr_ofdm_x1 = htole16(calib->ofdm_x1); 4611 cmd.corr_ofdm_mrc_x1 = htole16(calib->ofdm_mrc_x1); 4612 cmd.corr_ofdm_x4 = htole16(calib->ofdm_x4); 4613 cmd.corr_ofdm_mrc_x4 = htole16(calib->ofdm_mrc_x4); 4614 cmd.energy_ofdm = htole16(sc->limits->energy_ofdm); 4615 cmd.energy_ofdm_th = htole16(62); 4406 4616 /* CCK modulation. */ 4407 cmd.corr_cck_x4 = htole16(calib->cck_x4);4408 cmd.corr_cck_mrc_x4 = htole16(calib->cck_mrc_x4);4409 cmd.energy_cck = htole16(calib->energy_cck);4617 cmd.corr_cck_x4 = htole16(calib->cck_x4); 4618 cmd.corr_cck_mrc_x4 = htole16(calib->cck_mrc_x4); 4619 cmd.energy_cck = htole16(calib->energy_cck); 4410 4620 /* Barker modulation: use default values. */ 4411 cmd.corr_barker = htole16(190);4412 cmd.corr_barker_mrc = htole16(390);4621 cmd.corr_barker = htole16(190); 4622 cmd.corr_barker_mrc = htole16(390); 4413 4623 4414 4624 DPRINTF(sc, IWN_DEBUG_CALIBRATE, 4415 4625 "%s: set sensitivity %d/%d/%d/%d/%d/%d/%d\n", __func__, 4416 4626 calib->ofdm_x1, calib->ofdm_mrc_x1, calib->ofdm_x4, 4417 4627 calib->ofdm_mrc_x4, calib->cck_x4, 4418 4628 calib->cck_mrc_x4, calib->energy_cck); 4419 return iwn_cmd(sc, IWN_CMD_SET_SENSITIVITY, &cmd, sizeof cmd, 1); 4629 4630 if (!(sc->sc_flags & IWN_FLAG_ENH_SENS)) 4631 goto send; 4632 /* Enhanced sensitivity settings. */ 4633 len = sizeof (struct iwn_enhanced_sensitivity_cmd); 4634 cmd.ofdm_det_slope_mrc = htole16(668); 4635 cmd.ofdm_det_icept_mrc = htole16(4); 4636 cmd.ofdm_det_slope = htole16(486); 4637 cmd.ofdm_det_icept = htole16(37); 4638 cmd.cck_det_slope_mrc = htole16(853); 4639 cmd.cck_det_icept_mrc = htole16(4); 4640 cmd.cck_det_slope = htole16(476); 4641 cmd.cck_det_icept = htole16(99); 4642 send: 4643 return iwn_cmd(sc, IWN_CMD_SET_SENSITIVITY, &cmd, len, 1); 4420 4644 } 4421 4645 4422 4646 /* … … iwn_send_sensitivity(struct iwn_softc *sc) 4426 4650 static int 4427 4651 iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async) 4428 4652 { 4429 const struct iwn_pmgt *pmgt;4430 4653 struct iwn_pmgt_cmd cmd; 4654 const struct iwn_pmgt *pmgt; 4431 4655 uint32_t max, skip_dtim; 4432 uint32_t tmp;4656 uint32_t reg; 4433 4657 int i; 4434 4658 4435 4659 /* Select which PS parameters to use. */ … … iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async) 4446 4670 if (level == 5) 4447 4671 cmd.flags |= htole16(IWN_PS_FAST_PD); 4448 4672 /* Retrieve PCIe Active State Power Management (ASPM). */ 4449 tmp= pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);4450 if (!( tmp& 0x1)) /* L0s Entry disabled. */4673 reg = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1); 4674 if (!(reg & 0x1)) /* L0s Entry disabled. */ 4451 4675 cmd.flags |= htole16(IWN_PS_PCI_PMGT); 4452 4676 cmd.rxtimeout = htole32(pmgt->rxtimeout * 1024); 4453 4677 cmd.txtimeout = htole32(pmgt->txtimeout * 1024); … … iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async) 4475 4699 } 4476 4700 4477 4701 static int 4702 iwn_send_btcoex(struct iwn_softc *sc) 4703 { 4704 struct iwn_bluetooth cmd; 4705 4706 memset(&cmd, 0, sizeof cmd); 4707 cmd.flags = IWN_BT_COEX_CHAN_ANN | IWN_BT_COEX_BT_PRIO; 4708 cmd.lead_time = IWN_BT_LEAD_TIME_DEF; 4709 cmd.max_kill = IWN_BT_MAX_KILL_DEF; 4710 DPRINTF(sc, IWN_DEBUG_RESET, "%s: configuring bluetooth coexistence\n", 4711 __func__); 4712 return iwn_cmd(sc, IWN_CMD_BT_COEX, &cmd, sizeof(cmd), 0); 4713 } 4714 4715 static int 4716 iwn_send_advanced_btcoex(struct iwn_softc *sc) 4717 { 4718 static const uint32_t btcoex_3wire[12] = { 4719 0xaaaaaaaa, 0xaaaaaaaa, 0xaeaaaaaa, 0xaaaaaaaa, 4720 0xcc00ff28, 0x0000aaaa, 0xcc00aaaa, 0x0000aaaa, 4721 0xc0004000, 0x00004000, 0xf0005000, 0xf0005000, 4722 }; 4723 struct iwn6000_btcoex_config btconfig; 4724 struct iwn_btcoex_priotable btprio; 4725 struct iwn_btcoex_prot btprot; 4726 int error, i; 4727 4728 memset(&btconfig, 0, sizeof btconfig); 4729 btconfig.flags = 145; 4730 btconfig.max_kill = 5; 4731 btconfig.bt3_t7_timer = 1; 4732 btconfig.kill_ack = htole32(0xffff0000); 4733 btconfig.kill_cts = htole32(0xffff0000); 4734 btconfig.sample_time = 2; 4735 btconfig.bt3_t2_timer = 0xc; 4736 for (i = 0; i < 12; i++) 4737 btconfig.lookup_table[i] = htole32(btcoex_3wire[i]); 4738 btconfig.valid = htole16(0xff); 4739 btconfig.prio_boost = 0xf0; 4740 DPRINTF(sc, IWN_DEBUG_RESET, 4741 "%s: configuring advanced bluetooth coexistence\n", __func__); 4742 error = iwn_cmd(sc, IWN_CMD_BT_COEX, &btconfig, sizeof(btconfig), 1); 4743 if (error != 0) 4744 return error; 4745 4746 memset(&btprio, 0, sizeof btprio); 4747 btprio.calib_init1 = 0x6; 4748 btprio.calib_init2 = 0x7; 4749 btprio.calib_periodic_low1 = 0x2; 4750 btprio.calib_periodic_low2 = 0x3; 4751 btprio.calib_periodic_high1 = 0x4; 4752 btprio.calib_periodic_high2 = 0x5; 4753 btprio.dtim = 0x6; 4754 btprio.scan52 = 0x8; 4755 btprio.scan24 = 0xa; 4756 error = iwn_cmd(sc, IWN_CMD_BT_COEX_PRIOTABLE, &btprio, sizeof(btprio), 4757 1); 4758 if (error != 0) 4759 return error; 4760 4761 /* Force BT state machine change. */ 4762 memset(&btprot, 0, sizeof btprio); 4763 btprot.open = 1; 4764 btprot.type = 1; 4765 error = iwn_cmd(sc, IWN_CMD_BT_COEX_PROT, &btprot, sizeof(btprot), 1); 4766 if (error != 0) 4767 return error; 4768 btprot.open = 0; 4769 return iwn_cmd(sc, IWN_CMD_BT_COEX_PROT, &btprot, sizeof(btprot), 1); 4770 } 4771 4772 static int 4478 4773 iwn_config(struct iwn_softc *sc) 4479 4774 { 4480 const struct iwn_hal *hal = sc->sc_hal;4775 struct iwn_ops *ops = &sc->ops; 4481 4776 struct ifnet *ifp = sc->sc_ifp; 4482 4777 struct ieee80211com *ic = ifp->if_l2com; 4483 struct iwn_bluetooth bluetooth;4484 4778 uint32_t txmask; 4485 int error;4486 4779 uint16_t rxchain; 4780 int error; 4781 4782 if (sc->hw_type == IWN_HW_REV_TYPE_6005) { 4783 /* Set radio temperature sensor offset. */ 4784 error = iwn5000_temp_offset_calib(sc); 4785 if (error != 0) { 4786 device_printf(sc->sc_dev, 4787 "%s: could not set temperature offset\n", __func__); 4788 return error; 4789 } 4790 } 4487 4791 4488 /* Configure valid TX chains for 5000 Series. */4792 /* Configure valid TX chains for >=5000 Series. */ 4489 4793 if (sc->hw_type != IWN_HW_REV_TYPE_4965) { 4490 4794 txmask = htole32(sc->txchainmask); 4491 4795 DPRINTF(sc, IWN_DEBUG_RESET, … … iwn_config(struct iwn_softc *sc) 4501 4805 } 4502 4806 4503 4807 /* Configure bluetooth coexistence. */ 4504 memset(&bluetooth, 0, sizeof bluetooth); 4505 bluetooth.flags = IWN_BT_COEX_CHAN_ANN | IWN_BT_COEX_BT_PRIO; 4506 bluetooth.lead_time = IWN_BT_LEAD_TIME_DEF; 4507 bluetooth.max_kill = IWN_BT_MAX_KILL_DEF; 4508 DPRINTF(sc, IWN_DEBUG_RESET, "%s: config bluetooth coexistence\n", 4509 __func__); 4510 error = iwn_cmd(sc, IWN_CMD_BT_COEX, &bluetooth, sizeof bluetooth, 0); 4808 if (sc->sc_flags & IWN_FLAG_ADV_BTCOEX) 4809 error = iwn_send_advanced_btcoex(sc); 4810 else 4811 error = iwn_send_btcoex(sc); 4511 4812 if (error != 0) { 4512 4813 device_printf(sc->sc_dev, 4513 4814 "%s: could not configure bluetooth coexistence, error %d\n", … … iwn_config(struct iwn_softc *sc) 4548 4849 IWN_RXCHAIN_IDLE_COUNT(2); 4549 4850 sc->rxon.rxchain = htole16(rxchain); 4550 4851 DPRINTF(sc, IWN_DEBUG_RESET, "%s: setting configuration\n", __func__); 4551 error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 0);4852 error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 0); 4552 4853 if (error != 0) { 4553 device_printf(sc->sc_dev, 4554 "%s: RXON command failed\n",__func__);4854 device_printf(sc->sc_dev, "%s: RXON command failed\n", 4855 __func__); 4555 4856 return error; 4556 4857 } 4557 4858 4558 error = iwn_add_broadcast_node(sc, 0); 4559 if (error != 0) { 4560 device_printf(sc->sc_dev, 4561 "%s: could not add broadcast node\n", __func__); 4859 if ((error = iwn_add_broadcast_node(sc, 0)) != 0) { 4860 device_printf(sc->sc_dev, "%s: could not add broadcast node\n", 4861 __func__); 4562 4862 return error; 4563 4863 } 4564 4864 4565 4865 /* Configuration has changed, set TX power accordingly. */ 4566 error = hal->set_txpower(sc, ic->ic_curchan, 0); 4567 if (error != 0) { 4568 device_printf(sc->sc_dev, 4569 "%s: could not set TX power\n", __func__); 4866 if ((error = ops->set_txpower(sc, ic->ic_curchan, 0)) != 0) { 4867 device_printf(sc->sc_dev, "%s: could not set TX power\n", 4868 __func__); 4570 4869 return error; 4571 4870 } 4572 4871 4573 error = iwn_set_critical_temp(sc); 4574 if (error != 0) { 4872 if ((error = iwn_set_critical_temp(sc)) != 0) { 4575 4873 device_printf(sc->sc_dev, 4576 "%s: c could not set critical temperature\n", __func__);4874 "%s: could not set critical temperature\n", __func__); 4577 4875 return error; 4578 4876 } 4579 4877 4580 4878 /* Set power saving level to CAM during initialization. */ 4581 error = iwn_set_pslevel(sc, 0, 0, 0); 4582 if (error != 0) { 4879 if ((error = iwn_set_pslevel(sc, 0, 0, 0)) != 0) { 4583 4880 device_printf(sc->sc_dev, 4584 4881 "%s: could not set power saving level\n", __func__); 4585 4882 return error; … … iwn_config(struct iwn_softc *sc) 4587 4884 return 0; 4588 4885 } 4589 4886 4887 /* 4888 * Add an ssid element to a frame. 4889 */ 4890 static uint8_t * 4891 ieee80211_add_ssid(uint8_t *frm, const uint8_t *ssid, u_int len) 4892 { 4893 *frm++ = IEEE80211_ELEMID_SSID; 4894 *frm++ = len; 4895 memcpy(frm, ssid, len); 4896 return frm + len; 4897 } 4898 4590 4899 static int 4591 4900 iwn_scan(struct iwn_softc *sc) 4592 4901 { … … iwn_scan(struct iwn_softc *sc) 4600 4909 struct ieee80211_frame *wh; 4601 4910 struct ieee80211_rateset *rs; 4602 4911 struct ieee80211_channel *c; 4603 int buflen, error, nrates;4912 uint8_t *buf, *frm; 4604 4913 uint16_t rxchain; 4605 uint8_t *buf, *frm, txant; 4914 uint8_t txant; 4915 int buflen, error; 4606 4916 4607 4917 buf = malloc(IWN_SCAN_MAXSZ, M_DEVBUF, M_NOWAIT | M_ZERO); 4608 4918 if (buf == NULL) { … … iwn_scan(struct iwn_softc *sc) 4612 4922 return ENOMEM; 4613 4923 } 4614 4924 hdr = (struct iwn_scan_hdr *)buf; 4615 4616 4925 /* 4617 4926 * Move to the next channel if no frames are received within 10ms 4618 4927 * after sending the probe request. … … iwn_scan(struct iwn_softc *sc) 4636 4945 4637 4946 tx = (struct iwn_cmd_data *)(hdr + 1); 4638 4947 tx->flags = htole32(IWN_TX_AUTO_SEQ); 4639 tx->id = sc-> sc_hal->broadcast_id;4948 tx->id = sc->broadcast_id; 4640 4949 tx->lifetime = htole32(IWN_LIFETIME_INFINITE); 4641 4950 4642 4951 if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) { … … iwn_scan(struct iwn_softc *sc) 4660 4969 essid[0].len = ss->ss_ssid[0].len; 4661 4970 memcpy(essid[0].data, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len); 4662 4971 } 4663 4664 4972 /* 4665 4973 * Build a probe request frame. Most of the following code is a 4666 4974 * copy & paste of what is done in net80211. … … iwn_scan(struct iwn_softc *sc) 4676 4984 *(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */ 4677 4985 4678 4986 frm = (uint8_t *)(wh + 1); 4679 4680 /* Add SSID IE. */ 4681 *frm++ = IEEE80211_ELEMID_SSID; 4682 *frm++ = ss->ss_ssid[0].len; 4683 memcpy(frm, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len); 4684 frm += ss->ss_ssid[0].len; 4685 4686 /* Add supported rates IE. */ 4687 *frm++ = IEEE80211_ELEMID_RATES; 4688 nrates = rs->rs_nrates; 4689 if (nrates > IEEE80211_RATE_SIZE) 4690 nrates = IEEE80211_RATE_SIZE; 4691 *frm++ = nrates; 4692 memcpy(frm, rs->rs_rates, nrates); 4693 frm += nrates; 4694 4695 /* Add supported xrates IE. */ 4696 if (rs->rs_nrates > IEEE80211_RATE_SIZE) { 4697 nrates = rs->rs_nrates - IEEE80211_RATE_SIZE; 4698 *frm++ = IEEE80211_ELEMID_XRATES; 4699 *frm++ = (uint8_t)nrates; 4700 memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates); 4701 frm += nrates; 4702 } 4987 frm = ieee80211_add_ssid(frm, NULL, 0); 4988 frm = ieee80211_add_rates(frm, rs); 4989 if (rs->rs_nrates > IEEE80211_RATE_SIZE) 4990 frm = ieee80211_add_xrates(frm, rs); 4991 #if 0 /* HT */ 4992 if (ic->ic_flags & IEEE80211_F_HTON) 4993 frm = ieee80211_add_htcaps(frm, ic); 4994 #endif 4703 4995 4704 4996 /* Set length of probe request. */ 4705 4997 tx->len = htole16(frm - (uint8_t *)wh); … … iwn_scan(struct iwn_softc *sc) 4761 5053 static int 4762 5054 iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap) 4763 5055 { 4764 const struct iwn_hal *hal = sc->sc_hal;5056 struct iwn_ops *ops = &sc->ops; 4765 5057 struct ifnet *ifp = sc->sc_ifp; 4766 5058 struct ieee80211com *ic = ifp->if_l2com; 4767 5059 struct ieee80211_node *ni = vap->iv_bss; 4768 5060 int error; 4769 5061 4770 sc->calib.state = IWN_CALIB_STATE_INIT;4771 4772 5062 /* Update adapter configuration. */ 4773 5063 IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid); 4774 sc->rxon.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));5064 sc->rxon.chan = ieee80211_chan2ieee(ic, ni->ni_chan); 4775 5065 sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF); 4776 5066 if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) 4777 5067 sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ); … … iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap) 4786 5076 sc->rxon.cck_mask = 0x03; 4787 5077 sc->rxon.ofdm_mask = 0; 4788 5078 } else { 4789 /* XXX assume 802.11b/g*/5079 /* Assume 802.11b/g. */ 4790 5080 sc->rxon.cck_mask = 0x0f; 4791 5081 sc->rxon.ofdm_mask = 0x15; 4792 5082 } 4793 DPRINTF(sc, IWN_DEBUG_STATE, 4794 "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x " 4795 "ht_single 0x%x ht_dual 0x%x rxchain 0x%x " 4796 "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n", 4797 __func__, 4798 le16toh(sc->rxon.chan), sc->rxon.mode, le32toh(sc->rxon.flags), 4799 sc->rxon.cck_mask, sc->rxon.ofdm_mask, 4800 sc->rxon.ht_single_mask, sc->rxon.ht_dual_mask, 4801 le16toh(sc->rxon.rxchain), 4802 sc->rxon.myaddr, ":", sc->rxon.wlap, ":", sc->rxon.bssid, ":", 4803 le16toh(sc->rxon.associd), le32toh(sc->rxon.filter)); 4804 error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1); 5083 DPRINTF(sc, IWN_DEBUG_STATE, "rxon chan %d flags %x cck %x ofdm %x\n", 5084 sc->rxon.chan, sc->rxon.flags, sc->rxon.cck_mask, 5085 sc->rxon.ofdm_mask); 5086 error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1); 4805 5087 if (error != 0) { 4806 device_printf(sc->sc_dev, 4807 "%s: RXON command failed, error %d\n",__func__, error);5088 device_printf(sc->sc_dev, "%s: RXON command failed, error %d\n", 5089 __func__, error); 4808 5090 return error; 4809 5091 } 4810 5092 4811 5093 /* Configuration has changed, set TX power accordingly. */ 4812 error = hal->set_txpower(sc, ni->ni_chan, 1); 4813 if (error != 0) { 5094 if ((error = ops->set_txpower(sc, ni->ni_chan, 1)) != 0) { 4814 5095 device_printf(sc->sc_dev, 4815 "%s: could not set T xpower, error %d\n", __func__, error);5096 "%s: could not set TX power, error %d\n", __func__, error); 4816 5097 return error; 4817 5098 } 4818 5099 /* 4819 5100 * Reconfiguring RXON clears the firmware nodes table so we must 4820 5101 * add the broadcast node again. 4821 5102 */ 4822 error = iwn_add_broadcast_node(sc, 1); 4823 if (error != 0) { 5103 if ((error = iwn_add_broadcast_node(sc, 1)) != 0) { 4824 5104 device_printf(sc->sc_dev, 4825 "%s: could not add broadcast node, error %d\n", 4826 __func__,error);5105 "%s: could not add broadcast node, error %d\n", __func__, 5106 error); 4827 5107 return error; 4828 5108 } 4829 5109 return 0; 4830 5110 } 4831 5111 4832 /*4833 * Configure the adapter for associated state.4834 */4835 5112 static int 4836 5113 iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap) 4837 5114 { 4838 5115 #define MS(v,x) (((v) & x) >> x##_S) 4839 const struct iwn_hal *hal = sc->sc_hal;5116 struct iwn_ops *ops = &sc->ops; 4840 5117 struct ifnet *ifp = sc->sc_ifp; 4841 5118 struct ieee80211com *ic = ifp->if_l2com; 4842 5119 struct ieee80211_node *ni = vap->iv_bss; … … iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap) 4845 5122 4846 5123 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 4847 5124 /* Link LED blinks while monitoring. */ 4848 iwn_set_led(sc, IWN_LED_LINK, 20, 20);5125 iwn_set_led(sc, IWN_LED_LINK, 5, 5); 4849 5126 return 0; 4850 5127 } 4851 error = iwn_set_timing(sc, ni); 4852 if (error != 0) { 5128 if ((error = iwn_set_timing(sc, ni)) != 0) { 4853 5129 device_printf(sc->sc_dev, 4854 5130 "%s: could not set timing, error %d\n", __func__, error); 4855 5131 return error; … … iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap) 4857 5133 4858 5134 /* Update adapter configuration. */ 4859 5135 IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid); 4860 sc->rxon.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));4861 5136 sc->rxon.associd = htole16(IEEE80211_AID(ni->ni_associd)); 4862 /* Short preamble and slot time are negotiated when associating. */ 4863 sc->rxon.flags &= ~htole32(IWN_RXON_SHPREAMBLE | IWN_RXON_SHSLOT); 4864 sc->rxon.flags |= htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF); 5137 sc->rxon.chan = ieee80211_chan2ieee(ic, ni->ni_chan); 5138 sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF); 4865 5139 if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) 4866 5140 sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ); 4867 else4868 sc->rxon.flags &= ~htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);4869 5141 if (ic->ic_flags & IEEE80211_F_SHSLOT) 4870 5142 sc->rxon.flags |= htole32(IWN_RXON_SHSLOT); 4871 5143 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) … … iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap) 4877 5149 sc->rxon.cck_mask = 0x03; 4878 5150 sc->rxon.ofdm_mask = 0; 4879 5151 } else { 4880 /* XXX assume 802.11b/g*/5152 /* Assume 802.11b/g. */ 4881 5153 sc->rxon.cck_mask = 0x0f; 4882 5154 sc->rxon.ofdm_mask = 0x15; 4883 5155 } … … iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap) 4902 5174 maxrxampdu = ampdudensity = 0; 4903 5175 #endif 4904 5176 sc->rxon.filter |= htole32(IWN_FILTER_BSS); 4905 4906 DPRINTF(sc, IWN_DEBUG_STATE, 4907 "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x " 4908 "ht_single 0x%x ht_dual 0x%x rxchain 0x%x " 4909 "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n", 4910 __func__, 4911 le16toh(sc->rxon.chan), sc->rxon.mode, le32toh(sc->rxon.flags), 4912 sc->rxon.cck_mask, sc->rxon.ofdm_mask, 4913 sc->rxon.ht_single_mask, sc->rxon.ht_dual_mask, 4914 le16toh(sc->rxon.rxchain), 4915 sc->rxon.myaddr, ":", sc->rxon.wlap, ":", sc->rxon.bssid, ":", 4916 le16toh(sc->rxon.associd), le32toh(sc->rxon.filter)); 4917 error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1); 5177 DPRINTF(sc, IWN_DEBUG_STATE, "rxon chan %d flags %x\n", 5178 sc->rxon.chan, sc->rxon.flags); 5179 error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1); 4918 5180 if (error != 0) { 4919 5181 device_printf(sc->sc_dev, 4920 "%s: could not update configuration, error %d\n", 4921 __func__,error);5182 "%s: could not update configuration, error %d\n", __func__, 5183 error); 4922 5184 return error; 4923 5185 } 4924 5186 4925 5187 /* Configuration has changed, set TX power accordingly. */ 4926 error = hal->set_txpower(sc, ni->ni_chan, 1); 4927 if (error != 0) { 5188 if ((error = ops->set_txpower(sc, ni->ni_chan, 1)) != 0) { 4928 5189 device_printf(sc->sc_dev, 4929 "%s: could not set T xpower, error %d\n", __func__, error);5190 "%s: could not set TX power, error %d\n", __func__, error); 4930 5191 return error; 4931 5192 } 4932 5193 5194 /* Fake a join to initialize the TX rate. */ 5195 ((struct iwn_node *)ni)->id = IWN_ID_BSS; 5196 iwn_newassoc(ni, 1); 5197 4933 5198 /* Add BSS node. */ 4934 5199 memset(&node, 0, sizeof node); 4935 5200 IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr); … … iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap) 4938 5203 node.htflags = htole32(IWN_AMDPU_SIZE_FACTOR(3) | 4939 5204 IWN_AMDPU_DENSITY(5)); /* 2us */ 4940 5205 #endif 4941 DPRINTF(sc, IWN_DEBUG_STATE, "%s: add BSS node, id %d htflags 0x%x\n", 4942 __func__, node.id, le32toh(node.htflags)); 4943 error = hal->add_node(sc, &node, 1); 5206 DPRINTF(sc, IWN_DEBUG_STATE, "%s: adding BSS node\n", __func__); 5207 error = ops->add_node(sc, &node, 1); 4944 5208 if (error != 0) { 4945 device_printf(sc->sc_dev, "could not add BSS node\n"); 5209 device_printf(sc->sc_dev, 5210 "%s: could not add BSS node, error %d\n", __func__, error); 4946 5211 return error; 4947 5212 } 4948 DPRINTF(sc, IWN_DEBUG_STATE, "setting link quality for node %d\n", 4949 node.id); 4950 error = iwn_set_link_quality(sc, node.id, 1); 4951 if (error != 0) { 5213 DPRINTF(sc, IWN_DEBUG_STATE, "%s: setting link quality for node %d\n", 5214 __func__, node.id); 5215 if ((error = iwn_set_link_quality(sc, ni)) != 0) { 4952 5216 device_printf(sc->sc_dev, 4953 "%s: could not setup MRRfor node %d, error %d\n",5217 "%s: could not setup link quality for node %d, error %d\n", 4954 5218 __func__, node.id, error); 4955 5219 return error; 4956 5220 } 4957 5221 4958 error = iwn_init_sensitivity(sc); 4959 if (error != 0) { 5222 if ((error = iwn_init_sensitivity(sc)) != 0) { 4960 5223 device_printf(sc->sc_dev, 4961 "%s: could not set sensitivity, error %d\n", 4962 __func__,error);5224 "%s: could not set sensitivity, error %d\n", __func__, 5225 error); 4963 5226 return error; 4964 5227 } 4965 4966 5228 /* Start periodic calibration timer. */ 4967 5229 sc->calib.state = IWN_CALIB_STATE_ASSOC; 4968 iwn_calib_reset(sc); 5230 sc->calib_cnt = 0; 5231 callout_reset(&sc->calib_to, msecs_to_ticks(500), iwn_calib_timeout, 5232 sc); 4969 5233 4970 5234 /* Link LED always on while associated. */ 4971 5235 iwn_set_led(sc, IWN_LED_LINK, 0, 1); 4972 4973 5236 return 0; 4974 5237 #undef MS 4975 5238 } … … iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni, 4985 5248 { 4986 5249 struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid]; 4987 5250 struct iwn_softc *sc = ic->ic_softc; 5251 struct iwn_ops *ops = &sc->ops; 4988 5252 struct iwn_node *wn = (void *)ni; 4989 5253 struct iwn_node_info node; 4990 5254 … … iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni, 4995 5259 node.addba_tid = tid; 4996 5260 node.addba_ssn = htole16(ba->ba_winstart); 4997 5261 DPRINTF(sc, IWN_DEBUG_RECV, "ADDBA RA=%d TID=%d SSN=%d\n", 4998 wn->id, tid, ba->ba_winstart) );4999 return sc->sc_hal->add_node(sc, &node, 1);5262 wn->id, tid, ba->ba_winstart); 5263 return ops->add_node(sc, &node, 1); 5000 5264 } 5001 5265 5002 5266 /* 5003 5267 * This function is called by upper layer on teardown of an HT-immediate 5004 * Block Ack agreement (eg. uppon receipt of a DELBA frame .)5268 * Block Ack agreement (eg. uppon receipt of a DELBA frame). 5005 5269 */ 5006 5270 static void 5007 5271 iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni, 5008 5272 uint8_t tid) 5009 5273 { 5010 5274 struct iwn_softc *sc = ic->ic_softc; 5275 struct iwn_ops *ops = &sc->ops; 5011 5276 struct iwn_node *wn = (void *)ni; 5012 5277 struct iwn_node_info node; 5013 5278 … … iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni, 5017 5282 node.flags = IWN_FLAG_SET_DELBA; 5018 5283 node.delba_tid = tid; 5019 5284 DPRINTF(sc, IWN_DEBUG_RECV, "DELBA RA=%d TID=%d\n", wn->id, tid); 5020 (void) sc->sc_hal->add_node(sc, &node, 1);5285 (void)ops->add_node(sc, &node, 1); 5021 5286 } 5022 5287 5023 5288 /* … … iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni, 5030 5295 { 5031 5296 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid]; 5032 5297 struct iwn_softc *sc = ic->ic_softc; 5033 const struct iwn_hal *hal = sc->sc_hal;5298 struct iwn_ops *ops = &sc->ops; 5034 5299 struct iwn_node *wn = (void *)ni; 5035 5300 struct iwn_node_info node; 5036 5301 int error; … … iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni, 5042 5307 node.control = IWN_NODE_UPDATE; 5043 5308 node.flags = IWN_FLAG_SET_DISABLE_TID; 5044 5309 node.disable_tid = htole16(wn->disable_tid); 5045 error = hal->add_node(sc, &node, 1);5310 error = ops->add_node(sc, &node, 1); 5046 5311 if (error != 0) 5047 5312 return error; 5048 5313 5049 5314 if ((error = iwn_nic_lock(sc)) != 0) 5050 5315 return error; 5051 hal->ampdu_tx_start(sc, ni, tid, ba->ba_winstart);5316 ops->ampdu_tx_start(sc, ni, tid, ba->ba_winstart); 5052 5317 iwn_nic_unlock(sc); 5053 5318 return 0; 5054 5319 } … … iwn_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni, 5059 5324 { 5060 5325 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid]; 5061 5326 struct iwn_softc *sc = ic->ic_softc; 5062 int error;5327 struct iwn_ops *ops = &sc->ops; 5063 5328 5064 error = iwn_nic_lock(sc); 5065 if (error != 0) 5329 if (iwn_nic_lock(sc) != 0) 5066 5330 return; 5067 sc->sc_hal->ampdu_tx_stop(sc, tid, ba->ba_winstart);5331 ops->ampdu_tx_stop(sc, tid, ba->ba_winstart); 5068 5332 iwn_nic_unlock(sc); 5069 5333 } 5070 5334 … … iwn5000_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn) 5190 5454 #endif 5191 5455 5192 5456 /* 5193 * Send calibration results to the runtime firmware. These results were 5194 * obtained on first boot from the initialization firmware, or by reading 5195 * the EEPROM for crystal calibration. 5196 */ 5197 static int 5198 iwn5000_send_calib_results(struct iwn_softc *sc) 5199 { 5200 struct iwn_calib_info *calib_result; 5201 int idx, error; 5202 5203 for (idx = 0; idx < IWN_CALIB_NUM; idx++) { 5204 calib_result = &sc->calib_results[idx]; 5205 5206 /* No support for this type of calibration. */ 5207 if ((sc->calib_init & (1 << idx)) == 0) 5208 continue; 5209 5210 /* No calibration result available. */ 5211 if (calib_result->buf == NULL) 5212 continue; 5213 5214 DPRINTF(sc, IWN_DEBUG_CALIBRATE, 5215 "%s: send calibration result idx=%d, len=%d\n", 5216 __func__, idx, calib_result->len); 5217 5218 error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, calib_result->buf, 5219 calib_result->len, 0); 5220 if (error != 0) { 5221 device_printf(sc->sc_dev, 5222 "%s: could not send calibration result " 5223 "idx=%d, error=%d\n", 5224 __func__, idx, error); 5225 return error; 5226 } 5227 } 5228 return 0; 5229 } 5230 5231 /* 5232 * Save calibration result at the given index. The index determines 5233 * in which order the results are sent to the runtime firmware. 5457 * Query calibration tables from the initialization firmware. We do this 5458 * only once at first boot. Called from a process context. 5234 5459 */ 5235 5460 static int 5236 iwn5000_save_calib_result(struct iwn_softc *sc, struct iwn_phy_calib *calib, 5237 int len, int idx) 5461 iwn5000_query_calibration(struct iwn_softc *sc) 5238 5462 { 5239 struct iwn_calib_info *calib_result = &sc->calib_results[idx];5240 5241 DPRINTF(sc, IWN_DEBUG_CALIBRATE,5242 "%s: saving calibration result code=%d, idx=%d, len=%d\n",5243 __func__, calib->code, idx, len);5244 5245 if (calib_result->buf != NULL)5246 free(calib_result->buf, M_DEVBUF);5247 5248 calib_result->buf = malloc(len, M_DEVBUF, M_NOWAIT);5249 if (calib_result->buf == NULL) {5250 device_printf(sc->sc_dev,5251 "%s: not enough memory for calibration result "5252 "code=%d, len=%d\n", __func__, calib->code, len);5253 return ENOMEM;5254 }5255 5256 calib_result->len = len;5257 memcpy(calib_result->buf, calib, len);5258 return 0;5259 }5260 5261 static void5262 iwn5000_free_calib_results(struct iwn_softc *sc)5263 {5264 struct iwn_calib_info *calib_result;5265 int idx;5266 5267 for (idx = 0; idx < IWN_CALIB_NUM; idx++) {5268 calib_result = &sc->calib_results[idx];5269 5270 if (calib_result->buf != NULL)5271 free(calib_result->buf, M_DEVBUF);5272 5273 calib_result->buf = NULL;5274 calib_result->len = 0;5275 }5276 }5277 5278 /*5279 * Obtain the crystal calibration result from the EEPROM.5280 */5281 static int5282 iwn5000_chrystal_calib(struct iwn_softc *sc)5283 {5284 struct iwn5000_phy_calib_crystal cmd;5285 uint32_t base, crystal;5286 uint16_t val;5287 5288 /* Read crystal calibration. */5289 iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2);5290 base = le16toh(val);5291 iwn_read_prom_data(sc, base + IWN5000_EEPROM_CRYSTAL, &crystal,5292 sizeof(uint32_t));5293 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: crystal calibration=0x%08x\n",5294 __func__, le32toh(crystal));5295 5296 memset(&cmd, 0, sizeof cmd);5297 cmd.code = IWN5000_PHY_CALIB_CRYSTAL;5298 cmd.ngroups = 1;5299 cmd.isvalid = 1;5300 cmd.cap_pin[0] = le32toh(crystal) & 0xff;5301 cmd.cap_pin[1] = (le32toh(crystal) >> 16) & 0xff;5302 5303 return iwn5000_save_calib_result(sc, (struct iwn_phy_calib *)&cmd,5304 sizeof cmd, IWN_CALIB_IDX_XTAL);5305 }5306 5307 /*5308 * Query calibration results from the initialization firmware. We do this5309 * only once at first boot.5310 */5311 static int5312 iwn5000_send_calib_query(struct iwn_softc *sc, uint32_t cfg)5313 {5314 #define CALIB_INIT_CFG 0xffffffff;5315 5463 struct iwn5000_calib_config cmd; 5316 5464 int error; 5317 5465 5318 5466 memset(&cmd, 0, sizeof cmd); 5319 cmd.ucode.once.enable = CALIB_INIT_CFG; 5320 if (cfg == 0) { 5321 cmd.ucode.once.start = CALIB_INIT_CFG; 5322 cmd.ucode.once.send = CALIB_INIT_CFG; 5323 cmd.ucode.flags = CALIB_INIT_CFG; 5324 } else 5325 cmd.ucode.once.start = cfg; 5326 5327 DPRINTF(sc, IWN_DEBUG_CALIBRATE, 5328 "%s: query calibration results, cfg %x\n", __func__, cfg); 5329 5467 cmd.ucode.once.enable = 0xffffffff; 5468 cmd.ucode.once.start = 0xffffffff; 5469 cmd.ucode.once.send = 0xffffffff; 5470 cmd.ucode.flags = 0xffffffff; 5471 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: sending calibration query\n", 5472 __func__); 5330 5473 error = iwn_cmd(sc, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof cmd, 0); 5331 5474 if (error != 0) 5332 5475 return error; 5333 5476 5334 5477 /* Wait at most two seconds for calibration to complete. */ 5335 5478 if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE)) 5336 error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", 2 * hz); 5337 5479 error = msleep(sc, &sc->sc_mtx, PCATCH, "iwncal", 2 * hz); 5338 5480 return error; 5339 #undef CALIB_INIT_CFG5340 5481 } 5341 5482 5342 5483 /* 5343 * Process a CALIBRATION_RESULT notification sent by the initialization5344 * firmware on response to a CMD_CALIB_CONFIG command.5484 * Send calibration results to the runtime firmware. These results were 5485 * obtained on first boot from the initialization firmware. 5345 5486 */ 5346 5487 static int 5347 iwn5000_rx_calib_result(struct iwn_softc *sc, struct iwn_rx_desc *desc, 5348 struct iwn_rx_data *data) 5488 iwn5000_send_calibration(struct iwn_softc *sc) 5349 5489 { 5350 #define FRAME_SIZE_MASK 0x3fff 5351 struct iwn_phy_calib *calib = (struct iwn_phy_calib *)(desc + 1); 5352 int len, idx; 5353 5354 bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); 5355 len = (le32toh(desc->len) & FRAME_SIZE_MASK); 5356 5357 /* Remove length field itself. */ 5358 len -= 4; 5490 int idx, error; 5359 5491 5360 /* 5361 * Determine the order in which the results will be send to the 5362 * runtime firmware. 5363 */ 5364 switch (calib->code) { 5365 case IWN5000_PHY_CALIB_DC: 5366 idx = IWN_CALIB_IDX_DC; 5367 break; 5368 case IWN5000_PHY_CALIB_LO: 5369 idx = IWN_CALIB_IDX_LO; 5370 break; 5371 case IWN5000_PHY_CALIB_TX_IQ: 5372 idx = IWN_CALIB_IDX_TX_IQ; 5373 break; 5374 case IWN5000_PHY_CALIB_TX_IQ_PERIODIC: 5375 idx = IWN_CALIB_IDX_TX_IQ_PERIODIC; 5376 break; 5377 case IWN5000_PHY_CALIB_BASE_BAND: 5378 idx = IWN_CALIB_IDX_BASE_BAND; 5379 break; 5380 default: 5492 for (idx = 0; idx < 5; idx++) { 5493 if (sc->calibcmd[idx].buf == NULL) 5494 continue; /* No results available. */ 5381 5495 DPRINTF(sc, IWN_DEBUG_CALIBRATE, 5382 "%s: unknown calibration code=%d\n", __func__, calib->code); 5383 return EINVAL; 5496 "send calibration result idx=%d len=%d\n", idx, 5497 sc->calibcmd[idx].len); 5498 error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, sc->calibcmd[idx].buf, 5499 sc->calibcmd[idx].len, 0); 5500 if (error != 0) { 5501 device_printf(sc->sc_dev, 5502 "%s: could not send calibration result, error %d\n", 5503 __func__, error); 5504 return error; 5505 } 5384 5506 } 5385 return iwn5000_save_calib_result(sc, calib, len, idx); 5386 #undef FRAME_SIZE_MASK 5507 return 0; 5387 5508 } 5388 5509 5389 5510 static int … … iwn5000_send_wimax_coex(struct iwn_softc *sc) 5413 5534 return iwn_cmd(sc, IWN5000_CMD_WIMAX_COEX, &wimax, sizeof wimax, 0); 5414 5535 } 5415 5536 5537 static int 5538 iwn5000_crystal_calib(struct iwn_softc *sc) 5539 { 5540 struct iwn5000_phy_calib_crystal cmd; 5541 5542 memset(&cmd, 0, sizeof cmd); 5543 cmd.code = IWN5000_PHY_CALIB_CRYSTAL; 5544 cmd.ngroups = 1; 5545 cmd.isvalid = 1; 5546 cmd.cap_pin[0] = le32toh(sc->eeprom_crystal) & 0xff; 5547 cmd.cap_pin[1] = (le32toh(sc->eeprom_crystal) >> 16) & 0xff; 5548 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "sending crystal calibration %d, %d\n", 5549 cmd.cap_pin[0], cmd.cap_pin[1]); 5550 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0); 5551 } 5552 5553 static int 5554 iwn5000_temp_offset_calib(struct iwn_softc *sc) 5555 { 5556 struct iwn5000_phy_calib_temp_offset cmd; 5557 5558 memset(&cmd, 0, sizeof cmd); 5559 cmd.code = IWN5000_PHY_CALIB_TEMP_OFFSET; 5560 cmd.ngroups = 1; 5561 cmd.isvalid = 1; 5562 if (sc->eeprom_temp != 0) 5563 cmd.offset = htole16(sc->eeprom_temp); 5564 else 5565 cmd.offset = htole16(IWN_DEFAULT_TEMP_OFFSET); 5566 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "setting radio sensor offset to %d\n", 5567 le16toh(cmd.offset)); 5568 return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0); 5569 } 5570 5416 5571 /* 5417 5572 * This function is called after the runtime firmware notifies us of its 5418 * readiness (called in a process context .)5573 * readiness (called in a process context). 5419 5574 */ 5420 5575 static int 5421 5576 iwn4965_post_alive(struct iwn_softc *sc) … … iwn4965_post_alive(struct iwn_softc *sc) 5430 5585 iwn_mem_set_region_4(sc, sc->sched_base + IWN4965_SCHED_CTX_OFF, 0, 5431 5586 IWN4965_SCHED_CTX_LEN / sizeof (uint32_t)); 5432 5587 5433 /* Set physical address of TX scheduler rings (1KB aligned .)*/5588 /* Set physical address of TX scheduler rings (1KB aligned). */ 5434 5589 iwn_prph_write(sc, IWN4965_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10); 5435 5590 5436 5591 IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY); … … iwn4965_post_alive(struct iwn_softc *sc) 5468 5623 5469 5624 /* 5470 5625 * This function is called after the initialization or runtime firmware 5471 * notifies us of its readiness (called in a process context .)5626 * notifies us of its readiness (called in a process context). 5472 5627 */ 5473 5628 static int 5474 5629 iwn5000_post_alive(struct iwn_softc *sc) … … iwn5000_post_alive(struct iwn_softc *sc) 5478 5633 /* Switch to using ICT interrupt mode. */ 5479 5634 iwn5000_ict_reset(sc); 5480 5635 5481 error = iwn_nic_lock(sc); 5482 if (error != 0) 5636 if ((error = iwn_nic_lock(sc)) != 0) 5483 5637 return error; 5484 5638 5485 5639 /* Clear TX scheduler state in SRAM. */ … … iwn5000_post_alive(struct iwn_softc *sc) 5487 5641 iwn_mem_set_region_4(sc, sc->sched_base + IWN5000_SCHED_CTX_OFF, 0, 5488 5642 IWN5000_SCHED_CTX_LEN / sizeof (uint32_t)); 5489 5643 5490 /* Set physical address of TX scheduler rings (1KB aligned .)*/5644 /* Set physical address of TX scheduler rings (1KB aligned). */ 5491 5645 iwn_prph_write(sc, IWN5000_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10); 5492 5646 5493 5647 IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY); … … iwn5000_post_alive(struct iwn_softc *sc) 5529 5683 __func__, error); 5530 5684 return error; 5531 5685 } 5532 5533 if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE)) { 5534 /* 5535 * Start calibration by setting and sending the chrystal 5536 * calibration first, this must be done before we are able 5537 * to query the other calibration results. 5538 */ 5539 error = iwn5000_chrystal_calib(sc); 5686 if (sc->hw_type != IWN_HW_REV_TYPE_5150) { 5687 /* Perform crystal calibration. */ 5688 error = iwn5000_crystal_calib(sc); 5540 5689 if (error != 0) { 5541 5690 device_printf(sc->sc_dev, 5542 "%s: could not set chrystal calibration, " 5543 "error=%d\n", __func__, error); 5544 return error; 5545 } 5546 error = iwn5000_send_calib_results(sc); 5547 if (error != 0) { 5548 device_printf(sc->sc_dev, 5549 "%s: could not send chrystal calibration, " 5550 "error=%d\n", __func__, error); 5691 "%s: crystal calibration failed, error %d\n", 5692 __func__, error); 5551 5693 return error; 5552 5694 } 5553 5554 /* 5555 * Query other calibration results from the initialization 5556 * firmware. 5557 */ 5558 error = iwn5000_send_calib_query(sc, 0); 5559 if (error != 0) { 5695 } 5696 if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE)) { 5697 /* Query calibration from the initialization firmware. */ 5698 if ((error = iwn5000_query_calibration(sc)) != 0) { 5560 5699 device_printf(sc->sc_dev, 5561 "%s: could not query calibration, error =%d\n",5700 "%s: could not query calibration, error %d\n", 5562 5701 __func__, error); 5563 5702 return error; 5564 5703 } 5565 5566 5704 /* 5567 5705 * We have the calibration results now, reboot with the 5568 5706 * runtime firmware (call ourselves recursively!) … … iwn5000_post_alive(struct iwn_softc *sc) 5570 5708 iwn_hw_stop(sc); 5571 5709 error = iwn_hw_init(sc); 5572 5710 } else { 5573 /* 5574 * Send calibration results obtained from the initialization 5575 * firmware to the runtime firmware. 5576 */ 5577 error = iwn5000_send_calib_results(sc); 5578 5579 /* 5580 * Tell the runtime firmware to do certain calibration types. 5581 */ 5582 if (sc->calib_runtime != 0) { 5583 error = iwn5000_send_calib_query(sc, sc->calib_runtime); 5584 if (error != 0) { 5585 device_printf(sc->sc_dev, 5586 "%s: could not send query calibration, " 5587 "error=%d, cfg=%x\n", __func__, error, 5588 sc->calib_runtime); 5589 } 5590 } 5711 /* Send calibration results to runtime firmware. */ 5712 error = iwn5000_send_calibration(sc); 5591 5713 } 5592 5714 return error; 5593 5715 } 5594 5716 5595 5717 /* 5596 5718 * The firmware boot code is small and is intended to be copied directly into 5597 * the NIC internal memory (no DMA transfer .)5719 * the NIC internal memory (no DMA transfer). 5598 5720 */ 5599 5721 static int 5600 5722 iwn4965_load_bootcode(struct iwn_softc *sc, const uint8_t *ucode, int size) … … iwn4965_load_bootcode(struct iwn_softc *sc, const uint8_t *ucode, int size) 5603 5725 5604 5726 size /= sizeof (uint32_t); 5605 5727 5606 error = iwn_nic_lock(sc); 5607 if (error != 0) 5728 if ((error = iwn_nic_lock(sc)) != 0) 5608 5729 return error; 5609 5730 5610 5731 /* Copy microcode image into NIC memory. */ … … iwn4965_load_firmware(struct iwn_softc *sc) 5648 5769 5649 5770 /* Copy initialization sections into pre-allocated DMA-safe memory. */ 5650 5771 memcpy(dma->vaddr, fw->init.data, fw->init.datasz); 5651 bus_dmamap_sync( sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);5772 bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE); 5652 5773 memcpy(dma->vaddr + IWN4965_FW_DATA_MAXSZ, 5653 5774 fw->init.text, fw->init.textsz); 5654 bus_dmamap_sync( sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);5775 bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE); 5655 5776 5656 5777 /* Tell adapter where to find initialization sections. */ 5657 error = iwn_nic_lock(sc); 5658 if (error != 0) 5778 if ((error = iwn_nic_lock(sc)) != 0) 5659 5779 return error; 5660 5780 iwn_prph_write(sc, IWN_BSM_DRAM_DATA_ADDR, dma->paddr >> 4); 5661 5781 iwn_prph_write(sc, IWN_BSM_DRAM_DATA_SIZE, fw->init.datasz); … … iwn4965_load_firmware(struct iwn_softc *sc) 5675 5795 IWN_WRITE(sc, IWN_RESET, 0); 5676 5796 5677 5797 /* Wait at most one second for first alive notification. */ 5678 error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz); 5679 if (error) { 5798 if ((error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz)) != 0) { 5680 5799 device_printf(sc->sc_dev, 5681 5800 "%s: timeout waiting for adapter to initialize, error %d\n", 5682 5801 __func__, error); … … iwn4965_load_firmware(struct iwn_softc *sc) 5689 5808 5690 5809 /* Copy runtime sections into pre-allocated DMA-safe memory. */ 5691 5810 memcpy(dma->vaddr, fw->main.data, fw->main.datasz); 5692 bus_dmamap_sync( sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);5811 bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE); 5693 5812 memcpy(dma->vaddr + IWN4965_FW_DATA_MAXSZ, 5694 5813 fw->main.text, fw->main.textsz); 5695 bus_dmamap_sync( sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);5814 bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE); 5696 5815 5697 5816 /* Tell adapter where to find runtime sections. */ 5698 error = iwn_nic_lock(sc); 5699 if (error != 0) 5817 if ((error = iwn_nic_lock(sc)) != 0) 5700 5818 return error; 5701 5702 5819 iwn_prph_write(sc, IWN_BSM_DRAM_DATA_ADDR, dma->paddr >> 4); 5703 5820 iwn_prph_write(sc, IWN_BSM_DRAM_DATA_SIZE, fw->main.datasz); 5704 5821 iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_ADDR, … … iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst, 5719 5836 5720 5837 /* Copy firmware section into pre-allocated DMA-safe memory. */ 5721 5838 memcpy(dma->vaddr, section, size); 5722 bus_dmamap_sync( sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);5839 bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE); 5723 5840 5724 error = iwn_nic_lock(sc); 5725 if (error != 0) 5841 if ((error = iwn_nic_lock(sc)) != 0) 5726 5842 return error; 5727 5843 5728 5844 IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_DMACHNL), … … iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst, 5745 5861 iwn_nic_unlock(sc); 5746 5862 5747 5863 /* Wait at most five seconds for FH DMA transfer to complete. */ 5748 return msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);5864 return msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", 5 * hz); 5749 5865 } 5750 5866 5751 5867 static int … … iwn_read_firmware_leg(struct iwn_softc *sc, struct iwn_fw_info *fw) 5790 5906 size_t hdrlen = 24; 5791 5907 uint32_t rev; 5792 5908 5793 ptr = (const uint32_t *) sc->fw_fp->data;5909 ptr = (const uint32_t *)fw->data; 5794 5910 rev = le32toh(*ptr++); 5795 5911 5796 5912 /* Check firmware API version. */ … … iwn_read_firmware_leg(struct iwn_softc *sc, struct iwn_fw_info *fw) 5805 5921 ptr++; 5806 5922 } 5807 5923 if (fw->size < hdrlen) { 5808 device_printf(sc->sc_dev, 5809 "%s: firmware file too short: %zu bytes\n", 5924 device_printf(sc->sc_dev, "%s: firmware too short: %zu bytes\n", 5810 5925 __func__, fw->size); 5811 5926 return EINVAL; 5812 5927 } … … iwn_read_firmware_leg(struct iwn_softc *sc, struct iwn_fw_info *fw) 5819 5934 /* Check that all firmware sections fit. */ 5820 5935 if (fw->size < hdrlen + fw->main.textsz + fw->main.datasz + 5821 5936 fw->init.textsz + fw->init.datasz + fw->boot.textsz) { 5822 device_printf(sc->sc_dev, 5823 "%s: firmware file too short: %zu bytes\n", 5937 device_printf(sc->sc_dev, "%s: firmware too short: %zu bytes\n", 5824 5938 __func__, fw->size); 5825 5939 return EINVAL; 5826 5940 } … … iwn_read_firmware_leg(struct iwn_softc *sc, struct iwn_fw_info *fw) 5831 5945 fw->init.text = fw->main.data + fw->main.datasz; 5832 5946 fw->init.data = fw->init.text + fw->init.textsz; 5833 5947 fw->boot.text = fw->init.data + fw->init.datasz; 5834 5835 5948 return 0; 5836 5949 } 5837 5950 5838 5951 /* 5839 5952 * Extract text and data sections from a TLV firmware image. 5840 5953 */ 5841 int5954 static int 5842 5955 iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw, 5843 5956 uint16_t alt) 5844 5957 { … … iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw, 5846 5959 const struct iwn_fw_tlv *tlv; 5847 5960 const uint8_t *ptr, *end; 5848 5961 uint64_t altmask; 5849 uint32_t len ;5962 uint32_t len, tmp; 5850 5963 5851 5964 if (fw->size < sizeof (*hdr)) { 5852 device_printf(sc->sc_dev, 5853 "%s: firmware file too short: %zu bytes\n", 5965 device_printf(sc->sc_dev, "%s: firmware too short: %zu bytes\n", 5854 5966 __func__, fw->size); 5855 5967 return EINVAL; 5856 5968 } 5857 5969 hdr = (const struct iwn_fw_tlv_hdr *)fw->data; 5858 5970 if (hdr->signature != htole32(IWN_FW_SIGNATURE)) { 5859 device_printf(sc->sc_dev, 5860 "%s: bad firmware file signature 0x%08x\n", 5971 device_printf(sc->sc_dev, "%s: bad firmware signature 0x%08x\n", 5861 5972 __func__, le32toh(hdr->signature)); 5862 5973 return EINVAL; 5863 5974 } 5975 DPRINTF(sc, IWN_DEBUG_RESET, "FW: \"%.64s\", build 0x%x\n", hdr->descr, 5976 le32toh(hdr->build)); 5864 5977 5865 5978 /* 5866 5979 * Select the closest supported alternative that is less than … … iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw, 5869 5982 altmask = le64toh(hdr->altmask); 5870 5983 while (alt > 0 && !(altmask & (1ULL << alt))) 5871 5984 alt--; /* Downgrade. */ 5985 DPRINTF(sc, IWN_DEBUG_RESET, "using alternative %d\n", alt); 5872 5986 5873 5987 ptr = (const uint8_t *)(hdr + 1); 5874 5988 end = (const uint8_t *)(fw->data + fw->size); … … iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw, 5881 5995 ptr += sizeof (*tlv); 5882 5996 if (ptr + len > end) { 5883 5997 device_printf(sc->sc_dev, 5884 "%s: firmware file too short: %zu bytes\n",5885 __func__,fw->size);5998 "%s: firmware too short: %zu bytes\n", __func__, 5999 fw->size); 5886 6000 return EINVAL; 5887 6001 } 5888 6002 /* Skip other alternatives. */ … … iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw, 5910 6024 fw->boot.text = ptr; 5911 6025 fw->boot.textsz = len; 5912 6026 break; 6027 case IWN_FW_TLV_ENH_SENS: 6028 if (!len) 6029 sc->sc_flags |= IWN_FLAG_ENH_SENS; 6030 break; 6031 case IWN_FW_TLV_PHY_CALIB: 6032 tmp = htole32(*ptr); 6033 if (tmp < 253) { 6034 sc->reset_noise_gain = tmp; 6035 sc->noise_gain = tmp + 1; 6036 } 6037 break; 5913 6038 default: 5914 6039 DPRINTF(sc, IWN_DEBUG_RESET, 5915 "%s: TLV type %d not handled\n", 5916 __func__, le16toh(tlv->type)); 6040 "TLV type %d not handled\n", le16toh(tlv->type)); 5917 6041 break; 5918 6042 } 5919 next: /* TLV fields are 32-bit aligned. */6043 next: /* TLV fields are 32-bit aligned. */ 5920 6044 ptr += (len + 3) & ~3; 5921 6045 } 5922 6046 return 0; … … next: /* TLV fields are 32-bit aligned. */ 5925 6049 static int 5926 6050 iwn_read_firmware(struct iwn_softc *sc) 5927 6051 { 5928 const struct iwn_hal *hal = sc->sc_hal;5929 6052 struct iwn_fw_info *fw = &sc->fw; 5930 6053 int error; 5931 6054 … … iwn_read_firmware(struct iwn_softc *sc) 5936 6059 /* Read firmware image from filesystem. */ 5937 6060 sc->fw_fp = firmware_get(sc->fwname); 5938 6061 if (sc->fw_fp == NULL) { 5939 device_printf(sc->sc_dev, 5940 "%s: could not load firmare image \"%s\"\n", __func__, 5941 sc->fwname); 6062 device_printf(sc->sc_dev, "%s: could not read firmware %s\n", 6063 __func__, sc->fwname); 5942 6064 IWN_LOCK(sc); 5943 6065 return EINVAL; 5944 6066 } … … iwn_read_firmware(struct iwn_softc *sc) 5947 6069 fw->size = sc->fw_fp->datasize; 5948 6070 fw->data = (const uint8_t *)sc->fw_fp->data; 5949 6071 if (fw->size < sizeof (uint32_t)) { 5950 device_printf(sc->sc_dev, 5951 "%s: firmware file too short: %zu bytes\n", 6072 device_printf(sc->sc_dev, "%s: firmware too short: %zu bytes\n", 5952 6073 __func__, fw->size); 6074 firmware_put(sc->fw_fp, FIRMWARE_UNLOAD); 6075 sc->fw_fp = NULL; 5953 6076 return EINVAL; 5954 6077 } 5955 6078 … … iwn_read_firmware(struct iwn_softc *sc) 5960 6083 error = iwn_read_firmware_tlv(sc, fw, 1); 5961 6084 if (error != 0) { 5962 6085 device_printf(sc->sc_dev, 5963 "%s: could not read firmware sections\n", __func__); 6086 "%s: could not read firmware sections, error %d\n", 6087 __func__, error); 6088 firmware_put(sc->fw_fp, FIRMWARE_UNLOAD); 6089 sc->fw_fp = NULL; 5964 6090 return error; 5965 6091 } 5966 6092 5967 6093 /* Make sure text and data sections fit in hardware memory. */ 5968 if (fw->main.textsz > hal->fw_text_maxsz ||5969 fw->main.datasz > hal->fw_data_maxsz ||5970 fw->init.textsz > hal->fw_text_maxsz ||5971 fw->init.datasz > hal->fw_data_maxsz ||6094 if (fw->main.textsz > sc->fw_text_maxsz || 6095 fw->main.datasz > sc->fw_data_maxsz || 6096 fw->init.textsz > sc->fw_text_maxsz || 6097 fw->init.datasz > sc->fw_data_maxsz || 5972 6098 fw->boot.textsz > IWN_FW_BOOT_TEXT_MAXSZ || 5973 6099 (fw->boot.textsz & 3) != 0) { 5974 device_printf(sc->sc_dev, 5975 "%s: firmware sections too large\n", __func__); 6100 device_printf(sc->sc_dev, "%s: firmware sections too large\n", 6101 __func__); 6102 firmware_put(sc->fw_fp, FIRMWARE_UNLOAD); 6103 sc->fw_fp = NULL; 5976 6104 return EINVAL; 5977 6105 } 5978 6106 … … iwn_clock_wait(struct iwn_softc *sc) 6002 6130 static int 6003 6131 iwn_apm_init(struct iwn_softc *sc) 6004 6132 { 6005 uint32_t tmp;6133 uint32_t reg; 6006 6134 int error; 6007 6135 6008 /* Disable L0s exit timer (NMI bug workaround .)*/6136 /* Disable L0s exit timer (NMI bug workaround). */ 6009 6137 IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_DIS_L0S_TIMER); 6010 /* Don't wait for ICH L0s (ICH bug workaround .)*/6138 /* Don't wait for ICH L0s (ICH bug workaround). */ 6011 6139 IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_L1A_NO_L0S_RX); 6012 6140 6013 /* Set FH wait threshold to max (HW bug under stress workaround .)*/6141 /* Set FH wait threshold to max (HW bug under stress workaround). */ 6014 6142 IWN_SETBITS(sc, IWN_DBG_HPET_MEM, 0xffff0000); 6015 6143 6016 6144 /* Enable HAP INTA to move adapter from L1a to L0s. */ 6017 6145 IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_HAP_WAKE_L1A); 6018 6146 6019 6147 /* Retrieve PCIe Active State Power Management (ASPM). */ 6020 tmp= pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);6148 reg = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1); 6021 6149 /* Workaround for HW instability in PCIe L0->L0s->L1 transition. */ 6022 if ( tmp& 0x02) /* L1 Entry enabled. */6150 if (reg & 0x02) /* L1 Entry enabled. */ 6023 6151 IWN_SETBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA); 6024 6152 else 6025 6153 IWN_CLRBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA); … … iwn_apm_init(struct iwn_softc *sc) 6029 6157 IWN_SETBITS(sc, IWN_ANA_PLL, IWN_ANA_PLL_INIT); 6030 6158 6031 6159 /* Wait for clock stabilization before accessing prph. */ 6032 error = iwn_clock_wait(sc); 6033 if (error != 0) 6160 if ((error = iwn_clock_wait(sc)) != 0) 6034 6161 return error; 6035 6162 6036 error = iwn_nic_lock(sc); 6037 if (error != 0) 6163 if ((error = iwn_nic_lock(sc)) != 0) 6038 6164 return error; 6039 6040 6165 if (sc->hw_type == IWN_HW_REV_TYPE_4965) { 6041 /* Enable DMA and BSM (Bootstrap State Machine .)*/6166 /* Enable DMA and BSM (Bootstrap State Machine). */ 6042 6167 iwn_prph_write(sc, IWN_APMG_CLK_EN, 6043 6168 IWN_APMG_CLK_CTRL_DMA_CLK_RQT | 6044 6169 IWN_APMG_CLK_CTRL_BSM_CLK_RQT); … … iwn_apm_init(struct iwn_softc *sc) 6048 6173 IWN_APMG_CLK_CTRL_DMA_CLK_RQT); 6049 6174 } 6050 6175 DELAY(20); 6051 6052 6176 /* Disable L1-Active. */ 6053 6177 iwn_prph_setbits(sc, IWN_APMG_PCI_STT, IWN_APMG_PCI_STT_L1A_DIS); 6054 6178 iwn_nic_unlock(sc); … … iwn_apm_stop_master(struct iwn_softc *sc) 6068 6192 return; 6069 6193 DELAY(10); 6070 6194 } 6071 device_printf(sc->sc_dev, "%s: timeout waiting for master\n", 6072 __func__); 6195 device_printf(sc->sc_dev, "%s: timeout waiting for master\n", __func__); 6073 6196 } 6074 6197 6075 6198 static void … … iwn5000_nic_config(struct iwn_softc *sc) 6118 6241 IWN_SETBITS(sc, IWN_HW_IF_CONFIG, 6119 6242 IWN_HW_IF_CONFIG_RADIO_SI | IWN_HW_IF_CONFIG_MAC_SI); 6120 6243 6121 error = iwn_nic_lock(sc); 6122 if (error != 0) 6244 if ((error = iwn_nic_lock(sc)) != 0) 6123 6245 return error; 6124 6246 iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_EARLY_PWROFF_DIS); 6125 6247 … … iwn5000_nic_config(struct iwn_softc *sc) 6140 6262 /* Use internal power amplifier only. */ 6141 6263 IWN_WRITE(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_RADIO_2X2_IPA); 6142 6264 } 6143 if (sc->hw_type == IWN_HW_REV_TYPE_6050 && sc->calib_ver >= 6) { 6265 if ((sc->hw_type == IWN_HW_REV_TYPE_6050 || 6266 sc->hw_type == IWN_HW_REV_TYPE_6005) && sc->calib_ver >= 6) { 6144 6267 /* Indicate that ROM calibration version is >=6. */ 6145 6268 IWN_SETBITS(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_CALIB_VER6); 6146 6269 } 6270 if (sc->hw_type == IWN_HW_REV_TYPE_6005) 6271 IWN_SETBITS(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_6050_1X2); 6147 6272 return 0; 6148 6273 } 6149 6274 … … iwn_hw_prepare(struct iwn_softc *sc) 6189 6314 static int 6190 6315 iwn_hw_init(struct iwn_softc *sc) 6191 6316 { 6192 const struct iwn_hal *hal = sc->sc_hal;6317 struct iwn_ops *ops = &sc->ops; 6193 6318 int error, chnl, qid; 6194 6319 6195 6320 /* Clear pending interrupts. */ 6196 6321 IWN_WRITE(sc, IWN_INT, 0xffffffff); 6197 6322 6198 error = iwn_apm_init(sc); 6199 if (error != 0) { 6323 if ((error = iwn_apm_init(sc)) != 0) { 6200 6324 device_printf(sc->sc_dev, 6201 "%s: could not power ON adapter, error %d\n", 6202 __func__,error);6325 "%s: could not power ON adapter, error %d\n", __func__, 6326 error); 6203 6327 return error; 6204 6328 } 6205 6329 6206 6330 /* Select VMAIN power source. */ 6207 error = iwn_nic_lock(sc); 6208 if (error != 0) 6331 if ((error = iwn_nic_lock(sc)) != 0) 6209 6332 return error; 6210 6333 iwn_prph_clrbits(sc, IWN_APMG_PS, IWN_APMG_PS_PWR_SRC_MASK); 6211 6334 iwn_nic_unlock(sc); 6212 6335 6213 6336 /* Perform adapter-specific initialization. */ 6214 error = hal->nic_config(sc); 6215 if (error != 0) 6337 if ((error = ops->nic_config(sc)) != 0) 6216 6338 return error; 6217 6339 6218 6340 /* Initialize RX ring. */ 6219 error = iwn_nic_lock(sc); 6220 if (error != 0) 6341 if ((error = iwn_nic_lock(sc)) != 0) 6221 6342 return error; 6222 6343 IWN_WRITE(sc, IWN_FH_RX_CONFIG, 0); 6223 6344 IWN_WRITE(sc, IWN_FH_RX_WPTR, 0); 6224 /* Set physical address of RX ring (256-byte aligned .)*/6345 /* Set physical address of RX ring (256-byte aligned). */ 6225 6346 IWN_WRITE(sc, IWN_FH_RX_BASE, sc->rxq.desc_dma.paddr >> 8); 6226 /* Set physical address of RX status (16-byte aligned .)*/6347 /* Set physical address of RX status (16-byte aligned). */ 6227 6348 IWN_WRITE(sc, IWN_FH_STATUS_WPTR, sc->rxq.stat_dma.paddr >> 4); 6228 6349 /* Enable RX. */ 6229 6350 IWN_WRITE(sc, IWN_FH_RX_CONFIG, … … iwn_hw_init(struct iwn_softc *sc) 6236 6357 iwn_nic_unlock(sc); 6237 6358 IWN_WRITE(sc, IWN_FH_RX_WPTR, (IWN_RX_RING_COUNT - 1) & ~7); 6238 6359 6239 error = iwn_nic_lock(sc); 6240 if (error != 0) 6360 if ((error = iwn_nic_lock(sc)) != 0) 6241 6361 return error; 6242 6362 6243 6363 /* Initialize TX scheduler. */ 6244 iwn_prph_write(sc, hal->sched_txfact_addr, 0);6364 iwn_prph_write(sc, sc->sched_txfact_addr, 0); 6245 6365 6246 /* Set physical address of "keep warm" page (16-byte aligned .)*/6366 /* Set physical address of "keep warm" page (16-byte aligned). */ 6247 6367 IWN_WRITE(sc, IWN_FH_KW_ADDR, sc->kw_dma.paddr >> 4); 6248 6368 6249 6369 /* Initialize TX rings. */ 6250 for (qid = 0; qid < hal->ntxqs; qid++) {6370 for (qid = 0; qid < sc->ntxqs; qid++) { 6251 6371 struct iwn_tx_ring *txq = &sc->txq[qid]; 6252 6372 6253 /* Set physical address of TX ring (256-byte aligned .)*/6373 /* Set physical address of TX ring (256-byte aligned). */ 6254 6374 IWN_WRITE(sc, IWN_FH_CBBC_QUEUE(qid), 6255 6375 txq->desc_dma.paddr >> 8); 6256 6376 } 6257 6377 iwn_nic_unlock(sc); 6258 6378 6259 6379 /* Enable DMA channels. */ 6260 for (chnl = 0; chnl < hal->ndmachnls; chnl++) {6380 for (chnl = 0; chnl < sc->ndmachnls; chnl++) { 6261 6381 IWN_WRITE(sc, IWN_FH_TX_CONFIG(chnl), 6262 6382 IWN_FH_TX_CONFIG_DMA_ENA | 6263 6383 IWN_FH_TX_CONFIG_DMA_CREDIT_ENA); … … iwn_hw_init(struct iwn_softc *sc) 6278 6398 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL); 6279 6399 IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL); 6280 6400 6281 error = hal->load_firmware(sc); 6282 if (error != 0) { 6401 /* Enable shadow registers. */ 6402 if (sc->hw_type >= IWN_HW_REV_TYPE_6000) 6403 IWN_SETBITS(sc, IWN_SHADOW_REG_CTRL, 0x800fffff); 6404 6405 if ((error = ops->load_firmware(sc)) != 0) { 6283 6406 device_printf(sc->sc_dev, 6284 "%s: could not load firmware, error %d\n", 6285 __func__,error);6407 "%s: could not load firmware, error %d\n", __func__, 6408 error); 6286 6409 return error; 6287 6410 } 6288 6411 /* Wait at most one second for firmware alive notification. */ 6289 error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz); 6290 if (error != 0) { 6412 if ((error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz)) != 0) { 6291 6413 device_printf(sc->sc_dev, 6292 6414 "%s: timeout waiting for adapter to initialize, error %d\n", 6293 6415 __func__, error); 6294 6416 return error; 6295 6417 } 6296 6418 /* Do post-firmware initialization. */ 6297 return hal->post_alive(sc);6419 return ops->post_alive(sc); 6298 6420 } 6299 6421 6300 6422 static void 6301 6423 iwn_hw_stop(struct iwn_softc *sc) 6302 6424 { 6303 const struct iwn_hal *hal = sc->sc_hal;6304 uint32_t tmp;6305 6425 int chnl, qid, ntries; 6306 6426 6307 6427 IWN_WRITE(sc, IWN_RESET, IWN_RESET_NEVO); … … iwn_hw_stop(struct iwn_softc *sc) 6316 6436 iwn_nic_unlock(sc); 6317 6437 6318 6438 /* Stop TX scheduler. */ 6319 iwn_prph_write(sc, hal->sched_txfact_addr, 0);6439 iwn_prph_write(sc, sc->sched_txfact_addr, 0); 6320 6440 6321 6441 /* Stop all DMA channels. */ 6322 6442 if (iwn_nic_lock(sc) == 0) { 6323 for (chnl = 0; chnl < hal->ndmachnls; chnl++) {6443 for (chnl = 0; chnl < sc->ndmachnls; chnl++) { 6324 6444 IWN_WRITE(sc, IWN_FH_TX_CONFIG(chnl), 0); 6325 6445 for (ntries = 0; ntries < 200; ntries++) { 6326 tmp = IWN_READ(sc, IWN_FH_TX_STATUS); 6327 if ((tmp & IWN_FH_TX_STATUS_IDLE(chnl)) == 6446 if (IWN_READ(sc, IWN_FH_TX_STATUS) & 6328 6447 IWN_FH_TX_STATUS_IDLE(chnl)) 6329 6448 break; 6330 6449 DELAY(10); … … iwn_hw_stop(struct iwn_softc *sc) 6337 6456 iwn_reset_rx_ring(sc, &sc->rxq); 6338 6457 6339 6458 /* Reset all TX rings. */ 6340 for (qid = 0; qid < hal->ntxqs; qid++)6459 for (qid = 0; qid < sc->ntxqs; qid++) 6341 6460 iwn_reset_tx_ring(sc, &sc->txq[qid]); 6342 6461 6343 6462 if (iwn_nic_lock(sc) == 0) { … … iwn_hw_stop(struct iwn_softc *sc) 6346 6465 iwn_nic_unlock(sc); 6347 6466 } 6348 6467 DELAY(5); 6349 6350 6468 /* Power OFF adapter. */ 6351 6469 iwn_apm_stop(sc); 6352 6470 } 6353 6471 6354 6472 static void 6473 iwn_radio_on(void *arg0, int pending) 6474 { 6475 struct iwn_softc *sc = arg0; 6476 struct ifnet *ifp = sc->sc_ifp; 6477 struct ieee80211com *ic = ifp->if_l2com; 6478 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 6479 6480 if (vap != NULL) { 6481 iwn_init(sc); 6482 ieee80211_init(vap); 6483 } 6484 } 6485 6486 static void 6487 iwn_radio_off(void *arg0, int pending) 6488 { 6489 struct iwn_softc *sc = arg0; 6490 struct ifnet *ifp = sc->sc_ifp; 6491 struct ieee80211com *ic = ifp->if_l2com; 6492 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 6493 6494 iwn_stop(sc); 6495 if (vap != NULL) 6496 ieee80211_stop(vap); 6497 6498 /* Enable interrupts to get RF toggle notification. */ 6499 IWN_LOCK(sc); 6500 IWN_WRITE(sc, IWN_INT, 0xffffffff); 6501 IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask); 6502 IWN_UNLOCK(sc); 6503 } 6504 6505 static void 6355 6506 iwn_init_locked(struct iwn_softc *sc) 6356 6507 { 6357 6508 struct ifnet *ifp = sc->sc_ifp; … … iwn_init_locked(struct iwn_softc *sc) 6359 6510 6360 6511 IWN_LOCK_ASSERT(sc); 6361 6512 6362 error = iwn_hw_prepare(sc); 6363 if (error != 0) { 6364 device_printf(sc->sc_dev, "%s: hardware not ready, eror %d\n", 6513 if ((error = iwn_hw_prepare(sc)) != 0) { 6514 device_printf(sc->sc_dev, "%s: hardware not ready, error %d\n", 6365 6515 __func__, error); 6366 6516 goto fail; 6367 6517 } … … iwn_init_locked(struct iwn_softc *sc) 6374 6524 if (!(IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)) { 6375 6525 device_printf(sc->sc_dev, 6376 6526 "radio is disabled by hardware switch\n"); 6377 6378 6527 /* Enable interrupts to get RF toggle notifications. */ 6379 6528 IWN_WRITE(sc, IWN_INT, 0xffffffff); 6380 6529 IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask); … … iwn_init_locked(struct iwn_softc *sc) 6382 6531 } 6383 6532 6384 6533 /* Read firmware images from the filesystem. */ 6385 error = iwn_read_firmware(sc); 6386 if (error != 0) { 6534 if ((error = iwn_read_firmware(sc)) != 0) { 6387 6535 device_printf(sc->sc_dev, 6388 "%s: could not read firmware, error %d\n", 6389 __func__,error);6536 "%s: could not read firmware, error %d\n", __func__, 6537 error); 6390 6538 goto fail; 6391 6539 } 6392 6540 … … iwn_init_locked(struct iwn_softc *sc) 6396 6544 sc->fw_fp = NULL; 6397 6545 if (error != 0) { 6398 6546 device_printf(sc->sc_dev, 6399 "%s: could not initialize hardware, error %d\n", 6400 __func__,error);6547 "%s: could not initialize hardware, error %d\n", __func__, 6548 error); 6401 6549 goto fail; 6402 6550 } 6403 6551 6404 6552 /* Configure adapter now that it is ready. */ 6405 error = iwn_config(sc); 6406 if (error != 0) { 6553 if ((error = iwn_config(sc)) != 0) { 6407 6554 device_printf(sc->sc_dev, 6408 "%s: could not configure device, error %d\n", 6409 __func__,error);6555 "%s: could not configure device, error %d\n", __func__, 6556 error); 6410 6557 goto fail; 6411 6558 } 6412 6559 6413 6560 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 6414 6561 ifp->if_drv_flags |= IFF_DRV_RUNNING; 6415 6562 6563 callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc); 6416 6564 return; 6417 6565 6418 fail: 6419 iwn_stop_locked(sc); 6566 fail: iwn_stop_locked(sc); 6420 6567 } 6421 6568 6422 6569 static void … … iwn_stop_locked(struct iwn_softc *sc) 6442 6589 IWN_LOCK_ASSERT(sc); 6443 6590 6444 6591 sc->sc_tx_timer = 0; 6445 callout_stop(&sc->sc_timer_to); 6592 callout_stop(&sc->watchdog_to); 6593 callout_stop(&sc->calib_to); 6446 6594 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 6447 6595 6448 6596 /* Power OFF hardware. */ … … iwn_set_channel(struct ieee80211com *ic) 6499 6647 const struct ieee80211_channel *c = ic->ic_curchan; 6500 6648 struct ifnet *ifp = ic->ic_ifp; 6501 6649 struct iwn_softc *sc = ifp->if_softc; 6650 int error; 6502 6651 6503 6652 IWN_LOCK(sc); 6504 6653 sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq); 6505 6654 sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags); 6506 6655 sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq); 6507 6656 sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags); 6657 6658 /* 6659 * Only need to set the channel in Monitor mode. AP scanning and auth 6660 * are already taken care of by their respective firmware commands. 6661 */ 6662 if (ic->ic_opmode == IEEE80211_M_MONITOR) { 6663 error = iwn_config(sc); 6664 if (error != 0) 6665 device_printf(sc->sc_dev, 6666 "%s: error %d settting channel\n", __func__, error); 6667 } 6508 6668 IWN_UNLOCK(sc); 6509 6669 } 6510 6670 … … iwn_scan_mindwell(struct ieee80211_scan_state *ss) 6536 6696 /* NB: don't try to abort scan; wait for firmware to finish */ 6537 6697 } 6538 6698 6539 static struct iwn_eeprom_chan *6540 iwn_find_eeprom_channel(struct iwn_softc *sc, struct ieee80211_channel *c)6541 {6542 int i, j;6543 6544 for (j = 0; j < 7; j++) {6545 for (i = 0; i < iwn_bands[j].nchan; i++) {6546 if (iwn_bands[j].chan[i] == c->ic_ieee)6547 return &sc->eeprom_channels[j][i];6548 }6549 }6550 6551 return NULL;6552 }6553 6554 /*6555 * Enforce flags read from EEPROM.6556 */6557 static int6558 iwn_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,6559 int nchan, struct ieee80211_channel chans[])6560 {6561 struct iwn_softc *sc = ic->ic_ifp->if_softc;6562 int i;6563 6564 for (i = 0; i < nchan; i++) {6565 struct ieee80211_channel *c = &chans[i];6566 struct iwn_eeprom_chan *channel;6567 6568 channel = iwn_find_eeprom_channel(sc, c);6569 if (channel == NULL) {6570 if_printf(ic->ic_ifp,6571 "%s: invalid channel %u freq %u/0x%x\n",6572 __func__, c->ic_ieee, c->ic_freq, c->ic_flags);6573 return EINVAL;6574 }6575 c->ic_flags |= iwn_eeprom_channel_flags(channel);6576 }6577 6578 return 0;6579 }6580 6581 6699 static void 6582 6700 iwn_hw_reset(void *arg0, int pending) 6583 6701 { … … iwn_hw_reset(void *arg0, int pending) 6589 6707 iwn_init(sc); 6590 6708 ieee80211_notify_radio(ic, 1); 6591 6709 } 6592 6593 static void6594 iwn_radio_on(void *arg0, int pending)6595 {6596 struct iwn_softc *sc = arg0;6597 struct ifnet *ifp = sc->sc_ifp;6598 struct ieee80211com *ic = ifp->if_l2com;6599 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);6600 6601 if (vap != NULL) {6602 iwn_init(sc);6603 ieee80211_init(vap);6604 }6605 }6606 6607 static void6608 iwn_radio_off(void *arg0, int pending)6609 {6610 struct iwn_softc *sc = arg0;6611 struct ifnet *ifp = sc->sc_ifp;6612 struct ieee80211com *ic = ifp->if_l2com;6613 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);6614 6615 iwn_stop(sc);6616 if (vap != NULL)6617 ieee80211_stop(vap);6618 6619 /* Enable interrupts to get RF toggle notification. */6620 IWN_LOCK(sc);6621 IWN_WRITE(sc, IWN_INT, 0xffffffff);6622 IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);6623 IWN_UNLOCK(sc);6624 }6625 6626 static void6627 iwn_sysctlattach(struct iwn_softc *sc)6628 {6629 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);6630 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);6631 6632 #ifdef IWN_DEBUG6633 sc->sc_debug = 0;6634 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,6635 "debug", CTLFLAG_RW, &sc->sc_debug, 0, "control debugging printfs");6636 #endif6637 }6638 6639 static int6640 iwn_shutdown(device_t dev)6641 {6642 struct iwn_softc *sc = device_get_softc(dev);6643 6644 iwn_stop(sc);6645 return 0;6646 }6647 6648 static int6649 iwn_suspend(device_t dev)6650 {6651 struct iwn_softc *sc = device_get_softc(dev);6652 struct ifnet *ifp = sc->sc_ifp;6653 struct ieee80211com *ic = ifp->if_l2com;6654 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);6655 6656 iwn_stop(sc);6657 if (vap != NULL)6658 ieee80211_stop(vap);6659 return 0;6660 }6661 6662 static int6663 iwn_resume(device_t dev)6664 {6665 struct iwn_softc *sc = device_get_softc(dev);6666 struct ifnet *ifp = sc->sc_ifp;6667 struct ieee80211com *ic = ifp->if_l2com;6668 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);6669 6670 /* Clear device-specific "PCI retry timeout" register (41h). */6671 pci_write_config(dev, 0x41, 0, 1);6672 6673 if (ifp->if_flags & IFF_UP) {6674 iwn_init(sc);6675 if (vap != NULL)6676 ieee80211_init(vap);6677 if (ifp->if_drv_flags & IFF_DRV_RUNNING)6678 iwn_start(ifp);6679 }6680 return 0;6681 }6682 6683 #ifdef IWN_DEBUG6684 static const char *6685 iwn_intr_str(uint8_t cmd)6686 {6687 switch (cmd) {6688 /* Notifications */6689 case IWN_UC_READY: return "UC_READY";6690 case IWN_ADD_NODE_DONE: return "ADD_NODE_DONE";6691 case IWN_TX_DONE: return "TX_DONE";6692 case IWN_START_SCAN: return "START_SCAN";6693 case IWN_STOP_SCAN: return "STOP_SCAN";6694 case IWN_RX_STATISTICS: return "RX_STATS";6695 case IWN_BEACON_STATISTICS: return "BEACON_STATS";6696 case IWN_STATE_CHANGED: return "STATE_CHANGED";6697 case IWN_BEACON_MISSED: return "BEACON_MISSED";6698 case IWN_RX_PHY: return "RX_PHY";6699 case IWN_MPDU_RX_DONE: return "MPDU_RX_DONE";6700 case IWN_RX_DONE: return "RX_DONE";6701 6702 /* Command Notifications */6703 case IWN_CMD_RXON: return "IWN_CMD_RXON";6704 case IWN_CMD_RXON_ASSOC: return "IWN_CMD_RXON_ASSOC";6705 case IWN_CMD_EDCA_PARAMS: return "IWN_CMD_EDCA_PARAMS";6706 case IWN_CMD_TIMING: return "IWN_CMD_TIMING";6707 case IWN_CMD_LINK_QUALITY: return "IWN_CMD_LINK_QUALITY";6708 case IWN_CMD_SET_LED: return "IWN_CMD_SET_LED";6709 case IWN5000_CMD_WIMAX_COEX: return "IWN5000_CMD_WIMAX_COEX";6710 case IWN5000_CMD_CALIB_CONFIG: return "IWN5000_CMD_CALIB_CONFIG";6711 case IWN5000_CMD_CALIB_RESULT: return "IWN5000_CMD_CALIB_RESULT";6712 case IWN5000_CMD_CALIB_COMPLETE: return "IWN5000_CMD_CALIB_COMPLETE";6713 case IWN_CMD_SET_POWER_MODE: return "IWN_CMD_SET_POWER_MODE";6714 case IWN_CMD_SCAN: return "IWN_CMD_SCAN";6715 case IWN_CMD_SCAN_RESULTS: return "IWN_CMD_SCAN_RESULTS";6716 case IWN_CMD_TXPOWER: return "IWN_CMD_TXPOWER";6717 case IWN_CMD_TXPOWER_DBM: return "IWN_CMD_TXPOWER_DBM";6718 case IWN5000_CMD_TX_ANT_CONFIG: return "IWN5000_CMD_TX_ANT_CONFIG";6719 case IWN_CMD_BT_COEX: return "IWN_CMD_BT_COEX";6720 case IWN_CMD_SET_CRITICAL_TEMP: return "IWN_CMD_SET_CRITICAL_TEMP";6721 case IWN_CMD_SET_SENSITIVITY: return "IWN_CMD_SET_SENSITIVITY";6722 case IWN_CMD_PHY_CALIB: return "IWN_CMD_PHY_CALIB";6723 }6724 return "UNKNOWN INTR NOTIF/CMD";6725 }6726 #endif /* IWN_DEBUG */6727 6728 static device_method_t iwn_methods[] = {6729 /* Device interface */6730 DEVMETHOD(device_probe, iwn_probe),6731 DEVMETHOD(device_attach, iwn_attach),6732 DEVMETHOD(device_detach, iwn_detach),6733 DEVMETHOD(device_shutdown, iwn_shutdown),6734 DEVMETHOD(device_suspend, iwn_suspend),6735 DEVMETHOD(device_resume, iwn_resume),6736 { 0, 0 }6737 };6738 6739 static driver_t iwn_driver = {6740 "iwn",6741 iwn_methods,6742 sizeof (struct iwn_softc)6743 };6744 static devclass_t iwn_devclass;6745 6746 DRIVER_MODULE(iwn, pci, iwn_driver, iwn_devclass, 0, 0);6747 MODULE_DEPEND(iwn, pci, 1, 1, 1);6748 MODULE_DEPEND(iwn, firmware, 1, 1, 1);6749 MODULE_DEPEND(iwn, wlan, 1, 1, 1); -
src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnreg.h
diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnreg.h b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnreg.h index 5472ea3..e08b309 100644
a b 17 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 19 */ 20 #ifndef __IF_IWNREG_H__21 #define __IF_IWNREG_H__22 23 #define IWN_CT_KILL_THRESHOLD 114 /* in Celsius */24 #define IWN_CT_KILL_EXIT_THRESHOLD 95 /* in Celsius */25 20 26 21 #define IWN_TX_RING_COUNT 256 27 22 #define IWN_TX_RING_LOMARK 192 … … 32 27 #define IWN4965_NTXQUEUES 16 33 28 #define IWN5000_NTXQUEUES 20 34 29 35 #define IWN4965_FIRSTAGGQUEUE 736 #define IWN5000_FIRSTAGGQUEUE 1037 38 30 #define IWN4965_NDMACHNLS 7 39 31 #define IWN5000_NDMACHNLS 8 40 32 … … 43 35 #define IWN_ICT_SIZE 4096 44 36 #define IWN_ICT_COUNT (IWN_ICT_SIZE / sizeof (uint32_t)) 45 37 46 /* For cards with PAN command, default is IWN_CMD_QUEUE_NUM */47 #define IWN_CMD_QUEUE_NUM 448 #define IWN_PAN_CMD_QUEUE 949 50 38 /* Maximum number of DMA segments for TX. */ 51 39 #define IWN_MAX_SCATTER 20 52 40 … … 71 59 #define IWN_INT 0x008 72 60 #define IWN_INT_MASK 0x00c 73 61 #define IWN_FH_INT 0x010 74 #define IWN_GPIO_IN 0x018 /* read external chip pins */75 62 #define IWN_RESET 0x020 76 63 #define IWN_GP_CNTRL 0x024 77 64 #define IWN_HW_REV 0x028 … … 79 66 #define IWN_EEPROM_GP 0x030 80 67 #define IWN_OTP_GP 0x034 81 68 #define IWN_GIO 0x03c 82 #define IWN_GP_UCODE 0x04883 69 #define IWN_GP_DRIVER 0x050 84 #define IWN_UCODE_GP1 0x05485 #define IWN_UCODE_GP1_SET 0x05886 70 #define IWN_UCODE_GP1_CLR 0x05c 87 #define IWN_UCODE_GP2 0x06088 71 #define IWN_LED 0x094 89 72 #define IWN_DRAM_INT_TBL 0x0a0 90 73 #define IWN_SHADOW_REG_CTRL 0x0a8 … … 93 76 #define IWN_HW_REV_WA 0x22c 94 77 #define IWN_DBG_HPET_MEM 0x240 95 78 #define IWN_DBG_LINK_PWR_MGMT 0x250 96 /* Need nic_lock for use above */97 79 #define IWN_MEM_RADDR 0x40c 98 80 #define IWN_MEM_WADDR 0x410 99 81 #define IWN_MEM_WDATA 0x418 100 82 #define IWN_MEM_RDATA 0x41c 101 #define IWN_TARG_MBX_C 0x430102 83 #define IWN_PRPH_WADDR 0x444 103 84 #define IWN_PRPH_RADDR 0x448 104 85 #define IWN_PRPH_WDATA 0x44c … … 200 181 #define IWN_RESET_SW (1 << 7) 201 182 #define IWN_RESET_MASTER_DISABLED (1 << 8) 202 183 #define IWN_RESET_STOP_MASTER (1 << 9) 203 #define IWN_RESET_LINK_PWR_MGMT_DIS (1 U<< 31)184 #define IWN_RESET_LINK_PWR_MGMT_DIS (1 << 31) 204 185 205 186 /* Possible flags for register IWN_GP_CNTRL. */ 206 187 #define IWN_GP_CNTRL_MAC_ACCESS_ENA (1 << 0) … … 210 191 #define IWN_GP_CNTRL_SLEEP (1 << 4) 211 192 #define IWN_GP_CNTRL_RFKILL (1 << 27) 212 193 194 /* Possible flags for register IWN_HW_REV. */ 195 #define IWN_HW_REV_TYPE_SHIFT 4 196 #define IWN_HW_REV_TYPE_MASK 0x000000f0 197 #define IWN_HW_REV_TYPE_4965 0 198 #define IWN_HW_REV_TYPE_5300 2 199 #define IWN_HW_REV_TYPE_5350 3 200 #define IWN_HW_REV_TYPE_5150 4 201 #define IWN_HW_REV_TYPE_5100 5 202 #define IWN_HW_REV_TYPE_1000 6 203 #define IWN_HW_REV_TYPE_6000 7 204 #define IWN_HW_REV_TYPE_6050 8 205 #define IWN_HW_REV_TYPE_6005 11 206 213 207 /* Possible flags for register IWN_GIO_CHICKEN. */ 214 208 #define IWN_GIO_CHICKEN_L1A_NO_L0S_RX (1 << 23) 215 209 #define IWN_GIO_CHICKEN_DIS_L0S_TIMER (1 << 29) … … 223 217 #define IWN_GP_DRIVER_RADIO_2X2_IPA (2 << 0) 224 218 #define IWN_GP_DRIVER_CALIB_VER6 (1 << 2) 225 219 #define IWN_GP_DRIVER_6050_1X2 (1 << 3) 226 #define IWN_GP_DRIVER_REG_BIT_RADIO_IQ_INVERT (1 << 7)227 #define IWN_GP_DRIVER_NONE 0228 220 229 221 /* Possible flags for register IWN_UCODE_GP1_CLR. */ 230 222 #define IWN_UCODE_GP1_RFKILL (1 << 1) 231 223 #define IWN_UCODE_GP1_CMD_BLOCKED (1 << 2) 232 224 #define IWN_UCODE_GP1_CTEMP_STOP_RF (1 << 3) 233 #define IWN_UCODE_GP1_CFG_COMPLETE (1 << 5)234 225 235 226 /* Possible flags/values for register IWN_LED. */ 236 227 #define IWN_LED_BSM_CTRL (1 << 5) 237 228 #define IWN_LED_OFF 0x00000038 238 229 #define IWN_LED_ON 0x00000078 239 230 240 #define IWN_MAX_BLINK_TBL 10241 #define IWN_LED_STATIC_ON 0242 #define IWN_LED_STATIC_OFF 1243 #define IWN_LED_SLOW_BLINK 2244 #define IWN_LED_INT_BLINK 3245 #define IWN_LED_UNIT 0x1388 /* 5 ms */246 247 static const struct {248 uint16_t tpt; /* Mb/s */249 uint8_t on_time;250 uint8_t off_time;251 } blink_tbl[] =252 {253 {300, 5, 5},254 {200, 8, 8},255 {100, 11, 11},256 {70, 13, 13},257 {50, 15, 15},258 {20, 17, 17},259 {10, 19, 19},260 {5, 22, 22},261 {1, 26, 26},262 {0, 33, 33},263 /* SOLID_ON */264 };265 266 231 /* Possible flags for register IWN_DRAM_INT_TBL. */ 267 232 #define IWN_DRAM_INT_TBL_WRAP_CHECK (1 << 27) 268 #define IWN_DRAM_INT_TBL_ENABLE (1 U<< 31)233 #define IWN_DRAM_INT_TBL_ENABLE (1 << 31) 269 234 270 235 /* Possible values for register IWN_ANA_PLL. */ 271 236 #define IWN_ANA_PLL_INIT 0x00880300 … … static const struct { 275 240 276 241 /* Possible flags for register IWN_BSM_WR_CTRL. */ 277 242 #define IWN_BSM_WR_CTRL_START_EN (1 << 30) 278 #define IWN_BSM_WR_CTRL_START (1 U<< 31)243 #define IWN_BSM_WR_CTRL_START (1 << 31) 279 244 280 245 /* Possible flags for register IWN_INT. */ 281 246 #define IWN_INT_ALIVE (1 << 0) … … static const struct { 288 253 #define IWN_INT_FH_TX (1 << 27) 289 254 #define IWN_INT_RX_PERIODIC (1 << 28) 290 255 #define IWN_INT_HW_ERR (1 << 29) 291 #define IWN_INT_FH_RX (1 U<< 31)256 #define IWN_INT_FH_RX (1 << 31) 292 257 293 258 /* Shortcut. */ 294 259 #define IWN_INT_MASK_DEF \ … … static const struct { 308 273 309 274 /* Possible flags/values for register IWN_FH_TX_CONFIG. */ 310 275 #define IWN_FH_TX_CONFIG_DMA_PAUSE 0 311 #define IWN_FH_TX_CONFIG_DMA_ENA (1 U<< 31)276 #define IWN_FH_TX_CONFIG_DMA_ENA (1 << 31) 312 277 #define IWN_FH_TX_CONFIG_CIRQ_HOST_ENDTFD (1 << 20) 313 278 314 279 /* Possible flags/values for register IWN_FH_TXBUF_STATUS. */ … … static const struct { 323 288 #define IWN_FH_TX_STATUS_IDLE(chnl) (1 << ((chnl) + 16)) 324 289 325 290 /* Possible flags for register IWN_FH_RX_CONFIG. */ 326 #define IWN_FH_RX_CONFIG_ENA (1 U<< 31)291 #define IWN_FH_RX_CONFIG_ENA (1 << 31) 327 292 #define IWN_FH_RX_CONFIG_NRBD(x) ((x) << 20) 328 293 #define IWN_FH_RX_CONFIG_RB_SIZE_8K (1 << 16) 329 294 #define IWN_FH_RX_CONFIG_SINGLE_FRAME (1 << 15) … … static const struct { 332 297 #define IWN_FH_RX_CONFIG_IGN_RXF_EMPTY (1 << 2) 333 298 334 299 /* Possible flags for register IWN_FH_TX_CONFIG. */ 335 #define IWN_FH_TX_CONFIG_DMA_ENA (1 U<< 31)300 #define IWN_FH_TX_CONFIG_DMA_ENA (1 << 31) 336 301 #define IWN_FH_TX_CONFIG_DMA_CREDIT_ENA (1 << 3) 337 302 338 303 /* Possible flags for register IWN_EEPROM. */ … … static const struct { 380 345 #define IWN_APMG_PCI_STT_L1A_DIS (1 << 11) 381 346 382 347 /* Possible flags for register IWN_BSM_DRAM_TEXT_SIZE. */ 383 #define IWN_FW_UPDATED (1 U<< 31)348 #define IWN_FW_UPDATED (1 << 31) 384 349 385 350 #define IWN_SCHED_WINSZ 64 386 351 #define IWN_SCHED_LIMIT 64 … … struct iwn_rx_status { 409 374 } __packed; 410 375 411 376 struct iwn_rx_desc { 412 /*413 * The first 4 bytes of the RX frame header contain both the RX frame414 * size and some flags.415 * Bit fields:416 * 31: flag flush RB request417 * 30: flag ignore TC (terminal counter) request418 * 29: flag fast IRQ request419 * 28-14: Reserved420 * 13-00: RX frame size421 */422 377 uint32_t len; 423 378 uint8_t type; 424 379 #define IWN_UC_READY 1 425 380 #define IWN_ADD_NODE_DONE 24 426 381 #define IWN_TX_DONE 28 427 #define IWN_REPLY_LED_CMD 72428 382 #define IWN5000_CALIBRATION_RESULT 102 429 383 #define IWN5000_CALIBRATION_DONE 103 430 384 #define IWN_START_SCAN 130 431 #define IWN_NOTIF_SCAN_RESULT 131432 385 #define IWN_STOP_SCAN 132 433 386 #define IWN_RX_STATISTICS 156 434 387 #define IWN_BEACON_STATISTICS 157 … … struct iwn_rx_desc { 439 392 #define IWN_RX_DONE 195 440 393 #define IWN_RX_COMPRESSED_BA 197 441 394 442 uint8_t flags; /* 0:5 reserved, 6 abort, 7 internal */443 uint8_t idx; /* position within TX queue */395 uint8_t flags; 396 uint8_t idx; 444 397 uint8_t qid; 445 /* 0:4 TX queue id - 5:6 reserved - 7 unsolicited RX446 * or uCode-originated notification447 */448 398 } __packed; 449 399 450 #define IWN_RX_DESC_QID_MSK 0x1F451 #define IWN_UNSOLICITED_RX_NOTIF 0x80452 453 /* CARD_STATE_NOTIFICATION */454 #define IWN_STATE_CHANGE_HW_CARD_DISABLED 0x01455 #define IWN_STATE_CHANGE_SW_CARD_DISABLED 0x02456 #define IWN_STATE_CHANGE_CT_CARD_DISABLED 0x04457 #define IWN_STATE_CHANGE_RXON_CARD_DISABLED 0x10458 459 400 /* Possible RX status flags. */ 460 401 #define IWN_RX_NO_CRC_ERR (1 << 0) 461 402 #define IWN_RX_NO_OVFL_ERR (1 << 1) … … struct iwn_tx_cmd { 479 420 #define IWN_CMD_LINK_QUALITY 78 480 421 #define IWN_CMD_SET_LED 72 481 422 #define IWN5000_CMD_WIMAX_COEX 90 482 #define IWN_TEMP_NOTIFICATION 98483 423 #define IWN5000_CMD_CALIB_CONFIG 101 484 424 #define IWN5000_CMD_CALIB_RESULT 102 485 425 #define IWN5000_CMD_CALIB_COMPLETE 103 … … struct iwn_tx_cmd { 496 436 #define IWN_CMD_PHY_CALIB 176 497 437 #define IWN_CMD_BT_COEX_PRIOTABLE 204 498 438 #define IWN_CMD_BT_COEX_PROT 205 499 #define IWN_CMD_BT_COEX_NOTIF 206500 /* PAN commands */501 #define IWN_CMD_WIPAN_PARAMS 0xb2502 #define IWN_CMD_WIPAN_RXON 0xb3503 #define IWN_CMD_WIPAN_RXON_TIMING 0xb4504 #define IWN_CMD_WIPAN_RXON_ASSOC 0xb6505 #define IWN_CMD_WIPAN_QOS_PARAM 0xb7506 #define IWN_CMD_WIPAN_WEPKEY 0xb8507 #define IWN_CMD_WIPAN_P2P_CHANNEL_SWITCH 0xb9508 #define IWN_CMD_WIPAN_NOA_NOTIFICATION 0xbc509 #define IWN_CMD_WIPAN_DEACTIVATION_COMPLETE 0xbd510 439 511 440 uint8_t flags; 512 441 uint8_t idx; … … struct iwn_tx_cmd { 514 443 uint8_t data[136]; 515 444 } __packed; 516 445 517 /*518 * Structure for IWN_CMD_GET_STATISTICS = (0x9c) 156519 * all devices identical.520 *521 * This command triggers an immediate response containing uCode statistics.522 * The response is in the same format as IWN_BEACON_STATISTICS (0x9d) 157.523 *524 * If the CLEAR_STATS configuration flag is set, uCode will clear its525 * internal copy of the statistics (counters) after issuing the response.526 * This flag does not affect IWN_BEACON_STATISTICS after beacons (see below).527 *528 * If the DISABLE_NOTIF configuration flag is set, uCode will not issue529 * IWN_BEACON_STATISTICS after received beacons. This flag530 * does not affect the response to the IWN_CMD_GET_STATISTICS 0x9c itself.531 */532 struct iwn_statistics_cmd {533 uint32_t configuration_flags;534 #define IWN_STATS_CONF_CLEAR_STATS htole32(0x1)535 #define IWN_STATS_CONF_DISABLE_NOTIF htole32(0x2)536 } __packed;537 538 446 /* Antenna flags, used in various commands. */ 539 447 #define IWN_ANT_A (1 << 0) 540 448 #define IWN_ANT_B (1 << 1) … … struct iwn_statistics_cmd { 542 450 /* Shortcuts. */ 543 451 #define IWN_ANT_AB (IWN_ANT_A | IWN_ANT_B) 544 452 #define IWN_ANT_BC (IWN_ANT_B | IWN_ANT_C) 545 #define IWN_ANT_AC (IWN_ANT_A | IWN_ANT_C)546 453 #define IWN_ANT_ABC (IWN_ANT_A | IWN_ANT_B | IWN_ANT_C) 547 454 548 455 /* Structure for command IWN_CMD_RXON. */ … … struct iwn_rxon { 558 465 #define IWN_MODE_STA 3 559 466 #define IWN_MODE_IBSS 4 560 467 #define IWN_MODE_MONITOR 6 561 #define IWN_MODE_2STA 8562 #define IWN_MODE_P2P 9563 468 564 469 uint8_t air; 565 470 uint16_t rxchain; … … struct iwn_rxon { 584 489 #define IWN_RXON_ANTENNA_A (1 << 8) 585 490 #define IWN_RXON_ANTENNA_B (1 << 9) 586 491 #define IWN_RXON_TSF (1 << 15) 587 #define IWN_RXON_HT_HT40MINUS (1 << 22)588 #define IWN_RXON_HT_PROTMODE(x) (x << 23)589 #define IWN_RXON_HT_MODEPURE40 (1 << 25)590 #define IWN_RXON_HT_MODEMIXED (2 << 25)591 492 #define IWN_RXON_CTS_TO_SELF (1 << 30) 592 493 593 494 uint32_t filter; … … struct iwn_cmd_timing { 643 544 uint16_t atim; 644 545 uint32_t binitval; 645 546 uint16_t lintval; 646 uint8_t dtim_period; 647 uint8_t delta_cp_bss_tbtts; 547 uint16_t reserved; 648 548 } __packed; 649 549 650 550 /* Structure for command IWN_CMD_ADD_NODE. */ … … struct iwn_node_info { 658 558 uint16_t reserved2; 659 559 uint8_t id; 660 560 #define IWN_ID_BSS 0 661 #define IWN_STA_ID 1662 663 #define IWN_PAN_ID_BCAST 14664 561 #define IWN5000_ID_BROADCAST 15 665 562 #define IWN4965_ID_BROADCAST 31 666 563 … … struct iwn_node_info { 691 588 uint8_t txmic[8]; 692 589 693 590 uint32_t htflags; 694 #define IWN_SMPS_MIMO_PROT (1 << 17)695 591 #define IWN_AMDPU_SIZE_FACTOR(x) ((x) << 19) 696 #define IWN_NODE_HT40 (1 << 21)697 #define IWN_SMPS_MIMO_DIS (1 << 22)698 592 #define IWN_AMDPU_DENSITY(x) ((x) << 23) 699 593 700 594 uint32_t mask; … … struct iwn4965_node_info { 731 625 uint32_t reserved7; 732 626 } __packed; 733 627 734 #define IWN_RFLAG_MCS (1 << 8) 735 #define IWN_RFLAG_CCK (1 << 9) 736 #define IWN_RFLAG_GREENFIELD (1 << 10) 737 #define IWN_RFLAG_HT40 (1 << 11) 738 #define IWN_RFLAG_DUPLICATE (1 << 12) 739 #define IWN_RFLAG_SGI (1 << 13) 740 #define IWN_RFLAG_ANT(x) ((x) << 14) 628 #define IWN_RFLAG_CCK (1 << 1) 629 #define IWN_RFLAG_ANT(x) ((x) << 6) 741 630 742 631 /* Structure for command IWN_CMD_TX_DATA. */ 743 632 struct iwn_cmd_data { … … struct iwn_cmd_data { 758 647 #define IWN_TX_NEED_PADDING (1 << 20) 759 648 760 649 uint32_t scratch; 761 uint32_t rate; 650 uint8_t plcp; 651 uint8_t rflags; 652 uint16_t xrflags; 762 653 763 654 uint8_t id; 764 655 uint8_t security; … … struct iwn_cmd_link_quality { 799 690 uint8_t ampdu_threshold; 800 691 uint8_t ampdu_max; 801 692 uint32_t reserved2; 802 uint32_t retry[IWN_MAX_TX_RETRIES]; 693 struct { 694 uint8_t plcp; 695 uint8_t rflags; 696 uint16_t xrflags; 697 } __packed retry[IWN_MAX_TX_RETRIES]; 803 698 uint32_t reserved3; 804 699 } __packed; 805 700 … … struct iwn5000_wimax_coex { 835 730 struct iwn5000_calib_elem { 836 731 uint32_t enable; 837 732 uint32_t start; 838 #define IWN5000_CALIB_DC (1 << 1)839 840 733 uint32_t send; 841 734 uint32_t apply; 842 735 uint32_t reserved; … … struct iwn_pmgt_cmd { 862 755 #define IWN_PS_SLEEP_OVER_DTIM (1 << 2) 863 756 #define IWN_PS_PCI_PMGT (1 << 3) 864 757 #define IWN_PS_FAST_PD (1 << 4) 865 #define IWN_PS_BEACON_FILTERING (1 << 5)866 #define IWN_PS_SHADOW_REG (1 << 6)867 #define IWN_PS_CT_KILL (1 << 7)868 #define IWN_PS_BT_SCD (1 << 8)869 #define IWN_PS_ADVANCED_PM (1 << 9)870 758 871 759 uint8_t keepalive; 872 760 uint8_t debug; … … struct iwn_scan_essid { 885 773 886 774 struct iwn_scan_hdr { 887 775 uint16_t len; 888 uint8_t scan_flags;776 uint8_t reserved1; 889 777 uint8_t nchan; 890 778 uint16_t quiet_time; 891 779 uint16_t quiet_threshold; … … struct iwn_scan_hdr { 904 792 905 793 struct iwn_scan_chan { 906 794 uint32_t flags; 907 #define IWN_CHAN_PASSIVE (0 << 0)908 795 #define IWN_CHAN_ACTIVE (1 << 0) 909 796 #define IWN_CHAN_NPBREQS(x) (((1 << (x)) - 1) << 1) 910 797 … … struct iwn_scan_chan { 915 802 uint16_t passive; /* msecs */ 916 803 } __packed; 917 804 918 #define IWN_SCAN_CRC_TH_DISABLED 0919 #define IWN_SCAN_CRC_TH_DEFAULT htole16(1)920 #define IWN_SCAN_CRC_TH_NEVER htole16(0xffff)921 922 805 /* Maximum size of a scan command. */ 923 806 #define IWN_SCAN_MAXSZ (MCLBYTES - 4) 924 807 925 /*926 * For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after927 * sending probe req. This should be set long enough to hear probe responses928 * from more than one AP.929 */930 #define IWN_ACTIVE_DWELL_TIME_2GHZ (30) /* all times in msec */931 #define IWN_ACTIVE_DWELL_TIME_5GHZ (20)932 #define IWN_ACTIVE_DWELL_FACTOR_2GHZ (3)933 #define IWN_ACTIVE_DWELL_FACTOR_5GHZ (2)934 935 /*936 * For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.937 * Must be set longer than active dwell time.938 * For the most reliable scan, set > AP beacon interval (typically 100msec).939 */940 #define IWN_PASSIVE_DWELL_TIME_2GHZ (20) /* all times in msec */941 #define IWN_PASSIVE_DWELL_TIME_5GHZ (10)942 #define IWN_PASSIVE_DWELL_BASE (100)943 #define IWN_CHANNEL_TUNE_TIME (5)944 945 #define IWN_SCAN_CHAN_TIMEOUT 2946 #define IWN_MAX_SCAN_CHANNEL 50947 948 /*949 * If active scanning is requested but a certain channel is950 * marked passive, we can do active scanning if we detect951 * transmissions.952 *953 * There is an issue with some firmware versions that triggers954 * a sysassert on a "good CRC threshold" of zero (== disabled),955 * on a radar channel even though this means that we should NOT956 * send probes.957 *958 * The "good CRC threshold" is the number of frames that we959 * need to receive during our dwell time on a channel before960 * sending out probes -- setting this to a huge value will961 * mean we never reach it, but at the same time work around962 * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER963 * here instead of IWL_GOOD_CRC_TH_DISABLED.964 *965 * This was fixed in later versions along with some other966 * scan changes, and the threshold behaves as a flag in those967 * versions.968 */969 #define IWN_GOOD_CRC_TH_DISABLED 0970 #define IWN_GOOD_CRC_TH_DEFAULT htole16(1)971 #define IWN_GOOD_CRC_TH_NEVER htole16(0xffff)972 973 808 /* Structure for command IWN_CMD_TXPOWER (4965AGN only.) */ 974 809 #define IWN_RIDX_MAX 32 975 810 struct iwn4965_cmd_txpower { … … struct iwn_bluetooth { 1016 851 1017 852 struct iwn6000_btcoex_config { 1018 853 uint8_t flags; 1019 #define IWN_BT_FLAG_COEX6000_CHAN_INHIBITION 11020 #define IWN_BT_FLAG_COEX6000_MODE_MASK ((1 << 3) | (1 << 4) | (1 << 5 ))1021 #define IWN_BT_FLAG_COEX6000_MODE_SHIFT 31022 #define IWN_BT_FLAG_COEX6000_MODE_DISABLED 01023 #define IWN_BT_FLAG_COEX6000_MODE_LEGACY_2W 11024 #define IWN_BT_FLAG_COEX6000_MODE_3W 21025 #define IWN_BT_FLAG_COEX6000_MODE_4W 31026 1027 #define IWN_BT_FLAG_UCODE_DEFAULT (1 << 6)1028 #define IWN_BT_FLAG_SYNC_2_BT_DISABLE (1 << 7)1029 854 uint8_t lead_time; 1030 855 uint8_t max_kill; 1031 856 uint8_t bt3_t7_timer; … … struct iwn6000_btcoex_config { 1042 867 uint16_t rx_prio_boost; 1043 868 } __packed; 1044 869 1045 /* Structure for enhanced command IWN_CMD_BLUETOOTH for 2000 Series. */1046 struct iwn2000_btcoex_config {1047 uint8_t flags; /* Cf Flags in iwn6000_btcoex_config */1048 uint8_t lead_time;1049 uint8_t max_kill;1050 uint8_t bt3_t7_timer;1051 uint32_t kill_ack;1052 uint32_t kill_cts;1053 uint8_t sample_time;1054 uint8_t bt3_t2_timer;1055 uint16_t bt4_reaction;1056 uint32_t lookup_table[12];1057 uint16_t bt4_decision;1058 uint16_t valid;1059 1060 uint32_t prio_boost; /* size change prior to iwn6000_btcoex_config */1061 uint8_t reserved; /* added prior to iwn6000_btcoex_config */1062 1063 uint8_t tx_prio_boost;1064 uint16_t rx_prio_boost;1065 } __packed;1066 1067 870 struct iwn_btcoex_priotable { 1068 871 uint8_t calib_init1; 1069 872 uint8_t calib_init2; … … struct iwn_enhanced_sensitivity_cmd { 1141 944 uint16_t reserved; 1142 945 } __packed; 1143 946 1144 /*1145 * Define maximal number of calib result send to runtime firmware1146 * PS: TEMP_OFFSET count for 2 (std and v2)1147 */1148 #define IWN5000_PHY_CALIB_MAX_RESULT 81149 1150 947 /* Structures for command IWN_CMD_PHY_CALIB. */ 1151 948 struct iwn_phy_calib { 1152 949 uint8_t code; … … struct iwn5000_phy_calib_temp_offset { 1188 985 uint16_t reserved; 1189 986 } __packed; 1190 987 1191 struct iwn5000_phy_calib_temp_offsetv2 {1192 uint8_t code;1193 uint8_t group;1194 uint8_t ngroups;1195 uint8_t isvalid;1196 int16_t offset_high;1197 int16_t offset_low;1198 int16_t burnt_voltage_ref;1199 int16_t reserved;1200 } __packed;1201 1202 988 struct iwn_phy_calib_gain { 1203 989 uint8_t code; 1204 990 uint8_t group; … … struct iwn_ucode_info { 1266 1052 } __packed; 1267 1053 1268 1054 /* Structures for IWN_TX_DONE notification. */ 1269 #define IWN_TX_STATUS_MSK 0xff1270 #define TX_STATUS_SUCCESS 0x011271 #define TX_STATUS_DIRECT_DONE 0x021272 1273 1055 #define IWN_TX_SUCCESS 0x00 1274 1056 #define IWN_TX_FAIL 0x80 /* all failures have 0x80 set */ 1275 1057 #define IWN_TX_FAIL_SHORT_LIMIT 0x82 /* too many RTS retries */ … … struct iwn_ucode_info { 1277 1059 #define IWN_TX_FAIL_FIFO_UNDERRRUN 0x84 /* tx fifo not kept running */ 1278 1060 #define IWN_TX_FAIL_DEST_IN_PS 0x88 /* sta found in power save */ 1279 1061 #define IWN_TX_FAIL_TX_LOCKED 0x90 /* waiting to see traffic */ 1280 #define IWN_TX_FAIL_STA_INVALID 0x8b /* XXX STA invalid (???) */1281 1062 1282 1063 struct iwn4965_tx_stat { 1283 1064 uint8_t nframes; 1284 1065 uint8_t btkillcnt; 1285 1066 uint8_t rtsfailcnt; 1286 1067 uint8_t ackfailcnt; 1287 uint32_t rate; 1068 uint8_t rate; 1069 uint8_t rflags; 1070 uint16_t xrflags; 1288 1071 uint16_t duration; 1289 1072 uint16_t reserved; 1290 1073 uint32_t power[2]; … … struct iwn4965_tx_stat { 1292 1075 } __packed; 1293 1076 1294 1077 struct iwn5000_tx_stat { 1295 uint8_t nframes; /* 1 no aggregation, >1 aggregation */1078 uint8_t nframes; 1296 1079 uint8_t btkillcnt; 1297 1080 uint8_t rtsfailcnt; 1298 1081 uint8_t ackfailcnt; 1299 uint32_t rate; 1082 uint8_t rate; 1083 uint8_t rflags; 1084 uint16_t xrflags; 1300 1085 uint16_t duration; 1301 1086 uint16_t reserved; 1302 1087 uint32_t power[2]; … … struct iwn5000_tx_stat { 1304 1089 uint16_t seq; 1305 1090 uint16_t len; 1306 1091 uint8_t tlc; 1307 uint8_t ratid; /* tid (0:3), sta_id (4:7) */1092 uint8_t ratid; 1308 1093 uint8_t fc[2]; 1309 1094 uint16_t status; 1310 1095 uint16_t sequence; … … struct iwn_rx_stat { 1351 1136 1352 1137 uint16_t chan; 1353 1138 uint8_t phybuf[32]; 1354 uint32_t rate; 1355 /* 1356 * rate bit fields 1357 * 1358 * High-throughput (HT) rate format for bits 7:0 (bit 8 must be "1"): 1359 * 2-0: 0) 6 Mbps 1360 * 1) 12 Mbps 1361 * 2) 18 Mbps 1362 * 3) 24 Mbps 1363 * 4) 36 Mbps 1364 * 5) 48 Mbps 1365 * 6) 54 Mbps 1366 * 7) 60 Mbps 1367 * 1368 * 4-3: 0) Single stream (SISO) 1369 * 1) Dual stream (MIMO) 1370 * 2) Triple stream (MIMO) 1371 * 1372 * 5: Value of 0x20 in bits 7:0 indicates 6 Mbps HT40 duplicate data 1373 * 1374 * Legacy OFDM rate format for bits 7:0 (bit 8 must be "0", bit 9 "0"): 1375 * 3-0: 0xD) 6 Mbps 1376 * 0xF) 9 Mbps 1377 * 0x5) 12 Mbps 1378 * 0x7) 18 Mbps 1379 * 0x9) 24 Mbps 1380 * 0xB) 36 Mbps 1381 * 0x1) 48 Mbps 1382 * 0x3) 54 Mbps 1383 * 1384 * Legacy CCK rate format for bits 7:0 (bit 8 must be "0", bit 9 "1"): 1385 * 6-0: 10) 1 Mbps 1386 * 20) 2 Mbps 1387 * 55) 5.5 Mbps 1388 * 110) 11 Mbps 1389 * 1390 */ 1139 uint8_t rate; 1140 uint8_t rflags; 1141 uint16_t xrflags; 1391 1142 uint16_t len; 1392 1143 uint16_t reserve3; 1393 1144 } __packed; … … struct iwn_rx_ht_phy_stats { 1509 1260 uint32_t good_ampdu_crc32; 1510 1261 uint32_t ampdu; 1511 1262 uint32_t fragment; 1512 uint32_t unsupport_mcs;1263 uint32_t reserved; 1513 1264 } __packed; 1514 1265 1515 1266 struct iwn_rx_stats { … … struct iwn_rx_stats { 1519 1270 struct iwn_rx_ht_phy_stats ht; 1520 1271 } __packed; 1521 1272 1522 struct iwn_rx_general_stats_bt {1523 struct iwn_rx_general_stats common;1524 /* additional stats for bt */1525 uint32_t num_bt_kills;1526 uint32_t reserved[2];1527 } __packed;1528 1529 struct iwn_rx_stats_bt {1530 struct iwn_rx_phy_stats ofdm;1531 struct iwn_rx_phy_stats cck;1532 struct iwn_rx_general_stats_bt general_bt;1533 struct iwn_rx_ht_phy_stats ht;1534 } __packed;1535 1536 1273 struct iwn_tx_stats { 1537 1274 uint32_t preamble; 1538 1275 uint32_t rx_detected; … … struct iwn_tx_stats { 1544 1281 uint32_t exp_ack; 1545 1282 uint32_t ack; 1546 1283 uint32_t msdu; 1547 uint32_t bu rst_err1;1284 uint32_t busrt_err1; 1548 1285 uint32_t burst_err2; 1549 1286 uint32_t cts_collision; 1550 1287 uint32_t ack_collision; … … struct iwn_tx_stats { 1558 1295 uint32_t underrun; 1559 1296 uint32_t bt_ht_kill; 1560 1297 uint32_t rx_ba_resp; 1561 /* 1562 * 6000 series only - LSB=ant A, ant B, ant C, MSB=reserved 1563 * TX power on chain in 1/2 dBm. 1564 */ 1565 uint32_t tx_power; 1566 uint32_t reserved[1]; 1298 uint32_t reserved[2]; 1567 1299 } __packed; 1568 1300 1569 1301 struct iwn_general_stats { 1570 uint32_t temp; /* radio temperature */1571 uint32_t temp_m; /* radio voltage */1302 uint32_t temp; 1303 uint32_t temp_m; 1572 1304 uint32_t burst_check; 1573 1305 uint32_t burst; 1574 uint32_t wait_for_silence_timeout_cnt; 1575 uint32_t reserved1[3]; 1306 uint32_t reserved1[4]; 1576 1307 uint32_t sleep; 1577 1308 uint32_t slot_out; 1578 1309 uint32_t slot_idle; … … struct iwn_general_stats { 1583 1314 uint32_t probe; 1584 1315 uint32_t reserved2[2]; 1585 1316 uint32_t rx_enabled; 1586 /* 1587 * This is the number of times we have to re-tune 1588 * in order to get out of bad PHY status. 1589 */ 1590 uint32_t num_of_sos_states; 1317 uint32_t reserved3[3]; 1591 1318 } __packed; 1592 1319 1593 1320 struct iwn_stats { … … struct iwn_stats { 1595 1322 struct iwn_rx_stats rx; 1596 1323 struct iwn_tx_stats tx; 1597 1324 struct iwn_general_stats general; 1598 uint32_t reserved1[2];1599 1325 } __packed; 1600 1326 1601 struct iwn_bt_activity_stats {1602 /* Tx statistics */1603 uint32_t hi_priority_tx_req_cnt;1604 uint32_t hi_priority_tx_denied_cnt;1605 uint32_t lo_priority_tx_req_cnt;1606 uint32_t lo_priority_tx_denied_cnt;1607 /* Rx statistics */1608 uint32_t hi_priority_rx_req_cnt;1609 uint32_t hi_priority_rx_denied_cnt;1610 uint32_t lo_priority_rx_req_cnt;1611 uint32_t lo_priority_rx_denied_cnt;1612 } __packed;1613 1614 struct iwn_stats_bt {1615 uint32_t flags;1616 struct iwn_rx_stats_bt rx_bt;1617 struct iwn_tx_stats tx;1618 struct iwn_general_stats general;1619 struct iwn_bt_activity_stats activity;1620 uint32_t reserved1[2];1621 };1622 1327 1623 1328 /* Firmware error dump. */ 1624 1329 struct iwn_fw_dump { … … struct iwn_fw_tlv { 1656 1361 #define IWN_FW_TLV_INIT_DATA 4 1657 1362 #define IWN_FW_TLV_BOOT_TEXT 5 1658 1363 #define IWN_FW_TLV_PBREQ_MAXLEN 6 1659 #define IWN_FW_TLV_PAN 71660 #define IWN_FW_TLV_RUNT_EVTLOG_PTR 81661 #define IWN_FW_TLV_RUNT_EVTLOG_SIZE 91662 #define IWN_FW_TLV_RUNT_ERRLOG_PTR 101663 #define IWN_FW_TLV_INIT_EVTLOG_PTR 111664 #define IWN_FW_TLV_INIT_EVTLOG_SIZE 121665 #define IWN_FW_TLV_INIT_ERRLOG_PTR 131666 1364 #define IWN_FW_TLV_ENH_SENS 14 1667 1365 #define IWN_FW_TLV_PHY_CALIB 15 1668 #define IWN_FW_TLV_WOWLAN_INST 161669 #define IWN_FW_TLV_WOWLAN_DATA 171670 #define IWN_FW_TLV_FLAGS 181671 1366 1672 1367 uint16_t alt; 1673 1368 uint32_t len; … … struct iwn_fw_tlv { 1682 1377 #define IWN5000_FWSZ IWN5000_FW_TEXT_MAXSZ 1683 1378 1684 1379 /* 1685 * Microcode flags TLV (18.)1686 */1687 1688 /**1689 * enum iwn_ucode_tlv_flag - ucode API flags1690 * @IWN_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously1691 * was a separate TLV but moved here to save space.1692 * @IWN_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,1693 * treats good CRC threshold as a boolean1694 * @IWN_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).1695 * @IWN_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.1696 * @IWN_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS1697 * @IWN_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD1698 * @IWN_UCODE_TLV_FLAGS_SHORT_BL: 16 entries of black list instead of 64 in scan1699 * offload profile config command.1700 * @IWN_UCODE_TLV_FLAGS_RX_ENERGY_API: supports rx signal strength api1701 * @IWN_UCODE_TLV_FLAGS_TIME_EVENT_API_V2: using the new time event API.1702 * @IWN_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six1703 * (rather than two) IPv6 addresses1704 * @IWN_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API1705 * @IWN_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element1706 * from the probe request template.1707 * @IWN_UCODE_TLV_FLAGS_D3_CONTINUITY_API: modified D3 API to allow keeping1708 * connection when going back to D01709 * @IWN_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL: new NS offload (small version)1710 * @IWN_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version)1711 * @IWN_UCODE_TLV_FLAGS_SCHED_SCAN: this uCode image supports scheduled scan.1712 * @IWN_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API1713 * @IWN_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command1714 * containing CAM (Continuous Active Mode) indication.1715 */1716 enum iwn_ucode_tlv_flag {1717 IWN_UCODE_TLV_FLAGS_PAN = (1 << 0),1718 IWN_UCODE_TLV_FLAGS_NEWSCAN = (1 << 1),1719 IWN_UCODE_TLV_FLAGS_MFP = (1 << 2),1720 IWN_UCODE_TLV_FLAGS_P2P = (1 << 3),1721 IWN_UCODE_TLV_FLAGS_DW_BC_TABLE = (1 << 4),1722 IWN_UCODE_TLV_FLAGS_NEWBT_COEX = (1 << 5),1723 IWN_UCODE_TLV_FLAGS_UAPSD = (1 << 6),1724 IWN_UCODE_TLV_FLAGS_SHORT_BL = (1 << 7),1725 IWN_UCODE_TLV_FLAGS_RX_ENERGY_API = (1 << 8),1726 IWN_UCODE_TLV_FLAGS_TIME_EVENT_API_V2 = (1 << 9),1727 IWN_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = (1 << 10),1728 IWN_UCODE_TLV_FLAGS_BF_UPDATED = (1 << 11),1729 IWN_UCODE_TLV_FLAGS_NO_BASIC_SSID = (1 << 12),1730 IWN_UCODE_TLV_FLAGS_D3_CONTINUITY_API = (1 << 14),1731 IWN_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL = (1 << 15),1732 IWN_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE = (1 << 16),1733 IWN_UCODE_TLV_FLAGS_SCHED_SCAN = (1 << 17),1734 IWN_UCODE_TLV_FLAGS_STA_KEY_CMD = (1 << 19),1735 IWN_UCODE_TLV_FLAGS_DEVICE_PS_CMD = (1 << 20),1736 };1737 1738 /*1739 1380 * Offsets into EEPROM. 1740 1381 */ 1741 1382 #define IWN_EEPROM_MAC 0x015 … … enum iwn_ucode_tlv_flag { 1755 1396 #define IWN4965_EEPROM_VOLTAGE 0x0e9 1756 1397 #define IWN4965_EEPROM_BANDS 0x0ea 1757 1398 /* Indirect offsets. */ 1758 #define IWN5000_EEPROM_NO_HT40 0x0001759 1399 #define IWN5000_EEPROM_DOMAIN 0x001 1760 1400 #define IWN5000_EEPROM_BAND1 0x004 1761 1401 #define IWN5000_EEPROM_BAND2 0x013 … … enum iwn_ucode_tlv_flag { 1763 1403 #define IWN5000_EEPROM_BAND4 0x02e 1764 1404 #define IWN5000_EEPROM_BAND5 0x03a 1765 1405 #define IWN5000_EEPROM_BAND6 0x041 1766 #define IWN6000_EEPROM_BAND6 0x0401767 1406 #define IWN5000_EEPROM_BAND7 0x049 1768 1407 #define IWN6000_EEPROM_ENHINFO 0x054 1769 1408 #define IWN5000_EEPROM_CRYSTAL 0x128 … … struct iwn_eeprom_chan { 1793 1432 } __packed; 1794 1433 1795 1434 struct iwn_eeprom_enhinfo { 1796 uint8_t flags; 1797 #define IWN_ENHINFO_VALID 0x01 1798 #define IWN_ENHINFO_5GHZ 0x02 1799 #define IWN_ENHINFO_OFDM 0x04 1800 #define IWN_ENHINFO_HT40 0x08 1801 #define IWN_ENHINFO_HTAP 0x10 1802 #define IWN_ENHINFO_RES1 0x20 1803 #define IWN_ENHINFO_RES2 0x40 1804 #define IWN_ENHINFO_COMMON 0x80 1805 1806 uint8_t chan; 1435 uint16_t chan; 1807 1436 int8_t chain[3]; /* max power in half-dBm */ 1808 1437 uint8_t reserved; 1809 1438 int8_t mimo2; /* max power in half-dBm */ … … static const uint32_t iwn5000_regulatory_bands[IWN_NBANDS] = { 1857 1486 IWN5000_EEPROM_BAND7 1858 1487 }; 1859 1488 1860 static const uint32_t iwn6000_regulatory_bands[IWN_NBANDS] = {1861 IWN5000_EEPROM_BAND1,1862 IWN5000_EEPROM_BAND2,1863 IWN5000_EEPROM_BAND3,1864 IWN5000_EEPROM_BAND4,1865 IWN5000_EEPROM_BAND5,1866 IWN6000_EEPROM_BAND6,1867 IWN5000_EEPROM_BAND71868 };1869 1870 static const uint32_t iwn1000_regulatory_bands[IWN_NBANDS] = {1871 IWN5000_EEPROM_BAND1,1872 IWN5000_EEPROM_BAND2,1873 IWN5000_EEPROM_BAND3,1874 IWN5000_EEPROM_BAND4,1875 IWN5000_EEPROM_BAND5,1876 IWN5000_EEPROM_BAND6,1877 IWN5000_EEPROM_NO_HT40,1878 };1879 1880 static const uint32_t iwn2030_regulatory_bands[IWN_NBANDS] = {1881 IWN5000_EEPROM_BAND1,1882 IWN5000_EEPROM_BAND2,1883 IWN5000_EEPROM_BAND3,1884 IWN5000_EEPROM_BAND4,1885 IWN5000_EEPROM_BAND5,1886 IWN6000_EEPROM_BAND6,1887 IWN5000_EEPROM_BAND71888 };1889 1890 1489 #define IWN_CHAN_BANDS_COUNT 7 1891 1490 #define IWN_MAX_CHAN_PER_BAND 14 1892 1491 static const struct iwn_chan_band { … … static const struct iwn_chan_band { 1906 1505 { 11, { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 } } 1907 1506 }; 1908 1507 1909 static const uint8_t iwn_bss_ac_to_queue[] = { 1910 2, 3, 1, 0, 1911 }; 1912 1913 static const uint8_t iwn_pan_ac_to_queue[] = { 1914 5, 4, 6, 7, 1915 }; 1916 #define IWN1000_OTP_NBLOCKS 3 1917 #define IWN6000_OTP_NBLOCKS 4 1508 #define IWN1000_OTP_NBLOCKS 3 1509 #define IWN6000_OTP_NBLOCKS 4 1918 1510 #define IWN6050_OTP_NBLOCKS 7 1919 1511 1920 1512 /* HW rate indices. */ 1921 1513 #define IWN_RIDX_CCK1 0 1922 1514 #define IWN_RIDX_OFDM6 4 1923 1515 1924 #define IWN4965_MAX_PWR_INDEX 107 1925 #define IWN_POWERSAVE_LVL_NONE 0 1926 #define IWN_POWERSAVE_LVL_VOIP_COMPATIBLE 1 1927 #define IWN_POWERSAVE_LVL_MAX 5 1928 1929 #define IWN_POWERSAVE_LVL_DEFAULT IWN_POWERSAVE_LVL_NONE 1516 static const struct iwn_rate { 1517 uint8_t rate; 1518 uint8_t plcp; 1519 uint8_t flags; 1520 } iwn_rates[IWN_RIDX_MAX + 1] = { 1521 { 2, 10, IWN_RFLAG_CCK }, 1522 { 4, 20, IWN_RFLAG_CCK }, 1523 { 11, 55, IWN_RFLAG_CCK }, 1524 { 22, 110, IWN_RFLAG_CCK }, 1525 { 12, 0xd, 0 }, 1526 { 18, 0xf, 0 }, 1527 { 24, 0x5, 0 }, 1528 { 36, 0x7, 0 }, 1529 { 48, 0x9, 0 }, 1530 { 72, 0xb, 0 }, 1531 { 96, 0x1, 0 }, 1532 { 108, 0x3, 0 }, 1533 { 120, 0x3, 0 } 1534 }; 1930 1535 1931 /* DTIM value to pass in for IWN_POWERSAVE_LVL_VOIP_COMPATIBLE */ 1932 #define IWN_POWERSAVE_DTIM_VOIP_COMPATIBLE 2 1536 #define IWN4965_MAX_PWR_INDEX 107 1933 1537 1934 1538 /* 1935 1539 * RF Tx gain values from highest to lowest power (values obtained from … … struct iwn_sensitivity_limits { 2047 1651 uint32_t min_energy_cck; 2048 1652 uint32_t energy_cck; 2049 1653 uint32_t energy_ofdm; 2050 uint32_t barker_mrc;2051 1654 }; 2052 1655 2053 1656 /* … … static const struct iwn_sensitivity_limits iwn4965_sensitivity_limits = { 2062 1665 200, 400, 2063 1666 97, 2064 1667 100, 2065 100, 2066 390 1668 100 2067 1669 }; 2068 1670 2069 1671 static const struct iwn_sensitivity_limits iwn5000_sensitivity_limits = { … … static const struct iwn_sensitivity_limits iwn5000_sensitivity_limits = { 2075 1677 170, 400, 2076 1678 95, 2077 1679 95, 2078 95, 2079 390 1680 95 2080 1681 }; 2081 1682 2082 1683 static const struct iwn_sensitivity_limits iwn5150_sensitivity_limits = { … … static const struct iwn_sensitivity_limits iwn5150_sensitivity_limits = { 2088 1689 170, 400, 2089 1690 95, 2090 1691 95, 2091 95, 2092 390, 1692 95 2093 1693 }; 2094 1694 2095 1695 static const struct iwn_sensitivity_limits iwn1000_sensitivity_limits = { … … static const struct iwn_sensitivity_limits iwn1000_sensitivity_limits = { 2101 1701 170, 400, 2102 1702 95, 2103 1703 95, 2104 95, 2105 390, 1704 95 2106 1705 }; 2107 1706 2108 1707 static const struct iwn_sensitivity_limits iwn6000_sensitivity_limits = { … … static const struct iwn_sensitivity_limits iwn6000_sensitivity_limits = { 2114 1713 160, 310, 2115 1714 97, 2116 1715 97, 2117 100, 2118 390 2119 }; 2120 2121 static const struct iwn_sensitivity_limits iwn6235_sensitivity_limits = { 2122 105, 110, 2123 192, 232, 2124 80, 145, 2125 128, 232, 2126 125, 175, 2127 160, 310, 2128 100, 2129 110, 2130 110, 2131 336 2132 }; 2133 2134 2135 /* Get value from linux kernel 3.2.+ in Drivers/net/wireless/iwlwifi/iwl-2000.c*/ 2136 static const struct iwn_sensitivity_limits iwn2030_sensitivity_limits = { 2137 105,110, 2138 128,232, 2139 80,145, 2140 128,232, 2141 125,175, 2142 160,310, 2143 97, 2144 97, 2145 110 1716 100 2146 1717 }; 2147 1718 2148 1719 /* Map TID to TX scheduler's FIFO. */ … … static const char * const iwn_fw_errmsg[] = { 2228 1799 #define IWN_BARRIER_READ_WRITE(sc) \ 2229 1800 bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->sc_sz, \ 2230 1801 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE) 2231 2232 #endif /* __IF_IWNREG_H__ */ -
src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnvar.h
diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnvar.h b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnvar.h index bcc01b2..e53a5b2 100644
a b 2 2 /* $OpenBSD: if_iwnvar.h,v 1.18 2010/04/30 16:06:46 damien Exp $ */ 3 3 4 4 /*- 5 * Copyright (c) 2013 Cedric GROSS <cg@cgross.info>6 * Copyright (c) 2011 Intel Corporation7 5 * Copyright (c) 2007, 2008 8 6 * Damien Bergamini <damien.bergamini@free.fr> 9 7 * Copyright (c) 2008 Sam Leffler, Errno Consulting … … 20 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 21 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 20 */ 23 enum iwn_rxon_ctx_id {24 IWN_RXON_BSS_CTX,25 IWN_RXON_PAN_CTX,26 IWN_NUM_RXON_CTX27 };28 29 struct iwn_pan_slot {30 uint16_t time;31 uint8_t type;32 uint8_t reserved;33 } __packed;34 35 struct iwn_pan_params_cmd {36 uint16_t flags;37 #define IWN_PAN_PARAMS_FLG_SLOTTED_MODE (1 << 3)38 39 uint8_t reserved;40 uint8_t num_slots;41 struct iwn_pan_slot slots[10];42 } __packed;43 44 struct iwn_led_mode45 {46 uint8_t led_cur_mode;47 uint64_t led_cur_bt;48 uint64_t led_last_bt;49 uint64_t led_cur_tpt;50 uint64_t led_last_tpt;51 uint64_t led_bt_diff;52 int led_cur_time;53 int led_last_time;54 };55 21 56 22 struct iwn_rx_radiotap_header { 57 23 struct ieee80211_radiotap_header wr_ihdr; … … struct iwn_tx_ring { 112 78 int qid; 113 79 int queued; 114 80 int cur; 115 int read;116 81 }; 117 82 118 83 struct iwn_softc; … … struct iwn_node { 136 101 struct ieee80211_node ni; /* must be the first */ 137 102 uint16_t disable_tid; 138 103 uint8_t id; 139 struct { 140 uint64_t bitmap; 141 int startidx; 142 int nframes; 143 } agg[IEEE80211_TID_SIZE]; 104 uint8_t ridx[IEEE80211_RATE_MAXSIZE]; 144 105 }; 145 106 146 107 struct iwn_calib_state { … … struct iwn_calib_state { 163 124 uint32_t bad_plcp_cck; 164 125 uint32_t fa_cck; 165 126 uint32_t low_fa; 166 uint32_t bad_plcp_ht;167 127 uint8_t cck_state; 168 128 #define IWN_CCK_STATE_INIT 0 169 129 #define IWN_CCK_STATE_LOFA 1 … … struct iwn_ops { 214 174 int); 215 175 void (*tx_done)(struct iwn_softc *, struct iwn_rx_desc *, 216 176 struct iwn_rx_data *); 177 #if 0 /* HT */ 217 178 void (*ampdu_tx_start)(struct iwn_softc *, 218 struct ieee80211_node *, int,uint8_t, uint16_t);219 void (*ampdu_tx_stop)(struct iwn_softc *, int,uint8_t,179 struct ieee80211_node *, uint8_t, uint16_t); 180 void (*ampdu_tx_stop)(struct iwn_softc *, uint8_t, 220 181 uint16_t); 182 #endif 221 183 }; 222 184 223 185 struct iwn_vap { … … struct iwn_vap { 226 188 227 189 int (*iv_newstate)(struct ieee80211vap *, 228 190 enum ieee80211_state, int); 229 int ctx;230 int beacon_int;231 uint8_t macaddr[IEEE80211_ADDR_LEN];232 233 191 }; 234 192 #define IWN_VAP(_vap) ((struct iwn_vap *)(_vap)) 235 193 … … struct iwn_softc { 249 207 #define IWN_FLAG_HAS_11N (1 << 6) 250 208 #define IWN_FLAG_ENH_SENS (1 << 7) 251 209 #define IWN_FLAG_ADV_BTCOEX (1 << 8) 252 #define IWN_FLAG_PAN_SUPPORT (1 << 9)253 #define IWN_FLAG_BTCOEX (1 << 10)254 210 255 211 uint8_t hw_type; 256 /* subdevice_id used to adjust configuration */257 uint16_t subdevice_id;258 212 259 213 struct iwn_ops ops; 260 214 const char *fwname; 261 215 const struct iwn_sensitivity_limits 262 216 *limits; 263 217 int ntxqs; 264 int firstaggqueue;265 218 int ndmachnls; 266 219 uint8_t broadcast_id; 267 220 int rxonsz; … … struct iwn_softc { 296 249 struct iwn_tx_ring txq[IWN5000_NTXQUEUES]; 297 250 struct iwn_rx_ring rxq; 298 251 252 int mem_rid; 299 253 struct resource *mem; 300 254 bus_space_tag_t sc_st; 301 255 bus_space_handle_t sc_sh; 256 int irq_rid; 302 257 struct resource *irq; 303 258 void *sc_ih; 304 259 bus_size_t sc_sz; … … struct iwn_softc { 309 264 struct task sc_radioon_task; 310 265 struct task sc_radiooff_task; 311 266 312 /* Calibration information */313 267 struct callout calib_to; 314 268 int calib_cnt; 315 269 struct iwn_calib_state calib; 316 int last_calib_ticks;317 270 struct callout watchdog_to; 318 struct callout ct_kill_exit_to; 271 319 272 struct iwn_fw_info fw; 320 struct iwn_calib_info calibcmd[ IWN5000_PHY_CALIB_MAX_RESULT];273 struct iwn_calib_info calibcmd[5]; 321 274 uint32_t errptr; 322 275 323 276 struct iwn_rx_stat last_rx_stat; 324 277 int last_rx_valid; 325 278 struct iwn_ucode_info ucode_info; 326 struct iwn_rxon rx_on[IWN_NUM_RXON_CTX]; 327 struct iwn_rxon *rxon; 328 int ctx; 329 struct ieee80211vap *ivap[IWN_NUM_RXON_CTX]; 330 331 /* General statistics */ 332 /* 333 * The statistics are reset after each channel 334 * change. So it may be zeroed after things like 335 * a background scan. 336 * 337 * So for now, this is just a cheap hack to 338 * expose the last received statistics dump 339 * via an ioctl(). Later versions of this 340 * could expose the last 'n' messages, or just 341 * provide a pipeline for the firmware responses 342 * via something like BPF. 343 */ 344 struct iwn_stats last_stat; 345 int last_stat_valid; 346 347 uint8_t uc_scan_progress; 279 struct iwn_rxon rxon; 348 280 uint32_t rawtemp; 349 281 int temp; 350 282 int noise; … … struct iwn_softc { 359 291 char eeprom_domain[4]; 360 292 uint32_t eeprom_crystal; 361 293 int16_t eeprom_temp; 362 int16_t eeprom_temp_high;363 294 int16_t eeprom_voltage; 364 295 int8_t maxpwr2GHz; 365 296 int8_t maxpwr5GHz; 366 297 int8_t maxpwr[IEEE80211_CHAN_MAX]; 367 368 uint32_t tlv_feature_flags; 298 int8_t enh_maxpwr[35]; 369 299 370 300 int32_t temp_off; 371 301 uint32_t int_mask; … … struct iwn_softc { 376 306 uint8_t chainmask; 377 307 378 308 int sc_tx_timer; 379 int sc_scan_timer;380 381 /* Are we doing a scan? */382 int sc_is_scanning;383 384 struct ieee80211_tx_ampdu *qid2tap[IWN5000_NTXQUEUES];385 386 int (*sc_ampdu_rx_start)(struct ieee80211_node *,387 struct ieee80211_rx_ampdu *, int, int, int);388 void (*sc_ampdu_rx_stop)(struct ieee80211_node *,389 struct ieee80211_rx_ampdu *);390 int (*sc_addba_request)(struct ieee80211_node *,391 struct ieee80211_tx_ampdu *, int, int, int);392 int (*sc_addba_response)(struct ieee80211_node *,393 struct ieee80211_tx_ampdu *, int, int, int);394 void (*sc_addba_stop)(struct ieee80211_node *,395 struct ieee80211_tx_ampdu *);396 397 struct iwn_led_mode sc_led;398 309 399 310 struct iwn_rx_radiotap_header sc_rxtap; 400 311 struct iwn_tx_radiotap_header sc_txtap; 401 402 /* The power save level originally configured by user */403 int desired_pwrsave_level;404 405 /*406 * The current power save level, this may differ from the407 * configured value due to thermal throttling etc.408 */409 int current_pwrsave_level;410 411 /* For specific params */412 const struct iwn_base_params *base_params;413 312 }; 414 313 415 314 #define IWN_LOCK_INIT(_sc) \