linux/drivers/net/wireless/ath/ath10k/debug.c
<<
>>
Prefs
   1// SPDX-License-Identifier: ISC
   2/*
   3 * Copyright (c) 2005-2011 Atheros Communications Inc.
   4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
   5 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
   6 */
   7
   8#include <linux/module.h>
   9#include <linux/debugfs.h>
  10#include <linux/vmalloc.h>
  11#include <linux/crc32.h>
  12#include <linux/firmware.h>
  13
  14#include "core.h"
  15#include "debug.h"
  16#include "hif.h"
  17#include "wmi-ops.h"
  18
  19/* ms */
  20#define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
  21
  22#define ATH10K_DEBUG_CAL_DATA_LEN 12064
  23
  24void ath10k_info(struct ath10k *ar, const char *fmt, ...)
  25{
  26        struct va_format vaf = {
  27                .fmt = fmt,
  28        };
  29        va_list args;
  30
  31        va_start(args, fmt);
  32        vaf.va = &args;
  33        dev_info(ar->dev, "%pV", &vaf);
  34        trace_ath10k_log_info(ar, &vaf);
  35        va_end(args);
  36}
  37EXPORT_SYMBOL(ath10k_info);
  38
  39void ath10k_debug_print_hwfw_info(struct ath10k *ar)
  40{
  41        const struct firmware *firmware;
  42        char fw_features[128] = {};
  43        u32 crc = 0;
  44
  45        ath10k_core_get_fw_features_str(ar, fw_features, sizeof(fw_features));
  46
  47        ath10k_info(ar, "%s target 0x%08x chip_id 0x%08x sub %04x:%04x",
  48                    ar->hw_params.name,
  49                    ar->target_version,
  50                    ar->bus_param.chip_id,
  51                    ar->id.subsystem_vendor, ar->id.subsystem_device);
  52
  53        ath10k_info(ar, "kconfig debug %d debugfs %d tracing %d dfs %d testmode %d\n",
  54                    IS_ENABLED(CONFIG_ATH10K_DEBUG),
  55                    IS_ENABLED(CONFIG_ATH10K_DEBUGFS),
  56                    IS_ENABLED(CONFIG_ATH10K_TRACING),
  57                    IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED),
  58                    IS_ENABLED(CONFIG_NL80211_TESTMODE));
  59
  60        firmware = ar->normal_mode_fw.fw_file.firmware;
  61        if (firmware)
  62                crc = crc32_le(0, firmware->data, firmware->size);
  63
  64        ath10k_info(ar, "firmware ver %s api %d features %s crc32 %08x\n",
  65                    ar->hw->wiphy->fw_version,
  66                    ar->fw_api,
  67                    fw_features,
  68                    crc);
  69}
  70
  71void ath10k_debug_print_board_info(struct ath10k *ar)
  72{
  73        char boardinfo[100];
  74        const struct firmware *board;
  75        u32 crc;
  76
  77        if (ar->id.bmi_ids_valid)
  78                scnprintf(boardinfo, sizeof(boardinfo), "%d:%d",
  79                          ar->id.bmi_chip_id, ar->id.bmi_board_id);
  80        else
  81                scnprintf(boardinfo, sizeof(boardinfo), "N/A");
  82
  83        board = ar->normal_mode_fw.board;
  84        if (!IS_ERR_OR_NULL(board))
  85                crc = crc32_le(0, board->data, board->size);
  86        else
  87                crc = 0;
  88
  89        ath10k_info(ar, "board_file api %d bmi_id %s crc32 %08x",
  90                    ar->bd_api,
  91                    boardinfo,
  92                    crc);
  93}
  94
  95void ath10k_debug_print_boot_info(struct ath10k *ar)
  96{
  97        ath10k_info(ar, "htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d raw %d hwcrypto %d\n",
  98                    ar->htt.target_version_major,
  99                    ar->htt.target_version_minor,
 100                    ar->normal_mode_fw.fw_file.wmi_op_version,
 101                    ar->normal_mode_fw.fw_file.htt_op_version,
 102                    ath10k_cal_mode_str(ar->cal_mode),
 103                    ar->max_num_stations,
 104                    test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags),
 105                    !test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags));
 106}
 107
 108void ath10k_print_driver_info(struct ath10k *ar)
 109{
 110        ath10k_debug_print_hwfw_info(ar);
 111        ath10k_debug_print_board_info(ar);
 112        ath10k_debug_print_boot_info(ar);
 113}
 114EXPORT_SYMBOL(ath10k_print_driver_info);
 115
 116void ath10k_err(struct ath10k *ar, const char *fmt, ...)
 117{
 118        struct va_format vaf = {
 119                .fmt = fmt,
 120        };
 121        va_list args;
 122
 123        va_start(args, fmt);
 124        vaf.va = &args;
 125        dev_err(ar->dev, "%pV", &vaf);
 126        trace_ath10k_log_err(ar, &vaf);
 127        va_end(args);
 128}
 129EXPORT_SYMBOL(ath10k_err);
 130
 131void ath10k_warn(struct ath10k *ar, const char *fmt, ...)
 132{
 133        struct va_format vaf = {
 134                .fmt = fmt,
 135        };
 136        va_list args;
 137
 138        va_start(args, fmt);
 139        vaf.va = &args;
 140        dev_warn_ratelimited(ar->dev, "%pV", &vaf);
 141        trace_ath10k_log_warn(ar, &vaf);
 142
 143        va_end(args);
 144}
 145EXPORT_SYMBOL(ath10k_warn);
 146
 147#ifdef CONFIG_ATH10K_DEBUGFS
 148
 149static ssize_t ath10k_read_wmi_services(struct file *file,
 150                                        char __user *user_buf,
 151                                        size_t count, loff_t *ppos)
 152{
 153        struct ath10k *ar = file->private_data;
 154        char *buf;
 155        size_t len = 0, buf_len = 8192;
 156        const char *name;
 157        ssize_t ret_cnt;
 158        bool enabled;
 159        int i;
 160
 161        buf = kzalloc(buf_len, GFP_KERNEL);
 162        if (!buf)
 163                return -ENOMEM;
 164
 165        mutex_lock(&ar->conf_mutex);
 166
 167        spin_lock_bh(&ar->data_lock);
 168        for (i = 0; i < WMI_SERVICE_MAX; i++) {
 169                enabled = test_bit(i, ar->wmi.svc_map);
 170                name = wmi_service_name(i);
 171
 172                if (!name) {
 173                        if (enabled)
 174                                len += scnprintf(buf + len, buf_len - len,
 175                                                 "%-40s %s (bit %d)\n",
 176                                                 "unknown", "enabled", i);
 177
 178                        continue;
 179                }
 180
 181                len += scnprintf(buf + len, buf_len - len,
 182                                 "%-40s %s\n",
 183                                 name, enabled ? "enabled" : "-");
 184        }
 185        spin_unlock_bh(&ar->data_lock);
 186
 187        ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
 188
 189        mutex_unlock(&ar->conf_mutex);
 190
 191        kfree(buf);
 192        return ret_cnt;
 193}
 194
 195static const struct file_operations fops_wmi_services = {
 196        .read = ath10k_read_wmi_services,
 197        .open = simple_open,
 198        .owner = THIS_MODULE,
 199        .llseek = default_llseek,
 200};
 201
 202static void ath10k_fw_stats_pdevs_free(struct list_head *head)
 203{
 204        struct ath10k_fw_stats_pdev *i, *tmp;
 205
 206        list_for_each_entry_safe(i, tmp, head, list) {
 207                list_del(&i->list);
 208                kfree(i);
 209        }
 210}
 211
 212static void ath10k_fw_stats_vdevs_free(struct list_head *head)
 213{
 214        struct ath10k_fw_stats_vdev *i, *tmp;
 215
 216        list_for_each_entry_safe(i, tmp, head, list) {
 217                list_del(&i->list);
 218                kfree(i);
 219        }
 220}
 221
 222static void ath10k_fw_stats_peers_free(struct list_head *head)
 223{
 224        struct ath10k_fw_stats_peer *i, *tmp;
 225
 226        list_for_each_entry_safe(i, tmp, head, list) {
 227                list_del(&i->list);
 228                kfree(i);
 229        }
 230}
 231
 232static void ath10k_fw_extd_stats_peers_free(struct list_head *head)
 233{
 234        struct ath10k_fw_extd_stats_peer *i, *tmp;
 235
 236        list_for_each_entry_safe(i, tmp, head, list) {
 237                list_del(&i->list);
 238                kfree(i);
 239        }
 240}
 241
 242static void ath10k_debug_fw_stats_reset(struct ath10k *ar)
 243{
 244        spin_lock_bh(&ar->data_lock);
 245        ar->debug.fw_stats_done = false;
 246        ar->debug.fw_stats.extended = false;
 247        ath10k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
 248        ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
 249        ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers);
 250        ath10k_fw_extd_stats_peers_free(&ar->debug.fw_stats.peers_extd);
 251        spin_unlock_bh(&ar->data_lock);
 252}
 253
 254void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
 255{
 256        struct ath10k_fw_stats stats = {};
 257        bool is_start, is_started, is_end;
 258        size_t num_peers;
 259        size_t num_vdevs;
 260        int ret;
 261
 262        INIT_LIST_HEAD(&stats.pdevs);
 263        INIT_LIST_HEAD(&stats.vdevs);
 264        INIT_LIST_HEAD(&stats.peers);
 265        INIT_LIST_HEAD(&stats.peers_extd);
 266
 267        spin_lock_bh(&ar->data_lock);
 268        ret = ath10k_wmi_pull_fw_stats(ar, skb, &stats);
 269        if (ret) {
 270                ath10k_warn(ar, "failed to pull fw stats: %d\n", ret);
 271                goto free;
 272        }
 273
 274        /* Stat data may exceed htc-wmi buffer limit. In such case firmware
 275         * splits the stats data and delivers it in a ping-pong fashion of
 276         * request cmd-update event.
 277         *
 278         * However there is no explicit end-of-data. Instead start-of-data is
 279         * used as an implicit one. This works as follows:
 280         *  a) discard stat update events until one with pdev stats is
 281         *     delivered - this skips session started at end of (b)
 282         *  b) consume stat update events until another one with pdev stats is
 283         *     delivered which is treated as end-of-data and is itself discarded
 284         */
 285        if (ath10k_peer_stats_enabled(ar))
 286                ath10k_sta_update_rx_duration(ar, &stats);
 287
 288        if (ar->debug.fw_stats_done) {
 289                if (!ath10k_peer_stats_enabled(ar))
 290                        ath10k_warn(ar, "received unsolicited stats update event\n");
 291
 292                goto free;
 293        }
 294
 295        num_peers = ath10k_wmi_fw_stats_num_peers(&ar->debug.fw_stats.peers);
 296        num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs);
 297        is_start = (list_empty(&ar->debug.fw_stats.pdevs) &&
 298                    !list_empty(&stats.pdevs));
 299        is_end = (!list_empty(&ar->debug.fw_stats.pdevs) &&
 300                  !list_empty(&stats.pdevs));
 301
 302        if (is_start)
 303                list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs);
 304
 305        if (is_end)
 306                ar->debug.fw_stats_done = true;
 307
 308        if (stats.extended)
 309                ar->debug.fw_stats.extended = true;
 310
 311        is_started = !list_empty(&ar->debug.fw_stats.pdevs);
 312
 313        if (is_started && !is_end) {
 314                if (num_peers >= ATH10K_MAX_NUM_PEER_IDS) {
 315                        /* Although this is unlikely impose a sane limit to
 316                         * prevent firmware from DoS-ing the host.
 317                         */
 318                        ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers);
 319                        ath10k_fw_extd_stats_peers_free(&ar->debug.fw_stats.peers_extd);
 320                        ath10k_warn(ar, "dropping fw peer stats\n");
 321                        goto free;
 322                }
 323
 324                if (num_vdevs >= BITS_PER_LONG) {
 325                        ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
 326                        ath10k_warn(ar, "dropping fw vdev stats\n");
 327                        goto free;
 328                }
 329
 330                if (!list_empty(&stats.peers))
 331                        list_splice_tail_init(&stats.peers_extd,
 332                                              &ar->debug.fw_stats.peers_extd);
 333
 334                list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers);
 335                list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs);
 336        }
 337
 338        complete(&ar->debug.fw_stats_complete);
 339
 340free:
 341        /* In some cases lists have been spliced and cleared. Free up
 342         * resources if that is not the case.
 343         */
 344        ath10k_fw_stats_pdevs_free(&stats.pdevs);
 345        ath10k_fw_stats_vdevs_free(&stats.vdevs);
 346        ath10k_fw_stats_peers_free(&stats.peers);
 347        ath10k_fw_extd_stats_peers_free(&stats.peers_extd);
 348
 349        spin_unlock_bh(&ar->data_lock);
 350}
 351
 352static int ath10k_debug_fw_stats_request(struct ath10k *ar)
 353{
 354        unsigned long timeout, time_left;
 355        int ret;
 356
 357        lockdep_assert_held(&ar->conf_mutex);
 358
 359        timeout = jiffies + msecs_to_jiffies(1 * HZ);
 360
 361        ath10k_debug_fw_stats_reset(ar);
 362
 363        for (;;) {
 364                if (time_after(jiffies, timeout))
 365                        return -ETIMEDOUT;
 366
 367                reinit_completion(&ar->debug.fw_stats_complete);
 368
 369                ret = ath10k_wmi_request_stats(ar, ar->fw_stats_req_mask);
 370                if (ret) {
 371                        ath10k_warn(ar, "could not request stats (%d)\n", ret);
 372                        return ret;
 373                }
 374
 375                time_left =
 376                wait_for_completion_timeout(&ar->debug.fw_stats_complete,
 377                                            1 * HZ);
 378                if (!time_left)
 379                        return -ETIMEDOUT;
 380
 381                spin_lock_bh(&ar->data_lock);
 382                if (ar->debug.fw_stats_done) {
 383                        spin_unlock_bh(&ar->data_lock);
 384                        break;
 385                }
 386                spin_unlock_bh(&ar->data_lock);
 387        }
 388
 389        return 0;
 390}
 391
 392static int ath10k_fw_stats_open(struct inode *inode, struct file *file)
 393{
 394        struct ath10k *ar = inode->i_private;
 395        void *buf = NULL;
 396        int ret;
 397
 398        mutex_lock(&ar->conf_mutex);
 399
 400        if (ar->state != ATH10K_STATE_ON) {
 401                ret = -ENETDOWN;
 402                goto err_unlock;
 403        }
 404
 405        buf = vmalloc(ATH10K_FW_STATS_BUF_SIZE);
 406        if (!buf) {
 407                ret = -ENOMEM;
 408                goto err_unlock;
 409        }
 410
 411        ret = ath10k_debug_fw_stats_request(ar);
 412        if (ret) {
 413                ath10k_warn(ar, "failed to request fw stats: %d\n", ret);
 414                goto err_free;
 415        }
 416
 417        ret = ath10k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, buf);
 418        if (ret) {
 419                ath10k_warn(ar, "failed to fill fw stats: %d\n", ret);
 420                goto err_free;
 421        }
 422
 423        file->private_data = buf;
 424
 425        mutex_unlock(&ar->conf_mutex);
 426        return 0;
 427
 428err_free:
 429        vfree(buf);
 430
 431err_unlock:
 432        mutex_unlock(&ar->conf_mutex);
 433        return ret;
 434}
 435
 436static int ath10k_fw_stats_release(struct inode *inode, struct file *file)
 437{
 438        vfree(file->private_data);
 439
 440        return 0;
 441}
 442
 443static ssize_t ath10k_fw_stats_read(struct file *file, char __user *user_buf,
 444                                    size_t count, loff_t *ppos)
 445{
 446        const char *buf = file->private_data;
 447        size_t len = strlen(buf);
 448
 449        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 450}
 451
 452static const struct file_operations fops_fw_stats = {
 453        .open = ath10k_fw_stats_open,
 454        .release = ath10k_fw_stats_release,
 455        .read = ath10k_fw_stats_read,
 456        .owner = THIS_MODULE,
 457        .llseek = default_llseek,
 458};
 459
 460static ssize_t ath10k_debug_fw_reset_stats_read(struct file *file,
 461                                                char __user *user_buf,
 462                                                size_t count, loff_t *ppos)
 463{
 464        struct ath10k *ar = file->private_data;
 465        int ret;
 466        size_t len = 0, buf_len = 500;
 467        char *buf;
 468
 469        buf = kmalloc(buf_len, GFP_KERNEL);
 470        if (!buf)
 471                return -ENOMEM;
 472
 473        spin_lock_bh(&ar->data_lock);
 474
 475        len += scnprintf(buf + len, buf_len - len,
 476                         "fw_crash_counter\t\t%d\n", ar->stats.fw_crash_counter);
 477        len += scnprintf(buf + len, buf_len - len,
 478                         "fw_warm_reset_counter\t\t%d\n",
 479                         ar->stats.fw_warm_reset_counter);
 480        len += scnprintf(buf + len, buf_len - len,
 481                         "fw_cold_reset_counter\t\t%d\n",
 482                         ar->stats.fw_cold_reset_counter);
 483
 484        spin_unlock_bh(&ar->data_lock);
 485
 486        ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
 487
 488        kfree(buf);
 489
 490        return ret;
 491}
 492
 493static const struct file_operations fops_fw_reset_stats = {
 494        .open = simple_open,
 495        .read = ath10k_debug_fw_reset_stats_read,
 496        .owner = THIS_MODULE,
 497        .llseek = default_llseek,
 498};
 499
 500/* This is a clean assert crash in firmware. */
 501static int ath10k_debug_fw_assert(struct ath10k *ar)
 502{
 503        struct wmi_vdev_install_key_cmd *cmd;
 504        struct sk_buff *skb;
 505
 506        skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + 16);
 507        if (!skb)
 508                return -ENOMEM;
 509
 510        cmd = (struct wmi_vdev_install_key_cmd *)skb->data;
 511        memset(cmd, 0, sizeof(*cmd));
 512
 513        /* big enough number so that firmware asserts */
 514        cmd->vdev_id = __cpu_to_le32(0x7ffe);
 515
 516        return ath10k_wmi_cmd_send(ar, skb,
 517                                   ar->wmi.cmd->vdev_install_key_cmdid);
 518}
 519
 520static ssize_t ath10k_read_simulate_fw_crash(struct file *file,
 521                                             char __user *user_buf,
 522                                             size_t count, loff_t *ppos)
 523{
 524        const char buf[] =
 525                "To simulate firmware crash write one of the keywords to this file:\n"
 526                "`soft` - this will send WMI_FORCE_FW_HANG_ASSERT to firmware if FW supports that command.\n"
 527                "`hard` - this will send to firmware command with illegal parameters causing firmware crash.\n"
 528                "`assert` - this will send special illegal parameter to firmware to cause assert failure and crash.\n"
 529                "`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n";
 530
 531        return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
 532}
 533
 534/* Simulate firmware crash:
 535 * 'soft': Call wmi command causing firmware hang. This firmware hang is
 536 * recoverable by warm firmware reset.
 537 * 'hard': Force firmware crash by setting any vdev parameter for not allowed
 538 * vdev id. This is hard firmware crash because it is recoverable only by cold
 539 * firmware reset.
 540 */
 541static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
 542                                              const char __user *user_buf,
 543                                              size_t count, loff_t *ppos)
 544{
 545        struct ath10k *ar = file->private_data;
 546        char buf[32] = {0};
 547        ssize_t rc;
 548        int ret;
 549
 550        /* filter partial writes and invalid commands */
 551        if (*ppos != 0 || count >= sizeof(buf) || count == 0)
 552                return -EINVAL;
 553
 554        rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
 555        if (rc < 0)
 556                return rc;
 557
 558        /* drop the possible '\n' from the end */
 559        if (buf[*ppos - 1] == '\n')
 560                buf[*ppos - 1] = '\0';
 561
 562        mutex_lock(&ar->conf_mutex);
 563
 564        if (ar->state != ATH10K_STATE_ON &&
 565            ar->state != ATH10K_STATE_RESTARTED) {
 566                ret = -ENETDOWN;
 567                goto exit;
 568        }
 569
 570        if (!strcmp(buf, "soft")) {
 571                ath10k_info(ar, "simulating soft firmware crash\n");
 572                ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0);
 573        } else if (!strcmp(buf, "hard")) {
 574                ath10k_info(ar, "simulating hard firmware crash\n");
 575                /* 0x7fff is vdev id, and it is always out of range for all
 576                 * firmware variants in order to force a firmware crash.
 577                 */
 578                ret = ath10k_wmi_vdev_set_param(ar, 0x7fff,
 579                                                ar->wmi.vdev_param->rts_threshold,
 580                                                0);
 581        } else if (!strcmp(buf, "assert")) {
 582                ath10k_info(ar, "simulating firmware assert crash\n");
 583                ret = ath10k_debug_fw_assert(ar);
 584        } else if (!strcmp(buf, "hw-restart")) {
 585                ath10k_info(ar, "user requested hw restart\n");
 586                queue_work(ar->workqueue, &ar->restart_work);
 587                ret = 0;
 588        } else {
 589                ret = -EINVAL;
 590                goto exit;
 591        }
 592
 593        if (ret) {
 594                ath10k_warn(ar, "failed to simulate firmware crash: %d\n", ret);
 595                goto exit;
 596        }
 597
 598        ret = count;
 599
 600exit:
 601        mutex_unlock(&ar->conf_mutex);
 602        return ret;
 603}
 604
 605static const struct file_operations fops_simulate_fw_crash = {
 606        .read = ath10k_read_simulate_fw_crash,
 607        .write = ath10k_write_simulate_fw_crash,
 608        .open = simple_open,
 609        .owner = THIS_MODULE,
 610        .llseek = default_llseek,
 611};
 612
 613static ssize_t ath10k_read_chip_id(struct file *file, char __user *user_buf,
 614                                   size_t count, loff_t *ppos)
 615{
 616        struct ath10k *ar = file->private_data;
 617        size_t len;
 618        char buf[50];
 619
 620        len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->bus_param.chip_id);
 621
 622        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 623}
 624
 625static const struct file_operations fops_chip_id = {
 626        .read = ath10k_read_chip_id,
 627        .open = simple_open,
 628        .owner = THIS_MODULE,
 629        .llseek = default_llseek,
 630};
 631
 632static ssize_t ath10k_reg_addr_read(struct file *file,
 633                                    char __user *user_buf,
 634                                    size_t count, loff_t *ppos)
 635{
 636        struct ath10k *ar = file->private_data;
 637        u8 buf[32];
 638        size_t len = 0;
 639        u32 reg_addr;
 640
 641        mutex_lock(&ar->conf_mutex);
 642        reg_addr = ar->debug.reg_addr;
 643        mutex_unlock(&ar->conf_mutex);
 644
 645        len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n", reg_addr);
 646
 647        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 648}
 649
 650static ssize_t ath10k_reg_addr_write(struct file *file,
 651                                     const char __user *user_buf,
 652                                     size_t count, loff_t *ppos)
 653{
 654        struct ath10k *ar = file->private_data;
 655        u32 reg_addr;
 656        int ret;
 657
 658        ret = kstrtou32_from_user(user_buf, count, 0, &reg_addr);
 659        if (ret)
 660                return ret;
 661
 662        if (!IS_ALIGNED(reg_addr, 4))
 663                return -EFAULT;
 664
 665        mutex_lock(&ar->conf_mutex);
 666        ar->debug.reg_addr = reg_addr;
 667        mutex_unlock(&ar->conf_mutex);
 668
 669        return count;
 670}
 671
 672static const struct file_operations fops_reg_addr = {
 673        .read = ath10k_reg_addr_read,
 674        .write = ath10k_reg_addr_write,
 675        .open = simple_open,
 676        .owner = THIS_MODULE,
 677        .llseek = default_llseek,
 678};
 679
 680static ssize_t ath10k_reg_value_read(struct file *file,
 681                                     char __user *user_buf,
 682                                     size_t count, loff_t *ppos)
 683{
 684        struct ath10k *ar = file->private_data;
 685        u8 buf[48];
 686        size_t len;
 687        u32 reg_addr, reg_val;
 688        int ret;
 689
 690        mutex_lock(&ar->conf_mutex);
 691
 692        if (ar->state != ATH10K_STATE_ON &&
 693            ar->state != ATH10K_STATE_UTF) {
 694                ret = -ENETDOWN;
 695                goto exit;
 696        }
 697
 698        reg_addr = ar->debug.reg_addr;
 699
 700        reg_val = ath10k_hif_read32(ar, reg_addr);
 701        len = scnprintf(buf, sizeof(buf), "0x%08x:0x%08x\n", reg_addr, reg_val);
 702
 703        ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
 704
 705exit:
 706        mutex_unlock(&ar->conf_mutex);
 707
 708        return ret;
 709}
 710
 711static ssize_t ath10k_reg_value_write(struct file *file,
 712                                      const char __user *user_buf,
 713                                      size_t count, loff_t *ppos)
 714{
 715        struct ath10k *ar = file->private_data;
 716        u32 reg_addr, reg_val;
 717        int ret;
 718
 719        mutex_lock(&ar->conf_mutex);
 720
 721        if (ar->state != ATH10K_STATE_ON &&
 722            ar->state != ATH10K_STATE_UTF) {
 723                ret = -ENETDOWN;
 724                goto exit;
 725        }
 726
 727        reg_addr = ar->debug.reg_addr;
 728
 729        ret = kstrtou32_from_user(user_buf, count, 0, &reg_val);
 730        if (ret)
 731                goto exit;
 732
 733        ath10k_hif_write32(ar, reg_addr, reg_val);
 734
 735        ret = count;
 736
 737exit:
 738        mutex_unlock(&ar->conf_mutex);
 739
 740        return ret;
 741}
 742
 743static const struct file_operations fops_reg_value = {
 744        .read = ath10k_reg_value_read,
 745        .write = ath10k_reg_value_write,
 746        .open = simple_open,
 747        .owner = THIS_MODULE,
 748        .llseek = default_llseek,
 749};
 750
 751static ssize_t ath10k_mem_value_read(struct file *file,
 752                                     char __user *user_buf,
 753                                     size_t count, loff_t *ppos)
 754{
 755        struct ath10k *ar = file->private_data;
 756        u8 *buf;
 757        int ret;
 758
 759        if (*ppos < 0)
 760                return -EINVAL;
 761
 762        if (!count)
 763                return 0;
 764
 765        mutex_lock(&ar->conf_mutex);
 766
 767        buf = vmalloc(count);
 768        if (!buf) {
 769                ret = -ENOMEM;
 770                goto exit;
 771        }
 772
 773        if (ar->state != ATH10K_STATE_ON &&
 774            ar->state != ATH10K_STATE_UTF) {
 775                ret = -ENETDOWN;
 776                goto exit;
 777        }
 778
 779        ret = ath10k_hif_diag_read(ar, *ppos, buf, count);
 780        if (ret) {
 781                ath10k_warn(ar, "failed to read address 0x%08x via diagnose window fnrom debugfs: %d\n",
 782                            (u32)(*ppos), ret);
 783                goto exit;
 784        }
 785
 786        ret = copy_to_user(user_buf, buf, count);
 787        if (ret) {
 788                ret = -EFAULT;
 789                goto exit;
 790        }
 791
 792        count -= ret;
 793        *ppos += count;
 794        ret = count;
 795
 796exit:
 797        vfree(buf);
 798        mutex_unlock(&ar->conf_mutex);
 799
 800        return ret;
 801}
 802
 803static ssize_t ath10k_mem_value_write(struct file *file,
 804                                      const char __user *user_buf,
 805                                      size_t count, loff_t *ppos)
 806{
 807        struct ath10k *ar = file->private_data;
 808        u8 *buf;
 809        int ret;
 810
 811        if (*ppos < 0)
 812                return -EINVAL;
 813
 814        if (!count)
 815                return 0;
 816
 817        mutex_lock(&ar->conf_mutex);
 818
 819        buf = vmalloc(count);
 820        if (!buf) {
 821                ret = -ENOMEM;
 822                goto exit;
 823        }
 824
 825        if (ar->state != ATH10K_STATE_ON &&
 826            ar->state != ATH10K_STATE_UTF) {
 827                ret = -ENETDOWN;
 828                goto exit;
 829        }
 830
 831        ret = copy_from_user(buf, user_buf, count);
 832        if (ret) {
 833                ret = -EFAULT;
 834                goto exit;
 835        }
 836
 837        ret = ath10k_hif_diag_write(ar, *ppos, buf, count);
 838        if (ret) {
 839                ath10k_warn(ar, "failed to write address 0x%08x via diagnose window from debugfs: %d\n",
 840                            (u32)(*ppos), ret);
 841                goto exit;
 842        }
 843
 844        *ppos += count;
 845        ret = count;
 846
 847exit:
 848        vfree(buf);
 849        mutex_unlock(&ar->conf_mutex);
 850
 851        return ret;
 852}
 853
 854static const struct file_operations fops_mem_value = {
 855        .read = ath10k_mem_value_read,
 856        .write = ath10k_mem_value_write,
 857        .open = simple_open,
 858        .owner = THIS_MODULE,
 859        .llseek = default_llseek,
 860};
 861
 862static int ath10k_debug_htt_stats_req(struct ath10k *ar)
 863{
 864        u64 cookie;
 865        int ret;
 866
 867        lockdep_assert_held(&ar->conf_mutex);
 868
 869        if (ar->debug.htt_stats_mask == 0)
 870                /* htt stats are disabled */
 871                return 0;
 872
 873        if (ar->state != ATH10K_STATE_ON)
 874                return 0;
 875
 876        cookie = get_jiffies_64();
 877
 878        ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask,
 879                                       ar->debug.reset_htt_stats, cookie);
 880        if (ret) {
 881                ath10k_warn(ar, "failed to send htt stats request: %d\n", ret);
 882                return ret;
 883        }
 884
 885        queue_delayed_work(ar->workqueue, &ar->debug.htt_stats_dwork,
 886                           msecs_to_jiffies(ATH10K_DEBUG_HTT_STATS_INTERVAL));
 887
 888        return 0;
 889}
 890
 891static void ath10k_debug_htt_stats_dwork(struct work_struct *work)
 892{
 893        struct ath10k *ar = container_of(work, struct ath10k,
 894                                         debug.htt_stats_dwork.work);
 895
 896        mutex_lock(&ar->conf_mutex);
 897
 898        ath10k_debug_htt_stats_req(ar);
 899
 900        mutex_unlock(&ar->conf_mutex);
 901}
 902
 903static ssize_t ath10k_read_htt_stats_mask(struct file *file,
 904                                          char __user *user_buf,
 905                                          size_t count, loff_t *ppos)
 906{
 907        struct ath10k *ar = file->private_data;
 908        char buf[32];
 909        size_t len;
 910
 911        len = scnprintf(buf, sizeof(buf), "%lu\n", ar->debug.htt_stats_mask);
 912
 913        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 914}
 915
 916static ssize_t ath10k_write_htt_stats_mask(struct file *file,
 917                                           const char __user *user_buf,
 918                                           size_t count, loff_t *ppos)
 919{
 920        struct ath10k *ar = file->private_data;
 921        unsigned long mask;
 922        int ret;
 923
 924        ret = kstrtoul_from_user(user_buf, count, 0, &mask);
 925        if (ret)
 926                return ret;
 927
 928        /* max 17 bit masks (for now) */
 929        if (mask > HTT_STATS_BIT_MASK)
 930                return -E2BIG;
 931
 932        mutex_lock(&ar->conf_mutex);
 933
 934        ar->debug.htt_stats_mask = mask;
 935
 936        ret = ath10k_debug_htt_stats_req(ar);
 937        if (ret)
 938                goto out;
 939
 940        ret = count;
 941
 942out:
 943        mutex_unlock(&ar->conf_mutex);
 944
 945        return ret;
 946}
 947
 948static const struct file_operations fops_htt_stats_mask = {
 949        .read = ath10k_read_htt_stats_mask,
 950        .write = ath10k_write_htt_stats_mask,
 951        .open = simple_open,
 952        .owner = THIS_MODULE,
 953        .llseek = default_llseek,
 954};
 955
 956static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file,
 957                                               char __user *user_buf,
 958                                               size_t count, loff_t *ppos)
 959{
 960        struct ath10k *ar = file->private_data;
 961        char buf[64];
 962        u8 amsdu, ampdu;
 963        size_t len;
 964
 965        mutex_lock(&ar->conf_mutex);
 966
 967        amsdu = ar->htt.max_num_amsdu;
 968        ampdu = ar->htt.max_num_ampdu;
 969        mutex_unlock(&ar->conf_mutex);
 970
 971        len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu);
 972
 973        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 974}
 975
 976static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file,
 977                                                const char __user *user_buf,
 978                                                size_t count, loff_t *ppos)
 979{
 980        struct ath10k *ar = file->private_data;
 981        int res;
 982        char buf[64] = {0};
 983        unsigned int amsdu, ampdu;
 984
 985        res = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
 986                                     user_buf, count);
 987        if (res <= 0)
 988                return res;
 989
 990        res = sscanf(buf, "%u %u", &amsdu, &ampdu);
 991
 992        if (res != 2)
 993                return -EINVAL;
 994
 995        mutex_lock(&ar->conf_mutex);
 996
 997        res = ath10k_htt_h2t_aggr_cfg_msg(&ar->htt, ampdu, amsdu);
 998        if (res)
 999                goto out;
