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/slab.h> 18 #include <linux/vmalloc.h> 19 #include <linux/export.h> 20 #include <asm/unaligned.h> 21 22 #include "ath9k.h" 23 24 #define REG_WRITE_D(_ah, _reg, _val) \ 25 ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg)) 26 #define REG_READ_D(_ah, _reg) \ 27 ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) 28 29 void ath9k_debug_sync_cause(struct ath_softc *sc, u32 sync_cause) 30 { 31 if (sync_cause) 32 sc->debug.stats.istats.sync_cause_all++; 33 if (sync_cause & AR_INTR_SYNC_RTC_IRQ) 34 sc->debug.stats.istats.sync_rtc_irq++; 35 if (sync_cause & AR_INTR_SYNC_MAC_IRQ) 36 sc->debug.stats.istats.sync_mac_irq++; 37 if (sync_cause & AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS) 38 sc->debug.stats.istats.eeprom_illegal_access++; 39 if (sync_cause & AR_INTR_SYNC_APB_TIMEOUT) 40 sc->debug.stats.istats.apb_timeout++; 41 if (sync_cause & AR_INTR_SYNC_PCI_MODE_CONFLICT) 42 sc->debug.stats.istats.pci_mode_conflict++; 43 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) 44 sc->debug.stats.istats.host1_fatal++; 45 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) 46 sc->debug.stats.istats.host1_perr++; 47 if (sync_cause & AR_INTR_SYNC_TRCV_FIFO_PERR) 48 sc->debug.stats.istats.trcv_fifo_perr++; 49 if (sync_cause & AR_INTR_SYNC_RADM_CPL_EP) 50 sc->debug.stats.istats.radm_cpl_ep++; 51 if (sync_cause & AR_INTR_SYNC_RADM_CPL_DLLP_ABORT) 52 sc->debug.stats.istats.radm_cpl_dllp_abort++; 53 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TLP_ABORT) 54 sc->debug.stats.istats.radm_cpl_tlp_abort++; 55 if (sync_cause & AR_INTR_SYNC_RADM_CPL_ECRC_ERR) 56 sc->debug.stats.istats.radm_cpl_ecrc_err++; 57 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) 58 sc->debug.stats.istats.radm_cpl_timeout++; 59 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) 60 sc->debug.stats.istats.local_timeout++; 61 if (sync_cause & AR_INTR_SYNC_PM_ACCESS) 62 sc->debug.stats.istats.pm_access++; 63 if (sync_cause & AR_INTR_SYNC_MAC_AWAKE) 64 sc->debug.stats.istats.mac_awake++; 65 if (sync_cause & AR_INTR_SYNC_MAC_ASLEEP) 66 sc->debug.stats.istats.mac_asleep++; 67 if (sync_cause & AR_INTR_SYNC_MAC_SLEEP_ACCESS) 68 sc->debug.stats.istats.mac_sleep_access++; 69 } 70 71 static ssize_t ath9k_debugfs_read_buf(struct file *file, char __user *user_buf, 72 size_t count, loff_t *ppos) 73 { 74 u8 *buf = file->private_data; 75 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); 76 } 77 78 static int ath9k_debugfs_release_buf(struct inode *inode, struct file *file) 79 { 80 vfree(file->private_data); 81 return 0; 82 } 83 84 #ifdef CONFIG_ATH_DEBUG 85 86 static ssize_t read_file_debug(struct file *file, char __user *user_buf, 87 size_t count, loff_t *ppos) 88 { 89 struct ath_softc *sc = file->private_data; 90 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 91 char buf[32]; 92 unsigned int len; 93 94 len = sprintf(buf, "0x%08x\n", common->debug_mask); 95 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 96 } 97 98 static ssize_t write_file_debug(struct file *file, const char __user *user_buf, 99 size_t count, loff_t *ppos) 100 { 101 struct ath_softc *sc = file->private_data; 102 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 103 unsigned long mask; 104 char buf[32]; 105 ssize_t len; 106 107 len = min(count, sizeof(buf) - 1); 108 if (copy_from_user(buf, user_buf, len)) 109 return -EFAULT; 110 111 buf[len] = '\0'; 112 if (kstrtoul(buf, 0, &mask)) 113 return -EINVAL; 114 115 common->debug_mask = mask; 116 return count; 117 } 118 119 static const struct file_operations fops_debug = { 120 .read = read_file_debug, 121 .write = write_file_debug, 122 .open = simple_open, 123 .owner = THIS_MODULE, 124 .llseek = default_llseek, 125 }; 126 127 #endif 128 129 #define DMA_BUF_LEN 1024 130 131 132 static ssize_t read_file_ani(struct file *file, char __user *user_buf, 133 size_t count, loff_t *ppos) 134 { 135 struct ath_softc *sc = file->private_data; 136 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 137 struct ath_hw *ah = sc->sc_ah; 138 unsigned int len = 0, size = 1024; 139 ssize_t retval = 0; 140 char *buf; 141 142 buf = kzalloc(size, GFP_KERNEL); 143 if (buf == NULL) 144 return -ENOMEM; 145 146 if (common->disable_ani) { 147 len += scnprintf(buf + len, size - len, "%s: %s\n", 148 "ANI", "DISABLED"); 149 goto exit; 150 } 151 152 len += scnprintf(buf + len, size - len, "%15s: %s\n", 153 "ANI", "ENABLED"); 154 len += scnprintf(buf + len, size - len, "%15s: %u\n", 155 "ANI RESET", ah->stats.ast_ani_reset); 156 len += scnprintf(buf + len, size - len, "%15s: %u\n", 157 "SPUR UP", ah->stats.ast_ani_spurup); 158 len += scnprintf(buf + len, size - len, "%15s: %u\n", 159 "SPUR DOWN", ah->stats.ast_ani_spurup); 160 len += scnprintf(buf + len, size - len, "%15s: %u\n", 161 "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon); 162 len += scnprintf(buf + len, size - len, "%15s: %u\n", 163 "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff); 164 len += scnprintf(buf + len, size - len, "%15s: %u\n", 165 "MRC-CCK ON", ah->stats.ast_ani_ccklow); 166 len += scnprintf(buf + len, size - len, "%15s: %u\n", 167 "MRC-CCK OFF", ah->stats.ast_ani_cckhigh); 168 len += scnprintf(buf + len, size - len, "%15s: %u\n", 169 "FIR-STEP UP", ah->stats.ast_ani_stepup); 170 len += scnprintf(buf + len, size - len, "%15s: %u\n", 171 "FIR-STEP DOWN", ah->stats.ast_ani_stepdown); 172 len += scnprintf(buf + len, size - len, "%15s: %u\n", 173 "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero); 174 len += scnprintf(buf + len, size - len, "%15s: %u\n", 175 "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs); 176 len += scnprintf(buf + len, size - len, "%15s: %u\n", 177 "CCK ERRORS", ah->stats.ast_ani_cckerrs); 178 exit: 179 if (len > size) 180 len = size; 181 182 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 183 kfree(buf); 184 185 return retval; 186 } 187 188 static ssize_t write_file_ani(struct file *file, 189 const char __user *user_buf, 190 size_t count, loff_t *ppos) 191 { 192 struct ath_softc *sc = file->private_data; 193 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 194 unsigned long ani; 195 char buf[32]; 196 ssize_t len; 197 198 len = min(count, sizeof(buf) - 1); 199 if (copy_from_user(buf, user_buf, len)) 200 return -EFAULT; 201 202 buf[len] = '\0'; 203 if (kstrtoul(buf, 0, &ani)) 204 return -EINVAL; 205 206 if (ani < 0 || ani > 1) 207 return -EINVAL; 208 209 common->disable_ani = !ani; 210 211 if (common->disable_ani) { 212 clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); 213 ath_stop_ani(sc); 214 } else { 215 ath_check_ani(sc); 216 } 217 218 return count; 219 } 220 221 static const struct file_operations fops_ani = { 222 .read = read_file_ani, 223 .write = write_file_ani, 224 .open = simple_open, 225 .owner = THIS_MODULE, 226 .llseek = default_llseek, 227 }; 228 229 #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 230 231 static ssize_t read_file_bt_ant_diversity(struct file *file, 232 char __user *user_buf, 233 size_t count, loff_t *ppos) 234 { 235 struct ath_softc *sc = file->private_data; 236 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 237 char buf[32]; 238 unsigned int len; 239 240 len = sprintf(buf, "%d\n", common->bt_ant_diversity); 241 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 242 } 243 244 static ssize_t write_file_bt_ant_diversity(struct file *file, 245 const char __user *user_buf, 246 size_t count, loff_t *ppos) 247 { 248 struct ath_softc *sc = file->private_data; 249 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 250 struct ath9k_hw_capabilities *pCap = &sc->sc_ah->caps; 251 unsigned long bt_ant_diversity; 252 char buf[32]; 253 ssize_t len; 254 255 len = min(count, sizeof(buf) - 1); 256 if (copy_from_user(buf, user_buf, len)) 257 return -EFAULT; 258 259 if (!(pCap->hw_caps & ATH9K_HW_CAP_BT_ANT_DIV)) 260 goto exit; 261 262 buf[len] = '\0'; 263 if (kstrtoul(buf, 0, &bt_ant_diversity)) 264 return -EINVAL; 265 266 common->bt_ant_diversity = !!bt_ant_diversity; 267 ath9k_ps_wakeup(sc); 268 ath9k_hw_set_bt_ant_diversity(sc->sc_ah, common->bt_ant_diversity); 269 ath_dbg(common, CONFIG, "Enable WLAN/BT RX Antenna diversity: %d\n", 270 common->bt_ant_diversity); 271 ath9k_ps_restore(sc); 272 exit: 273 return count; 274 } 275 276 static const struct file_operations fops_bt_ant_diversity = { 277 .read = read_file_bt_ant_diversity, 278 .write = write_file_bt_ant_diversity, 279 .open = simple_open, 280 .owner = THIS_MODULE, 281 .llseek = default_llseek, 282 }; 283 284 #endif 285 286 void ath9k_debug_stat_ant(struct ath_softc *sc, 287 struct ath_hw_antcomb_conf *div_ant_conf, 288 int main_rssi_avg, int alt_rssi_avg) 289 { 290 struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN]; 291 struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT]; 292 293 as_main->lna_attempt_cnt[div_ant_conf->main_lna_conf]++; 294 as_alt->lna_attempt_cnt[div_ant_conf->alt_lna_conf]++; 295 296 as_main->rssi_avg = main_rssi_avg; 297 as_alt->rssi_avg = alt_rssi_avg; 298 } 299 300 static ssize_t read_file_antenna_diversity(struct file *file, 301 char __user *user_buf, 302 size_t count, loff_t *ppos) 303 { 304 struct ath_softc *sc = file->private_data; 305 struct ath_hw *ah = sc->sc_ah; 306 struct ath9k_hw_capabilities *pCap = &ah->caps; 307 struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN]; 308 struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT]; 309 struct ath_hw_antcomb_conf div_ant_conf; 310 unsigned int len = 0, size = 1024; 311 ssize_t retval = 0; 312 char *buf; 313 char *lna_conf_str[4] = {"LNA1_MINUS_LNA2", 314 "LNA2", 315 "LNA1", 316 "LNA1_PLUS_LNA2"}; 317 318 buf = kzalloc(size, GFP_KERNEL); 319 if (buf == NULL) 320 return -ENOMEM; 321 322 if (!(pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)) { 323 len += scnprintf(buf + len, size - len, "%s\n", 324 "Antenna Diversity Combining is disabled"); 325 goto exit; 326 } 327 328 ath9k_ps_wakeup(sc); 329 ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf); 330 len += scnprintf(buf + len, size - len, "Current MAIN config : %s\n", 331 lna_conf_str[div_ant_conf.main_lna_conf]); 332 len += scnprintf(buf + len, size - len, "Current ALT config : %s\n", 333 lna_conf_str[div_ant_conf.alt_lna_conf]); 334 len += scnprintf(buf + len, size - len, "Average MAIN RSSI : %d\n", 335 as_main->rssi_avg); 336 len += scnprintf(buf + len, size - len, "Average ALT RSSI : %d\n\n", 337 as_alt->rssi_avg); 338 ath9k_ps_restore(sc); 339 340 len += scnprintf(buf + len, size - len, "Packet Receive Cnt:\n"); 341 len += scnprintf(buf + len, size - len, "-------------------\n"); 342 343 len += scnprintf(buf + len, size - len, "%30s%15s\n", 344 "MAIN", "ALT"); 345 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", 346 "TOTAL COUNT", 347 as_main->recv_cnt, 348 as_alt->recv_cnt); 349 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", 350 "LNA1", 351 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1], 352 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1]); 353 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", 354 "LNA2", 355 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2], 356 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2]); 357 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", 358 "LNA1 + LNA2", 359 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2], 360 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]); 361 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", 362 "LNA1 - LNA2", 363 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2], 364 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]); 365 366 len += scnprintf(buf + len, size - len, "\nLNA Config Attempts:\n"); 367 len += scnprintf(buf + len, size - len, "--------------------\n"); 368 369 len += scnprintf(buf + len, size - len, "%30s%15s\n", 370 "MAIN", "ALT"); 371 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", 372 "LNA1", 373 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1], 374 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1]); 375 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", 376 "LNA2", 377 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2], 378 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2]); 379 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", 380 "LNA1 + LNA2", 381 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2], 382 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]); 383 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", 384 "LNA1 - LNA2", 385 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2], 386 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]); 387 388 exit: 389 if (len > size) 390 len = size; 391 392 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 393 kfree(buf); 394 395 return retval; 396 } 397 398 static const struct file_operations fops_antenna_diversity = { 399 .read = read_file_antenna_diversity, 400 .open = simple_open, 401 .owner = THIS_MODULE, 402 .llseek = default_llseek, 403 }; 404 405 static ssize_t read_file_dma(struct file *file, char __user *user_buf, 406 size_t count, loff_t *ppos) 407 { 408 struct ath_softc *sc = file->private_data; 409 struct ath_hw *ah = sc->sc_ah; 410 char *buf; 411 int retval; 412 unsigned int len = 0; 413 u32 val[ATH9K_NUM_DMA_DEBUG_REGS]; 414 int i, qcuOffset = 0, dcuOffset = 0; 415 u32 *qcuBase = &val[0], *dcuBase = &val[4]; 416 417 buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL); 418 if (!buf) 419 return -ENOMEM; 420 421 ath9k_ps_wakeup(sc); 422 423 REG_WRITE_D(ah, AR_MACMISC, 424 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) | 425 (AR_MACMISC_MISC_OBS_BUS_1 << 426 AR_MACMISC_MISC_OBS_BUS_MSB_S))); 427 428 len += scnprintf(buf + len, DMA_BUF_LEN - len, 429 "Raw DMA Debug values:\n"); 430 431 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) { 432 if (i % 4 == 0) 433 len += scnprintf(buf + len, DMA_BUF_LEN - len, "\n"); 434 435 val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32))); 436 len += scnprintf(buf + len, DMA_BUF_LEN - len, "%d: %08x ", 437 i, val[i]); 438 } 439 440 len += scnprintf(buf + len, DMA_BUF_LEN - len, "\n\n"); 441 len += scnprintf(buf + len, DMA_BUF_LEN - len, 442 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); 443 444 for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) { 445 if (i == 8) { 446 qcuOffset = 0; 447 qcuBase++; 448 } 449 450 if (i == 6) { 451 dcuOffset = 0; 452 dcuBase++; 453 } 454 455 len += scnprintf(buf + len, DMA_BUF_LEN - len, 456 "%2d %2x %1x %2x %2x\n", 457 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, 458 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), 459 val[2] & (0x7 << (i * 3)) >> (i * 3), 460 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); 461 } 462 463 len += scnprintf(buf + len, DMA_BUF_LEN - len, "\n"); 464 465 len += scnprintf(buf + len, DMA_BUF_LEN - len, 466 "qcu_stitch state: %2x qcu_fetch state: %2x\n", 467 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22); 468 len += scnprintf(buf + len, DMA_BUF_LEN - len, 469 "qcu_complete state: %2x dcu_complete state: %2x\n", 470 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3)); 471 len += scnprintf(buf + len, DMA_BUF_LEN - len, 472 "dcu_arb state: %2x dcu_fp state: %2x\n", 473 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27); 474 len += scnprintf(buf + len, DMA_BUF_LEN - len, 475 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n", 476 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10); 477 len += scnprintf(buf + len, DMA_BUF_LEN - len, 478 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n", 479 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12); 480 len += scnprintf(buf + len, DMA_BUF_LEN - len, 481 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", 482 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); 483 484 len += scnprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x\n", 485 REG_READ_D(ah, AR_OBS_BUS_1)); 486 len += scnprintf(buf + len, DMA_BUF_LEN - len, 487 "AR_CR: 0x%x\n", REG_READ_D(ah, AR_CR)); 488 489 ath9k_ps_restore(sc); 490 491 if (len > DMA_BUF_LEN) 492 len = DMA_BUF_LEN; 493 494 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 495 kfree(buf); 496 return retval; 497 } 498 499 static const struct file_operations fops_dma = { 500 .read = read_file_dma, 501 .open = simple_open, 502 .owner = THIS_MODULE, 503 .llseek = default_llseek, 504 }; 505 506 507 void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) 508 { 509 if (status) 510 sc->debug.stats.istats.total++; 511 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { 512 if (status & ATH9K_INT_RXLP) 513 sc->debug.stats.istats.rxlp++; 514 if (status & ATH9K_INT_RXHP) 515 sc->debug.stats.istats.rxhp++; 516 if (status & ATH9K_INT_BB_WATCHDOG) 517 sc->debug.stats.istats.bb_watchdog++; 518 } else { 519 if (status & ATH9K_INT_RX) 520 sc->debug.stats.istats.rxok++; 521 } 522 if (status & ATH9K_INT_RXEOL) 523 sc->debug.stats.istats.rxeol++; 524 if (status & ATH9K_INT_RXORN) 525 sc->debug.stats.istats.rxorn++; 526 if (status & ATH9K_INT_TX) 527 sc->debug.stats.istats.txok++; 528 if (status & ATH9K_INT_TXURN) 529 sc->debug.stats.istats.txurn++; 530 if (status & ATH9K_INT_RXPHY) 531 sc->debug.stats.istats.rxphyerr++; 532 if (status & ATH9K_INT_RXKCM) 533 sc->debug.stats.istats.rx_keycache_miss++; 534 if (status & ATH9K_INT_SWBA) 535 sc->debug.stats.istats.swba++; 536 if (status & ATH9K_INT_BMISS) 537 sc->debug.stats.istats.bmiss++; 538 if (status & ATH9K_INT_BNR) 539 sc->debug.stats.istats.bnr++; 540 if (status & ATH9K_INT_CST) 541 sc->debug.stats.istats.cst++; 542 if (status & ATH9K_INT_GTT) 543 sc->debug.stats.istats.gtt++; 544 if (status & ATH9K_INT_TIM) 545 sc->debug.stats.istats.tim++; 546 if (status & ATH9K_INT_CABEND) 547 sc->debug.stats.istats.cabend++; 548 if (status & ATH9K_INT_DTIMSYNC) 549 sc->debug.stats.istats.dtimsync++; 550 if (status & ATH9K_INT_DTIM) 551 sc->debug.stats.istats.dtim++; 552 if (status & ATH9K_INT_TSFOOR) 553 sc->debug.stats.istats.tsfoor++; 554 if (status & ATH9K_INT_MCI) 555 sc->debug.stats.istats.mci++; 556 if (status & ATH9K_INT_GENTIMER) 557 sc->debug.stats.istats.gen_timer++; 558 } 559 560 static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, 561 size_t count, loff_t *ppos) 562 { 563 struct ath_softc *sc = file->private_data; 564 unsigned int len = 0; 565 int rv; 566 int mxlen = 4000; 567 char *buf = kmalloc(mxlen, GFP_KERNEL); 568 if (!buf) 569 return -ENOMEM; 570 571 #define PR_IS(a, s) \ 572 do { \ 573 len += scnprintf(buf + len, mxlen - len, \ 574 "%21s: %10u\n", a, \ 575 sc->debug.stats.istats.s); \ 576 } while (0) 577 578 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { 579 PR_IS("RXLP", rxlp); 580 PR_IS("RXHP", rxhp); 581 PR_IS("WATHDOG", bb_watchdog); 582 } else { 583 PR_IS("RX", rxok); 584 } 585 PR_IS("RXEOL", rxeol); 586 PR_IS("RXORN", rxorn); 587 PR_IS("TX", txok); 588 PR_IS("TXURN", txurn); 589 PR_IS("MIB", mib); 590 PR_IS("RXPHY", rxphyerr); 591 PR_IS("RXKCM", rx_keycache_miss); 592 PR_IS("SWBA", swba); 593 PR_IS("BMISS", bmiss); 594 PR_IS("BNR", bnr); 595 PR_IS("CST", cst); 596 PR_IS("GTT", gtt); 597 PR_IS("TIM", tim); 598 PR_IS("CABEND", cabend); 599 PR_IS("DTIMSYNC", dtimsync); 600 PR_IS("DTIM", dtim); 601 PR_IS("TSFOOR", tsfoor); 602 PR_IS("MCI", mci); 603 PR_IS("GENTIMER", gen_timer); 604 PR_IS("TOTAL", total); 605 606 len += scnprintf(buf + len, mxlen - len, 607 "SYNC_CAUSE stats:\n"); 608 609 PR_IS("Sync-All", sync_cause_all); 610 PR_IS("RTC-IRQ", sync_rtc_irq); 611 PR_IS("MAC-IRQ", sync_mac_irq); 612 PR_IS("EEPROM-Illegal-Access", eeprom_illegal_access); 613 PR_IS("APB-Timeout", apb_timeout); 614 PR_IS("PCI-Mode-Conflict", pci_mode_conflict); 615 PR_IS("HOST1-Fatal", host1_fatal); 616 PR_IS("HOST1-Perr", host1_perr); 617 PR_IS("TRCV-FIFO-Perr", trcv_fifo_perr); 618 PR_IS("RADM-CPL-EP", radm_cpl_ep); 619 PR_IS("RADM-CPL-DLLP-Abort", radm_cpl_dllp_abort); 620 PR_IS("RADM-CPL-TLP-Abort", radm_cpl_tlp_abort); 621 PR_IS("RADM-CPL-ECRC-Err", radm_cpl_ecrc_err); 622 PR_IS("RADM-CPL-Timeout", radm_cpl_timeout); 623 PR_IS("Local-Bus-Timeout", local_timeout); 624 PR_IS("PM-Access", pm_access); 625 PR_IS("MAC-Awake", mac_awake); 626 PR_IS("MAC-Asleep", mac_asleep); 627 PR_IS("MAC-Sleep-Access", mac_sleep_access); 628 629 if (len > mxlen) 630 len = mxlen; 631 632 rv = simple_read_from_buffer(user_buf, count, ppos, buf, len); 633 kfree(buf); 634 return rv; 635 } 636 637 static const struct file_operations fops_interrupt = { 638 .read = read_file_interrupt, 639 .open = simple_open, 640 .owner = THIS_MODULE, 641 .llseek = default_llseek, 642 }; 643 644 static ssize_t read_file_xmit(struct file *file, char __user *user_buf, 645 size_t count, loff_t *ppos) 646 { 647 struct ath_softc *sc = file->private_data; 648 char *buf; 649 unsigned int len = 0, size = 2048; 650 ssize_t retval = 0; 651 652 buf = kzalloc(size, GFP_KERNEL); 653 if (buf == NULL) 654 return -ENOMEM; 655 656 len += sprintf(buf, "%30s %10s%10s%10s\n\n", 657 "BE", "BK", "VI", "VO"); 658 659 PR("MPDUs Queued: ", queued); 660 PR("MPDUs Completed: ", completed); 661 PR("MPDUs XRetried: ", xretries); 662 PR("Aggregates: ", a_aggr); 663 PR("AMPDUs Queued HW:", a_queued_hw); 664 PR("AMPDUs Queued SW:", a_queued_sw); 665 PR("AMPDUs Completed:", a_completed); 666 PR("AMPDUs Retried: ", a_retries); 667 PR("AMPDUs XRetried: ", a_xretries); 668 PR("TXERR Filtered: ", txerr_filtered); 669 PR("FIFO Underrun: ", fifo_underrun); 670 PR("TXOP Exceeded: ", xtxop); 671 PR("TXTIMER Expiry: ", timer_exp); 672 PR("DESC CFG Error: ", desc_cfg_err); 673 PR("DATA Underrun: ", data_underrun); 674 PR("DELIM Underrun: ", delim_underrun); 675 PR("TX-Pkts-All: ", tx_pkts_all); 676 PR("TX-Bytes-All: ", tx_bytes_all); 677 PR("HW-put-tx-buf: ", puttxbuf); 678 PR("HW-tx-start: ", txstart); 679 PR("HW-tx-proc-desc: ", txprocdesc); 680 PR("TX-Failed: ", txfailed); 681 682 if (len > size) 683 len = size; 684 685 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 686 kfree(buf); 687 688 return retval; 689 } 690 691 static ssize_t print_queue(struct ath_softc *sc, struct ath_txq *txq, 692 char *buf, ssize_t size) 693 { 694 ssize_t len = 0; 695 696 ath_txq_lock(sc, txq); 697 698 len += scnprintf(buf + len, size - len, "%s: %d ", 699 "qnum", txq->axq_qnum); 700 len += scnprintf(buf + len, size - len, "%s: %2d ", 701 "qdepth", txq->axq_depth); 702 len += scnprintf(buf + len, size - len, "%s: %2d ", 703 "ampdu-depth", txq->axq_ampdu_depth); 704 len += scnprintf(buf + len, size - len, "%s: %3d ", 705 "pending", txq->pending_frames); 706 len += scnprintf(buf + len, size - len, "%s: %d\n", 707 "stopped", txq->stopped); 708 709 ath_txq_unlock(sc, txq); 710 return len; 711 } 712 713 static ssize_t read_file_queues(struct file *file, char __user *user_buf, 714 size_t count, loff_t *ppos) 715 { 716 struct ath_softc *sc = file->private_data; 717 struct ath_txq *txq; 718 char *buf; 719 unsigned int len = 0, size = 1024; 720 ssize_t retval = 0; 721 int i; 722 char *qname[4] = {"VO", "VI", "BE", "BK"}; 723 724 buf = kzalloc(size, GFP_KERNEL); 725 if (buf == NULL) 726 return -ENOMEM; 727 728 for (i = 0; i < IEEE80211_NUM_ACS; i++) { 729 txq = sc->tx.txq_map[i]; 730 len += scnprintf(buf + len, size - len, "(%s): ", qname[i]); 731 len += print_queue(sc, txq, buf + len, size - len); 732 } 733 734 len += scnprintf(buf + len, size - len, "(CAB): "); 735 len += print_queue(sc, sc->beacon.cabq, buf + len, size - len); 736 737 if (len > size) 738 len = size; 739 740 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 741 kfree(buf); 742 743 return retval; 744 } 745 746 static ssize_t read_file_misc(struct file *file, char __user *user_buf, 747 size_t count, loff_t *ppos) 748 { 749 struct ath_softc *sc = file->private_data; 750 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 751 struct ieee80211_hw *hw = sc->hw; 752 struct ath9k_vif_iter_data iter_data; 753 char buf[512]; 754 unsigned int len = 0; 755 ssize_t retval = 0; 756 unsigned int reg; 757 u32 rxfilter; 758 759 len += scnprintf(buf + len, sizeof(buf) - len, 760 "BSSID: %pM\n", common->curbssid); 761 len += scnprintf(buf + len, sizeof(buf) - len, 762 "BSSID-MASK: %pM\n", common->bssidmask); 763 len += scnprintf(buf + len, sizeof(buf) - len, 764 "OPMODE: %s\n", 765 ath_opmode_to_string(sc->sc_ah->opmode)); 766 767 ath9k_ps_wakeup(sc); 768 rxfilter = ath9k_hw_getrxfilter(sc->sc_ah); 769 ath9k_ps_restore(sc); 770 771 len += scnprintf(buf + len, sizeof(buf) - len, 772 "RXFILTER: 0x%x", rxfilter); 773 774 if (rxfilter & ATH9K_RX_FILTER_UCAST) 775 len += scnprintf(buf + len, sizeof(buf) - len, " UCAST"); 776 if (rxfilter & ATH9K_RX_FILTER_MCAST) 777 len += scnprintf(buf + len, sizeof(buf) - len, " MCAST"); 778 if (rxfilter & ATH9K_RX_FILTER_BCAST) 779 len += scnprintf(buf + len, sizeof(buf) - len, " BCAST"); 780 if (rxfilter & ATH9K_RX_FILTER_CONTROL) 781 len += scnprintf(buf + len, sizeof(buf) - len, " CONTROL"); 782 if (rxfilter & ATH9K_RX_FILTER_BEACON) 783 len += scnprintf(buf + len, sizeof(buf) - len, " BEACON"); 784 if (rxfilter & ATH9K_RX_FILTER_PROM) 785 len += scnprintf(buf + len, sizeof(buf) - len, " PROM"); 786 if (rxfilter & ATH9K_RX_FILTER_PROBEREQ) 787 len += scnprintf(buf + len, sizeof(buf) - len, " PROBEREQ"); 788 if (rxfilter & ATH9K_RX_FILTER_PHYERR) 789 len += scnprintf(buf + len, sizeof(buf) - len, " PHYERR"); 790 if (rxfilter & ATH9K_RX_FILTER_MYBEACON) 791 len += scnprintf(buf + len, sizeof(buf) - len, " MYBEACON"); 792 if (rxfilter & ATH9K_RX_FILTER_COMP_BAR) 793 len += scnprintf(buf + len, sizeof(buf) - len, " COMP_BAR"); 794 if (rxfilter & ATH9K_RX_FILTER_PSPOLL) 795 len += scnprintf(buf + len, sizeof(buf) - len, " PSPOLL"); 796 if (rxfilter & ATH9K_RX_FILTER_PHYRADAR) 797 len += scnprintf(buf + len, sizeof(buf) - len, " PHYRADAR"); 798 if (rxfilter & ATH9K_RX_FILTER_MCAST_BCAST_ALL) 799 len += scnprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL"); 800 if (rxfilter & ATH9K_RX_FILTER_CONTROL_WRAPPER) 801 len += scnprintf(buf + len, sizeof(buf) - len, " CONTROL_WRAPPER"); 802 803 len += scnprintf(buf + len, sizeof(buf) - len, "\n"); 804 805 reg = sc->sc_ah->imask; 806 807 len += scnprintf(buf + len, sizeof(buf) - len, 808 "INTERRUPT-MASK: 0x%x", reg); 809 810 if (reg & ATH9K_INT_SWBA) 811 len += scnprintf(buf + len, sizeof(buf) - len, " SWBA"); 812 if (reg & ATH9K_INT_BMISS) 813 len += scnprintf(buf + len, sizeof(buf) - len, " BMISS"); 814 if (reg & ATH9K_INT_CST) 815 len += scnprintf(buf + len, sizeof(buf) - len, " CST"); 816 if (reg & ATH9K_INT_RX) 817 len += scnprintf(buf + len, sizeof(buf) - len, " RX"); 818 if (reg & ATH9K_INT_RXHP) 819 len += scnprintf(buf + len, sizeof(buf) - len, " RXHP"); 820 if (reg & ATH9K_INT_RXLP) 821 len += scnprintf(buf + len, sizeof(buf) - len, " RXLP"); 822 if (reg & ATH9K_INT_BB_WATCHDOG) 823 len += scnprintf(buf + len, sizeof(buf) - len, " BB_WATCHDOG"); 824 825 len += scnprintf(buf + len, sizeof(buf) - len, "\n"); 826 827 ath9k_calculate_iter_data(hw, NULL, &iter_data); 828 829 len += scnprintf(buf + len, sizeof(buf) - len, 830 "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i" 831 " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n", 832 iter_data.naps, iter_data.nstations, iter_data.nmeshes, 833 iter_data.nwds, iter_data.nadhocs, 834 sc->nvifs, sc->nbcnvifs); 835 836 if (len > sizeof(buf)) 837 len = sizeof(buf); 838 839 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 840 return retval; 841 } 842 843 static ssize_t read_file_reset(struct file *file, char __user *user_buf, 844 size_t count, loff_t *ppos) 845 { 846 struct ath_softc *sc = file->private_data; 847 char buf[512]; 848 unsigned int len = 0; 849 850 len += scnprintf(buf + len, sizeof(buf) - len, 851 "%17s: %2d\n", "Baseband Hang", 852 sc->debug.stats.reset[RESET_TYPE_BB_HANG]); 853 len += scnprintf(buf + len, sizeof(buf) - len, 854 "%17s: %2d\n", "Baseband Watchdog", 855 sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG]); 856 len += scnprintf(buf + len, sizeof(buf) - len, 857 "%17s: %2d\n", "Fatal HW Error", 858 sc->debug.stats.reset[RESET_TYPE_FATAL_INT]); 859 len += scnprintf(buf + len, sizeof(buf) - len, 860 "%17s: %2d\n", "TX HW error", 861 sc->debug.stats.reset[RESET_TYPE_TX_ERROR]); 862 len += scnprintf(buf + len, sizeof(buf) - len, 863 "%17s: %2d\n", "TX Path Hang", 864 sc->debug.stats.reset[RESET_TYPE_TX_HANG]); 865 len += scnprintf(buf + len, sizeof(buf) - len, 866 "%17s: %2d\n", "PLL RX Hang", 867 sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); 868 len += scnprintf(buf + len, sizeof(buf) - len, 869 "%17s: %2d\n", "MCI Reset", 870 sc->debug.stats.reset[RESET_TYPE_MCI]); 871 872 if (len > sizeof(buf)) 873 len = sizeof(buf); 874 875 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 876 } 877 878 void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, 879 struct ath_tx_status *ts, struct ath_txq *txq, 880 unsigned int flags) 881 { 882 int qnum = txq->axq_qnum; 883 884 TX_STAT_INC(qnum, tx_pkts_all); 885 sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len; 886 887 if (bf_isampdu(bf)) { 888 if (flags & ATH_TX_ERROR) 889 TX_STAT_INC(qnum, a_xretries); 890 else 891 TX_STAT_INC(qnum, a_completed); 892 } else { 893 if (ts->ts_status & ATH9K_TXERR_XRETRY) 894 TX_STAT_INC(qnum, xretries); 895 else 896 TX_STAT_INC(qnum, completed); 897 } 898 899 if (ts->ts_status & ATH9K_TXERR_FILT) 900 TX_STAT_INC(qnum, txerr_filtered); 901 if (ts->ts_status & ATH9K_TXERR_FIFO) 902 TX_STAT_INC(qnum, fifo_underrun); 903 if (ts->ts_status & ATH9K_TXERR_XTXOP) 904 TX_STAT_INC(qnum, xtxop); 905 if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED) 906 TX_STAT_INC(qnum, timer_exp); 907 if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR) 908 TX_STAT_INC(qnum, desc_cfg_err); 909 if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN) 910 TX_STAT_INC(qnum, data_underrun); 911 if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) 912 TX_STAT_INC(qnum, delim_underrun); 913 } 914 915 static const struct file_operations fops_xmit = { 916 .read = read_file_xmit, 917 .open = simple_open, 918 .owner = THIS_MODULE, 919 .llseek = default_llseek, 920 }; 921 922 static const struct file_operations fops_queues = { 923 .read = read_file_queues, 924 .open = simple_open, 925 .owner = THIS_MODULE, 926 .llseek = default_llseek, 927 }; 928 929 static const struct file_operations fops_misc = { 930 .read = read_file_misc, 931 .open = simple_open, 932 .owner = THIS_MODULE, 933 .llseek = default_llseek, 934 }; 935 936 static const struct file_operations fops_reset = { 937 .read = read_file_reset, 938 .open = simple_open, 939 .owner = THIS_MODULE, 940 .llseek = default_llseek, 941 }; 942 943 static ssize_t read_file_recv(struct file *file, char __user *user_buf, 944 size_t count, loff_t *ppos) 945 { 946 #define RXS_ERR(s, e) \ 947 do { \ 948 len += scnprintf(buf + len, size - len, \ 949 "%18s : %10u\n", s, \ 950 sc->debug.stats.rxstats.e);\ 951 } while (0) 952 953 struct ath_softc *sc = file->private_data; 954 char *buf; 955 unsigned int len = 0, size = 1600; 956 ssize_t retval = 0; 957 958 buf = kzalloc(size, GFP_KERNEL); 959 if (buf == NULL) 960 return -ENOMEM; 961 962 RXS_ERR("PKTS-ALL", rx_pkts_all); 963 RXS_ERR("BYTES-ALL", rx_bytes_all); 964 RXS_ERR("BEACONS", rx_beacons); 965 RXS_ERR("FRAGS", rx_frags); 966 RXS_ERR("SPECTRAL", rx_spectral); 967 968 RXS_ERR("CRC ERR", crc_err); 969 RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err); 970 RXS_ERR("PHY ERR", phy_err); 971 RXS_ERR("MIC ERR", mic_err); 972 RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err); 973 RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err); 974 RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err); 975 RXS_ERR("LENGTH-ERR", rx_len_err); 976 RXS_ERR("OOM-ERR", rx_oom_err); 977 RXS_ERR("RATE-ERR", rx_rate_err); 978 RXS_ERR("TOO-MANY-FRAGS", rx_too_many_frags_err); 979 980 if (len > size) 981 len = size; 982 983 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 984 kfree(buf); 985 986 return retval; 987 988 #undef RXS_ERR 989 } 990 991 void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) 992 { 993 #define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ 994 995 RX_STAT_INC(rx_pkts_all); 996 sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen; 997 998 if (rs->rs_status & ATH9K_RXERR_CRC) 999 RX_STAT_INC(crc_err); 1000 if (rs->rs_status & ATH9K_RXERR_DECRYPT) 1001 RX_STAT_INC(decrypt_crc_err); 1002 if (rs->rs_status & ATH9K_RXERR_MIC) 1003 RX_STAT_INC(mic_err); 1004 if (rs->rs_status & ATH9K_RX_DELIM_CRC_PRE) 1005 RX_STAT_INC(pre_delim_crc_err); 1006 if (rs->rs_status & ATH9K_RX_DELIM_CRC_POST) 1007 RX_STAT_INC(post_delim_crc_err); 1008 if (rs->rs_status & ATH9K_RX_DECRYPT_BUSY) 1009 RX_STAT_INC(decrypt_busy_err); 1010 1011 if (rs->rs_status & ATH9K_RXERR_PHY) { 1012 RX_STAT_INC(phy_err); 1013 if (rs->rs_phyerr < ATH9K_PHYERR_MAX) 1014 RX_PHY_ERR_INC(rs->rs_phyerr); 1015 } 1016 1017 #undef RX_PHY_ERR_INC 1018 } 1019 1020 static const struct file_operations fops_recv = { 1021 .read = read_file_recv, 1022 .open = simple_open, 1023 .owner = THIS_MODULE, 1024 .llseek = default_llseek, 1025 }; 1026 1027 static ssize_t read_file_phy_err(struct file *file, char __user *user_buf, 1028 size_t count, loff_t *ppos) 1029 { 1030 #define PHY_ERR(s, p) \ 1031 len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \ 1032 sc->debug.stats.rxstats.phy_err_stats[p]); 1033 1034 struct ath_softc *sc = file->private_data; 1035 char *buf; 1036 unsigned int len = 0, size = 1600; 1037 ssize_t retval = 0; 1038 1039 buf = kzalloc(size, GFP_KERNEL); 1040 if (buf == NULL) 1041 return -ENOMEM; 1042 1043 PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); 1044 PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING); 1045 PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY); 1046 PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE); 1047 PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH); 1048 PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR); 1049 PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE); 1050 PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR); 1051 PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING); 1052 PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); 1053 PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); 1054 PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); 1055 PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP); 1056 PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE); 1057 PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART); 1058 PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT); 1059 PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING); 1060 PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC); 1061 PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL); 1062 PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE); 1063 PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART); 1064 PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); 1065 PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP); 1066 PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR); 1067 PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); 1068 PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); 1069 1070 if (len > size) 1071 len = size; 1072 1073 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 1074 kfree(buf); 1075 1076 return retval; 1077 1078 #undef PHY_ERR 1079 } 1080 1081 static const struct file_operations fops_phy_err = { 1082 .read = read_file_phy_err, 1083 .open = simple_open, 1084 .owner = THIS_MODULE, 1085 .llseek = default_llseek, 1086 }; 1087 1088 static ssize_t read_file_regidx(struct file *file, char __user *user_buf, 1089 size_t count, loff_t *ppos) 1090 { 1091 struct ath_softc *sc = file->private_data; 1092 char buf[32]; 1093 unsigned int len; 1094 1095 len = sprintf(buf, "0x%08x\n", sc->debug.regidx); 1096 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1097 } 1098 1099 static ssize_t write_file_regidx(struct file *file, const char __user *user_buf, 1100 size_t count, loff_t *ppos) 1101 { 1102 struct ath_softc *sc = file->private_data; 1103 unsigned long regidx; 1104 char buf[32]; 1105 ssize_t len; 1106 1107 len = min(count, sizeof(buf) - 1); 1108 if (copy_from_user(buf, user_buf, len)) 1109 return -EFAULT; 1110 1111 buf[len] = '\0'; 1112 if (kstrtoul(buf, 0, ®idx)) 1113 return -EINVAL; 1114 1115 sc->debug.regidx = regidx; 1116 return count; 1117 } 1118 1119 static const struct file_operations fops_regidx = { 1120 .read = read_file_regidx, 1121 .write = write_file_regidx, 1122 .open = simple_open, 1123 .owner = THIS_MODULE, 1124 .llseek = default_llseek, 1125 }; 1126 1127 static ssize_t read_file_regval(struct file *file, char __user *user_buf, 1128 size_t count, loff_t *ppos) 1129 { 1130 struct ath_softc *sc = file->private_data; 1131 struct ath_hw *ah = sc->sc_ah; 1132 char buf[32]; 1133 unsigned int len; 1134 u32 regval; 1135 1136 ath9k_ps_wakeup(sc); 1137 regval = REG_READ_D(ah, sc->debug.regidx); 1138 ath9k_ps_restore(sc); 1139 len = sprintf(buf, "0x%08x\n", regval); 1140 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1141 } 1142 1143 static ssize_t write_file_regval(struct file *file, const char __user *user_buf, 1144 size_t count, loff_t *ppos) 1145 { 1146 struct ath_softc *sc = file->private_data; 1147 struct ath_hw *ah = sc->sc_ah; 1148 unsigned long regval; 1149 char buf[32]; 1150 ssize_t len; 1151 1152 len = min(count, sizeof(buf) - 1); 1153 if (copy_from_user(buf, user_buf, len)) 1154 return -EFAULT; 1155 1156 buf[len] = '\0'; 1157 if (kstrtoul(buf, 0, ®val)) 1158 return -EINVAL; 1159 1160 ath9k_ps_wakeup(sc); 1161 REG_WRITE_D(ah, sc->debug.regidx, regval); 1162 ath9k_ps_restore(sc); 1163 return count; 1164 } 1165 1166 static const struct file_operations fops_regval = { 1167 .read = read_file_regval, 1168 .write = write_file_regval, 1169 .open = simple_open, 1170 .owner = THIS_MODULE, 1171 .llseek = default_llseek, 1172 }; 1173 1174 #define REGDUMP_LINE_SIZE 20 1175 1176 static int open_file_regdump(struct inode *inode, struct file *file) 1177 { 1178 struct ath_softc *sc = inode->i_private; 1179 unsigned int len = 0; 1180 u8 *buf; 1181 int i; 1182 unsigned long num_regs, regdump_len, max_reg_offset; 1183 1184 max_reg_offset = AR_SREV_9300_20_OR_LATER(sc->sc_ah) ? 0x16bd4 : 0xb500; 1185 num_regs = max_reg_offset / 4 + 1; 1186 regdump_len = num_regs * REGDUMP_LINE_SIZE + 1; 1187 buf = vmalloc(regdump_len); 1188 if (!buf) 1189 return -ENOMEM; 1190 1191 ath9k_ps_wakeup(sc); 1192 for (i = 0; i < num_regs; i++) 1193 len += scnprintf(buf + len, regdump_len - len, 1194 "0x%06x 0x%08x\n", i << 2, REG_READ(sc->sc_ah, i << 2)); 1195 ath9k_ps_restore(sc); 1196 1197 file->private_data = buf; 1198 1199 return 0; 1200 } 1201 1202 static const struct file_operations fops_regdump = { 1203 .open = open_file_regdump, 1204 .read = ath9k_debugfs_read_buf, 1205 .release = ath9k_debugfs_release_buf, 1206 .owner = THIS_MODULE, 1207 .llseek = default_llseek,/* read accesses f_pos */ 1208 }; 1209 1210 static ssize_t read_file_dump_nfcal(struct file *file, char __user *user_buf, 1211 size_t count, loff_t *ppos) 1212 { 1213 struct ath_softc *sc = file->private_data; 1214 struct ath_hw *ah = sc->sc_ah; 1215 struct ath9k_nfcal_hist *h = sc->caldata.nfCalHist; 1216 struct ath_common *common = ath9k_hw_common(ah); 1217 struct ieee80211_conf *conf = &common->hw->conf; 1218 u32 len = 0, size = 1500; 1219 u32 i, j; 1220 ssize_t retval = 0; 1221 char *buf; 1222 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; 1223 u8 nread; 1224 1225 buf = kzalloc(size, GFP_KERNEL); 1226 if (!buf) 1227 return -ENOMEM; 1228 1229 len += scnprintf(buf + len, size - len, 1230 "Channel Noise Floor : %d\n", ah->noise); 1231 len += scnprintf(buf + len, size - len, 1232 "Chain | privNF | # Readings | NF Readings\n"); 1233 for (i = 0; i < NUM_NF_READINGS; i++) { 1234 if (!(chainmask & (1 << i)) || 1235 ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))) 1236 continue; 1237 1238 nread = AR_PHY_CCA_FILTERWINDOW_LENGTH - h[i].invalidNFcount; 1239 len += scnprintf(buf + len, size - len, " %d\t %d\t %d\t\t", 1240 i, h[i].privNF, nread); 1241 for (j = 0; j < nread; j++) 1242 len += scnprintf(buf + len, size - len, 1243 " %d", h[i].nfCalBuffer[j]); 1244 len += scnprintf(buf + len, size - len, "\n"); 1245 } 1246 1247 if (len > size) 1248 len = size; 1249 1250 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 1251 kfree(buf); 1252 1253 return retval; 1254 } 1255 1256 static const struct file_operations fops_dump_nfcal = { 1257 .read = read_file_dump_nfcal, 1258 .open = simple_open, 1259 .owner = THIS_MODULE, 1260 .llseek = default_llseek, 1261 }; 1262 1263 static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, 1264 size_t count, loff_t *ppos) 1265 { 1266 struct ath_softc *sc = file->private_data; 1267 struct ath_hw *ah = sc->sc_ah; 1268 u32 len = 0, size = 1500; 1269 ssize_t retval = 0; 1270 char *buf; 1271 1272 buf = kzalloc(size, GFP_KERNEL); 1273 if (!buf) 1274 return -ENOMEM; 1275 1276 len = ah->eep_ops->dump_eeprom(ah, true, buf, len, size); 1277 1278 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 1279 kfree(buf); 1280 1281 return retval; 1282 } 1283 1284 static const struct file_operations fops_base_eeprom = { 1285 .read = read_file_base_eeprom, 1286 .open = simple_open, 1287 .owner = THIS_MODULE, 1288 .llseek = default_llseek, 1289 }; 1290 1291 static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf, 1292 size_t count, loff_t *ppos) 1293 { 1294 struct ath_softc *sc = file->private_data; 1295 struct ath_hw *ah = sc->sc_ah; 1296 u32 len = 0, size = 6000; 1297 char *buf; 1298 size_t retval; 1299 1300 buf = kzalloc(size, GFP_KERNEL); 1301 if (buf == NULL) 1302 return -ENOMEM; 1303 1304 len = ah->eep_ops->dump_eeprom(ah, false, buf, len, size); 1305 1306 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 1307 kfree(buf); 1308 1309 return retval; 1310 } 1311 1312 static const struct file_operations fops_modal_eeprom = { 1313 .read = read_file_modal_eeprom, 1314 .open = simple_open, 1315 .owner = THIS_MODULE, 1316 .llseek = default_llseek, 1317 }; 1318 1319 #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 1320 static ssize_t read_file_btcoex(struct file *file, char __user *user_buf, 1321 size_t count, loff_t *ppos) 1322 { 1323 struct ath_softc *sc = file->private_data; 1324 u32 len = 0, size = 1500; 1325 char *buf; 1326 size_t retval; 1327 1328 buf = kzalloc(size, GFP_KERNEL); 1329 if (buf == NULL) 1330 return -ENOMEM; 1331 1332 if (!sc->sc_ah->common.btcoex_enabled) { 1333 len = scnprintf(buf, size, "%s\n", 1334 "BTCOEX is disabled"); 1335 goto exit; 1336 } 1337 1338 len = ath9k_dump_btcoex(sc, buf, size); 1339 exit: 1340 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 1341 kfree(buf); 1342 1343 return retval; 1344 } 1345 1346 static const struct file_operations fops_btcoex = { 1347 .read = read_file_btcoex, 1348 .open = simple_open, 1349 .owner = THIS_MODULE, 1350 .llseek = default_llseek, 1351 }; 1352 #endif 1353 1354 /* Ethtool support for get-stats */ 1355 1356 #define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" 1357 static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = { 1358 "tx_pkts_nic", 1359 "tx_bytes_nic", 1360 "rx_pkts_nic", 1361 "rx_bytes_nic", 1362 AMKSTR(d_tx_pkts), 1363 AMKSTR(d_tx_bytes), 1364 AMKSTR(d_tx_mpdus_queued), 1365 AMKSTR(d_tx_mpdus_completed), 1366 AMKSTR(d_tx_mpdu_xretries), 1367 AMKSTR(d_tx_aggregates), 1368 AMKSTR(d_tx_ampdus_queued_hw), 1369 AMKSTR(d_tx_ampdus_queued_sw), 1370 AMKSTR(d_tx_ampdus_completed), 1371 AMKSTR(d_tx_ampdu_retries), 1372 AMKSTR(d_tx_ampdu_xretries), 1373 AMKSTR(d_tx_fifo_underrun), 1374 AMKSTR(d_tx_op_exceeded), 1375 AMKSTR(d_tx_timer_expiry), 1376 AMKSTR(d_tx_desc_cfg_err), 1377 AMKSTR(d_tx_data_underrun), 1378 AMKSTR(d_tx_delim_underrun), 1379 "d_rx_crc_err", 1380 "d_rx_decrypt_crc_err", 1381 "d_rx_phy_err", 1382 "d_rx_mic_err", 1383 "d_rx_pre_delim_crc_err", 1384 "d_rx_post_delim_crc_err", 1385 "d_rx_decrypt_busy_err", 1386 1387 "d_rx_phyerr_radar", 1388 "d_rx_phyerr_ofdm_timing", 1389 "d_rx_phyerr_cck_timing", 1390 1391 }; 1392 #define ATH9K_SSTATS_LEN ARRAY_SIZE(ath9k_gstrings_stats) 1393 1394 void ath9k_get_et_strings(struct ieee80211_hw *hw, 1395 struct ieee80211_vif *vif, 1396 u32 sset, u8 *data) 1397 { 1398 if (sset == ETH_SS_STATS) 1399 memcpy(data, *ath9k_gstrings_stats, 1400 sizeof(ath9k_gstrings_stats)); 1401 } 1402 1403 int ath9k_get_et_sset_count(struct ieee80211_hw *hw, 1404 struct ieee80211_vif *vif, int sset) 1405 { 1406 if (sset == ETH_SS_STATS) 1407 return ATH9K_SSTATS_LEN; 1408 return 0; 1409 } 1410 1411 #define AWDATA(elem) \ 1412 do { \ 1413 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem; \ 1414 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].elem; \ 1415 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].elem; \ 1416 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].elem; \ 1417 } while (0) 1418 1419 #define AWDATA_RX(elem) \ 1420 do { \ 1421 data[i++] = sc->debug.stats.rxstats.elem; \ 1422 } while (0) 1423 1424 void ath9k_get_et_stats(struct ieee80211_hw *hw, 1425 struct ieee80211_vif *vif, 1426 struct ethtool_stats *stats, u64 *data) 1427 { 1428 struct ath_softc *sc = hw->priv; 1429 int i = 0; 1430 1431 data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all + 1432 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_pkts_all + 1433 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_pkts_all + 1434 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_pkts_all); 1435 data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all + 1436 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_bytes_all + 1437 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_bytes_all + 1438 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_bytes_all); 1439 AWDATA_RX(rx_pkts_all); 1440 AWDATA_RX(rx_bytes_all); 1441 1442 AWDATA(tx_pkts_all); 1443 AWDATA(tx_bytes_all); 1444 AWDATA(queued); 1445 AWDATA(completed); 1446 AWDATA(xretries); 1447 AWDATA(a_aggr); 1448 AWDATA(a_queued_hw); 1449 AWDATA(a_queued_sw); 1450 AWDATA(a_completed); 1451 AWDATA(a_retries); 1452 AWDATA(a_xretries); 1453 AWDATA(fifo_underrun); 1454 AWDATA(xtxop); 1455 AWDATA(timer_exp); 1456 AWDATA(desc_cfg_err); 1457 AWDATA(data_underrun); 1458 AWDATA(delim_underrun); 1459 1460 AWDATA_RX(crc_err); 1461 AWDATA_RX(decrypt_crc_err); 1462 AWDATA_RX(phy_err); 1463 AWDATA_RX(mic_err); 1464 AWDATA_RX(pre_delim_crc_err); 1465 AWDATA_RX(post_delim_crc_err); 1466 AWDATA_RX(decrypt_busy_err); 1467 1468 AWDATA_RX(phy_err_stats[ATH9K_PHYERR_RADAR]); 1469 AWDATA_RX(phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]); 1470 AWDATA_RX(phy_err_stats[ATH9K_PHYERR_CCK_TIMING]); 1471 1472 WARN_ON(i != ATH9K_SSTATS_LEN); 1473 } 1474 1475 void ath9k_deinit_debug(struct ath_softc *sc) 1476 { 1477 ath9k_spectral_deinit_debug(sc); 1478 } 1479 1480 int ath9k_init_debug(struct ath_hw *ah) 1481 { 1482 struct ath_common *common = ath9k_hw_common(ah); 1483 struct ath_softc *sc = (struct ath_softc *) common->priv; 1484 1485 sc->debug.debugfs_phy = debugfs_create_dir("ath9k", 1486 sc->hw->wiphy->debugfsdir); 1487 if (!sc->debug.debugfs_phy) 1488 return -ENOMEM; 1489 1490 #ifdef CONFIG_ATH_DEBUG 1491 debugfs_create_file("debug", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1492 sc, &fops_debug); 1493 #endif 1494 1495 ath9k_dfs_init_debug(sc); 1496 ath9k_tx99_init_debug(sc); 1497 ath9k_spectral_init_debug(sc); 1498 1499 debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, 1500 &fops_dma); 1501 debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc, 1502 &fops_interrupt); 1503 debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, 1504 &fops_xmit); 1505 debugfs_create_file("queues", S_IRUSR, sc->debug.debugfs_phy, sc, 1506 &fops_queues); 1507 debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1508 &sc->tx.txq_max_pending[IEEE80211_AC_BK]); 1509 debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1510 &sc->tx.txq_max_pending[IEEE80211_AC_BE]); 1511 debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1512 &sc->tx.txq_max_pending[IEEE80211_AC_VI]); 1513 debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1514 &sc->tx.txq_max_pending[IEEE80211_AC_VO]); 1515 debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, 1516 &fops_misc); 1517 debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc, 1518 &fops_reset); 1519 debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc, 1520 &fops_recv); 1521 debugfs_create_file("phy_err", S_IRUSR, sc->debug.debugfs_phy, sc, 1522 &fops_phy_err); 1523 debugfs_create_u8("rx_chainmask", S_IRUSR, sc->debug.debugfs_phy, 1524 &ah->rxchainmask); 1525 debugfs_create_u8("tx_chainmask", S_IRUSR, sc->debug.debugfs_phy, 1526 &ah->txchainmask); 1527 debugfs_create_file("ani", S_IRUSR | S_IWUSR, 1528 sc->debug.debugfs_phy, sc, &fops_ani); 1529 debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1530 &sc->sc_ah->config.enable_paprd); 1531 debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1532 sc, &fops_regidx); 1533 debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1534 sc, &fops_regval); 1535 debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR, 1536 sc->debug.debugfs_phy, 1537 &ah->config.cwm_ignore_extcca); 1538 debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc, 1539 &fops_regdump); 1540 debugfs_create_file("dump_nfcal", S_IRUSR, sc->debug.debugfs_phy, sc, 1541 &fops_dump_nfcal); 1542 debugfs_create_file("base_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, 1543 &fops_base_eeprom); 1544 debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, 1545 &fops_modal_eeprom); 1546 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, 1547 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); 1548 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, 1549 sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); 1550 debugfs_create_file("antenna_diversity", S_IRUSR, 1551 sc->debug.debugfs_phy, sc, &fops_antenna_diversity); 1552 #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 1553 debugfs_create_file("bt_ant_diversity", S_IRUSR | S_IWUSR, 1554 sc->debug.debugfs_phy, sc, &fops_bt_ant_diversity); 1555 debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc, 1556 &fops_btcoex); 1557 #endif 1558 1559 return 0; 1560 } 1561