diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/debug.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 236 |
1 files changed, 197 insertions, 39 deletions
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 64e30cd45d05..29898f8d1893 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -78,6 +78,90 @@ static const struct file_operations fops_debug = { | |||
78 | 78 | ||
79 | #define DMA_BUF_LEN 1024 | 79 | #define DMA_BUF_LEN 1024 |
80 | 80 | ||
81 | static ssize_t read_file_tx_chainmask(struct file *file, char __user *user_buf, | ||
82 | size_t count, loff_t *ppos) | ||
83 | { | ||
84 | struct ath_softc *sc = file->private_data; | ||
85 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
86 | char buf[32]; | ||
87 | unsigned int len; | ||
88 | |||
89 | len = snprintf(buf, sizeof(buf), "0x%08x\n", common->tx_chainmask); | ||
90 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
91 | } | ||
92 | |||
93 | static ssize_t write_file_tx_chainmask(struct file *file, const char __user *user_buf, | ||
94 | size_t count, loff_t *ppos) | ||
95 | { | ||
96 | struct ath_softc *sc = file->private_data; | ||
97 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
98 | unsigned long mask; | ||
99 | char buf[32]; | ||
100 | ssize_t len; | ||
101 | |||
102 | len = min(count, sizeof(buf) - 1); | ||
103 | if (copy_from_user(buf, user_buf, len)) | ||
104 | return -EINVAL; | ||
105 | |||
106 | buf[len] = '\0'; | ||
107 | if (strict_strtoul(buf, 0, &mask)) | ||
108 | return -EINVAL; | ||
109 | |||
110 | common->tx_chainmask = mask; | ||
111 | sc->sc_ah->caps.tx_chainmask = mask; | ||
112 | return count; | ||
113 | } | ||
114 | |||
115 | static const struct file_operations fops_tx_chainmask = { | ||
116 | .read = read_file_tx_chainmask, | ||
117 | .write = write_file_tx_chainmask, | ||
118 | .open = ath9k_debugfs_open, | ||
119 | .owner = THIS_MODULE | ||
120 | }; | ||
121 | |||
122 | |||
123 | static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf, | ||
124 | size_t count, loff_t *ppos) | ||
125 | { | ||
126 | struct ath_softc *sc = file->private_data; | ||
127 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
128 | char buf[32]; | ||
129 | unsigned int len; | ||
130 | |||
131 | len = snprintf(buf, sizeof(buf), "0x%08x\n", common->rx_chainmask); | ||
132 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
133 | } | ||
134 | |||
135 | static ssize_t write_file_rx_chainmask(struct file *file, const char __user *user_buf, | ||
136 | size_t count, loff_t *ppos) | ||
137 | { | ||
138 | struct ath_softc *sc = file->private_data; | ||
139 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
140 | unsigned long mask; | ||
141 | char buf[32]; | ||
142 | ssize_t len; | ||
143 | |||
144 | len = min(count, sizeof(buf) - 1); | ||
145 | if (copy_from_user(buf, user_buf, len)) | ||
146 | return -EINVAL; | ||
147 | |||
148 | buf[len] = '\0'; | ||
149 | if (strict_strtoul(buf, 0, &mask)) | ||
150 | return -EINVAL; | ||
151 | |||
152 | common->rx_chainmask = mask; | ||
153 | sc->sc_ah->caps.rx_chainmask = mask; | ||
154 | return count; | ||
155 | } | ||
156 | |||
157 | static const struct file_operations fops_rx_chainmask = { | ||
158 | .read = read_file_rx_chainmask, | ||
159 | .write = write_file_rx_chainmask, | ||
160 | .open = ath9k_debugfs_open, | ||
161 | .owner = THIS_MODULE | ||
162 | }; | ||
163 | |||
164 | |||
81 | static ssize_t read_file_dma(struct file *file, char __user *user_buf, | 165 | static ssize_t read_file_dma(struct file *file, char __user *user_buf, |
82 | size_t count, loff_t *ppos) | 166 | size_t count, loff_t *ppos) |
83 | { | 167 | { |
@@ -711,6 +795,86 @@ static const struct file_operations fops_recv = { | |||
711 | .owner = THIS_MODULE | 795 | .owner = THIS_MODULE |
712 | }; | 796 | }; |
713 | 797 | ||
798 | static ssize_t read_file_regidx(struct file *file, char __user *user_buf, | ||
799 | size_t count, loff_t *ppos) | ||
800 | { | ||
801 | struct ath_softc *sc = file->private_data; | ||
802 | char buf[32]; | ||
803 | unsigned int len; | ||
804 | |||
805 | len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.regidx); | ||
806 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
807 | } | ||
808 | |||
809 | static ssize_t write_file_regidx(struct file *file, const char __user *user_buf, | ||
810 | size_t count, loff_t *ppos) | ||
811 | { | ||
812 | struct ath_softc *sc = file->private_data; | ||
813 | unsigned long regidx; | ||
814 | char buf[32]; | ||
815 | ssize_t len; | ||
816 | |||
817 | len = min(count, sizeof(buf) - 1); | ||
818 | if (copy_from_user(buf, user_buf, len)) | ||
819 | return -EINVAL; | ||
820 | |||
821 | buf[len] = '\0'; | ||
822 | if (strict_strtoul(buf, 0, ®idx)) | ||
823 | return -EINVAL; | ||
824 | |||
825 | sc->debug.regidx = regidx; | ||
826 | return count; | ||
827 | } | ||
828 | |||
829 | static const struct file_operations fops_regidx = { | ||
830 | .read = read_file_regidx, | ||
831 | .write = write_file_regidx, | ||
832 | .open = ath9k_debugfs_open, | ||
833 | .owner = THIS_MODULE | ||
834 | }; | ||
835 | |||
836 | static ssize_t read_file_regval(struct file *file, char __user *user_buf, | ||
837 | size_t count, loff_t *ppos) | ||
838 | { | ||
839 | struct ath_softc *sc = file->private_data; | ||
840 | struct ath_hw *ah = sc->sc_ah; | ||
841 | char buf[32]; | ||
842 | unsigned int len; | ||
843 | u32 regval; | ||
844 | |||
845 | regval = REG_READ_D(ah, sc->debug.regidx); | ||
846 | len = snprintf(buf, sizeof(buf), "0x%08x\n", regval); | ||
847 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
848 | } | ||
849 | |||
850 | static ssize_t write_file_regval(struct file *file, const char __user *user_buf, | ||
851 | size_t count, loff_t *ppos) | ||
852 | { | ||
853 | struct ath_softc *sc = file->private_data; | ||
854 | struct ath_hw *ah = sc->sc_ah; | ||
855 | unsigned long regval; | ||
856 | char buf[32]; | ||
857 | ssize_t len; | ||
858 | |||
859 | len = min(count, sizeof(buf) - 1); | ||
860 | if (copy_from_user(buf, user_buf, len)) | ||
861 | return -EINVAL; | ||
862 | |||
863 | buf[len] = '\0'; | ||
864 | if (strict_strtoul(buf, 0, ®val)) | ||
865 | return -EINVAL; | ||
866 | |||
867 | REG_WRITE_D(ah, sc->debug.regidx, regval); | ||
868 | return count; | ||
869 | } | ||
870 | |||
871 | static const struct file_operations fops_regval = { | ||
872 | .read = read_file_regval, | ||
873 | .write = write_file_regval, | ||
874 | .open = ath9k_debugfs_open, | ||
875 | .owner = THIS_MODULE | ||
876 | }; | ||
877 | |||
714 | int ath9k_init_debug(struct ath_hw *ah) | 878 | int ath9k_init_debug(struct ath_hw *ah) |
715 | { | 879 | { |
716 | struct ath_common *common = ath9k_hw_common(ah); | 880 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -722,54 +886,55 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
722 | sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy), | 886 | sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy), |
723 | ath9k_debugfs_root); | 887 | ath9k_debugfs_root); |
724 | if (!sc->debug.debugfs_phy) | 888 | if (!sc->debug.debugfs_phy) |
725 | goto err; | 889 | return -ENOMEM; |
726 | 890 | ||
727 | #ifdef CONFIG_ATH_DEBUG | 891 | #ifdef CONFIG_ATH_DEBUG |
728 | sc->debug.debugfs_debug = debugfs_create_file("debug", | 892 | if (!debugfs_create_file("debug", S_IRUSR | S_IWUSR, |
729 | S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug); | 893 | sc->debug.debugfs_phy, sc, &fops_debug)) |
730 | if (!sc->debug.debugfs_debug) | ||
731 | goto err; | 894 | goto err; |
732 | #endif | 895 | #endif |
733 | 896 | ||
734 | sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR, | 897 | if (!debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, |
735 | sc->debug.debugfs_phy, sc, &fops_dma); | 898 | sc, &fops_dma)) |
736 | if (!sc->debug.debugfs_dma) | 899 | goto err; |
900 | |||
901 | if (!debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, | ||
902 | sc, &fops_interrupt)) | ||
903 | goto err; | ||
904 | |||
905 | if (!debugfs_create_file("rcstat", S_IRUSR, sc->debug.debugfs_phy, | ||
906 | sc, &fops_rcstat)) | ||
907 | goto err; | ||
908 | |||
909 | if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, | ||
910 | sc->debug.debugfs_phy, sc, &fops_wiphy)) | ||
911 | goto err; | ||
912 | |||
913 | if (!debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, | ||
914 | sc, &fops_xmit)) | ||
737 | goto err; | 915 | goto err; |
738 | 916 | ||
739 | sc->debug.debugfs_interrupt = debugfs_create_file("interrupt", | 917 | if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, |
740 | S_IRUSR, | 918 | sc, &fops_recv)) |
741 | sc->debug.debugfs_phy, | ||
742 | sc, &fops_interrupt); | ||
743 | if (!sc->debug.debugfs_interrupt) | ||
744 | goto err; | 919 | goto err; |
745 | 920 | ||
746 | sc->debug.debugfs_rcstat = debugfs_create_file("rcstat", | 921 | if (!debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR, |
747 | S_IRUSR, | 922 | sc->debug.debugfs_phy, sc, &fops_rx_chainmask)) |
748 | sc->debug.debugfs_phy, | ||
749 | sc, &fops_rcstat); | ||
750 | if (!sc->debug.debugfs_rcstat) | ||
751 | goto err; | 923 | goto err; |
752 | 924 | ||
753 | sc->debug.debugfs_wiphy = debugfs_create_file( | 925 | if (!debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR, |
754 | "wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, | 926 | sc->debug.debugfs_phy, sc, &fops_tx_chainmask)) |
755 | &fops_wiphy); | ||
756 | if (!sc->debug.debugfs_wiphy) | ||
757 | goto err; | 927 | goto err; |
758 | 928 | ||
759 | sc->debug.debugfs_xmit = debugfs_create_file("xmit", | 929 | if (!debugfs_create_file("regidx", S_IRUSR | S_IWUSR, |
760 | S_IRUSR, | 930 | sc->debug.debugfs_phy, sc, &fops_regidx)) |
761 | sc->debug.debugfs_phy, | ||
762 | sc, &fops_xmit); | ||
763 | if (!sc->debug.debugfs_xmit) | ||
764 | goto err; | 931 | goto err; |
765 | 932 | ||
766 | sc->debug.debugfs_recv = debugfs_create_file("recv", | 933 | if (!debugfs_create_file("regval", S_IRUSR | S_IWUSR, |
767 | S_IRUSR, | 934 | sc->debug.debugfs_phy, sc, &fops_regval)) |
768 | sc->debug.debugfs_phy, | ||
769 | sc, &fops_recv); | ||
770 | if (!sc->debug.debugfs_recv) | ||
771 | goto err; | 935 | goto err; |
772 | 936 | ||
937 | sc->debug.regidx = 0; | ||
773 | return 0; | 938 | return 0; |
774 | err: | 939 | err: |
775 | ath9k_exit_debug(ah); | 940 | ath9k_exit_debug(ah); |
@@ -781,14 +946,7 @@ void ath9k_exit_debug(struct ath_hw *ah) | |||
781 | struct ath_common *common = ath9k_hw_common(ah); | 946 | struct ath_common *common = ath9k_hw_common(ah); |
782 | struct ath_softc *sc = (struct ath_softc *) common->priv; | 947 | struct ath_softc *sc = (struct ath_softc *) common->priv; |
783 | 948 | ||
784 | debugfs_remove(sc->debug.debugfs_recv); | 949 | debugfs_remove_recursive(sc->debug.debugfs_phy); |
785 | debugfs_remove(sc->debug.debugfs_xmit); | ||
786 | debugfs_remove(sc->debug.debugfs_wiphy); | ||
787 | debugfs_remove(sc->debug.debugfs_rcstat); | ||
788 | debugfs_remove(sc->debug.debugfs_interrupt); | ||
789 | debugfs_remove(sc->debug.debugfs_dma); | ||
790 | debugfs_remove(sc->debug.debugfs_debug); | ||
791 | debugfs_remove(sc->debug.debugfs_phy); | ||
792 | } | 950 | } |
793 | 951 | ||
794 | int ath9k_debug_create_root(void) | 952 | int ath9k_debug_create_root(void) |