diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2011-02-28 08:33:16 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-28 14:11:27 -0500 |
commit | ad6e82a5348e494c0023d77fa55933f23b55711c (patch) | |
tree | 277df5b7f7f3087c2d25cbc490c4c9933b0684f6 | |
parent | b7977ffaab5187ad75edaf04ac854615cea93828 (diff) |
iwlwifi: move check health code into iwl-rx.c
Remove check_plcp_health and check_ack_health ops methods, they are
unneeded after iwlegacy driver split. Merge check health code into to
iwl-rx.c and make functions static.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-1000.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-2000.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-6000.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 87 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 66 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rx.c | 162 |
9 files changed, 155 insertions, 183 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index ba78bc8a259f..e8e1c2dc8659 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -232,8 +232,6 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
232 | .bt_stats_read = iwl_ucode_bt_stats_read, | 232 | .bt_stats_read = iwl_ucode_bt_stats_read, |
233 | .reply_tx_error = iwl_reply_tx_error_read, | 233 | .reply_tx_error = iwl_reply_tx_error_read, |
234 | }, | 234 | }, |
235 | .check_plcp_health = iwl_good_plcp_health, | ||
236 | .check_ack_health = iwl_good_ack_health, | ||
237 | .txfifo_flush = iwlagn_txfifo_flush, | 235 | .txfifo_flush = iwlagn_txfifo_flush, |
238 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 236 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
239 | .tt_ops = { | 237 | .tt_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 335adedcee43..d7b6126408c9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -315,8 +315,6 @@ static struct iwl_lib_ops iwl2000_lib = { | |||
315 | .bt_stats_read = iwl_ucode_bt_stats_read, | 315 | .bt_stats_read = iwl_ucode_bt_stats_read, |
316 | .reply_tx_error = iwl_reply_tx_error_read, | 316 | .reply_tx_error = iwl_reply_tx_error_read, |
317 | }, | 317 | }, |
318 | .check_plcp_health = iwl_good_plcp_health, | ||
319 | .check_ack_health = iwl_good_ack_health, | ||
320 | .txfifo_flush = iwlagn_txfifo_flush, | 318 | .txfifo_flush = iwlagn_txfifo_flush, |
321 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 319 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
322 | .tt_ops = { | 320 | .tt_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 79ab0a6b1386..90e727b1b4c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -402,8 +402,6 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
402 | .bt_stats_read = iwl_ucode_bt_stats_read, | 402 | .bt_stats_read = iwl_ucode_bt_stats_read, |
403 | .reply_tx_error = iwl_reply_tx_error_read, | 403 | .reply_tx_error = iwl_reply_tx_error_read, |
404 | }, | 404 | }, |
405 | .check_plcp_health = iwl_good_plcp_health, | ||
406 | .check_ack_health = iwl_good_ack_health, | ||
407 | .txfifo_flush = iwlagn_txfifo_flush, | 405 | .txfifo_flush = iwlagn_txfifo_flush, |
408 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 406 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
409 | .tt_ops = { | 407 | .tt_ops = { |
@@ -471,8 +469,6 @@ static struct iwl_lib_ops iwl5150_lib = { | |||
471 | .bt_stats_read = iwl_ucode_bt_stats_read, | 469 | .bt_stats_read = iwl_ucode_bt_stats_read, |
472 | .reply_tx_error = iwl_reply_tx_error_read, | 470 | .reply_tx_error = iwl_reply_tx_error_read, |
473 | }, | 471 | }, |
474 | .check_plcp_health = iwl_good_plcp_health, | ||
475 | .check_ack_health = iwl_good_ack_health, | ||
476 | .txfifo_flush = iwlagn_txfifo_flush, | 472 | .txfifo_flush = iwlagn_txfifo_flush, |
477 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 473 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
478 | .tt_ops = { | 474 | .tt_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index f6493f77610d..a745b01c0ec1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -343,8 +343,6 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
343 | .bt_stats_read = iwl_ucode_bt_stats_read, | 343 | .bt_stats_read = iwl_ucode_bt_stats_read, |
344 | .reply_tx_error = iwl_reply_tx_error_read, | 344 | .reply_tx_error = iwl_reply_tx_error_read, |
345 | }, | 345 | }, |
346 | .check_plcp_health = iwl_good_plcp_health, | ||
347 | .check_ack_health = iwl_good_ack_health, | ||
348 | .txfifo_flush = iwlagn_txfifo_flush, | 346 | .txfifo_flush = iwlagn_txfifo_flush, |
349 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 347 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
350 | .tt_ops = { | 348 | .tt_ops = { |
@@ -415,8 +413,6 @@ static struct iwl_lib_ops iwl6030_lib = { | |||
415 | .bt_stats_read = iwl_ucode_bt_stats_read, | 413 | .bt_stats_read = iwl_ucode_bt_stats_read, |
416 | .reply_tx_error = iwl_reply_tx_error_read, | 414 | .reply_tx_error = iwl_reply_tx_error_read, |
417 | }, | 415 | }, |
418 | .check_plcp_health = iwl_good_plcp_health, | ||
419 | .check_ack_health = iwl_good_ack_health, | ||
420 | .txfifo_flush = iwlagn_txfifo_flush, | 416 | .txfifo_flush = iwlagn_txfifo_flush, |
421 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 417 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
422 | .tt_ops = { | 418 | .tt_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index b192ca842f0a..7a89a55ec316 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c | |||
@@ -169,93 +169,6 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, | |||
169 | 169 | ||
170 | #define REG_RECALIB_PERIOD (60) | 170 | #define REG_RECALIB_PERIOD (60) |
171 | 171 | ||
172 | /** | ||
173 | * iwl_good_plcp_health - checks for plcp error. | ||
174 | * | ||
175 | * When the plcp error is exceeding the thresholds, reset the radio | ||
176 | * to improve the throughput. | ||
177 | */ | ||
178 | bool iwl_good_plcp_health(struct iwl_priv *priv, | ||
179 | struct iwl_rx_packet *pkt) | ||
180 | { | ||
181 | bool rc = true; | ||
182 | int combined_plcp_delta; | ||
183 | unsigned int plcp_msec; | ||
184 | unsigned long plcp_received_jiffies; | ||
185 | |||
186 | if (priv->cfg->base_params->plcp_delta_threshold == | ||
187 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { | ||
188 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); | ||
189 | return rc; | ||
190 | } | ||
191 | |||
192 | /* | ||
193 | * check for plcp_err and trigger radio reset if it exceeds | ||
194 | * the plcp error threshold plcp_delta. | ||
195 | */ | ||
196 | plcp_received_jiffies = jiffies; | ||
197 | plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - | ||
198 | (long) priv->plcp_jiffies); | ||
199 | priv->plcp_jiffies = plcp_received_jiffies; | ||
200 | /* | ||
201 | * check to make sure plcp_msec is not 0 to prevent division | ||
202 | * by zero. | ||
203 | */ | ||
204 | if (plcp_msec) { | ||
205 | struct statistics_rx_phy *ofdm; | ||
206 | struct statistics_rx_ht_phy *ofdm_ht; | ||
207 | |||
208 | if (iwl_bt_statistics(priv)) { | ||
209 | ofdm = &pkt->u.stats_bt.rx.ofdm; | ||
210 | ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; | ||
211 | combined_plcp_delta = | ||
212 | (le32_to_cpu(ofdm->plcp_err) - | ||
213 | le32_to_cpu(priv->_agn.statistics_bt. | ||
214 | rx.ofdm.plcp_err)) + | ||
215 | (le32_to_cpu(ofdm_ht->plcp_err) - | ||
216 | le32_to_cpu(priv->_agn.statistics_bt. | ||
217 | rx.ofdm_ht.plcp_err)); | ||
218 | } else { | ||
219 | ofdm = &pkt->u.stats.rx.ofdm; | ||
220 | ofdm_ht = &pkt->u.stats.rx.ofdm_ht; | ||
221 | combined_plcp_delta = | ||
222 | (le32_to_cpu(ofdm->plcp_err) - | ||
223 | le32_to_cpu(priv->_agn.statistics. | ||
224 | rx.ofdm.plcp_err)) + | ||
225 | (le32_to_cpu(ofdm_ht->plcp_err) - | ||
226 | le32_to_cpu(priv->_agn.statistics. | ||
227 | rx.ofdm_ht.plcp_err)); | ||
228 | } | ||
229 | |||
230 | if ((combined_plcp_delta > 0) && | ||
231 | ((combined_plcp_delta * 100) / plcp_msec) > | ||
232 | priv->cfg->base_params->plcp_delta_threshold) { | ||
233 | /* | ||
234 | * if plcp_err exceed the threshold, | ||
235 | * the following data is printed in csv format: | ||
236 | * Text: plcp_err exceeded %d, | ||
237 | * Received ofdm.plcp_err, | ||
238 | * Current ofdm.plcp_err, | ||
239 | * Received ofdm_ht.plcp_err, | ||
240 | * Current ofdm_ht.plcp_err, | ||
241 | * combined_plcp_delta, | ||
242 | * plcp_msec | ||
243 | */ | ||
244 | IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " | ||
245 | "%u, %u, %u, %u, %d, %u mSecs\n", | ||
246 | priv->cfg->base_params->plcp_delta_threshold, | ||
247 | le32_to_cpu(ofdm->plcp_err), | ||
248 | le32_to_cpu(ofdm->plcp_err), | ||
249 | le32_to_cpu(ofdm_ht->plcp_err), | ||
250 | le32_to_cpu(ofdm_ht->plcp_err), | ||
251 | combined_plcp_delta, plcp_msec); | ||
252 | |||
253 | rc = false; | ||
254 | } | ||
255 | } | ||
256 | return rc; | ||
257 | } | ||
258 | |||
259 | void iwl_rx_statistics(struct iwl_priv *priv, | 172 | void iwl_rx_statistics(struct iwl_priv *priv, |
260 | struct iwl_rx_mem_buffer *rxb) | 173 | struct iwl_rx_mem_buffer *rxb) |
261 | { | 174 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 4792418191e4..c96d4ad5def0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1413,72 +1413,6 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1413 | iwl_enable_rfkill_int(priv); | 1413 | iwl_enable_rfkill_int(priv); |
1414 | } | 1414 | } |
1415 | 1415 | ||
1416 | /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ | ||
1417 | #define ACK_CNT_RATIO (50) | ||
1418 | #define BA_TIMEOUT_CNT (5) | ||
1419 | #define BA_TIMEOUT_MAX (16) | ||
1420 | |||
1421 | /** | ||
1422 | * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries. | ||
1423 | * | ||
1424 | * When the ACK count ratio is low and aggregated BA timeout retries exceeding | ||
1425 | * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal | ||
1426 | * operation state. | ||
1427 | */ | ||
1428 | bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) | ||
1429 | { | ||
1430 | int actual_delta, expected_delta, ba_timeout_delta; | ||
1431 | struct statistics_tx *cur, *old; | ||
1432 | |||
1433 | if (priv->_agn.agg_tids_count) | ||
1434 | return true; | ||
1435 | |||
1436 | if (iwl_bt_statistics(priv)) { | ||
1437 | cur = &pkt->u.stats_bt.tx; | ||
1438 | old = &priv->_agn.statistics_bt.tx; | ||
1439 | } else { | ||
1440 | cur = &pkt->u.stats.tx; | ||
1441 | old = &priv->_agn.statistics.tx; | ||
1442 | } | ||
1443 | |||
1444 | actual_delta = le32_to_cpu(cur->actual_ack_cnt) - | ||
1445 | le32_to_cpu(old->actual_ack_cnt); | ||
1446 | expected_delta = le32_to_cpu(cur->expected_ack_cnt) - | ||
1447 | le32_to_cpu(old->expected_ack_cnt); | ||
1448 | |||
1449 | /* Values should not be negative, but we do not trust the firmware */ | ||
1450 | if (actual_delta <= 0 || expected_delta <= 0) | ||
1451 | return true; | ||
1452 | |||
1453 | ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) - | ||
1454 | le32_to_cpu(old->agg.ba_timeout); | ||
1455 | |||
1456 | if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO && | ||
1457 | ba_timeout_delta > BA_TIMEOUT_CNT) { | ||
1458 | IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n", | ||
1459 | actual_delta, expected_delta, ba_timeout_delta); | ||
1460 | |||
1461 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
1462 | /* | ||
1463 | * This is ifdef'ed on DEBUGFS because otherwise the | ||
1464 | * statistics aren't available. If DEBUGFS is set but | ||
1465 | * DEBUG is not, these will just compile out. | ||
1466 | */ | ||
1467 | IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n", | ||
1468 | priv->_agn.delta_statistics.tx.rx_detected_cnt); | ||
1469 | IWL_DEBUG_RADIO(priv, | ||
1470 | "ack_or_ba_timeout_collision delta %d\n", | ||
1471 | priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision); | ||
1472 | #endif | ||
1473 | |||
1474 | if (ba_timeout_delta >= BA_TIMEOUT_MAX) | ||
1475 | return false; | ||
1476 | } | ||
1477 | |||
1478 | return true; | ||
1479 | } | ||
1480 | |||
1481 | |||
1482 | /***************************************************************************** | 1416 | /***************************************************************************** |
1483 | * | 1417 | * |
1484 | * sysfs attributes | 1418 | * sysfs attributes |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 88c7210dfb91..b5a169be48e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -121,8 +121,6 @@ void iwl_disable_ict(struct iwl_priv *priv); | |||
121 | int iwl_alloc_isr_ict(struct iwl_priv *priv); | 121 | int iwl_alloc_isr_ict(struct iwl_priv *priv); |
122 | void iwl_free_isr_ict(struct iwl_priv *priv); | 122 | void iwl_free_isr_ict(struct iwl_priv *priv); |
123 | irqreturn_t iwl_isr_ict(int irq, void *data); | 123 | irqreturn_t iwl_isr_ict(int irq, void *data); |
124 | bool iwl_good_ack_health(struct iwl_priv *priv, | ||
125 | struct iwl_rx_packet *pkt); | ||
126 | 124 | ||
127 | /* tx queue */ | 125 | /* tx queue */ |
128 | void iwlagn_set_wr_ptrs(struct iwl_priv *priv, | 126 | void iwlagn_set_wr_ptrs(struct iwl_priv *priv, |
@@ -248,8 +246,6 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); | |||
248 | /* rx */ | 246 | /* rx */ |
249 | void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | 247 | void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, |
250 | struct iwl_rx_mem_buffer *rxb); | 248 | struct iwl_rx_mem_buffer *rxb); |
251 | bool iwl_good_plcp_health(struct iwl_priv *priv, | ||
252 | struct iwl_rx_packet *pkt); | ||
253 | void iwl_rx_statistics(struct iwl_priv *priv, | 249 | void iwl_rx_statistics(struct iwl_priv *priv, |
254 | struct iwl_rx_mem_buffer *rxb); | 250 | struct iwl_rx_mem_buffer *rxb); |
255 | void iwl_reply_statistics(struct iwl_priv *priv, | 251 | void iwl_reply_statistics(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 1be7f2957411..193ca98a6231 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -210,12 +210,7 @@ struct iwl_lib_ops { | |||
210 | 210 | ||
211 | /* temperature */ | 211 | /* temperature */ |
212 | struct iwl_temp_ops temp_ops; | 212 | struct iwl_temp_ops temp_ops; |
213 | /* check for plcp health */ | 213 | |
214 | bool (*check_plcp_health)(struct iwl_priv *priv, | ||
215 | struct iwl_rx_packet *pkt); | ||
216 | /* check for ack health */ | ||
217 | bool (*check_ack_health)(struct iwl_priv *priv, | ||
218 | struct iwl_rx_packet *pkt); | ||
219 | int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control); | 214 | int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control); |
220 | void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); | 215 | void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); |
221 | 216 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index fd84d53db3ac..feee76181ac5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -227,8 +227,158 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, | |||
227 | priv->measurement_status |= MEASUREMENT_READY; | 227 | priv->measurement_status |= MEASUREMENT_READY; |
228 | } | 228 | } |
229 | 229 | ||
230 | void iwl_recover_from_statistics(struct iwl_priv *priv, | 230 | /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ |
231 | struct iwl_rx_packet *pkt) | 231 | #define ACK_CNT_RATIO (50) |
232 | #define BA_TIMEOUT_CNT (5) | ||
233 | #define BA_TIMEOUT_MAX (16) | ||
234 | |||
235 | /** | ||
236 | * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries. | ||
237 | * | ||
238 | * When the ACK count ratio is low and aggregated BA timeout retries exceeding | ||
239 | * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal | ||
240 | * operation state. | ||
241 | */ | ||
242 | static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) | ||
243 | { | ||
244 | int actual_delta, expected_delta, ba_timeout_delta; | ||
245 | struct statistics_tx *cur, *old; | ||
246 | |||
247 | if (priv->_agn.agg_tids_count) | ||
248 | return true; | ||
249 | |||
250 | if (iwl_bt_statistics(priv)) { | ||
251 | cur = &pkt->u.stats_bt.tx; | ||
252 | old = &priv->_agn.statistics_bt.tx; | ||
253 | } else { | ||
254 | cur = &pkt->u.stats.tx; | ||
255 | old = &priv->_agn.statistics.tx; | ||
256 | } | ||
257 | |||
258 | actual_delta = le32_to_cpu(cur->actual_ack_cnt) - | ||
259 | le32_to_cpu(old->actual_ack_cnt); | ||
260 | expected_delta = le32_to_cpu(cur->expected_ack_cnt) - | ||
261 | le32_to_cpu(old->expected_ack_cnt); | ||
262 | |||
263 | /* Values should not be negative, but we do not trust the firmware */ | ||
264 | if (actual_delta <= 0 || expected_delta <= 0) | ||
265 | return true; | ||
266 | |||
267 | ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) - | ||
268 | le32_to_cpu(old->agg.ba_timeout); | ||
269 | |||
270 | if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO && | ||
271 | ba_timeout_delta > BA_TIMEOUT_CNT) { | ||
272 | IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n", | ||
273 | actual_delta, expected_delta, ba_timeout_delta); | ||
274 | |||
275 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
276 | /* | ||
277 | * This is ifdef'ed on DEBUGFS because otherwise the | ||
278 | * statistics aren't available. If DEBUGFS is set but | ||
279 | * DEBUG is not, these will just compile out. | ||
280 | */ | ||
281 | IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n", | ||
282 | priv->_agn.delta_statistics.tx.rx_detected_cnt); | ||
283 | IWL_DEBUG_RADIO(priv, | ||
284 | "ack_or_ba_timeout_collision delta %d\n", | ||
285 | priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision); | ||
286 | #endif | ||
287 | |||
288 | if (ba_timeout_delta >= BA_TIMEOUT_MAX) | ||
289 | return false; | ||
290 | } | ||
291 | |||
292 | return true; | ||
293 | } | ||
294 | |||
295 | /** | ||
296 | * iwl_good_plcp_health - checks for plcp error. | ||
297 | * | ||
298 | * When the plcp error is exceeding the thresholds, reset the radio | ||
299 | * to improve the throughput. | ||
300 | */ | ||
301 | static bool iwl_good_plcp_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) | ||
302 | { | ||
303 | bool rc = true; | ||
304 | int combined_plcp_delta; | ||
305 | unsigned int plcp_msec; | ||
306 | unsigned long plcp_received_jiffies; | ||
307 | |||
308 | if (priv->cfg->base_params->plcp_delta_threshold == | ||
309 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { | ||
310 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); | ||
311 | return rc; | ||
312 | } | ||
313 | |||
314 | /* | ||
315 | * check for plcp_err and trigger radio reset if it exceeds | ||
316 | * the plcp error threshold plcp_delta. | ||
317 | */ | ||
318 | plcp_received_jiffies = jiffies; | ||
319 | plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - | ||
320 | (long) priv->plcp_jiffies); | ||
321 | priv->plcp_jiffies = plcp_received_jiffies; | ||
322 | /* | ||
323 | * check to make sure plcp_msec is not 0 to prevent division | ||
324 | * by zero. | ||
325 | */ | ||
326 | if (plcp_msec) { | ||
327 | struct statistics_rx_phy *ofdm; | ||
328 | struct statistics_rx_ht_phy *ofdm_ht; | ||
329 | |||
330 | if (iwl_bt_statistics(priv)) { | ||
331 | ofdm = &pkt->u.stats_bt.rx.ofdm; | ||
332 | ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; | ||
333 | combined_plcp_delta = | ||
334 | (le32_to_cpu(ofdm->plcp_err) - | ||
335 | le32_to_cpu(priv->_agn.statistics_bt. | ||
336 | rx.ofdm.plcp_err)) + | ||
337 | (le32_to_cpu(ofdm_ht->plcp_err) - | ||
338 | le32_to_cpu(priv->_agn.statistics_bt. | ||
339 | rx.ofdm_ht.plcp_err)); | ||
340 | } else { | ||
341 | ofdm = &pkt->u.stats.rx.ofdm; | ||
342 | ofdm_ht = &pkt->u.stats.rx.ofdm_ht; | ||
343 | combined_plcp_delta = | ||
344 | (le32_to_cpu(ofdm->plcp_err) - | ||
345 | le32_to_cpu(priv->_agn.statistics. | ||
346 | rx.ofdm.plcp_err)) + | ||
347 | (le32_to_cpu(ofdm_ht->plcp_err) - | ||
348 | le32_to_cpu(priv->_agn.statistics. | ||
349 | rx.ofdm_ht.plcp_err)); | ||
350 | } | ||
351 | |||
352 | if ((combined_plcp_delta > 0) && | ||
353 | ((combined_plcp_delta * 100) / plcp_msec) > | ||
354 | priv->cfg->base_params->plcp_delta_threshold) { | ||
355 | /* | ||
356 | * if plcp_err exceed the threshold, | ||
357 | * the following data is printed in csv format: | ||
358 | * Text: plcp_err exceeded %d, | ||
359 | * Received ofdm.plcp_err, | ||
360 | * Current ofdm.plcp_err, | ||
361 | * Received ofdm_ht.plcp_err, | ||
362 | * Current ofdm_ht.plcp_err, | ||
363 | * combined_plcp_delta, | ||
364 | * plcp_msec | ||
365 | */ | ||
366 | IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " | ||
367 | "%u, %u, %u, %u, %d, %u mSecs\n", | ||
368 | priv->cfg->base_params->plcp_delta_threshold, | ||
369 | le32_to_cpu(ofdm->plcp_err), | ||
370 | le32_to_cpu(ofdm->plcp_err), | ||
371 | le32_to_cpu(ofdm_ht->plcp_err), | ||
372 | le32_to_cpu(ofdm_ht->plcp_err), | ||
373 | combined_plcp_delta, plcp_msec); | ||
374 | |||
375 | rc = false; | ||
376 | } | ||
377 | } | ||
378 | return rc; | ||
379 | } | ||
380 | |||
381 | void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) | ||
232 | { | 382 | { |
233 | const struct iwl_mod_params *mod_params = priv->cfg->mod_params; | 383 | const struct iwl_mod_params *mod_params = priv->cfg->mod_params; |
234 | 384 | ||
@@ -236,17 +386,13 @@ void iwl_recover_from_statistics(struct iwl_priv *priv, | |||
236 | !iwl_is_any_associated(priv)) | 386 | !iwl_is_any_associated(priv)) |
237 | return; | 387 | return; |
238 | 388 | ||
239 | if (mod_params->ack_check && | 389 | if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) { |
240 | priv->cfg->ops->lib->check_ack_health && | ||
241 | !priv->cfg->ops->lib->check_ack_health(priv, pkt)) { | ||
242 | IWL_ERR(priv, "low ack count detected, restart firmware\n"); | 390 | IWL_ERR(priv, "low ack count detected, restart firmware\n"); |
243 | if (!iwl_force_reset(priv, IWL_FW_RESET, false)) | 391 | if (!iwl_force_reset(priv, IWL_FW_RESET, false)) |
244 | return; | 392 | return; |
245 | } | 393 | } |
246 | 394 | ||
247 | if (mod_params->plcp_check && | 395 | if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt)) |
248 | priv->cfg->ops->lib->check_plcp_health && | ||
249 | !priv->cfg->ops->lib->check_plcp_health(priv, pkt)) | ||
250 | iwl_force_reset(priv, IWL_RF_RESET, false); | 396 | iwl_force_reset(priv, IWL_RF_RESET, false); |
251 | } | 397 | } |
252 | 398 | ||