cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

htc_drv_debug.c (14976B)


      1/*
      2 * Copyright (c) 2010-2011 Atheros Communications Inc.
      3 *
      4 * Permission to use, copy, modify, and/or distribute this software for any
      5 * purpose with or without fee is hereby granted, provided that the above
      6 * copyright notice and this permission notice appear in all copies.
      7 *
      8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15 */
     16
     17#include "htc.h"
     18
     19static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf,
     20				       size_t count, loff_t *ppos)
     21{
     22	struct ath9k_htc_priv *priv = file->private_data;
     23	struct ath9k_htc_target_int_stats cmd_rsp;
     24	char buf[512];
     25	unsigned int len = 0;
     26	int ret = 0;
     27
     28	memset(&cmd_rsp, 0, sizeof(cmd_rsp));
     29
     30	ath9k_htc_ps_wakeup(priv);
     31
     32	WMI_CMD(WMI_INT_STATS_CMDID);
     33	if (ret) {
     34		ath9k_htc_ps_restore(priv);
     35		return -EINVAL;
     36	}
     37
     38	ath9k_htc_ps_restore(priv);
     39
     40	len += scnprintf(buf + len, sizeof(buf) - len,
     41			 "%20s : %10u\n", "RX",
     42			 be32_to_cpu(cmd_rsp.rx));
     43
     44	len += scnprintf(buf + len, sizeof(buf) - len,
     45			 "%20s : %10u\n", "RXORN",
     46			 be32_to_cpu(cmd_rsp.rxorn));
     47
     48	len += scnprintf(buf + len, sizeof(buf) - len,
     49			 "%20s : %10u\n", "RXEOL",
     50			 be32_to_cpu(cmd_rsp.rxeol));
     51
     52	len += scnprintf(buf + len, sizeof(buf) - len,
     53			 "%20s : %10u\n", "TXURN",
     54			 be32_to_cpu(cmd_rsp.txurn));
     55
     56	len += scnprintf(buf + len, sizeof(buf) - len,
     57			 "%20s : %10u\n", "TXTO",
     58			 be32_to_cpu(cmd_rsp.txto));
     59
     60	len += scnprintf(buf + len, sizeof(buf) - len,
     61			 "%20s : %10u\n", "CST",
     62			 be32_to_cpu(cmd_rsp.cst));
     63
     64	if (len > sizeof(buf))
     65		len = sizeof(buf);
     66
     67	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
     68}
     69
     70static const struct file_operations fops_tgt_int_stats = {
     71	.read = read_file_tgt_int_stats,
     72	.open = simple_open,
     73	.owner = THIS_MODULE,
     74	.llseek = default_llseek,
     75};
     76
     77static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf,
     78				      size_t count, loff_t *ppos)
     79{
     80	struct ath9k_htc_priv *priv = file->private_data;
     81	struct ath9k_htc_target_tx_stats cmd_rsp;
     82	char buf[512];
     83	unsigned int len = 0;
     84	int ret = 0;
     85
     86	memset(&cmd_rsp, 0, sizeof(cmd_rsp));
     87
     88	ath9k_htc_ps_wakeup(priv);
     89
     90	WMI_CMD(WMI_TX_STATS_CMDID);
     91	if (ret) {
     92		ath9k_htc_ps_restore(priv);
     93		return -EINVAL;
     94	}
     95
     96	ath9k_htc_ps_restore(priv);
     97
     98	len += scnprintf(buf + len, sizeof(buf) - len,
     99			 "%20s : %10u\n", "Xretries",
    100			 be32_to_cpu(cmd_rsp.xretries));
    101
    102	len += scnprintf(buf + len, sizeof(buf) - len,
    103			 "%20s : %10u\n", "FifoErr",
    104			 be32_to_cpu(cmd_rsp.fifoerr));
    105
    106	len += scnprintf(buf + len, sizeof(buf) - len,
    107			 "%20s : %10u\n", "Filtered",
    108			 be32_to_cpu(cmd_rsp.filtered));
    109
    110	len += scnprintf(buf + len, sizeof(buf) - len,
    111			 "%20s : %10u\n", "TimerExp",
    112			 be32_to_cpu(cmd_rsp.timer_exp));
    113
    114	len += scnprintf(buf + len, sizeof(buf) - len,
    115			 "%20s : %10u\n", "ShortRetries",
    116			 be32_to_cpu(cmd_rsp.shortretries));
    117
    118	len += scnprintf(buf + len, sizeof(buf) - len,
    119			 "%20s : %10u\n", "LongRetries",
    120			 be32_to_cpu(cmd_rsp.longretries));
    121
    122	len += scnprintf(buf + len, sizeof(buf) - len,
    123			 "%20s : %10u\n", "QueueNull",
    124			 be32_to_cpu(cmd_rsp.qnull));
    125
    126	len += scnprintf(buf + len, sizeof(buf) - len,
    127			 "%20s : %10u\n", "EncapFail",
    128			 be32_to_cpu(cmd_rsp.encap_fail));
    129
    130	len += scnprintf(buf + len, sizeof(buf) - len,
    131			 "%20s : %10u\n", "NoBuf",
    132			 be32_to_cpu(cmd_rsp.nobuf));
    133
    134	if (len > sizeof(buf))
    135		len = sizeof(buf);
    136
    137	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
    138}
    139
    140static const struct file_operations fops_tgt_tx_stats = {
    141	.read = read_file_tgt_tx_stats,
    142	.open = simple_open,
    143	.owner = THIS_MODULE,
    144	.llseek = default_llseek,
    145};
    146
    147static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf,
    148				      size_t count, loff_t *ppos)
    149{
    150	struct ath9k_htc_priv *priv = file->private_data;
    151	struct ath9k_htc_target_rx_stats cmd_rsp;
    152	char buf[512];
    153	unsigned int len = 0;
    154	int ret = 0;
    155
    156	memset(&cmd_rsp, 0, sizeof(cmd_rsp));
    157
    158	ath9k_htc_ps_wakeup(priv);
    159
    160	WMI_CMD(WMI_RX_STATS_CMDID);
    161	if (ret) {
    162		ath9k_htc_ps_restore(priv);
    163		return -EINVAL;
    164	}
    165
    166	ath9k_htc_ps_restore(priv);
    167
    168	len += scnprintf(buf + len, sizeof(buf) - len,
    169			 "%20s : %10u\n", "NoBuf",
    170			 be32_to_cpu(cmd_rsp.nobuf));
    171
    172	len += scnprintf(buf + len, sizeof(buf) - len,
    173			 "%20s : %10u\n", "HostSend",
    174			 be32_to_cpu(cmd_rsp.host_send));
    175
    176	len += scnprintf(buf + len, sizeof(buf) - len,
    177			 "%20s : %10u\n", "HostDone",
    178			 be32_to_cpu(cmd_rsp.host_done));
    179
    180	if (len > sizeof(buf))
    181		len = sizeof(buf);
    182
    183	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
    184}
    185
    186static const struct file_operations fops_tgt_rx_stats = {
    187	.read = read_file_tgt_rx_stats,
    188	.open = simple_open,
    189	.owner = THIS_MODULE,
    190	.llseek = default_llseek,
    191};
    192
    193static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
    194			      size_t count, loff_t *ppos)
    195{
    196	struct ath9k_htc_priv *priv = file->private_data;
    197	char buf[512];
    198	unsigned int len = 0;
    199
    200	len += scnprintf(buf + len, sizeof(buf) - len,
    201			 "%20s : %10u\n", "Buffers queued",
    202			 priv->debug.tx_stats.buf_queued);
    203	len += scnprintf(buf + len, sizeof(buf) - len,
    204			 "%20s : %10u\n", "Buffers completed",
    205			 priv->debug.tx_stats.buf_completed);
    206	len += scnprintf(buf + len, sizeof(buf) - len,
    207			 "%20s : %10u\n", "SKBs queued",
    208			 priv->debug.tx_stats.skb_queued);
    209	len += scnprintf(buf + len, sizeof(buf) - len,
    210			 "%20s : %10u\n", "SKBs success",
    211			 priv->debug.tx_stats.skb_success);
    212	len += scnprintf(buf + len, sizeof(buf) - len,
    213			 "%20s : %10u\n", "SKBs failed",
    214			 priv->debug.tx_stats.skb_failed);
    215	len += scnprintf(buf + len, sizeof(buf) - len,
    216			 "%20s : %10u\n", "CAB queued",
    217			 priv->debug.tx_stats.cab_queued);
    218
    219	len += scnprintf(buf + len, sizeof(buf) - len,
    220			 "%20s : %10u\n", "BE queued",
    221			 priv->debug.tx_stats.queue_stats[IEEE80211_AC_BE]);
    222	len += scnprintf(buf + len, sizeof(buf) - len,
    223			 "%20s : %10u\n", "BK queued",
    224			 priv->debug.tx_stats.queue_stats[IEEE80211_AC_BK]);
    225	len += scnprintf(buf + len, sizeof(buf) - len,
    226			 "%20s : %10u\n", "VI queued",
    227			 priv->debug.tx_stats.queue_stats[IEEE80211_AC_VI]);
    228	len += scnprintf(buf + len, sizeof(buf) - len,
    229			 "%20s : %10u\n", "VO queued",
    230			 priv->debug.tx_stats.queue_stats[IEEE80211_AC_VO]);
    231
    232	if (len > sizeof(buf))
    233		len = sizeof(buf);
    234
    235	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
    236}
    237
    238static const struct file_operations fops_xmit = {
    239	.read = read_file_xmit,
    240	.open = simple_open,
    241	.owner = THIS_MODULE,
    242	.llseek = default_llseek,
    243};
    244
    245void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
    246			     struct ath_rx_status *rs)
    247{
    248	ath9k_cmn_debug_stat_rx(&priv->debug.rx_stats, rs);
    249}
    250
    251static ssize_t read_file_skb_rx(struct file *file, char __user *user_buf,
    252			      size_t count, loff_t *ppos)
    253{
    254	struct ath9k_htc_priv *priv = file->private_data;
    255	char *buf;
    256	unsigned int len = 0, size = 1500;
    257	ssize_t retval = 0;
    258
    259	buf = kzalloc(size, GFP_KERNEL);
    260	if (buf == NULL)
    261		return -ENOMEM;
    262
    263	len += scnprintf(buf + len, size - len,
    264			 "%20s : %10u\n", "SKBs allocated",
    265			 priv->debug.skbrx_stats.skb_allocated);
    266	len += scnprintf(buf + len, size - len,
    267			 "%20s : %10u\n", "SKBs completed",
    268			 priv->debug.skbrx_stats.skb_completed);
    269	len += scnprintf(buf + len, size - len,
    270			 "%20s : %10u\n", "SKBs Dropped",
    271			 priv->debug.skbrx_stats.skb_dropped);
    272
    273	if (len > size)
    274		len = size;
    275
    276	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
    277	kfree(buf);
    278
    279	return retval;
    280}
    281
    282static const struct file_operations fops_skb_rx = {
    283	.read = read_file_skb_rx,
    284	.open = simple_open,
    285	.owner = THIS_MODULE,
    286	.llseek = default_llseek,
    287};
    288
    289static ssize_t read_file_slot(struct file *file, char __user *user_buf,
    290			      size_t count, loff_t *ppos)
    291{
    292	struct ath9k_htc_priv *priv = file->private_data;
    293	char buf[512];
    294	unsigned int len;
    295
    296	spin_lock_bh(&priv->tx.tx_lock);
    297	len = scnprintf(buf, sizeof(buf),
    298			"TX slot bitmap : %*pb\n"
    299			"Used slots     : %d\n",
    300			MAX_TX_BUF_NUM, priv->tx.tx_slot,
    301			bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM));
    302	spin_unlock_bh(&priv->tx.tx_lock);
    303	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
    304}
    305
    306static const struct file_operations fops_slot = {
    307	.read = read_file_slot,
    308	.open = simple_open,
    309	.owner = THIS_MODULE,
    310	.llseek = default_llseek,
    311};
    312
    313static ssize_t read_file_queue(struct file *file, char __user *user_buf,
    314			       size_t count, loff_t *ppos)
    315{
    316	struct ath9k_htc_priv *priv = file->private_data;
    317	char buf[512];
    318	unsigned int len = 0;
    319
    320	len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
    321			 "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue));
    322
    323	len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
    324			 "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue));
    325
    326	len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
    327			 "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue));
    328
    329	len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
    330			 "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue));
    331
    332	len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
    333			 "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue));
    334
    335	len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
    336			 "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue));
    337
    338	len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
    339			 "Failed queue", skb_queue_len(&priv->tx.tx_failed));
    340
    341	spin_lock_bh(&priv->tx.tx_lock);
    342	len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
    343			 "Queued count", priv->tx.queued_cnt);
    344	spin_unlock_bh(&priv->tx.tx_lock);
    345
    346	if (len > sizeof(buf))
    347		len = sizeof(buf);
    348
    349	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
    350
    351}
    352
    353static const struct file_operations fops_queue = {
    354	.read = read_file_queue,
    355	.open = simple_open,
    356	.owner = THIS_MODULE,
    357	.llseek = default_llseek,
    358};
    359
    360static ssize_t read_file_debug(struct file *file, char __user *user_buf,
    361			       size_t count, loff_t *ppos)
    362{
    363	struct ath9k_htc_priv *priv = file->private_data;
    364	struct ath_common *common = ath9k_hw_common(priv->ah);
    365	char buf[32];
    366	unsigned int len;
    367
    368	len = sprintf(buf, "0x%08x\n", common->debug_mask);
    369	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
    370}
    371
    372static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
    373				size_t count, loff_t *ppos)
    374{
    375	struct ath9k_htc_priv *priv = file->private_data;
    376	struct ath_common *common = ath9k_hw_common(priv->ah);
    377	unsigned long mask;
    378	char buf[32];
    379	ssize_t len;
    380
    381	len = min(count, sizeof(buf) - 1);
    382	if (copy_from_user(buf, user_buf, len))
    383		return -EFAULT;
    384
    385	buf[len] = '\0';
    386	if (kstrtoul(buf, 0, &mask))
    387		return -EINVAL;
    388
    389	common->debug_mask = mask;
    390	return count;
    391}
    392
    393static const struct file_operations fops_debug = {
    394	.read = read_file_debug,
    395	.write = write_file_debug,
    396	.open = simple_open,
    397	.owner = THIS_MODULE,
    398	.llseek = default_llseek,
    399};
    400
    401/* Ethtool support for get-stats */
    402#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
    403static const char ath9k_htc_gstrings_stats[][ETH_GSTRING_LEN] = {
    404	"tx_pkts_nic",
    405	"tx_bytes_nic",
    406	"rx_pkts_nic",
    407	"rx_bytes_nic",
    408
    409	AMKSTR(d_tx_pkts),
    410
    411	"d_rx_crc_err",
    412	"d_rx_decrypt_crc_err",
    413	"d_rx_phy_err",
    414	"d_rx_mic_err",
    415	"d_rx_pre_delim_crc_err",
    416	"d_rx_post_delim_crc_err",
    417	"d_rx_decrypt_busy_err",
    418
    419	"d_rx_phyerr_radar",
    420	"d_rx_phyerr_ofdm_timing",
    421	"d_rx_phyerr_cck_timing",
    422
    423};
    424#define ATH9K_HTC_SSTATS_LEN ARRAY_SIZE(ath9k_htc_gstrings_stats)
    425
    426void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
    427			      struct ieee80211_vif *vif,
    428			      u32 sset, u8 *data)
    429{
    430	if (sset == ETH_SS_STATS)
    431		memcpy(data, *ath9k_htc_gstrings_stats,
    432		       sizeof(ath9k_htc_gstrings_stats));
    433}
    434
    435int ath9k_htc_get_et_sset_count(struct ieee80211_hw *hw,
    436				struct ieee80211_vif *vif, int sset)
    437{
    438	if (sset == ETH_SS_STATS)
    439		return ATH9K_HTC_SSTATS_LEN;
    440	return 0;
    441}
    442
    443#define STXBASE priv->debug.tx_stats
    444#define SRXBASE priv->debug.rx_stats
    445#define SKBTXBASE priv->debug.tx_stats
    446#define SKBRXBASE priv->debug.skbrx_stats
    447#define ASTXQ(a)					\
    448	data[i++] = STXBASE.a[IEEE80211_AC_BE];		\
    449	data[i++] = STXBASE.a[IEEE80211_AC_BK];		\
    450	data[i++] = STXBASE.a[IEEE80211_AC_VI];		\
    451	data[i++] = STXBASE.a[IEEE80211_AC_VO]
    452
    453void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
    454			    struct ieee80211_vif *vif,
    455			    struct ethtool_stats *stats, u64 *data)
    456{
    457	struct ath9k_htc_priv *priv = hw->priv;
    458	int i = 0;
    459
    460	data[i++] = SKBTXBASE.skb_success;
    461	data[i++] = SKBTXBASE.skb_success_bytes;
    462	data[i++] = SKBRXBASE.skb_completed;
    463	data[i++] = SKBRXBASE.skb_completed_bytes;
    464
    465	ASTXQ(queue_stats);
    466
    467	data[i++] = SRXBASE.crc_err;
    468	data[i++] = SRXBASE.decrypt_crc_err;
    469	data[i++] = SRXBASE.phy_err;
    470	data[i++] = SRXBASE.mic_err;
    471	data[i++] = SRXBASE.pre_delim_crc_err;
    472	data[i++] = SRXBASE.post_delim_crc_err;
    473	data[i++] = SRXBASE.decrypt_busy_err;
    474
    475	data[i++] = SRXBASE.phy_err_stats[ATH9K_PHYERR_RADAR];
    476	data[i++] = SRXBASE.phy_err_stats[ATH9K_PHYERR_OFDM_TIMING];
    477	data[i++] = SRXBASE.phy_err_stats[ATH9K_PHYERR_CCK_TIMING];
    478
    479	WARN_ON(i != ATH9K_HTC_SSTATS_LEN);
    480}
    481
    482void ath9k_htc_deinit_debug(struct ath9k_htc_priv *priv)
    483{
    484	ath9k_cmn_spectral_deinit_debug(&priv->spec_priv);
    485}
    486
    487int ath9k_htc_init_debug(struct ath_hw *ah)
    488{
    489	struct ath_common *common = ath9k_hw_common(ah);
    490	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
    491
    492	priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,
    493					     priv->hw->wiphy->debugfsdir);
    494	if (!priv->debug.debugfs_phy)
    495		return -ENOMEM;
    496
    497	ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy);
    498
    499	debugfs_create_file("tgt_int_stats", 0400, priv->debug.debugfs_phy,
    500			    priv, &fops_tgt_int_stats);
    501	debugfs_create_file("tgt_tx_stats", 0400, priv->debug.debugfs_phy,
    502			    priv, &fops_tgt_tx_stats);
    503	debugfs_create_file("tgt_rx_stats", 0400, priv->debug.debugfs_phy,
    504			    priv, &fops_tgt_rx_stats);
    505	debugfs_create_file("xmit", 0400, priv->debug.debugfs_phy,
    506			    priv, &fops_xmit);
    507	debugfs_create_file("skb_rx", 0400, priv->debug.debugfs_phy,
    508			    priv, &fops_skb_rx);
    509
    510	ath9k_cmn_debug_recv(priv->debug.debugfs_phy, &priv->debug.rx_stats);
    511	ath9k_cmn_debug_phy_err(priv->debug.debugfs_phy, &priv->debug.rx_stats);
    512
    513	debugfs_create_file("slot", 0400, priv->debug.debugfs_phy,
    514			    priv, &fops_slot);
    515	debugfs_create_file("queue", 0400, priv->debug.debugfs_phy,
    516			    priv, &fops_queue);
    517	debugfs_create_file("debug", 0600, priv->debug.debugfs_phy,
    518			    priv, &fops_debug);
    519
    520	ath9k_cmn_debug_base_eeprom(priv->debug.debugfs_phy, priv->ah);
    521	ath9k_cmn_debug_modal_eeprom(priv->debug.debugfs_phy, priv->ah);
    522
    523	return 0;
    524}