debugfs.c (0b8532102293b1abb70385232e88ea75d098c808) debugfs.c (0c936b3c96337c3fd5ad4951ca7bdc54fa578a02)
1/*
2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *

--- 1908 unchanged lines hidden (view full) ---

1917static const struct file_operations fops_tx_latency = {
1918 .open = wil_tx_latency_seq_open,
1919 .release = single_release,
1920 .read = seq_read,
1921 .write = wil_tx_latency_write,
1922 .llseek = seq_lseek,
1923};
1924
1/*
2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *

--- 1908 unchanged lines hidden (view full) ---

1917static const struct file_operations fops_tx_latency = {
1918 .open = wil_tx_latency_seq_open,
1919 .release = single_release,
1920 .read = seq_read,
1921 .write = wil_tx_latency_write,
1922 .llseek = seq_lseek,
1923};
1924
1925static void wil_link_stats_print_basic(struct wil6210_vif *vif,
1926 struct seq_file *s,
1927 struct wmi_link_stats_basic *basic)
1928{
1929 char per[5] = "?";
1930
1931 if (basic->per_average != 0xff)
1932 snprintf(per, sizeof(per), "%d%%", basic->per_average);
1933
1934 seq_printf(s, "CID %d {\n"
1935 "\tTxMCS %d TxTpt %d\n"
1936 "\tGoodput(rx:tx) %d:%d\n"
1937 "\tRxBcastFrames %d\n"
1938 "\tRSSI %d SQI %d SNR %d PER %s\n"
1939 "\tRx RFC %d Ant num %d\n"
1940 "\tSectors(rx:tx) my %d:%d peer %d:%d\n"
1941 "}\n",
1942 basic->cid,
1943 basic->bf_mcs, le32_to_cpu(basic->tx_tpt),
1944 le32_to_cpu(basic->rx_goodput),
1945 le32_to_cpu(basic->tx_goodput),
1946 le32_to_cpu(basic->rx_bcast_frames),
1947 basic->rssi, basic->sqi, basic->snr, per,
1948 basic->selected_rfc, basic->rx_effective_ant_num,
1949 basic->my_rx_sector, basic->my_tx_sector,
1950 basic->other_rx_sector, basic->other_tx_sector);
1951}
1952
1953static void wil_link_stats_print_global(struct wil6210_priv *wil,
1954 struct seq_file *s,
1955 struct wmi_link_stats_global *global)
1956{
1957 seq_printf(s, "Frames(rx:tx) %d:%d\n"
1958 "BA Frames(rx:tx) %d:%d\n"
1959 "Beacons %d\n"
1960 "Rx Errors (MIC:CRC) %d:%d\n"
1961 "Tx Errors (no ack) %d\n",
1962 le32_to_cpu(global->rx_frames),
1963 le32_to_cpu(global->tx_frames),
1964 le32_to_cpu(global->rx_ba_frames),
1965 le32_to_cpu(global->tx_ba_frames),
1966 le32_to_cpu(global->tx_beacons),
1967 le32_to_cpu(global->rx_mic_errors),
1968 le32_to_cpu(global->rx_crc_errors),
1969 le32_to_cpu(global->tx_fail_no_ack));
1970}
1971
1972static void wil_link_stats_debugfs_show_vif(struct wil6210_vif *vif,
1973 struct seq_file *s)
1974{
1975 struct wil6210_priv *wil = vif_to_wil(vif);
1976 struct wmi_link_stats_basic *stats;
1977 int i;
1978
1979 if (!vif->fw_stats_ready) {
1980 seq_puts(s, "no statistics\n");
1981 return;
1982 }
1983
1984 seq_printf(s, "TSF %lld\n", vif->fw_stats_tsf);
1985 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
1986 if (wil->sta[i].status == wil_sta_unused)
1987 continue;
1988 if (wil->sta[i].mid != vif->mid)
1989 continue;
1990
1991 stats = &wil->sta[i].fw_stats_basic;
1992 wil_link_stats_print_basic(vif, s, stats);
1993 }
1994}
1995
1996static int wil_link_stats_debugfs_show(struct seq_file *s, void *data)
1997{
1998 struct wil6210_priv *wil = s->private;
1999 struct wil6210_vif *vif;
2000 int i, rc;
2001
2002 rc = mutex_lock_interruptible(&wil->vif_mutex);
2003 if (rc)
2004 return rc;
2005
2006 /* iterate over all MIDs and show per-cid statistics. Then show the
2007 * global statistics
2008 */
2009 for (i = 0; i < wil->max_vifs; i++) {
2010 vif = wil->vifs[i];
2011
2012 seq_printf(s, "MID %d ", i);
2013 if (!vif) {
2014 seq_puts(s, "unused\n");
2015 continue;
2016 }
2017
2018 wil_link_stats_debugfs_show_vif(vif, s);
2019 }
2020
2021 mutex_unlock(&wil->vif_mutex);
2022
2023 return 0;
2024}
2025
2026static int wil_link_stats_seq_open(struct inode *inode, struct file *file)
2027{
2028 return single_open(file, wil_link_stats_debugfs_show, inode->i_private);
2029}
2030
2031static ssize_t wil_link_stats_write(struct file *file, const char __user *buf,
2032 size_t len, loff_t *ppos)
2033{
2034 struct seq_file *s = file->private_data;
2035 struct wil6210_priv *wil = s->private;
2036 int cid, interval, rc, i;
2037 struct wil6210_vif *vif;
2038 char *kbuf = kmalloc(len + 1, GFP_KERNEL);
2039
2040 if (!kbuf)
2041 return -ENOMEM;
2042
2043 rc = simple_write_to_buffer(kbuf, len, ppos, buf, len);
2044 if (rc != len) {
2045 kfree(kbuf);
2046 return rc >= 0 ? -EIO : rc;
2047 }
2048
2049 kbuf[len] = '\0';
2050 /* specify cid (use -1 for all cids) and snapshot interval in ms */
2051 rc = sscanf(kbuf, "%d %d", &cid, &interval);
2052 kfree(kbuf);
2053 if (rc < 0)
2054 return rc;
2055 if (rc < 2 || interval < 0)
2056 return -EINVAL;
2057
2058 wil_info(wil, "request link statistics, cid %d interval %d\n",
2059 cid, interval);
2060
2061 rc = mutex_lock_interruptible(&wil->vif_mutex);
2062 if (rc)
2063 return rc;
2064
2065 for (i = 0; i < wil->max_vifs; i++) {
2066 vif = wil->vifs[i];
2067 if (!vif)
2068 continue;
2069
2070 rc = wmi_link_stats_cfg(vif, WMI_LINK_STATS_TYPE_BASIC,
2071 (cid == -1 ? 0xff : cid), interval);
2072 if (rc)
2073 wil_err(wil, "link statistics failed for mid %d\n", i);
2074 }
2075 mutex_unlock(&wil->vif_mutex);
2076
2077 return len;
2078}
2079
2080static const struct file_operations fops_link_stats = {
2081 .open = wil_link_stats_seq_open,
2082 .release = single_release,
2083 .read = seq_read,
2084 .write = wil_link_stats_write,
2085 .llseek = seq_lseek,
2086};
2087
2088static int
2089wil_link_stats_global_debugfs_show(struct seq_file *s, void *data)
2090{
2091 struct wil6210_priv *wil = s->private;
2092
2093 if (!wil->fw_stats_global.ready)
2094 return 0;
2095
2096 seq_printf(s, "TSF %lld\n", wil->fw_stats_global.tsf);
2097 wil_link_stats_print_global(wil, s, &wil->fw_stats_global.stats);
2098
2099 return 0;
2100}
2101
2102static int
2103wil_link_stats_global_seq_open(struct inode *inode, struct file *file)
2104{
2105 return single_open(file, wil_link_stats_global_debugfs_show,
2106 inode->i_private);
2107}
2108
2109static ssize_t
2110wil_link_stats_global_write(struct file *file, const char __user *buf,
2111 size_t len, loff_t *ppos)
2112{
2113 struct seq_file *s = file->private_data;
2114 struct wil6210_priv *wil = s->private;
2115 int interval, rc;
2116 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
2117
2118 /* specify snapshot interval in ms */
2119 rc = kstrtoint_from_user(buf, len, 0, &interval);
2120 if (rc || interval < 0) {
2121 wil_err(wil, "Invalid argument\n");
2122 return -EINVAL;
2123 }
2124
2125 wil_info(wil, "request global link stats, interval %d\n", interval);
2126
2127 rc = wmi_link_stats_cfg(vif, WMI_LINK_STATS_TYPE_GLOBAL, 0, interval);
2128 if (rc)
2129 wil_err(wil, "global link stats failed %d\n", rc);
2130
2131 return rc ? rc : len;
2132}
2133
2134static const struct file_operations fops_link_stats_global = {
2135 .open = wil_link_stats_global_seq_open,
2136 .release = single_release,
2137 .read = seq_read,
2138 .write = wil_link_stats_global_write,
2139 .llseek = seq_lseek,
2140};
2141
1925static ssize_t wil_read_file_led_cfg(struct file *file, char __user *user_buf,
1926 size_t count, loff_t *ppos)
1927{
1928 char buf[80];
1929 int n;
1930
1931 n = snprintf(buf, sizeof(buf),
1932 "led_id is set to %d, echo 1 to enable, 0 to disable\n",

--- 318 unchanged lines hidden (view full) ---

2251 {"fw_capabilities", 0444, &fops_fw_capabilities},
2252 {"fw_version", 0444, &fops_fw_version},
2253 {"suspend_stats", 0644, &fops_suspend_stats},
2254 {"compressed_rx_status", 0644, &fops_compressed_rx_status},
2255 {"srings", 0444, &fops_srings},
2256 {"status_msg", 0444, &fops_status_msg},
2257 {"rx_buff_mgmt", 0444, &fops_rx_buff_mgmt},
2258 {"tx_latency", 0644, &fops_tx_latency},
2142static ssize_t wil_read_file_led_cfg(struct file *file, char __user *user_buf,
2143 size_t count, loff_t *ppos)
2144{
2145 char buf[80];
2146 int n;
2147
2148 n = snprintf(buf, sizeof(buf),
2149 "led_id is set to %d, echo 1 to enable, 0 to disable\n",

--- 318 unchanged lines hidden (view full) ---

2468 {"fw_capabilities", 0444, &fops_fw_capabilities},
2469 {"fw_version", 0444, &fops_fw_version},
2470 {"suspend_stats", 0644, &fops_suspend_stats},
2471 {"compressed_rx_status", 0644, &fops_compressed_rx_status},
2472 {"srings", 0444, &fops_srings},
2473 {"status_msg", 0444, &fops_status_msg},
2474 {"rx_buff_mgmt", 0444, &fops_rx_buff_mgmt},
2475 {"tx_latency", 0644, &fops_tx_latency},
2476 {"link_stats", 0644, &fops_link_stats},
2477 {"link_stats_global", 0644, &fops_link_stats_global},
2259};
2260
2261static void wil6210_debugfs_init_files(struct wil6210_priv *wil,
2262 struct dentry *dbg)
2263{
2264 int i;
2265
2266 for (i = 0; i < ARRAY_SIZE(dbg_files); i++)

--- 122 unchanged lines hidden ---
2478};
2479
2480static void wil6210_debugfs_init_files(struct wil6210_priv *wil,
2481 struct dentry *dbg)
2482{
2483 int i;
2484
2485 for (i = 0; i < ARRAY_SIZE(dbg_files); i++)

--- 122 unchanged lines hidden ---