162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright (c) 2008-2011 Atheros Communications Inc.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Permission to use, copy, modify, and/or distribute this software for any
562306a36Sopenharmony_ci * purpose with or without fee is hereby granted, provided that the above
662306a36Sopenharmony_ci * copyright notice and this permission notice appear in all copies.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
962306a36Sopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1062306a36Sopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1162306a36Sopenharmony_ci * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1262306a36Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1362306a36Sopenharmony_ci * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1462306a36Sopenharmony_ci * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1562306a36Sopenharmony_ci */
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include "common.h"
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistatic ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
2062306a36Sopenharmony_ci				      size_t count, loff_t *ppos)
2162306a36Sopenharmony_ci{
2262306a36Sopenharmony_ci	struct ath_hw *ah = file->private_data;
2362306a36Sopenharmony_ci	u32 len = 0, size = 6000;
2462306a36Sopenharmony_ci	char *buf;
2562306a36Sopenharmony_ci	size_t retval;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	buf = kzalloc(size, GFP_KERNEL);
2862306a36Sopenharmony_ci	if (buf == NULL)
2962306a36Sopenharmony_ci		return -ENOMEM;
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	len = ah->eep_ops->dump_eeprom(ah, false, buf, len, size);
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
3462306a36Sopenharmony_ci	kfree(buf);
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	return retval;
3762306a36Sopenharmony_ci}
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_cistatic const struct file_operations fops_modal_eeprom = {
4062306a36Sopenharmony_ci	.read = read_file_modal_eeprom,
4162306a36Sopenharmony_ci	.open = simple_open,
4262306a36Sopenharmony_ci	.owner = THIS_MODULE,
4362306a36Sopenharmony_ci	.llseek = default_llseek,
4462306a36Sopenharmony_ci};
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_civoid ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy,
4862306a36Sopenharmony_ci				  struct ath_hw *ah)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	debugfs_create_file("modal_eeprom", 0400, debugfs_phy, ah,
5162306a36Sopenharmony_ci			    &fops_modal_eeprom);
5262306a36Sopenharmony_ci}
5362306a36Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_modal_eeprom);
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistatic ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
5662306a36Sopenharmony_ci				     size_t count, loff_t *ppos)
5762306a36Sopenharmony_ci{
5862306a36Sopenharmony_ci	struct ath_hw *ah = file->private_data;
5962306a36Sopenharmony_ci	u32 len = 0, size = 1500;
6062306a36Sopenharmony_ci	ssize_t retval = 0;
6162306a36Sopenharmony_ci	char *buf;
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	buf = kzalloc(size, GFP_KERNEL);
6462306a36Sopenharmony_ci	if (!buf)
6562306a36Sopenharmony_ci		return -ENOMEM;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	len = ah->eep_ops->dump_eeprom(ah, true, buf, len, size);
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
7062306a36Sopenharmony_ci	kfree(buf);
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	return retval;
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistatic const struct file_operations fops_base_eeprom = {
7662306a36Sopenharmony_ci	.read = read_file_base_eeprom,
7762306a36Sopenharmony_ci	.open = simple_open,
7862306a36Sopenharmony_ci	.owner = THIS_MODULE,
7962306a36Sopenharmony_ci	.llseek = default_llseek,
8062306a36Sopenharmony_ci};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_civoid ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy,
8362306a36Sopenharmony_ci				 struct ath_hw *ah)
8462306a36Sopenharmony_ci{
8562306a36Sopenharmony_ci	debugfs_create_file("base_eeprom", 0400, debugfs_phy, ah,
8662306a36Sopenharmony_ci			    &fops_base_eeprom);
8762306a36Sopenharmony_ci}
8862306a36Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_base_eeprom);
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_civoid ath9k_cmn_debug_stat_rx(struct ath_rx_stats *rxstats,
9162306a36Sopenharmony_ci			     struct ath_rx_status *rs)
9262306a36Sopenharmony_ci{
9362306a36Sopenharmony_ci#define RX_PHY_ERR_INC(c) rxstats->phy_err_stats[c]++
9462306a36Sopenharmony_ci#define RX_CMN_STAT_INC(c) (rxstats->c++)
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	RX_CMN_STAT_INC(rx_pkts_all);
9762306a36Sopenharmony_ci	rxstats->rx_bytes_all += rs->rs_datalen;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	if (rs->rs_status & ATH9K_RXERR_CRC)
10062306a36Sopenharmony_ci		RX_CMN_STAT_INC(crc_err);
10162306a36Sopenharmony_ci	if (rs->rs_status & ATH9K_RXERR_DECRYPT)
10262306a36Sopenharmony_ci		RX_CMN_STAT_INC(decrypt_crc_err);
10362306a36Sopenharmony_ci	if (rs->rs_status & ATH9K_RXERR_MIC)
10462306a36Sopenharmony_ci		RX_CMN_STAT_INC(mic_err);
10562306a36Sopenharmony_ci	if (rs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
10662306a36Sopenharmony_ci		RX_CMN_STAT_INC(pre_delim_crc_err);
10762306a36Sopenharmony_ci	if (rs->rs_status & ATH9K_RX_DELIM_CRC_POST)
10862306a36Sopenharmony_ci		RX_CMN_STAT_INC(post_delim_crc_err);
10962306a36Sopenharmony_ci	if (rs->rs_status & ATH9K_RX_DECRYPT_BUSY)
11062306a36Sopenharmony_ci		RX_CMN_STAT_INC(decrypt_busy_err);
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	if (rs->rs_status & ATH9K_RXERR_PHY) {
11362306a36Sopenharmony_ci		RX_CMN_STAT_INC(phy_err);
11462306a36Sopenharmony_ci		if (rs->rs_phyerr < ATH9K_PHYERR_MAX)
11562306a36Sopenharmony_ci			RX_PHY_ERR_INC(rs->rs_phyerr);
11662306a36Sopenharmony_ci	}
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci#undef RX_CMN_STAT_INC
11962306a36Sopenharmony_ci#undef RX_PHY_ERR_INC
12062306a36Sopenharmony_ci}
12162306a36Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_stat_rx);
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_cistatic ssize_t read_file_recv(struct file *file, char __user *user_buf,
12462306a36Sopenharmony_ci			      size_t count, loff_t *ppos)
12562306a36Sopenharmony_ci{
12662306a36Sopenharmony_ci#define RXS_ERR(s, e)					\
12762306a36Sopenharmony_ci	do {						\
12862306a36Sopenharmony_ci		len += scnprintf(buf + len, size - len,	\
12962306a36Sopenharmony_ci				 "%18s : %10u\n", s,	\
13062306a36Sopenharmony_ci				 rxstats->e);		\
13162306a36Sopenharmony_ci	} while (0)
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci	struct ath_rx_stats *rxstats = file->private_data;
13462306a36Sopenharmony_ci	char *buf;
13562306a36Sopenharmony_ci	unsigned int len = 0, size = 1600;
13662306a36Sopenharmony_ci	ssize_t retval = 0;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	buf = kzalloc(size, GFP_KERNEL);
13962306a36Sopenharmony_ci	if (buf == NULL)
14062306a36Sopenharmony_ci		return -ENOMEM;
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	RXS_ERR("PKTS-ALL", rx_pkts_all);
14362306a36Sopenharmony_ci	RXS_ERR("BYTES-ALL", rx_bytes_all);
14462306a36Sopenharmony_ci	RXS_ERR("BEACONS", rx_beacons);
14562306a36Sopenharmony_ci	RXS_ERR("FRAGS", rx_frags);
14662306a36Sopenharmony_ci	RXS_ERR("SPECTRAL", rx_spectral);
14762306a36Sopenharmony_ci	RXS_ERR("SPECTRAL SMPL GOOD", rx_spectral_sample_good);
14862306a36Sopenharmony_ci	RXS_ERR("SPECTRAL SMPL ERR", rx_spectral_sample_err);
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	RXS_ERR("CRC ERR", crc_err);
15162306a36Sopenharmony_ci	RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err);
15262306a36Sopenharmony_ci	RXS_ERR("PHY ERR", phy_err);
15362306a36Sopenharmony_ci	RXS_ERR("MIC ERR", mic_err);
15462306a36Sopenharmony_ci	RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err);
15562306a36Sopenharmony_ci	RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err);
15662306a36Sopenharmony_ci	RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err);
15762306a36Sopenharmony_ci	RXS_ERR("LENGTH-ERR", rx_len_err);
15862306a36Sopenharmony_ci	RXS_ERR("OOM-ERR", rx_oom_err);
15962306a36Sopenharmony_ci	RXS_ERR("RATE-ERR", rx_rate_err);
16062306a36Sopenharmony_ci	RXS_ERR("TOO-MANY-FRAGS", rx_too_many_frags_err);
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci	if (len > size)
16362306a36Sopenharmony_ci		len = size;
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
16662306a36Sopenharmony_ci	kfree(buf);
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	return retval;
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci#undef RXS_ERR
17162306a36Sopenharmony_ci}
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_cistatic const struct file_operations fops_recv = {
17462306a36Sopenharmony_ci	.read = read_file_recv,
17562306a36Sopenharmony_ci	.open = simple_open,
17662306a36Sopenharmony_ci	.owner = THIS_MODULE,
17762306a36Sopenharmony_ci	.llseek = default_llseek,
17862306a36Sopenharmony_ci};
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_civoid ath9k_cmn_debug_recv(struct dentry *debugfs_phy,
18162306a36Sopenharmony_ci			  struct ath_rx_stats *rxstats)
18262306a36Sopenharmony_ci{
18362306a36Sopenharmony_ci	debugfs_create_file("recv", 0400, debugfs_phy, rxstats, &fops_recv);
18462306a36Sopenharmony_ci}
18562306a36Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_recv);
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_cistatic ssize_t read_file_phy_err(struct file *file, char __user *user_buf,
18862306a36Sopenharmony_ci				 size_t count, loff_t *ppos)
18962306a36Sopenharmony_ci{
19062306a36Sopenharmony_ci#define PHY_ERR(s, p) \
19162306a36Sopenharmony_ci	len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \
19262306a36Sopenharmony_ci			 rxstats->phy_err_stats[p])
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	struct ath_rx_stats *rxstats = file->private_data;
19562306a36Sopenharmony_ci	char *buf;
19662306a36Sopenharmony_ci	unsigned int len = 0, size = 1600;
19762306a36Sopenharmony_ci	ssize_t retval = 0;
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	buf = kzalloc(size, GFP_KERNEL);
20062306a36Sopenharmony_ci	if (buf == NULL)
20162306a36Sopenharmony_ci		return -ENOMEM;
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci	PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
20462306a36Sopenharmony_ci	PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING);
20562306a36Sopenharmony_ci	PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY);
20662306a36Sopenharmony_ci	PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE);
20762306a36Sopenharmony_ci	PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH);
20862306a36Sopenharmony_ci	PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR);
20962306a36Sopenharmony_ci	PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE);
21062306a36Sopenharmony_ci	PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR);
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING);
21362306a36Sopenharmony_ci	PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
21462306a36Sopenharmony_ci	PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
21562306a36Sopenharmony_ci	PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
21662306a36Sopenharmony_ci	PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP);
21762306a36Sopenharmony_ci	PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE);
21862306a36Sopenharmony_ci	PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART);
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	PHY_ERR("CCK-BLOCKER ERR", ATH9K_PHYERR_CCK_BLOCKER);
22162306a36Sopenharmony_ci	PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING);
22262306a36Sopenharmony_ci	PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC);
22362306a36Sopenharmony_ci	PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
22462306a36Sopenharmony_ci	PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
22562306a36Sopenharmony_ci	PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP);
22662306a36Sopenharmony_ci	PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE);
22762306a36Sopenharmony_ci	PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART);
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci	PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR);
23062306a36Sopenharmony_ci	PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
23162306a36Sopenharmony_ci	PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
23262306a36Sopenharmony_ci	PHY_ERR("HT-ZLF ERR", ATH9K_PHYERR_HT_ZLF);
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci	PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT);
23562306a36Sopenharmony_ci	PHY_ERR("GREEN-FIELD ERR", ATH9K_PHYERR_GREEN_FIELD);
23662306a36Sopenharmony_ci	PHY_ERR("SPECTRAL ERR", ATH9K_PHYERR_SPECTRAL);
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	if (len > size)
23962306a36Sopenharmony_ci		len = size;
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ci	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
24262306a36Sopenharmony_ci	kfree(buf);
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	return retval;
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci#undef PHY_ERR
24762306a36Sopenharmony_ci}
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_cistatic const struct file_operations fops_phy_err = {
25062306a36Sopenharmony_ci	.read = read_file_phy_err,
25162306a36Sopenharmony_ci	.open = simple_open,
25262306a36Sopenharmony_ci	.owner = THIS_MODULE,
25362306a36Sopenharmony_ci	.llseek = default_llseek,
25462306a36Sopenharmony_ci};
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_civoid ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy,
25762306a36Sopenharmony_ci			     struct ath_rx_stats *rxstats)
25862306a36Sopenharmony_ci{
25962306a36Sopenharmony_ci	debugfs_create_file("phy_err", 0400, debugfs_phy, rxstats,
26062306a36Sopenharmony_ci			    &fops_phy_err);
26162306a36Sopenharmony_ci}
26262306a36Sopenharmony_ciEXPORT_SYMBOL(ath9k_cmn_debug_phy_err);
263