diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/debug.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 494 |
1 files changed, 477 insertions, 17 deletions
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index d1eb89611ff7..2741203e803f 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
19 | #include <linux/export.h> | ||
19 | #include <asm/unaligned.h> | 20 | #include <asm/unaligned.h> |
20 | 21 | ||
21 | #include "ath9k.h" | 22 | #include "ath9k.h" |
@@ -95,11 +96,11 @@ static ssize_t read_file_tx_chainmask(struct file *file, char __user *user_buf, | |||
95 | size_t count, loff_t *ppos) | 96 | size_t count, loff_t *ppos) |
96 | { | 97 | { |
97 | struct ath_softc *sc = file->private_data; | 98 | struct ath_softc *sc = file->private_data; |
98 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 99 | struct ath_hw *ah = sc->sc_ah; |
99 | char buf[32]; | 100 | char buf[32]; |
100 | unsigned int len; | 101 | unsigned int len; |
101 | 102 | ||
102 | len = sprintf(buf, "0x%08x\n", common->tx_chainmask); | 103 | len = sprintf(buf, "0x%08x\n", ah->txchainmask); |
103 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | 104 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); |
104 | } | 105 | } |
105 | 106 | ||
@@ -107,7 +108,7 @@ static ssize_t write_file_tx_chainmask(struct file *file, const char __user *use | |||
107 | size_t count, loff_t *ppos) | 108 | size_t count, loff_t *ppos) |
108 | { | 109 | { |
109 | struct ath_softc *sc = file->private_data; | 110 | struct ath_softc *sc = file->private_data; |
110 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 111 | struct ath_hw *ah = sc->sc_ah; |
111 | unsigned long mask; | 112 | unsigned long mask; |
112 | char buf[32]; | 113 | char buf[32]; |
113 | ssize_t len; | 114 | ssize_t len; |
@@ -120,8 +121,8 @@ static ssize_t write_file_tx_chainmask(struct file *file, const char __user *use | |||
120 | if (strict_strtoul(buf, 0, &mask)) | 121 | if (strict_strtoul(buf, 0, &mask)) |
121 | return -EINVAL; | 122 | return -EINVAL; |
122 | 123 | ||
123 | common->tx_chainmask = mask; | 124 | ah->txchainmask = mask; |
124 | sc->sc_ah->caps.tx_chainmask = mask; | 125 | ah->caps.tx_chainmask = mask; |
125 | return count; | 126 | return count; |
126 | } | 127 | } |
127 | 128 | ||
@@ -138,11 +139,11 @@ static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf, | |||
138 | size_t count, loff_t *ppos) | 139 | size_t count, loff_t *ppos) |
139 | { | 140 | { |
140 | struct ath_softc *sc = file->private_data; | 141 | struct ath_softc *sc = file->private_data; |
141 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 142 | struct ath_hw *ah = sc->sc_ah; |
142 | char buf[32]; | 143 | char buf[32]; |
143 | unsigned int len; | 144 | unsigned int len; |
144 | 145 | ||
145 | len = sprintf(buf, "0x%08x\n", common->rx_chainmask); | 146 | len = sprintf(buf, "0x%08x\n", ah->rxchainmask); |
146 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | 147 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); |
147 | } | 148 | } |
148 | 149 | ||
@@ -150,7 +151,7 @@ static ssize_t write_file_rx_chainmask(struct file *file, const char __user *use | |||
150 | size_t count, loff_t *ppos) | 151 | size_t count, loff_t *ppos) |
151 | { | 152 | { |
152 | struct ath_softc *sc = file->private_data; | 153 | struct ath_softc *sc = file->private_data; |
153 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 154 | struct ath_hw *ah = sc->sc_ah; |
154 | unsigned long mask; | 155 | unsigned long mask; |
155 | char buf[32]; | 156 | char buf[32]; |
156 | ssize_t len; | 157 | ssize_t len; |
@@ -163,8 +164,8 @@ static ssize_t write_file_rx_chainmask(struct file *file, const char __user *use | |||
163 | if (strict_strtoul(buf, 0, &mask)) | 164 | if (strict_strtoul(buf, 0, &mask)) |
164 | return -EINVAL; | 165 | return -EINVAL; |
165 | 166 | ||
166 | common->rx_chainmask = mask; | 167 | ah->rxchainmask = mask; |
167 | sc->sc_ah->caps.rx_chainmask = mask; | 168 | ah->caps.rx_chainmask = mask; |
168 | return count; | 169 | return count; |
169 | } | 170 | } |
170 | 171 | ||
@@ -523,9 +524,22 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, | |||
523 | if (tmp & ATH9K_RX_FILTER_PHYRADAR) | 524 | if (tmp & ATH9K_RX_FILTER_PHYRADAR) |
524 | len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR"); | 525 | len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR"); |
525 | if (tmp & ATH9K_RX_FILTER_MCAST_BCAST_ALL) | 526 | if (tmp & ATH9K_RX_FILTER_MCAST_BCAST_ALL) |
526 | len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL\n"); | 527 | len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL"); |
527 | else | 528 | |
528 | len += snprintf(buf + len, sizeof(buf) - len, "\n"); | 529 | len += snprintf(buf + len, sizeof(buf) - len, |
530 | "\n\nReset causes:\n" | ||
531 | " baseband hang: %d\n" | ||
532 | " baseband watchdog: %d\n" | ||
533 | " fatal hardware error interrupt: %d\n" | ||
534 | " tx hardware error: %d\n" | ||
535 | " tx path hang: %d\n" | ||
536 | " pll rx hang: %d\n", | ||
537 | sc->debug.stats.reset[RESET_TYPE_BB_HANG], | ||
538 | sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG], | ||
539 | sc->debug.stats.reset[RESET_TYPE_FATAL_INT], | ||
540 | sc->debug.stats.reset[RESET_TYPE_TX_ERROR], | ||
541 | sc->debug.stats.reset[RESET_TYPE_TX_HANG], | ||
542 | sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); | ||
529 | 543 | ||
530 | if (len > sizeof(buf)) | 544 | if (len > sizeof(buf)) |
531 | len = sizeof(buf); | 545 | len = sizeof(buf); |
@@ -711,7 +725,7 @@ static ssize_t read_file_stations(struct file *file, char __user *user_buf, | |||
711 | " tid: %p %s %s %i %p %p\n", | 725 | " tid: %p %s %s %i %p %p\n", |
712 | tid, tid->sched ? "sched" : "idle", | 726 | tid, tid->sched ? "sched" : "idle", |
713 | tid->paused ? "paused" : "running", | 727 | tid->paused ? "paused" : "running", |
714 | list_empty(&tid->buf_q), | 728 | skb_queue_empty(&tid->buf_q), |
715 | tid->an, tid->ac); | 729 | tid->an, tid->ac); |
716 | if (len >= size) | 730 | if (len >= size) |
717 | goto done; | 731 | goto done; |
@@ -826,20 +840,23 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, | |||
826 | } | 840 | } |
827 | 841 | ||
828 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | 842 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, |
829 | struct ath_tx_status *ts, struct ath_txq *txq) | 843 | struct ath_tx_status *ts, struct ath_txq *txq, |
844 | unsigned int flags) | ||
830 | { | 845 | { |
846 | #define TX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].ts\ | ||
847 | [sc->debug.tsidx].c) | ||
831 | int qnum = txq->axq_qnum; | 848 | int qnum = txq->axq_qnum; |
832 | 849 | ||
833 | TX_STAT_INC(qnum, tx_pkts_all); | 850 | TX_STAT_INC(qnum, tx_pkts_all); |
834 | sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len; | 851 | sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len; |
835 | 852 | ||
836 | if (bf_isampdu(bf)) { | 853 | if (bf_isampdu(bf)) { |
837 | if (bf_isxretried(bf)) | 854 | if (flags & ATH_TX_BAR) |
838 | TX_STAT_INC(qnum, a_xretries); | 855 | TX_STAT_INC(qnum, a_xretries); |
839 | else | 856 | else |
840 | TX_STAT_INC(qnum, a_completed); | 857 | TX_STAT_INC(qnum, a_completed); |
841 | } else { | 858 | } else { |
842 | if (bf_isxretried(bf)) | 859 | if (ts->ts_status & ATH9K_TXERR_XRETRY) |
843 | TX_STAT_INC(qnum, xretries); | 860 | TX_STAT_INC(qnum, xretries); |
844 | else | 861 | else |
845 | TX_STAT_INC(qnum, completed); | 862 | TX_STAT_INC(qnum, completed); |
@@ -857,6 +874,35 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | |||
857 | TX_STAT_INC(qnum, data_underrun); | 874 | TX_STAT_INC(qnum, data_underrun); |
858 | if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) | 875 | if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) |
859 | TX_STAT_INC(qnum, delim_underrun); | 876 | TX_STAT_INC(qnum, delim_underrun); |
877 | |||
878 | spin_lock(&sc->debug.samp_lock); | ||
879 | TX_SAMP_DBG(jiffies) = jiffies; | ||
880 | TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0; | ||
881 | TX_SAMP_DBG(rssi_ctl1) = ts->ts_rssi_ctl1; | ||
882 | TX_SAMP_DBG(rssi_ctl2) = ts->ts_rssi_ctl2; | ||
883 | TX_SAMP_DBG(rssi_ext0) = ts->ts_rssi_ext0; | ||
884 | TX_SAMP_DBG(rssi_ext1) = ts->ts_rssi_ext1; | ||
885 | TX_SAMP_DBG(rssi_ext2) = ts->ts_rssi_ext2; | ||
886 | TX_SAMP_DBG(rateindex) = ts->ts_rateindex; | ||
887 | TX_SAMP_DBG(isok) = !!(ts->ts_status & ATH9K_TXERR_MASK); | ||
888 | TX_SAMP_DBG(rts_fail_cnt) = ts->ts_shortretry; | ||
889 | TX_SAMP_DBG(data_fail_cnt) = ts->ts_longretry; | ||
890 | TX_SAMP_DBG(rssi) = ts->ts_rssi; | ||
891 | TX_SAMP_DBG(tid) = ts->tid; | ||
892 | TX_SAMP_DBG(qid) = ts->qid; | ||
893 | |||
894 | if (ts->ts_flags & ATH9K_TX_BA) { | ||
895 | TX_SAMP_DBG(ba_low) = ts->ba_low; | ||
896 | TX_SAMP_DBG(ba_high) = ts->ba_high; | ||
897 | } else { | ||
898 | TX_SAMP_DBG(ba_low) = 0; | ||
899 | TX_SAMP_DBG(ba_high) = 0; | ||
900 | } | ||
901 | |||
902 | sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES; | ||
903 | spin_unlock(&sc->debug.samp_lock); | ||
904 | |||
905 | #undef TX_SAMP_DBG | ||
860 | } | 906 | } |
861 | 907 | ||
862 | static const struct file_operations fops_xmit = { | 908 | static const struct file_operations fops_xmit = { |
@@ -995,6 +1041,8 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | |||
995 | { | 1041 | { |
996 | #define RX_STAT_INC(c) sc->debug.stats.rxstats.c++ | 1042 | #define RX_STAT_INC(c) sc->debug.stats.rxstats.c++ |
997 | #define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ | 1043 | #define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ |
1044 | #define RX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].rs\ | ||
1045 | [sc->debug.rsidx].c) | ||
998 | 1046 | ||
999 | u32 phyerr; | 1047 | u32 phyerr; |
1000 | 1048 | ||
@@ -1030,8 +1078,25 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | |||
1030 | 1078 | ||
1031 | sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; | 1079 | sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; |
1032 | 1080 | ||
1081 | spin_lock(&sc->debug.samp_lock); | ||
1082 | RX_SAMP_DBG(jiffies) = jiffies; | ||
1083 | RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0; | ||
1084 | RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1; | ||
1085 | RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2; | ||
1086 | RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0; | ||
1087 | RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1; | ||
1088 | RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2; | ||
1089 | RX_SAMP_DBG(antenna) = rs->rs_antenna; | ||
1090 | RX_SAMP_DBG(rssi) = rs->rs_rssi; | ||
1091 | RX_SAMP_DBG(rate) = rs->rs_rate; | ||
1092 | RX_SAMP_DBG(is_mybeacon) = rs->is_mybeacon; | ||
1093 | |||
1094 | sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES; | ||
1095 | spin_unlock(&sc->debug.samp_lock); | ||
1096 | |||
1033 | #undef RX_STAT_INC | 1097 | #undef RX_STAT_INC |
1034 | #undef RX_PHY_ERR_INC | 1098 | #undef RX_PHY_ERR_INC |
1099 | #undef RX_SAMP_DBG | ||
1035 | } | 1100 | } |
1036 | 1101 | ||
1037 | static const struct file_operations fops_recv = { | 1102 | static const struct file_operations fops_recv = { |
@@ -1163,6 +1228,389 @@ static const struct file_operations fops_regdump = { | |||
1163 | .llseek = default_llseek,/* read accesses f_pos */ | 1228 | .llseek = default_llseek,/* read accesses f_pos */ |
1164 | }; | 1229 | }; |
1165 | 1230 | ||
1231 | static ssize_t read_file_dump_nfcal(struct file *file, char __user *user_buf, | ||
1232 | size_t count, loff_t *ppos) | ||
1233 | { | ||
1234 | struct ath_softc *sc = file->private_data; | ||
1235 | struct ath_hw *ah = sc->sc_ah; | ||
1236 | struct ath9k_nfcal_hist *h = sc->caldata.nfCalHist; | ||
1237 | struct ath_common *common = ath9k_hw_common(ah); | ||
1238 | struct ieee80211_conf *conf = &common->hw->conf; | ||
1239 | u32 len = 0, size = 1500; | ||
1240 | u32 i, j; | ||
1241 | ssize_t retval = 0; | ||
1242 | char *buf; | ||
1243 | u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; | ||
1244 | u8 nread; | ||
1245 | |||
1246 | buf = kzalloc(size, GFP_KERNEL); | ||
1247 | if (!buf) | ||
1248 | return -ENOMEM; | ||
1249 | |||
1250 | len += snprintf(buf + len, size - len, | ||
1251 | "Channel Noise Floor : %d\n", ah->noise); | ||
1252 | len += snprintf(buf + len, size - len, | ||
1253 | "Chain | privNF | # Readings | NF Readings\n"); | ||
1254 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
1255 | if (!(chainmask & (1 << i)) || | ||
1256 | ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))) | ||
1257 | continue; | ||
1258 | |||
1259 | nread = AR_PHY_CCA_FILTERWINDOW_LENGTH - h[i].invalidNFcount; | ||
1260 | len += snprintf(buf + len, size - len, " %d\t %d\t %d\t\t", | ||
1261 | i, h[i].privNF, nread); | ||
1262 | for (j = 0; j < nread; j++) | ||
1263 | len += snprintf(buf + len, size - len, | ||
1264 | " %d", h[i].nfCalBuffer[j]); | ||
1265 | len += snprintf(buf + len, size - len, "\n"); | ||
1266 | } | ||
1267 | |||
1268 | if (len > size) | ||
1269 | len = size; | ||
1270 | |||
1271 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
1272 | kfree(buf); | ||
1273 | |||
1274 | return retval; | ||
1275 | } | ||
1276 | |||
1277 | static const struct file_operations fops_dump_nfcal = { | ||
1278 | .read = read_file_dump_nfcal, | ||
1279 | .open = ath9k_debugfs_open, | ||
1280 | .owner = THIS_MODULE, | ||
1281 | .llseek = default_llseek, | ||
1282 | }; | ||
1283 | |||
1284 | static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, | ||
1285 | size_t count, loff_t *ppos) | ||
1286 | { | ||
1287 | struct ath_softc *sc = file->private_data; | ||
1288 | struct ath_hw *ah = sc->sc_ah; | ||
1289 | u32 len = 0, size = 1500; | ||
1290 | ssize_t retval = 0; | ||
1291 | char *buf; | ||
1292 | |||
1293 | buf = kzalloc(size, GFP_KERNEL); | ||
1294 | if (!buf) | ||
1295 | return -ENOMEM; | ||
1296 | |||
1297 | len = ah->eep_ops->dump_eeprom(ah, true, buf, len, size); | ||
1298 | |||
1299 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
1300 | kfree(buf); | ||
1301 | |||
1302 | return retval; | ||
1303 | } | ||
1304 | |||
1305 | static const struct file_operations fops_base_eeprom = { | ||
1306 | .read = read_file_base_eeprom, | ||
1307 | .open = ath9k_debugfs_open, | ||
1308 | .owner = THIS_MODULE, | ||
1309 | .llseek = default_llseek, | ||
1310 | }; | ||
1311 | |||
1312 | static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf, | ||
1313 | size_t count, loff_t *ppos) | ||
1314 | { | ||
1315 | struct ath_softc *sc = file->private_data; | ||
1316 | struct ath_hw *ah = sc->sc_ah; | ||
1317 | u32 len = 0, size = 6000; | ||
1318 | char *buf; | ||
1319 | size_t retval; | ||
1320 | |||
1321 | buf = kzalloc(size, GFP_KERNEL); | ||
1322 | if (buf == NULL) | ||
1323 | return -ENOMEM; | ||
1324 | |||
1325 | len = ah->eep_ops->dump_eeprom(ah, false, buf, len, size); | ||
1326 | |||
1327 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
1328 | kfree(buf); | ||
1329 | |||
1330 | return retval; | ||
1331 | } | ||
1332 | |||
1333 | static const struct file_operations fops_modal_eeprom = { | ||
1334 | .read = read_file_modal_eeprom, | ||
1335 | .open = ath9k_debugfs_open, | ||
1336 | .owner = THIS_MODULE, | ||
1337 | .llseek = default_llseek, | ||
1338 | }; | ||
1339 | |||
1340 | void ath9k_debug_samp_bb_mac(struct ath_softc *sc) | ||
1341 | { | ||
1342 | #define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c) | ||
1343 | struct ath_hw *ah = sc->sc_ah; | ||
1344 | struct ath_common *common = ath9k_hw_common(ah); | ||
1345 | unsigned long flags; | ||
1346 | int i; | ||
1347 | |||
1348 | ath9k_ps_wakeup(sc); | ||
1349 | |||
1350 | spin_lock_bh(&sc->debug.samp_lock); | ||
1351 | |||
1352 | spin_lock_irqsave(&common->cc_lock, flags); | ||
1353 | ath_hw_cycle_counters_update(common); | ||
1354 | |||
1355 | ATH_SAMP_DBG(cc.cycles) = common->cc_ani.cycles; | ||
1356 | ATH_SAMP_DBG(cc.rx_busy) = common->cc_ani.rx_busy; | ||
1357 | ATH_SAMP_DBG(cc.rx_frame) = common->cc_ani.rx_frame; | ||
1358 | ATH_SAMP_DBG(cc.tx_frame) = common->cc_ani.tx_frame; | ||
1359 | spin_unlock_irqrestore(&common->cc_lock, flags); | ||
1360 | |||
1361 | ATH_SAMP_DBG(noise) = ah->noise; | ||
1362 | |||
1363 | REG_WRITE_D(ah, AR_MACMISC, | ||
1364 | ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) | | ||
1365 | (AR_MACMISC_MISC_OBS_BUS_1 << | ||
1366 | AR_MACMISC_MISC_OBS_BUS_MSB_S))); | ||
1367 | |||
1368 | for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) | ||
1369 | ATH_SAMP_DBG(dma_dbg_reg_vals[i]) = REG_READ_D(ah, | ||
1370 | AR_DMADBG_0 + (i * sizeof(u32))); | ||
1371 | |||
1372 | ATH_SAMP_DBG(pcu_obs) = REG_READ_D(ah, AR_OBS_BUS_1); | ||
1373 | ATH_SAMP_DBG(pcu_cr) = REG_READ_D(ah, AR_CR); | ||
1374 | |||
1375 | memcpy(ATH_SAMP_DBG(nfCalHist), sc->caldata.nfCalHist, | ||
1376 | sizeof(ATH_SAMP_DBG(nfCalHist))); | ||
1377 | |||
1378 | sc->debug.sampidx = (sc->debug.sampidx + 1) % ATH_DBG_MAX_SAMPLES; | ||
1379 | spin_unlock_bh(&sc->debug.samp_lock); | ||
1380 | ath9k_ps_restore(sc); | ||
1381 | |||
1382 | #undef ATH_SAMP_DBG | ||
1383 | } | ||
1384 | |||
1385 | static int open_file_bb_mac_samps(struct inode *inode, struct file *file) | ||
1386 | { | ||
1387 | #define ATH_SAMP_DBG(c) bb_mac_samp[sampidx].c | ||
1388 | struct ath_softc *sc = inode->i_private; | ||
1389 | struct ath_hw *ah = sc->sc_ah; | ||
1390 | struct ath_common *common = ath9k_hw_common(ah); | ||
1391 | struct ieee80211_conf *conf = &common->hw->conf; | ||
1392 | struct ath_dbg_bb_mac_samp *bb_mac_samp; | ||
1393 | struct ath9k_nfcal_hist *h; | ||
1394 | int i, j, qcuOffset = 0, dcuOffset = 0; | ||
1395 | u32 *qcuBase, *dcuBase, size = 30000, len = 0; | ||
1396 | u32 sampidx = 0; | ||
1397 | u8 *buf; | ||
1398 | u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; | ||
1399 | u8 nread; | ||
1400 | |||
1401 | if (sc->sc_flags & SC_OP_INVALID) | ||
1402 | return -EAGAIN; | ||
1403 | |||
1404 | buf = vmalloc(size); | ||
1405 | if (!buf) | ||
1406 | return -ENOMEM; | ||
1407 | bb_mac_samp = vmalloc(sizeof(*bb_mac_samp) * ATH_DBG_MAX_SAMPLES); | ||
1408 | if (!bb_mac_samp) { | ||
1409 | vfree(buf); | ||
1410 | return -ENOMEM; | ||
1411 | } | ||
1412 | /* Account the current state too */ | ||
1413 | ath9k_debug_samp_bb_mac(sc); | ||
1414 | |||
1415 | spin_lock_bh(&sc->debug.samp_lock); | ||
1416 | memcpy(bb_mac_samp, sc->debug.bb_mac_samp, | ||
1417 | sizeof(*bb_mac_samp) * ATH_DBG_MAX_SAMPLES); | ||
1418 | len += snprintf(buf + len, size - len, | ||
1419 | "Current Sample Index: %d\n", sc->debug.sampidx); | ||
1420 | spin_unlock_bh(&sc->debug.samp_lock); | ||
1421 | |||
1422 | len += snprintf(buf + len, size - len, | ||
1423 | "Raw DMA Debug Dump:\n"); | ||
1424 | len += snprintf(buf + len, size - len, "Sample |\t"); | ||
1425 | for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) | ||
1426 | len += snprintf(buf + len, size - len, " DMA Reg%d |\t", i); | ||
1427 | len += snprintf(buf + len, size - len, "\n"); | ||
1428 | |||
1429 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1430 | len += snprintf(buf + len, size - len, "%d\t", sampidx); | ||
1431 | |||
1432 | for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) | ||
1433 | len += snprintf(buf + len, size - len, " %08x\t", | ||
1434 | ATH_SAMP_DBG(dma_dbg_reg_vals[i])); | ||
1435 | len += snprintf(buf + len, size - len, "\n"); | ||
1436 | } | ||
1437 | len += snprintf(buf + len, size - len, "\n"); | ||
1438 | |||
1439 | len += snprintf(buf + len, size - len, | ||
1440 | "Sample Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); | ||
1441 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1442 | qcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[0]); | ||
1443 | dcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[4]); | ||
1444 | |||
1445 | for (i = 0; i < ATH9K_NUM_QUEUES; i++, | ||
1446 | qcuOffset += 4, dcuOffset += 5) { | ||
1447 | if (i == 8) { | ||
1448 | qcuOffset = 0; | ||
1449 | qcuBase++; | ||
1450 | } | ||
1451 | |||
1452 | if (i == 6) { | ||
1453 | dcuOffset = 0; | ||
1454 | dcuBase++; | ||
1455 | } | ||
1456 | if (!sc->debug.stats.txstats[i].queued) | ||
1457 | continue; | ||
1458 | |||
1459 | len += snprintf(buf + len, size - len, | ||
1460 | "%4d %7d %2x %1x %2x %2x\n", | ||
1461 | sampidx, i, | ||
1462 | (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, | ||
1463 | (*qcuBase & (0x8 << qcuOffset)) >> | ||
1464 | (qcuOffset + 3), | ||
1465 | ATH_SAMP_DBG(dma_dbg_reg_vals[2]) & | ||
1466 | (0x7 << (i * 3)) >> (i * 3), | ||
1467 | (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); | ||
1468 | } | ||
1469 | len += snprintf(buf + len, size - len, "\n"); | ||
1470 | } | ||
1471 | len += snprintf(buf + len, size - len, | ||
1472 | "samp qcu_sh qcu_fh qcu_comp dcu_comp dcu_arb dcu_fp " | ||
1473 | "ch_idle_dur ch_idle_dur_val txfifo_val0 txfifo_val1 " | ||
1474 | "txfifo_dcu0 txfifo_dcu1 pcu_obs AR_CR\n"); | ||
1475 | |||
1476 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1477 | qcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[0]); | ||
1478 | dcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[4]); | ||
1479 | |||
1480 | len += snprintf(buf + len, size - len, "%4d %5x %5x ", sampidx, | ||
1481 | (ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x003c0000) >> 18, | ||
1482 | (ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x03c00000) >> 22); | ||
1483 | len += snprintf(buf + len, size - len, "%7x %8x ", | ||
1484 | (ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x1c000000) >> 26, | ||
1485 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x3)); | ||
1486 | len += snprintf(buf + len, size - len, "%7x %7x ", | ||
1487 | (ATH_SAMP_DBG(dma_dbg_reg_vals[5]) & 0x06000000) >> 25, | ||
1488 | (ATH_SAMP_DBG(dma_dbg_reg_vals[5]) & 0x38000000) >> 27); | ||
1489 | len += snprintf(buf + len, size - len, "%7d %12d ", | ||
1490 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x000003fc) >> 2, | ||
1491 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00000400) >> 10); | ||
1492 | len += snprintf(buf + len, size - len, "%12d %12d ", | ||
1493 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00000800) >> 11, | ||
1494 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00001000) >> 12); | ||
1495 | len += snprintf(buf + len, size - len, "%12d %12d ", | ||
1496 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x0001e000) >> 13, | ||
1497 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x001e0000) >> 17); | ||
1498 | len += snprintf(buf + len, size - len, "0x%07x 0x%07x\n", | ||
1499 | ATH_SAMP_DBG(pcu_obs), ATH_SAMP_DBG(pcu_cr)); | ||
1500 | } | ||
1501 | |||
1502 | len += snprintf(buf + len, size - len, | ||
1503 | "Sample ChNoise Chain privNF #Reading Readings\n"); | ||
1504 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1505 | h = ATH_SAMP_DBG(nfCalHist); | ||
1506 | if (!ATH_SAMP_DBG(noise)) | ||
1507 | continue; | ||
1508 | |||
1509 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
1510 | if (!(chainmask & (1 << i)) || | ||
1511 | ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))) | ||
1512 | continue; | ||
1513 | |||
1514 | nread = AR_PHY_CCA_FILTERWINDOW_LENGTH - | ||
1515 | h[i].invalidNFcount; | ||
1516 | len += snprintf(buf + len, size - len, | ||
1517 | "%4d %5d %4d\t %d\t %d\t", | ||
1518 | sampidx, ATH_SAMP_DBG(noise), | ||
1519 | i, h[i].privNF, nread); | ||
1520 | for (j = 0; j < nread; j++) | ||
1521 | len += snprintf(buf + len, size - len, | ||
1522 | " %d", h[i].nfCalBuffer[j]); | ||
1523 | len += snprintf(buf + len, size - len, "\n"); | ||
1524 | } | ||
1525 | } | ||
1526 | len += snprintf(buf + len, size - len, "\nCycle counters:\n" | ||
1527 | "Sample Total Rxbusy Rxframes Txframes\n"); | ||
1528 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1529 | if (!ATH_SAMP_DBG(cc.cycles)) | ||
1530 | continue; | ||
1531 | len += snprintf(buf + len, size - len, | ||
1532 | "%4d %08x %08x %08x %08x\n", | ||
1533 | sampidx, ATH_SAMP_DBG(cc.cycles), | ||
1534 | ATH_SAMP_DBG(cc.rx_busy), | ||
1535 | ATH_SAMP_DBG(cc.rx_frame), | ||
1536 | ATH_SAMP_DBG(cc.tx_frame)); | ||
1537 | } | ||
1538 | |||
1539 | len += snprintf(buf + len, size - len, "Tx status Dump :\n"); | ||
1540 | len += snprintf(buf + len, size - len, | ||
1541 | "Sample rssi:- ctl0 ctl1 ctl2 ext0 ext1 ext2 comb " | ||
1542 | "isok rts_fail data_fail rate tid qid " | ||
1543 | "ba_low ba_high tx_before(ms)\n"); | ||
1544 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1545 | for (i = 0; i < ATH_DBG_MAX_SAMPLES; i++) { | ||
1546 | if (!ATH_SAMP_DBG(ts[i].jiffies)) | ||
1547 | continue; | ||
1548 | len += snprintf(buf + len, size - len, "%-14d" | ||
1549 | "%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d %-8d " | ||
1550 | "%-9d %-4d %-3d %-3d %08x %08x %-11d\n", | ||
1551 | sampidx, | ||
1552 | ATH_SAMP_DBG(ts[i].rssi_ctl0), | ||
1553 | ATH_SAMP_DBG(ts[i].rssi_ctl1), | ||
1554 | ATH_SAMP_DBG(ts[i].rssi_ctl2), | ||
1555 | ATH_SAMP_DBG(ts[i].rssi_ext0), | ||
1556 | ATH_SAMP_DBG(ts[i].rssi_ext1), | ||
1557 | ATH_SAMP_DBG(ts[i].rssi_ext2), | ||
1558 | ATH_SAMP_DBG(ts[i].rssi), | ||
1559 | ATH_SAMP_DBG(ts[i].isok), | ||
1560 | ATH_SAMP_DBG(ts[i].rts_fail_cnt), | ||
1561 | ATH_SAMP_DBG(ts[i].data_fail_cnt), | ||
1562 | ATH_SAMP_DBG(ts[i].rateindex), | ||
1563 | ATH_SAMP_DBG(ts[i].tid), | ||
1564 | ATH_SAMP_DBG(ts[i].qid), | ||
1565 | ATH_SAMP_DBG(ts[i].ba_low), | ||
1566 | ATH_SAMP_DBG(ts[i].ba_high), | ||
1567 | jiffies_to_msecs(jiffies - | ||
1568 | ATH_SAMP_DBG(ts[i].jiffies))); | ||
1569 | } | ||
1570 | } | ||
1571 | |||
1572 | len += snprintf(buf + len, size - len, "Rx status Dump :\n"); | ||
1573 | len += snprintf(buf + len, size - len, "Sample rssi:- ctl0 ctl1 ctl2 " | ||
1574 | "ext0 ext1 ext2 comb beacon ant rate rx_before(ms)\n"); | ||
1575 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1576 | for (i = 0; i < ATH_DBG_MAX_SAMPLES; i++) { | ||
1577 | if (!ATH_SAMP_DBG(rs[i].jiffies)) | ||
1578 | continue; | ||
1579 | len += snprintf(buf + len, size - len, "%-14d" | ||
1580 | "%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-9s %-2d %02x %-13d\n", | ||
1581 | sampidx, | ||
1582 | ATH_SAMP_DBG(rs[i].rssi_ctl0), | ||
1583 | ATH_SAMP_DBG(rs[i].rssi_ctl1), | ||
1584 | ATH_SAMP_DBG(rs[i].rssi_ctl2), | ||
1585 | ATH_SAMP_DBG(rs[i].rssi_ext0), | ||
1586 | ATH_SAMP_DBG(rs[i].rssi_ext1), | ||
1587 | ATH_SAMP_DBG(rs[i].rssi_ext2), | ||
1588 | ATH_SAMP_DBG(rs[i].rssi), | ||
1589 | ATH_SAMP_DBG(rs[i].is_mybeacon) ? | ||
1590 | "True" : "False", | ||
1591 | ATH_SAMP_DBG(rs[i].antenna), | ||
1592 | ATH_SAMP_DBG(rs[i].rate), | ||
1593 | jiffies_to_msecs(jiffies - | ||
1594 | ATH_SAMP_DBG(rs[i].jiffies))); | ||
1595 | } | ||
1596 | } | ||
1597 | |||
1598 | vfree(bb_mac_samp); | ||
1599 | file->private_data = buf; | ||
1600 | |||
1601 | return 0; | ||
1602 | #undef ATH_SAMP_DBG | ||
1603 | } | ||
1604 | |||
1605 | static const struct file_operations fops_samps = { | ||
1606 | .open = open_file_bb_mac_samps, | ||
1607 | .read = ath9k_debugfs_read_buf, | ||
1608 | .release = ath9k_debugfs_release_buf, | ||
1609 | .owner = THIS_MODULE, | ||
1610 | .llseek = default_llseek, | ||
1611 | }; | ||
1612 | |||
1613 | |||
1166 | int ath9k_init_debug(struct ath_hw *ah) | 1614 | int ath9k_init_debug(struct ath_hw *ah) |
1167 | { | 1615 | { |
1168 | struct ath_common *common = ath9k_hw_common(ah); | 1616 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -1206,6 +1654,14 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1206 | &ah->config.cwm_ignore_extcca); | 1654 | &ah->config.cwm_ignore_extcca); |
1207 | debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc, | 1655 | debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc, |
1208 | &fops_regdump); | 1656 | &fops_regdump); |
1657 | debugfs_create_file("dump_nfcal", S_IRUSR, sc->debug.debugfs_phy, sc, | ||
1658 | &fops_dump_nfcal); | ||
1659 | debugfs_create_file("base_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, | ||
1660 | &fops_base_eeprom); | ||
1661 | debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, | ||
1662 | &fops_modal_eeprom); | ||
1663 | debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, | ||
1664 | &fops_samps); | ||
1209 | 1665 | ||
1210 | debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, | 1666 | debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, |
1211 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); | 1667 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); |
@@ -1214,5 +1670,9 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1214 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); | 1670 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); |
1215 | 1671 | ||
1216 | sc->debug.regidx = 0; | 1672 | sc->debug.regidx = 0; |
1673 | memset(&sc->debug.bb_mac_samp, 0, sizeof(sc->debug.bb_mac_samp)); | ||
1674 | sc->debug.sampidx = 0; | ||
1675 | sc->debug.tsidx = 0; | ||
1676 | sc->debug.rsidx = 0; | ||
1217 | return 0; | 1677 | return 0; |
1218 | } | 1678 | } |