aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2011-02-28 08:33:16 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-02-28 14:11:27 -0500
commitad6e82a5348e494c0023d77fa55933f23b55711c (patch)
tree277df5b7f7f3087c2d25cbc490c4c9933b0684f6
parentb7977ffaab5187ad75edaf04ac854615cea93828 (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.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c87
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c66
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c162
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 */
178bool 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
259void iwl_rx_statistics(struct iwl_priv *priv, 172void 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 */
1428bool 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);
121int iwl_alloc_isr_ict(struct iwl_priv *priv); 121int iwl_alloc_isr_ict(struct iwl_priv *priv);
122void iwl_free_isr_ict(struct iwl_priv *priv); 122void iwl_free_isr_ict(struct iwl_priv *priv);
123irqreturn_t iwl_isr_ict(int irq, void *data); 123irqreturn_t iwl_isr_ict(int irq, void *data);
124bool iwl_good_ack_health(struct iwl_priv *priv,
125 struct iwl_rx_packet *pkt);
126 124
127/* tx queue */ 125/* tx queue */
128void iwlagn_set_wr_ptrs(struct iwl_priv *priv, 126void 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 */
249void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 247void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
250 struct iwl_rx_mem_buffer *rxb); 248 struct iwl_rx_mem_buffer *rxb);
251bool iwl_good_plcp_health(struct iwl_priv *priv,
252 struct iwl_rx_packet *pkt);
253void iwl_rx_statistics(struct iwl_priv *priv, 249void iwl_rx_statistics(struct iwl_priv *priv,
254 struct iwl_rx_mem_buffer *rxb); 250 struct iwl_rx_mem_buffer *rxb);
255void iwl_reply_statistics(struct iwl_priv *priv, 251void 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
230void 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 */
242static 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 */
301static 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
381void 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