diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2011-08-26 02:10:59 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-08-29 15:25:34 -0400 |
commit | 1f7b6172db86e9ab2b4cd794441bb2c40ab287fc (patch) | |
tree | 3e44d755f23dddfd49abe1106f70e661dd87c474 | |
parent | e4ef84d94b0dbb75b4da6628611341af5812360f (diff) |
iwlagn: move isr_statistics to transport layer
It is accessed by the transport layer only, hence the move.
The debugfs handlers that accessed it moved to the transport layer too.
The rx_handlers part of it stayed in the upper layer and a special debugfs
has been added for it
Also add missing includes to iwl-commands.h.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-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-commands.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debugfs.c | 54 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 23 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h | 19 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c | 27 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans.c | 88 |
9 files changed, 140 insertions, 83 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 0016c61b3000..86b974804ead 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -69,6 +69,9 @@ | |||
69 | #ifndef __iwl_commands_h__ | 69 | #ifndef __iwl_commands_h__ |
70 | #define __iwl_commands_h__ | 70 | #define __iwl_commands_h__ |
71 | 71 | ||
72 | #include <linux/etherdevice.h> | ||
73 | #include <linux/ieee80211.h> | ||
74 | |||
72 | struct iwl_priv; | 75 | struct iwl_priv; |
73 | 76 | ||
74 | /* uCode version contains 4 values: Major/Minor/API/Serial */ | 77 | /* uCode version contains 4 values: Major/Minor/API/Serial */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 88fc39619214..347cbec935b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1121,11 +1121,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) | |||
1121 | &statistics_cmd); | 1121 | &statistics_cmd); |
1122 | } | 1122 | } |
1123 | 1123 | ||
1124 | void iwl_clear_isr_stats(struct iwl_priv *priv) | ||
1125 | { | ||
1126 | memset(&priv->isr_stats, 0, sizeof(priv->isr_stats)); | ||
1127 | } | ||
1128 | |||
1129 | int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, | 1124 | int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, |
1130 | const struct ieee80211_tx_queue_params *params) | 1125 | const struct ieee80211_tx_queue_params *params) |
1131 | { | 1126 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index aa6211837b48..110ffaea0949 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -387,8 +387,6 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, | |||
387 | } | 387 | } |
388 | #endif | 388 | #endif |
389 | 389 | ||
390 | void iwl_clear_isr_stats(struct iwl_priv *priv); | ||
391 | |||
392 | /***************************************************** | 390 | /***************************************************** |
393 | * GEOS | 391 | * GEOS |
394 | ******************************************************/ | 392 | ******************************************************/ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index fa070de2840c..787dae5fec99 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -556,11 +556,12 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, | |||
556 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 556 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
557 | } | 557 | } |
558 | 558 | ||
559 | static ssize_t iwl_dbgfs_interrupt_read(struct file *file, | 559 | static ssize_t iwl_dbgfs_rx_handlers_read(struct file *file, |
560 | char __user *user_buf, | 560 | char __user *user_buf, |
561 | size_t count, loff_t *ppos) { | 561 | size_t count, loff_t *ppos) { |
562 | 562 | ||
563 | struct iwl_priv *priv = file->private_data; | 563 | struct iwl_priv *priv = file->private_data; |
564 | |||
564 | int pos = 0; | 565 | int pos = 0; |
565 | int cnt = 0; | 566 | int cnt = 0; |
566 | char *buf; | 567 | char *buf; |
@@ -573,61 +574,25 @@ static ssize_t iwl_dbgfs_interrupt_read(struct file *file, | |||
573 | return -ENOMEM; | 574 | return -ENOMEM; |
574 | } | 575 | } |
575 | 576 | ||
576 | pos += scnprintf(buf + pos, bufsz - pos, | ||
577 | "Interrupt Statistics Report:\n"); | ||
578 | |||
579 | pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n", | ||
580 | priv->isr_stats.hw); | ||
581 | pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n", | ||
582 | priv->isr_stats.sw); | ||
583 | if (priv->isr_stats.sw || priv->isr_stats.hw) { | ||
584 | pos += scnprintf(buf + pos, bufsz - pos, | ||
585 | "\tLast Restarting Code: 0x%X\n", | ||
586 | priv->isr_stats.err_code); | ||
587 | } | ||
588 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
589 | pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n", | ||
590 | priv->isr_stats.sch); | ||
591 | pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n", | ||
592 | priv->isr_stats.alive); | ||
593 | #endif | ||
594 | pos += scnprintf(buf + pos, bufsz - pos, | ||
595 | "HW RF KILL switch toggled:\t %u\n", | ||
596 | priv->isr_stats.rfkill); | ||
597 | |||
598 | pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n", | ||
599 | priv->isr_stats.ctkill); | ||
600 | |||
601 | pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n", | ||
602 | priv->isr_stats.wakeup); | ||
603 | |||
604 | pos += scnprintf(buf + pos, bufsz - pos, | ||
605 | "Rx command responses:\t\t %u\n", | ||
606 | priv->isr_stats.rx); | ||
607 | for (cnt = 0; cnt < REPLY_MAX; cnt++) { | 577 | for (cnt = 0; cnt < REPLY_MAX; cnt++) { |
608 | if (priv->isr_stats.rx_handlers[cnt] > 0) | 578 | if (priv->rx_handlers_stats[cnt] > 0) |
609 | pos += scnprintf(buf + pos, bufsz - pos, | 579 | pos += scnprintf(buf + pos, bufsz - pos, |
610 | "\tRx handler[%36s]:\t\t %u\n", | 580 | "\tRx handler[%36s]:\t\t %u\n", |
611 | get_cmd_string(cnt), | 581 | get_cmd_string(cnt), |
612 | priv->isr_stats.rx_handlers[cnt]); | 582 | priv->rx_handlers_stats[cnt]); |
613 | } | 583 | } |
614 | 584 | ||
615 | pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n", | ||
616 | priv->isr_stats.tx); | ||
617 | |||
618 | pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n", | ||
619 | priv->isr_stats.unhandled); | ||
620 | |||
621 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 585 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
622 | kfree(buf); | 586 | kfree(buf); |
623 | return ret; | 587 | return ret; |
624 | } | 588 | } |
625 | 589 | ||
626 | static ssize_t iwl_dbgfs_interrupt_write(struct file *file, | 590 | static ssize_t iwl_dbgfs_rx_handlers_write(struct file *file, |
627 | const char __user *user_buf, | 591 | const char __user *user_buf, |
628 | size_t count, loff_t *ppos) | 592 | size_t count, loff_t *ppos) |
629 | { | 593 | { |
630 | struct iwl_priv *priv = file->private_data; | 594 | struct iwl_priv *priv = file->private_data; |
595 | |||
631 | char buf[8]; | 596 | char buf[8]; |
632 | int buf_size; | 597 | int buf_size; |
633 | u32 reset_flag; | 598 | u32 reset_flag; |
@@ -639,7 +604,8 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file, | |||
639 | if (sscanf(buf, "%x", &reset_flag) != 1) | 604 | if (sscanf(buf, "%x", &reset_flag) != 1) |
640 | return -EFAULT; | 605 | return -EFAULT; |
641 | if (reset_flag == 0) | 606 | if (reset_flag == 0) |
642 | iwl_clear_isr_stats(priv); | 607 | memset(&priv->rx_handlers_stats[0], 0, |
608 | sizeof(priv->rx_handlers_stats)); | ||
643 | 609 | ||
644 | return count; | 610 | return count; |
645 | } | 611 | } |
@@ -834,7 +800,7 @@ DEBUGFS_READ_FILE_OPS(nvm); | |||
834 | DEBUGFS_READ_FILE_OPS(stations); | 800 | DEBUGFS_READ_FILE_OPS(stations); |
835 | DEBUGFS_READ_FILE_OPS(channels); | 801 | DEBUGFS_READ_FILE_OPS(channels); |
836 | DEBUGFS_READ_FILE_OPS(status); | 802 | DEBUGFS_READ_FILE_OPS(status); |
837 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); | 803 | DEBUGFS_READ_WRITE_FILE_OPS(rx_handlers); |
838 | DEBUGFS_READ_FILE_OPS(qos); | 804 | DEBUGFS_READ_FILE_OPS(qos); |
839 | DEBUGFS_READ_FILE_OPS(thermal_throttling); | 805 | DEBUGFS_READ_FILE_OPS(thermal_throttling); |
840 | DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); | 806 | DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); |
@@ -2471,7 +2437,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
2471 | DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); | 2437 | DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); |
2472 | DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); | 2438 | DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); |
2473 | DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); | 2439 | DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); |
2474 | DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); | 2440 | DEBUGFS_ADD_FILE(rx_handlers, dir_data, S_IWUSR | S_IRUSR); |
2475 | DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); | 2441 | DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); |
2476 | DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR); | 2442 | DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR); |
2477 | DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); | 2443 | DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 40a01c0e4f30..f3852edaccf5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -810,22 +810,6 @@ enum iwl_pa_type { | |||
810 | IWL_PA_INTERNAL = 1, | 810 | IWL_PA_INTERNAL = 1, |
811 | }; | 811 | }; |
812 | 812 | ||
813 | /* interrupt statistics */ | ||
814 | struct isr_statistics { | ||
815 | u32 hw; | ||
816 | u32 sw; | ||
817 | u32 err_code; | ||
818 | u32 sch; | ||
819 | u32 alive; | ||
820 | u32 rfkill; | ||
821 | u32 ctkill; | ||
822 | u32 wakeup; | ||
823 | u32 rx; | ||
824 | u32 rx_handlers[REPLY_MAX]; | ||
825 | u32 tx; | ||
826 | u32 unhandled; | ||
827 | }; | ||
828 | |||
829 | /* reply_tx_statistics (for _agn devices) */ | 813 | /* reply_tx_statistics (for _agn devices) */ |
830 | struct reply_tx_error_statistics { | 814 | struct reply_tx_error_statistics { |
831 | u32 pp_delay; | 815 | u32 pp_delay; |
@@ -1155,6 +1139,9 @@ struct iwl_priv { | |||
1155 | /* jiffies when last recovery from statistics was performed */ | 1139 | /* jiffies when last recovery from statistics was performed */ |
1156 | unsigned long rx_statistics_jiffies; | 1140 | unsigned long rx_statistics_jiffies; |
1157 | 1141 | ||
1142 | /*counters */ | ||
1143 | u32 rx_handlers_stats[REPLY_MAX]; | ||
1144 | |||
1158 | /* force reset */ | 1145 | /* force reset */ |
1159 | struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; | 1146 | struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; |
1160 | 1147 | ||
@@ -1258,10 +1245,6 @@ struct iwl_priv { | |||
1258 | struct traffic_stats tx_stats; | 1245 | struct traffic_stats tx_stats; |
1259 | struct traffic_stats rx_stats; | 1246 | struct traffic_stats rx_stats; |
1260 | 1247 | ||
1261 | /* counts interrupts */ | ||
1262 | /* TODO: move to the transport layer */ | ||
1263 | struct isr_statistics isr_stats; | ||
1264 | |||
1265 | struct iwl_power_mgr power_data; | 1248 | struct iwl_power_mgr power_data; |
1266 | struct iwl_tt_mgmt thermal_throttle; | 1249 | struct iwl_tt_mgmt thermal_throttle; |
1267 | 1250 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index a5e4ddad2e04..d7c7c93b2daf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -1020,7 +1020,7 @@ void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
1020 | * handle those that need handling via function in | 1020 | * handle those that need handling via function in |
1021 | * rx_handlers table. See iwl_setup_rx_handlers() */ | 1021 | * rx_handlers table. See iwl_setup_rx_handlers() */ |
1022 | if (priv->rx_handlers[pkt->hdr.cmd]) { | 1022 | if (priv->rx_handlers[pkt->hdr.cmd]) { |
1023 | priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; | 1023 | priv->rx_handlers_stats[pkt->hdr.cmd]++; |
1024 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | 1024 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); |
1025 | } else { | 1025 | } else { |
1026 | /* No handling needed */ | 1026 | /* No handling needed */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h index 4694c462ed4e..f60b26f4dc7b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h | |||
@@ -33,6 +33,24 @@ | |||
33 | * trans_pcie layer */ | 33 | * trans_pcie layer */ |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * struct isr_statistics - interrupt statistics | ||
37 | * | ||
38 | */ | ||
39 | struct isr_statistics { | ||
40 | u32 hw; | ||
41 | u32 sw; | ||
42 | u32 err_code; | ||
43 | u32 sch; | ||
44 | u32 alive; | ||
45 | u32 rfkill; | ||
46 | u32 ctkill; | ||
47 | u32 wakeup; | ||
48 | u32 rx; | ||
49 | u32 tx; | ||
50 | u32 unhandled; | ||
51 | }; | ||
52 | |||
53 | /** | ||
36 | * struct iwl_rx_queue - Rx queue | 54 | * struct iwl_rx_queue - Rx queue |
37 | * @bd: driver's pointer to buffer of receive buffer descriptors (rbd) | 55 | * @bd: driver's pointer to buffer of receive buffer descriptors (rbd) |
38 | * @bd_dma: bus address of buffer of receive buffer descriptors (rbd) | 56 | * @bd_dma: bus address of buffer of receive buffer descriptors (rbd) |
@@ -88,6 +106,7 @@ struct iwl_trans_pcie { | |||
88 | u32 inta; | 106 | u32 inta; |
89 | bool use_ict; | 107 | bool use_ict; |
90 | struct tasklet_struct irq_tasklet; | 108 | struct tasklet_struct irq_tasklet; |
109 | struct isr_statistics isr_stats; | ||
91 | 110 | ||
92 | u32 inta_mask; | 111 | u32 inta_mask; |
93 | }; | 112 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c index aa7ced4324b8..b1635eee24b7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c | |||
@@ -569,6 +569,9 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
569 | { | 569 | { |
570 | u32 base; | 570 | u32 base; |
571 | struct iwl_error_event_table table; | 571 | struct iwl_error_event_table table; |
572 | struct iwl_trans *trans = trans(priv); | ||
573 | struct iwl_trans_pcie *trans_pcie = | ||
574 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
572 | 575 | ||
573 | base = priv->device_pointers.error_event_table; | 576 | base = priv->device_pointers.error_event_table; |
574 | if (priv->ucode_type == IWL_UCODE_INIT) { | 577 | if (priv->ucode_type == IWL_UCODE_INIT) { |
@@ -596,7 +599,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
596 | priv->shrd->status, table.valid); | 599 | priv->shrd->status, table.valid); |
597 | } | 600 | } |
598 | 601 | ||
599 | priv->isr_stats.err_code = table.error_id; | 602 | trans_pcie->isr_stats.err_code = table.error_id; |
600 | 603 | ||
601 | trace_iwlwifi_dev_ucode_error(priv, table.error_id, table.tsf_low, | 604 | trace_iwlwifi_dev_ucode_error(priv, table.error_id, table.tsf_low, |
602 | table.data1, table.data2, table.line, | 605 | table.data1, table.data2, table.line, |
@@ -905,6 +908,8 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
905 | 908 | ||
906 | struct iwl_trans_pcie *trans_pcie = | 909 | struct iwl_trans_pcie *trans_pcie = |
907 | IWL_TRANS_GET_PCIE_TRANS(trans); | 910 | IWL_TRANS_GET_PCIE_TRANS(trans); |
911 | struct isr_statistics *isr_stats = &trans_pcie->isr_stats; | ||
912 | |||
908 | 913 | ||
909 | spin_lock_irqsave(&trans->shrd->lock, flags); | 914 | spin_lock_irqsave(&trans->shrd->lock, flags); |
910 | 915 | ||
@@ -945,7 +950,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
945 | /* Tell the device to stop sending interrupts */ | 950 | /* Tell the device to stop sending interrupts */ |
946 | iwl_disable_interrupts(trans); | 951 | iwl_disable_interrupts(trans); |
947 | 952 | ||
948 | priv(trans)->isr_stats.hw++; | 953 | isr_stats->hw++; |
949 | iwl_irq_handle_error(priv(trans)); | 954 | iwl_irq_handle_error(priv(trans)); |
950 | 955 | ||
951 | handled |= CSR_INT_BIT_HW_ERR; | 956 | handled |= CSR_INT_BIT_HW_ERR; |
@@ -959,13 +964,13 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
959 | if (inta & CSR_INT_BIT_SCD) { | 964 | if (inta & CSR_INT_BIT_SCD) { |
960 | IWL_DEBUG_ISR(trans, "Scheduler finished to transmit " | 965 | IWL_DEBUG_ISR(trans, "Scheduler finished to transmit " |
961 | "the frame/frames.\n"); | 966 | "the frame/frames.\n"); |
962 | priv(trans)->isr_stats.sch++; | 967 | isr_stats->sch++; |
963 | } | 968 | } |
964 | 969 | ||
965 | /* Alive notification via Rx interrupt will do the real work */ | 970 | /* Alive notification via Rx interrupt will do the real work */ |
966 | if (inta & CSR_INT_BIT_ALIVE) { | 971 | if (inta & CSR_INT_BIT_ALIVE) { |
967 | IWL_DEBUG_ISR(trans, "Alive interrupt\n"); | 972 | IWL_DEBUG_ISR(trans, "Alive interrupt\n"); |
968 | priv(trans)->isr_stats.alive++; | 973 | isr_stats->alive++; |
969 | } | 974 | } |
970 | } | 975 | } |
971 | #endif | 976 | #endif |
@@ -982,7 +987,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
982 | IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", | 987 | IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", |
983 | hw_rf_kill ? "disable radio" : "enable radio"); | 988 | hw_rf_kill ? "disable radio" : "enable radio"); |
984 | 989 | ||
985 | priv(trans)->isr_stats.rfkill++; | 990 | isr_stats->rfkill++; |
986 | 991 | ||
987 | /* driver only loads ucode once setting the interface up. | 992 | /* driver only loads ucode once setting the interface up. |
988 | * the driver allows loading the ucode even if the radio | 993 | * the driver allows loading the ucode even if the radio |
@@ -1006,7 +1011,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1006 | /* Chip got too hot and stopped itself */ | 1011 | /* Chip got too hot and stopped itself */ |
1007 | if (inta & CSR_INT_BIT_CT_KILL) { | 1012 | if (inta & CSR_INT_BIT_CT_KILL) { |
1008 | IWL_ERR(trans, "Microcode CT kill error detected.\n"); | 1013 | IWL_ERR(trans, "Microcode CT kill error detected.\n"); |
1009 | priv(trans)->isr_stats.ctkill++; | 1014 | isr_stats->ctkill++; |
1010 | handled |= CSR_INT_BIT_CT_KILL; | 1015 | handled |= CSR_INT_BIT_CT_KILL; |
1011 | } | 1016 | } |
1012 | 1017 | ||
@@ -1014,7 +1019,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1014 | if (inta & CSR_INT_BIT_SW_ERR) { | 1019 | if (inta & CSR_INT_BIT_SW_ERR) { |
1015 | IWL_ERR(trans, "Microcode SW error detected. " | 1020 | IWL_ERR(trans, "Microcode SW error detected. " |
1016 | " Restarting 0x%X.\n", inta); | 1021 | " Restarting 0x%X.\n", inta); |
1017 | priv(trans)->isr_stats.sw++; | 1022 | isr_stats->sw++; |
1018 | iwl_irq_handle_error(priv(trans)); | 1023 | iwl_irq_handle_error(priv(trans)); |
1019 | handled |= CSR_INT_BIT_SW_ERR; | 1024 | handled |= CSR_INT_BIT_SW_ERR; |
1020 | } | 1025 | } |
@@ -1027,7 +1032,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1027 | iwl_txq_update_write_ptr(priv(trans), | 1032 | iwl_txq_update_write_ptr(priv(trans), |
1028 | &priv(trans)->txq[i]); | 1033 | &priv(trans)->txq[i]); |
1029 | 1034 | ||
1030 | priv(trans)->isr_stats.wakeup++; | 1035 | isr_stats->wakeup++; |
1031 | 1036 | ||
1032 | handled |= CSR_INT_BIT_WAKEUP; | 1037 | handled |= CSR_INT_BIT_WAKEUP; |
1033 | } | 1038 | } |
@@ -1075,14 +1080,14 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1075 | iwl_write8(priv(trans), CSR_INT_PERIODIC_REG, | 1080 | iwl_write8(priv(trans), CSR_INT_PERIODIC_REG, |
1076 | CSR_INT_PERIODIC_ENA); | 1081 | CSR_INT_PERIODIC_ENA); |
1077 | 1082 | ||
1078 | priv(trans)->isr_stats.rx++; | 1083 | isr_stats->rx++; |
1079 | } | 1084 | } |
1080 | 1085 | ||
1081 | /* This "Tx" DMA channel is used only for loading uCode */ | 1086 | /* This "Tx" DMA channel is used only for loading uCode */ |
1082 | if (inta & CSR_INT_BIT_FH_TX) { | 1087 | if (inta & CSR_INT_BIT_FH_TX) { |
1083 | iwl_write32(priv(trans), CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); | 1088 | iwl_write32(priv(trans), CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); |
1084 | IWL_DEBUG_ISR(trans, "uCode load interrupt\n"); | 1089 | IWL_DEBUG_ISR(trans, "uCode load interrupt\n"); |
1085 | priv(trans)->isr_stats.tx++; | 1090 | isr_stats->tx++; |
1086 | handled |= CSR_INT_BIT_FH_TX; | 1091 | handled |= CSR_INT_BIT_FH_TX; |
1087 | /* Wake up uCode load routine, now that load is complete */ | 1092 | /* Wake up uCode load routine, now that load is complete */ |
1088 | priv(trans)->ucode_write_complete = 1; | 1093 | priv(trans)->ucode_write_complete = 1; |
@@ -1091,7 +1096,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1091 | 1096 | ||
1092 | if (inta & ~handled) { | 1097 | if (inta & ~handled) { |
1093 | IWL_ERR(trans, "Unhandled INTA bits 0x%08x\n", inta & ~handled); | 1098 | IWL_ERR(trans, "Unhandled INTA bits 0x%08x\n", inta & ~handled); |
1094 | priv(trans)->isr_stats.unhandled++; | 1099 | isr_stats->unhandled++; |
1095 | } | 1100 | } |
1096 | 1101 | ||
1097 | if (inta & ~(trans_pcie->inta_mask)) { | 1102 | if (inta & ~(trans_pcie->inta_mask)) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 5926cac711b3..63a310135f76 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c | |||
@@ -1496,8 +1496,95 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, | |||
1496 | return count; | 1496 | return count; |
1497 | } | 1497 | } |
1498 | 1498 | ||
1499 | static ssize_t iwl_dbgfs_interrupt_read(struct file *file, | ||
1500 | char __user *user_buf, | ||
1501 | size_t count, loff_t *ppos) { | ||
1502 | |||
1503 | struct iwl_trans *trans = file->private_data; | ||
1504 | struct iwl_trans_pcie *trans_pcie = | ||
1505 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1506 | struct isr_statistics *isr_stats = &trans_pcie->isr_stats; | ||
1507 | |||
1508 | int pos = 0; | ||
1509 | char *buf; | ||
1510 | int bufsz = 24 * 64; /* 24 items * 64 char per item */ | ||
1511 | ssize_t ret; | ||
1512 | |||
1513 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
1514 | if (!buf) { | ||
1515 | IWL_ERR(trans, "Can not allocate Buffer\n"); | ||
1516 | return -ENOMEM; | ||
1517 | } | ||
1518 | |||
1519 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1520 | "Interrupt Statistics Report:\n"); | ||
1521 | |||
1522 | pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n", | ||
1523 | isr_stats->hw); | ||
1524 | pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n", | ||
1525 | isr_stats->sw); | ||
1526 | if (isr_stats->sw || isr_stats->hw) { | ||
1527 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1528 | "\tLast Restarting Code: 0x%X\n", | ||
1529 | isr_stats->err_code); | ||
1530 | } | ||
1531 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1532 | pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n", | ||
1533 | isr_stats->sch); | ||
1534 | pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n", | ||
1535 | isr_stats->alive); | ||
1536 | #endif | ||
1537 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1538 | "HW RF KILL switch toggled:\t %u\n", isr_stats->rfkill); | ||
1539 | |||
1540 | pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n", | ||
1541 | isr_stats->ctkill); | ||
1542 | |||
1543 | pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n", | ||
1544 | isr_stats->wakeup); | ||
1545 | |||
1546 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1547 | "Rx command responses:\t\t %u\n", isr_stats->rx); | ||
1548 | |||
1549 | pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n", | ||
1550 | isr_stats->tx); | ||
1551 | |||
1552 | pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n", | ||
1553 | isr_stats->unhandled); | ||
1554 | |||
1555 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
1556 | kfree(buf); | ||
1557 | return ret; | ||
1558 | } | ||
1559 | |||
1560 | static ssize_t iwl_dbgfs_interrupt_write(struct file *file, | ||
1561 | const char __user *user_buf, | ||
1562 | size_t count, loff_t *ppos) | ||
1563 | { | ||
1564 | struct iwl_trans *trans = file->private_data; | ||
1565 | struct iwl_trans_pcie *trans_pcie = | ||
1566 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1567 | struct isr_statistics *isr_stats = &trans_pcie->isr_stats; | ||
1568 | |||
1569 | char buf[8]; | ||
1570 | int buf_size; | ||
1571 | u32 reset_flag; | ||
1572 | |||
1573 | memset(buf, 0, sizeof(buf)); | ||
1574 | buf_size = min(count, sizeof(buf) - 1); | ||
1575 | if (copy_from_user(buf, user_buf, buf_size)) | ||
1576 | return -EFAULT; | ||
1577 | if (sscanf(buf, "%x", &reset_flag) != 1) | ||
1578 | return -EFAULT; | ||
1579 | if (reset_flag == 0) | ||
1580 | memset(isr_stats, 0, sizeof(*isr_stats)); | ||
1581 | |||
1582 | return count; | ||
1583 | } | ||
1584 | |||
1499 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); | 1585 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); |
1500 | DEBUGFS_READ_WRITE_FILE_OPS(log_event); | 1586 | DEBUGFS_READ_WRITE_FILE_OPS(log_event); |
1587 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); | ||
1501 | DEBUGFS_READ_FILE_OPS(rx_queue); | 1588 | DEBUGFS_READ_FILE_OPS(rx_queue); |
1502 | DEBUGFS_READ_FILE_OPS(tx_queue); | 1589 | DEBUGFS_READ_FILE_OPS(tx_queue); |
1503 | 1590 | ||
@@ -1512,6 +1599,7 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, | |||
1512 | DEBUGFS_ADD_FILE(rx_queue, dir, S_IRUSR); | 1599 | DEBUGFS_ADD_FILE(rx_queue, dir, S_IRUSR); |
1513 | DEBUGFS_ADD_FILE(tx_queue, dir, S_IRUSR); | 1600 | DEBUGFS_ADD_FILE(tx_queue, dir, S_IRUSR); |
1514 | DEBUGFS_ADD_FILE(log_event, dir, S_IWUSR | S_IRUSR); | 1601 | DEBUGFS_ADD_FILE(log_event, dir, S_IWUSR | S_IRUSR); |
1602 | DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR); | ||
1515 | return 0; | 1603 | return 0; |
1516 | } | 1604 | } |
1517 | #else | 1605 | #else |