aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-rx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index dc06c7bb0f5c..ea309f42a78a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -602,11 +602,15 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
602 602
603#define REG_RECALIB_PERIOD (60) 603#define REG_RECALIB_PERIOD (60)
604 604
605#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n"
605void iwl_rx_statistics(struct iwl_priv *priv, 606void iwl_rx_statistics(struct iwl_priv *priv,
606 struct iwl_rx_mem_buffer *rxb) 607 struct iwl_rx_mem_buffer *rxb)
607{ 608{
608 int change; 609 int change;
609 struct iwl_rx_packet *pkt = rxb_addr(rxb); 610 struct iwl_rx_packet *pkt = rxb_addr(rxb);
611 int combined_plcp_delta;
612 unsigned int plcp_msec;
613 unsigned long plcp_received_jiffies;
610 614
611 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 615 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
612 (int)sizeof(priv->statistics), 616 (int)sizeof(priv->statistics),
@@ -621,6 +625,56 @@ void iwl_rx_statistics(struct iwl_priv *priv,
621#ifdef CONFIG_IWLWIFI_DEBUG 625#ifdef CONFIG_IWLWIFI_DEBUG
622 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); 626 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
623#endif 627#endif
628 /*
629 * check for plcp_err and trigger radio reset if it exceeds
630 * the plcp error threshold plcp_delta.
631 */
632 plcp_received_jiffies = jiffies;
633 plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
634 (long) priv->plcp_jiffies);
635 priv->plcp_jiffies = plcp_received_jiffies;
636 /*
637 * check to make sure plcp_msec is not 0 to prevent division
638 * by zero.
639 */
640 if (plcp_msec) {
641 combined_plcp_delta =
642 (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
643 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) +
644 (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
645 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err));
646
647 if ((combined_plcp_delta > 0) &&
648 ((combined_plcp_delta * 100) / plcp_msec) >
649 priv->cfg->plcp_delta_threshold) {
650 /*
651 * if plcp_err exceed the threshold, the following
652 * data is printed in csv format:
653 * Text: plcp_err exceeded %d,
654 * Received ofdm.plcp_err,
655 * Current ofdm.plcp_err,
656 * Received ofdm_ht.plcp_err,
657 * Current ofdm_ht.plcp_err,
658 * combined_plcp_delta,
659 * plcp_msec
660 */
661 IWL_DEBUG_RADIO(priv, PLCP_MSG,
662 priv->cfg->plcp_delta_threshold,
663 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
664 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err),
665 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
666 le32_to_cpu(
667 priv->statistics.rx.ofdm_ht.plcp_err),
668 combined_plcp_delta, plcp_msec);
669
670 /*
671 * Reset the RF radio due to the high plcp
672 * error rate
673 */
674 iwl_force_rf_reset(priv);
675 }
676 }
677
624 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); 678 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
625 679
626 set_bit(STATUS_STATISTICS, &priv->status); 680 set_bit(STATUS_STATISTICS, &priv->status);