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
 352int 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 from 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_rx_crc_err_drop", /* frame with FCS error, dropped late in kernel */
1098        "d_no_beacon",
1099        "d_tx_mpdus_queued",
1100        "d_tx_msdu_queued",
1101        "d_tx_msdu_dropped",
1102        "d_local_enqued",
1103        "d_local_freed",
1104        "d_tx_ppdu_hw_queued",
1105        "d_tx_ppdu_reaped",
1106        "d_tx_fifo_underrun",
1107        "d_tx_ppdu_abort",
1108        "d_tx_mpdu_requed",
1109        "d_tx_excessive_retries",
1110        "d_tx_hw_rate",
1111        "d_tx_dropped_sw_retries",
1112        "d_tx_illegal_rate",
1113        "d_tx_continuous_xretries",
1114        "d_tx_timeout",
1115        "d_tx_mpdu_txop_limit",
1116        "d_pdev_resets",
1117        "d_rx_mid_ppdu_route_change",
1118        "d_rx_status",
1119        "d_rx_extra_frags_ring0",
1120        "d_rx_extra_frags_ring1",
1121        "d_rx_extra_frags_ring2",
1122        "d_rx_extra_frags_ring3",
1123        "d_rx_msdu_htt",
1124        "d_rx_mpdu_htt",
1125        "d_rx_msdu_stack",
1126        "d_rx_mpdu_stack",
1127        "d_rx_phy_err",
1128        "d_rx_phy_err_drops",
1129        "d_rx_mpdu_errors", /* FCS, MIC, ENC */
1130        "d_fw_crash_count",
1131        "d_fw_warm_reset_count",
1132        "d_fw_cold_reset_count",
1133};
1134
1135#define ATH10K_SSTATS_LEN ARRAY_SIZE(ath10k_gstrings_stats)
1136
1137void ath10k_debug_get_et_strings(struct ieee80211_hw *hw,
1138                                 struct ieee80211_vif *vif,
1139                                 u32 sset, u8 *data)
1140{
1141        if (sset == ETH_SS_STATS)
1142                memcpy(data, *ath10k_gstrings_stats,
1143                       sizeof(ath10k_gstrings_stats));
1144}
1145
1146int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw,
1147                                   struct ieee80211_vif *vif, int sset)
1148{
1149        if (sset == ETH_SS_STATS)
1150                return ATH10K_SSTATS_LEN;
1151
1152        return 0;
1153}
1154
1155void ath10k_debug_get_et_stats(struct ieee80211_hw *hw,
1156                               struct ieee80211_vif *vif,
1157                               struct ethtool_stats *stats, u64 *data)
1158{
1159        struct ath10k *ar = hw->priv;
1160        static const struct ath10k_fw_stats_pdev zero_stats = {};
1161        const struct ath10k_fw_stats_pdev *pdev_stats;
1162        int i = 0, ret;
1163
1164        mutex_lock(&ar->conf_mutex);
1165
1166        if (ar->state == ATH10K_STATE_ON) {
1167                ret = ath10k_debug_fw_stats_request(ar);
1168                if (ret) {
1169                        /* just print a warning and try to use older results */
1170                        ath10k_warn(ar,
1171                                    "failed to get fw stats for ethtool: %d\n",
1172                                    ret);
1173                }
1174        }
1175
1176        pdev_stats = list_first_entry_or_null(&ar->debug.fw_stats.pdevs,
1177                                              struct ath10k_fw_stats_pdev,
1178                                              list);
1179        if (!pdev_stats) {
1180                /* no results available so just return zeroes */
1181                pdev_stats = &zero_stats;
1182        }
1183
1184        spin_lock_bh(&ar->data_lock);
1185
1186        data[i++] = pdev_stats->hw_reaped; /* ppdu reaped */
1187        data[i++] = 0; /* tx bytes */
1188        data[i++] = pdev_stats->htt_mpdus;
1189        data[i++] = 0; /* rx bytes */
1190        data[i++] = pdev_stats->ch_noise_floor;
1191        data[i++] = pdev_stats->cycle_count;
1192        data[i++] = pdev_stats->phy_err_count;
1193        data[i++] = pdev_stats->rts_bad;
1194        data[i++] = pdev_stats->rts_good;
1195        data[i++] = pdev_stats->chan_tx_power;
1196        data[i++] = pdev_stats->fcs_bad;
1197        data[i++] = ar->stats.rx_crc_err_drop;
1198        data[i++] = pdev_stats->no_beacons;
1199        data[i++] = pdev_stats->mpdu_enqued;
1200        data[i++] = pdev_stats->msdu_enqued;
1201        data[i++] = pdev_stats->wmm_drop;
1202        data[i++] = pdev_stats->local_enqued;
1203        data[i++] = pdev_stats->local_freed;
1204        data[i++] = pdev_stats->hw_queued;
1205        data[i++] = pdev_stats->hw_reaped;
1206        data[i++] = pdev_stats->underrun;
1207        data[i++] = pdev_stats->tx_abort;
1208        data[i++] = pdev_stats->mpdus_requed;
1209        data[i++] = pdev_stats->tx_ko;
1210        data[i++] = pdev_stats->data_rc;
1211        data[i++] = pdev_stats->sw_retry_failure;
1212        data[i++] = pdev_stats->illgl_rate_phy_err;
1213        data[i++] = pdev_stats->pdev_cont_xretry;
1214        data[i++] = pdev_stats->pdev_tx_timeout;
1215        data[i++] = pdev_stats->txop_ovf;
1216        data[i++] = pdev_stats->pdev_resets;
1217        data[i++] = pdev_stats->mid_ppdu_route_change;
1218        data[i++] = pdev_stats->status_rcvd;
1219        data[i++] = pdev_stats->r0_frags;
1220        data[i++] = pdev_stats->r1_frags;
1221        data[i++] = pdev_stats->r2_frags;
1222        data[i++] = pdev_stats->r3_frags;
1223        data[i++] = pdev_stats->htt_msdus;
1224        data[i++] = pdev_stats->htt_mpdus;
1225        data[i++] = pdev_stats->loc_msdus;
1226        data[i++] = pdev_stats->loc_mpdus;
1227        data[i++] = pdev_stats->phy_errs;
1228        data[i++] = pdev_stats->phy_err_drop;
1229        data[i++] = pdev_stats->mpdu_errs;
1230        data[i++] = ar->stats.fw_crash_counter;
1231        data[i++] = ar->stats.fw_warm_reset_counter;
1232        data[i++] = ar->stats.fw_cold_reset_counter;
1233
1234        spin_unlock_bh(&ar->data_lock);
1235
1236        mutex_unlock(&ar->conf_mutex);
1237
1238        WARN_ON(i != ATH10K_SSTATS_LEN);
1239}
1240
1241static const struct file_operations fops_fw_dbglog = {
1242        .read = ath10k_read_fw_dbglog,
1243        .write = ath10k_write_fw_dbglog,
1244        .open = simple_open,
1245        .owner = THIS_MODULE,
1246        .llseek = default_llseek,
1247};
1248
1249static int ath10k_debug_cal_data_fetch(struct ath10k *ar)
1250{
1251        u32 hi_addr;
1252        __le32 addr;
1253        int ret;
1254
1255        lockdep_assert_held(&ar->conf_mutex);
1256
1257        if (WARN_ON(ar->hw_params.cal_data_len > ATH10K_DEBUG_CAL_DATA_LEN))
1258                return -EINVAL;
1259
1260        if (ar->hw_params.cal_data_len == 0)
1261                return -EOPNOTSUPP;
1262
1263        hi_addr = host_interest_item_address(HI_ITEM(hi_board_data));
1264
1265        ret = ath10k_hif_diag_read(ar, hi_addr, &addr, sizeof(addr));
1266        if (ret) {
1267                ath10k_warn(ar, "failed to read hi_board_data address: %d\n",
1268                            ret);
1269                return ret;
1270        }
1271
1272        ret = ath10k_hif_diag_read(ar, le32_to_cpu(addr), ar->debug.cal_data,
1273                                   ar->hw_params.cal_data_len);
1274        if (ret) {
1275                ath10k_warn(ar, "failed to read calibration data: %d\n", ret);
1276                return ret;
1277        }
1278
1279        return 0;
1280}
1281
1282static int ath10k_debug_cal_data_open(struct inode *inode, struct file *file)
1283{
1284        struct ath10k *ar = inode->i_private;
1285
1286        mutex_lock(&ar->conf_mutex);
1287
1288        if (ar->state == ATH10K_STATE_ON ||
1289            ar->state == ATH10K_STATE_UTF) {
1290                ath10k_debug_cal_data_fetch(ar);
1291        }
1292
1293        file->private_data = ar;
1294        mutex_unlock(&ar->conf_mutex);
1295
1296        return 0;
1297}
1298
1299static ssize_t ath10k_debug_cal_data_read(struct file *file,
1300                                          char __user *user_buf,
1301                                          size_t count, loff_t *ppos)
1302{
1303        struct ath10k *ar = file->private_data;
1304
1305        mutex_lock(&ar->conf_mutex);
1306
1307        count = simple_read_from_buffer(user_buf, count, ppos,
1308                                        ar->debug.cal_data,
1309                                        ar->hw_params.cal_data_len);
1310
1311        mutex_unlock(&ar->conf_mutex);
1312
1313        return count;
1314}
1315
1316static ssize_t ath10k_write_ani_enable(struct file *file,
1317                                       const char __user *user_buf,
1318                                       size_t count, loff_t *ppos)
1319{
1320        struct ath10k *ar = file->private_data;
1321        int ret;
1322        u8 enable;
1323
1324        if (kstrtou8_from_user(user_buf, count, 0, &enable))
1325                return -EINVAL;
1326
1327        mutex_lock(&ar->conf_mutex);
1328
1329        if (ar->ani_enabled == enable) {
1330                ret = count;
1331                goto exit;
1332        }
1333
1334        ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->ani_enable,
1335                                        enable);
1336        if (ret) {
1337                ath10k_warn(ar, "ani_enable failed from debugfs: %d\n", ret);
1338                goto exit;
1339        }
1340        ar->ani_enabled = enable;
1341
1342        ret = count;
1343
1344exit:
1345        mutex_unlock(&ar->conf_mutex);
1346
1347        return ret;
1348}
1349
1350static ssize_t ath10k_read_ani_enable(struct file *file, char __user *user_buf,
1351                                      size_t count, loff_t *ppos)
1352{
1353        struct ath10k *ar = file->private_data;
1354        size_t len;
1355        char buf[32];
1356
1357        len = scnprintf(buf, sizeof(buf), "%d\n", ar->ani_enabled);
1358
1359        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1360}
1361
1362static const struct file_operations fops_ani_enable = {
1363        .read = ath10k_read_ani_enable,
1364        .write = ath10k_write_ani_enable,
1365        .open = simple_open,
1366        .owner = THIS_MODULE,
1367        .llseek = default_llseek,
1368};
1369
1370static const struct file_operations fops_cal_data = {
1371        .open = ath10k_debug_cal_data_open,
1372        .read = ath10k_debug_cal_data_read,
1373        .owner = THIS_MODULE,
1374        .llseek = default_llseek,
1375};
1376
1377static ssize_t ath10k_read_nf_cal_period(struct file *file,
1378                                         char __user *user_buf,
1379                                         size_t count, loff_t *ppos)
1380{
1381        struct ath10k *ar = file->private_data;
1382        size_t len;
1383        char buf[32];
1384
1385        len = scnprintf(buf, sizeof(buf), "%d\n", ar->debug.nf_cal_period);
1386
1387        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1388}
1389
1390static ssize_t ath10k_write_nf_cal_period(struct file *file,
1391                                          const char __user *user_buf,
1392                                          size_t count, loff_t *ppos)
1393{
1394        struct ath10k *ar = file->private_data;
1395        unsigned long period;
1396        int ret;
1397
1398        ret = kstrtoul_from_user(user_buf, count, 0, &period);
1399        if (ret)
1400                return ret;
1401
1402        if (period > WMI_PDEV_PARAM_CAL_PERIOD_MAX)
1403                return -EINVAL;
1404
1405        /* there's no way to switch back to the firmware default */
1406        if (period == 0)
1407                return -EINVAL;
1408
1409        mutex_lock(&ar->conf_mutex);
1410
1411        ar->debug.nf_cal_period = period;
1412
1413        if (ar->state != ATH10K_STATE_ON) {
1414                /* firmware is not running, nothing else to do */
1415                ret = count;
1416                goto exit;
1417        }
1418
1419        ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->cal_period,
1420                                        ar->debug.nf_cal_period);
1421        if (ret) {
1422                ath10k_warn(ar, "cal period cfg failed from debugfs: %d\n",
1423                            ret);
1424                goto exit;
1425        }
1426
1427        ret = count;
1428
1429exit:
1430        mutex_unlock(&ar->conf_mutex);
1431
1432        return ret;
1433}
1434
1435static const struct file_operations fops_nf_cal_period = {
1436        .read = ath10k_read_nf_cal_period,
1437        .write = ath10k_write_nf_cal_period,
1438        .open = simple_open,
1439        .owner = THIS_MODULE,
1440        .llseek = default_llseek,
1441};
1442
1443#define ATH10K_TPC_CONFIG_BUF_SIZE      (1024 * 1024)
1444
1445static int ath10k_debug_tpc_stats_request(struct ath10k *ar)
1446{
1447        int ret;
1448        unsigned long time_left;
1449
1450        lockdep_assert_held(&ar->conf_mutex);
1451
1452        reinit_completion(&ar->debug.tpc_complete);
1453
1454        ret = ath10k_wmi_pdev_get_tpc_config(ar, WMI_TPC_CONFIG_PARAM);
1455        if (ret) {
1456                ath10k_warn(ar, "failed to request tpc config: %d\n", ret);
1457                return ret;
1458        }
1459
1460        time_left = wait_for_completion_timeout(&ar->debug.tpc_complete,
1461                                                1 * HZ);
1462        if (time_left == 0)
1463                return -ETIMEDOUT;
1464
1465        return 0;
1466}
1467
1468void ath10k_debug_tpc_stats_process(struct ath10k *ar,
1469                                    struct ath10k_tpc_stats *tpc_stats)
1470{
1471        spin_lock_bh(&ar->data_lock);
1472
1473        kfree(ar->debug.tpc_stats);
1474        ar->debug.tpc_stats = tpc_stats;
1475        complete(&ar->debug.tpc_complete);
1476
1477        spin_unlock_bh(&ar->data_lock);
1478}
1479
1480void
1481ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
1482                                     struct ath10k_tpc_stats_final *tpc_stats)
1483{
1484        spin_lock_bh(&ar->data_lock);
1485
1486        kfree(ar->debug.tpc_stats_final);
1487        ar->debug.tpc_stats_final = tpc_stats;
1488        complete(&ar->debug.tpc_complete);
1489
1490        spin_unlock_bh(&ar->data_lock);
1491}
1492
1493static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats,
1494                                   unsigned int j, char *buf, size_t *len)
1495{
1496        int i;
1497        size_t buf_len;
1498        static const char table_str[][5] = { "CDD",
1499                                             "STBC",
1500                                             "TXBF" };
1501        static const char pream_str[][6] = { "CCK",
1502                                             "OFDM",
1503                                             "HT20",
1504                                             "HT40",
1505                                             "VHT20",
1506                                             "VHT40",
1507                                             "VHT80",
1508                                             "HTCUP" };
1509
1510        buf_len = ATH10K_TPC_CONFIG_BUF_SIZE;
1511        *len += scnprintf(buf + *len, buf_len - *len,
1512                          "********************************\n");
1513        *len += scnprintf(buf + *len, buf_len - *len,
1514                          "******************* %s POWER TABLE ****************\n",
1515                          table_str[j]);
1516        *len += scnprintf(buf + *len, buf_len - *len,
1517                          "********************************\n");
1518        *len += scnprintf(buf + *len, buf_len - *len,
1519                          "No.  Preamble Rate_code ");
1520
1521        for (i = 0; i < tpc_stats->num_tx_chain; i++)
1522                *len += scnprintf(buf + *len, buf_len - *len,
1523                                  "tpc_value%d ", i);
1524
1525        *len += scnprintf(buf + *len, buf_len - *len, "\n");
1526
1527        for (i = 0; i < tpc_stats->rate_max; i++) {
1528                *len += scnprintf(buf + *len, buf_len - *len,
1529                                  "%8d %s 0x%2x %s\n", i,
1530                                  pream_str[tpc_stats->tpc_table[j].pream_idx[i]],
1531                                  tpc_stats->tpc_table[j].rate_code[i],
1532                                  tpc_stats->tpc_table[j].tpc_value[i]);
1533        }
1534
1535        *len += scnprintf(buf + *len, buf_len - *len,
1536                          "***********************************\n");
1537}
1538
1539static void ath10k_tpc_stats_fill(struct ath10k *ar,
1540                                  struct ath10k_tpc_stats *tpc_stats,
1541                                  char *buf)
1542{
1543        int j;
1544        size_t len, buf_len;
1545
1546        len = 0;
1547        buf_len = ATH10K_TPC_CONFIG_BUF_SIZE;
1548
1549        spin_lock_bh(&ar->data_lock);
1550
1551        if (!tpc_stats) {
1552                ath10k_warn(ar, "failed to get tpc stats\n");
1553                goto unlock;
1554        }
1555
1556        len += scnprintf(buf + len, buf_len - len, "\n");
1557        len += scnprintf(buf + len, buf_len - len,
1558                         "*************************************\n");
1559        len += scnprintf(buf + len, buf_len - len,
1560                         "TPC config for channel %4d mode %d\n",
1561                         tpc_stats->chan_freq,
1562                         tpc_stats->phy_mode);
1563        len += scnprintf(buf + len, buf_len - len,
1564                         "*************************************\n");
1565        len += scnprintf(buf + len, buf_len - len,
1566                         "CTL           =  0x%2x Reg. Domain            = %2d\n",
1567                         tpc_stats->ctl,
1568                         tpc_stats->reg_domain);
1569        len += scnprintf(buf + len, buf_len - len,
1570                         "Antenna Gain  = %2d Reg. Max Antenna Gain     =  %2d\n",
1571                         tpc_stats->twice_antenna_gain,
1572                         tpc_stats->twice_antenna_reduction);
1573        len += scnprintf(buf + len, buf_len - len,
1574                         "Power Limit   = %2d Reg. Max Power            = %2d\n",
1575                         tpc_stats->power_limit,
1576                         tpc_stats->twice_max_rd_power / 2);
1577        len += scnprintf(buf + len, buf_len - len,
1578                         "Num tx chains = %2d Num supported rates       = %2d\n",
1579                         tpc_stats->num_tx_chain,
1580                         tpc_stats->rate_max);
1581
1582        for (j = 0; j < WMI_TPC_FLAG; j++) {
1583                switch (j) {
1584                case WMI_TPC_TABLE_TYPE_CDD:
1585                        if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
1586                                len += scnprintf(buf + len, buf_len - len,
1587                                                 "CDD not supported\n");
1588                                break;
1589                        }
1590
1591                        ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
1592                        break;
1593                case WMI_TPC_TABLE_TYPE_STBC:
1594                        if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
1595                                len += scnprintf(buf + len, buf_len - len,
1596                                                 "STBC not supported\n");
1597                                break;
1598                        }
1599
1600                        ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
1601                        break;
1602                case WMI_TPC_TABLE_TYPE_TXBF:
1603                        if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
1604                                len += scnprintf(buf + len, buf_len - len,
1605                                                 "TXBF not supported\n***************************\n");
1606                                break;
1607                        }
1608
1609                        ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
1610                        break;
1611                default:
1612                        len += scnprintf(buf + len, buf_len - len,
1613                                         "Invalid Type\n");
1614                        break;
1615                }
1616        }
1617
1618unlock:
1619        spin_unlock_bh(&ar->data_lock);
1620
1621        if (len >= buf_len)
1622                buf[len - 1] = 0;
1623        else
1624                buf[len] = 0;
1625}
1626
1627static int ath10k_tpc_stats_open(struct inode *inode, struct file *file)
1628{
1629        struct ath10k *ar = inode->i_private;
1630        void *buf = NULL;
1631        int ret;
1632
1633        mutex_lock(&ar->conf_mutex);
1634
1635        if (ar->state != ATH10K_STATE_ON) {
1636                ret = -ENETDOWN;
1637                goto err_unlock;
1638        }
1639
1640        buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE);
1641        if (!buf) {
1642                ret = -ENOMEM;
1643                goto err_unlock;
1644        }
1645
1646        ret = ath10k_debug_tpc_stats_request(ar);
1647        if (ret) {
1648                ath10k_warn(ar, "failed to request tpc config stats: %d\n",
1649                            ret);
1650                goto err_free;
1651        }
1652
1653        ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
1654        file->private_data = buf;
1655
1656        mutex_unlock(&ar->conf_mutex);
1657        return 0;
1658
1659err_free:
1660        vfree(buf);
1661
1662err_unlock:
1663        mutex_unlock(&ar->conf_mutex);
1664        return ret;
1665}
1666
1667static int ath10k_tpc_stats_release(struct inode *inode, struct file *file)
1668{
1669        vfree(file->private_data);
1670
1671        return 0;
1672}
1673
1674static ssize_t ath10k_tpc_stats_read(struct file *file, char __user *user_buf,
1675                                     size_t count, loff_t *ppos)
1676{
1677        const char *buf = file->private_data;
1678        size_t len = strlen(buf);
1679
1680        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1681}
1682
1683static const struct file_operations fops_tpc_stats = {
1684        .open = ath10k_tpc_stats_open,
1685        .release = ath10k_tpc_stats_release,
1686        .read = ath10k_tpc_stats_read,
1687        .owner = THIS_MODULE,
1688        .llseek = default_llseek,
1689};
1690
1691int ath10k_debug_start(struct ath10k *ar)
1692{
1693        int ret;
1694
1695        lockdep_assert_held(&ar->conf_mutex);
1696
1697        ret = ath10k_debug_htt_stats_req(ar);
1698        if (ret)
1699                /* continue normally anyway, this isn't serious */
1700                ath10k_warn(ar, "failed to start htt stats workqueue: %d\n",
1701                            ret);
1702
1703        if (ar->debug.fw_dbglog_mask) {
1704                ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask,
1705                                            ATH10K_DBGLOG_LEVEL_WARN);
1706                if (ret)
1707                        /* not serious */
1708                        ath10k_warn(ar, "failed to enable dbglog during start: %d",
1709                                    ret);
1710        }
1711
1712        if (ar->pktlog_filter) {
1713                ret = ath10k_wmi_pdev_pktlog_enable(ar,
1714                                                    ar->pktlog_filter);
1715                if (ret)
1716                        /* not serious */
1717                        ath10k_warn(ar,
1718                                    "failed to enable pktlog filter %x: %d\n",
1719                                    ar->pktlog_filter, ret);
1720        } else {
1721                ret = ath10k_wmi_pdev_pktlog_disable(ar);
1722                if (ret)
1723                        /* not serious */
1724                        ath10k_warn(ar, "failed to disable pktlog: %d\n", ret);
1725        }
1726
1727        if (ar->debug.nf_cal_period &&
1728            !test_bit(ATH10K_FW_FEATURE_NON_BMI,
1729                      ar->normal_mode_fw.fw_file.fw_features)) {
1730                ret = ath10k_wmi_pdev_set_param(ar,
1731                                                ar->wmi.pdev_param->cal_period,
1732                                                ar->debug.nf_cal_period);
1733                if (ret)
1734                        /* not serious */
1735                        ath10k_warn(ar, "cal period cfg failed from debug start: %d\n",
1736                                    ret);
1737        }
1738
1739        return ret;
1740}
1741
1742void ath10k_debug_stop(struct ath10k *ar)
1743{
1744        lockdep_assert_held(&ar->conf_mutex);
1745
1746        if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
1747                      ar->normal_mode_fw.fw_file.fw_features))
1748                ath10k_debug_cal_data_fetch(ar);
1749
1750        /* Must not use _sync to avoid deadlock, we do that in
1751         * ath10k_debug_destroy(). The check for htt_stats_mask is to avoid
1752         * warning from del_timer().
1753         */
1754        if (ar->debug.htt_stats_mask != 0)
1755                cancel_delayed_work(&ar->debug.htt_stats_dwork);
1756
1757        ath10k_wmi_pdev_pktlog_disable(ar);
1758}
1759
1760static ssize_t ath10k_write_simulate_radar(struct file *file,
1761                                           const char __user *user_buf,
1762                                           size_t count, loff_t *ppos)
1763{
1764        struct ath10k *ar = file->private_data;
1765        struct ath10k_vif *arvif;
1766
1767        /* Just check for for the first vif alone, as all the vifs will be
1768         * sharing the same channel and if the channel is disabled, all the
1769         * vifs will share the same 'is_started' state.
1770         */
1771        arvif = list_first_entry(&ar->arvifs, typeof(*arvif), list);
1772        if (!arvif->is_started)
1773                return -EINVAL;
1774
1775        ieee80211_radar_detected(ar->hw);
1776
1777        return count;
1778}
1779
1780static const struct file_operations fops_simulate_radar = {
1781        .write = ath10k_write_simulate_radar,
1782        .open = simple_open,
1783        .owner = THIS_MODULE,
1784        .llseek = default_llseek,
1785};
1786
1787#define ATH10K_DFS_STAT(s, p) (\
1788        len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
1789                         ar->debug.dfs_stats.p))
1790
1791#define ATH10K_DFS_POOL_STAT(s, p) (\
1792        len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
1793                         ar->debug.dfs_pool_stats.p))
1794
1795static ssize_t ath10k_read_dfs_stats(struct file *file, char __user *user_buf,
1796                                     size_t count, loff_t *ppos)
1797{
1798        int retval = 0, len = 0;
1799        const int size = 8000;
1800        struct ath10k *ar = file->private_data;
1801        char *buf;
1802
1803        buf = kzalloc(size, GFP_KERNEL);
1804        if (buf == NULL)
1805                return -ENOMEM;
1806
1807        if (!ar->dfs_detector) {
1808                len += scnprintf(buf + len, size - len, "DFS not enabled\n");
1809                goto exit;
1810        }
1811
1812        ar->debug.dfs_pool_stats =
1813                        ar->dfs_detector->get_stats(ar->dfs_detector);
1814
1815        len += scnprintf(buf + len, size - len, "Pulse detector statistics:\n");
1816
1817        ATH10K_DFS_STAT("reported phy errors", phy_errors);
1818        ATH10K_DFS_STAT("pulse events reported", pulses_total);
1819        ATH10K_DFS_STAT("DFS pulses detected", pulses_detected);
1820        ATH10K_DFS_STAT("DFS pulses discarded", pulses_discarded);
1821        ATH10K_DFS_STAT("Radars detected", radar_detected);
1822
1823        len += scnprintf(buf + len, size - len, "Global Pool statistics:\n");
1824        ATH10K_DFS_POOL_STAT("Pool references", pool_reference);
1825        ATH10K_DFS_POOL_STAT("Pulses allocated", pulse_allocated);
1826        ATH10K_DFS_POOL_STAT("Pulses alloc error", pulse_alloc_error);
1827        ATH10K_DFS_POOL_STAT("Pulses in use", pulse_used);
1828        ATH10K_DFS_POOL_STAT("Seqs. allocated", pseq_allocated);
1829        ATH10K_DFS_POOL_STAT("Seqs. alloc error", pseq_alloc_error);
1830        ATH10K_DFS_POOL_STAT("Seqs. in use", pseq_used);
1831
1832exit:
1833        if (len > size)
1834                len = size;
1835
1836        retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1837        kfree(buf);
1838
1839        return retval;
1840}
1841
1842static const struct file_operations fops_dfs_stats = {
1843        .read = ath10k_read_dfs_stats,
1844        .open = simple_open,
1845        .owner = THIS_MODULE,
1846        .llseek = default_llseek,
1847};
1848
1849static ssize_t ath10k_write_pktlog_filter(struct file *file,
1850                                          const char __user *ubuf,
1851                                          size_t count, loff_t *ppos)
1852{
1853        struct ath10k *ar = file->private_data;
1854        u32 filter;
1855        int ret;
1856
1857        if (kstrtouint_from_user(ubuf, count, 0, &filter))
1858                return -EINVAL;
1859
1860        mutex_lock(&ar->conf_mutex);
1861
1862        if (ar->state != ATH10K_STATE_ON) {
1863                ar->pktlog_filter = filter;
1864                ret = count;
1865                goto out;
1866        }
1867
1868        if (filter == ar->pktlog_filter) {
1869                ret = count;
1870                goto out;
1871        }
1872
1873        if (filter) {
1874                ret = ath10k_wmi_pdev_pktlog_enable(ar, filter);
1875                if (ret) {
1876                        ath10k_warn(ar, "failed to enable pktlog filter %x: %d\n",
1877                                    ar->pktlog_filter, ret);
1878                        goto out;
1879                }
1880        } else {
1881                ret = ath10k_wmi_pdev_pktlog_disable(ar);
1882                if (ret) {
1883                        ath10k_warn(ar, "failed to disable pktlog: %d\n", ret);
1884                        goto out;
1885                }
1886        }
1887
1888        ar->pktlog_filter = filter;
1889        ret = count;
1890
1891out:
1892        mutex_unlock(&ar->conf_mutex);
1893        return ret;
1894}
1895
1896static ssize_t ath10k_read_pktlog_filter(struct file *file, char __user *ubuf,
1897                                         size_t count, loff_t *ppos)
1898{
1899        char buf[32];
1900        struct ath10k *ar = file->private_data;
1901        int len = 0;
1902
1903        mutex_lock(&ar->conf_mutex);
1904        len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
1905                        ar->pktlog_filter);
1906        mutex_unlock(&ar->conf_mutex);
1907
1908        return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1909}
1910
1911static const struct file_operations fops_pktlog_filter = {
1912        .read = ath10k_read_pktlog_filter,
1913        .write = ath10k_write_pktlog_filter,
1914        .open = simple_open
1915};
1916
1917static ssize_t ath10k_write_quiet_period(struct file *file,
1918                                         const char __user *ubuf,
1919                                         size_t count, loff_t *ppos)
1920{
1921        struct ath10k *ar = file->private_data;
1922        u32 period;
1923
1924        if (kstrtouint_from_user(ubuf, count, 0, &period))
1925                return -EINVAL;
1926
1927        if (period < ATH10K_QUIET_PERIOD_MIN) {
1928                ath10k_warn(ar, "Quiet period %u can not be lesser than 25ms\n",
1929                            period);
1930                return -EINVAL;
1931        }
1932        mutex_lock(&ar->conf_mutex);
1933        ar->thermal.quiet_period = period;
1934        ath10k_thermal_set_throttling(ar);
1935        mutex_unlock(&ar->conf_mutex);
1936
1937        return count;
1938}
1939
1940static ssize_t ath10k_read_quiet_period(struct file *file, char __user *ubuf,
1941                                        size_t count, loff_t *ppos)
1942{
1943        char buf[32];
1944        struct ath10k *ar = file->private_data;
1945        int len = 0;
1946
1947        mutex_lock(&ar->conf_mutex);
1948        len = scnprintf(buf, sizeof(buf) - len, "%d\n",
1949                        ar->thermal.quiet_period);
1950        mutex_unlock(&ar->conf_mutex);
1951
1952        return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1953}
1954
1955static const struct file_operations fops_quiet_period = {
1956        .read = ath10k_read_quiet_period,
1957        .write = ath10k_write_quiet_period,
1958        .open = simple_open
1959};
1960
1961static ssize_t ath10k_write_btcoex(struct file *file,
1962                                   const char __user *ubuf,
1963                                   size_t count, loff_t *ppos)
1964{
1965        struct ath10k *ar = file->private_data;
1966        char buf[32];
1967        size_t buf_size;
1968        int ret;
1969        bool val;
1970        u32 pdev_param;
1971
1972        buf_size = min(count, (sizeof(buf) - 1));
1973        if (copy_from_user(buf, ubuf, buf_size))
1974                return -EFAULT;
1975
1976        buf[buf_size] = '\0';
1977
1978        if (strtobool(buf, &val) != 0)
1979                return -EINVAL;
1980
1981        if (!ar->coex_support)
1982                return -EOPNOTSUPP;
1983
1984        mutex_lock(&ar->conf_mutex);
1985
1986        if (ar->state != ATH10K_STATE_ON &&
1987            ar->state != ATH10K_STATE_RESTARTED) {
1988                ret = -ENETDOWN;
1989                goto exit;
1990        }
1991
1992        if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val)) {
1993                ret = count;
1994                goto exit;
1995        }
1996
1997        pdev_param = ar->wmi.pdev_param->enable_btcoex;
1998        if (test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
1999                     ar->running_fw->fw_file.fw_features)) {
2000                ret = ath10k_wmi_pdev_set_param(ar, pdev_param, val);
2001                if (ret) {
2002                        ath10k_warn(ar, "failed to enable btcoex: %d\n", ret);
2003                        ret = count;
2004                        goto exit;
2005                }
2006        } else {
2007                ath10k_info(ar, "restarting firmware due to btcoex change");
2008                queue_work(ar->workqueue, &ar->restart_work);
2009        }
2010
2011        if (val)
2012                set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
2013        else
2014                clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
2015
2016        ret = count;
2017
2018exit:
2019        mutex_unlock(&ar->conf_mutex);
2020
2021        return ret;
2022}
2023
2024static ssize_t ath10k_read_btcoex(struct file *file, char __user *ubuf,
2025                                  size_t count, loff_t *ppos)
2026{
2027        char buf[32];
2028        struct ath10k *ar = file->private_data;
2029        int len = 0;
2030
2031        mutex_lock(&ar->conf_mutex);
2032        len = scnprintf(buf, sizeof(buf) - len, "%d\n",
2033                        test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags));
2034        mutex_unlock(&ar->conf_mutex);
2035
2036        return simple_read_from_buffer(ubuf, count, ppos, buf, len);
2037}
2038
2039static const struct file_operations fops_btcoex = {
2040        .read = ath10k_read_btcoex,
2041        .write = ath10k_write_btcoex,
2042        .open = simple_open
2043};
2044
2045static ssize_t ath10k_write_enable_extd_tx_stats(struct file *file,
2046                                                 const char __user *ubuf,
2047                                                 size_t count, loff_t *ppos)
2048{
2049        struct ath10k *ar = file->private_data;
2050        u32 filter;
2051        int ret;
2052
2053        if (kstrtouint_from_user(ubuf, count, 0, &filter))
2054                return -EINVAL;
2055
2056        mutex_lock(&ar->conf_mutex);
2057
2058        if (ar->state != ATH10K_STATE_ON) {
2059                ar->debug.enable_extd_tx_stats = filter;
2060                ret = count;
2061                goto out;
2062        }
2063
2064        if (filter == ar->debug.enable_extd_tx_stats) {
2065                ret = count;
2066                goto out;
2067        }
2068
2069        ar->debug.enable_extd_tx_stats = filter;
2070        ret = count;
2071
2072out:
2073        mutex_unlock(&ar->conf_mutex);
2074        return ret;
2075}
2076
2077static ssize_t ath10k_read_enable_extd_tx_stats(struct file *file,
2078                                                char __user *ubuf,
2079                                                size_t count, loff_t *ppos)
2080
2081{
2082        char buf[32];
2083        struct ath10k *ar = file->private_data;
2084        int len = 0;
2085
2086        mutex_lock(&ar->conf_mutex);
2087        len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
2088                        ar->debug.enable_extd_tx_stats);
2089        mutex_unlock(&ar->conf_mutex);
2090
2091        return simple_read_from_buffer(ubuf, count, ppos, buf, len);
2092}
2093
2094static const struct file_operations fops_enable_extd_tx_stats = {
2095        .read = ath10k_read_enable_extd_tx_stats,
2096        .write = ath10k_write_enable_extd_tx_stats,
2097        .open = simple_open
2098};
2099
2100static ssize_t ath10k_write_peer_stats(struct file *file,
2101                                       const char __user *ubuf,
2102                                       size_t count, loff_t *ppos)
2103{
2104        struct ath10k *ar = file->private_data;
2105        char buf[32];
2106        size_t buf_size;
2107        int ret;
2108        bool val;
2109
2110        buf_size = min(count, (sizeof(buf) - 1));
2111        if (copy_from_user(buf, ubuf, buf_size))
2112                return -EFAULT;
2113
2114        buf[buf_size] = '\0';
2115
2116        if (strtobool(buf, &val) != 0)
2117                return -EINVAL;
2118
2119        mutex_lock(&ar->conf_mutex);
2120
2121        if (ar->state != ATH10K_STATE_ON &&
2122            ar->state != ATH10K_STATE_RESTARTED) {
2123                ret = -ENETDOWN;
2124                goto exit;
2125        }
2126
2127        if (!(test_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags) ^ val)) {
2128                ret = count;
2129                goto exit;
2130        }
2131
2132        if (val)
2133                set_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
2134        else
2135                clear_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
2136
2137        ath10k_info(ar, "restarting firmware due to Peer stats change");
2138
2139        queue_work(ar->workqueue, &ar->restart_work);
2140        ret = count;
2141
2142exit:
2143        mutex_unlock(&ar->conf_mutex);
2144        return ret;
2145}
2146
2147static ssize_t ath10k_read_peer_stats(struct file *file, char __user *ubuf,
2148                                      size_t count, loff_t *ppos)
2149
2150{
2151        char buf[32];
2152        struct ath10k *ar = file->private_data;
2153        int len = 0;
2154
2155        mutex_lock(&ar->conf_mutex);
2156        len = scnprintf(buf, sizeof(buf) - len, "%d\n",
2157                        test_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags));
2158        mutex_unlock(&ar->conf_mutex);
2159
2160        return simple_read_from_buffer(ubuf, count, ppos, buf, len);
2161}
2162
2163static const struct file_operations fops_peer_stats = {
2164        .read = ath10k_read_peer_stats,
2165        .write = ath10k_write_peer_stats,
2166        .open = simple_open
2167};
2168
2169static ssize_t ath10k_debug_fw_checksums_read(struct file *file,
2170                                              char __user *user_buf,
2171                                              size_t count, loff_t *ppos)
2172{
2173        struct ath10k *ar = file->private_data;
2174        size_t len = 0, buf_len = 4096;
2175        ssize_t ret_cnt;
2176        char *buf;
2177
2178        buf = kzalloc(buf_len, GFP_KERNEL);
2179        if (!buf)
2180                return -ENOMEM;
2181
2182        mutex_lock(&ar->conf_mutex);
2183
2184        len += scnprintf(buf + len, buf_len - len,
2185                         "firmware-N.bin\t\t%08x\n",
2186                         crc32_le(0, ar->normal_mode_fw.fw_file.firmware->data,
2187                                  ar->normal_mode_fw.fw_file.firmware->size));
2188        len += scnprintf(buf + len, buf_len - len,
2189                         "athwlan\t\t\t%08x\n",
2190                         crc32_le(0, ar->normal_mode_fw.fw_file.firmware_data,
2191                                  ar->normal_mode_fw.fw_file.firmware_len));
2192        len += scnprintf(buf + len, buf_len - len,
2193                         "otp\t\t\t%08x\n",
2194                         crc32_le(0, ar->normal_mode_fw.fw_file.otp_data,
2195                                  ar->normal_mode_fw.fw_file.otp_len));
2196        len += scnprintf(buf + len, buf_len - len,
2197                         "codeswap\t\t%08x\n",
2198                         crc32_le(0, ar->normal_mode_fw.fw_file.codeswap_data,
2199                                  ar->normal_mode_fw.fw_file.codeswap_len));
2200        len += scnprintf(buf + len, buf_len - len,
2201                         "board-N.bin\t\t%08x\n",
2202                         crc32_le(0, ar->normal_mode_fw.board->data,
2203                                  ar->normal_mode_fw.board->size));
2204        len += scnprintf(buf + len, buf_len - len,
2205                         "board\t\t\t%08x\n",
2206                         crc32_le(0, ar->normal_mode_fw.board_data,
2207                                  ar->normal_mode_fw.board_len));
2208
2209        ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
2210
2211        mutex_unlock(&ar->conf_mutex);
2212
2213        kfree(buf);
2214        return ret_cnt;
2215}
2216
2217static const struct file_operations fops_fw_checksums = {
2218        .read = ath10k_debug_fw_checksums_read,
2219        .open = simple_open,
2220        .owner = THIS_MODULE,
2221        .llseek = default_llseek,
2222};
2223
2224static ssize_t ath10k_sta_tid_stats_mask_read(struct file *file,
2225                                              char __user *user_buf,
2226                                              size_t count, loff_t *ppos)
2227{
2228        struct ath10k *ar = file->private_data;
2229        char buf[32];
2230        size_t len;
2231
2232        len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->sta_tid_stats_mask);
2233        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2234}
2235
2236static ssize_t ath10k_sta_tid_stats_mask_write(struct file *file,
2237                                               const char __user *user_buf,
2238                                               size_t count, loff_t *ppos)
2239{
2240        struct ath10k *ar = file->private_data;
2241        char buf[32];
2242        ssize_t len;
2243        u32 mask;
2244
2245        len = min(count, sizeof(buf) - 1);
2246        if (copy_from_user(buf, user_buf, len))
2247                return -EFAULT;
2248
2249        buf[len] = '\0';
2250        if (kstrtoint(buf, 0, &mask))
2251                return -EINVAL;
2252
2253        ar->sta_tid_stats_mask = mask;
2254
2255        return len;
2256}
2257
2258static const struct file_operations fops_sta_tid_stats_mask = {
2259        .read = ath10k_sta_tid_stats_mask_read,
2260        .write = ath10k_sta_tid_stats_mask_write,
2261        .open = simple_open,
2262        .owner = THIS_MODULE,
2263        .llseek = default_llseek,
2264};
2265
2266static int ath10k_debug_tpc_stats_final_request(struct ath10k *ar)
2267{
2268        int ret;
2269        unsigned long time_left;
2270
2271        lockdep_assert_held(&ar->conf_mutex);
2272
2273        reinit_completion(&ar->debug.tpc_complete);
2274
2275        ret = ath10k_wmi_pdev_get_tpc_table_cmdid(ar, WMI_TPC_CONFIG_PARAM);
2276        if (ret) {
2277                ath10k_warn(ar, "failed to request tpc table cmdid: %d\n", ret);
2278                return ret;
2279        }
2280
2281        time_left = wait_for_completion_timeout(&ar->debug.tpc_complete,
2282                                                1 * HZ);
2283        if (time_left == 0)
2284                return -ETIMEDOUT;
2285
2286        return 0;
2287}
2288
2289static int ath10k_tpc_stats_final_open(struct inode *inode, struct file *file)
2290{
2291        struct ath10k *ar = inode->i_private;
2292        void *buf;
2293        int ret;
2294
2295        mutex_lock(&ar->conf_mutex);
2296
2297        if (ar->state != ATH10K_STATE_ON) {
2298                ret = -ENETDOWN;
2299                goto err_unlock;
2300        }
2301
2302        buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE);
2303        if (!buf) {
2304                ret = -ENOMEM;
2305                goto err_unlock;
2306        }
2307
2308        ret = ath10k_debug_tpc_stats_final_request(ar);
2309        if (ret) {
2310                ath10k_warn(ar, "failed to request tpc stats final: %d\n",
2311                            ret);
2312                goto err_free;
2313        }
2314
2315        ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
2316        file->private_data = buf;
2317
2318        mutex_unlock(&ar->conf_mutex);
2319        return 0;
2320
2321err_free:
2322        vfree(buf);
2323
2324err_unlock:
2325        mutex_unlock(&ar->conf_mutex);
2326        return ret;
2327}
2328
2329static int ath10k_tpc_stats_final_release(struct inode *inode,
2330                                          struct file *file)
2331{
2332        vfree(file->private_data);
2333
2334        return 0;
2335}
2336
2337static ssize_t ath10k_tpc_stats_final_read(struct file *file,
2338                                           char __user *user_buf,
2339                                           size_t count, loff_t *ppos)
2340{
2341        const char *buf = file->private_data;
2342        unsigned int len = strlen(buf);
2343
2344        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2345}
2346
2347static const struct file_operations fops_tpc_stats_final = {
2348        .open = ath10k_tpc_stats_final_open,
2349        .release = ath10k_tpc_stats_final_release,
2350        .read = ath10k_tpc_stats_final_read,
2351        .owner = THIS_MODULE,
2352        .llseek = default_llseek,
2353};
2354
2355static ssize_t ath10k_write_warm_hw_reset(struct file *file,
2356                                          const char __user *user_buf,
2357                                          size_t count, loff_t *ppos)
2358{
2359        struct ath10k *ar = file->private_data;
2360        int ret;
2361        bool val;
2362
2363        if (kstrtobool_from_user(user_buf, count, &val))
2364                return -EFAULT;
2365
2366        if (!val)
2367                return -EINVAL;
2368
2369        mutex_lock(&ar->conf_mutex);
2370
2371        if (ar->state != ATH10K_STATE_ON) {
2372                ret = -ENETDOWN;
2373                goto exit;
2374        }
2375
2376        ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pdev_reset,
2377                                        WMI_RST_MODE_WARM_RESET);
2378
2379        if (ret) {
2380                ath10k_warn(ar, "failed to enable warm hw reset: %d\n", ret);
2381                goto exit;
2382        }
2383
2384        ret = count;
2385
2386exit:
2387        mutex_unlock(&ar->conf_mutex);
2388        return ret;
2389}
2390
2391static const struct file_operations fops_warm_hw_reset = {
2392        .write = ath10k_write_warm_hw_reset,
2393        .open = simple_open,
2394        .owner = THIS_MODULE,
2395        .llseek = default_llseek,
2396};
2397
2398static void ath10k_peer_ps_state_disable(void *data,
2399                                         struct ieee80211_sta *sta)
2400{
2401        struct ath10k *ar = data;
2402        struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
2403
2404        spin_lock_bh(&ar->data_lock);
2405        arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
2406        spin_unlock_bh(&ar->data_lock);
2407}
2408
2409static ssize_t ath10k_write_ps_state_enable(struct file *file,
2410                                            const char __user *user_buf,
2411                                            size_t count, loff_t *ppos)
2412{
2413        struct ath10k *ar = file->private_data;
2414        int ret;
2415        u32 param;
2416        u8 ps_state_enable;
2417
2418        if (kstrtou8_from_user(user_buf, count, 0, &ps_state_enable))
2419                return -EINVAL;
2420
2421        if (ps_state_enable > 1)
2422                return -EINVAL;
2423
2424        mutex_lock(&ar->conf_mutex);
2425
2426        if (ar->ps_state_enable == ps_state_enable) {
2427                ret = count;
2428                goto exit;
2429        }
2430
2431        param = ar->wmi.pdev_param->peer_sta_ps_statechg_enable;
2432        ret = ath10k_wmi_pdev_set_param(ar, param, ps_state_enable);
2433        if (ret) {
2434                ath10k_warn(ar, "failed to enable ps_state_enable: %d\n",
2435                            ret);
2436                goto exit;
2437        }
2438        ar->ps_state_enable = ps_state_enable;
2439
2440        if (!ar->ps_state_enable)
2441                ieee80211_iterate_stations_atomic(ar->hw,
2442                                                  ath10k_peer_ps_state_disable,
2443                                                  ar);
2444
2445        ret = count;
2446
2447exit:
2448        mutex_unlock(&ar->conf_mutex);
2449
2450        return ret;
2451}
2452
2453static ssize_t ath10k_read_ps_state_enable(struct file *file,
2454                                           char __user *user_buf,
2455                                           size_t count, loff_t *ppos)
2456{
2457        struct ath10k *ar = file->private_data;
2458        int len = 0;
2459        char buf[32];
2460
2461        mutex_lock(&ar->conf_mutex);
2462        len = scnprintf(buf, sizeof(buf) - len, "%d\n",
2463                        ar->ps_state_enable);
2464        mutex_unlock(&ar->conf_mutex);
2465
2466        return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2467}
2468
2469static const struct file_operations fops_ps_state_enable = {
2470        .read = ath10k_read_ps_state_enable,
2471        .write = ath10k_write_ps_state_enable,
2472        .open = simple_open,
2473        .owner = THIS_MODULE,
2474        .llseek = default_llseek,
2475};
2476
2477static ssize_t ath10k_write_reset_htt_stats(struct file *file,
2478                                            const char __user *user_buf,
2479                                            size_t count, loff_t *ppos)
2480{
2481        struct ath10k *ar = file->private_data;
2482        unsigned long reset;
2483        int ret;
2484
2485        ret = kstrtoul_from_user(user_buf, count, 0, &reset);
2486        if (ret)
2487                return ret;
2488
2489        if (reset == 0 || reset > 0x1ffff)
2490                return -EINVAL;
2491
2492        mutex_lock(&ar->conf_mutex);
2493
2494        ar->debug.reset_htt_stats = reset;
2495
2496        ret = ath10k_debug_htt_stats_req(ar);
2497        if (ret)
2498                goto out;
2499
2500        ar->debug.reset_htt_stats = 0;
2501        ret = count;
2502
2503out:
2504        mutex_unlock(&ar->conf_mutex);
2505        return ret;
2506}
2507
2508static const struct file_operations fops_reset_htt_stats = {
2509        .write = ath10k_write_reset_htt_stats,
2510        .owner = THIS_MODULE,
2511        .open = simple_open,
2512        .llseek = default_llseek,
2513};
2514
2515int ath10k_debug_create(struct ath10k *ar)
2516{
2517        ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN);
2518        if (!ar->debug.cal_data)
2519                return -ENOMEM;
2520
2521        INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
2522        INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
2523        INIT_LIST_HEAD(&ar->debug.fw_stats.peers);
2524        INIT_LIST_HEAD(&ar->debug.fw_stats.peers_extd);
2525
2526        return 0;
2527}
2528
2529void ath10k_debug_destroy(struct ath10k *ar)
2530{
2531        vfree(ar->debug.cal_data);
2532        ar->debug.cal_data = NULL;
2533
2534        ath10k_debug_fw_stats_reset(ar);
2535
2536        kfree(ar->debug.tpc_stats);
2537        kfree(ar->debug.tpc_stats_final);
2538}
2539
2540int ath10k_debug_register(struct ath10k *ar)
2541{
2542        ar->debug.debugfs_phy = debugfs_create_dir("ath10k",
2543                                                   ar->hw->wiphy->debugfsdir);
2544        if (IS_ERR_OR_NULL(ar->debug.debugfs_phy)) {
2545                if (IS_ERR(ar->debug.debugfs_phy))
2546                        return PTR_ERR(ar->debug.debugfs_phy);
2547
2548                return -ENOMEM;
2549        }
2550
2551        INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork,
2552                          ath10k_debug_htt_stats_dwork);
2553
2554        init_completion(&ar->debug.tpc_complete);
2555        init_completion(&ar->debug.fw_stats_complete);
2556
2557        debugfs_create_file("fw_stats", 0400, ar->debug.debugfs_phy, ar,
2558                            &fops_fw_stats);
2559
2560        debugfs_create_file("fw_reset_stats", 0400, ar->debug.debugfs_phy, ar,
2561                            &fops_fw_reset_stats);
2562
2563        debugfs_create_file("wmi_services", 0400, ar->debug.debugfs_phy, ar,
2564                            &fops_wmi_services);
2565
2566        debugfs_create_file("simulate_fw_crash", 0600, ar->debug.debugfs_phy, ar,
2567                            &fops_simulate_fw_crash);
2568
2569        debugfs_create_file("reg_addr", 0600, ar->debug.debugfs_phy, ar,
2570                            &fops_reg_addr);
2571
2572        debugfs_create_file("reg_value", 0600, ar->debug.debugfs_phy, ar,
2573                            &fops_reg_value);
2574
2575        debugfs_create_file("mem_value", 0600, ar->debug.debugfs_phy, ar,
2576                            &fops_mem_value);
2577
2578        debugfs_create_file("chip_id", 0400, ar->debug.debugfs_phy, ar,
2579                            &fops_chip_id);
2580
2581        debugfs_create_file("htt_stats_mask", 0600, ar->debug.debugfs_phy, ar,
2582                            &fops_htt_stats_mask);
2583
2584        debugfs_create_file("htt_max_amsdu_ampdu", 0600, ar->debug.debugfs_phy, ar,
2585                            &fops_htt_max_amsdu_ampdu);
2586
2587        debugfs_create_file("fw_dbglog", 0600, ar->debug.debugfs_phy, ar,
2588                            &fops_fw_dbglog);
2589
2590        if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
2591                      ar->normal_mode_fw.fw_file.fw_features)) {
2592                debugfs_create_file("cal_data", 0400, ar->debug.debugfs_phy, ar,
2593                                    &fops_cal_data);
2594
2595                debugfs_create_file("nf_cal_period", 0600, ar->debug.debugfs_phy, ar,
2596                                    &fops_nf_cal_period);
2597        }
2598
2599        debugfs_create_file("ani_enable", 0600, ar->debug.debugfs_phy, ar,
2600                            &fops_ani_enable);
2601
2602        if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) {
2603                debugfs_create_file("dfs_simulate_radar", 0200, ar->debug.debugfs_phy,
2604                                    ar, &fops_simulate_radar);
2605
2606                debugfs_create_bool("dfs_block_radar_events", 0200,
2607                                    ar->debug.debugfs_phy,
2608                                    &ar->dfs_block_radar_events);
2609
2610                debugfs_create_file("dfs_stats", 0400, ar->debug.debugfs_phy, ar,
2611                                    &fops_dfs_stats);
2612        }
2613
2614        debugfs_create_file("pktlog_filter", 0644, ar->debug.debugfs_phy, ar,
2615                            &fops_pktlog_filter);
2616
2617        if (test_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map))
2618                debugfs_create_file("quiet_period", 0644, ar->debug.debugfs_phy, ar,
2619                                    &fops_quiet_period);
2620
2621        debugfs_create_file("tpc_stats", 0400, ar->debug.debugfs_phy, ar,
2622                            &fops_tpc_stats);
2623
2624        if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
2625                debugfs_create_file("btcoex", 0644, ar->debug.debugfs_phy, ar,
2626                                    &fops_btcoex);
2627
2628        if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map)) {
2629                debugfs_create_file("peer_stats", 0644, ar->debug.debugfs_phy, ar,
2630                                    &fops_peer_stats);
2631
2632                debugfs_create_file("enable_extd_tx_stats", 0644,
2633                                    ar->debug.debugfs_phy, ar,
2634                                    &fops_enable_extd_tx_stats);
2635        }
2636
2637        debugfs_create_file("fw_checksums", 0400, ar->debug.debugfs_phy, ar,
2638                            &fops_fw_checksums);
2639
2640        if (IS_ENABLED(CONFIG_MAC80211_DEBUGFS))
2641                debugfs_create_file("sta_tid_stats_mask", 0600,
2642                                    ar->debug.debugfs_phy,
2643                                    ar, &fops_sta_tid_stats_mask);
2644
2645        if (test_bit(WMI_SERVICE_TPC_STATS_FINAL, ar->wmi.svc_map))
2646                debugfs_create_file("tpc_stats_final", 0400,
2647                                    ar->debug.debugfs_phy, ar,
2648                                    &fops_tpc_stats_final);
2649
2650        if (test_bit(WMI_SERVICE_RESET_CHIP, ar->wmi.svc_map))
2651                debugfs_create_file("warm_hw_reset", 0600,
2652                                    ar->debug.debugfs_phy, ar,
2653                                    &fops_warm_hw_reset);
2654
2655        debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_phy, ar,
2656                            &fops_ps_state_enable);
2657
2658        debugfs_create_file("reset_htt_stats", 0200, ar->debug.debugfs_phy, ar,
2659                            &fops_reset_htt_stats);
2660
2661        return 0;
2662}
2663
2664void ath10k_debug_unregister(struct ath10k *ar)
2665{
2666        cancel_delayed_work_sync(&ar->debug.htt_stats_dwork);
2667}
2668
2669#endif /* CONFIG_ATH10K_DEBUGFS */
2670
2671#ifdef CONFIG_ATH10K_DEBUG
2672void __ath10k_dbg(struct ath10k *ar, enum ath10k_debug_mask mask,
2673                  const char *fmt, ...)
2674{
2675        struct va_format vaf;
2676        va_list args;
2677
2678        va_start(args, fmt);
2679
2680        vaf.fmt = fmt;
2681        vaf.va = &args;
2682
2683        if (ath10k_debug_mask & mask)
2684                dev_printk(KERN_DEBUG, ar->dev, "%pV", &vaf);
2685
2686        trace_ath10k_log_dbg(ar, mask, &vaf);
2687
2688        va_end(args);
2689}
2690EXPORT_SYMBOL(__ath10k_dbg);
2691
2692void ath10k_dbg_dump(struct ath10k *ar,
2693                     enum ath10k_debug_mask mask,
2694                     const char *msg, const char *prefix,
2695                     const void *buf, size_t len)
2696{
2697        char linebuf[256];
2698        size_t linebuflen;
2699        const void *ptr;
2700
2701        if (ath10k_debug_mask & mask) {
2702                if (msg)
2703                        __ath10k_dbg(ar, mask, "%s\n", msg);
2704
2705                for (ptr = buf; (ptr - buf) < len; ptr += 16) {
2706                        linebuflen = 0;
2707                        linebuflen += scnprintf(linebuf + linebuflen,
2708                                                sizeof(linebuf) - linebuflen,
2709                                                "%s%08x: ",
2710                                                (prefix ? prefix : ""),
2711                                                (unsigned int)(ptr - buf));
2712                        hex_dump_to_buffer(ptr, len - (ptr - buf), 16, 1,
2713                                           linebuf + linebuflen,
2714                                           sizeof(linebuf) - linebuflen, true);
2715                        dev_printk(KERN_DEBUG, ar->dev, "%s\n", linebuf);
2716                }
2717        }
2718
2719        /* tracing code doesn't like null strings :/ */
2720        trace_ath10k_log_dbg_dump(ar, msg ? msg : "", prefix ? prefix : "",
2721                                  buf, len);
2722}
2723EXPORT_SYMBOL(ath10k_dbg_dump);
2724
2725#endif /* CONFIG_ATH10K_DEBUG */
2726