1 /* 2 * Copyright (c) 2008-2011 Atheros Communications Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <linux/export.h> 18 #include "common.h" 19 20 static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf, 21 size_t count, loff_t *ppos) 22 { 23 struct ath_hw *ah = file->private_data; 24 u32 len = 0, size = 6000; 25 char *buf; 26 size_t retval; 27 28 buf = kzalloc(size, GFP_KERNEL); 29 if (buf == NULL) 30 return -ENOMEM; 31 32 len = ah->eep_ops->dump_eeprom(ah, false, buf, len, size); 33 34 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 35 kfree(buf); 36 37 return retval; 38 } 39 40 static const struct file_operations fops_modal_eeprom = { 41 .read = read_file_modal_eeprom, 42 .open = simple_open, 43 .owner = THIS_MODULE, 44 .llseek = default_llseek, 45 }; 46 47 48 void ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy, 49 struct ath_hw *ah) 50 { 51 debugfs_create_file("modal_eeprom", 0400, debugfs_phy, ah, 52 &fops_modal_eeprom); 53 } 54 EXPORT_SYMBOL(ath9k_cmn_debug_modal_eeprom); 55 56 static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, 57 size_t count, loff_t *ppos) 58 { 59 struct ath_hw *ah = file->private_data; 60 u32 len = 0, size = 1500; 61 ssize_t retval = 0; 62 char *buf; 63 64 buf = kzalloc(size, GFP_KERNEL); 65 if (!buf) 66 return -ENOMEM; 67 68 len = ah->eep_ops->dump_eeprom(ah, true, buf, len, size); 69 70 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 71 kfree(buf); 72 73 return retval; 74 } 75 76 static const struct file_operations fops_base_eeprom = { 77 .read = read_file_base_eeprom, 78 .open = simple_open, 79 .owner = THIS_MODULE, 80 .llseek = default_llseek, 81 }; 82 83 void ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy, 84 struct ath_hw *ah) 85 { 86 debugfs_create_file("base_eeprom", 0400, debugfs_phy, ah, 87 &fops_base_eeprom); 88 } 89 EXPORT_SYMBOL(ath9k_cmn_debug_base_eeprom); 90 91 void ath9k_cmn_debug_stat_rx(struct ath_rx_stats *rxstats, 92 struct ath_rx_status *rs) 93 { 94 #define RX_PHY_ERR_INC(c) rxstats->phy_err_stats[c]++ 95 #define RX_CMN_STAT_INC(c) (rxstats->c++) 96 97 RX_CMN_STAT_INC(rx_pkts_all); 98 rxstats->rx_bytes_all += rs->rs_datalen; 99 100 if (rs->rs_status & ATH9K_RXERR_CRC) 101 RX_CMN_STAT_INC(crc_err); 102 if (rs->rs_status & ATH9K_RXERR_DECRYPT) 103 RX_CMN_STAT_INC(decrypt_crc_err); 104 if (rs->rs_status & ATH9K_RXERR_MIC) 105 RX_CMN_STAT_INC(mic_err); 106 if (rs->rs_status & ATH9K_RX_DELIM_CRC_PRE) 107 RX_CMN_STAT_INC(pre_delim_crc_err); 108 if (rs->rs_status & ATH9K_RX_DELIM_CRC_POST) 109 RX_CMN_STAT_INC(post_delim_crc_err); 110 if (rs->rs_status & ATH9K_RX_DECRYPT_BUSY) 111 RX_CMN_STAT_INC(decrypt_busy_err); 112 113 if (rs->rs_status & ATH9K_RXERR_PHY) { 114 RX_CMN_STAT_INC(phy_err); 115 if (rs->rs_phyerr < ATH9K_PHYERR_MAX) 116 RX_PHY_ERR_INC(rs->rs_phyerr); 117 } 118 119 #undef RX_CMN_STAT_INC 120 #undef RX_PHY_ERR_INC 121 } 122 EXPORT_SYMBOL(ath9k_cmn_debug_stat_rx); 123 124 static ssize_t read_file_recv(struct file *file, char __user *user_buf, 125 size_t count, loff_t *ppos) 126 { 127 #define RXS_ERR(s, e) \ 128 do { \ 129 len += scnprintf(buf + len, size - len, \ 130 "%18s : %10u\n", s, \ 131 rxstats->e); \ 132 } while (0) 133 134 struct ath_rx_stats *rxstats = file->private_data; 135 char *buf; 136 unsigned int len = 0, size = 1600; 137 ssize_t retval = 0; 138 139 buf = kzalloc(size, GFP_KERNEL); 140 if (buf == NULL) 141 return -ENOMEM; 142 143 RXS_ERR("PKTS-ALL", rx_pkts_all); 144 RXS_ERR("BYTES-ALL", rx_bytes_all); 145 RXS_ERR("BEACONS", rx_beacons); 146 RXS_ERR("FRAGS", rx_frags); 147 RXS_ERR("SPECTRAL", rx_spectral); 148 RXS_ERR("SPECTRAL SMPL GOOD", rx_spectral_sample_good); 149 RXS_ERR("SPECTRAL SMPL ERR", rx_spectral_sample_err); 150 151 RXS_ERR("CRC ERR", crc_err); 152 RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err); 153 RXS_ERR("PHY ERR", phy_err); 154 RXS_ERR("MIC ERR", mic_err); 155 RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err); 156 RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err); 157 RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err); 158 RXS_ERR("LENGTH-ERR", rx_len_err); 159 RXS_ERR("OOM-ERR", rx_oom_err); 160 RXS_ERR("RATE-ERR", rx_rate_err); 161 RXS_ERR("TOO-MANY-FRAGS", rx_too_many_frags_err); 162 163 if (len > size) 164 len = size; 165 166 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 167 kfree(buf); 168 169 return retval; 170 171 #undef RXS_ERR 172 } 173 174 static const struct file_operations fops_recv = { 175 .read = read_file_recv, 176 .open = simple_open, 177 .owner = THIS_MODULE, 178 .llseek = default_llseek, 179 }; 180 181 void ath9k_cmn_debug_recv(struct dentry *debugfs_phy, 182 struct ath_rx_stats *rxstats) 183 { 184 debugfs_create_file("recv", 0400, debugfs_phy, rxstats, &fops_recv); 185 } 186 EXPORT_SYMBOL(ath9k_cmn_debug_recv); 187 188 static ssize_t read_file_phy_err(struct file *file, char __user *user_buf, 189 size_t count, loff_t *ppos) 190 { 191 #define PHY_ERR(s, p) \ 192 len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \ 193 rxstats->phy_err_stats[p]) 194 195 struct ath_rx_stats *rxstats = file->private_data; 196 char *buf; 197 unsigned int len = 0, size = 1600; 198 ssize_t retval = 0; 199 200 buf = kzalloc(size, GFP_KERNEL); 201 if (buf == NULL) 202 return -ENOMEM; 203 204 PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); 205 PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING); 206 PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY); 207 PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE); 208 PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH); 209 PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR); 210 PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE); 211 PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR); 212 213 PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING); 214 PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); 215 PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); 216 PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); 217 PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP); 218 PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE); 219 PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART); 220 221 PHY_ERR("CCK-BLOCKER ERR", ATH9K_PHYERR_CCK_BLOCKER); 222 PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING); 223 PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC); 224 PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL); 225 PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); 226 PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP); 227 PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE); 228 PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART); 229 230 PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR); 231 PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); 232 PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); 233 PHY_ERR("HT-ZLF ERR", ATH9K_PHYERR_HT_ZLF); 234 235 PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT); 236 PHY_ERR("GREEN-FIELD ERR", ATH9K_PHYERR_GREEN_FIELD); 237 PHY_ERR("SPECTRAL ERR", ATH9K_PHYERR_SPECTRAL); 238 239 if (len > size) 240 len = size; 241 242 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 243 kfree(buf); 244 245 return retval; 246 247 #undef PHY_ERR 248 } 249 250 static const struct file_operations fops_phy_err = { 251 .read = read_file_phy_err, 252 .open = simple_open, 253 .owner = THIS_MODULE, 254 .llseek = default_llseek, 255 }; 256 257 void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy, 258 struct ath_rx_stats *rxstats) 259 { 260 debugfs_create_file("phy_err", 0400, debugfs_phy, rxstats, 261 &fops_phy_err); 262 } 263 EXPORT_SYMBOL(ath9k_cmn_debug_phy_err); 264