diff options
author | David S. Miller <davem@davemloft.net> | 2010-02-26 02:26:21 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-26 02:26:21 -0500 |
commit | 19bc291c99f018bd4f2c38bbf69144086dca903f (patch) | |
tree | 9d3cf9bc0c5a78e363dc0547da8bcd1e7c394265 /drivers/net/wireless/iwlwifi | |
parent | 04488734806948624dabc4514f96f14cd75b9a50 (diff) | |
parent | 4a6967b88af02eebeedfbb91bc09160750225bb5 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Conflicts:
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/rt2x00/rt2800pci.c
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
20 files changed, 418 insertions, 157 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 694ceef88590..3bf2e6e9b2d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -246,7 +246,7 @@ struct iwl_cfg iwl1000_bgn_cfg = { | |||
246 | .use_rts_for_ht = true, /* use rts/cts protection */ | 246 | .use_rts_for_ht = true, /* use rts/cts protection */ |
247 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 247 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
248 | .support_ct_kill_exit = true, | 248 | .support_ct_kill_exit = true, |
249 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 249 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, |
250 | .chain_noise_scale = 1000, | 250 | .chain_noise_scale = 1000, |
251 | }; | 251 | }; |
252 | 252 | ||
@@ -274,7 +274,7 @@ struct iwl_cfg iwl1000_bg_cfg = { | |||
274 | .led_compensation = 51, | 274 | .led_compensation = 51, |
275 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 275 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
276 | .support_ct_kill_exit = true, | 276 | .support_ct_kill_exit = true, |
277 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 277 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, |
278 | .chain_noise_scale = 1000, | 278 | .chain_noise_scale = 1000, |
279 | }; | 279 | }; |
280 | 280 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 6940f086823c..303cc8193adc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -45,8 +45,8 @@ | |||
45 | #include "iwl-sta.h" | 45 | #include "iwl-sta.h" |
46 | #include "iwl-3945.h" | 46 | #include "iwl-3945.h" |
47 | #include "iwl-eeprom.h" | 47 | #include "iwl-eeprom.h" |
48 | #include "iwl-helpers.h" | ||
49 | #include "iwl-core.h" | 48 | #include "iwl-core.h" |
49 | #include "iwl-helpers.h" | ||
50 | #include "iwl-led.h" | 50 | #include "iwl-led.h" |
51 | #include "iwl-3945-led.h" | 51 | #include "iwl-3945-led.h" |
52 | 52 | ||
@@ -2470,11 +2470,9 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv) | |||
2470 | memset((void *)&priv->hw_params, 0, | 2470 | memset((void *)&priv->hw_params, 0, |
2471 | sizeof(struct iwl_hw_params)); | 2471 | sizeof(struct iwl_hw_params)); |
2472 | 2472 | ||
2473 | priv->shared_virt = | 2473 | priv->shared_virt = dma_alloc_coherent(&priv->pci_dev->dev, |
2474 | pci_alloc_consistent(priv->pci_dev, | 2474 | sizeof(struct iwl3945_shared), |
2475 | sizeof(struct iwl3945_shared), | 2475 | &priv->shared_phys, GFP_KERNEL); |
2476 | &priv->shared_phys); | ||
2477 | |||
2478 | if (!priv->shared_virt) { | 2476 | if (!priv->shared_virt) { |
2479 | IWL_ERR(priv, "failed to allocate pci memory\n"); | 2477 | IWL_ERR(priv, "failed to allocate pci memory\n"); |
2480 | mutex_unlock(&priv->mutex); | 2478 | mutex_unlock(&priv->mutex); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 8f553f36d270..452dfd5456c6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -171,24 +171,6 @@ struct iwl3945_frame { | |||
171 | 171 | ||
172 | #define SCAN_INTERVAL 100 | 172 | #define SCAN_INTERVAL 100 |
173 | 173 | ||
174 | #define STATUS_HCMD_ACTIVE 0 /* host command in progress */ | ||
175 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ | ||
176 | #define STATUS_INT_ENABLED 2 | ||
177 | #define STATUS_RF_KILL_HW 3 | ||
178 | #define STATUS_INIT 5 | ||
179 | #define STATUS_ALIVE 6 | ||
180 | #define STATUS_READY 7 | ||
181 | #define STATUS_TEMPERATURE 8 | ||
182 | #define STATUS_GEO_CONFIGURED 9 | ||
183 | #define STATUS_EXIT_PENDING 10 | ||
184 | #define STATUS_STATISTICS 12 | ||
185 | #define STATUS_SCANNING 13 | ||
186 | #define STATUS_SCAN_ABORTING 14 | ||
187 | #define STATUS_SCAN_HW 15 | ||
188 | #define STATUS_POWER_PMI 16 | ||
189 | #define STATUS_FW_ERROR 17 | ||
190 | #define STATUS_CONF_PENDING 18 | ||
191 | |||
192 | #define MAX_TID_COUNT 9 | 174 | #define MAX_TID_COUNT 9 |
193 | 175 | ||
194 | #define IWL_INVALID_RATE 0xFF | 176 | #define IWL_INVALID_RATE 0xFF |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index b07874f7da7f..1bd2cd836026 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -581,6 +581,13 @@ static int iwl4965_alive_notify(struct iwl_priv *priv) | |||
581 | 581 | ||
582 | iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); | 582 | iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); |
583 | 583 | ||
584 | /* make sure all queue are not stopped */ | ||
585 | memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); | ||
586 | for (i = 0; i < 4; i++) | ||
587 | atomic_set(&priv->queue_stop_count[i], 0); | ||
588 | |||
589 | /* reset to 0 to enable all the queue first */ | ||
590 | priv->txq_ctx_active_msk = 0; | ||
584 | /* Map each Tx/cmd queue to its corresponding fifo */ | 591 | /* Map each Tx/cmd queue to its corresponding fifo */ |
585 | for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { | 592 | for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { |
586 | int ac = default_queue_to_tx_fifo[i]; | 593 | int ac = default_queue_to_tx_fifo[i]; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 2cf92a51f041..e476acb53aa7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -648,6 +648,13 @@ int iwl5000_alive_notify(struct iwl_priv *priv) | |||
648 | 648 | ||
649 | iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); | 649 | iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); |
650 | 650 | ||
651 | /* make sure all queue are not stopped */ | ||
652 | memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); | ||
653 | for (i = 0; i < 4; i++) | ||
654 | atomic_set(&priv->queue_stop_count[i], 0); | ||
655 | |||
656 | /* reset to 0 to enable all the queue first */ | ||
657 | priv->txq_ctx_active_msk = 0; | ||
651 | /* map qos queues to fifos one-to-one */ | 658 | /* map qos queues to fifos one-to-one */ |
652 | for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) { | 659 | for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) { |
653 | int ac = iwl5000_default_queue_to_tx_fifo[i]; | 660 | int ac = iwl5000_default_queue_to_tx_fifo[i]; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 782e23a26984..c4844adff92a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -70,6 +70,14 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv) | |||
70 | priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; | 70 | priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; |
71 | } | 71 | } |
72 | 72 | ||
73 | /* Indicate calibration version to uCode. */ | ||
74 | static void iwl6050_set_calib_version(struct iwl_priv *priv) | ||
75 | { | ||
76 | if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6) | ||
77 | iwl_set_bit(priv, CSR_GP_DRIVER_REG, | ||
78 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | ||
79 | } | ||
80 | |||
73 | /* NIC configuration for 6000 series */ | 81 | /* NIC configuration for 6000 series */ |
74 | static void iwl6000_nic_config(struct iwl_priv *priv) | 82 | static void iwl6000_nic_config(struct iwl_priv *priv) |
75 | { | 83 | { |
@@ -96,6 +104,8 @@ static void iwl6000_nic_config(struct iwl_priv *priv) | |||
96 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); | 104 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); |
97 | } | 105 | } |
98 | /* else do nothing, uCode configured */ | 106 | /* else do nothing, uCode configured */ |
107 | if (priv->cfg->ops->lib->temp_ops.set_calib_version) | ||
108 | priv->cfg->ops->lib->temp_ops.set_calib_version(priv); | ||
99 | } | 109 | } |
100 | 110 | ||
101 | static struct iwl_sensitivity_ranges iwl6000_sensitivity = { | 111 | static struct iwl_sensitivity_ranges iwl6000_sensitivity = { |
@@ -277,6 +287,71 @@ static const struct iwl_ops iwl6000_ops = { | |||
277 | .led = &iwlagn_led_ops, | 287 | .led = &iwlagn_led_ops, |
278 | }; | 288 | }; |
279 | 289 | ||
290 | static struct iwl_lib_ops iwl6050_lib = { | ||
291 | .set_hw_params = iwl6000_hw_set_hw_params, | ||
292 | .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, | ||
293 | .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, | ||
294 | .txq_set_sched = iwl5000_txq_set_sched, | ||
295 | .txq_agg_enable = iwl5000_txq_agg_enable, | ||
296 | .txq_agg_disable = iwl5000_txq_agg_disable, | ||
297 | .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, | ||
298 | .txq_free_tfd = iwl_hw_txq_free_tfd, | ||
299 | .txq_init = iwl_hw_tx_queue_init, | ||
300 | .rx_handler_setup = iwl5000_rx_handler_setup, | ||
301 | .setup_deferred_work = iwl5000_setup_deferred_work, | ||
302 | .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, | ||
303 | .load_ucode = iwl5000_load_ucode, | ||
304 | .dump_nic_event_log = iwl_dump_nic_event_log, | ||
305 | .dump_nic_error_log = iwl_dump_nic_error_log, | ||
306 | .dump_csr = iwl_dump_csr, | ||
307 | .dump_fh = iwl_dump_fh, | ||
308 | .init_alive_start = iwl5000_init_alive_start, | ||
309 | .alive_notify = iwl5000_alive_notify, | ||
310 | .send_tx_power = iwl5000_send_tx_power, | ||
311 | .update_chain_flags = iwl_update_chain_flags, | ||
312 | .set_channel_switch = iwl6000_hw_channel_switch, | ||
313 | .apm_ops = { | ||
314 | .init = iwl_apm_init, | ||
315 | .stop = iwl_apm_stop, | ||
316 | .config = iwl6000_nic_config, | ||
317 | .set_pwr_src = iwl_set_pwr_src, | ||
318 | }, | ||
319 | .eeprom_ops = { | ||
320 | .regulatory_bands = { | ||
321 | EEPROM_5000_REG_BAND_1_CHANNELS, | ||
322 | EEPROM_5000_REG_BAND_2_CHANNELS, | ||
323 | EEPROM_5000_REG_BAND_3_CHANNELS, | ||
324 | EEPROM_5000_REG_BAND_4_CHANNELS, | ||
325 | EEPROM_5000_REG_BAND_5_CHANNELS, | ||
326 | EEPROM_5000_REG_BAND_24_HT40_CHANNELS, | ||
327 | EEPROM_5000_REG_BAND_52_HT40_CHANNELS | ||
328 | }, | ||
329 | .verify_signature = iwlcore_eeprom_verify_signature, | ||
330 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||
331 | .release_semaphore = iwlcore_eeprom_release_semaphore, | ||
332 | .calib_version = iwl5000_eeprom_calib_version, | ||
333 | .query_addr = iwl5000_eeprom_query_addr, | ||
334 | .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, | ||
335 | }, | ||
336 | .post_associate = iwl_post_associate, | ||
337 | .isr = iwl_isr_ict, | ||
338 | .config_ap = iwl_config_ap, | ||
339 | .temp_ops = { | ||
340 | .temperature = iwl5000_temperature, | ||
341 | .set_ct_kill = iwl6000_set_ct_threshold, | ||
342 | .set_calib_version = iwl6050_set_calib_version, | ||
343 | }, | ||
344 | .add_bcast_station = iwl_add_bcast_station, | ||
345 | }; | ||
346 | |||
347 | static const struct iwl_ops iwl6050_ops = { | ||
348 | .ucode = &iwl5000_ucode, | ||
349 | .lib = &iwl6050_lib, | ||
350 | .hcmd = &iwl5000_hcmd, | ||
351 | .utils = &iwl5000_hcmd_utils, | ||
352 | .led = &iwlagn_led_ops, | ||
353 | }; | ||
354 | |||
280 | /* | 355 | /* |
281 | * "i": Internal configuration, use internal Power Amplifier | 356 | * "i": Internal configuration, use internal Power Amplifier |
282 | */ | 357 | */ |
@@ -380,7 +455,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { | |||
380 | .ucode_api_max = IWL6050_UCODE_API_MAX, | 455 | .ucode_api_max = IWL6050_UCODE_API_MAX, |
381 | .ucode_api_min = IWL6050_UCODE_API_MIN, | 456 | .ucode_api_min = IWL6050_UCODE_API_MIN, |
382 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | 457 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, |
383 | .ops = &iwl6000_ops, | 458 | .ops = &iwl6050_ops, |
384 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 459 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
385 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, | 460 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, |
386 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 461 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
@@ -412,7 +487,7 @@ struct iwl_cfg iwl6050_2abg_cfg = { | |||
412 | .ucode_api_max = IWL6050_UCODE_API_MAX, | 487 | .ucode_api_max = IWL6050_UCODE_API_MAX, |
413 | .ucode_api_min = IWL6050_UCODE_API_MIN, | 488 | .ucode_api_min = IWL6050_UCODE_API_MIN, |
414 | .sku = IWL_SKU_A|IWL_SKU_G, | 489 | .sku = IWL_SKU_A|IWL_SKU_G, |
415 | .ops = &iwl6000_ops, | 490 | .ops = &iwl6050_ops, |
416 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 491 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
417 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, | 492 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, |
418 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | 493 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 6aebcedaca8d..8bf7c20b9d39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -298,10 +298,23 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, | |||
298 | struct iwl_lq_sta *lq_data, u8 tid, | 298 | struct iwl_lq_sta *lq_data, u8 tid, |
299 | struct ieee80211_sta *sta) | 299 | struct ieee80211_sta *sta) |
300 | { | 300 | { |
301 | int ret; | ||
302 | |||
301 | if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { | 303 | if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { |
302 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", | 304 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", |
303 | sta->addr, tid); | 305 | sta->addr, tid); |
304 | ieee80211_start_tx_ba_session(sta, tid); | 306 | ret = ieee80211_start_tx_ba_session(sta, tid); |
307 | if (ret == -EAGAIN) { | ||
308 | /* | ||
309 | * driver and mac80211 is out of sync | ||
310 | * this might be cause by reloading firmware | ||
311 | * stop the tx ba session here | ||
312 | */ | ||
313 | IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n", | ||
314 | tid); | ||
315 | ret = ieee80211_stop_tx_ba_session(sta, tid, | ||
316 | WLAN_BACK_INITIATOR); | ||
317 | } | ||
305 | } | 318 | } |
306 | } | 319 | } |
307 | 320 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1854c720b5e0..af60b178ad4b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -2941,10 +2941,21 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, | |||
2941 | return ret; | 2941 | return ret; |
2942 | case IEEE80211_AMPDU_TX_START: | 2942 | case IEEE80211_AMPDU_TX_START: |
2943 | IWL_DEBUG_HT(priv, "start Tx\n"); | 2943 | IWL_DEBUG_HT(priv, "start Tx\n"); |
2944 | return iwl_tx_agg_start(priv, sta->addr, tid, ssn); | 2944 | ret = iwl_tx_agg_start(priv, sta->addr, tid, ssn); |
2945 | if (ret == 0) { | ||
2946 | priv->agg_tids_count++; | ||
2947 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | ||
2948 | priv->agg_tids_count); | ||
2949 | } | ||
2950 | return ret; | ||
2945 | case IEEE80211_AMPDU_TX_STOP: | 2951 | case IEEE80211_AMPDU_TX_STOP: |
2946 | IWL_DEBUG_HT(priv, "stop Tx\n"); | 2952 | IWL_DEBUG_HT(priv, "stop Tx\n"); |
2947 | ret = iwl_tx_agg_stop(priv, sta->addr, tid); | 2953 | ret = iwl_tx_agg_stop(priv, sta->addr, tid); |
2954 | if ((ret == 0) && (priv->agg_tids_count > 0)) { | ||
2955 | priv->agg_tids_count--; | ||
2956 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | ||
2957 | priv->agg_tids_count); | ||
2958 | } | ||
2948 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2959 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2949 | return 0; | 2960 | return 0; |
2950 | else | 2961 | else |
@@ -3353,6 +3364,7 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
3353 | INIT_LIST_HEAD(&priv->free_frames); | 3364 | INIT_LIST_HEAD(&priv->free_frames); |
3354 | 3365 | ||
3355 | mutex_init(&priv->mutex); | 3366 | mutex_init(&priv->mutex); |
3367 | mutex_init(&priv->sync_cmd_mutex); | ||
3356 | 3368 | ||
3357 | /* Clear the driver's (not device's) station table */ | 3369 | /* Clear the driver's (not device's) station table */ |
3358 | iwl_clear_stations_table(priv); | 3370 | iwl_clear_stations_table(priv); |
@@ -3364,6 +3376,13 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
3364 | priv->iw_mode = NL80211_IFTYPE_STATION; | 3376 | priv->iw_mode = NL80211_IFTYPE_STATION; |
3365 | priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; | 3377 | priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; |
3366 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; | 3378 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; |
3379 | priv->agg_tids_count = 0; | ||
3380 | |||
3381 | /* initialize force reset */ | ||
3382 | priv->force_reset[IWL_RF_RESET].reset_duration = | ||
3383 | IWL_DELAY_NEXT_FORCE_RF_RESET; | ||
3384 | priv->force_reset[IWL_FW_RESET].reset_duration = | ||
3385 | IWL_DELAY_NEXT_FORCE_FW_RELOAD; | ||
3367 | 3386 | ||
3368 | /* Choose which receivers/antennas to use */ | 3387 | /* Choose which receivers/antennas to use */ |
3369 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 3388 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
@@ -3540,6 +3559,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3540 | */ | 3559 | */ |
3541 | spin_lock_init(&priv->reg_lock); | 3560 | spin_lock_init(&priv->reg_lock); |
3542 | spin_lock_init(&priv->lock); | 3561 | spin_lock_init(&priv->lock); |
3562 | |||
3563 | /* | ||
3564 | * stop and reset the on-board processor just in case it is in a | ||
3565 | * strange state ... like being left stranded by a primary kernel | ||
3566 | * and this is now the kdump kernel trying to start up | ||
3567 | */ | ||
3568 | iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | ||
3569 | |||
3543 | iwl_hw_detect(priv); | 3570 | iwl_hw_detect(priv); |
3544 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", | 3571 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", |
3545 | priv->cfg->name, priv->hw_rev); | 3572 | priv->cfg->name, priv->hw_rev); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index c2f31eb26bef..ab3c77b92cc8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -3470,11 +3470,7 @@ enum { | |||
3470 | IWL_PHY_CALIBRATE_DIFF_GAIN_CMD = 7, | 3470 | IWL_PHY_CALIBRATE_DIFF_GAIN_CMD = 7, |
3471 | IWL_PHY_CALIBRATE_DC_CMD = 8, | 3471 | IWL_PHY_CALIBRATE_DC_CMD = 8, |
3472 | IWL_PHY_CALIBRATE_LO_CMD = 9, | 3472 | IWL_PHY_CALIBRATE_LO_CMD = 9, |
3473 | IWL_PHY_CALIBRATE_RX_BB_CMD = 10, | ||
3474 | IWL_PHY_CALIBRATE_TX_IQ_CMD = 11, | 3473 | IWL_PHY_CALIBRATE_TX_IQ_CMD = 11, |
3475 | IWL_PHY_CALIBRATE_RX_IQ_CMD = 12, | ||
3476 | IWL_PHY_CALIBRATION_NOISE_CMD = 13, | ||
3477 | IWL_PHY_CALIBRATE_AGC_TABLE_CMD = 14, | ||
3478 | IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15, | 3474 | IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15, |
3479 | IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, | 3475 | IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, |
3480 | IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, | 3476 | IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 728410083cb8..112149e9b31e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1670,9 +1670,9 @@ EXPORT_SYMBOL(iwl_set_tx_power); | |||
1670 | void iwl_free_isr_ict(struct iwl_priv *priv) | 1670 | void iwl_free_isr_ict(struct iwl_priv *priv) |
1671 | { | 1671 | { |
1672 | if (priv->ict_tbl_vir) { | 1672 | if (priv->ict_tbl_vir) { |
1673 | pci_free_consistent(priv->pci_dev, (sizeof(u32) * ICT_COUNT) + | 1673 | dma_free_coherent(&priv->pci_dev->dev, |
1674 | PAGE_SIZE, priv->ict_tbl_vir, | 1674 | (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, |
1675 | priv->ict_tbl_dma); | 1675 | priv->ict_tbl_vir, priv->ict_tbl_dma); |
1676 | priv->ict_tbl_vir = NULL; | 1676 | priv->ict_tbl_vir = NULL; |
1677 | } | 1677 | } |
1678 | } | 1678 | } |
@@ -1688,9 +1688,9 @@ int iwl_alloc_isr_ict(struct iwl_priv *priv) | |||
1688 | if (priv->cfg->use_isr_legacy) | 1688 | if (priv->cfg->use_isr_legacy) |
1689 | return 0; | 1689 | return 0; |
1690 | /* allocate shrared data table */ | 1690 | /* allocate shrared data table */ |
1691 | priv->ict_tbl_vir = pci_alloc_consistent(priv->pci_dev, (sizeof(u32) * | 1691 | priv->ict_tbl_vir = dma_alloc_coherent(&priv->pci_dev->dev, |
1692 | ICT_COUNT) + PAGE_SIZE, | 1692 | (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, |
1693 | &priv->ict_tbl_dma); | 1693 | &priv->ict_tbl_dma, GFP_KERNEL); |
1694 | if (!priv->ict_tbl_vir) | 1694 | if (!priv->ict_tbl_vir) |
1695 | return -ENOMEM; | 1695 | return -ENOMEM; |
1696 | 1696 | ||
@@ -3334,7 +3334,7 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display) | |||
3334 | } | 3334 | } |
3335 | EXPORT_SYMBOL(iwl_dump_fh); | 3335 | EXPORT_SYMBOL(iwl_dump_fh); |
3336 | 3336 | ||
3337 | void iwl_force_rf_reset(struct iwl_priv *priv) | 3337 | static void iwl_force_rf_reset(struct iwl_priv *priv) |
3338 | { | 3338 | { |
3339 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 3339 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
3340 | return; | 3340 | return; |
@@ -3356,7 +3356,50 @@ void iwl_force_rf_reset(struct iwl_priv *priv) | |||
3356 | iwl_internal_short_hw_scan(priv); | 3356 | iwl_internal_short_hw_scan(priv); |
3357 | return; | 3357 | return; |
3358 | } | 3358 | } |
3359 | EXPORT_SYMBOL(iwl_force_rf_reset); | 3359 | |
3360 | |||
3361 | int iwl_force_reset(struct iwl_priv *priv, int mode) | ||
3362 | { | ||
3363 | struct iwl_force_reset *force_reset; | ||
3364 | |||
3365 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
3366 | return -EINVAL; | ||
3367 | |||
3368 | if (mode >= IWL_MAX_FORCE_RESET) { | ||
3369 | IWL_DEBUG_INFO(priv, "invalid reset request.\n"); | ||
3370 | return -EINVAL; | ||
3371 | } | ||
3372 | force_reset = &priv->force_reset[mode]; | ||
3373 | force_reset->reset_request_count++; | ||
3374 | if (force_reset->last_force_reset_jiffies && | ||
3375 | time_after(force_reset->last_force_reset_jiffies + | ||
3376 | force_reset->reset_duration, jiffies)) { | ||
3377 | IWL_DEBUG_INFO(priv, "force reset rejected\n"); | ||
3378 | force_reset->reset_reject_count++; | ||
3379 | return -EAGAIN; | ||
3380 | } | ||
3381 | force_reset->reset_success_count++; | ||
3382 | force_reset->last_force_reset_jiffies = jiffies; | ||
3383 | IWL_DEBUG_INFO(priv, "perform force reset (%d)\n", mode); | ||
3384 | switch (mode) { | ||
3385 | case IWL_RF_RESET: | ||
3386 | iwl_force_rf_reset(priv); | ||
3387 | break; | ||
3388 | case IWL_FW_RESET: | ||
3389 | IWL_ERR(priv, "On demand firmware reload\n"); | ||
3390 | /* Set the FW error flag -- cleared on iwl_down */ | ||
3391 | set_bit(STATUS_FW_ERROR, &priv->status); | ||
3392 | wake_up_interruptible(&priv->wait_command_queue); | ||
3393 | /* | ||
3394 | * Keep the restart process from trying to send host | ||
3395 | * commands by clearing the INIT status bit | ||
3396 | */ | ||
3397 | clear_bit(STATUS_READY, &priv->status); | ||
3398 | queue_work(priv->workqueue, &priv->restart); | ||
3399 | break; | ||
3400 | } | ||
3401 | return 0; | ||
3402 | } | ||
3360 | 3403 | ||
3361 | #ifdef CONFIG_PM | 3404 | #ifdef CONFIG_PM |
3362 | 3405 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 1b0701b876c3..4ef7739f9e8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -117,6 +117,7 @@ struct iwl_apm_ops { | |||
117 | struct iwl_temp_ops { | 117 | struct iwl_temp_ops { |
118 | void (*temperature)(struct iwl_priv *priv); | 118 | void (*temperature)(struct iwl_priv *priv); |
119 | void (*set_ct_kill)(struct iwl_priv *priv); | 119 | void (*set_ct_kill)(struct iwl_priv *priv); |
120 | void (*set_calib_version)(struct iwl_priv *priv); | ||
120 | }; | 121 | }; |
121 | 122 | ||
122 | struct iwl_ucode_ops { | 123 | struct iwl_ucode_ops { |
@@ -414,13 +415,13 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | |||
414 | void iwl_cmd_queue_free(struct iwl_priv *priv); | 415 | void iwl_cmd_queue_free(struct iwl_priv *priv); |
415 | int iwl_rx_queue_alloc(struct iwl_priv *priv); | 416 | int iwl_rx_queue_alloc(struct iwl_priv *priv); |
416 | void iwl_rx_handle(struct iwl_priv *priv); | 417 | void iwl_rx_handle(struct iwl_priv *priv); |
417 | int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, | 418 | void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, |
418 | struct iwl_rx_queue *q); | 419 | struct iwl_rx_queue *q); |
419 | void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | 420 | void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); |
420 | void iwl_rx_replenish(struct iwl_priv *priv); | 421 | void iwl_rx_replenish(struct iwl_priv *priv); |
421 | void iwl_rx_replenish_now(struct iwl_priv *priv); | 422 | void iwl_rx_replenish_now(struct iwl_priv *priv); |
422 | int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | 423 | int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); |
423 | int iwl_rx_queue_restock(struct iwl_priv *priv); | 424 | void iwl_rx_queue_restock(struct iwl_priv *priv); |
424 | int iwl_rx_queue_space(const struct iwl_rx_queue *q); | 425 | int iwl_rx_queue_space(const struct iwl_rx_queue *q); |
425 | void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority); | 426 | void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority); |
426 | void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); | 427 | void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); |
@@ -450,9 +451,9 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); | |||
450 | void iwl_hw_txq_ctx_free(struct iwl_priv *priv); | 451 | void iwl_hw_txq_ctx_free(struct iwl_priv *priv); |
451 | int iwl_hw_tx_queue_init(struct iwl_priv *priv, | 452 | int iwl_hw_tx_queue_init(struct iwl_priv *priv, |
452 | struct iwl_tx_queue *txq); | 453 | struct iwl_tx_queue *txq); |
453 | int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); | ||
454 | void iwl_free_tfds_in_queue(struct iwl_priv *priv, | 454 | void iwl_free_tfds_in_queue(struct iwl_priv *priv, |
455 | int sta_id, int tid, int freed); | 455 | int sta_id, int tid, int freed); |
456 | void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); | ||
456 | int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | 457 | int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, |
457 | int slots_num, u32 txq_id); | 458 | int slots_num, u32 txq_id); |
458 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); | 459 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); |
@@ -503,7 +504,7 @@ int iwl_scan_cancel(struct iwl_priv *priv); | |||
503 | int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); | 504 | int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); |
504 | int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); | 505 | int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); |
505 | int iwl_internal_short_hw_scan(struct iwl_priv *priv); | 506 | int iwl_internal_short_hw_scan(struct iwl_priv *priv); |
506 | void iwl_force_rf_reset(struct iwl_priv *priv); | 507 | int iwl_force_reset(struct iwl_priv *priv, int mode); |
507 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, | 508 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, |
508 | const u8 *ie, int ie_len, int left); | 509 | const u8 *ie, int ie_len, int left); |
509 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); | 510 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); |
@@ -605,7 +606,7 @@ void iwlcore_free_geos(struct iwl_priv *priv); | |||
605 | /*************** DRIVER STATUS FUNCTIONS *****/ | 606 | /*************** DRIVER STATUS FUNCTIONS *****/ |
606 | 607 | ||
607 | #define STATUS_HCMD_ACTIVE 0 /* host command in progress */ | 608 | #define STATUS_HCMD_ACTIVE 0 /* host command in progress */ |
608 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ | 609 | /* 1 is unused (used to be STATUS_HCMD_SYNC_ACTIVE) */ |
609 | #define STATUS_INT_ENABLED 2 | 610 | #define STATUS_INT_ENABLED 2 |
610 | #define STATUS_RF_KILL_HW 3 | 611 | #define STATUS_RF_KILL_HW 3 |
611 | #define STATUS_CT_KILL 4 | 612 | #define STATUS_CT_KILL 4 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 1e00720bf8b1..808b7146bead 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -369,7 +369,7 @@ | |||
369 | #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB (0x00000000) | 369 | #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB (0x00000000) |
370 | #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB (0x00000001) | 370 | #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB (0x00000001) |
371 | #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002) | 371 | #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002) |
372 | 372 | #define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004) | |
373 | 373 | ||
374 | /* GIO Chicken Bits (PCI Express bus link power management) */ | 374 | /* GIO Chicken Bits (PCI Express bus link power management) */ |
375 | #define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) | 375 | #define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index d134301b553c..7bf44f146799 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -530,8 +530,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, | |||
530 | 530 | ||
531 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", | 531 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", |
532 | test_bit(STATUS_HCMD_ACTIVE, &priv->status)); | 532 | test_bit(STATUS_HCMD_ACTIVE, &priv->status)); |
533 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_SYNC_ACTIVE: %d\n", | ||
534 | test_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)); | ||
535 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", | 533 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", |
536 | test_bit(STATUS_INT_ENABLED, &priv->status)); | 534 | test_bit(STATUS_INT_ENABLED, &priv->status)); |
537 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", | 535 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", |
@@ -2223,6 +2221,62 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, | |||
2223 | return count; | 2221 | return count; |
2224 | } | 2222 | } |
2225 | 2223 | ||
2224 | static ssize_t iwl_dbgfs_force_reset_read(struct file *file, | ||
2225 | char __user *user_buf, | ||
2226 | size_t count, loff_t *ppos) { | ||
2227 | |||
2228 | struct iwl_priv *priv = file->private_data; | ||
2229 | int i, pos = 0; | ||
2230 | char buf[300]; | ||
2231 | const size_t bufsz = sizeof(buf); | ||
2232 | struct iwl_force_reset *force_reset; | ||
2233 | |||
2234 | for (i = 0; i < IWL_MAX_FORCE_RESET; i++) { | ||
2235 | force_reset = &priv->force_reset[i]; | ||
2236 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2237 | "Force reset method %d\n", i); | ||
2238 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2239 | "\tnumber of reset request: %d\n", | ||
2240 | force_reset->reset_request_count); | ||
2241 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2242 | "\tnumber of reset request success: %d\n", | ||
2243 | force_reset->reset_success_count); | ||
2244 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2245 | "\tnumber of reset request reject: %d\n", | ||
2246 | force_reset->reset_reject_count); | ||
2247 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2248 | "\treset duration: %lu\n", | ||
2249 | force_reset->reset_duration); | ||
2250 | } | ||
2251 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
2252 | } | ||
2253 | |||
2254 | static ssize_t iwl_dbgfs_force_reset_write(struct file *file, | ||
2255 | const char __user *user_buf, | ||
2256 | size_t count, loff_t *ppos) { | ||
2257 | |||
2258 | struct iwl_priv *priv = file->private_data; | ||
2259 | char buf[8]; | ||
2260 | int buf_size; | ||
2261 | int reset, ret; | ||
2262 | |||
2263 | memset(buf, 0, sizeof(buf)); | ||
2264 | buf_size = min(count, sizeof(buf) - 1); | ||
2265 | if (copy_from_user(buf, user_buf, buf_size)) | ||
2266 | return -EFAULT; | ||
2267 | if (sscanf(buf, "%d", &reset) != 1) | ||
2268 | return -EINVAL; | ||
2269 | switch (reset) { | ||
2270 | case IWL_RF_RESET: | ||
2271 | case IWL_FW_RESET: | ||
2272 | ret = iwl_force_reset(priv, reset); | ||
2273 | break; | ||
2274 | default: | ||
2275 | return -EINVAL; | ||
2276 | } | ||
2277 | return ret ? ret : count; | ||
2278 | } | ||
2279 | |||
2226 | DEBUGFS_READ_FILE_OPS(rx_statistics); | 2280 | DEBUGFS_READ_FILE_OPS(rx_statistics); |
2227 | DEBUGFS_READ_FILE_OPS(tx_statistics); | 2281 | DEBUGFS_READ_FILE_OPS(tx_statistics); |
2228 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); | 2282 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); |
@@ -2243,6 +2297,7 @@ DEBUGFS_READ_FILE_OPS(fh_reg); | |||
2243 | DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); | 2297 | DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); |
2244 | DEBUGFS_WRITE_FILE_OPS(internal_scan); | 2298 | DEBUGFS_WRITE_FILE_OPS(internal_scan); |
2245 | DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); | 2299 | DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); |
2300 | DEBUGFS_READ_WRITE_FILE_OPS(force_reset); | ||
2246 | 2301 | ||
2247 | /* | 2302 | /* |
2248 | * Create the debugfs files and directories | 2303 | * Create the debugfs files and directories |
@@ -2296,6 +2351,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
2296 | DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); | 2351 | DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); |
2297 | DEBUGFS_ADD_FILE(internal_scan, dir_debug, S_IWUSR); | 2352 | DEBUGFS_ADD_FILE(internal_scan, dir_debug, S_IWUSR); |
2298 | DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); | 2353 | DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); |
2354 | DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); | ||
2299 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { | 2355 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { |
2300 | DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); | 2356 | DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); |
2301 | DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); | 2357 | DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 55dc5a866542..7914d65a5a55 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1033,8 +1033,26 @@ struct iwl_event_log { | |||
1033 | #define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (0) | 1033 | #define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (0) |
1034 | #define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50) | 1034 | #define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50) |
1035 | #define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100) | 1035 | #define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100) |
1036 | #define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF (200) | ||
1036 | #define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255) | 1037 | #define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255) |
1037 | 1038 | ||
1039 | #define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) | ||
1040 | #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) | ||
1041 | |||
1042 | enum iwl_reset { | ||
1043 | IWL_RF_RESET = 0, | ||
1044 | IWL_FW_RESET, | ||
1045 | IWL_MAX_FORCE_RESET, | ||
1046 | }; | ||
1047 | |||
1048 | struct iwl_force_reset { | ||
1049 | int reset_request_count; | ||
1050 | int reset_success_count; | ||
1051 | int reset_reject_count; | ||
1052 | unsigned long reset_duration; | ||
1053 | unsigned long last_force_reset_jiffies; | ||
1054 | }; | ||
1055 | |||
1038 | struct iwl_priv { | 1056 | struct iwl_priv { |
1039 | 1057 | ||
1040 | /* ieee device used by generic ieee processing code */ | 1058 | /* ieee device used by generic ieee processing code */ |
@@ -1066,6 +1084,12 @@ struct iwl_priv { | |||
1066 | /* storing the jiffies when the plcp error rate is received */ | 1084 | /* storing the jiffies when the plcp error rate is received */ |
1067 | unsigned long plcp_jiffies; | 1085 | unsigned long plcp_jiffies; |
1068 | 1086 | ||
1087 | /* reporting the number of tids has AGG on. 0 means no AGGREGATION */ | ||
1088 | u8 agg_tids_count; | ||
1089 | |||
1090 | /* force reset */ | ||
1091 | struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; | ||
1092 | |||
1069 | /* we allocate array of iwl4965_channel_info for NIC's valid channels. | 1093 | /* we allocate array of iwl4965_channel_info for NIC's valid channels. |
1070 | * Access via channel # using indirect index array */ | 1094 | * Access via channel # using indirect index array */ |
1071 | struct iwl_channel_info *channel_info; /* channel info array */ | 1095 | struct iwl_channel_info *channel_info; /* channel info array */ |
@@ -1087,7 +1111,6 @@ struct iwl_priv { | |||
1087 | unsigned long scan_start; | 1111 | unsigned long scan_start; |
1088 | unsigned long scan_pass_start; | 1112 | unsigned long scan_pass_start; |
1089 | unsigned long scan_start_tsf; | 1113 | unsigned long scan_start_tsf; |
1090 | unsigned long last_internal_scan_jiffies; | ||
1091 | void *scan; | 1114 | void *scan; |
1092 | int scan_bands; | 1115 | int scan_bands; |
1093 | struct cfg80211_scan_request *scan_request; | 1116 | struct cfg80211_scan_request *scan_request; |
@@ -1100,6 +1123,7 @@ struct iwl_priv { | |||
1100 | spinlock_t hcmd_lock; /* protect hcmd */ | 1123 | spinlock_t hcmd_lock; /* protect hcmd */ |
1101 | spinlock_t reg_lock; /* protect hw register access */ | 1124 | spinlock_t reg_lock; /* protect hw register access */ |
1102 | struct mutex mutex; | 1125 | struct mutex mutex; |
1126 | struct mutex sync_cmd_mutex; /* enable serialization of sync commands */ | ||
1103 | 1127 | ||
1104 | /* basic pci-network driver stuff */ | 1128 | /* basic pci-network driver stuff */ |
1105 | struct pci_dev *pci_dev; | 1129 | struct pci_dev *pci_dev; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 86783c27d97c..73681c4fefe7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -164,15 +164,13 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
164 | /* A synchronous command can not have a callback set. */ | 164 | /* A synchronous command can not have a callback set. */ |
165 | BUG_ON(cmd->callback); | 165 | BUG_ON(cmd->callback); |
166 | 166 | ||
167 | if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) { | 167 | IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", |
168 | IWL_ERR(priv, | ||
169 | "Error sending %s: Already sending a host command\n", | ||
170 | get_cmd_string(cmd->id)); | 168 | get_cmd_string(cmd->id)); |
171 | ret = -EBUSY; | 169 | mutex_lock(&priv->sync_cmd_mutex); |
172 | goto out; | ||
173 | } | ||
174 | 170 | ||
175 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); | 171 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); |
172 | IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s \n", | ||
173 | get_cmd_string(cmd->id)); | ||
176 | 174 | ||
177 | cmd_idx = iwl_enqueue_hcmd(priv, cmd); | 175 | cmd_idx = iwl_enqueue_hcmd(priv, cmd); |
178 | if (cmd_idx < 0) { | 176 | if (cmd_idx < 0) { |
@@ -193,6 +191,8 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
193 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); | 191 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); |
194 | 192 | ||
195 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | 193 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); |
194 | IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n", | ||
195 | get_cmd_string(cmd->id)); | ||
196 | ret = -ETIMEDOUT; | 196 | ret = -ETIMEDOUT; |
197 | goto cancel; | 197 | goto cancel; |
198 | } | 198 | } |
@@ -237,7 +237,7 @@ fail: | |||
237 | cmd->reply_page = 0; | 237 | cmd->reply_page = 0; |
238 | } | 238 | } |
239 | out: | 239 | out: |
240 | clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status); | 240 | mutex_unlock(&priv->sync_cmd_mutex); |
241 | return ret; | 241 | return ret; |
242 | } | 242 | } |
243 | EXPORT_SYMBOL(iwl_send_cmd_sync); | 243 | EXPORT_SYMBOL(iwl_send_cmd_sync); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 45af5bbc1c56..51a67fb2e185 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h | |||
@@ -80,8 +80,8 @@ static inline void iwl_free_fw_desc(struct pci_dev *pci_dev, | |||
80 | struct fw_desc *desc) | 80 | struct fw_desc *desc) |
81 | { | 81 | { |
82 | if (desc->v_addr) | 82 | if (desc->v_addr) |
83 | pci_free_consistent(pci_dev, desc->len, | 83 | dma_free_coherent(&pci_dev->dev, desc->len, |
84 | desc->v_addr, desc->p_addr); | 84 | desc->v_addr, desc->p_addr); |
85 | desc->v_addr = NULL; | 85 | desc->v_addr = NULL; |
86 | desc->len = 0; | 86 | desc->len = 0; |
87 | } | 87 | } |
@@ -89,7 +89,8 @@ static inline void iwl_free_fw_desc(struct pci_dev *pci_dev, | |||
89 | static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, | 89 | static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, |
90 | struct fw_desc *desc) | 90 | struct fw_desc *desc) |
91 | { | 91 | { |
92 | desc->v_addr = pci_alloc_consistent(pci_dev, desc->len, &desc->p_addr); | 92 | desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len, |
93 | &desc->p_addr, GFP_KERNEL); | ||
93 | return (desc->v_addr != NULL) ? 0 : -ENOMEM; | 94 | return (desc->v_addr != NULL) ? 0 : -ENOMEM; |
94 | } | 95 | } |
95 | 96 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 0f718f6df5fd..0d09f571e185 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -123,12 +123,11 @@ EXPORT_SYMBOL(iwl_rx_queue_space); | |||
123 | /** | 123 | /** |
124 | * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue | 124 | * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue |
125 | */ | 125 | */ |
126 | int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) | 126 | void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) |
127 | { | 127 | { |
128 | unsigned long flags; | 128 | unsigned long flags; |
129 | u32 rx_wrt_ptr_reg = priv->hw_params.rx_wrt_ptr_reg; | 129 | u32 rx_wrt_ptr_reg = priv->hw_params.rx_wrt_ptr_reg; |
130 | u32 reg; | 130 | u32 reg; |
131 | int ret = 0; | ||
132 | 131 | ||
133 | spin_lock_irqsave(&q->lock, flags); | 132 | spin_lock_irqsave(&q->lock, flags); |
134 | 133 | ||
@@ -161,7 +160,6 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) | |||
161 | 160 | ||
162 | exit_unlock: | 161 | exit_unlock: |
163 | spin_unlock_irqrestore(&q->lock, flags); | 162 | spin_unlock_irqrestore(&q->lock, flags); |
164 | return ret; | ||
165 | } | 163 | } |
166 | EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr); | 164 | EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr); |
167 | /** | 165 | /** |
@@ -184,14 +182,13 @@ static inline __le32 iwl_dma_addr2rbd_ptr(struct iwl_priv *priv, | |||
184 | * also updates the memory address in the firmware to reference the new | 182 | * also updates the memory address in the firmware to reference the new |
185 | * target buffer. | 183 | * target buffer. |
186 | */ | 184 | */ |
187 | int iwl_rx_queue_restock(struct iwl_priv *priv) | 185 | void iwl_rx_queue_restock(struct iwl_priv *priv) |
188 | { | 186 | { |
189 | struct iwl_rx_queue *rxq = &priv->rxq; | 187 | struct iwl_rx_queue *rxq = &priv->rxq; |
190 | struct list_head *element; | 188 | struct list_head *element; |
191 | struct iwl_rx_mem_buffer *rxb; | 189 | struct iwl_rx_mem_buffer *rxb; |
192 | unsigned long flags; | 190 | unsigned long flags; |
193 | int write; | 191 | int write; |
194 | int ret = 0; | ||
195 | 192 | ||
196 | spin_lock_irqsave(&rxq->lock, flags); | 193 | spin_lock_irqsave(&rxq->lock, flags); |
197 | write = rxq->write & ~0x7; | 194 | write = rxq->write & ~0x7; |
@@ -220,10 +217,8 @@ int iwl_rx_queue_restock(struct iwl_priv *priv) | |||
220 | spin_lock_irqsave(&rxq->lock, flags); | 217 | spin_lock_irqsave(&rxq->lock, flags); |
221 | rxq->need_update = 1; | 218 | rxq->need_update = 1; |
222 | spin_unlock_irqrestore(&rxq->lock, flags); | 219 | spin_unlock_irqrestore(&rxq->lock, flags); |
223 | ret = iwl_rx_queue_update_write_ptr(priv, rxq); | 220 | iwl_rx_queue_update_write_ptr(priv, rxq); |
224 | } | 221 | } |
225 | |||
226 | return ret; | ||
227 | } | 222 | } |
228 | EXPORT_SYMBOL(iwl_rx_queue_restock); | 223 | EXPORT_SYMBOL(iwl_rx_queue_restock); |
229 | 224 | ||
@@ -350,10 +345,10 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
350 | } | 345 | } |
351 | } | 346 | } |
352 | 347 | ||
353 | pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, | 348 | dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, |
354 | rxq->dma_addr); | 349 | rxq->dma_addr); |
355 | pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status), | 350 | dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), |
356 | rxq->rb_stts, rxq->rb_stts_dma); | 351 | rxq->rb_stts, rxq->rb_stts_dma); |
357 | rxq->bd = NULL; | 352 | rxq->bd = NULL; |
358 | rxq->rb_stts = NULL; | 353 | rxq->rb_stts = NULL; |
359 | } | 354 | } |
@@ -362,7 +357,7 @@ EXPORT_SYMBOL(iwl_rx_queue_free); | |||
362 | int iwl_rx_queue_alloc(struct iwl_priv *priv) | 357 | int iwl_rx_queue_alloc(struct iwl_priv *priv) |
363 | { | 358 | { |
364 | struct iwl_rx_queue *rxq = &priv->rxq; | 359 | struct iwl_rx_queue *rxq = &priv->rxq; |
365 | struct pci_dev *dev = priv->pci_dev; | 360 | struct device *dev = &priv->pci_dev->dev; |
366 | int i; | 361 | int i; |
367 | 362 | ||
368 | spin_lock_init(&rxq->lock); | 363 | spin_lock_init(&rxq->lock); |
@@ -370,12 +365,13 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv) | |||
370 | INIT_LIST_HEAD(&rxq->rx_used); | 365 | INIT_LIST_HEAD(&rxq->rx_used); |
371 | 366 | ||
372 | /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ | 367 | /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ |
373 | rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); | 368 | rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr, |
369 | GFP_KERNEL); | ||
374 | if (!rxq->bd) | 370 | if (!rxq->bd) |
375 | goto err_bd; | 371 | goto err_bd; |
376 | 372 | ||
377 | rxq->rb_stts = pci_alloc_consistent(dev, sizeof(struct iwl_rb_status), | 373 | rxq->rb_stts = dma_alloc_coherent(dev, sizeof(struct iwl_rb_status), |
378 | &rxq->rb_stts_dma); | 374 | &rxq->rb_stts_dma, GFP_KERNEL); |
379 | if (!rxq->rb_stts) | 375 | if (!rxq->rb_stts) |
380 | goto err_rb; | 376 | goto err_rb; |
381 | 377 | ||
@@ -392,8 +388,8 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv) | |||
392 | return 0; | 388 | return 0; |
393 | 389 | ||
394 | err_rb: | 390 | err_rb: |
395 | pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, | 391 | dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, |
396 | rxq->dma_addr); | 392 | rxq->dma_addr); |
397 | err_bd: | 393 | err_bd: |
398 | return -ENOMEM; | 394 | return -ENOMEM; |
399 | } | 395 | } |
@@ -620,6 +616,11 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, | |||
620 | 616 | ||
621 | #define REG_RECALIB_PERIOD (60) | 617 | #define REG_RECALIB_PERIOD (60) |
622 | 618 | ||
619 | /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ | ||
620 | #define ACK_CNT_RATIO (50) | ||
621 | #define BA_TIMEOUT_CNT (5) | ||
622 | #define BA_TIMEOUT_MAX (16) | ||
623 | |||
623 | #define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n" | 624 | #define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n" |
624 | void iwl_rx_statistics(struct iwl_priv *priv, | 625 | void iwl_rx_statistics(struct iwl_priv *priv, |
625 | struct iwl_rx_mem_buffer *rxb) | 626 | struct iwl_rx_mem_buffer *rxb) |
@@ -629,6 +630,9 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
629 | int combined_plcp_delta; | 630 | int combined_plcp_delta; |
630 | unsigned int plcp_msec; | 631 | unsigned int plcp_msec; |
631 | unsigned long plcp_received_jiffies; | 632 | unsigned long plcp_received_jiffies; |
633 | int actual_ack_cnt_delta; | ||
634 | int expected_ack_cnt_delta; | ||
635 | int ba_timeout_delta; | ||
632 | 636 | ||
633 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", | 637 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", |
634 | (int)sizeof(priv->statistics), | 638 | (int)sizeof(priv->statistics), |
@@ -643,6 +647,44 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
643 | #ifdef CONFIG_IWLWIFI_DEBUG | 647 | #ifdef CONFIG_IWLWIFI_DEBUG |
644 | iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); | 648 | iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); |
645 | #endif | 649 | #endif |
650 | actual_ack_cnt_delta = le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) - | ||
651 | le32_to_cpu(priv->statistics.tx.actual_ack_cnt); | ||
652 | expected_ack_cnt_delta = le32_to_cpu( | ||
653 | pkt->u.stats.tx.expected_ack_cnt) - | ||
654 | le32_to_cpu(priv->statistics.tx.expected_ack_cnt); | ||
655 | ba_timeout_delta = le32_to_cpu( | ||
656 | pkt->u.stats.tx.agg.ba_timeout) - | ||
657 | le32_to_cpu(priv->statistics.tx.agg.ba_timeout); | ||
658 | if ((priv->agg_tids_count > 0) && | ||
659 | (expected_ack_cnt_delta > 0) && | ||
660 | (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta) < | ||
661 | ACK_CNT_RATIO) && | ||
662 | (ba_timeout_delta > BA_TIMEOUT_CNT)) { | ||
663 | IWL_DEBUG_RADIO(priv, | ||
664 | "actual_ack_cnt delta = %d, expected_ack_cnt = %d\n", | ||
665 | actual_ack_cnt_delta, expected_ack_cnt_delta); | ||
666 | |||
667 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
668 | IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n", | ||
669 | priv->delta_statistics.tx.rx_detected_cnt); | ||
670 | IWL_DEBUG_RADIO(priv, | ||
671 | "ack_or_ba_timeout_collision delta = %d\n", | ||
672 | priv->delta_statistics.tx.ack_or_ba_timeout_collision); | ||
673 | #endif | ||
674 | IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n", | ||
675 | ba_timeout_delta); | ||
676 | if ((actual_ack_cnt_delta == 0) && | ||
677 | (ba_timeout_delta >= | ||
678 | BA_TIMEOUT_MAX)) { | ||
679 | IWL_DEBUG_RADIO(priv, | ||
680 | "call iwl_force_reset(IWL_FW_RESET)\n"); | ||
681 | iwl_force_reset(priv, IWL_FW_RESET); | ||
682 | } else { | ||
683 | IWL_DEBUG_RADIO(priv, | ||
684 | "call iwl_force_reset(IWL_RF_RESET)\n"); | ||
685 | iwl_force_reset(priv, IWL_RF_RESET); | ||
686 | } | ||
687 | } | ||
646 | /* | 688 | /* |
647 | * check for plcp_err and trigger radio reset if it exceeds | 689 | * check for plcp_err and trigger radio reset if it exceeds |
648 | * the plcp error threshold plcp_delta. | 690 | * the plcp error threshold plcp_delta. |
@@ -689,7 +731,7 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
689 | * Reset the RF radio due to the high plcp | 731 | * Reset the RF radio due to the high plcp |
690 | * error rate | 732 | * error rate |
691 | */ | 733 | */ |
692 | iwl_force_rf_reset(priv); | 734 | iwl_force_reset(priv, IWL_RF_RESET); |
693 | } | 735 | } |
694 | } | 736 | } |
695 | 737 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index f786a407638f..dd9ff2ed645a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -250,8 +250,6 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, | |||
250 | 250 | ||
251 | if (!priv->is_internal_short_scan) | 251 | if (!priv->is_internal_short_scan) |
252 | priv->next_scan_jiffies = 0; | 252 | priv->next_scan_jiffies = 0; |
253 | else | ||
254 | priv->last_internal_scan_jiffies = jiffies; | ||
255 | 253 | ||
256 | IWL_DEBUG_INFO(priv, "Setting scan to off\n"); | 254 | IWL_DEBUG_INFO(priv, "Setting scan to off\n"); |
257 | 255 | ||
@@ -471,21 +469,6 @@ EXPORT_SYMBOL(iwl_init_scan_params); | |||
471 | 469 | ||
472 | static int iwl_scan_initiate(struct iwl_priv *priv) | 470 | static int iwl_scan_initiate(struct iwl_priv *priv) |
473 | { | 471 | { |
474 | if (!iwl_is_ready_rf(priv)) { | ||
475 | IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n"); | ||
476 | return -EIO; | ||
477 | } | ||
478 | |||
479 | if (test_bit(STATUS_SCANNING, &priv->status)) { | ||
480 | IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); | ||
481 | return -EAGAIN; | ||
482 | } | ||
483 | |||
484 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
485 | IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); | ||
486 | return -EAGAIN; | ||
487 | } | ||
488 | |||
489 | IWL_DEBUG_INFO(priv, "Starting scan...\n"); | 472 | IWL_DEBUG_INFO(priv, "Starting scan...\n"); |
490 | set_bit(STATUS_SCANNING, &priv->status); | 473 | set_bit(STATUS_SCANNING, &priv->status); |
491 | priv->is_internal_short_scan = false; | 474 | priv->is_internal_short_scan = false; |
@@ -517,6 +500,18 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, | |||
517 | goto out_unlock; | 500 | goto out_unlock; |
518 | } | 501 | } |
519 | 502 | ||
503 | if (test_bit(STATUS_SCANNING, &priv->status)) { | ||
504 | IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); | ||
505 | ret = -EAGAIN; | ||
506 | goto out_unlock; | ||
507 | } | ||
508 | |||
509 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
510 | IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); | ||
511 | ret = -EAGAIN; | ||
512 | goto out_unlock; | ||
513 | } | ||
514 | |||
520 | /* We don't schedule scan within next_scan_jiffies period. | 515 | /* We don't schedule scan within next_scan_jiffies period. |
521 | * Avoid scanning during possible EAPOL exchange, return | 516 | * Avoid scanning during possible EAPOL exchange, return |
522 | * success immediately. | 517 | * success immediately. |
@@ -551,8 +546,6 @@ EXPORT_SYMBOL(iwl_mac_hw_scan); | |||
551 | * internal short scan, this function should only been called while associated. | 546 | * internal short scan, this function should only been called while associated. |
552 | * It will reset and tune the radio to prevent possible RF related problem | 547 | * It will reset and tune the radio to prevent possible RF related problem |
553 | */ | 548 | */ |
554 | #define IWL_DELAY_NEXT_INTERNAL_SCAN (HZ*1) | ||
555 | |||
556 | int iwl_internal_short_hw_scan(struct iwl_priv *priv) | 549 | int iwl_internal_short_hw_scan(struct iwl_priv *priv) |
557 | { | 550 | { |
558 | int ret = 0; | 551 | int ret = 0; |
@@ -572,12 +565,6 @@ int iwl_internal_short_hw_scan(struct iwl_priv *priv) | |||
572 | ret = -EAGAIN; | 565 | ret = -EAGAIN; |
573 | goto out; | 566 | goto out; |
574 | } | 567 | } |
575 | if (priv->last_internal_scan_jiffies && | ||
576 | time_after(priv->last_internal_scan_jiffies + | ||
577 | IWL_DELAY_NEXT_INTERNAL_SCAN, jiffies)) { | ||
578 | IWL_DEBUG_SCAN(priv, "internal scan rejected\n"); | ||
579 | goto out; | ||
580 | } | ||
581 | 568 | ||
582 | priv->scan_bands = 0; | 569 | priv->scan_bands = 0; |
583 | if (priv->band == IEEE80211_BAND_5GHZ) | 570 | if (priv->band == IEEE80211_BAND_5GHZ) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 6eff3d4d0616..10701b8eef23 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -60,7 +60,8 @@ static const u16 default_tid_to_tx_fifo[] = { | |||
60 | static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv, | 60 | static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv, |
61 | struct iwl_dma_ptr *ptr, size_t size) | 61 | struct iwl_dma_ptr *ptr, size_t size) |
62 | { | 62 | { |
63 | ptr->addr = pci_alloc_consistent(priv->pci_dev, size, &ptr->dma); | 63 | ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma, |
64 | GFP_KERNEL); | ||
64 | if (!ptr->addr) | 65 | if (!ptr->addr) |
65 | return -ENOMEM; | 66 | return -ENOMEM; |
66 | ptr->size = size; | 67 | ptr->size = size; |
@@ -73,21 +74,20 @@ static inline void iwl_free_dma_ptr(struct iwl_priv *priv, | |||
73 | if (unlikely(!ptr->addr)) | 74 | if (unlikely(!ptr->addr)) |
74 | return; | 75 | return; |
75 | 76 | ||
76 | pci_free_consistent(priv->pci_dev, ptr->size, ptr->addr, ptr->dma); | 77 | dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma); |
77 | memset(ptr, 0, sizeof(*ptr)); | 78 | memset(ptr, 0, sizeof(*ptr)); |
78 | } | 79 | } |
79 | 80 | ||
80 | /** | 81 | /** |
81 | * iwl_txq_update_write_ptr - Send new write index to hardware | 82 | * iwl_txq_update_write_ptr - Send new write index to hardware |
82 | */ | 83 | */ |
83 | int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) | 84 | void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) |
84 | { | 85 | { |
85 | u32 reg = 0; | 86 | u32 reg = 0; |
86 | int ret = 0; | ||
87 | int txq_id = txq->q.id; | 87 | int txq_id = txq->q.id; |
88 | 88 | ||
89 | if (txq->need_update == 0) | 89 | if (txq->need_update == 0) |
90 | return ret; | 90 | return; |
91 | 91 | ||
92 | /* if we're trying to save power */ | 92 | /* if we're trying to save power */ |
93 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { | 93 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { |
@@ -101,7 +101,7 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) | |||
101 | txq_id, reg); | 101 | txq_id, reg); |
102 | iwl_set_bit(priv, CSR_GP_CNTRL, | 102 | iwl_set_bit(priv, CSR_GP_CNTRL, |
103 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 103 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
104 | return ret; | 104 | return; |
105 | } | 105 | } |
106 | 106 | ||
107 | iwl_write_direct32(priv, HBUS_TARG_WRPTR, | 107 | iwl_write_direct32(priv, HBUS_TARG_WRPTR, |
@@ -114,8 +114,6 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) | |||
114 | txq->q.write_ptr | (txq_id << 8)); | 114 | txq->q.write_ptr | (txq_id << 8)); |
115 | 115 | ||
116 | txq->need_update = 0; | 116 | txq->need_update = 0; |
117 | |||
118 | return ret; | ||
119 | } | 117 | } |
120 | EXPORT_SYMBOL(iwl_txq_update_write_ptr); | 118 | EXPORT_SYMBOL(iwl_txq_update_write_ptr); |
121 | 119 | ||
@@ -146,7 +144,7 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) | |||
146 | { | 144 | { |
147 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; | 145 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
148 | struct iwl_queue *q = &txq->q; | 146 | struct iwl_queue *q = &txq->q; |
149 | struct pci_dev *dev = priv->pci_dev; | 147 | struct device *dev = &priv->pci_dev->dev; |
150 | int i; | 148 | int i; |
151 | 149 | ||
152 | if (q->n_bd == 0) | 150 | if (q->n_bd == 0) |
@@ -163,8 +161,8 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) | |||
163 | 161 | ||
164 | /* De-alloc circular buffer of TFDs */ | 162 | /* De-alloc circular buffer of TFDs */ |
165 | if (txq->q.n_bd) | 163 | if (txq->q.n_bd) |
166 | pci_free_consistent(dev, priv->hw_params.tfd_size * | 164 | dma_free_coherent(dev, priv->hw_params.tfd_size * |
167 | txq->q.n_bd, txq->tfds, txq->q.dma_addr); | 165 | txq->q.n_bd, txq->tfds, txq->q.dma_addr); |
168 | 166 | ||
169 | /* De-alloc array of per-TFD driver data */ | 167 | /* De-alloc array of per-TFD driver data */ |
170 | kfree(txq->txb); | 168 | kfree(txq->txb); |
@@ -193,7 +191,7 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) | |||
193 | { | 191 | { |
194 | struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; | 192 | struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; |
195 | struct iwl_queue *q = &txq->q; | 193 | struct iwl_queue *q = &txq->q; |
196 | struct pci_dev *dev = priv->pci_dev; | 194 | struct device *dev = &priv->pci_dev->dev; |
197 | int i; | 195 | int i; |
198 | 196 | ||
199 | if (q->n_bd == 0) | 197 | if (q->n_bd == 0) |
@@ -205,8 +203,8 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) | |||
205 | 203 | ||
206 | /* De-alloc circular buffer of TFDs */ | 204 | /* De-alloc circular buffer of TFDs */ |
207 | if (txq->q.n_bd) | 205 | if (txq->q.n_bd) |
208 | pci_free_consistent(dev, priv->hw_params.tfd_size * | 206 | dma_free_coherent(dev, priv->hw_params.tfd_size * txq->q.n_bd, |
209 | txq->q.n_bd, txq->tfds, txq->q.dma_addr); | 207 | txq->tfds, txq->q.dma_addr); |
210 | 208 | ||
211 | /* deallocate arrays */ | 209 | /* deallocate arrays */ |
212 | kfree(txq->cmd); | 210 | kfree(txq->cmd); |
@@ -297,7 +295,7 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, | |||
297 | static int iwl_tx_queue_alloc(struct iwl_priv *priv, | 295 | static int iwl_tx_queue_alloc(struct iwl_priv *priv, |
298 | struct iwl_tx_queue *txq, u32 id) | 296 | struct iwl_tx_queue *txq, u32 id) |
299 | { | 297 | { |
300 | struct pci_dev *dev = priv->pci_dev; | 298 | struct device *dev = &priv->pci_dev->dev; |
301 | size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX; | 299 | size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX; |
302 | 300 | ||
303 | /* Driver private data, only for Tx (not command) queues, | 301 | /* Driver private data, only for Tx (not command) queues, |
@@ -316,8 +314,8 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, | |||
316 | 314 | ||
317 | /* Circular buffer of transmit frame descriptors (TFDs), | 315 | /* Circular buffer of transmit frame descriptors (TFDs), |
318 | * shared with device */ | 316 | * shared with device */ |
319 | txq->tfds = pci_alloc_consistent(dev, tfd_sz, &txq->q.dma_addr); | 317 | txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, |
320 | 318 | GFP_KERNEL); | |
321 | if (!txq->tfds) { | 319 | if (!txq->tfds) { |
322 | IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz); | 320 | IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz); |
323 | goto error; | 321 | goto error; |
@@ -745,7 +743,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
745 | u8 tid = 0; | 743 | u8 tid = 0; |
746 | u8 *qc = NULL; | 744 | u8 *qc = NULL; |
747 | unsigned long flags; | 745 | unsigned long flags; |
748 | int ret; | ||
749 | 746 | ||
750 | spin_lock_irqsave(&priv->lock, flags); | 747 | spin_lock_irqsave(&priv->lock, flags); |
751 | if (iwl_is_rfkill(priv)) { | 748 | if (iwl_is_rfkill(priv)) { |
@@ -820,8 +817,10 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
820 | hdr->seq_ctrl |= cpu_to_le16(seq_number); | 817 | hdr->seq_ctrl |= cpu_to_le16(seq_number); |
821 | seq_number += 0x10; | 818 | seq_number += 0x10; |
822 | /* aggregation is on for this <sta,tid> */ | 819 | /* aggregation is on for this <sta,tid> */ |
823 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | 820 | if (info->flags & IEEE80211_TX_CTL_AMPDU && |
821 | priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) { | ||
824 | txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; | 822 | txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; |
823 | } | ||
825 | } | 824 | } |
826 | 825 | ||
827 | txq = &priv->txq[txq_id]; | 826 | txq = &priv->txq[txq_id]; |
@@ -963,7 +962,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
963 | 962 | ||
964 | /* Tell device the write index *just past* this latest filled TFD */ | 963 | /* Tell device the write index *just past* this latest filled TFD */ |
965 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 964 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
966 | ret = iwl_txq_update_write_ptr(priv, txq); | 965 | iwl_txq_update_write_ptr(priv, txq); |
967 | spin_unlock_irqrestore(&priv->lock, flags); | 966 | spin_unlock_irqrestore(&priv->lock, flags); |
968 | 967 | ||
969 | /* | 968 | /* |
@@ -977,9 +976,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
977 | if (sta_priv && sta_priv->client) | 976 | if (sta_priv && sta_priv->client) |
978 | atomic_inc(&sta_priv->pending_frames); | 977 | atomic_inc(&sta_priv->pending_frames); |
979 | 978 | ||
980 | if (ret) | ||
981 | return ret; | ||
982 | |||
983 | if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) { | 979 | if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) { |
984 | if (wait_write_ptr) { | 980 | if (wait_write_ptr) { |
985 | spin_lock_irqsave(&priv->lock, flags); | 981 | spin_lock_irqsave(&priv->lock, flags); |
@@ -1018,7 +1014,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
1018 | struct iwl_cmd_meta *out_meta; | 1014 | struct iwl_cmd_meta *out_meta; |
1019 | dma_addr_t phys_addr; | 1015 | dma_addr_t phys_addr; |
1020 | unsigned long flags; | 1016 | unsigned long flags; |
1021 | int len, ret; | 1017 | int len; |
1022 | u32 idx; | 1018 | u32 idx; |
1023 | u16 fix_size; | 1019 | u16 fix_size; |
1024 | 1020 | ||
@@ -1115,10 +1111,10 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
1115 | 1111 | ||
1116 | /* Increment and update queue's write index */ | 1112 | /* Increment and update queue's write index */ |
1117 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 1113 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
1118 | ret = iwl_txq_update_write_ptr(priv, txq); | 1114 | iwl_txq_update_write_ptr(priv, txq); |
1119 | 1115 | ||
1120 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); | 1116 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); |
1121 | return ret ? ret : idx; | 1117 | return idx; |
1122 | } | 1118 | } |
1123 | 1119 | ||
1124 | static void iwl_tx_status(struct iwl_priv *priv, struct sk_buff *skb) | 1120 | static void iwl_tx_status(struct iwl_priv *priv, struct sk_buff *skb) |
@@ -1260,6 +1256,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
1260 | 1256 | ||
1261 | if (!(meta->flags & CMD_ASYNC)) { | 1257 | if (!(meta->flags & CMD_ASYNC)) { |
1262 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | 1258 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); |
1259 | IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n", | ||
1260 | get_cmd_string(cmd->hdr.cmd)); | ||
1263 | wake_up_interruptible(&priv->wait_command_queue); | 1261 | wake_up_interruptible(&priv->wait_command_queue); |
1264 | } | 1262 | } |
1265 | } | 1263 | } |
@@ -1346,7 +1344,7 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid) | |||
1346 | { | 1344 | { |
1347 | int tx_fifo_id, txq_id, sta_id, ssn = -1; | 1345 | int tx_fifo_id, txq_id, sta_id, ssn = -1; |
1348 | struct iwl_tid_data *tid_data; | 1346 | struct iwl_tid_data *tid_data; |
1349 | int ret, write_ptr, read_ptr; | 1347 | int write_ptr, read_ptr; |
1350 | unsigned long flags; | 1348 | unsigned long flags; |
1351 | 1349 | ||
1352 | if (!ra) { | 1350 | if (!ra) { |
@@ -1398,13 +1396,17 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid) | |||
1398 | priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; | 1396 | priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; |
1399 | 1397 | ||
1400 | spin_lock_irqsave(&priv->lock, flags); | 1398 | spin_lock_irqsave(&priv->lock, flags); |
1401 | ret = priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn, | 1399 | /* |
1400 | * the only reason this call can fail is queue number out of range, | ||
1401 | * which can happen if uCode is reloaded and all the station | ||
1402 | * information are lost. if it is outside the range, there is no need | ||
1403 | * to deactivate the uCode queue, just return "success" to allow | ||
1404 | * mac80211 to clean up it own data. | ||
1405 | */ | ||
1406 | priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn, | ||
1402 | tx_fifo_id); | 1407 | tx_fifo_id); |
1403 | spin_unlock_irqrestore(&priv->lock, flags); | 1408 | spin_unlock_irqrestore(&priv->lock, flags); |
1404 | 1409 | ||
1405 | if (ret) | ||
1406 | return ret; | ||
1407 | |||
1408 | ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid); | 1410 | ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid); |
1409 | 1411 | ||
1410 | return 0; | 1412 | return 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index eac2b9a95711..54daa38ecba3 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -53,8 +53,8 @@ | |||
53 | #include "iwl-commands.h" | 53 | #include "iwl-commands.h" |
54 | #include "iwl-sta.h" | 54 | #include "iwl-sta.h" |
55 | #include "iwl-3945.h" | 55 | #include "iwl-3945.h" |
56 | #include "iwl-helpers.h" | ||
57 | #include "iwl-core.h" | 56 | #include "iwl-core.h" |
57 | #include "iwl-helpers.h" | ||
58 | #include "iwl-dev.h" | 58 | #include "iwl-dev.h" |
59 | #include "iwl-spectrum.h" | 59 | #include "iwl-spectrum.h" |
60 | 60 | ||
@@ -352,10 +352,10 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) | |||
352 | static void iwl3945_unset_hw_params(struct iwl_priv *priv) | 352 | static void iwl3945_unset_hw_params(struct iwl_priv *priv) |
353 | { | 353 | { |
354 | if (priv->shared_virt) | 354 | if (priv->shared_virt) |
355 | pci_free_consistent(priv->pci_dev, | 355 | dma_free_coherent(&priv->pci_dev->dev, |
356 | sizeof(struct iwl3945_shared), | 356 | sizeof(struct iwl3945_shared), |
357 | priv->shared_virt, | 357 | priv->shared_virt, |
358 | priv->shared_phys); | 358 | priv->shared_phys); |
359 | } | 359 | } |
360 | 360 | ||
361 | static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, | 361 | static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, |
@@ -478,7 +478,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
478 | u8 wait_write_ptr = 0; | 478 | u8 wait_write_ptr = 0; |
479 | u8 *qc = NULL; | 479 | u8 *qc = NULL; |
480 | unsigned long flags; | 480 | unsigned long flags; |
481 | int rc; | ||
482 | 481 | ||
483 | spin_lock_irqsave(&priv->lock, flags); | 482 | spin_lock_irqsave(&priv->lock, flags); |
484 | if (iwl_is_rfkill(priv)) { | 483 | if (iwl_is_rfkill(priv)) { |
@@ -663,12 +662,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
663 | 662 | ||
664 | /* Tell device the write index *just past* this latest filled TFD */ | 663 | /* Tell device the write index *just past* this latest filled TFD */ |
665 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 664 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
666 | rc = iwl_txq_update_write_ptr(priv, txq); | 665 | iwl_txq_update_write_ptr(priv, txq); |
667 | spin_unlock_irqrestore(&priv->lock, flags); | 666 | spin_unlock_irqrestore(&priv->lock, flags); |
668 | 667 | ||
669 | if (rc) | ||
670 | return rc; | ||
671 | |||
672 | if ((iwl_queue_space(q) < q->high_mark) | 668 | if ((iwl_queue_space(q) < q->high_mark) |
673 | && priv->mac80211_registered) { | 669 | && priv->mac80211_registered) { |
674 | if (wait_write_ptr) { | 670 | if (wait_write_ptr) { |
@@ -1063,13 +1059,13 @@ static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl_priv *priv, | |||
1063 | * also updates the memory address in the firmware to reference the new | 1059 | * also updates the memory address in the firmware to reference the new |
1064 | * target buffer. | 1060 | * target buffer. |
1065 | */ | 1061 | */ |
1066 | static int iwl3945_rx_queue_restock(struct iwl_priv *priv) | 1062 | static void iwl3945_rx_queue_restock(struct iwl_priv *priv) |
1067 | { | 1063 | { |
1068 | struct iwl_rx_queue *rxq = &priv->rxq; | 1064 | struct iwl_rx_queue *rxq = &priv->rxq; |
1069 | struct list_head *element; | 1065 | struct list_head *element; |
1070 | struct iwl_rx_mem_buffer *rxb; | 1066 | struct iwl_rx_mem_buffer *rxb; |
1071 | unsigned long flags; | 1067 | unsigned long flags; |
1072 | int write, rc; | 1068 | int write; |
1073 | 1069 | ||
1074 | spin_lock_irqsave(&rxq->lock, flags); | 1070 | spin_lock_irqsave(&rxq->lock, flags); |
1075 | write = rxq->write & ~0x7; | 1071 | write = rxq->write & ~0x7; |
@@ -1099,12 +1095,8 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv) | |||
1099 | spin_lock_irqsave(&rxq->lock, flags); | 1095 | spin_lock_irqsave(&rxq->lock, flags); |
1100 | rxq->need_update = 1; | 1096 | rxq->need_update = 1; |
1101 | spin_unlock_irqrestore(&rxq->lock, flags); | 1097 | spin_unlock_irqrestore(&rxq->lock, flags); |
1102 | rc = iwl_rx_queue_update_write_ptr(priv, rxq); | 1098 | iwl_rx_queue_update_write_ptr(priv, rxq); |
1103 | if (rc) | ||
1104 | return rc; | ||
1105 | } | 1099 | } |
1106 | |||
1107 | return 0; | ||
1108 | } | 1100 | } |
1109 | 1101 | ||
1110 | /** | 1102 | /** |
@@ -1249,10 +1241,10 @@ static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rx | |||
1249 | } | 1241 | } |
1250 | } | 1242 | } |
1251 | 1243 | ||
1252 | pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, | 1244 | dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, |
1253 | rxq->dma_addr); | 1245 | rxq->dma_addr); |
1254 | pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status), | 1246 | dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), |
1255 | rxq->rb_stts, rxq->rb_stts_dma); | 1247 | rxq->rb_stts, rxq->rb_stts_dma); |
1256 | rxq->bd = NULL; | 1248 | rxq->bd = NULL; |
1257 | rxq->rb_stts = NULL; | 1249 | rxq->rb_stts = NULL; |
1258 | } | 1250 | } |
@@ -3855,6 +3847,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
3855 | INIT_LIST_HEAD(&priv->free_frames); | 3847 | INIT_LIST_HEAD(&priv->free_frames); |
3856 | 3848 | ||
3857 | mutex_init(&priv->mutex); | 3849 | mutex_init(&priv->mutex); |
3850 | mutex_init(&priv->sync_cmd_mutex); | ||
3858 | 3851 | ||
3859 | /* Clear the driver's (not device's) station table */ | 3852 | /* Clear the driver's (not device's) station table */ |
3860 | iwl_clear_stations_table(priv); | 3853 | iwl_clear_stations_table(priv); |
@@ -4047,6 +4040,13 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
4047 | spin_lock_init(&priv->reg_lock); | 4040 | spin_lock_init(&priv->reg_lock); |
4048 | spin_lock_init(&priv->lock); | 4041 | spin_lock_init(&priv->lock); |
4049 | 4042 | ||
4043 | /* | ||
4044 | * stop and reset the on-board processor just in case it is in a | ||
4045 | * strange state ... like being left stranded by a primary kernel | ||
4046 | * and this is now the kdump kernel trying to start up | ||
4047 | */ | ||
4048 | iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | ||
4049 | |||
4050 | /*********************** | 4050 | /*********************** |
4051 | * 4. Read EEPROM | 4051 | * 4. Read EEPROM |
4052 | * ********************/ | 4052 | * ********************/ |