.. | .. |
---|
| 1 | +// SPDX-License-Identifier: ISC |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2005-2011 Atheros Communications Inc. |
---|
3 | 4 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. |
---|
4 | 5 | * Copyright (c) 2018, The Linux Foundation. All rights reserved. |
---|
5 | | - * |
---|
6 | | - * Permission to use, copy, modify, and/or distribute this software for any |
---|
7 | | - * purpose with or without fee is hereby granted, provided that the above |
---|
8 | | - * copyright notice and this permission notice appear in all copies. |
---|
9 | | - * |
---|
10 | | - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
---|
11 | | - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
---|
12 | | - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
---|
13 | | - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
---|
14 | | - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
---|
15 | | - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
---|
16 | | - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
---|
17 | 6 | */ |
---|
18 | 7 | |
---|
19 | 8 | #include <linux/module.h> |
---|
.. | .. |
---|
58 | 47 | ath10k_info(ar, "%s target 0x%08x chip_id 0x%08x sub %04x:%04x", |
---|
59 | 48 | ar->hw_params.name, |
---|
60 | 49 | ar->target_version, |
---|
61 | | - ar->chip_id, |
---|
| 50 | + ar->bus_param.chip_id, |
---|
62 | 51 | ar->id.subsystem_vendor, ar->id.subsystem_device); |
---|
63 | 52 | |
---|
64 | 53 | ath10k_info(ar, "kconfig debug %d debugfs %d tracing %d dfs %d testmode %d\n", |
---|
.. | .. |
---|
316 | 305 | if (is_end) |
---|
317 | 306 | ar->debug.fw_stats_done = true; |
---|
318 | 307 | |
---|
| 308 | + if (stats.extended) |
---|
| 309 | + ar->debug.fw_stats.extended = true; |
---|
| 310 | + |
---|
319 | 311 | is_started = !list_empty(&ar->debug.fw_stats.pdevs); |
---|
320 | 312 | |
---|
321 | 313 | if (is_started && !is_end) { |
---|
.. | .. |
---|
357 | 349 | spin_unlock_bh(&ar->data_lock); |
---|
358 | 350 | } |
---|
359 | 351 | |
---|
360 | | -static int ath10k_debug_fw_stats_request(struct ath10k *ar) |
---|
| 352 | +int ath10k_debug_fw_stats_request(struct ath10k *ar) |
---|
361 | 353 | { |
---|
362 | 354 | unsigned long timeout, time_left; |
---|
363 | 355 | int ret; |
---|
.. | .. |
---|
625 | 617 | size_t len; |
---|
626 | 618 | char buf[50]; |
---|
627 | 619 | |
---|
628 | | - len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->chip_id); |
---|
| 620 | + len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->bus_param.chip_id); |
---|
629 | 621 | |
---|
630 | 622 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); |
---|
631 | 623 | } |
---|
.. | .. |
---|
786 | 778 | |
---|
787 | 779 | ret = ath10k_hif_diag_read(ar, *ppos, buf, count); |
---|
788 | 780 | if (ret) { |
---|
789 | | - ath10k_warn(ar, "failed to read address 0x%08x via diagnose window fnrom debugfs: %d\n", |
---|
| 781 | + ath10k_warn(ar, "failed to read address 0x%08x via diagnose window from debugfs: %d\n", |
---|
790 | 782 | (u32)(*ppos), ret); |
---|
791 | 783 | goto exit; |
---|
792 | 784 | } |
---|
.. | .. |
---|
884 | 876 | cookie = get_jiffies_64(); |
---|
885 | 877 | |
---|
886 | 878 | ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask, |
---|
887 | | - cookie); |
---|
| 879 | + ar->debug.reset_htt_stats, cookie); |
---|
888 | 880 | if (ret) { |
---|
889 | 881 | ath10k_warn(ar, "failed to send htt stats request: %d\n", ret); |
---|
890 | 882 | return ret; |
---|
.. | .. |
---|
933 | 925 | if (ret) |
---|
934 | 926 | return ret; |
---|
935 | 927 | |
---|
936 | | - /* max 8 bit masks (for now) */ |
---|
937 | | - if (mask > 0xff) |
---|
| 928 | + /* max 17 bit masks (for now) */ |
---|
| 929 | + if (mask > HTT_STATS_BIT_MASK) |
---|
938 | 930 | return -E2BIG; |
---|
939 | 931 | |
---|
940 | 932 | mutex_lock(&ar->conf_mutex); |
---|
.. | .. |
---|
1102 | 1094 | "d_rts_good", |
---|
1103 | 1095 | "d_tx_power", /* in .5 dbM I think */ |
---|
1104 | 1096 | "d_rx_crc_err", /* fcs_bad */ |
---|
| 1097 | + "d_rx_crc_err_drop", /* frame with FCS error, dropped late in kernel */ |
---|
1105 | 1098 | "d_no_beacon", |
---|
1106 | 1099 | "d_tx_mpdus_queued", |
---|
1107 | 1100 | "d_tx_msdu_queued", |
---|
.. | .. |
---|
1201 | 1194 | data[i++] = pdev_stats->rts_good; |
---|
1202 | 1195 | data[i++] = pdev_stats->chan_tx_power; |
---|
1203 | 1196 | data[i++] = pdev_stats->fcs_bad; |
---|
| 1197 | + data[i++] = ar->stats.rx_crc_err_drop; |
---|
1204 | 1198 | data[i++] = pdev_stats->no_beacons; |
---|
1205 | 1199 | data[i++] = pdev_stats->mpdu_enqued; |
---|
1206 | 1200 | data[i++] = pdev_stats->msdu_enqued; |
---|
.. | .. |
---|
1262 | 1256 | |
---|
1263 | 1257 | if (WARN_ON(ar->hw_params.cal_data_len > ATH10K_DEBUG_CAL_DATA_LEN)) |
---|
1264 | 1258 | return -EINVAL; |
---|
| 1259 | + |
---|
| 1260 | + if (ar->hw_params.cal_data_len == 0) |
---|
| 1261 | + return -EOPNOTSUPP; |
---|
1265 | 1262 | |
---|
1266 | 1263 | hi_addr = host_interest_item_address(HI_ITEM(hi_board_data)); |
---|
1267 | 1264 | |
---|
.. | .. |
---|
1981 | 1978 | if (strtobool(buf, &val) != 0) |
---|
1982 | 1979 | return -EINVAL; |
---|
1983 | 1980 | |
---|
| 1981 | + if (!ar->coex_support) |
---|
| 1982 | + return -EOPNOTSUPP; |
---|
| 1983 | + |
---|
1984 | 1984 | mutex_lock(&ar->conf_mutex); |
---|
1985 | 1985 | |
---|
1986 | 1986 | if (ar->state != ATH10K_STATE_ON && |
---|
.. | .. |
---|
2039 | 2039 | static const struct file_operations fops_btcoex = { |
---|
2040 | 2040 | .read = ath10k_read_btcoex, |
---|
2041 | 2041 | .write = ath10k_write_btcoex, |
---|
| 2042 | + .open = simple_open |
---|
| 2043 | +}; |
---|
| 2044 | + |
---|
| 2045 | +static 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 | + |
---|
| 2072 | +out: |
---|
| 2073 | + mutex_unlock(&ar->conf_mutex); |
---|
| 2074 | + return ret; |
---|
| 2075 | +} |
---|
| 2076 | + |
---|
| 2077 | +static 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 | + |
---|
| 2094 | +static 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, |
---|
2042 | 2097 | .open = simple_open |
---|
2043 | 2098 | }; |
---|
2044 | 2099 | |
---|
.. | .. |
---|
2318 | 2373 | goto exit; |
---|
2319 | 2374 | } |
---|
2320 | 2375 | |
---|
2321 | | - if (!(test_bit(WMI_SERVICE_RESET_CHIP, ar->wmi.svc_map))) |
---|
2322 | | - ath10k_warn(ar, "wmi service for reset chip is not available\n"); |
---|
2323 | | - |
---|
2324 | 2376 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pdev_reset, |
---|
2325 | 2377 | WMI_RST_MODE_WARM_RESET); |
---|
2326 | 2378 | |
---|
.. | .. |
---|
2340 | 2392 | .write = ath10k_write_warm_hw_reset, |
---|
2341 | 2393 | .open = simple_open, |
---|
2342 | 2394 | .owner = THIS_MODULE, |
---|
| 2395 | + .llseek = default_llseek, |
---|
| 2396 | +}; |
---|
| 2397 | + |
---|
| 2398 | +static 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 | + |
---|
| 2409 | +static 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 | + |
---|
| 2447 | +exit: |
---|
| 2448 | + mutex_unlock(&ar->conf_mutex); |
---|
| 2449 | + |
---|
| 2450 | + return ret; |
---|
| 2451 | +} |
---|
| 2452 | + |
---|
| 2453 | +static 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 | + |
---|
| 2469 | +static 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 | + |
---|
| 2477 | +static 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 | + |
---|
| 2503 | +out: |
---|
| 2504 | + mutex_unlock(&ar->conf_mutex); |
---|
| 2505 | + return ret; |
---|
| 2506 | +} |
---|
| 2507 | + |
---|
| 2508 | +static const struct file_operations fops_reset_htt_stats = { |
---|
| 2509 | + .write = ath10k_write_reset_htt_stats, |
---|
| 2510 | + .owner = THIS_MODULE, |
---|
| 2511 | + .open = simple_open, |
---|
2343 | 2512 | .llseek = default_llseek, |
---|
2344 | 2513 | }; |
---|
2345 | 2514 | |
---|
.. | .. |
---|
2445 | 2614 | debugfs_create_file("pktlog_filter", 0644, ar->debug.debugfs_phy, ar, |
---|
2446 | 2615 | &fops_pktlog_filter); |
---|
2447 | 2616 | |
---|
2448 | | - debugfs_create_file("quiet_period", 0644, ar->debug.debugfs_phy, ar, |
---|
2449 | | - &fops_quiet_period); |
---|
| 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); |
---|
2450 | 2620 | |
---|
2451 | 2621 | debugfs_create_file("tpc_stats", 0400, ar->debug.debugfs_phy, ar, |
---|
2452 | 2622 | &fops_tpc_stats); |
---|
.. | .. |
---|
2455 | 2625 | debugfs_create_file("btcoex", 0644, ar->debug.debugfs_phy, ar, |
---|
2456 | 2626 | &fops_btcoex); |
---|
2457 | 2627 | |
---|
2458 | | - if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map)) |
---|
| 2628 | + if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map)) { |
---|
2459 | 2629 | debugfs_create_file("peer_stats", 0644, ar->debug.debugfs_phy, ar, |
---|
2460 | 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 | + } |
---|
2461 | 2636 | |
---|
2462 | 2637 | debugfs_create_file("fw_checksums", 0400, ar->debug.debugfs_phy, ar, |
---|
2463 | 2638 | &fops_fw_checksums); |
---|
.. | .. |
---|
2472 | 2647 | ar->debug.debugfs_phy, ar, |
---|
2473 | 2648 | &fops_tpc_stats_final); |
---|
2474 | 2649 | |
---|
2475 | | - debugfs_create_file("warm_hw_reset", 0600, ar->debug.debugfs_phy, ar, |
---|
2476 | | - &fops_warm_hw_reset); |
---|
| 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); |
---|
2477 | 2660 | |
---|
2478 | 2661 | return 0; |
---|
2479 | 2662 | } |
---|
.. | .. |
---|
2486 | 2669 | #endif /* CONFIG_ATH10K_DEBUGFS */ |
---|
2487 | 2670 | |
---|
2488 | 2671 | #ifdef CONFIG_ATH10K_DEBUG |
---|
2489 | | -void ath10k_dbg(struct ath10k *ar, enum ath10k_debug_mask mask, |
---|
2490 | | - const char *fmt, ...) |
---|
| 2672 | +void __ath10k_dbg(struct ath10k *ar, enum ath10k_debug_mask mask, |
---|
| 2673 | + const char *fmt, ...) |
---|
2491 | 2674 | { |
---|
2492 | 2675 | struct va_format vaf; |
---|
2493 | 2676 | va_list args; |
---|
.. | .. |
---|
2504 | 2687 | |
---|
2505 | 2688 | va_end(args); |
---|
2506 | 2689 | } |
---|
2507 | | -EXPORT_SYMBOL(ath10k_dbg); |
---|
| 2690 | +EXPORT_SYMBOL(__ath10k_dbg); |
---|
2508 | 2691 | |
---|
2509 | 2692 | void ath10k_dbg_dump(struct ath10k *ar, |
---|
2510 | 2693 | enum ath10k_debug_mask mask, |
---|
.. | .. |
---|
2517 | 2700 | |
---|
2518 | 2701 | if (ath10k_debug_mask & mask) { |
---|
2519 | 2702 | if (msg) |
---|
2520 | | - ath10k_dbg(ar, mask, "%s\n", msg); |
---|
| 2703 | + __ath10k_dbg(ar, mask, "%s\n", msg); |
---|
2521 | 2704 | |
---|
2522 | 2705 | for (ptr = buf; (ptr - buf) < len; ptr += 16) { |
---|
2523 | 2706 | linebuflen = 0; |
---|