18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (c) 2008-2011 Atheros Communications Inc. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission to use, copy, modify, and/or distribute this software for any 58c2ecf20Sopenharmony_ci * purpose with or without fee is hereby granted, provided that the above 68c2ecf20Sopenharmony_ci * copyright notice and this permission notice appear in all copies. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 98c2ecf20Sopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 108c2ecf20Sopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 118c2ecf20Sopenharmony_ci * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 128c2ecf20Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 138c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 148c2ecf20Sopenharmony_ci * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include "common.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf, 208c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 218c2ecf20Sopenharmony_ci{ 228c2ecf20Sopenharmony_ci struct ath_hw *ah = file->private_data; 238c2ecf20Sopenharmony_ci u32 len = 0, size = 6000; 248c2ecf20Sopenharmony_ci char *buf; 258c2ecf20Sopenharmony_ci size_t retval; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci buf = kzalloc(size, GFP_KERNEL); 288c2ecf20Sopenharmony_ci if (buf == NULL) 298c2ecf20Sopenharmony_ci return -ENOMEM; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci len = ah->eep_ops->dump_eeprom(ah, false, buf, len, size); 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 348c2ecf20Sopenharmony_ci kfree(buf); 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci return retval; 378c2ecf20Sopenharmony_ci} 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cistatic const struct file_operations fops_modal_eeprom = { 408c2ecf20Sopenharmony_ci .read = read_file_modal_eeprom, 418c2ecf20Sopenharmony_ci .open = simple_open, 428c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 438c2ecf20Sopenharmony_ci .llseek = default_llseek, 448c2ecf20Sopenharmony_ci}; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_civoid ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy, 488c2ecf20Sopenharmony_ci struct ath_hw *ah) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci debugfs_create_file("modal_eeprom", 0400, debugfs_phy, ah, 518c2ecf20Sopenharmony_ci &fops_modal_eeprom); 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_modal_eeprom); 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistatic ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, 568c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci struct ath_hw *ah = file->private_data; 598c2ecf20Sopenharmony_ci u32 len = 0, size = 1500; 608c2ecf20Sopenharmony_ci ssize_t retval = 0; 618c2ecf20Sopenharmony_ci char *buf; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci buf = kzalloc(size, GFP_KERNEL); 648c2ecf20Sopenharmony_ci if (!buf) 658c2ecf20Sopenharmony_ci return -ENOMEM; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci len = ah->eep_ops->dump_eeprom(ah, true, buf, len, size); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 708c2ecf20Sopenharmony_ci kfree(buf); 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci return retval; 738c2ecf20Sopenharmony_ci} 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic const struct file_operations fops_base_eeprom = { 768c2ecf20Sopenharmony_ci .read = read_file_base_eeprom, 778c2ecf20Sopenharmony_ci .open = simple_open, 788c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 798c2ecf20Sopenharmony_ci .llseek = default_llseek, 808c2ecf20Sopenharmony_ci}; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_civoid ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy, 838c2ecf20Sopenharmony_ci struct ath_hw *ah) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci debugfs_create_file("base_eeprom", 0400, debugfs_phy, ah, 868c2ecf20Sopenharmony_ci &fops_base_eeprom); 878c2ecf20Sopenharmony_ci} 888c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_base_eeprom); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_civoid ath9k_cmn_debug_stat_rx(struct ath_rx_stats *rxstats, 918c2ecf20Sopenharmony_ci struct ath_rx_status *rs) 928c2ecf20Sopenharmony_ci{ 938c2ecf20Sopenharmony_ci#define RX_PHY_ERR_INC(c) rxstats->phy_err_stats[c]++ 948c2ecf20Sopenharmony_ci#define RX_CMN_STAT_INC(c) (rxstats->c++) 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci RX_CMN_STAT_INC(rx_pkts_all); 978c2ecf20Sopenharmony_ci rxstats->rx_bytes_all += rs->rs_datalen; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci if (rs->rs_status & ATH9K_RXERR_CRC) 1008c2ecf20Sopenharmony_ci RX_CMN_STAT_INC(crc_err); 1018c2ecf20Sopenharmony_ci if (rs->rs_status & ATH9K_RXERR_DECRYPT) 1028c2ecf20Sopenharmony_ci RX_CMN_STAT_INC(decrypt_crc_err); 1038c2ecf20Sopenharmony_ci if (rs->rs_status & ATH9K_RXERR_MIC) 1048c2ecf20Sopenharmony_ci RX_CMN_STAT_INC(mic_err); 1058c2ecf20Sopenharmony_ci if (rs->rs_status & ATH9K_RX_DELIM_CRC_PRE) 1068c2ecf20Sopenharmony_ci RX_CMN_STAT_INC(pre_delim_crc_err); 1078c2ecf20Sopenharmony_ci if (rs->rs_status & ATH9K_RX_DELIM_CRC_POST) 1088c2ecf20Sopenharmony_ci RX_CMN_STAT_INC(post_delim_crc_err); 1098c2ecf20Sopenharmony_ci if (rs->rs_status & ATH9K_RX_DECRYPT_BUSY) 1108c2ecf20Sopenharmony_ci RX_CMN_STAT_INC(decrypt_busy_err); 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci if (rs->rs_status & ATH9K_RXERR_PHY) { 1138c2ecf20Sopenharmony_ci RX_CMN_STAT_INC(phy_err); 1148c2ecf20Sopenharmony_ci if (rs->rs_phyerr < ATH9K_PHYERR_MAX) 1158c2ecf20Sopenharmony_ci RX_PHY_ERR_INC(rs->rs_phyerr); 1168c2ecf20Sopenharmony_ci } 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci#undef RX_CMN_STAT_INC 1198c2ecf20Sopenharmony_ci#undef RX_PHY_ERR_INC 1208c2ecf20Sopenharmony_ci} 1218c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_stat_rx); 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cistatic ssize_t read_file_recv(struct file *file, char __user *user_buf, 1248c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 1258c2ecf20Sopenharmony_ci{ 1268c2ecf20Sopenharmony_ci#define RXS_ERR(s, e) \ 1278c2ecf20Sopenharmony_ci do { \ 1288c2ecf20Sopenharmony_ci len += scnprintf(buf + len, size - len, \ 1298c2ecf20Sopenharmony_ci "%18s : %10u\n", s, \ 1308c2ecf20Sopenharmony_ci rxstats->e); \ 1318c2ecf20Sopenharmony_ci } while (0) 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci struct ath_rx_stats *rxstats = file->private_data; 1348c2ecf20Sopenharmony_ci char *buf; 1358c2ecf20Sopenharmony_ci unsigned int len = 0, size = 1600; 1368c2ecf20Sopenharmony_ci ssize_t retval = 0; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci buf = kzalloc(size, GFP_KERNEL); 1398c2ecf20Sopenharmony_ci if (buf == NULL) 1408c2ecf20Sopenharmony_ci return -ENOMEM; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci RXS_ERR("PKTS-ALL", rx_pkts_all); 1438c2ecf20Sopenharmony_ci RXS_ERR("BYTES-ALL", rx_bytes_all); 1448c2ecf20Sopenharmony_ci RXS_ERR("BEACONS", rx_beacons); 1458c2ecf20Sopenharmony_ci RXS_ERR("FRAGS", rx_frags); 1468c2ecf20Sopenharmony_ci RXS_ERR("SPECTRAL", rx_spectral); 1478c2ecf20Sopenharmony_ci RXS_ERR("SPECTRAL SMPL GOOD", rx_spectral_sample_good); 1488c2ecf20Sopenharmony_ci RXS_ERR("SPECTRAL SMPL ERR", rx_spectral_sample_err); 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci RXS_ERR("CRC ERR", crc_err); 1518c2ecf20Sopenharmony_ci RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err); 1528c2ecf20Sopenharmony_ci RXS_ERR("PHY ERR", phy_err); 1538c2ecf20Sopenharmony_ci RXS_ERR("MIC ERR", mic_err); 1548c2ecf20Sopenharmony_ci RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err); 1558c2ecf20Sopenharmony_ci RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err); 1568c2ecf20Sopenharmony_ci RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err); 1578c2ecf20Sopenharmony_ci RXS_ERR("LENGTH-ERR", rx_len_err); 1588c2ecf20Sopenharmony_ci RXS_ERR("OOM-ERR", rx_oom_err); 1598c2ecf20Sopenharmony_ci RXS_ERR("RATE-ERR", rx_rate_err); 1608c2ecf20Sopenharmony_ci RXS_ERR("TOO-MANY-FRAGS", rx_too_many_frags_err); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci if (len > size) 1638c2ecf20Sopenharmony_ci len = size; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 1668c2ecf20Sopenharmony_ci kfree(buf); 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci return retval; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci#undef RXS_ERR 1718c2ecf20Sopenharmony_ci} 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_cistatic const struct file_operations fops_recv = { 1748c2ecf20Sopenharmony_ci .read = read_file_recv, 1758c2ecf20Sopenharmony_ci .open = simple_open, 1768c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 1778c2ecf20Sopenharmony_ci .llseek = default_llseek, 1788c2ecf20Sopenharmony_ci}; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_civoid ath9k_cmn_debug_recv(struct dentry *debugfs_phy, 1818c2ecf20Sopenharmony_ci struct ath_rx_stats *rxstats) 1828c2ecf20Sopenharmony_ci{ 1838c2ecf20Sopenharmony_ci debugfs_create_file("recv", 0400, debugfs_phy, rxstats, &fops_recv); 1848c2ecf20Sopenharmony_ci} 1858c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_recv); 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_cistatic ssize_t read_file_phy_err(struct file *file, char __user *user_buf, 1888c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 1898c2ecf20Sopenharmony_ci{ 1908c2ecf20Sopenharmony_ci#define PHY_ERR(s, p) \ 1918c2ecf20Sopenharmony_ci len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \ 1928c2ecf20Sopenharmony_ci rxstats->phy_err_stats[p]); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci struct ath_rx_stats *rxstats = file->private_data; 1958c2ecf20Sopenharmony_ci char *buf; 1968c2ecf20Sopenharmony_ci unsigned int len = 0, size = 1600; 1978c2ecf20Sopenharmony_ci ssize_t retval = 0; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci buf = kzalloc(size, GFP_KERNEL); 2008c2ecf20Sopenharmony_ci if (buf == NULL) 2018c2ecf20Sopenharmony_ci return -ENOMEM; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); 2048c2ecf20Sopenharmony_ci PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING); 2058c2ecf20Sopenharmony_ci PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY); 2068c2ecf20Sopenharmony_ci PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE); 2078c2ecf20Sopenharmony_ci PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH); 2088c2ecf20Sopenharmony_ci PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR); 2098c2ecf20Sopenharmony_ci PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE); 2108c2ecf20Sopenharmony_ci PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR); 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING); 2138c2ecf20Sopenharmony_ci PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); 2148c2ecf20Sopenharmony_ci PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); 2158c2ecf20Sopenharmony_ci PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); 2168c2ecf20Sopenharmony_ci PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP); 2178c2ecf20Sopenharmony_ci PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE); 2188c2ecf20Sopenharmony_ci PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci PHY_ERR("CCK-BLOCKER ERR", ATH9K_PHYERR_CCK_BLOCKER); 2218c2ecf20Sopenharmony_ci PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING); 2228c2ecf20Sopenharmony_ci PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC); 2238c2ecf20Sopenharmony_ci PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL); 2248c2ecf20Sopenharmony_ci PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); 2258c2ecf20Sopenharmony_ci PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP); 2268c2ecf20Sopenharmony_ci PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE); 2278c2ecf20Sopenharmony_ci PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART); 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR); 2308c2ecf20Sopenharmony_ci PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); 2318c2ecf20Sopenharmony_ci PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); 2328c2ecf20Sopenharmony_ci PHY_ERR("HT-ZLF ERR", ATH9K_PHYERR_HT_ZLF); 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT); 2358c2ecf20Sopenharmony_ci PHY_ERR("GREEN-FIELD ERR", ATH9K_PHYERR_GREEN_FIELD); 2368c2ecf20Sopenharmony_ci PHY_ERR("SPECTRAL ERR", ATH9K_PHYERR_SPECTRAL); 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci if (len > size) 2398c2ecf20Sopenharmony_ci len = size; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 2428c2ecf20Sopenharmony_ci kfree(buf); 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci return retval; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci#undef PHY_ERR 2478c2ecf20Sopenharmony_ci} 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cistatic const struct file_operations fops_phy_err = { 2508c2ecf20Sopenharmony_ci .read = read_file_phy_err, 2518c2ecf20Sopenharmony_ci .open = simple_open, 2528c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 2538c2ecf20Sopenharmony_ci .llseek = default_llseek, 2548c2ecf20Sopenharmony_ci}; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_civoid ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy, 2578c2ecf20Sopenharmony_ci struct ath_rx_stats *rxstats) 2588c2ecf20Sopenharmony_ci{ 2598c2ecf20Sopenharmony_ci debugfs_create_file("phy_err", 0400, debugfs_phy, rxstats, 2608c2ecf20Sopenharmony_ci &fops_phy_err); 2618c2ecf20Sopenharmony_ci} 2628c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_phy_err); 263