diff options
author | Rajkumar Manoharan <rmanohar@qca.qualcomm.com> | 2011-08-27 06:47:47 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-08-29 15:33:03 -0400 |
commit | cf3af74824b1bf2bd60eb6a0dd82b27f9e9236ac (patch) | |
tree | c5ae88548f8acc38549032e8d659b39333b19417 /drivers/net/wireless/ath | |
parent | 059ee09b99942bf64f4075196a7a2a992e64193d (diff) |
ath9k: Add debugfs support for mac/baseband samples
This patch keep track of number of samples that includes
DMA debugs registers, PCU observe, CR, channel noise,
cycle conters, noisefloor history buffer and last N number
of tx and rx descriptor status. These samples are grouped
in table manner which dumping in debgufs.
Debugfs file location:
<debugfs_mnt>/ieee80211/phy#/ath9k/samples
Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 310 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.h | 47 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/mac.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 22 |
6 files changed, 369 insertions, 14 deletions
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index da45f325be7d..fbec5f7eca6e 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -828,6 +828,8 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, | |||
828 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | 828 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, |
829 | struct ath_tx_status *ts, struct ath_txq *txq) | 829 | struct ath_tx_status *ts, struct ath_txq *txq) |
830 | { | 830 | { |
831 | #define TX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].ts\ | ||
832 | [sc->debug.tsidx].c) | ||
831 | int qnum = txq->axq_qnum; | 833 | int qnum = txq->axq_qnum; |
832 | 834 | ||
833 | TX_STAT_INC(qnum, tx_pkts_all); | 835 | TX_STAT_INC(qnum, tx_pkts_all); |
@@ -857,6 +859,26 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | |||
857 | TX_STAT_INC(qnum, data_underrun); | 859 | TX_STAT_INC(qnum, data_underrun); |
858 | if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) | 860 | if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) |
859 | TX_STAT_INC(qnum, delim_underrun); | 861 | TX_STAT_INC(qnum, delim_underrun); |
862 | |||
863 | spin_lock(&sc->debug.samp_lock); | ||
864 | TX_SAMP_DBG(jiffies) = jiffies; | ||
865 | TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0; | ||
866 | TX_SAMP_DBG(rssi_ctl1) = ts->ts_rssi_ctl1; | ||
867 | TX_SAMP_DBG(rssi_ctl2) = ts->ts_rssi_ctl2; | ||
868 | TX_SAMP_DBG(rssi_ext0) = ts->ts_rssi_ext0; | ||
869 | TX_SAMP_DBG(rssi_ext1) = ts->ts_rssi_ext1; | ||
870 | TX_SAMP_DBG(rssi_ext2) = ts->ts_rssi_ext2; | ||
871 | TX_SAMP_DBG(rateindex) = ts->ts_rateindex; | ||
872 | TX_SAMP_DBG(isok) = !!(ts->ts_status & ATH9K_TXERR_MASK); | ||
873 | TX_SAMP_DBG(rts_fail_cnt) = ts->ts_shortretry; | ||
874 | TX_SAMP_DBG(data_fail_cnt) = ts->ts_longretry; | ||
875 | TX_SAMP_DBG(rssi) = ts->ts_rssi; | ||
876 | TX_SAMP_DBG(tid) = ts->tid; | ||
877 | TX_SAMP_DBG(qid) = ts->qid; | ||
878 | sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES; | ||
879 | spin_unlock(&sc->debug.samp_lock); | ||
880 | |||
881 | #undef TX_SAMP_DBG | ||
860 | } | 882 | } |
861 | 883 | ||
862 | static const struct file_operations fops_xmit = { | 884 | static const struct file_operations fops_xmit = { |
@@ -995,6 +1017,8 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | |||
995 | { | 1017 | { |
996 | #define RX_STAT_INC(c) sc->debug.stats.rxstats.c++ | 1018 | #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]++ | 1019 | #define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ |
1020 | #define RX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].rs\ | ||
1021 | [sc->debug.rsidx].c) | ||
998 | 1022 | ||
999 | u32 phyerr; | 1023 | u32 phyerr; |
1000 | 1024 | ||
@@ -1030,8 +1054,25 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | |||
1030 | 1054 | ||
1031 | sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; | 1055 | sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; |
1032 | 1056 | ||
1057 | spin_lock(&sc->debug.samp_lock); | ||
1058 | RX_SAMP_DBG(jiffies) = jiffies; | ||
1059 | RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0; | ||
1060 | RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1; | ||
1061 | RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2; | ||
1062 | RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0; | ||
1063 | RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1; | ||
1064 | RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2; | ||
1065 | RX_SAMP_DBG(antenna) = rs->rs_antenna; | ||
1066 | RX_SAMP_DBG(rssi) = rs->rs_rssi; | ||
1067 | RX_SAMP_DBG(rate) = rs->rs_rate; | ||
1068 | RX_SAMP_DBG(is_mybeacon) = rs->is_mybeacon; | ||
1069 | |||
1070 | sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES; | ||
1071 | spin_unlock(&sc->debug.samp_lock); | ||
1072 | |||
1033 | #undef RX_STAT_INC | 1073 | #undef RX_STAT_INC |
1034 | #undef RX_PHY_ERR_INC | 1074 | #undef RX_PHY_ERR_INC |
1075 | #undef RX_SAMP_DBG | ||
1035 | } | 1076 | } |
1036 | 1077 | ||
1037 | static const struct file_operations fops_recv = { | 1078 | static const struct file_operations fops_recv = { |
@@ -1272,6 +1313,269 @@ static const struct file_operations fops_modal_eeprom = { | |||
1272 | .llseek = default_llseek, | 1313 | .llseek = default_llseek, |
1273 | }; | 1314 | }; |
1274 | 1315 | ||
1316 | void ath9k_debug_samp_bb_mac(struct ath_softc *sc) | ||
1317 | { | ||
1318 | #define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c) | ||
1319 | struct ath_hw *ah = sc->sc_ah; | ||
1320 | struct ath_common *common = ath9k_hw_common(ah); | ||
1321 | unsigned long flags; | ||
1322 | int i; | ||
1323 | |||
1324 | ath9k_ps_wakeup(sc); | ||
1325 | |||
1326 | spin_lock_irqsave(&common->cc_lock, flags); | ||
1327 | ath_hw_cycle_counters_update(common); | ||
1328 | spin_unlock_irqrestore(&common->cc_lock, flags); | ||
1329 | |||
1330 | spin_lock_bh(&sc->debug.samp_lock); | ||
1331 | |||
1332 | ATH_SAMP_DBG(cc.cycles) = common->cc_ani.cycles; | ||
1333 | ATH_SAMP_DBG(cc.rx_busy) = common->cc_ani.rx_busy; | ||
1334 | ATH_SAMP_DBG(cc.rx_frame) = common->cc_ani.rx_frame; | ||
1335 | ATH_SAMP_DBG(cc.tx_frame) = common->cc_ani.tx_frame; | ||
1336 | ATH_SAMP_DBG(noise) = ah->noise; | ||
1337 | |||
1338 | REG_WRITE_D(ah, AR_MACMISC, | ||
1339 | ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) | | ||
1340 | (AR_MACMISC_MISC_OBS_BUS_1 << | ||
1341 | AR_MACMISC_MISC_OBS_BUS_MSB_S))); | ||
1342 | |||
1343 | for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) | ||
1344 | ATH_SAMP_DBG(dma_dbg_reg_vals[i]) = REG_READ_D(ah, | ||
1345 | AR_DMADBG_0 + (i * sizeof(u32))); | ||
1346 | |||
1347 | ATH_SAMP_DBG(pcu_obs) = REG_READ_D(ah, AR_OBS_BUS_1); | ||
1348 | ATH_SAMP_DBG(pcu_cr) = REG_READ_D(ah, AR_CR); | ||
1349 | |||
1350 | memcpy(ATH_SAMP_DBG(nfCalHist), sc->caldata.nfCalHist, | ||
1351 | sizeof(ATH_SAMP_DBG(nfCalHist))); | ||
1352 | |||
1353 | sc->debug.sampidx = (sc->debug.sampidx + 1) % ATH_DBG_MAX_SAMPLES; | ||
1354 | spin_unlock_bh(&sc->debug.samp_lock); | ||
1355 | ath9k_ps_restore(sc); | ||
1356 | |||
1357 | #undef ATH_SAMP_DBG | ||
1358 | } | ||
1359 | |||
1360 | static int open_file_bb_mac_samps(struct inode *inode, struct file *file) | ||
1361 | { | ||
1362 | #define ATH_SAMP_DBG(c) bb_mac_samp[sampidx].c | ||
1363 | struct ath_softc *sc = inode->i_private; | ||
1364 | struct ath_hw *ah = sc->sc_ah; | ||
1365 | struct ath_common *common = ath9k_hw_common(ah); | ||
1366 | struct ieee80211_conf *conf = &common->hw->conf; | ||
1367 | struct ath_dbg_bb_mac_samp *bb_mac_samp; | ||
1368 | struct ath9k_nfcal_hist *h; | ||
1369 | int i, j, qcuOffset = 0, dcuOffset = 0; | ||
1370 | u32 *qcuBase, *dcuBase, size = 30000, len = 0; | ||
1371 | u32 sampidx = 0; | ||
1372 | u8 *buf; | ||
1373 | u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; | ||
1374 | u8 nread; | ||
1375 | |||
1376 | buf = vmalloc(size); | ||
1377 | if (!buf) | ||
1378 | return -ENOMEM; | ||
1379 | bb_mac_samp = vmalloc(sizeof(*bb_mac_samp) * ATH_DBG_MAX_SAMPLES); | ||
1380 | if (!bb_mac_samp) { | ||
1381 | vfree(buf); | ||
1382 | return -ENOMEM; | ||
1383 | } | ||
1384 | |||
1385 | spin_lock_bh(&sc->debug.samp_lock); | ||
1386 | memcpy(bb_mac_samp, sc->debug.bb_mac_samp, | ||
1387 | sizeof(*bb_mac_samp) * ATH_DBG_MAX_SAMPLES); | ||
1388 | spin_unlock_bh(&sc->debug.samp_lock); | ||
1389 | |||
1390 | len += snprintf(buf + len, size - len, | ||
1391 | "Raw DMA Debug Dump:\n"); | ||
1392 | len += snprintf(buf + len, size - len, "Sample |\t"); | ||
1393 | for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) | ||
1394 | len += snprintf(buf + len, size - len, " DMA Reg%d |\t", i); | ||
1395 | len += snprintf(buf + len, size - len, "\n"); | ||
1396 | |||
1397 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1398 | len += snprintf(buf + len, size - len, "%d\t", sampidx); | ||
1399 | |||
1400 | for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) | ||
1401 | len += snprintf(buf + len, size - len, " %08x\t", | ||
1402 | ATH_SAMP_DBG(dma_dbg_reg_vals[i])); | ||
1403 | len += snprintf(buf + len, size - len, "\n"); | ||
1404 | } | ||
1405 | len += snprintf(buf + len, size - len, "\n"); | ||
1406 | |||
1407 | len += snprintf(buf + len, size - len, | ||
1408 | "Sample Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); | ||
1409 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1410 | qcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[0]); | ||
1411 | dcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[4]); | ||
1412 | |||
1413 | for (i = 0; i < ATH9K_NUM_QUEUES; i++, | ||
1414 | qcuOffset += 4, dcuOffset += 5) { | ||
1415 | if (i == 8) { | ||
1416 | qcuOffset = 0; | ||
1417 | qcuBase++; | ||
1418 | } | ||
1419 | |||
1420 | if (i == 6) { | ||
1421 | dcuOffset = 0; | ||
1422 | dcuBase++; | ||
1423 | } | ||
1424 | if (!sc->debug.stats.txstats[i].queued) | ||
1425 | continue; | ||
1426 | |||
1427 | len += snprintf(buf + len, size - len, | ||
1428 | "%4d %7d %2x %1x %2x %2x\n", | ||
1429 | sampidx, i, | ||
1430 | (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, | ||
1431 | (*qcuBase & (0x8 << qcuOffset)) >> | ||
1432 | (qcuOffset + 3), | ||
1433 | ATH_SAMP_DBG(dma_dbg_reg_vals[2]) & | ||
1434 | (0x7 << (i * 3)) >> (i * 3), | ||
1435 | (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); | ||
1436 | } | ||
1437 | len += snprintf(buf + len, size - len, "\n"); | ||
1438 | } | ||
1439 | len += snprintf(buf + len, size - len, | ||
1440 | "samp qcu_sh qcu_fh qcu_comp dcu_comp dcu_arb dcu_fp " | ||
1441 | "ch_idle_dur ch_idle_dur_val txfifo_val0 txfifo_val1 " | ||
1442 | "txfifo_dcu0 txfifo_dcu1 pcu_obs AR_CR\n"); | ||
1443 | |||
1444 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1445 | qcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[0]); | ||
1446 | dcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[4]); | ||
1447 | |||
1448 | len += snprintf(buf + len, size - len, "%4d %5x %5x ", sampidx, | ||
1449 | (ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x003c0000) >> 18, | ||
1450 | (ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x03c00000) >> 22); | ||
1451 | len += snprintf(buf + len, size - len, "%7x %8x ", | ||
1452 | (ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x1c000000) >> 26, | ||
1453 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x3)); | ||
1454 | len += snprintf(buf + len, size - len, "%7x %7x ", | ||
1455 | (ATH_SAMP_DBG(dma_dbg_reg_vals[5]) & 0x06000000) >> 25, | ||
1456 | (ATH_SAMP_DBG(dma_dbg_reg_vals[5]) & 0x38000000) >> 27); | ||
1457 | len += snprintf(buf + len, size - len, "%7d %12d ", | ||
1458 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x000003fc) >> 2, | ||
1459 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00000400) >> 10); | ||
1460 | len += snprintf(buf + len, size - len, "%12d %12d ", | ||
1461 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00000800) >> 11, | ||
1462 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00001000) >> 12); | ||
1463 | len += snprintf(buf + len, size - len, "%12d %12d ", | ||
1464 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x0001e000) >> 13, | ||
1465 | (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x001e0000) >> 17); | ||
1466 | len += snprintf(buf + len, size - len, "0x%07x 0x%07x\n", | ||
1467 | ATH_SAMP_DBG(pcu_obs), ATH_SAMP_DBG(pcu_cr)); | ||
1468 | } | ||
1469 | |||
1470 | len += snprintf(buf + len, size - len, | ||
1471 | "Sample ChNoise Chain privNF #Reading Readings\n"); | ||
1472 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1473 | h = ATH_SAMP_DBG(nfCalHist); | ||
1474 | if (!ATH_SAMP_DBG(noise)) | ||
1475 | continue; | ||
1476 | |||
1477 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
1478 | if (!(chainmask & (1 << i)) || | ||
1479 | ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))) | ||
1480 | continue; | ||
1481 | |||
1482 | nread = AR_PHY_CCA_FILTERWINDOW_LENGTH - | ||
1483 | h[i].invalidNFcount; | ||
1484 | len += snprintf(buf + len, size - len, | ||
1485 | "%4d %5d %4d\t %d\t %d\t", | ||
1486 | sampidx, ATH_SAMP_DBG(noise), | ||
1487 | i, h[i].privNF, nread); | ||
1488 | for (j = 0; j < nread; j++) | ||
1489 | len += snprintf(buf + len, size - len, | ||
1490 | " %d", h[i].nfCalBuffer[j]); | ||
1491 | len += snprintf(buf + len, size - len, "\n"); | ||
1492 | } | ||
1493 | } | ||
1494 | len += snprintf(buf + len, size - len, "\nCycle counters:\n" | ||
1495 | "Sample Total Rxbusy Rxframes Txframes\n"); | ||
1496 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1497 | if (!ATH_SAMP_DBG(cc.cycles)) | ||
1498 | continue; | ||
1499 | len += snprintf(buf + len, size - len, | ||
1500 | "%4d %08x %08x %08x %08x\n", | ||
1501 | sampidx, ATH_SAMP_DBG(cc.cycles), | ||
1502 | ATH_SAMP_DBG(cc.rx_busy), | ||
1503 | ATH_SAMP_DBG(cc.rx_frame), | ||
1504 | ATH_SAMP_DBG(cc.tx_frame)); | ||
1505 | } | ||
1506 | |||
1507 | len += snprintf(buf + len, size - len, "Tx status Dump :\n"); | ||
1508 | len += snprintf(buf + len, size - len, | ||
1509 | "Sample rssi:- ctl0 ctl1 ctl2 ext0 ext1 ext2 comb " | ||
1510 | "isok rts_fail data_fail rate tid qid tx_before(ms)\n"); | ||
1511 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1512 | for (i = 0; i < ATH_DBG_MAX_SAMPLES; i++) { | ||
1513 | if (!ATH_SAMP_DBG(ts[i].jiffies)) | ||
1514 | continue; | ||
1515 | len += snprintf(buf + len, size - len, "%4d \t" | ||
1516 | "%8d %4d %4d %4d %4d %4d %4d %4d %4d " | ||
1517 | "%4d %4d %2d %2d %d\n", | ||
1518 | sampidx, | ||
1519 | ATH_SAMP_DBG(ts[i].rssi_ctl0), | ||
1520 | ATH_SAMP_DBG(ts[i].rssi_ctl1), | ||
1521 | ATH_SAMP_DBG(ts[i].rssi_ctl2), | ||
1522 | ATH_SAMP_DBG(ts[i].rssi_ext0), | ||
1523 | ATH_SAMP_DBG(ts[i].rssi_ext1), | ||
1524 | ATH_SAMP_DBG(ts[i].rssi_ext2), | ||
1525 | ATH_SAMP_DBG(ts[i].rssi), | ||
1526 | ATH_SAMP_DBG(ts[i].isok), | ||
1527 | ATH_SAMP_DBG(ts[i].rts_fail_cnt), | ||
1528 | ATH_SAMP_DBG(ts[i].data_fail_cnt), | ||
1529 | ATH_SAMP_DBG(ts[i].rateindex), | ||
1530 | ATH_SAMP_DBG(ts[i].tid), | ||
1531 | ATH_SAMP_DBG(ts[i].qid), | ||
1532 | jiffies_to_msecs(jiffies - | ||
1533 | ATH_SAMP_DBG(ts[i].jiffies))); | ||
1534 | } | ||
1535 | } | ||
1536 | |||
1537 | len += snprintf(buf + len, size - len, "Rx status Dump :\n"); | ||
1538 | len += snprintf(buf + len, size - len, "Sample rssi:- ctl0 ctl1 ctl2 " | ||
1539 | "ext0 ext1 ext2 comb beacon ant rate rx_before(ms)\n"); | ||
1540 | for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) { | ||
1541 | for (i = 0; i < ATH_DBG_MAX_SAMPLES; i++) { | ||
1542 | if (!ATH_SAMP_DBG(rs[i].jiffies)) | ||
1543 | continue; | ||
1544 | len += snprintf(buf + len, size - len, "%4d \t" | ||
1545 | "%8d %4d %4d %4d %4d %4d %4d %s %4d %02x %d\n", | ||
1546 | sampidx, | ||
1547 | ATH_SAMP_DBG(rs[i].rssi_ctl0), | ||
1548 | ATH_SAMP_DBG(rs[i].rssi_ctl1), | ||
1549 | ATH_SAMP_DBG(rs[i].rssi_ctl2), | ||
1550 | ATH_SAMP_DBG(rs[i].rssi_ext0), | ||
1551 | ATH_SAMP_DBG(rs[i].rssi_ext1), | ||
1552 | ATH_SAMP_DBG(rs[i].rssi_ext2), | ||
1553 | ATH_SAMP_DBG(rs[i].rssi), | ||
1554 | ATH_SAMP_DBG(rs[i].is_mybeacon) ? | ||
1555 | "True" : "False", | ||
1556 | ATH_SAMP_DBG(rs[i].antenna), | ||
1557 | ATH_SAMP_DBG(rs[i].rate), | ||
1558 | jiffies_to_msecs(jiffies - | ||
1559 | ATH_SAMP_DBG(rs[i].jiffies))); | ||
1560 | } | ||
1561 | } | ||
1562 | |||
1563 | vfree(bb_mac_samp); | ||
1564 | file->private_data = buf; | ||
1565 | |||
1566 | return 0; | ||
1567 | #undef ATH_SAMP_DBG | ||
1568 | } | ||
1569 | |||
1570 | static const struct file_operations fops_samps = { | ||
1571 | .open = open_file_bb_mac_samps, | ||
1572 | .read = ath9k_debugfs_read_buf, | ||
1573 | .release = ath9k_debugfs_release_buf, | ||
1574 | .owner = THIS_MODULE, | ||
1575 | .llseek = default_llseek, | ||
1576 | }; | ||
1577 | |||
1578 | |||
1275 | int ath9k_init_debug(struct ath_hw *ah) | 1579 | int ath9k_init_debug(struct ath_hw *ah) |
1276 | { | 1580 | { |
1277 | struct ath_common *common = ath9k_hw_common(ah); | 1581 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -1321,6 +1625,8 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1321 | &fops_base_eeprom); | 1625 | &fops_base_eeprom); |
1322 | debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, | 1626 | debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, |
1323 | &fops_modal_eeprom); | 1627 | &fops_modal_eeprom); |
1628 | debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, | ||
1629 | &fops_samps); | ||
1324 | 1630 | ||
1325 | debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, | 1631 | debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, |
1326 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); | 1632 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); |
@@ -1329,5 +1635,9 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1329 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); | 1635 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); |
1330 | 1636 | ||
1331 | sc->debug.regidx = 0; | 1637 | sc->debug.regidx = 0; |
1638 | memset(&sc->debug.bb_mac_samp, 0, sizeof(sc->debug.bb_mac_samp)); | ||
1639 | sc->debug.sampidx = 0; | ||
1640 | sc->debug.tsidx = 0; | ||
1641 | sc->debug.rsidx = 0; | ||
1332 | return 0; | 1642 | return 0; |
1333 | } | 1643 | } |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 4a04510e1111..95f85bdc8db7 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -177,14 +177,57 @@ struct ath_stats { | |||
177 | struct ath_rx_stats rxstats; | 177 | struct ath_rx_stats rxstats; |
178 | }; | 178 | }; |
179 | 179 | ||
180 | #define ATH_DBG_MAX_SAMPLES 10 | ||
181 | struct ath_dbg_bb_mac_samp { | ||
182 | u32 dma_dbg_reg_vals[ATH9K_NUM_DMA_DEBUG_REGS]; | ||
183 | u32 pcu_obs, pcu_cr, noise; | ||
184 | struct { | ||
185 | u64 jiffies; | ||
186 | int8_t rssi_ctl0; | ||
187 | int8_t rssi_ctl1; | ||
188 | int8_t rssi_ctl2; | ||
189 | int8_t rssi_ext0; | ||
190 | int8_t rssi_ext1; | ||
191 | int8_t rssi_ext2; | ||
192 | int8_t rssi; | ||
193 | bool isok; | ||
194 | u8 rts_fail_cnt; | ||
195 | u8 data_fail_cnt; | ||
196 | u8 rateindex; | ||
197 | u8 qid; | ||
198 | u8 tid; | ||
199 | } ts[ATH_DBG_MAX_SAMPLES]; | ||
200 | struct { | ||
201 | u64 jiffies; | ||
202 | int8_t rssi_ctl0; | ||
203 | int8_t rssi_ctl1; | ||
204 | int8_t rssi_ctl2; | ||
205 | int8_t rssi_ext0; | ||
206 | int8_t rssi_ext1; | ||
207 | int8_t rssi_ext2; | ||
208 | int8_t rssi; | ||
209 | bool is_mybeacon; | ||
210 | u8 antenna; | ||
211 | u8 rate; | ||
212 | } rs[ATH_DBG_MAX_SAMPLES]; | ||
213 | struct ath_cycle_counters cc; | ||
214 | struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; | ||
215 | }; | ||
216 | |||
180 | struct ath9k_debug { | 217 | struct ath9k_debug { |
181 | struct dentry *debugfs_phy; | 218 | struct dentry *debugfs_phy; |
182 | u32 regidx; | 219 | u32 regidx; |
183 | struct ath_stats stats; | 220 | struct ath_stats stats; |
221 | spinlock_t samp_lock; | ||
222 | struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES]; | ||
223 | u8 sampidx; | ||
224 | u8 tsidx; | ||
225 | u8 rsidx; | ||
184 | }; | 226 | }; |
185 | 227 | ||
186 | int ath9k_init_debug(struct ath_hw *ah); | 228 | int ath9k_init_debug(struct ath_hw *ah); |
187 | 229 | ||
230 | void ath9k_debug_samp_bb_mac(struct ath_softc *sc); | ||
188 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); | 231 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); |
189 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | 232 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, |
190 | struct ath_tx_status *ts, struct ath_txq *txq); | 233 | struct ath_tx_status *ts, struct ath_txq *txq); |
@@ -197,6 +240,10 @@ static inline int ath9k_init_debug(struct ath_hw *ah) | |||
197 | return 0; | 240 | return 0; |
198 | } | 241 | } |
199 | 242 | ||
243 | static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc) | ||
244 | { | ||
245 | } | ||
246 | |||
200 | static inline void ath_debug_stat_interrupt(struct ath_softc *sc, | 247 | static inline void ath_debug_stat_interrupt(struct ath_softc *sc, |
201 | enum ath9k_int status) | 248 | enum ath9k_int status) |
202 | { | 249 | { |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d7761d1fc5ba..dd71a5f77516 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -572,6 +572,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
572 | mutex_init(&sc->mutex); | 572 | mutex_init(&sc->mutex); |
573 | #ifdef CONFIG_ATH9K_DEBUGFS | 573 | #ifdef CONFIG_ATH9K_DEBUGFS |
574 | spin_lock_init(&sc->nodes_lock); | 574 | spin_lock_init(&sc->nodes_lock); |
575 | spin_lock_init(&sc->debug.samp_lock); | ||
575 | INIT_LIST_HEAD(&sc->nodes); | 576 | INIT_LIST_HEAD(&sc->nodes); |
576 | #endif | 577 | #endif |
577 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | 578 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 153859ccc2a1..2c43e13da002 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -146,6 +146,7 @@ struct ath_rx_status { | |||
146 | u8 rs_moreaggr; | 146 | u8 rs_moreaggr; |
147 | u8 rs_num_delims; | 147 | u8 rs_num_delims; |
148 | u8 rs_flags; | 148 | u8 rs_flags; |
149 | bool is_mybeacon; | ||
149 | u32 evm0; | 150 | u32 evm0; |
150 | u32 evm1; | 151 | u32 evm1; |
151 | u32 evm2; | 152 | u32 evm2; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5ac4f3f2ad60..7b7864dfab75 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -546,6 +546,7 @@ set_timer: | |||
546 | * The interval must be the shortest necessary to satisfy ANI, | 546 | * The interval must be the shortest necessary to satisfy ANI, |
547 | * short calibration and long calibration. | 547 | * short calibration and long calibration. |
548 | */ | 548 | */ |
549 | ath9k_debug_samp_bb_mac(sc); | ||
549 | cal_interval = ATH_LONG_CALINTERVAL; | 550 | cal_interval = ATH_LONG_CALINTERVAL; |
550 | if (sc->sc_ah->config.enable_ani) | 551 | if (sc->sc_ah->config.enable_ani) |
551 | cal_interval = min(cal_interval, | 552 | cal_interval = min(cal_interval, |
@@ -978,6 +979,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
978 | 979 | ||
979 | sc->hw_busy_count = 0; | 980 | sc->hw_busy_count = 0; |
980 | 981 | ||
982 | ath9k_debug_samp_bb_mac(sc); | ||
981 | /* Stop ANI */ | 983 | /* Stop ANI */ |
982 | 984 | ||
983 | del_timer_sync(&common->ani.timer); | 985 | del_timer_sync(&common->ani.timer); |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 800e9ee7e035..9c7f905f3871 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -952,23 +952,12 @@ static void ath9k_process_rssi(struct ath_common *common, | |||
952 | struct ath_softc *sc = hw->priv; | 952 | struct ath_softc *sc = hw->priv; |
953 | struct ath_hw *ah = common->ah; | 953 | struct ath_hw *ah = common->ah; |
954 | int last_rssi; | 954 | int last_rssi; |
955 | __le16 fc; | ||
956 | 955 | ||
957 | if ((ah->opmode != NL80211_IFTYPE_STATION) && | 956 | if (!rx_stats->is_mybeacon || |
958 | (ah->opmode != NL80211_IFTYPE_ADHOC)) | 957 | ((ah->opmode != NL80211_IFTYPE_STATION) && |
958 | (ah->opmode != NL80211_IFTYPE_ADHOC))) | ||
959 | return; | 959 | return; |
960 | 960 | ||
961 | fc = hdr->frame_control; | ||
962 | if (!ieee80211_is_beacon(fc) || | ||
963 | compare_ether_addr(hdr->addr3, common->curbssid)) { | ||
964 | /* TODO: This doesn't work well if you have stations | ||
965 | * associated to two different APs because curbssid | ||
966 | * is just the last AP that any of the stations associated | ||
967 | * with. | ||
968 | */ | ||
969 | return; | ||
970 | } | ||
971 | |||
972 | if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr) | 961 | if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr) |
973 | ATH_RSSI_LPF(sc->last_rssi, rx_stats->rs_rssi); | 962 | ATH_RSSI_LPF(sc->last_rssi, rx_stats->rs_rssi); |
974 | 963 | ||
@@ -1838,6 +1827,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1838 | 1827 | ||
1839 | hdr = (struct ieee80211_hdr *) (hdr_skb->data + rx_status_len); | 1828 | hdr = (struct ieee80211_hdr *) (hdr_skb->data + rx_status_len); |
1840 | rxs = IEEE80211_SKB_RXCB(hdr_skb); | 1829 | rxs = IEEE80211_SKB_RXCB(hdr_skb); |
1830 | if (ieee80211_is_beacon(hdr->frame_control) && | ||
1831 | !compare_ether_addr(hdr->addr3, common->curbssid)) | ||
1832 | rs.is_mybeacon = true; | ||
1833 | else | ||
1834 | rs.is_mybeacon = false; | ||
1841 | 1835 | ||
1842 | ath_debug_stat_rx(sc, &rs); | 1836 | ath_debug_stat_rx(sc, &rs); |
1843 | 1837 | ||