aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/debug.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c297
1 files changed, 233 insertions, 64 deletions
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 081e0085ed4c..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
81static 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
93static 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
115static 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
123static 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
135static 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
157static 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
81static ssize_t read_file_dma(struct file *file, char __user *user_buf, 165static 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{
@@ -157,10 +241,10 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
157 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", 241 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
158 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); 242 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
159 243
160 len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x \n", 244 len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x\n",
161 REG_READ_D(ah, AR_OBS_BUS_1)); 245 REG_READ_D(ah, AR_OBS_BUS_1));
162 len += snprintf(buf + len, DMA_BUF_LEN - len, 246 len += snprintf(buf + len, DMA_BUF_LEN - len,
163 "AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR)); 247 "AR_CR: 0x%x\n", REG_READ_D(ah, AR_CR));
164 248
165 ath9k_ps_restore(sc); 249 ath9k_ps_restore(sc);
166 250
@@ -180,8 +264,15 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
180{ 264{
181 if (status) 265 if (status)
182 sc->debug.stats.istats.total++; 266 sc->debug.stats.istats.total++;
183 if (status & ATH9K_INT_RX) 267 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
184 sc->debug.stats.istats.rxok++; 268 if (status & ATH9K_INT_RXLP)
269 sc->debug.stats.istats.rxlp++;
270 if (status & ATH9K_INT_RXHP)
271 sc->debug.stats.istats.rxhp++;
272 } else {
273 if (status & ATH9K_INT_RX)
274 sc->debug.stats.istats.rxok++;
275 }
185 if (status & ATH9K_INT_RXEOL) 276 if (status & ATH9K_INT_RXEOL)
186 sc->debug.stats.istats.rxeol++; 277 sc->debug.stats.istats.rxeol++;
187 if (status & ATH9K_INT_RXORN) 278 if (status & ATH9K_INT_RXORN)
@@ -223,8 +314,15 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
223 char buf[512]; 314 char buf[512];
224 unsigned int len = 0; 315 unsigned int len = 0;
225 316
226 len += snprintf(buf + len, sizeof(buf) - len, 317 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
227 "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok); 318 len += snprintf(buf + len, sizeof(buf) - len,
319 "%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp);
320 len += snprintf(buf + len, sizeof(buf) - len,
321 "%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp);
322 } else {
323 len += snprintf(buf + len, sizeof(buf) - len,
324 "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
325 }
228 len += snprintf(buf + len, sizeof(buf) - len, 326 len += snprintf(buf + len, sizeof(buf) - len,
229 "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol); 327 "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
230 len += snprintf(buf + len, sizeof(buf) - len, 328 len += snprintf(buf + len, sizeof(buf) - len,
@@ -557,10 +655,8 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
557} 655}
558 656
559void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 657void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
560 struct ath_buf *bf) 658 struct ath_buf *bf, struct ath_tx_status *ts)
561{ 659{
562 struct ath_desc *ds = bf->bf_desc;
563
564 if (bf_isampdu(bf)) { 660 if (bf_isampdu(bf)) {
565 if (bf_isxretried(bf)) 661 if (bf_isxretried(bf))
566 TX_STAT_INC(txq->axq_qnum, a_xretries); 662 TX_STAT_INC(txq->axq_qnum, a_xretries);
@@ -570,17 +666,17 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
570 TX_STAT_INC(txq->axq_qnum, completed); 666 TX_STAT_INC(txq->axq_qnum, completed);
571 } 667 }
572 668
573 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO) 669 if (ts->ts_status & ATH9K_TXERR_FIFO)
574 TX_STAT_INC(txq->axq_qnum, fifo_underrun); 670 TX_STAT_INC(txq->axq_qnum, fifo_underrun);
575 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XTXOP) 671 if (ts->ts_status & ATH9K_TXERR_XTXOP)
576 TX_STAT_INC(txq->axq_qnum, xtxop); 672 TX_STAT_INC(txq->axq_qnum, xtxop);
577 if (ds->ds_txstat.ts_status & ATH9K_TXERR_TIMER_EXPIRED) 673 if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED)
578 TX_STAT_INC(txq->axq_qnum, timer_exp); 674 TX_STAT_INC(txq->axq_qnum, timer_exp);
579 if (ds->ds_txstat.ts_flags & ATH9K_TX_DESC_CFG_ERR) 675 if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR)
580 TX_STAT_INC(txq->axq_qnum, desc_cfg_err); 676 TX_STAT_INC(txq->axq_qnum, desc_cfg_err);
581 if (ds->ds_txstat.ts_flags & ATH9K_TX_DATA_UNDERRUN) 677 if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN)
582 TX_STAT_INC(txq->axq_qnum, data_underrun); 678 TX_STAT_INC(txq->axq_qnum, data_underrun);
583 if (ds->ds_txstat.ts_flags & ATH9K_TX_DELIM_UNDERRUN) 679 if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
584 TX_STAT_INC(txq->axq_qnum, delim_underrun); 680 TX_STAT_INC(txq->axq_qnum, delim_underrun);
585} 681}
586 682
@@ -663,30 +759,29 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
663#undef PHY_ERR 759#undef PHY_ERR
664} 760}
665 761
666void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf) 762void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
667{ 763{
668#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++ 764#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++
669#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ 765#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
670 766
671 struct ath_desc *ds = bf->bf_desc;
672 u32 phyerr; 767 u32 phyerr;
673 768
674 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) 769 if (rs->rs_status & ATH9K_RXERR_CRC)
675 RX_STAT_INC(crc_err); 770 RX_STAT_INC(crc_err);
676 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) 771 if (rs->rs_status & ATH9K_RXERR_DECRYPT)
677 RX_STAT_INC(decrypt_crc_err); 772 RX_STAT_INC(decrypt_crc_err);
678 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) 773 if (rs->rs_status & ATH9K_RXERR_MIC)
679 RX_STAT_INC(mic_err); 774 RX_STAT_INC(mic_err);
680 if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_PRE) 775 if (rs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
681 RX_STAT_INC(pre_delim_crc_err); 776 RX_STAT_INC(pre_delim_crc_err);
682 if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_POST) 777 if (rs->rs_status & ATH9K_RX_DELIM_CRC_POST)
683 RX_STAT_INC(post_delim_crc_err); 778 RX_STAT_INC(post_delim_crc_err);
684 if (ds->ds_rxstat.rs_status & ATH9K_RX_DECRYPT_BUSY) 779 if (rs->rs_status & ATH9K_RX_DECRYPT_BUSY)
685 RX_STAT_INC(decrypt_busy_err); 780 RX_STAT_INC(decrypt_busy_err);
686 781
687 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) { 782 if (rs->rs_status & ATH9K_RXERR_PHY) {
688 RX_STAT_INC(phy_err); 783 RX_STAT_INC(phy_err);
689 phyerr = ds->ds_rxstat.rs_phyerr & 0x24; 784 phyerr = rs->rs_phyerr & 0x24;
690 RX_PHY_ERR_INC(phyerr); 785 RX_PHY_ERR_INC(phyerr);
691 } 786 }
692 787
@@ -700,6 +795,86 @@ static const struct file_operations fops_recv = {
700 .owner = THIS_MODULE 795 .owner = THIS_MODULE
701}; 796};
702 797
798static 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
809static 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, &regidx))
823 return -EINVAL;
824
825 sc->debug.regidx = regidx;
826 return count;
827}
828
829static 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
836static 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
850static 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, &regval))
865 return -EINVAL;
866
867 REG_WRITE_D(ah, sc->debug.regidx, regval);
868 return count;
869}
870
871static 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
703int ath9k_init_debug(struct ath_hw *ah) 878int ath9k_init_debug(struct ath_hw *ah)
704{ 879{
705 struct ath_common *common = ath9k_hw_common(ah); 880 struct ath_common *common = ath9k_hw_common(ah);
@@ -711,54 +886,55 @@ int ath9k_init_debug(struct ath_hw *ah)
711 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),
712 ath9k_debugfs_root); 887 ath9k_debugfs_root);
713 if (!sc->debug.debugfs_phy) 888 if (!sc->debug.debugfs_phy)
714 goto err; 889 return -ENOMEM;
715 890
716#ifdef CONFIG_ATH_DEBUG 891#ifdef CONFIG_ATH_DEBUG
717 sc->debug.debugfs_debug = debugfs_create_file("debug", 892 if (!debugfs_create_file("debug", S_IRUSR | S_IWUSR,
718 S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug); 893 sc->debug.debugfs_phy, sc, &fops_debug))
719 if (!sc->debug.debugfs_debug)
720 goto err; 894 goto err;
721#endif 895#endif
722 896
723 sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR, 897 if (!debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy,
724 sc->debug.debugfs_phy, sc, &fops_dma); 898 sc, &fops_dma))
725 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))
726 goto err; 915 goto err;
727 916
728 sc->debug.debugfs_interrupt = debugfs_create_file("interrupt", 917 if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy,
729 S_IRUSR, 918 sc, &fops_recv))
730 sc->debug.debugfs_phy,
731 sc, &fops_interrupt);
732 if (!sc->debug.debugfs_interrupt)
733 goto err; 919 goto err;
734 920
735 sc->debug.debugfs_rcstat = debugfs_create_file("rcstat", 921 if (!debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR,
736 S_IRUSR, 922 sc->debug.debugfs_phy, sc, &fops_rx_chainmask))
737 sc->debug.debugfs_phy,
738 sc, &fops_rcstat);
739 if (!sc->debug.debugfs_rcstat)
740 goto err; 923 goto err;
741 924
742 sc->debug.debugfs_wiphy = debugfs_create_file( 925 if (!debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
743 "wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, 926 sc->debug.debugfs_phy, sc, &fops_tx_chainmask))
744 &fops_wiphy);
745 if (!sc->debug.debugfs_wiphy)
746 goto err; 927 goto err;
747 928
748 sc->debug.debugfs_xmit = debugfs_create_file("xmit", 929 if (!debugfs_create_file("regidx", S_IRUSR | S_IWUSR,
749 S_IRUSR, 930 sc->debug.debugfs_phy, sc, &fops_regidx))
750 sc->debug.debugfs_phy,
751 sc, &fops_xmit);
752 if (!sc->debug.debugfs_xmit)
753 goto err; 931 goto err;
754 932
755 sc->debug.debugfs_recv = debugfs_create_file("recv", 933 if (!debugfs_create_file("regval", S_IRUSR | S_IWUSR,
756 S_IRUSR, 934 sc->debug.debugfs_phy, sc, &fops_regval))
757 sc->debug.debugfs_phy,
758 sc, &fops_recv);
759 if (!sc->debug.debugfs_recv)
760 goto err; 935 goto err;
761 936
937 sc->debug.regidx = 0;
762 return 0; 938 return 0;
763err: 939err:
764 ath9k_exit_debug(ah); 940 ath9k_exit_debug(ah);
@@ -770,14 +946,7 @@ void ath9k_exit_debug(struct ath_hw *ah)
770 struct ath_common *common = ath9k_hw_common(ah); 946 struct ath_common *common = ath9k_hw_common(ah);
771 struct ath_softc *sc = (struct ath_softc *) common->priv; 947 struct ath_softc *sc = (struct ath_softc *) common->priv;
772 948
773 debugfs_remove(sc->debug.debugfs_recv); 949 debugfs_remove_recursive(sc->debug.debugfs_phy);
774 debugfs_remove(sc->debug.debugfs_xmit);
775 debugfs_remove(sc->debug.debugfs_wiphy);
776 debugfs_remove(sc->debug.debugfs_rcstat);
777 debugfs_remove(sc->debug.debugfs_interrupt);
778 debugfs_remove(sc->debug.debugfs_dma);
779 debugfs_remove(sc->debug.debugfs_debug);
780 debugfs_remove(sc->debug.debugfs_phy);
781} 950}
782 951
783int ath9k_debug_create_root(void) 952int ath9k_debug_create_root(void)