aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-debugfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-debugfs.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c193
1 files changed, 144 insertions, 49 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 64eb585f1578..11e08c068917 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -172,7 +172,6 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
172 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 172 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
173 const size_t bufsz = sizeof(buf); 173 const size_t bufsz = sizeof(buf);
174 174
175 iwl_grab_nic_access(priv);
176 for (i = priv->dbgfs->sram_len; i > 0; i -= 4) { 175 for (i = priv->dbgfs->sram_len; i > 0; i -= 4) {
177 val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \ 176 val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \
178 priv->dbgfs->sram_len - i); 177 priv->dbgfs->sram_len - i);
@@ -192,7 +191,6 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
192 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val); 191 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
193 } 192 }
194 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 193 pos += scnprintf(buf + pos, bufsz - pos, "\n");
195 iwl_release_nic_access(priv);
196 194
197 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 195 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
198 return ret; 196 return ret;
@@ -292,7 +290,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
292 return ret; 290 return ret;
293} 291}
294 292
295static ssize_t iwl_dbgfs_eeprom_read(struct file *file, 293static ssize_t iwl_dbgfs_nvm_read(struct file *file,
296 char __user *user_buf, 294 char __user *user_buf,
297 size_t count, 295 size_t count,
298 loff_t *ppos) 296 loff_t *ppos)
@@ -306,7 +304,7 @@ static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
306 buf_size = 4 * eeprom_len + 256; 304 buf_size = 4 * eeprom_len + 256;
307 305
308 if (eeprom_len % 16) { 306 if (eeprom_len % 16) {
309 IWL_ERR(priv, "EEPROM size is not multiple of 16.\n"); 307 IWL_ERR(priv, "NVM size is not multiple of 16.\n");
310 return -ENODATA; 308 return -ENODATA;
311 } 309 }
312 310
@@ -318,6 +316,13 @@ static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
318 } 316 }
319 317
320 ptr = priv->eeprom; 318 ptr = priv->eeprom;
319 if (!ptr) {
320 IWL_ERR(priv, "Invalid EEPROM/OTP memory\n");
321 return -ENOMEM;
322 }
323 pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s\n",
324 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
325 ? "OTP" : "EEPROM");
321 for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { 326 for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
322 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); 327 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
323 hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, 328 hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
@@ -375,51 +380,53 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
375 } 380 }
376 381
377 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ); 382 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ);
378 channels = supp_band->channels; 383 if (supp_band) {
379 384 channels = supp_band->channels;
380 pos += scnprintf(buf + pos, bufsz - pos,
381 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
382 supp_band->n_channels);
383 385
384 for (i = 0; i < supp_band->n_channels; i++)
385 pos += scnprintf(buf + pos, bufsz - pos, 386 pos += scnprintf(buf + pos, bufsz - pos,
386 "%d: %ddBm: BSS%s%s, %s.\n", 387 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
387 ieee80211_frequency_to_channel( 388 supp_band->n_channels);
388 channels[i].center_freq),
389 channels[i].max_power,
390 channels[i].flags & IEEE80211_CHAN_RADAR ?
391 " (IEEE 802.11h required)" : "",
392 (!(channels[i].flags & IEEE80211_CHAN_NO_IBSS)
393 || (channels[i].flags &
394 IEEE80211_CHAN_RADAR)) ? "" :
395 ", IBSS",
396 channels[i].flags &
397 IEEE80211_CHAN_PASSIVE_SCAN ?
398 "passive only" : "active/passive");
399 389
390 for (i = 0; i < supp_band->n_channels; i++)
391 pos += scnprintf(buf + pos, bufsz - pos,
392 "%d: %ddBm: BSS%s%s, %s.\n",
393 ieee80211_frequency_to_channel(
394 channels[i].center_freq),
395 channels[i].max_power,
396 channels[i].flags & IEEE80211_CHAN_RADAR ?
397 " (IEEE 802.11h required)" : "",
398 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
399 || (channels[i].flags &
400 IEEE80211_CHAN_RADAR)) ? "" :
401 ", IBSS",
402 channels[i].flags &
403 IEEE80211_CHAN_PASSIVE_SCAN ?
404 "passive only" : "active/passive");
405 }
400 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); 406 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
401 channels = supp_band->channels; 407 if (supp_band) {
402 408 channels = supp_band->channels;
403 pos += scnprintf(buf + pos, bufsz - pos,
404 "Displaying %d channels in 5.2GHz band (802.11a)\n",
405 supp_band->n_channels);
406 409
407 for (i = 0; i < supp_band->n_channels; i++)
408 pos += scnprintf(buf + pos, bufsz - pos, 410 pos += scnprintf(buf + pos, bufsz - pos,
409 "%d: %ddBm: BSS%s%s, %s.\n", 411 "Displaying %d channels in 5.2GHz band (802.11a)\n",
410 ieee80211_frequency_to_channel( 412 supp_band->n_channels);
411 channels[i].center_freq),
412 channels[i].max_power,
413 channels[i].flags & IEEE80211_CHAN_RADAR ?
414 " (IEEE 802.11h required)" : "",
415 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
416 || (channels[i].flags &
417 IEEE80211_CHAN_RADAR)) ? "" :
418 ", IBSS",
419 channels[i].flags &
420 IEEE80211_CHAN_PASSIVE_SCAN ?
421 "passive only" : "active/passive");
422 413
414 for (i = 0; i < supp_band->n_channels; i++)
415 pos += scnprintf(buf + pos, bufsz - pos,
416 "%d: %ddBm: BSS%s%s, %s.\n",
417 ieee80211_frequency_to_channel(
418 channels[i].center_freq),
419 channels[i].max_power,
420 channels[i].flags & IEEE80211_CHAN_RADAR ?
421 " (IEEE 802.11h required)" : "",
422 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
423 || (channels[i].flags &
424 IEEE80211_CHAN_RADAR)) ? "" :
425 ", IBSS",
426 channels[i].flags &
427 IEEE80211_CHAN_PASSIVE_SCAN ?
428 "passive only" : "active/passive");
429 }
423 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 430 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
424 kfree(buf); 431 kfree(buf);
425 return ret; 432 return ret;
@@ -442,8 +449,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
442 test_bit(STATUS_INT_ENABLED, &priv->status)); 449 test_bit(STATUS_INT_ENABLED, &priv->status));
443 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", 450 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
444 test_bit(STATUS_RF_KILL_HW, &priv->status)); 451 test_bit(STATUS_RF_KILL_HW, &priv->status));
445 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_SW:\t %d\n",
446 test_bit(STATUS_RF_KILL_SW, &priv->status));
447 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", 452 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
448 test_bit(STATUS_INIT, &priv->status)); 453 test_bit(STATUS_INIT, &priv->status));
449 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", 454 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
@@ -456,8 +461,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
456 test_bit(STATUS_GEO_CONFIGURED, &priv->status)); 461 test_bit(STATUS_GEO_CONFIGURED, &priv->status));
457 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", 462 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
458 test_bit(STATUS_EXIT_PENDING, &priv->status)); 463 test_bit(STATUS_EXIT_PENDING, &priv->status));
459 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_IN_SUSPEND:\t %d\n",
460 test_bit(STATUS_IN_SUSPEND, &priv->status));
461 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", 464 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
462 test_bit(STATUS_STATISTICS, &priv->status)); 465 test_bit(STATUS_STATISTICS, &priv->status));
463 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", 466 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
@@ -475,14 +478,104 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
475 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 478 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
476} 479}
477 480
481static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
482 char __user *user_buf,
483 size_t count, loff_t *ppos) {
484
485 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
486 int pos = 0;
487 int cnt = 0;
488 char *buf;
489 int bufsz = 24 * 64; /* 24 items * 64 char per item */
490 ssize_t ret;
491
492 buf = kzalloc(bufsz, GFP_KERNEL);
493 if (!buf) {
494 IWL_ERR(priv, "Can not allocate Buffer\n");
495 return -ENOMEM;
496 }
497
498 pos += scnprintf(buf + pos, bufsz - pos,
499 "Interrupt Statistics Report:\n");
500
501 pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
502 priv->isr_stats.hw);
503 pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
504 priv->isr_stats.sw);
505 if (priv->isr_stats.sw > 0) {
506 pos += scnprintf(buf + pos, bufsz - pos,
507 "\tLast Restarting Code: 0x%X\n",
508 priv->isr_stats.sw_err);
509 }
510#ifdef CONFIG_IWLWIFI_DEBUG
511 pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
512 priv->isr_stats.sch);
513 pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
514 priv->isr_stats.alive);
515#endif
516 pos += scnprintf(buf + pos, bufsz - pos,
517 "HW RF KILL switch toggled:\t %u\n",
518 priv->isr_stats.rfkill);
519
520 pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
521 priv->isr_stats.ctkill);
522
523 pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
524 priv->isr_stats.wakeup);
525
526 pos += scnprintf(buf + pos, bufsz - pos,
527 "Rx command responses:\t\t %u\n",
528 priv->isr_stats.rx);
529 for (cnt = 0; cnt < REPLY_MAX; cnt++) {
530 if (priv->isr_stats.rx_handlers[cnt] > 0)
531 pos += scnprintf(buf + pos, bufsz - pos,
532 "\tRx handler[%36s]:\t\t %u\n",
533 get_cmd_string(cnt),
534 priv->isr_stats.rx_handlers[cnt]);
535 }
536
537 pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
538 priv->isr_stats.tx);
539
540 pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
541 priv->isr_stats.unhandled);
542
543 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
544 kfree(buf);
545 return ret;
546}
547
548static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
549 const char __user *user_buf,
550 size_t count, loff_t *ppos)
551{
552 struct iwl_priv *priv = file->private_data;
553 char buf[8];
554 int buf_size;
555 u32 reset_flag;
556
557 memset(buf, 0, sizeof(buf));
558 buf_size = min(count, sizeof(buf) - 1);
559 if (copy_from_user(buf, user_buf, buf_size))
560 return -EFAULT;
561 if (sscanf(buf, "%x", &reset_flag) != 1)
562 return -EFAULT;
563 if (reset_flag == 0)
564 iwl_clear_isr_stats(priv);
565
566 return count;
567}
568
569
478DEBUGFS_READ_WRITE_FILE_OPS(sram); 570DEBUGFS_READ_WRITE_FILE_OPS(sram);
479DEBUGFS_WRITE_FILE_OPS(log_event); 571DEBUGFS_WRITE_FILE_OPS(log_event);
480DEBUGFS_READ_FILE_OPS(eeprom); 572DEBUGFS_READ_FILE_OPS(nvm);
481DEBUGFS_READ_FILE_OPS(stations); 573DEBUGFS_READ_FILE_OPS(stations);
482DEBUGFS_READ_FILE_OPS(rx_statistics); 574DEBUGFS_READ_FILE_OPS(rx_statistics);
483DEBUGFS_READ_FILE_OPS(tx_statistics); 575DEBUGFS_READ_FILE_OPS(tx_statistics);
484DEBUGFS_READ_FILE_OPS(channels); 576DEBUGFS_READ_FILE_OPS(channels);
485DEBUGFS_READ_FILE_OPS(status); 577DEBUGFS_READ_FILE_OPS(status);
578DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
486 579
487/* 580/*
488 * Create the debugfs files and directories 581 * Create the debugfs files and directories
@@ -510,7 +603,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
510 603
511 DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); 604 DEBUGFS_ADD_DIR(data, dbgfs->dir_drv);
512 DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv); 605 DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv);
513 DEBUGFS_ADD_FILE(eeprom, data); 606 DEBUGFS_ADD_FILE(nvm, data);
514 DEBUGFS_ADD_FILE(sram, data); 607 DEBUGFS_ADD_FILE(sram, data);
515 DEBUGFS_ADD_FILE(log_event, data); 608 DEBUGFS_ADD_FILE(log_event, data);
516 DEBUGFS_ADD_FILE(stations, data); 609 DEBUGFS_ADD_FILE(stations, data);
@@ -518,6 +611,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
518 DEBUGFS_ADD_FILE(tx_statistics, data); 611 DEBUGFS_ADD_FILE(tx_statistics, data);
519 DEBUGFS_ADD_FILE(channels, data); 612 DEBUGFS_ADD_FILE(channels, data);
520 DEBUGFS_ADD_FILE(status, data); 613 DEBUGFS_ADD_FILE(status, data);
614 DEBUGFS_ADD_FILE(interrupt, data);
521 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 615 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
522 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 616 DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
523 &priv->disable_chain_noise_cal); 617 &priv->disable_chain_noise_cal);
@@ -540,7 +634,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
540 if (!priv->dbgfs) 634 if (!priv->dbgfs)
541 return; 635 return;
542 636
543 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom); 637 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm);
544 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics); 638 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics);
545 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics); 639 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics);
546 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); 640 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
@@ -548,6 +642,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
548 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); 642 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
549 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels); 643 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
550 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status); 644 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
645 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
551 DEBUGFS_REMOVE(priv->dbgfs->dir_data); 646 DEBUGFS_REMOVE(priv->dbgfs->dir_data);
552 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); 647 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
553 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); 648 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);