1000
1001        res = count;
1002        ar->htt.max_num_amsdu = amsdu;
1003        ar->htt.max_num_ampdu = ampdu;
1004
1005out:
1006        mutex_unlock(&ar->conf_mutex);
1007        return res;
1008}
1009
1010static const struct file_operations fops_htt_max_amsdu_ampdu = {
1011        .read = ath10k_read_htt_max_amsdu_ampdu,
1012        .write = ath10k_write_htt_max_amsdu_ampdu,
1013        .open = simple_open,
1014        .owner = THIS_MODULE,
1015        .llseek = default_llseek,
1016};
1017
1018static ssize_t ath10k_read_fw_dbglog(struct file *file,
1019                                     char __user *user_buf,
1020                                     size_t count, loff_t *ppos)
1021{
1022        struct ath10k *ar = file->private_data;
1023        size_t len;
1024        char buf[96];
1025
1026        len = scnprintf(buf, sizeof(buf), "0x%16llx %u\n",
1027                        ar->debug.fw_dbglog_mask, ar->debug.fw_dbglog_level);
1028
1029        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1030}
1031
1032static ssize_t ath10k_write_fw_dbglog(struct file *file,
1033                                      const char __user *user_buf,
1034                                      size_t count, loff_t *ppos)
1035{
1036        struct ath10k *ar = file->private_data;
1037        int ret;
1038        char buf[96] = {0};
1039        unsigned int log_level;
1040        u64 mask;
1041
1042        ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
1043                                     user_buf, count);
1044        if (ret <= 0)
1045                return ret;
1046
1047        ret = sscanf(buf, "%llx %u", &mask, &log_level);
1048
1049        if (!ret)
1050                return -EINVAL;
1051
1052        if (ret == 1)
1053                /* default if user did not specify */
1054                log_level = ATH10K_DBGLOG_LEVEL_WARN;
1055
1056        mutex_lock(&ar->conf_mutex);
1057
1058        ar->debug.fw_dbglog_mask = mask;
1059        ar->debug.fw_dbglog_level = log_level;
1060
1061        if (ar->state == ATH10K_STATE_ON) {
1062                ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask,
1063                                            ar->debug.fw_dbglog_level);
1064                if (ret) {
1065                        ath10k_warn(ar, "dbglog cfg failed from debugfs: %d\n",
1066                                    ret);
1067                        goto exit;
1068                }
1069        }
1070
1071        ret = count;
1072
1073exit:
1074        mutex_unlock(&ar->conf_mutex);
1075
1076        return ret;
1077}
1078
1079/* TODO:  Would be nice to always support ethtool stats, would need to
1080 * move the stats storage out of ath10k_debug, or always have ath10k_debug
1081 * struct available..
1082 */
1083
1084/* This generally cooresponds to the debugfs fw_stats file */
1085static const char ath10k_gstrings_stats[][ETH_GSTRING_LEN] = {
1086        "tx_pkts_nic",
1087        "tx_bytes_nic",
1088        "rx_pkts_nic",
1089        "rx_bytes_nic",
1090        "d_noise_floor",
1091        "d_cycle_count",
1092        "d_phy_error",
1093        "d_rts_bad",
1094        "d_rts_good",
1095        "d_tx_power", /* in .5 dbM I think */
1096        "d_rx_crc_err", /* fcs_bad */
1097        "d_no_beacon",
1098        "d_tx_mpdus_queued",
1099        "d_tx_msdu_queued",
1100        "d_tx_msdu_dropped",
1101        "d_local_enqued",
1102        "d_local_freed",
1103        "d_tx_ppdu_hw_queued",
1104        "d_tx_ppdu_reaped",
1105        "d_tx_fifo_underrun",
1106        "d_tx_ppdu_abort",
1107        "d_tx_mpdu_requed",
1108        "d_tx_excessive_retries",
1109        "d_tx_hw_rate",
1110        "d_tx_dropped_sw_retries",
1111        "d_tx_illegal_rate",
1112        "d_tx_continuous_xretries",
1113        "d_tx_timeout",
1114        "d_tx_mpdu_txop_limit",
1115        "d_pdev_resets",
1116        "d_rx_mid_ppdu_route_change",
1117        "d_rx_status",
1118        "d_rx_extra_frags_ring0",
1119        "d_rx_extra_frags_ring1",
1120        "d_rx_extra_frags_ring2",
1121        "d_rx_extra_frags_ring3",
1122        "d_rx_msdu_htt",
1123        "d_rx_mpdu_htt",
1124        "d_rx_msdu_stack",
1125        "d_rx_mpdu_stack",
1126        "d_rx_phy_err",
1127        "d_rx_phy_err_drops",
1128        "d_rx_mpdu_errors", /* FCS, MIC, ENC */
1129        "d_fw_crash_count",
1130        "d_fw_warm_reset_count",
1131        "d_fw_cold_reset_count",
1132};
1133
1134#define ATH10K_SSTATS_LEN ARRAY_SIZE(ath10k_gstrings_stats)
1135
1136void ath10k_debug_get_et_strings(struct ieee80211_hw *hw,
1137                                 struct ieee80211_vif *vif,
1138                                 u32 sset, u8 *data)
1139{
1140        if (sset == ETH_SS_STATS)
1141                memcpy(data, *ath10k_gstrings_stats,
1142                       sizeof(ath10k_gstrings_stats));
1143}
1144
1145int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw,
1146                                   struct ieee80211_vif *vif, int sset)
1147{
1148        if (sset == ETH_SS_STATS)
1149                return ATH10K_SSTATS_LEN;
1150
1151        return 0;
1152}
1153
1154void ath10k_debug_get_et_stats(struct ieee80211_hw *hw,
1155                               struct ieee80211_vif *vif,
1156                               struct ethtool_stats *stats, u64 *data)
1157{
1158        struct ath10k *ar = hw->priv;
1159        static const struct ath10k_fw_stats_pdev zero_stats = {};
1160        const struct ath10k_fw_stats_pdev *pdev_stats;
1161        int i = 0, ret;
1162
1163        mutex_lock(&ar->conf_mutex);
1164
1165        if (ar->state == ATH10K_STATE_ON) {
1166                ret = ath10k_debug_fw_stats_request(ar);
1167                if (ret) {
1168                        /* just print a warning and try to use older results */
1169                        ath10k_warn(ar,
1170                                    "failed to get fw stats for ethtool: %d\n",
1171                                    ret);
1172                }
1173        }
1174
1175        pdev_stats = list_first_entry_or_null(&ar->debug.fw_stats.pdevs,
1176                                              struct ath10k_fw_stats_pdev,
1177                                              list);
1178        if (!pdev_stats) {
1179                /* no results available so just return zeroes */
1180                pdev_stats = &zero_stats;
1181        }
1182
1183        spin_lock_bh(&ar->data_lock);
1184
1185        data[i++] = pdev_stats->hw_reaped; /* ppdu reaped */
1186        data[i++] = 0; /* tx bytes */
1187        data[i++] = pdev_stats->htt_mpdus;
1188        data[i++] = 0; /* rx bytes */
1189        data[i++] = pdev_stats->ch_noise_floor;
1190        data[i++] = pdev_stats->cycle_count;
1191        data[i++] = pdev_stats->phy_err_count;
1192        data[i++] = pdev_stats->rts_bad;
1193        data[i++] = pdev_stats->rts_good;
1194        data[i++] = pdev_stats->chan_tx_power;
1195        data[i++] = pdev_stats->fcs_bad;
1196        data[i++] = pdev_stats->no_beacons;
1197        data[i++] = pdev_stats->mpdu_enqued;
1198        data[i++] = pdev_stats->msdu_enqued;
1199        data[i++] = pdev_stats->wmm_drop;
1200        data[i++] = pdev_stats->local_enqued;
1201        data[i++] = pdev_stats->local_freed;
1202        data[i++] = pdev_stats->hw_queued;
1203        data[i++] = pdev_stats->hw_reaped;
1204        data[i++] = pdev_stats->underrun;
1205        data[i++] = pdev_stats->tx_abort;
1206        data[i++] = pdev_stats->mpdus_requed;
1207        data[i++] = pdev_stats->tx_ko;
1208        data[i++] = pdev_stats->data_rc;
1209        data[i++] = pdev_stats->sw_retry_failure;
1210        data[i++] = pdev_stats->illgl_rate_phy_err;
1211        data[i++] = pdev_stats->pdev_cont_xretry;
1212        data[i++] = pdev_stats->pdev_tx_timeout;
1213        data[i++] = pdev_stats->txop_ovf;
1214        data[i++] = pdev_stats->pdev_resets;
1215        data[i++] = pdev_stats->mid_ppdu_route_change;
1216        data[i++] = pdev_stats->status_rcvd;
1217        data[i++] = pdev_stats->r0_frags;
1218        data[i++] = pdev_stats->r1_frags;
1219        data[i++] = pdev_stats->r2_frags;
1220        data[i++] = pdev_stats->r3_frags;
1221        data[i++] = pdev_stats->htt_msdus;
1222        data[i++] = pdev_stats->htt_mpdus;
1223        data[i++] = pdev_stats->loc_msdus;
1224        data[i++] = pdev_stats->loc_mpdus;
1225        data[i++] = pdev_stats->phy_errs;
1226        data[i++] = pdev_stats->phy_err_drop;
1227        data[i++] = pdev_stats->mpdu_errs;
1228        data[i++] = ar->stats.fw_crash_counter;
1229        data[i++] = ar->stats.fw_warm_reset_counter;
1230        data[i++] = ar->stats.fw_cold_reset_counter;
1231
1232        spin_unlock_bh(&ar->data_lock);
1233
1234        mutex_unlock(&ar->conf_mutex);
1235
1236        WARN_ON(i != ATH10K_SSTATS_LEN);
1237}
1238
1239static const struct file_operations fops_fw_dbglog = {
1240        .read = ath10k_read_fw_dbglog,
1241        .write = ath10k_write_fw_dbglog,
1242        .open = simple_open,
1243        .owner = THIS_MODULE,
1244        .llseek = default_llseek,
1245};
1246
1247static int ath10k_debug_cal_data_fetch(struct ath10k *ar)
1248{
1249        u32 hi_addr;
1250        __le32 addr;
1251        int ret;
1252
1253        lockdep_assert_held(&ar->conf_mutex);
1254
1255        if (WARN_ON(ar->hw_params.cal_data_len > ATH10K_DEBUG_CAL_DATA_LEN))
1256                return -EINVAL;
1257
1258        if (ar->hw_params.cal_data_len == 0)
1259                return -EOPNOTSUPP;
1260
1261        hi_addr = host_interest_item_address(HI_ITEM(hi_board_data));
1262
1263        ret = ath10k_hif_diag_read(ar, hi_addr, &addr, sizeof(addr));
1264        if (ret) {
1265                ath10k_warn(ar, "failed to read hi_board_data address: %d\n",
1266                            ret);
1267                return ret;
1268        }
1269
1270        ret = ath10k_hif_diag_read(ar, le32_to_cpu(addr), ar->debug.cal_data,
1271                                   ar->hw_params.cal_data_len);
1272        if (ret) {
1273                ath10k_warn(ar, "failed to read calibration data: %d\n", ret);
1274                return ret;
1275        }
1276
1277        return 0;
1278}
1279
1280static int ath10k_debug_cal_data_open(struct inode *inode, struct file *file)
1281{
1282        struct ath10k *ar = inode->i_private;
1283
1284        mutex_lock(&ar->conf_mutex);
1285
1286        if (ar->state == ATH10K_STATE_ON ||
1287            ar->state == ATH10K_STATE_UTF) {
1288                ath10k_debug_cal_data_fetch(ar);
1289        }
1290
1291        file->private_data = ar;
1292        mutex_unlock(&ar->conf_mutex);
1293
1294        return 0;
1295}
1296
1297static ssize_t ath10k_debug_cal_data_read(struct file *file,
1298                                          char __user *user_buf,
1299                                          size_t count, loff_t *ppos)
1300{
1301        struct ath10k *ar = file->private_data;
1302
1303        mutex_lock(&ar->conf_mutex);
1304
1305        count = simple_read_from_buffer(user_buf, count, ppos,
1306                                        ar->debug.cal_data,
1307                                        ar->hw_params.cal_data_len);
1308
1309        mutex_unlock(&ar->conf_mutex);
1310
1311        return count;
1312}
1313
1314static ssize_t ath10k_write_ani_enable(struct file *file,
1315                                       const char __user *user_buf,
1316                                       size_t count, loff_t *ppos)
1317{
1318        struct ath10k *ar = file->private_data;
1319        int ret;
1320        u8 enable;
1321
1322        if (kstrtou8_from_user(user_buf, count, 0, &enable))
1323                return -EINVAL;
1324
1325        mutex_lock(&ar->conf_mutex);
1326
1327        if (ar->ani_enabled == enable) {
1328                ret = count;
1329                goto exit;
1330        }
1331
1332        ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->ani_enable,
1333                                        enable);
1334        if (ret) {
1335                ath10k_warn(ar, "ani_enable failed from debugfs: %d\n", ret);
1336                goto exit;
1337        }
1338        ar->ani_enabled = enable;
1339
1340        ret = count;
1341
1342exit:
1343        mutex_unlock(&ar->conf_mutex);
1344
1345        return ret;
1346}
1347
1348static ssize_t ath10k_read_ani_enable(struct file *file, char __user *user_buf,
1349                                      size_t count, loff_t *ppos)
1350{
1351        struct ath10k *ar = file->private_data;
1352        size_t len;
1353        char buf[32];
1354
1355        len = scnprintf(buf, sizeof(buf), "%d\n", ar->ani_enabled);
1356
1357        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1358}
1359
1360static const struct file_operations fops_ani_enable = {
1361        .read = ath10k_read_ani_enable,
1362        .write = ath10k_write_ani_enable,
1363        .open = simple_open,
1364        .owner = THIS_MODULE,
1365        .llseek = default_llseek,
1366};
1367
1368static const struct file_operations fops_cal_data = {
1369        .open = ath10k_debug_cal_data_open,
1370        .read = ath10k_debug_cal_data_read,
1371        .owner = THIS_MODULE,
1372        .llseek = default_llseek,
1373};
1374
1375static ssize_t ath10k_read_nf_cal_period(struct file *file,
1376                                         char __user *user_buf,
1377                                         size_t count, loff_t *ppos)
1378{
1379        struct ath10k *ar = file->private_data;
1380        size_t len;
1381        char buf[32];
1382
1383        len = scnprintf(buf, sizeof(buf), "%d\n", ar->debug.nf_cal_period);
1384
1385        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1386}
1387
1388static ssize_t ath10k_write_nf_cal_period(struct file *file,
1389                                          const char __user *user_buf,
1390                                          size_t count, loff_t *ppos)
1391{
1392        struct ath10k *ar = file->private_data;
1393        unsigned long period;
1394        int ret;
1395
1396        ret = kstrtoul_from_user(user_buf, count, 0, &period);
1397        if (ret)
1398                return ret;
1399
1400        if (period > WMI_PDEV_PARAM_CAL_PERIOD_MAX)
1401                return -EINVAL;
1402
1403        /* there's no way to switch back to the firmware default */
1404        if (period == 0)
1405                return -EINVAL;
1406
1407        mutex_lock(&ar->conf_mutex);
1408
1409        ar->debug.nf_cal_period = period;
1410
1411        if (ar->state != ATH10K_STATE_ON) {
1412                /* firmware is not running, nothing else to do */
1413                ret = count;
1414                goto exit;
1415        }
1416
1417        ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->cal_period,
1418                                        ar->debug.nf_cal_period);
1419        if (ret) {
1420                ath10k_warn(ar, "cal period cfg failed from debugfs: %d\n",
1421                            ret);
1422                goto exit;
1423        }
1424
1425        ret = count;
1426
1427exit:
1428        mutex_unlock(&ar->conf_mutex);
1429
1430        return ret;
1431}
1432
1433static const struct file_operations fops_nf_cal_period = {
1434        .read = ath10k_read_nf_cal_period,
1435        .write = ath10k_write_nf_cal_period,
1436        .open = simple_open,
1437        .owner = THIS_MODULE,
1438        .llseek = default_llseek,
1439};
1440
1441#define ATH10K_TPC_CONFIG_BUF_SIZE      (1024 * 1024)
1442
1443static int ath10k_debug_tpc_stats_request(struct ath10k *ar)
1444{
1445        int ret;
1446        unsigned long time_left;
1447
1448        lockdep_assert_held(&ar->conf_mutex);
1449
1450        reinit_completion(&ar->debug.tpc_complete);
1451
1452        ret = ath10k_wmi_pdev_get_tpc_config(ar, WMI_TPC_CONFIG_PARAM);
1453        if (ret) {
1454                ath10k_warn(ar, "failed to request tpc config: %d\n", ret);
1455                return ret;
1456        }
1457
1458        time_left = wait_for_completion_timeout(&ar->debug.tpc_complete,
1459                                                1 * HZ);
1460        if (time_left == 0)
1461                return -ETIMEDOUT;
1462
1463        return 0;
1464}
1465
1466void ath10k_debug_tpc_stats_process(struct ath10k *ar,
1467                                    struct ath10k_tpc_stats *tpc_stats)
1468{
1469        spin_lock_bh(&ar->data_lock);
1470
1471        kfree(ar->debug.tpc_stats);
1472        ar->debug.tpc_stats = tpc_stats;
1473        complete(&ar->debug.tpc_complete);
1474
1475        spin_unlock_bh(&ar->data_lock);
1476}
1477
1478void
1479ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
1480                                     struct ath10k_tpc_stats_final *tpc_stats)
1481{
1482        spin_lock_bh(&ar->data_lock);
1483
1484        kfree(ar->debug.tpc_stats_final);
1485        ar->debug.tpc_stats_final = tpc_stats;
1486        complete(&ar->debug.tpc_complete);
1487
1488        spin_unlock_bh(&ar->data_lock);
1489}
1490
1491static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats,
1492                                   unsigned int j, char *buf, size_t *len)
1493{
1494        int i;
1495        size_t buf_len;
1496        static const char table_str[][5] = { "CDD",
1497                                             "STBC",
1498                                             "TXBF" };
1499        static const char pream_str[][6] = { "CCK",
1500                                             "OFDM",
1501                                             "HT20",
1502                                             "HT40",
1503                                             "VHT20",
1504                                             "VHT40",
1505                                             "VHT80",
1506                                             "HTCUP" };
1507
1508        buf_len = ATH10K_TPC_CONFIG_BUF_SIZE;
1509        *len += scnprintf(buf + *len, buf_len - *len,
1510                          "********************************\n");
1511        *len += scnprintf(buf + *len, buf_len - *len,
1512                          "******************* %s POWER TABLE ****************\n",
1513                          table_str[j]);
1514        *len += scnprintf(buf + *len, buf_len - *len,
1515                          "********************************\n");
1516        *len += scnprintf(buf + *len, buf_len - *len,
1517                          "No.  Preamble Rate_code ");
1518
1519        for (i = 0; i < WMI_TPC_TX_N_CHAIN; i++)
1520                *len += scnprintf(buf + *len, buf_len - *len,
1521                                  "tpc_value%d ", i);
1522
1523        *len += scnprintf(buf + *len, buf_len - *len, "\n");
1524
1525        for (i = 0; i < tpc_stats->rate_max; i++) {
1526                *len += scnprintf(buf + *len, buf_len - *len,
1527                                  "%8d %s 0x%2x %s\n", i,
1528                                  pream_str[tpc_stats->tpc_table[j].pream_idx[i]],
1529                                  tpc_stats->tpc_table[j].rate_code[i],
1530                                  tpc_stats->tpc_table[j].tpc_value[i]);
1531        }
1532
1533        *len += scnprintf(buf + *len, buf_len - *len,
1534                          "***********************************\n");
1535}
1536
1537static void ath10k_tpc_stats_fill(struct ath10k *ar,
1538                                  struct ath10k_tpc_stats *tpc_stats,
1539                                  char *buf)
1540{
1541        int j;
1542        size_t len, buf_len;
1543
1544        len = 0;
1545        buf_len = ATH10K_TPC_CONFIG_BUF_SIZE;
1546
1547        spin_lock_bh(&ar->data_lock);
1548
1549        if (!tpc_stats) {
1550                ath10k_warn(ar, "failed to get tpc stats\n");
1551                goto unlock;
1552        }
1553
1554        len += scnprintf(buf + len, buf_len - len, "\n");
1555        len += scnprintf(buf + len, buf_len - len,
1556                         "*************************************\n");
1557        len += scnprintf(buf + len, buf_len - len,
1558                         "TPC config for channel %4d mode %d\n",
1559                         tpc_stats->chan_freq,
1560                         tpc_stats->phy_mode);
1561        len += scnprintf(buf + len, buf_len - len,
1562                         "*************************************\n");
1563        len += scnprintf(buf + len, buf_len - len,
1564                         "CTL           =  0x%2x Reg. Domain            = %2d\n",
1565                         tpc_stats->ctl,
1566                         tpc_stats->reg_domain);
1567        len += scnprintf(buf + len, buf_len - len,
1568                         "Antenna Gain  = %2d Reg. Max Antenna Gain     =  %2d\n",
1569                         tpc_stats->twice_antenna_gain,
1570                         tpc_stats->twice_antenna_reduction);
1571        len += scnprintf(buf + len, buf_len - len,
1572                         "Power Limit   = %2d Reg. Max Power            = %2d\n",
1573                         tpc_stats->power_limit,
1574                         tpc_stats->twice_max_rd_power / 2);
1575        len += scnprintf(buf + len, buf_len - len,
1576                         "Num tx chains = %2d Num supported rates       = %2d\n",
1577                         tpc_stats->num_tx_chain,
1578                         tpc_stats->rate_max);
1579
1580        for (j = 0; j < WMI_TPC_FLAG; j++) {
1581                switch (j) {
1582                case WMI_TPC_TABLE_TYPE_CDD:
1583                        if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
1584                                len += scnprintf(buf + len, buf_len - len,
1585                                                 "CDD not supported\n");
1586                                break;
1587                        }
1588
1589                        ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
1590                        break;
1591                case WMI_TPC_TABLE_TYPE_STBC:
1592                        if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
1593                                len += scnprintf(buf + len, buf_len - len,
1594                                                 "STBC not supported\n");
1595                                break;
1596                        }
1597
1598                        ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
1599                        break;
1600                case WMI_TPC_TABLE_TYPE_TXBF:
1601                        if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
1602                                len += scnprintf(buf + len, buf_len - len,
1603                                                 "TXBF not supported\n***************************\n");
1604                                break;
1605                        }
1606
1607                        ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
1608                        break;
1609                default:
1610                        len += scnprintf(buf + len, buf_len - len,
1611                                         "Invalid Type\n");
1612                        break;
1613                }
1614        }
1615
1616unlock:
1617        spin_unlock_bh(&ar->data_lock);
1618
1619        if (len >= buf_len)
1620                buf[len - 1] = 0;
1621        else
1622                buf[len] = 0;
1623}
1624
1625static int ath10k_tpc_stats_open(struct inode *inode, struct file *file)
1626{
1627        struct ath10k *ar = inode->i_private;
1628        void *buf = NULL;
1629        int ret;
1630
1631        mutex_lock(&ar->conf_mutex);
1632
1633        if (ar->state != ATH10K_STATE_ON) {
1634                ret = -ENETDOWN;
1635                goto err_unlock;
1636        }
1637
1638        buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE);
1639        if (!buf) {
1640                ret = -ENOMEM;
1641                goto err_unlock;
1642        }
1643
1644        ret = ath10k_debug_tpc_stats_request(ar);
1645        if (ret) {
1646                ath10k_warn(ar, "failed to request tpc config stats: %d\n",
1647                            ret);
1648                goto err_free;
1649        }
1650
1651        ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
1652        file->private_data = buf;
1653
1654        mutex_unlock(&ar->conf_mutex);
1655        return 0;
1656
1657err_free:
1658        vfree(buf);
1659
1660err_unlock:
1661        mutex_unlock(&ar->conf_mutex);
1662        return ret;
1663}
1664
1665static int ath10k_tpc_stats_release(struct inode *inode, struct file *file)
1666{
1667        vfree(file->private_data);
1668
1669        return 0;
1670}
1671
1672static ssize_t ath10k_tpc_stats_read(struct file *file, char __user *user_buf,
1673                                     size_t count, loff_t *ppos)
1674{
1675        const char *buf = file->private_data;
1676        size_t len = strlen(buf);
1677
1678        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1679}
1680
1681static const struct file_operations fops_tpc_stats = {
1682        .open = ath10k_tpc_stats_open,
1683        .release = ath10k_tpc_stats_release,
1684        .read = ath10k_tpc_stats_read,
1685        .owner = THIS_MODULE,
1686        .llseek = default_llseek,
1687};
1688
1689int ath10k_debug_start(struct ath10k *ar)
1690{
1691        int ret;
1692
1693        lockdep_assert_held(&ar->conf_mutex);
1694
1695        ret = ath10k_debug_htt_stats_req(ar);
1696        if (ret)
1697                /* continue normally anyway, this isn't serious */
1698                ath10k_warn(ar, "failed to start htt stats workqueue: %d\n",
1699                            ret);
1700
1701        if (ar->debug.fw_dbglog_mask) {
1702                ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask,
1703                                            ATH10K_DBGLOG_LEVEL_WARN);
1704                if (ret)
1705                        /* not serious */
1706                        ath10k_warn(ar, "failed to enable dbglog during start: %d",
1707                                    ret);
1708        }
1709
1710        if (ar->pktlog_filter) {
1711                ret = ath10k_wmi_pdev_pktlog_enable(ar,
1712                                                    ar->pktlog_filter);
1713                if (ret)
1714                        /* not serious */
1715                        ath10k_warn(ar,
1716                                    "failed to enable pktlog filter %x: %d\n",
1717                                    ar->pktlog_filter, ret);
1718        } else {
1719                ret = ath10k_wmi_pdev_pktlog_disable(ar);
1720                if (ret)
1721                        /* not serious */
1722                        ath10k_warn(ar, "failed to disable pktlog: %d\n", ret);
1723        }
1724
1725        if (ar->debug.nf_cal_period &&
1726            !test_bit(ATH10K_FW_FEATURE_NON_BMI,
1727                      ar->normal_mode_fw.fw_file.fw_features)) {
1728                ret = ath10k_wmi_pdev_set_param(ar,
1729                                                ar->wmi.pdev_param->cal_period,
1730                                                ar->debug.nf_cal_period);
1731                if (ret)
1732                        /* not serious */
1733                        ath10k_warn(ar, "cal period cfg failed from debug start: %d\n",
1734                                    ret);
1735        }
1736
1737        return ret;
1738}
1739
1740void ath10k_debug_stop(struct ath10k *ar)
1741{
1742        lockdep_assert_held(&ar->conf_mutex);
1743
1744        if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
1745                      ar->normal_mode_fw.fw_file.fw_features))
1746                ath10k_debug_cal_data_fetch(ar);
1747
1748        /* Must not use _sync to avoid deadlock, we do that in
1749         * ath10k_debug_destroy(). The check for htt_stats_mask is to avoid
1750         * warning from del_timer().
1751         */
1752        if (ar->debug.htt_stats_mask != 0)
1753                cancel_delayed_work(&ar->debug.htt_stats_dwork);
1754
1755        ath10k_wmi_pdev_pktlog_disable(ar);
1756}
1757
1758static ssize_t ath10k_write_simulate_radar(struct file *file,
1759                                           const char __user *user_buf,
1760                                           size_t count, loff_t *ppos)
1761{
1762        struct ath10k *ar = file->private_data;
1763        struct ath10k_vif *arvif;
1764
1765        /* Just check for for the first vif alone, as all the vifs will be
1766         * sharing the same channel and if the channel is disabled, all the
1767         * vifs will share the same 'is_started' state.
1768         */
1769        arvif = list_first_entry(&ar->arvifs, typeof(*arvif), list);
1770        if (!arvif->is_started)
1771                return -EINVAL;
1772
1773        ieee80211_radar_detected(ar->hw);
1774
1775        return count;
1776}
1777
1778static const struct file_operations fops_simulate_radar = {
1779        .write = ath10k_write_simulate_radar,
1780        .open = simple_open,
1781        .owner = THIS_MODULE,
1782        .llseek = default_llseek,
1783};
1784
1785#define ATH10K_DFS_STAT(s, p) (\
1786        len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
1787                         ar->debug.dfs_stats.p))
1788
1789#define ATH10K_DFS_POOL_STAT(s, p) (\
1790        len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
1791                         ar->debug.dfs_pool_stats.p))
1792
1793static ssize_t ath10k_read_dfs_stats(struct file *file, char __user *user_buf,
1794                                     size_t count, loff_t *ppos)
1795{
1796        int retval = 0, len = 0;
1797        const int size = 8000;
1798        struct ath10k *ar = file->private_data;
1799        char *buf;
1800
1801        buf = kzalloc(size, GFP_KERNEL);
1802        if (buf == NULL)
1803                return -ENOMEM;
1804
1805        if (!ar->dfs_detector) {
1806                len += scnprintf(buf + len, size - len, "DFS not enabled\n");
1807                goto exit;
1808        }
1809
1810        ar->debug.dfs_pool_stats =
1811                        ar->dfs_detector->get_stats(ar->dfs_detector);
1812
1813        len += scnprintf(buf + len, size - len, "Pulse detector statistics:\n");
1814
1815        ATH10K_DFS_STAT("reported phy errors", phy_errors);
1816        ATH10K_DFS_STAT("pulse events reported", pulses_total);
1817        ATH10K_DFS_STAT("DFS pulses detected", pulses_detected);
1818        ATH10K_DFS_STAT("DFS pulses discarded", pulses_discarded);
1819        ATH10K_DFS_STAT("Radars detected", radar_detected);
1820
1821        len += scnprintf(buf + len, size - len, "Global Pool statistics:\n");
1822        ATH10K_DFS_POOL_STAT("Pool references", pool_reference);
1823        ATH10K_DFS_POOL_STAT("Pulses allocated", pulse_allocated);
1824        ATH10K_DFS_POOL_STAT("Pulses alloc error", pulse_alloc_error);
1825        ATH10K_DFS_POOL_STAT("Pulses in use", pulse_used);
1826        ATH10K_DFS_POOL_STAT("Seqs. allocated", pseq_allocated);
1827        ATH10K_DFS_POOL_STAT("Seqs. alloc error", pseq_alloc_error);
1828        ATH10K_DFS_POOL_STAT("Seqs. in use", pseq_used);
1829
1830exit:
1831        if (len > size)
1832                len = size;
1833
1834        retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1835        kfree(buf);
1836
1837        return retval;
1838}
1839
1840static const struct file_operations fops_dfs_stats = {
1841        .read = ath10k_read_dfs_stats,
1842        .open = simple_open,
1843        .owner = THIS_MODULE,
1844        .llseek = default_llseek,
1845};
1846
1847static ssize_t ath10k_write_pktlog_filter(struct file *file,
1848                                          const char __user *ubuf,
1849                                          size_t count, loff_t *ppos)
1850{
1851        struct ath10k *ar = file->private_data;
1852        u32 filter;
1853        int ret;
1854
1855        if (kstrtouint_from_user(ubuf, count, 0, &filter))
1856                return -EINVAL;
1857
1858        mutex_lock(&ar->conf_mutex);
1859
1860        if (ar->state != ATH10K_STATE_ON) {
1861                ar->pktlog_filter = filter;
1862                ret = count;
1863                goto out;
1864        }
1865
1866        if (filter == ar->pktlog_filter) {
1867                ret = count;
1868                goto out;
1869        }
1870
1871        if (filter) {
1872                ret = ath10k_wmi_pdev_pktlog_enable(ar, filter);
1873                if (ret) {
1874                        ath10k_warn(ar, "failed to enable pktlog filter %x: %d\n",
1875                                    ar->pktlog_filter, ret);
1876                        goto out;
1877                }
1878        } else {
1879                ret = ath10k_wmi_pdev_pktlog_disable(ar);
1880                if (ret) {
1881                        ath10k_warn(ar, "failed to disable pktlog: %d\n", ret);
1882                        goto out;
1883                }
1884        }
1885
1886        ar->pktlog_filter = filter;
1887        ret = count;
1888
1889out:
1890        mutex_unlock(&ar->conf_mutex);
1891        return ret;
1892}
1893
1894static ssize_t ath10k_read_pktlog_filter(struct file *file, char __user *ubuf,
1895                                         size_t count, loff_t *ppos)
1896{
1897        char buf[32];
1898        struct ath10k *ar = file->private_data;
1899        int len = 0;
1900
1901        mutex_lock(&ar->conf_mutex);
1902        len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
1903                        ar->pktlog_filter);
1904        mutex_unlock(&ar->conf_mutex);
1905
1906        return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1907}
1908
1909static const struct file_operations fops_pktlog_filter = {
1910        .read = ath10k_read_pktlog_filter,
1911        .write = ath10k_write_pktlog_filter,
1912        .open = simple_open
1913};
1914
1915static ssize_t ath10k_write_quiet_period(struct file *file,
1916                                         const char __user *ubuf,
1917                                         size_t count, loff_t *ppos)
1918{
1919        struct ath10k *ar = file->private_data;
1920        u32 period;
1921
1922        if (kstrtouint_from_user(ubuf, count, 0, &period))
1923                return -EINVAL;
1924
1925        if (period < ATH10K_QUIET_PERIOD_MIN) {
1926                ath10k_warn(ar, "Quiet period %u can not be lesser than 25ms\n",
1927                            period);
1928                return -EINVAL;
1929        }
1930        mutex_lock(&ar->conf_mutex);
1931        ar->thermal.quiet_period = period;
1932        ath10k_thermal_set_throttling(ar);
1933        mutex_unlock(&ar->conf_mutex);
1934
1935        return count;
1936}
1937
1938static ssize_t ath10k_read_quiet_period(struct file *file, char __user *ubuf,
1939                                        size_t count, loff_t *ppos)
1940{
1941        char buf[32];
1942        struct ath10k *ar = file->private_data;
1943        int len = 0;
1944
1945        mutex_lock(&ar->conf_mutex);
1946        len = scnprintf(buf, sizeof(buf) - len, "%d\n",
1947                        ar->thermal.quiet_period);
1948        mutex_unlock(&ar->conf_mutex);
1949
1950        return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1951}
1952
1953static const struct file_operations fops_quiet_period = {
1954        .read = ath10k_read_quiet_period,
1955        .write = ath10k_write_quiet_period,
1956        .open = simple_open
1957};
1958
1959static ssize_t ath10k_write_btcoex(struct file *file,
1960                                   const char __user *ubuf,
1961                                   size_t count, loff_t *ppos)
1962{
1963        struct ath10k *ar = file->private_data;
1964        char buf[32];
1965        size_t buf_size;
1966        int ret;
1967        bool val;
1968        u32 pdev_param;
1969
1970        buf_size = min(count, (sizeof(buf) - 1));
1971        if (copy_from_user(buf, ubuf, buf_size))
1972                return -EFAULT;
1973
1974        buf[buf_size] = '\0';
1975
1976        if (strtobool(buf, &val) != 0)
1977                return -EINVAL;
1978
1979        mutex_lock(&ar->conf_mutex);
1980
1981        if (ar->state != ATH10K_STATE_ON &&
1982            ar->state != ATH10K_STATE_RESTARTED) {
1983                ret = -ENETDOWN;
1984                goto exit;
1985        }
1986
1987        if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val)) {
1988                ret = count;
1989                goto exit;
1990        }
1991
1992        pdev_param = ar->wmi.pdev_param->enable_btcoex;
1993        if (test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
1994                     ar->running_fw->fw_file.fw_features)) {
1995                ret = ath10k_wmi_pdev_set_param(ar, pdev_param, val);
1996                if (ret) {
1997                        ath10k_warn(ar, "failed to enable btcoex: %d\n", ret);
1998                        ret = count;
1999                        goto exit;
2000                }
2001        } else {
2002                ath10k_info(ar, "restarting firmware due to btcoex change");
2003                queue_work(ar->workqueue, &ar->restart_work);
2004        }
2005
2006        if (val)
2007                set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
2008        else
2009                clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
2010
2011        ret = count;
2012
2013exit:
2014        mutex_unlock(&ar->conf_mutex);
2015
2016        return ret;
2017}
2018
2019static ssize_t ath10k_read_btcoex(struct file *file, char __user *ubuf,
2020                                  size_t count, loff_t *ppos)
2021{
2022        char buf[32];
2023        struct ath10k *ar = file->private_data;
2024        int len = 0;
2025
2026        mutex_lock(&ar->conf_mutex);
2027        len = scnprintf(buf, sizeof(buf) - len, "%d\n",
2028                        test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags));
2029        mutex_unlock(&ar->conf_mutex);
2030
2031        return simple_read_from_buffer(ubuf, count, ppos, buf, len);
2032}
2033
2034static const struct file_operations fops_btcoex = {
2035        .read = ath10k_read_btcoex,
2036        .write = ath10k_write_btcoex,
2037        .open = simple_open
2038};
2039
2040static ssize_t ath10k_write_enable_extd_tx_stats(struct file *file,
2041                                                 const char __user *ubuf,
2042                                                 size_t count, loff_t *ppos)
2043{
2044        struct ath10k *ar = file->private_data;
2045        u32 filter;
2046        int ret;
2047
2048        if (kstrtouint_from_user(ubuf, count, 0, &filter))
2049                return -EINVAL;
2050
2051        mutex_lock(&ar->conf_mutex);
2052
2053        if (ar->state != ATH10K_STATE_ON) {
2054                ar->debug.enable_extd_tx_stats = filter;
2055                ret = count;
2056                goto out;
2057        }
2058
2059        if (filter == ar->debug.enable_extd_tx_stats) {
2060                ret = count;
2061                goto out;
2062        }
2063
2064        ar->debug.enable_extd_tx_stats = filter;
2065        ret = count;
2066
2067out:
2068        mutex_unlock(&ar->conf_mutex);
2069        return ret;
2070}
2071
2072static ssize_t ath10k_read_enable_extd_tx_stats(struct file *file,
2073                                                char __user *ubuf,
2074                                                size_t count, loff_t *ppos)
2075
2076{
2077        char buf[32];
2078        struct ath10k *ar = file->private_data;
2079        int len = 0;
2080
2081        mutex_lock(&ar->conf_mutex);
2082        len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
2083                        ar->debug.enable_extd_tx_stats);
2084        mutex_unlock(&ar->conf_mutex);
2085
2086        return simple_read_from_buffer(ubuf, count, ppos, buf, len);
2087}
2088
2089static const struct file_operations fops_enable_extd_tx_stats = {
2090        .read = ath10k_read_enable_extd_tx_stats,
2091        .write = ath10k_write_enable_extd_tx_stats,
2092        .open = simple_open
2093};
2094
2095static ssize_t ath10k_write_peer_stats(struct file *file,
2096                                       const char __user *ubuf,
2097                                       size_t count, loff_t *ppos)
2098{
2099        struct ath10k *ar = file->private_data;
2100        char buf[32];
2101        size_t buf_size;
2102        int ret;
2103        bool val;
2104
2105        buf_size = min(count, (sizeof(buf) - 1));
2106        if (copy_from_user(buf, ubuf, buf_size))
2107                return -EFAULT;
2108
2109        buf[buf_size] = '\0';
2110
2111        if (strtobool(buf, &val) != 0)
2112                return -EINVAL;
2113
2114        mutex_lock(&ar->conf_mutex);
2115
2116        if (ar->state != ATH10K_STATE_ON &&
2117            ar->state != ATH10K_STATE_RESTARTED) {
2118                ret = -ENETDOWN;
2119                goto exit;
2120        }
2121
2122        if (!(test_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags) ^ val)) {
2123                ret = count;
2124                goto exit;
2125        }
2126
2127        if (val)
2128                set_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
2129        else
2130                clear_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
2131
2132        ath10k_info(ar, "restarting firmware due to Peer stats change");
2133
2134        queue_work(ar->workqueue, &ar->restart_work);
2135        ret = count;
2136
2137exit:
2138        mutex_unlock(&ar->conf_mutex);
2139        return ret;
2140}
2141
2142static ssize_t ath10k_read_peer_stats(struct file *file, char __user *ubuf,
2143                                      size_t count, loff_t *ppos)
2144
2145{
2146        char buf[32];
2147        struct ath10k *ar = file->private_data;
2148        int len = 0;
2149
2150        mutex_lock(&ar->conf_mutex);
2151        len = scnprintf(buf, sizeof(buf) - len, "%d\n",
2152                        test_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags));
2153        mutex_unlock(&ar->conf_mutex);
2154
2155        return simple_read_from_buffer(ubuf, count, ppos, buf, len);
2156}
2157
2158static const struct file_operations fops_peer_stats = {
2159        .read = ath10k_read_peer_stats,
2160        .write = ath10k_write_peer_stats,
2161        .open = simple_open
2162};
2163
2164static ssize_t ath10k_debug_fw_checksums_read(struct file *file,
2165                                              char __user *user_buf,
2166                                              size_t count, loff_t *ppos)
2167{
2168        struct ath10k *ar = file->private_data;
2169        size_t len = 0, buf_len = 4096;
2170        ssize_t ret_cnt;
2171        char *buf;
2172
2173        buf = kzalloc(buf_len, GFP_KERNEL);
2174        if (!buf)
2175                return -ENOMEM;
2176
2177        mutex_lock(&ar->conf_mutex);
2178
2179        len += scnprintf(buf + len, buf_len - len,
2180                         "firmware-N.bin\t\t%08x\n",
2181                         crc32_le(0, ar->normal_mode_fw.fw_file.firmware->data,
2182                                  ar->normal_mode_fw.fw_file.firmware->size));
2183        len += scnprintf(buf + len, buf_len - len,
2184                         "athwlan\t\t\t%08x\n",
2185                         crc32_le(0, ar->normal_mode_fw.fw_file.firmware_data,
2186                                  ar->normal_mode_fw.fw_file.firmware_len));
2187        len += scnprintf(buf + len, buf_len - len,
2188                         "otp\t\t\t%08x\n",
2189                         crc32_le(0, ar->normal_mode_fw.fw_file.otp_data,
2190                                  ar->normal_mode_fw.fw_file.otp_len));
2191        len += scnprintf(buf + len, buf_len - len,
2192                         "codeswap\t\t%08x\n",
2193                         crc32_le(0, ar->normal_mode_fw.fw_file.codeswap_data,
2194                                  ar->normal_mode_fw.fw_file.codeswap_len));
2195        len += scnprintf(buf + len, buf_len - len,
2196                         "board-N.bin\t\t%08x\n",
2197                         crc32_le(0, ar->normal_mode_fw.board->data,
2198                                  ar->normal_mode_fw.board->size));
2199        len += scnprintf(buf + len, buf_len - len,
2200                         "board\t\t\t%08x\n",
2201                         crc32_le(0, ar->normal_mode_fw.board_data,
2202                                  ar->normal_mode_fw.board_len));
2203
2204        ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
2205
2206        mutex_unlock(&ar->conf_mutex);
2207
2208        kfree(buf);
2209        return ret_cnt;
2210}
2211
2212static const struct file_operations fops_fw_checksums = {
2213        .read = ath10k_debug_fw_checksums_read,
2214        .open = simple_open,
2215        .owner = THIS_MODULE,
2216        .llseek = default_llseek,
2217};
2218
2219static ssize_t ath10k_sta_tid_stats_mask_read(struct file *file,
2220                                              char __user *user_buf,
2221                                              size_t count, loff_t *ppos)
2222{
2223        struct ath10k *ar = file->private_data;
2224        char buf[32];
2225        size_t len;
2226
2227        len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->sta_tid_stats_mask);
2228        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2229}
2230
2231static ssize_t ath10k_sta_tid_stats_mask_write(struct file *file,
2232                                               const char __user *user_buf,
2233                                               size_t count, loff_t *ppos)
2234{
2235        struct ath10k *ar = file->private_data;
2236        char buf[32];
2237        ssize_t len;
2238        u32 mask;
2239
2240        len = min(count, sizeof(buf) - 1);
2241        if (copy_from_user(buf, user_buf, len))
2242                return -EFAULT;
2243
2244        buf[len] = '\0';
2245        if (kstrtoint(buf, 0, &mask))
2246                return -EINVAL;
2247
2248        ar->sta_tid_stats_mask = mask;
2249
2250        return len;
2251}
2252
2253static const struct file_operations fops_sta_tid_stats_mask = {
2254        .read = ath10k_sta_tid_stats_mask_read,
2255        .write = ath10k_sta_tid_stats_mask_write,
2256        .open = simple_open,
2257        .owner = THIS_MODULE,
2258        .llseek = default_llseek,
2259};
2260
2261static int ath10k_debug_tpc_stats_final_request(struct ath10k *ar)
2262{
2263        int ret;
2264        unsigned long time_left;
2265
2266        lockdep_assert_held(&ar->conf_mutex);
2267
2268        reinit_completion(&ar->debug.tpc_complete);
2269
2270        ret = ath10k_wmi_pdev_get_tpc_table_cmdid(ar, WMI_TPC_CONFIG_PARAM);
2271        if (ret) {
2272                ath10k_warn(ar, "failed to request tpc table cmdid: %d\n", ret);
2273                return ret;
2274        }
2275
2276        time_left = wait_for_completion_timeout(&ar->debug.tpc_complete,
2277                                                1 * HZ);
2278        if (time_left == 0)
2279                return -ETIMEDOUT;
2280
2281        return 0;
2282}
2283
2284static int ath10k_tpc_stats_final_open(struct inode *inode, struct file *file)
2285{
2286        struct ath10k *ar = inode->i_private;
2287        void *buf;
2288        int ret;
2289
2290        mutex_lock(&ar->conf_mutex);
2291
2292        if (ar->state != ATH10K_STATE_ON) {
2293                ret = -ENETDOWN;
2294                goto err_unlock;
2295        }
2296
2297        buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE);
2298        if (!buf) {
2299                ret = -ENOMEM;
2300                goto err_unlock;
2301        }
2302
2303        ret = ath10k_debug_tpc_stats_final_request(ar);
2304        if (ret) {
2305                ath10k_warn(ar, "failed to request tpc stats final: %d\n",
2306                            ret);
2307                goto err_free;
2308        }
2309
2310        ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
2311        file->private_data = buf;
2312
2313        mutex_unlock(&ar->conf_mutex);
2314        return 0;
2315
2316err_free:
2317        vfree(buf);
2318
2319err_unlock:
2320        mutex_unlock(&ar->conf_mutex);
2321        return ret;
2322}
2323
2324static int ath10k_tpc_stats_final_release(struct inode *inode,
2325                                          struct file *file)
2326{
2327        vfree(file->private_data);
2328
2329        return 0;
2330}
2331
2332static ssize_t ath10k_tpc_stats_final_read(struct file *file,
2333                                           char __user *user_buf,
2334                                           size_t count, loff_t *ppos)
2335{
2336        const char *buf = file->private_data;
2337        unsigned int len = strlen(buf);
2338
2339        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2340}
2341
2342static const struct file_operations fops_tpc_stats_final = {
2343        .open = ath10k_tpc_stats_final_open,
2344        .release = ath10k_tpc_stats_final_release,
2345        .read = ath10k_tpc_stats_final_read,
2346        .owner = THIS_MODULE,
2347        .llseek = default_llseek,
2348};
2349
2350static ssize_t ath10k_write_warm_hw_reset(struct file *file,
2351                                          const char __user *user_buf,
2352                                          size_t count, loff_t *ppos)
2353{
2354        struct ath10k *ar = file->private_data;
2355        int ret;
2356        bool val;
2357
2358        if (kstrtobool_from_user(user_buf, count, &val))
2359                return -EFAULT;
2360
2361        if (!val)
2362                return -EINVAL;
2363
2364        mutex_lock(&ar->conf_mutex);
2365
2366        if (ar->state != ATH10K_STATE_ON) {
2367                ret = -ENETDOWN;
2368                goto exit;
2369        }
2370
2371        if (!(test_bit(WMI_SERVICE_RESET_CHIP, ar->wmi.svc_map)))
2372                ath10k_warn(ar, "wmi service for reset chip is not available\n");
2373
2374        ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pdev_reset,
2375                                        WMI_RST_MODE_WARM_RESET);
2376
2377        if (ret) {
2378                ath10k_warn(ar, "failed to enable warm hw reset: %d\n", ret);
2379                goto exit;
2380        }
2381
2382        ret = count;
2383
2384exit:
2385        mutex_unlock(&ar->conf_mutex);
2386        return ret;
2387}
2388
2389static const struct file_operations fops_warm_hw_reset = {
2390        .write = ath10k_write_warm_hw_reset,
2391        .open = simple_open,
2392        .owner = THIS_MODULE,
2393        .llseek = default_llseek,
2394};
2395
2396static void ath10k_peer_ps_state_disable(void *data,
2397                                         struct ieee80211_sta *sta)
2398{
2399        struct ath10k *ar = data;
2400        struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
2401
2402        spin_lock_bh(&ar->data_lock);
2403        arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
2404        spin_unlock_bh(&ar->data_lock);
2405}
2406
2407static ssize_t ath10k_write_ps_state_enable(struct file *file,
2408                                            const char __user *user_buf,
2409                                            size_t count, loff_t *ppos)
2410{
2411        struct ath10k *ar = file->private_data;
2412        int ret;
2413        u32 param;
2414        u8 ps_state_enable;
2415
2416        if (kstrtou8_from_user(user_buf, count, 0, &ps_state_enable))
2417                return -EINVAL;
2418
2419        if (ps_state_enable > 1)
2420                return -EINVAL;
2421
2422        mutex_lock(&ar->conf_mutex);
2423
2424        if (ar->ps_state_enable == ps_state_enable) {
2425                ret = count;
2426                goto exit;
2427        }
2428
2429        param = ar->wmi.pdev_param->peer_sta_ps_statechg_enable;
2430        ret = ath10k_wmi_pdev_set_param(ar, param, ps_state_enable);
2431        if (ret) {
2432                ath10k_warn(ar, "failed to enable ps_state_enable: %d\n",
2433                            ret);
2434                goto exit;
2435        }
2436        ar->ps_state_enable = ps_state_enable;
2437
2438        if (!ar->ps_state_enable)
2439                ieee80211_iterate_stations_atomic(ar->hw,
2440                                                  ath10k_peer_ps_state_disable,
2441                                                  ar);
2442
2443        ret = count;
2444
2445exit:
2446        mutex_unlock(&ar->conf_mutex);
2447
2448        return ret;
2449}
2450
2451static ssize_t ath10k_read_ps_state_enable(struct file *file,
2452                                           char __user *user_buf,
2453                                           size_t count, loff_t *ppos)
2454{
2455        struct ath10k *ar = file->private_data;
2456        int len = 0;
2457        char buf[32];
2458
2459        mutex_lock(&ar->conf_mutex);
2460        len = scnprintf(buf, sizeof(buf) - len, "%d\n",
2461                        ar->ps_state_enable);
2462        mutex_unlock(&ar->conf_mutex);
2463
2464        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2465}
2466
2467static const struct file_operations fops_ps_state_enable = {
2468        .read = ath10k_read_ps_state_enable,
2469        .write = ath10k_write_ps_state_enable,
2470        .open = simple_open,
2471        .owner = THIS_MODULE,
2472        .llseek = default_llseek,
2473};
2474
2475static ssize_t ath10k_write_reset_htt_stats(struct file *file,
2476                                            const char __user *user_buf,
2477                                            size_t count, loff_t *ppos)
2478{
2479        struct ath10k *ar = file->private_data;
2480        unsigned long reset;
2481        int ret;
2482
2483        ret = kstrtoul_from_user(user_buf, count, 0, &reset);
2484        if (ret)
2485                return ret;
2486
2487        if (reset == 0 || reset > 0x1ffff)
2488                return -EINVAL;
2489
2490        mutex_lock(&ar->conf_mutex);
2491
2492        ar->debug.reset_htt_stats = reset;
2493
2494        ret = ath10k_debug_htt_stats_req(ar);
2495        if (ret)
2496                goto out;
2497
2498        ar->debug.reset_htt_stats = 0;
2499        ret = count;
2500
2501out:
2502        mutex_unlock(&ar->conf_mutex);
2503        return ret;
2504}
2505
2506static const struct file_operations fops_reset_htt_stats = {
2507        .write = ath10k_write_reset_htt_stats,
2508        .owner = THIS_MODULE,
2509        .open = simple_open,
2510        .llseek = default_llseek,
2511};
2512
2513int ath10k_debug_create(struct ath10k *ar)
2514{
2515        ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN);
2516        if (!ar->debug.cal_data)
2517                return -ENOMEM;
2518
2519        INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
2520        INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
2521        INIT_LIST_HEAD(&ar->debug.fw_stats.peers);
2522        INIT_LIST_HEAD(&ar->debug.fw_stats.peers_extd);
2523
2524        return 0;
2525}
2526
2527void ath10k_debug_destroy(struct ath10k *ar)
2528{
2529        vfree(ar->debug.cal_data);
2530        ar->debug.cal_data = NULL;
2531
2532        ath10k_debug_fw_stats_reset(ar);
2533
2534        kfree(ar->debug.tpc_stats);
2535}
2536
2537int ath10k_debug_register(struct ath10k *ar)
2538{
2539        ar->debug.debugfs_phy = debugfs_create_dir("ath10k",
2540                                                   ar->hw->wiphy->debugfsdir);
2541        if (IS_ERR_OR_NULL(ar->debug.debugfs_phy)) {
2542                if (IS_ERR(ar->debug.debugfs_phy))
2543                        return PTR_ERR(ar->debug.debugfs_phy);
2544
2545                return -ENOMEM;
2546        }
2547
2548        INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork,
2549                          ath10k_debug_htt_stats_dwork);
2550
2551        init_completion(&ar->debug.tpc_complete);
2552        init_completion(&ar->debug.fw_stats_complete);
2553
2554        debugfs_create_file("fw_stats", 0400, ar->debug.debugfs_phy, ar,
2555                            &fops_fw_stats);
2556
2557        debugfs_create_file("fw_reset_stats", 0400, ar->debug.debugfs_phy, ar,
2558                            &fops_fw_reset_stats);
2559
2560        debugfs_create_file("wmi_services", 0400, ar->debug.debugfs_phy, ar,
2561                            &fops_wmi_services);
2562
2563        debugfs_create_file("simulate_fw_crash", 0600, ar->debug.debugfs_phy, ar,
2564                            &fops_simulate_fw_crash);
2565
2566        debugfs_create_file("reg_addr", 0600, ar->debug.debugfs_phy, ar,
2567                            &fops_reg_addr);
2568
2569        debugfs_create_file("reg_value", 0600, ar->debug.debugfs_phy, ar,
2570                            &fops_reg_value);
2571
2572        debugfs_create_file("mem_value", 0600, ar->debug.debugfs_phy, ar,
2573                            &fops_mem_value);
2574
2575        debugfs_create_file("chip_id", 0400, ar->debug.debugfs_phy, ar,
2576                            &fops_chip_id);
2577
2578        debugfs_create_file("htt_stats_mask", 0600, ar->debug.debugfs_phy, ar,
2579                            &fops_htt_stats_mask);
2580
2581        debugfs_create_file("htt_max_amsdu_ampdu", 0600, ar->debug.debugfs_phy, ar,
2582                            &fops_htt_max_amsdu_ampdu);
2583
2584        debugfs_create_file("fw_dbglog", 0600, ar->debug.debugfs_phy, ar,
2585                            &fops_fw_dbglog);
2586
2587        if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
2588                      ar->normal_mode_fw.fw_file.fw_features)) {
2589                debugfs_create_file("cal_data", 0400, ar->debug.debugfs_phy, ar,
2590                                    &fops_cal_data);
2591
2592                debugfs_create_file("nf_cal_period", 0600, ar->debug.debugfs_phy, ar,
2593                                    &fops_nf_cal_period);
2594        }
2595
2596        debugfs_create_file("ani_enable", 0600, ar->debug.debugfs_phy, ar,
2597                            &fops_ani_enable);
2598
2599        if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) {
2600                debugfs_create_file("dfs_simulate_radar", 0200, ar->debug.debugfs_phy,
2601                                    ar, &fops_simulate_radar);
2602
2603                debugfs_create_bool("dfs_block_radar_events", 0200,
2604                                    ar->debug.debugfs_phy,
2605                                    &ar->dfs_block_radar_events);
2606
2607                debugfs_create_file("dfs_stats", 0400, ar->debug.debugfs_phy, ar,
2608                                    &fops_dfs_stats);
2609        }
2610
2611        debugfs_create_file("pktlog_filter", 0644, ar->debug.debugfs_phy, ar,
2612                            &fops_pktlog_filter);
2613
2614        if (test_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map))
2615                debugfs_create_file("quiet_period", 0644, ar->debug.debugfs_phy, ar,
2616                                    &fops_quiet_period);
2617
2618        debugfs_create_file("tpc_stats", 0400, ar->debug.debugfs_phy, ar,
2619                            &fops_tpc_stats);
2620
2621        if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
2622                debugfs_create_file("btcoex", 0644, ar->debug.debugfs_phy, ar,
2623                                    &fops_btcoex);
2624
2625        if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map)) {
2626                debugfs_create_file("peer_stats", 0644, ar->debug.debugfs_phy, ar,
2627                                    &fops_peer_stats);
2628
2629                debugfs_create_file("enable_extd_tx_stats", 0644,
2630                                    ar->debug.debugfs_phy, ar,
2631                                    &fops_enable_extd_tx_stats);
2632        }
2633
2634        debugfs_create_file("fw_checksums", 0400, ar->debug.debugfs_phy, ar,
2635                            &fops_fw_checksums);
2636
2637        if (IS_ENABLED(CONFIG_MAC80211_DEBUGFS))
2638                debugfs_create_file("sta_tid_stats_mask", 0600,
2639                                    ar->debug.debugfs_phy,
2640                                    ar, &fops_sta_tid_stats_mask);
2641
2642        if (test_bit(WMI_SERVICE_TPC_STATS_FINAL, ar->wmi.svc_map))
2643                debugfs_create_file("tpc_stats_final", 0400,
2644                                    ar->debug.debugfs_phy, ar,
2645                                    &fops_tpc_stats_final);
2646
2647        debugfs_create_file("warm_hw_reset", 0600, ar->debug.debugfs_phy, ar,
2648                            &fops_warm_hw_reset);
2649
2650        debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_phy, ar,
2651                            &fops_ps_state_enable);
2652
2653        debugfs_create_file("reset_htt_stats", 0200, ar->debug.debugfs_phy, ar,
2654                            &fops_reset_htt_stats);
2655
2656        return 0;
2657}
2658
2659void ath10k_debug_unregister(struct ath10k *ar)
2660{
2661        cancel_delayed_work_sync(&ar->debug.htt_stats_dwork);
2662}
2663
2664#endif /* CONFIG_ATH10K_DEBUGFS */
2665
2666#ifdef CONFIG_ATH10K_DEBUG
2667void __ath10k_dbg(struct ath10k *ar, enum ath10k_debug_mask mask,
2668                  const char *fmt, ...)
2669{
2670        struct va_format vaf;
2671        va_list args;
2672
2673        va_start(args, fmt);
2674
2675        vaf.fmt = fmt;
2676        vaf.va = &args;
2677
2678        if (ath10k_debug_mask & mask)
2679                dev_printk(KERN_DEBUG, ar->dev, "%pV", &vaf);
2680
2681        trace_ath10k_log_dbg(ar, mask, &vaf);
2682
2683        va_end(args);
2684}
2685EXPORT_SYMBOL(__ath10k_dbg);
2686
2687void ath10k_dbg_dump(struct ath10k *ar,
2688                     enum ath10k_debug_mask mask,
2689                     const char *msg, const char *prefix,
2690                     const void *buf, size_t len)
2691{
2692        char linebuf[256];
2693        size_t linebuflen;
2694        const void *ptr;
2695
2696        if (ath10k_debug_mask & mask) {
2697                if (msg)
2698                        __ath10k_dbg(ar, mask, "%s\n", msg);
2699
2700                for (ptr = buf; (ptr - buf) < len; ptr += 16) {
2701                        linebuflen = 0;
2702                        linebuflen += scnprintf(linebuf + linebuflen,
2703                                                sizeof(linebuf) - linebuflen,
2704                                                "%s%08x: ",
2705                                                (prefix ? prefix : ""),
2706                                                (unsigned int)(ptr - buf));
2707                        hex_dump_to_buffer(ptr, len - (ptr - buf), 16, 1,
2708                                           linebuf + linebuflen,
2709                                           sizeof(linebuf) - linebuflen, true);
2710                        dev_printk(KERN_DEBUG, ar->dev, "%s\n", linebuf);
2711                }
2712        }
2713
2714        /* tracing code doesn't like null strings :/ */
2715        trace_ath10k_log_dbg_dump(ar, msg ? msg : "", prefix ? prefix : "",
2716                                  buf, len);
2717}
2718EXPORT_SYMBOL(ath10k_dbg_dump);
2719
2720#endif /* CONFIG_ATH10K_DEBUG */
2721