1 /* 2 * Copyright (c) 2005-2011 Atheros Communications Inc. 3 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <linux/module.h> 19 #include <linux/debugfs.h> 20 21 #include "core.h" 22 #include "debug.h" 23 24 /* ms */ 25 #define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000 26 27 static int ath10k_printk(const char *level, const char *fmt, ...) 28 { 29 struct va_format vaf; 30 va_list args; 31 int rtn; 32 33 va_start(args, fmt); 34 35 vaf.fmt = fmt; 36 vaf.va = &args; 37 38 rtn = printk("%sath10k: %pV", level, &vaf); 39 40 va_end(args); 41 42 return rtn; 43 } 44 45 int ath10k_info(const char *fmt, ...) 46 { 47 struct va_format vaf = { 48 .fmt = fmt, 49 }; 50 va_list args; 51 int ret; 52 53 va_start(args, fmt); 54 vaf.va = &args; 55 ret = ath10k_printk(KERN_INFO, "%pV", &vaf); 56 trace_ath10k_log_info(&vaf); 57 va_end(args); 58 59 return ret; 60 } 61 EXPORT_SYMBOL(ath10k_info); 62 63 int ath10k_err(const char *fmt, ...) 64 { 65 struct va_format vaf = { 66 .fmt = fmt, 67 }; 68 va_list args; 69 int ret; 70 71 va_start(args, fmt); 72 vaf.va = &args; 73 ret = ath10k_printk(KERN_ERR, "%pV", &vaf); 74 trace_ath10k_log_err(&vaf); 75 va_end(args); 76 77 return ret; 78 } 79 EXPORT_SYMBOL(ath10k_err); 80 81 int ath10k_warn(const char *fmt, ...) 82 { 83 struct va_format vaf = { 84 .fmt = fmt, 85 }; 86 va_list args; 87 int ret = 0; 88 89 va_start(args, fmt); 90 vaf.va = &args; 91 92 if (net_ratelimit()) 93 ret = ath10k_printk(KERN_WARNING, "%pV", &vaf); 94 95 trace_ath10k_log_warn(&vaf); 96 97 va_end(args); 98 99 return ret; 100 } 101 EXPORT_SYMBOL(ath10k_warn); 102 103 #ifdef CONFIG_ATH10K_DEBUGFS 104 105 void ath10k_debug_read_service_map(struct ath10k *ar, 106 void *service_map, 107 size_t map_size) 108 { 109 memcpy(ar->debug.wmi_service_bitmap, service_map, map_size); 110 } 111 112 static ssize_t ath10k_read_wmi_services(struct file *file, 113 char __user *user_buf, 114 size_t count, loff_t *ppos) 115 { 116 struct ath10k *ar = file->private_data; 117 char *buf; 118 unsigned int len = 0, buf_len = 1500; 119 const char *status; 120 ssize_t ret_cnt; 121 int i; 122 123 buf = kzalloc(buf_len, GFP_KERNEL); 124 if (!buf) 125 return -ENOMEM; 126 127 mutex_lock(&ar->conf_mutex); 128 129 if (len > buf_len) 130 len = buf_len; 131 132 for (i = 0; i < WMI_SERVICE_LAST; i++) { 133 if (WMI_SERVICE_IS_ENABLED(ar->debug.wmi_service_bitmap, i)) 134 status = "enabled"; 135 else 136 status = "disabled"; 137 138 len += scnprintf(buf + len, buf_len - len, 139 "0x%02x - %20s - %s\n", 140 i, wmi_service_name(i), status); 141 } 142 143 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); 144 145 mutex_unlock(&ar->conf_mutex); 146 147 kfree(buf); 148 return ret_cnt; 149 } 150 151 static const struct file_operations fops_wmi_services = { 152 .read = ath10k_read_wmi_services, 153 .open = simple_open, 154 .owner = THIS_MODULE, 155 .llseek = default_llseek, 156 }; 157 158 void ath10k_debug_read_target_stats(struct ath10k *ar, 159 struct wmi_stats_event *ev) 160 { 161 u8 *tmp = ev->data; 162 struct ath10k_target_stats *stats; 163 int num_pdev_stats, num_vdev_stats, num_peer_stats; 164 struct wmi_pdev_stats_10x *ps; 165 int i; 166 167 spin_lock_bh(&ar->data_lock); 168 169 stats = &ar->debug.target_stats; 170 171 num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); /* 0 or 1 */ 172 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); /* 0 or max vdevs */ 173 num_peer_stats = __le32_to_cpu(ev->num_peer_stats); /* 0 or max peers */ 174 175 if (num_pdev_stats) { 176 ps = (struct wmi_pdev_stats_10x *)tmp; 177 178 stats->ch_noise_floor = __le32_to_cpu(ps->chan_nf); 179 stats->tx_frame_count = __le32_to_cpu(ps->tx_frame_count); 180 stats->rx_frame_count = __le32_to_cpu(ps->rx_frame_count); 181 stats->rx_clear_count = __le32_to_cpu(ps->rx_clear_count); 182 stats->cycle_count = __le32_to_cpu(ps->cycle_count); 183 stats->phy_err_count = __le32_to_cpu(ps->phy_err_count); 184 stats->chan_tx_power = __le32_to_cpu(ps->chan_tx_pwr); 185 186 stats->comp_queued = __le32_to_cpu(ps->wal.tx.comp_queued); 187 stats->comp_delivered = 188 __le32_to_cpu(ps->wal.tx.comp_delivered); 189 stats->msdu_enqued = __le32_to_cpu(ps->wal.tx.msdu_enqued); 190 stats->mpdu_enqued = __le32_to_cpu(ps->wal.tx.mpdu_enqued); 191 stats->wmm_drop = __le32_to_cpu(ps->wal.tx.wmm_drop); 192 stats->local_enqued = __le32_to_cpu(ps->wal.tx.local_enqued); 193 stats->local_freed = __le32_to_cpu(ps->wal.tx.local_freed); 194 stats->hw_queued = __le32_to_cpu(ps->wal.tx.hw_queued); 195 stats->hw_reaped = __le32_to_cpu(ps->wal.tx.hw_reaped); 196 stats->underrun = __le32_to_cpu(ps->wal.tx.underrun); 197 stats->tx_abort = __le32_to_cpu(ps->wal.tx.tx_abort); 198 stats->mpdus_requed = __le32_to_cpu(ps->wal.tx.mpdus_requed); 199 stats->tx_ko = __le32_to_cpu(ps->wal.tx.tx_ko); 200 stats->data_rc = __le32_to_cpu(ps->wal.tx.data_rc); 201 stats->self_triggers = __le32_to_cpu(ps->wal.tx.self_triggers); 202 stats->sw_retry_failure = 203 __le32_to_cpu(ps->wal.tx.sw_retry_failure); 204 stats->illgl_rate_phy_err = 205 __le32_to_cpu(ps->wal.tx.illgl_rate_phy_err); 206 stats->pdev_cont_xretry = 207 __le32_to_cpu(ps->wal.tx.pdev_cont_xretry); 208 stats->pdev_tx_timeout = 209 __le32_to_cpu(ps->wal.tx.pdev_tx_timeout); 210 stats->pdev_resets = __le32_to_cpu(ps->wal.tx.pdev_resets); 211 stats->phy_underrun = __le32_to_cpu(ps->wal.tx.phy_underrun); 212 stats->txop_ovf = __le32_to_cpu(ps->wal.tx.txop_ovf); 213 214 stats->mid_ppdu_route_change = 215 __le32_to_cpu(ps->wal.rx.mid_ppdu_route_change); 216 stats->status_rcvd = __le32_to_cpu(ps->wal.rx.status_rcvd); 217 stats->r0_frags = __le32_to_cpu(ps->wal.rx.r0_frags); 218 stats->r1_frags = __le32_to_cpu(ps->wal.rx.r1_frags); 219 stats->r2_frags = __le32_to_cpu(ps->wal.rx.r2_frags); 220 stats->r3_frags = __le32_to_cpu(ps->wal.rx.r3_frags); 221 stats->htt_msdus = __le32_to_cpu(ps->wal.rx.htt_msdus); 222 stats->htt_mpdus = __le32_to_cpu(ps->wal.rx.htt_mpdus); 223 stats->loc_msdus = __le32_to_cpu(ps->wal.rx.loc_msdus); 224 stats->loc_mpdus = __le32_to_cpu(ps->wal.rx.loc_mpdus); 225 stats->oversize_amsdu = 226 __le32_to_cpu(ps->wal.rx.oversize_amsdu); 227 stats->phy_errs = __le32_to_cpu(ps->wal.rx.phy_errs); 228 stats->phy_err_drop = __le32_to_cpu(ps->wal.rx.phy_err_drop); 229 stats->mpdu_errs = __le32_to_cpu(ps->wal.rx.mpdu_errs); 230 231 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, 232 ar->fw_features)) { 233 stats->ack_rx_bad = __le32_to_cpu(ps->ack_rx_bad); 234 stats->rts_bad = __le32_to_cpu(ps->rts_bad); 235 stats->rts_good = __le32_to_cpu(ps->rts_good); 236 stats->fcs_bad = __le32_to_cpu(ps->fcs_bad); 237 stats->no_beacons = __le32_to_cpu(ps->no_beacons); 238 stats->mib_int_count = __le32_to_cpu(ps->mib_int_count); 239 tmp += sizeof(struct wmi_pdev_stats_10x); 240 } else { 241 tmp += sizeof(struct wmi_pdev_stats_old); 242 } 243 } 244 245 /* 0 or max vdevs */ 246 /* Currently firmware does not support VDEV stats */ 247 if (num_vdev_stats) { 248 struct wmi_vdev_stats *vdev_stats; 249 250 for (i = 0; i < num_vdev_stats; i++) { 251 vdev_stats = (struct wmi_vdev_stats *)tmp; 252 tmp += sizeof(struct wmi_vdev_stats); 253 } 254 } 255 256 if (num_peer_stats) { 257 struct wmi_peer_stats_10x *peer_stats; 258 struct ath10k_peer_stat *s; 259 260 stats->peers = num_peer_stats; 261 262 for (i = 0; i < num_peer_stats; i++) { 263 peer_stats = (struct wmi_peer_stats_10x *)tmp; 264 s = &stats->peer_stat[i]; 265 266 memcpy(s->peer_macaddr, &peer_stats->peer_macaddr.addr, 267 ETH_ALEN); 268 s->peer_rssi = __le32_to_cpu(peer_stats->peer_rssi); 269 s->peer_tx_rate = 270 __le32_to_cpu(peer_stats->peer_tx_rate); 271 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, 272 ar->fw_features)) { 273 s->peer_rx_rate = 274 __le32_to_cpu(peer_stats->peer_rx_rate); 275 tmp += sizeof(struct wmi_peer_stats_10x); 276 277 } else { 278 tmp += sizeof(struct wmi_peer_stats_old); 279 } 280 } 281 } 282 283 spin_unlock_bh(&ar->data_lock); 284 complete(&ar->debug.event_stats_compl); 285 } 286 287 static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf, 288 size_t count, loff_t *ppos) 289 { 290 struct ath10k *ar = file->private_data; 291 struct ath10k_target_stats *fw_stats; 292 char *buf = NULL; 293 unsigned int len = 0, buf_len = 8000; 294 ssize_t ret_cnt = 0; 295 long left; 296 int i; 297 int ret; 298 299 fw_stats = &ar->debug.target_stats; 300 301 mutex_lock(&ar->conf_mutex); 302 303 if (ar->state != ATH10K_STATE_ON) 304 goto exit; 305 306 buf = kzalloc(buf_len, GFP_KERNEL); 307 if (!buf) 308 goto exit; 309 310 ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT); 311 if (ret) { 312 ath10k_warn("could not request stats (%d)\n", ret); 313 goto exit; 314 } 315 316 left = wait_for_completion_timeout(&ar->debug.event_stats_compl, 1*HZ); 317 if (left <= 0) 318 goto exit; 319 320 spin_lock_bh(&ar->data_lock); 321 len += scnprintf(buf + len, buf_len - len, "\n"); 322 len += scnprintf(buf + len, buf_len - len, "%30s\n", 323 "ath10k PDEV stats"); 324 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 325 "================="); 326 327 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 328 "Channel noise floor", fw_stats->ch_noise_floor); 329 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 330 "Channel TX power", fw_stats->chan_tx_power); 331 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 332 "TX frame count", fw_stats->tx_frame_count); 333 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 334 "RX frame count", fw_stats->rx_frame_count); 335 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 336 "RX clear count", fw_stats->rx_clear_count); 337 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 338 "Cycle count", fw_stats->cycle_count); 339 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 340 "PHY error count", fw_stats->phy_err_count); 341 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 342 "RTS bad count", fw_stats->rts_bad); 343 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 344 "RTS good count", fw_stats->rts_good); 345 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 346 "FCS bad count", fw_stats->fcs_bad); 347 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 348 "No beacon count", fw_stats->no_beacons); 349 len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", 350 "MIB int count", fw_stats->mib_int_count); 351 352 len += scnprintf(buf + len, buf_len - len, "\n"); 353 len += scnprintf(buf + len, buf_len - len, "%30s\n", 354 "ath10k PDEV TX stats"); 355 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 356 "================="); 357 358 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 359 "HTT cookies queued", fw_stats->comp_queued); 360 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 361 "HTT cookies disp.", fw_stats->comp_delivered); 362 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 363 "MSDU queued", fw_stats->msdu_enqued); 364 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 365 "MPDU queued", fw_stats->mpdu_enqued); 366 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 367 "MSDUs dropped", fw_stats->wmm_drop); 368 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 369 "Local enqued", fw_stats->local_enqued); 370 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 371 "Local freed", fw_stats->local_freed); 372 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 373 "HW queued", fw_stats->hw_queued); 374 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 375 "PPDUs reaped", fw_stats->hw_reaped); 376 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 377 "Num underruns", fw_stats->underrun); 378 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 379 "PPDUs cleaned", fw_stats->tx_abort); 380 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 381 "MPDUs requed", fw_stats->mpdus_requed); 382 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 383 "Excessive retries", fw_stats->tx_ko); 384 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 385 "HW rate", fw_stats->data_rc); 386 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 387 "Sched self tiggers", fw_stats->self_triggers); 388 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 389 "Dropped due to SW retries", 390 fw_stats->sw_retry_failure); 391 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 392 "Illegal rate phy errors", 393 fw_stats->illgl_rate_phy_err); 394 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 395 "Pdev continous xretry", fw_stats->pdev_cont_xretry); 396 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 397 "TX timeout", fw_stats->pdev_tx_timeout); 398 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 399 "PDEV resets", fw_stats->pdev_resets); 400 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 401 "PHY underrun", fw_stats->phy_underrun); 402 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 403 "MPDU is more than txop limit", fw_stats->txop_ovf); 404 405 len += scnprintf(buf + len, buf_len - len, "\n"); 406 len += scnprintf(buf + len, buf_len - len, "%30s\n", 407 "ath10k PDEV RX stats"); 408 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 409 "================="); 410 411 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 412 "Mid PPDU route change", 413 fw_stats->mid_ppdu_route_change); 414 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 415 "Tot. number of statuses", fw_stats->status_rcvd); 416 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 417 "Extra frags on rings 0", fw_stats->r0_frags); 418 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 419 "Extra frags on rings 1", fw_stats->r1_frags); 420 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 421 "Extra frags on rings 2", fw_stats->r2_frags); 422 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 423 "Extra frags on rings 3", fw_stats->r3_frags); 424 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 425 "MSDUs delivered to HTT", fw_stats->htt_msdus); 426 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 427 "MPDUs delivered to HTT", fw_stats->htt_mpdus); 428 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 429 "MSDUs delivered to stack", fw_stats->loc_msdus); 430 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 431 "MPDUs delivered to stack", fw_stats->loc_mpdus); 432 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 433 "Oversized AMSUs", fw_stats->oversize_amsdu); 434 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 435 "PHY errors", fw_stats->phy_errs); 436 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 437 "PHY errors drops", fw_stats->phy_err_drop); 438 len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", 439 "MPDU errors (FCS, MIC, ENC)", fw_stats->mpdu_errs); 440 441 len += scnprintf(buf + len, buf_len - len, "\n"); 442 len += scnprintf(buf + len, buf_len - len, "%30s (%d)\n", 443 "ath10k PEER stats", fw_stats->peers); 444 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 445 "================="); 446 447 for (i = 0; i < fw_stats->peers; i++) { 448 len += scnprintf(buf + len, buf_len - len, "%30s %pM\n", 449 "Peer MAC address", 450 fw_stats->peer_stat[i].peer_macaddr); 451 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 452 "Peer RSSI", fw_stats->peer_stat[i].peer_rssi); 453 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 454 "Peer TX rate", 455 fw_stats->peer_stat[i].peer_tx_rate); 456 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 457 "Peer RX rate", 458 fw_stats->peer_stat[i].peer_rx_rate); 459 len += scnprintf(buf + len, buf_len - len, "\n"); 460 } 461 spin_unlock_bh(&ar->data_lock); 462 463 if (len > buf_len) 464 len = buf_len; 465 466 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); 467 468 exit: 469 mutex_unlock(&ar->conf_mutex); 470 kfree(buf); 471 return ret_cnt; 472 } 473 474 static const struct file_operations fops_fw_stats = { 475 .read = ath10k_read_fw_stats, 476 .open = simple_open, 477 .owner = THIS_MODULE, 478 .llseek = default_llseek, 479 }; 480 481 static ssize_t ath10k_read_simulate_fw_crash(struct file *file, 482 char __user *user_buf, 483 size_t count, loff_t *ppos) 484 { 485 const char buf[] = "To simulate firmware crash write one of the" 486 " keywords to this file:\n `soft` - this will send" 487 " WMI_FORCE_FW_HANG_ASSERT to firmware if FW" 488 " supports that command.\n `hard` - this will send" 489 " to firmware command with illegal parameters" 490 " causing firmware crash.\n"; 491 492 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); 493 } 494 495 /* Simulate firmware crash: 496 * 'soft': Call wmi command causing firmware hang. This firmware hang is 497 * recoverable by warm firmware reset. 498 * 'hard': Force firmware crash by setting any vdev parameter for not allowed 499 * vdev id. This is hard firmware crash because it is recoverable only by cold 500 * firmware reset. 501 */ 502 static ssize_t ath10k_write_simulate_fw_crash(struct file *file, 503 const char __user *user_buf, 504 size_t count, loff_t *ppos) 505 { 506 struct ath10k *ar = file->private_data; 507 char buf[32]; 508 int ret; 509 510 mutex_lock(&ar->conf_mutex); 511 512 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 513 514 /* make sure that buf is null terminated */ 515 buf[sizeof(buf) - 1] = 0; 516 517 if (ar->state != ATH10K_STATE_ON && 518 ar->state != ATH10K_STATE_RESTARTED) { 519 ret = -ENETDOWN; 520 goto exit; 521 } 522 523 /* drop the possible '\n' from the end */ 524 if (buf[count - 1] == '\n') { 525 buf[count - 1] = 0; 526 count--; 527 } 528 529 if (!strcmp(buf, "soft")) { 530 ath10k_info("simulating soft firmware crash\n"); 531 ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0); 532 } else if (!strcmp(buf, "hard")) { 533 ath10k_info("simulating hard firmware crash\n"); 534 ret = ath10k_wmi_vdev_set_param(ar, TARGET_NUM_VDEVS + 1, 535 ar->wmi.vdev_param->rts_threshold, 0); 536 } else { 537 ret = -EINVAL; 538 goto exit; 539 } 540 541 if (ret) { 542 ath10k_warn("failed to simulate firmware crash: %d\n", ret); 543 goto exit; 544 } 545 546 ret = count; 547 548 exit: 549 mutex_unlock(&ar->conf_mutex); 550 return ret; 551 } 552 553 static const struct file_operations fops_simulate_fw_crash = { 554 .read = ath10k_read_simulate_fw_crash, 555 .write = ath10k_write_simulate_fw_crash, 556 .open = simple_open, 557 .owner = THIS_MODULE, 558 .llseek = default_llseek, 559 }; 560 561 static ssize_t ath10k_read_chip_id(struct file *file, char __user *user_buf, 562 size_t count, loff_t *ppos) 563 { 564 struct ath10k *ar = file->private_data; 565 unsigned int len; 566 char buf[50]; 567 568 len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->chip_id); 569 570 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 571 } 572 573 static const struct file_operations fops_chip_id = { 574 .read = ath10k_read_chip_id, 575 .open = simple_open, 576 .owner = THIS_MODULE, 577 .llseek = default_llseek, 578 }; 579 580 static int ath10k_debug_htt_stats_req(struct ath10k *ar) 581 { 582 u64 cookie; 583 int ret; 584 585 lockdep_assert_held(&ar->conf_mutex); 586 587 if (ar->debug.htt_stats_mask == 0) 588 /* htt stats are disabled */ 589 return 0; 590 591 if (ar->state != ATH10K_STATE_ON) 592 return 0; 593 594 cookie = get_jiffies_64(); 595 596 ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask, 597 cookie); 598 if (ret) { 599 ath10k_warn("failed to send htt stats request: %d\n", ret); 600 return ret; 601 } 602 603 queue_delayed_work(ar->workqueue, &ar->debug.htt_stats_dwork, 604 msecs_to_jiffies(ATH10K_DEBUG_HTT_STATS_INTERVAL)); 605 606 return 0; 607 } 608 609 static void ath10k_debug_htt_stats_dwork(struct work_struct *work) 610 { 611 struct ath10k *ar = container_of(work, struct ath10k, 612 debug.htt_stats_dwork.work); 613 614 mutex_lock(&ar->conf_mutex); 615 616 ath10k_debug_htt_stats_req(ar); 617 618 mutex_unlock(&ar->conf_mutex); 619 } 620 621 static ssize_t ath10k_read_htt_stats_mask(struct file *file, 622 char __user *user_buf, 623 size_t count, loff_t *ppos) 624 { 625 struct ath10k *ar = file->private_data; 626 char buf[32]; 627 unsigned int len; 628 629 len = scnprintf(buf, sizeof(buf), "%lu\n", ar->debug.htt_stats_mask); 630 631 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 632 } 633 634 static ssize_t ath10k_write_htt_stats_mask(struct file *file, 635 const char __user *user_buf, 636 size_t count, loff_t *ppos) 637 { 638 struct ath10k *ar = file->private_data; 639 unsigned long mask; 640 int ret; 641 642 ret = kstrtoul_from_user(user_buf, count, 0, &mask); 643 if (ret) 644 return ret; 645 646 /* max 8 bit masks (for now) */ 647 if (mask > 0xff) 648 return -E2BIG; 649 650 mutex_lock(&ar->conf_mutex); 651 652 ar->debug.htt_stats_mask = mask; 653 654 ret = ath10k_debug_htt_stats_req(ar); 655 if (ret) 656 goto out; 657 658 ret = count; 659 660 out: 661 mutex_unlock(&ar->conf_mutex); 662 663 return ret; 664 } 665 666 static const struct file_operations fops_htt_stats_mask = { 667 .read = ath10k_read_htt_stats_mask, 668 .write = ath10k_write_htt_stats_mask, 669 .open = simple_open, 670 .owner = THIS_MODULE, 671 .llseek = default_llseek, 672 }; 673 674 static ssize_t ath10k_read_fw_dbglog(struct file *file, 675 char __user *user_buf, 676 size_t count, loff_t *ppos) 677 { 678 struct ath10k *ar = file->private_data; 679 unsigned int len; 680 char buf[32]; 681 682 len = scnprintf(buf, sizeof(buf), "0x%08x\n", 683 ar->debug.fw_dbglog_mask); 684 685 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 686 } 687 688 static ssize_t ath10k_write_fw_dbglog(struct file *file, 689 const char __user *user_buf, 690 size_t count, loff_t *ppos) 691 { 692 struct ath10k *ar = file->private_data; 693 unsigned long mask; 694 int ret; 695 696 ret = kstrtoul_from_user(user_buf, count, 0, &mask); 697 if (ret) 698 return ret; 699 700 mutex_lock(&ar->conf_mutex); 701 702 ar->debug.fw_dbglog_mask = mask; 703 704 if (ar->state == ATH10K_STATE_ON) { 705 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); 706 if (ret) { 707 ath10k_warn("dbglog cfg failed from debugfs: %d\n", 708 ret); 709 goto exit; 710 } 711 } 712 713 ret = count; 714 715 exit: 716 mutex_unlock(&ar->conf_mutex); 717 718 return ret; 719 } 720 721 static const struct file_operations fops_fw_dbglog = { 722 .read = ath10k_read_fw_dbglog, 723 .write = ath10k_write_fw_dbglog, 724 .open = simple_open, 725 .owner = THIS_MODULE, 726 .llseek = default_llseek, 727 }; 728 729 int ath10k_debug_start(struct ath10k *ar) 730 { 731 int ret; 732 733 lockdep_assert_held(&ar->conf_mutex); 734 735 ret = ath10k_debug_htt_stats_req(ar); 736 if (ret) 737 /* continue normally anyway, this isn't serious */ 738 ath10k_warn("failed to start htt stats workqueue: %d\n", ret); 739 740 if (ar->debug.fw_dbglog_mask) { 741 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); 742 if (ret) 743 /* not serious */ 744 ath10k_warn("failed to enable dbglog during start: %d", 745 ret); 746 } 747 748 return 0; 749 } 750 751 void ath10k_debug_stop(struct ath10k *ar) 752 { 753 lockdep_assert_held(&ar->conf_mutex); 754 755 /* Must not use _sync to avoid deadlock, we do that in 756 * ath10k_debug_destroy(). The check for htt_stats_mask is to avoid 757 * warning from del_timer(). */ 758 if (ar->debug.htt_stats_mask != 0) 759 cancel_delayed_work(&ar->debug.htt_stats_dwork); 760 } 761 762 static ssize_t ath10k_write_simulate_radar(struct file *file, 763 const char __user *user_buf, 764 size_t count, loff_t *ppos) 765 { 766 struct ath10k *ar = file->private_data; 767 768 ieee80211_radar_detected(ar->hw); 769 770 return count; 771 } 772 773 static const struct file_operations fops_simulate_radar = { 774 .write = ath10k_write_simulate_radar, 775 .open = simple_open, 776 .owner = THIS_MODULE, 777 .llseek = default_llseek, 778 }; 779 780 #define ATH10K_DFS_STAT(s, p) (\ 781 len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \ 782 ar->debug.dfs_stats.p)) 783 784 #define ATH10K_DFS_POOL_STAT(s, p) (\ 785 len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \ 786 ar->debug.dfs_pool_stats.p)) 787 788 static ssize_t ath10k_read_dfs_stats(struct file *file, char __user *user_buf, 789 size_t count, loff_t *ppos) 790 { 791 int retval = 0, len = 0; 792 const int size = 8000; 793 struct ath10k *ar = file->private_data; 794 char *buf; 795 796 buf = kzalloc(size, GFP_KERNEL); 797 if (buf == NULL) 798 return -ENOMEM; 799 800 if (!ar->dfs_detector) { 801 len += scnprintf(buf + len, size - len, "DFS not enabled\n"); 802 goto exit; 803 } 804 805 ar->debug.dfs_pool_stats = 806 ar->dfs_detector->get_stats(ar->dfs_detector); 807 808 len += scnprintf(buf + len, size - len, "Pulse detector statistics:\n"); 809 810 ATH10K_DFS_STAT("reported phy errors", phy_errors); 811 ATH10K_DFS_STAT("pulse events reported", pulses_total); 812 ATH10K_DFS_STAT("DFS pulses detected", pulses_detected); 813 ATH10K_DFS_STAT("DFS pulses discarded", pulses_discarded); 814 ATH10K_DFS_STAT("Radars detected", radar_detected); 815 816 len += scnprintf(buf + len, size - len, "Global Pool statistics:\n"); 817 ATH10K_DFS_POOL_STAT("Pool references", pool_reference); 818 ATH10K_DFS_POOL_STAT("Pulses allocated", pulse_allocated); 819 ATH10K_DFS_POOL_STAT("Pulses alloc error", pulse_alloc_error); 820 ATH10K_DFS_POOL_STAT("Pulses in use", pulse_used); 821 ATH10K_DFS_POOL_STAT("Seqs. allocated", pseq_allocated); 822 ATH10K_DFS_POOL_STAT("Seqs. alloc error", pseq_alloc_error); 823 ATH10K_DFS_POOL_STAT("Seqs. in use", pseq_used); 824 825 exit: 826 if (len > size) 827 len = size; 828 829 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 830 kfree(buf); 831 832 return retval; 833 } 834 835 static const struct file_operations fops_dfs_stats = { 836 .read = ath10k_read_dfs_stats, 837 .open = simple_open, 838 .owner = THIS_MODULE, 839 .llseek = default_llseek, 840 }; 841 842 int ath10k_debug_create(struct ath10k *ar) 843 { 844 ar->debug.debugfs_phy = debugfs_create_dir("ath10k", 845 ar->hw->wiphy->debugfsdir); 846 847 if (!ar->debug.debugfs_phy) 848 return -ENOMEM; 849 850 INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork, 851 ath10k_debug_htt_stats_dwork); 852 853 init_completion(&ar->debug.event_stats_compl); 854 855 debugfs_create_file("fw_stats", S_IRUSR, ar->debug.debugfs_phy, ar, 856 &fops_fw_stats); 857 858 debugfs_create_file("wmi_services", S_IRUSR, ar->debug.debugfs_phy, ar, 859 &fops_wmi_services); 860 861 debugfs_create_file("simulate_fw_crash", S_IRUSR, ar->debug.debugfs_phy, 862 ar, &fops_simulate_fw_crash); 863 864 debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy, 865 ar, &fops_chip_id); 866 867 debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy, 868 ar, &fops_htt_stats_mask); 869 870 debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy, 871 ar, &fops_fw_dbglog); 872 873 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) { 874 debugfs_create_file("dfs_simulate_radar", S_IWUSR, 875 ar->debug.debugfs_phy, ar, 876 &fops_simulate_radar); 877 878 debugfs_create_bool("dfs_block_radar_events", S_IWUSR, 879 ar->debug.debugfs_phy, 880 &ar->dfs_block_radar_events); 881 882 debugfs_create_file("dfs_stats", S_IRUSR, 883 ar->debug.debugfs_phy, ar, 884 &fops_dfs_stats); 885 } 886 887 return 0; 888 } 889 890 void ath10k_debug_destroy(struct ath10k *ar) 891 { 892 cancel_delayed_work_sync(&ar->debug.htt_stats_dwork); 893 } 894 895 #endif /* CONFIG_ATH10K_DEBUGFS */ 896 897 #ifdef CONFIG_ATH10K_DEBUG 898 void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...) 899 { 900 struct va_format vaf; 901 va_list args; 902 903 va_start(args, fmt); 904 905 vaf.fmt = fmt; 906 vaf.va = &args; 907 908 if (ath10k_debug_mask & mask) 909 ath10k_printk(KERN_DEBUG, "%pV", &vaf); 910 911 trace_ath10k_log_dbg(mask, &vaf); 912 913 va_end(args); 914 } 915 EXPORT_SYMBOL(ath10k_dbg); 916 917 void ath10k_dbg_dump(enum ath10k_debug_mask mask, 918 const char *msg, const char *prefix, 919 const void *buf, size_t len) 920 { 921 if (ath10k_debug_mask & mask) { 922 if (msg) 923 ath10k_dbg(mask, "%s\n", msg); 924 925 print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); 926 } 927 928 /* tracing code doesn't like null strings :/ */ 929 trace_ath10k_log_dbg_dump(msg ? msg : "", prefix ? prefix : "", 930 buf, len); 931 } 932 EXPORT_SYMBOL(ath10k_dbg_dump); 933 934 #endif /* CONFIG_ATH10K_DEBUG */ 935