aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c67
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c3
3 files changed, 69 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index a4d842a05836..05d808b28777 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -390,6 +390,67 @@ static void iwl3945_accumulative_statistics(struct iwl_priv *priv,
390} 390}
391#endif 391#endif
392 392
393/**
394 * iwl3945_good_plcp_health - checks for plcp error.
395 *
396 * When the plcp error is exceeding the thresholds, reset the radio
397 * to improve the throughput.
398 */
399static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
400 struct iwl_rx_packet *pkt)
401{
402 bool rc = true;
403 struct iwl3945_notif_statistics current_stat;
404 int combined_plcp_delta;
405 unsigned int plcp_msec;
406 unsigned long plcp_received_jiffies;
407
408 memcpy(&current_stat, pkt->u.raw, sizeof(struct
409 iwl3945_notif_statistics));
410 /*
411 * check for plcp_err and trigger radio reset if it exceeds
412 * the plcp error threshold plcp_delta.
413 */
414 plcp_received_jiffies = jiffies;
415 plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
416 (long) priv->plcp_jiffies);
417 priv->plcp_jiffies = plcp_received_jiffies;
418 /*
419 * check to make sure plcp_msec is not 0 to prevent division
420 * by zero.
421 */
422 if (plcp_msec) {
423 combined_plcp_delta =
424 (le32_to_cpu(current_stat.rx.ofdm.plcp_err) -
425 le32_to_cpu(priv->_3945.statistics.rx.ofdm.plcp_err));
426
427 if ((combined_plcp_delta > 0) &&
428 ((combined_plcp_delta * 100) / plcp_msec) >
429 priv->cfg->plcp_delta_threshold) {
430 /*
431 * if plcp_err exceed the threshold, the following
432 * data is printed in csv format:
433 * Text: plcp_err exceeded %d,
434 * Received ofdm.plcp_err,
435 * Current ofdm.plcp_err,
436 * combined_plcp_delta,
437 * plcp_msec
438 */
439 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
440 "%u, %d, %u mSecs\n",
441 priv->cfg->plcp_delta_threshold,
442 le32_to_cpu(current_stat.rx.ofdm.plcp_err),
443 combined_plcp_delta, plcp_msec);
444 /*
445 * Reset the RF radio due to the high plcp
446 * error rate
447 */
448 rc = false;
449 }
450 }
451 return rc;
452}
453
393void iwl3945_hw_rx_statistics(struct iwl_priv *priv, 454void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
394 struct iwl_rx_mem_buffer *rxb) 455 struct iwl_rx_mem_buffer *rxb)
395{ 456{
@@ -401,6 +462,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
401#ifdef CONFIG_IWLWIFI_DEBUG 462#ifdef CONFIG_IWLWIFI_DEBUG
402 iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); 463 iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw);
403#endif 464#endif
465 iwl_recover_from_statistics(priv, pkt);
404 466
405 memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); 467 memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics));
406} 468}
@@ -2792,6 +2854,7 @@ static struct iwl_lib_ops iwl3945_lib = {
2792 .config_ap = iwl3945_config_ap, 2854 .config_ap = iwl3945_config_ap,
2793 .manage_ibss_station = iwl3945_manage_ibss_station, 2855 .manage_ibss_station = iwl3945_manage_ibss_station,
2794 .add_bcast_station = iwl3945_add_bcast_station, 2856 .add_bcast_station = iwl3945_add_bcast_station,
2857 .check_plcp_health = iwl3945_good_plcp_health,
2795 2858
2796 .debugfs_ops = { 2859 .debugfs_ops = {
2797 .rx_stats_read = iwl3945_ucode_rx_stats_read, 2860 .rx_stats_read = iwl3945_ucode_rx_stats_read,
@@ -2832,7 +2895,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2832 .ht_greenfield_support = false, 2895 .ht_greenfield_support = false,
2833 .led_compensation = 64, 2896 .led_compensation = 64,
2834 .broken_powersave = true, 2897 .broken_powersave = true,
2835 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 2898 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
2836 .monitor_recover_period = IWL_MONITORING_PERIOD, 2899 .monitor_recover_period = IWL_MONITORING_PERIOD,
2837 .max_event_log_size = 512, 2900 .max_event_log_size = 512,
2838 .tx_power_by_driver = true, 2901 .tx_power_by_driver = true,
@@ -2853,7 +2916,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
2853 .ht_greenfield_support = false, 2916 .ht_greenfield_support = false,
2854 .led_compensation = 64, 2917 .led_compensation = 64,
2855 .broken_powersave = true, 2918 .broken_powersave = true,
2856 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 2919 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
2857 .monitor_recover_period = IWL_MONITORING_PERIOD, 2920 .monitor_recover_period = IWL_MONITORING_PERIOD,
2858 .max_event_log_size = 512, 2921 .max_event_log_size = 512,
2859 .tx_power_by_driver = true, 2922 .tx_power_by_driver = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 2f664a3f0484..7a3f94926c25 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -441,6 +441,8 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
441 struct iwl_rx_packet *pkt); 441 struct iwl_rx_packet *pkt);
442bool iwl_good_ack_health(struct iwl_priv *priv, 442bool iwl_good_ack_health(struct iwl_priv *priv,
443 struct iwl_rx_packet *pkt); 443 struct iwl_rx_packet *pkt);
444void iwl_recover_from_statistics(struct iwl_priv *priv,
445 struct iwl_rx_packet *pkt);
444void iwl_rx_statistics(struct iwl_priv *priv, 446void iwl_rx_statistics(struct iwl_priv *priv,
445 struct iwl_rx_mem_buffer *rxb); 447 struct iwl_rx_mem_buffer *rxb);
446void iwl_reply_statistics(struct iwl_priv *priv, 448void iwl_reply_statistics(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index d661fce000c2..c7c8d8a43eb3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -397,7 +397,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
397} 397}
398EXPORT_SYMBOL(iwl_good_plcp_health); 398EXPORT_SYMBOL(iwl_good_plcp_health);
399 399
400static void iwl_recover_from_statistics(struct iwl_priv *priv, 400void iwl_recover_from_statistics(struct iwl_priv *priv,
401 struct iwl_rx_packet *pkt) 401 struct iwl_rx_packet *pkt)
402{ 402{
403 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 403 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -428,6 +428,7 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv,
428 } 428 }
429 } 429 }
430} 430}
431EXPORT_SYMBOL(iwl_recover_from_statistics);
431 432
432void iwl_rx_statistics(struct iwl_priv *priv, 433void iwl_rx_statistics(struct iwl_priv *priv,
433 struct iwl_rx_mem_buffer *rxb) 434 struct iwl_rx_mem_buffer *rxb)