aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-02-22 15:10:22 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-02-22 15:10:22 -0500
commit5db5e44cdcdc5ee9cc821bd4d63445af0bb34bce (patch)
treeb5e5787a6d5c15e589d275c7434ebbf341257234 /drivers/net/wireless/iwlwifi/iwl-agn.c
parentdb62983a1e4b2af9e79c97af768f0c8b80bd93f0 (diff)
parent320d6c1b56de5f461c6062625b9664095f90ee95 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c74
1 files changed, 40 insertions, 34 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 8ee810f5fc06..abd0461bd307 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1413,34 +1413,42 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1413/** 1413/**
1414 * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries. 1414 * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries.
1415 * 1415 *
1416 * When the ACK count ratio is 0 and aggregated BA timeout retries exceeding 1416 * When the ACK count ratio is low and aggregated BA timeout retries exceeding
1417 * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal 1417 * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
1418 * operation state. 1418 * operation state.
1419 */ 1419 */
1420bool iwl_good_ack_health(struct iwl_priv *priv, 1420bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
1421 struct iwl_rx_packet *pkt)
1422{ 1421{
1423 bool rc = true; 1422 int actual_delta, expected_delta, ba_timeout_delta;
1424 int actual_ack_cnt_delta, expected_ack_cnt_delta; 1423 struct statistics_tx *cur, *old;
1425 int ba_timeout_delta; 1424
1426 1425 if (priv->_agn.agg_tids_count)
1427 actual_ack_cnt_delta = 1426 return true;
1428 le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) - 1427
1429 le32_to_cpu(priv->_agn.statistics.tx.actual_ack_cnt); 1428 if (iwl_bt_statistics(priv)) {
1430 expected_ack_cnt_delta = 1429 cur = &pkt->u.stats_bt.tx;
1431 le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) - 1430 old = &priv->_agn.statistics_bt.tx;
1432 le32_to_cpu(priv->_agn.statistics.tx.expected_ack_cnt); 1431 } else {
1433 ba_timeout_delta = 1432 cur = &pkt->u.stats.tx;
1434 le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) - 1433 old = &priv->_agn.statistics.tx;
1435 le32_to_cpu(priv->_agn.statistics.tx.agg.ba_timeout); 1434 }
1436 if ((priv->_agn.agg_tids_count > 0) && 1435
1437 (expected_ack_cnt_delta > 0) && 1436 actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
1438 (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta) 1437 le32_to_cpu(old->actual_ack_cnt);
1439 < ACK_CNT_RATIO) && 1438 expected_delta = le32_to_cpu(cur->expected_ack_cnt) -
1440 (ba_timeout_delta > BA_TIMEOUT_CNT)) { 1439 le32_to_cpu(old->expected_ack_cnt);
1441 IWL_DEBUG_RADIO(priv, "actual_ack_cnt delta = %d," 1440
1442 " expected_ack_cnt = %d\n", 1441 /* Values should not be negative, but we do not trust the firmware */
1443 actual_ack_cnt_delta, expected_ack_cnt_delta); 1442 if (actual_delta <= 0 || expected_delta <= 0)
1443 return true;
1444
1445 ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) -
1446 le32_to_cpu(old->agg.ba_timeout);
1447
1448 if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO &&
1449 ba_timeout_delta > BA_TIMEOUT_CNT) {
1450 IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n",
1451 actual_delta, expected_delta, ba_timeout_delta);
1444 1452
1445#ifdef CONFIG_IWLWIFI_DEBUGFS 1453#ifdef CONFIG_IWLWIFI_DEBUGFS
1446 /* 1454 /*
@@ -1448,20 +1456,18 @@ bool iwl_good_ack_health(struct iwl_priv *priv,
1448 * statistics aren't available. If DEBUGFS is set but 1456 * statistics aren't available. If DEBUGFS is set but
1449 * DEBUG is not, these will just compile out. 1457 * DEBUG is not, these will just compile out.
1450 */ 1458 */
1451 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n", 1459 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n",
1452 priv->_agn.delta_statistics.tx.rx_detected_cnt); 1460 priv->_agn.delta_statistics.tx.rx_detected_cnt);
1453 IWL_DEBUG_RADIO(priv, 1461 IWL_DEBUG_RADIO(priv,
1454 "ack_or_ba_timeout_collision delta = %d\n", 1462 "ack_or_ba_timeout_collision delta %d\n",
1455 priv->_agn.delta_statistics.tx. 1463 priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision);
1456 ack_or_ba_timeout_collision);
1457#endif 1464#endif
1458 IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n", 1465
1459 ba_timeout_delta); 1466 if (ba_timeout_delta >= BA_TIMEOUT_MAX)
1460 if (!actual_ack_cnt_delta && 1467 return false;
1461 (ba_timeout_delta >= BA_TIMEOUT_MAX))
1462 rc = false;
1463 } 1468 }
1464 return rc; 1469
1470 return true;
1465} 1471}
1466 1472
1467 1473