162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright (c) 2008-2011 Atheros Communications Inc. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Permission to use, copy, modify, and/or distribute this software for any 562306a36Sopenharmony_ci * purpose with or without fee is hereby granted, provided that the above 662306a36Sopenharmony_ci * copyright notice and this permission notice appear in all copies. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 962306a36Sopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1062306a36Sopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1162306a36Sopenharmony_ci * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1262306a36Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1362306a36Sopenharmony_ci * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1462306a36Sopenharmony_ci * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include "common.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistatic ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf, 2062306a36Sopenharmony_ci size_t count, loff_t *ppos) 2162306a36Sopenharmony_ci{ 2262306a36Sopenharmony_ci struct ath_hw *ah = file->private_data; 2362306a36Sopenharmony_ci u32 len = 0, size = 6000; 2462306a36Sopenharmony_ci char *buf; 2562306a36Sopenharmony_ci size_t retval; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci buf = kzalloc(size, GFP_KERNEL); 2862306a36Sopenharmony_ci if (buf == NULL) 2962306a36Sopenharmony_ci return -ENOMEM; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci len = ah->eep_ops->dump_eeprom(ah, false, buf, len, size); 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 3462306a36Sopenharmony_ci kfree(buf); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci return retval; 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic const struct file_operations fops_modal_eeprom = { 4062306a36Sopenharmony_ci .read = read_file_modal_eeprom, 4162306a36Sopenharmony_ci .open = simple_open, 4262306a36Sopenharmony_ci .owner = THIS_MODULE, 4362306a36Sopenharmony_ci .llseek = default_llseek, 4462306a36Sopenharmony_ci}; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_civoid ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy, 4862306a36Sopenharmony_ci struct ath_hw *ah) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci debugfs_create_file("modal_eeprom", 0400, debugfs_phy, ah, 5162306a36Sopenharmony_ci &fops_modal_eeprom); 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_modal_eeprom); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistatic ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, 5662306a36Sopenharmony_ci size_t count, loff_t *ppos) 5762306a36Sopenharmony_ci{ 5862306a36Sopenharmony_ci struct ath_hw *ah = file->private_data; 5962306a36Sopenharmony_ci u32 len = 0, size = 1500; 6062306a36Sopenharmony_ci ssize_t retval = 0; 6162306a36Sopenharmony_ci char *buf; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci buf = kzalloc(size, GFP_KERNEL); 6462306a36Sopenharmony_ci if (!buf) 6562306a36Sopenharmony_ci return -ENOMEM; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci len = ah->eep_ops->dump_eeprom(ah, true, buf, len, size); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 7062306a36Sopenharmony_ci kfree(buf); 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci return retval; 7362306a36Sopenharmony_ci} 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic const struct file_operations fops_base_eeprom = { 7662306a36Sopenharmony_ci .read = read_file_base_eeprom, 7762306a36Sopenharmony_ci .open = simple_open, 7862306a36Sopenharmony_ci .owner = THIS_MODULE, 7962306a36Sopenharmony_ci .llseek = default_llseek, 8062306a36Sopenharmony_ci}; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_civoid ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy, 8362306a36Sopenharmony_ci struct ath_hw *ah) 8462306a36Sopenharmony_ci{ 8562306a36Sopenharmony_ci debugfs_create_file("base_eeprom", 0400, debugfs_phy, ah, 8662306a36Sopenharmony_ci &fops_base_eeprom); 8762306a36Sopenharmony_ci} 8862306a36Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_base_eeprom); 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_civoid ath9k_cmn_debug_stat_rx(struct ath_rx_stats *rxstats, 9162306a36Sopenharmony_ci struct ath_rx_status *rs) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci#define RX_PHY_ERR_INC(c) rxstats->phy_err_stats[c]++ 9462306a36Sopenharmony_ci#define RX_CMN_STAT_INC(c) (rxstats->c++) 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci RX_CMN_STAT_INC(rx_pkts_all); 9762306a36Sopenharmony_ci rxstats->rx_bytes_all += rs->rs_datalen; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci if (rs->rs_status & ATH9K_RXERR_CRC) 10062306a36Sopenharmony_ci RX_CMN_STAT_INC(crc_err); 10162306a36Sopenharmony_ci if (rs->rs_status & ATH9K_RXERR_DECRYPT) 10262306a36Sopenharmony_ci RX_CMN_STAT_INC(decrypt_crc_err); 10362306a36Sopenharmony_ci if (rs->rs_status & ATH9K_RXERR_MIC) 10462306a36Sopenharmony_ci RX_CMN_STAT_INC(mic_err); 10562306a36Sopenharmony_ci if (rs->rs_status & ATH9K_RX_DELIM_CRC_PRE) 10662306a36Sopenharmony_ci RX_CMN_STAT_INC(pre_delim_crc_err); 10762306a36Sopenharmony_ci if (rs->rs_status & ATH9K_RX_DELIM_CRC_POST) 10862306a36Sopenharmony_ci RX_CMN_STAT_INC(post_delim_crc_err); 10962306a36Sopenharmony_ci if (rs->rs_status & ATH9K_RX_DECRYPT_BUSY) 11062306a36Sopenharmony_ci RX_CMN_STAT_INC(decrypt_busy_err); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci if (rs->rs_status & ATH9K_RXERR_PHY) { 11362306a36Sopenharmony_ci RX_CMN_STAT_INC(phy_err); 11462306a36Sopenharmony_ci if (rs->rs_phyerr < ATH9K_PHYERR_MAX) 11562306a36Sopenharmony_ci RX_PHY_ERR_INC(rs->rs_phyerr); 11662306a36Sopenharmony_ci } 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci#undef RX_CMN_STAT_INC 11962306a36Sopenharmony_ci#undef RX_PHY_ERR_INC 12062306a36Sopenharmony_ci} 12162306a36Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_stat_rx); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_cistatic ssize_t read_file_recv(struct file *file, char __user *user_buf, 12462306a36Sopenharmony_ci size_t count, loff_t *ppos) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci#define RXS_ERR(s, e) \ 12762306a36Sopenharmony_ci do { \ 12862306a36Sopenharmony_ci len += scnprintf(buf + len, size - len, \ 12962306a36Sopenharmony_ci "%18s : %10u\n", s, \ 13062306a36Sopenharmony_ci rxstats->e); \ 13162306a36Sopenharmony_ci } while (0) 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci struct ath_rx_stats *rxstats = file->private_data; 13462306a36Sopenharmony_ci char *buf; 13562306a36Sopenharmony_ci unsigned int len = 0, size = 1600; 13662306a36Sopenharmony_ci ssize_t retval = 0; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci buf = kzalloc(size, GFP_KERNEL); 13962306a36Sopenharmony_ci if (buf == NULL) 14062306a36Sopenharmony_ci return -ENOMEM; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci RXS_ERR("PKTS-ALL", rx_pkts_all); 14362306a36Sopenharmony_ci RXS_ERR("BYTES-ALL", rx_bytes_all); 14462306a36Sopenharmony_ci RXS_ERR("BEACONS", rx_beacons); 14562306a36Sopenharmony_ci RXS_ERR("FRAGS", rx_frags); 14662306a36Sopenharmony_ci RXS_ERR("SPECTRAL", rx_spectral); 14762306a36Sopenharmony_ci RXS_ERR("SPECTRAL SMPL GOOD", rx_spectral_sample_good); 14862306a36Sopenharmony_ci RXS_ERR("SPECTRAL SMPL ERR", rx_spectral_sample_err); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci RXS_ERR("CRC ERR", crc_err); 15162306a36Sopenharmony_ci RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err); 15262306a36Sopenharmony_ci RXS_ERR("PHY ERR", phy_err); 15362306a36Sopenharmony_ci RXS_ERR("MIC ERR", mic_err); 15462306a36Sopenharmony_ci RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err); 15562306a36Sopenharmony_ci RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err); 15662306a36Sopenharmony_ci RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err); 15762306a36Sopenharmony_ci RXS_ERR("LENGTH-ERR", rx_len_err); 15862306a36Sopenharmony_ci RXS_ERR("OOM-ERR", rx_oom_err); 15962306a36Sopenharmony_ci RXS_ERR("RATE-ERR", rx_rate_err); 16062306a36Sopenharmony_ci RXS_ERR("TOO-MANY-FRAGS", rx_too_many_frags_err); 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci if (len > size) 16362306a36Sopenharmony_ci len = size; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 16662306a36Sopenharmony_ci kfree(buf); 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci return retval; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci#undef RXS_ERR 17162306a36Sopenharmony_ci} 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_cistatic const struct file_operations fops_recv = { 17462306a36Sopenharmony_ci .read = read_file_recv, 17562306a36Sopenharmony_ci .open = simple_open, 17662306a36Sopenharmony_ci .owner = THIS_MODULE, 17762306a36Sopenharmony_ci .llseek = default_llseek, 17862306a36Sopenharmony_ci}; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_civoid ath9k_cmn_debug_recv(struct dentry *debugfs_phy, 18162306a36Sopenharmony_ci struct ath_rx_stats *rxstats) 18262306a36Sopenharmony_ci{ 18362306a36Sopenharmony_ci debugfs_create_file("recv", 0400, debugfs_phy, rxstats, &fops_recv); 18462306a36Sopenharmony_ci} 18562306a36Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_recv); 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_cistatic ssize_t read_file_phy_err(struct file *file, char __user *user_buf, 18862306a36Sopenharmony_ci size_t count, loff_t *ppos) 18962306a36Sopenharmony_ci{ 19062306a36Sopenharmony_ci#define PHY_ERR(s, p) \ 19162306a36Sopenharmony_ci len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \ 19262306a36Sopenharmony_ci rxstats->phy_err_stats[p]) 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci struct ath_rx_stats *rxstats = file->private_data; 19562306a36Sopenharmony_ci char *buf; 19662306a36Sopenharmony_ci unsigned int len = 0, size = 1600; 19762306a36Sopenharmony_ci ssize_t retval = 0; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci buf = kzalloc(size, GFP_KERNEL); 20062306a36Sopenharmony_ci if (buf == NULL) 20162306a36Sopenharmony_ci return -ENOMEM; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); 20462306a36Sopenharmony_ci PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING); 20562306a36Sopenharmony_ci PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY); 20662306a36Sopenharmony_ci PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE); 20762306a36Sopenharmony_ci PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH); 20862306a36Sopenharmony_ci PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR); 20962306a36Sopenharmony_ci PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE); 21062306a36Sopenharmony_ci PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING); 21362306a36Sopenharmony_ci PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); 21462306a36Sopenharmony_ci PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); 21562306a36Sopenharmony_ci PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); 21662306a36Sopenharmony_ci PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP); 21762306a36Sopenharmony_ci PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE); 21862306a36Sopenharmony_ci PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART); 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci PHY_ERR("CCK-BLOCKER ERR", ATH9K_PHYERR_CCK_BLOCKER); 22162306a36Sopenharmony_ci PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING); 22262306a36Sopenharmony_ci PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC); 22362306a36Sopenharmony_ci PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL); 22462306a36Sopenharmony_ci PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); 22562306a36Sopenharmony_ci PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP); 22662306a36Sopenharmony_ci PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE); 22762306a36Sopenharmony_ci PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR); 23062306a36Sopenharmony_ci PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); 23162306a36Sopenharmony_ci PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); 23262306a36Sopenharmony_ci PHY_ERR("HT-ZLF ERR", ATH9K_PHYERR_HT_ZLF); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT); 23562306a36Sopenharmony_ci PHY_ERR("GREEN-FIELD ERR", ATH9K_PHYERR_GREEN_FIELD); 23662306a36Sopenharmony_ci PHY_ERR("SPECTRAL ERR", ATH9K_PHYERR_SPECTRAL); 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci if (len > size) 23962306a36Sopenharmony_ci len = size; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 24262306a36Sopenharmony_ci kfree(buf); 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci return retval; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci#undef PHY_ERR 24762306a36Sopenharmony_ci} 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_cistatic const struct file_operations fops_phy_err = { 25062306a36Sopenharmony_ci .read = read_file_phy_err, 25162306a36Sopenharmony_ci .open = simple_open, 25262306a36Sopenharmony_ci .owner = THIS_MODULE, 25362306a36Sopenharmony_ci .llseek = default_llseek, 25462306a36Sopenharmony_ci}; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_civoid ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy, 25762306a36Sopenharmony_ci struct ath_rx_stats *rxstats) 25862306a36Sopenharmony_ci{ 25962306a36Sopenharmony_ci debugfs_create_file("phy_err", 0400, debugfs_phy, rxstats, 26062306a36Sopenharmony_ci &fops_phy_err); 26162306a36Sopenharmony_ci} 26262306a36Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_phy_err); 263