162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright (c) 2012 Broadcom Corporation 362306a36Sopenharmony_ci * Copyright (c) 2012 Canonical Ltd. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Permission to use, copy, modify, and/or distribute this software for any 662306a36Sopenharmony_ci * purpose with or without fee is hereby granted, provided that the above 762306a36Sopenharmony_ci * copyright notice and this permission notice appear in all copies. 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1062306a36Sopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1162306a36Sopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 1262306a36Sopenharmony_ci * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1362306a36Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 1462306a36Sopenharmony_ci * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 1562306a36Sopenharmony_ci * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ci#include <linux/debugfs.h> 1862306a36Sopenharmony_ci#include <linux/if_ether.h> 1962306a36Sopenharmony_ci#include <linux/if.h> 2062306a36Sopenharmony_ci#include <linux/net.h> 2162306a36Sopenharmony_ci#include <linux/netdevice.h> 2262306a36Sopenharmony_ci#include <linux/ieee80211.h> 2362306a36Sopenharmony_ci#include <linux/module.h> 2462306a36Sopenharmony_ci#include <net/mac80211.h> 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#include <defs.h> 2762306a36Sopenharmony_ci#include <brcmu_wifi.h> 2862306a36Sopenharmony_ci#include <brcmu_utils.h> 2962306a36Sopenharmony_ci#include "types.h" 3062306a36Sopenharmony_ci#include "main.h" 3162306a36Sopenharmony_ci#include "debug.h" 3262306a36Sopenharmony_ci#include "brcms_trace_events.h" 3362306a36Sopenharmony_ci#include "phy/phy_int.h" 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic struct dentry *root_folder; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_civoid brcms_debugfs_init(void) 3862306a36Sopenharmony_ci{ 3962306a36Sopenharmony_ci root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL); 4062306a36Sopenharmony_ci} 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_civoid brcms_debugfs_exit(void) 4362306a36Sopenharmony_ci{ 4462306a36Sopenharmony_ci debugfs_remove_recursive(root_folder); 4562306a36Sopenharmony_ci root_folder = NULL; 4662306a36Sopenharmony_ci} 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_civoid brcms_debugfs_attach(struct brcms_pub *drvr) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci drvr->dbgfs_dir = debugfs_create_dir( 5162306a36Sopenharmony_ci dev_name(&drvr->wlc->hw->d11core->dev), root_folder); 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_civoid brcms_debugfs_detach(struct brcms_pub *drvr) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci debugfs_remove_recursive(drvr->dbgfs_dir); 5762306a36Sopenharmony_ci} 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistruct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr) 6062306a36Sopenharmony_ci{ 6162306a36Sopenharmony_ci return drvr->dbgfs_dir; 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistatic 6562306a36Sopenharmony_ciint brcms_debugfs_hardware_read(struct seq_file *s, void *data) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci struct brcms_pub *drvr = s->private; 6862306a36Sopenharmony_ci struct brcms_hardware *hw = drvr->wlc->hw; 6962306a36Sopenharmony_ci struct bcma_device *core = hw->d11core; 7062306a36Sopenharmony_ci struct bcma_bus *bus = core->bus; 7162306a36Sopenharmony_ci char boardrev[BRCMU_BOARDREV_LEN]; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci seq_printf(s, "chipnum 0x%x\n" 7462306a36Sopenharmony_ci "chiprev 0x%x\n" 7562306a36Sopenharmony_ci "chippackage 0x%x\n" 7662306a36Sopenharmony_ci "corerev 0x%x\n" 7762306a36Sopenharmony_ci "boardid 0x%x\n" 7862306a36Sopenharmony_ci "boardvendor 0x%x\n" 7962306a36Sopenharmony_ci "boardrev %s\n" 8062306a36Sopenharmony_ci "boardflags 0x%x\n" 8162306a36Sopenharmony_ci "boardflags2 0x%x\n" 8262306a36Sopenharmony_ci "ucoderev 0x%x\n" 8362306a36Sopenharmony_ci "radiorev 0x%x\n" 8462306a36Sopenharmony_ci "phytype 0x%x\n" 8562306a36Sopenharmony_ci "phyrev 0x%x\n" 8662306a36Sopenharmony_ci "anarev 0x%x\n" 8762306a36Sopenharmony_ci "nvramrev %d\n", 8862306a36Sopenharmony_ci bus->chipinfo.id, bus->chipinfo.rev, bus->chipinfo.pkg, 8962306a36Sopenharmony_ci core->id.rev, bus->boardinfo.type, bus->boardinfo.vendor, 9062306a36Sopenharmony_ci brcmu_boardrev_str(hw->boardrev, boardrev), 9162306a36Sopenharmony_ci drvr->wlc->hw->boardflags, drvr->wlc->hw->boardflags2, 9262306a36Sopenharmony_ci drvr->wlc->ucode_rev, hw->band->radiorev, 9362306a36Sopenharmony_ci hw->band->phytype, hw->band->phyrev, hw->band->pi->ana_rev, 9462306a36Sopenharmony_ci hw->sromrev); 9562306a36Sopenharmony_ci return 0; 9662306a36Sopenharmony_ci} 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistatic int brcms_debugfs_macstat_read(struct seq_file *s, void *data) 9962306a36Sopenharmony_ci{ 10062306a36Sopenharmony_ci struct brcms_pub *drvr = s->private; 10162306a36Sopenharmony_ci struct brcms_info *wl = drvr->ieee_hw->priv; 10262306a36Sopenharmony_ci struct macstat stats; 10362306a36Sopenharmony_ci int i; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci spin_lock_bh(&wl->lock); 10662306a36Sopenharmony_ci stats = *(drvr->wlc->core->macstat_snapshot); 10762306a36Sopenharmony_ci spin_unlock_bh(&wl->lock); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci seq_printf(s, "txallfrm: %d\n", stats.txallfrm); 11062306a36Sopenharmony_ci seq_printf(s, "txrtsfrm: %d\n", stats.txrtsfrm); 11162306a36Sopenharmony_ci seq_printf(s, "txctsfrm: %d\n", stats.txctsfrm); 11262306a36Sopenharmony_ci seq_printf(s, "txackfrm: %d\n", stats.txackfrm); 11362306a36Sopenharmony_ci seq_printf(s, "txdnlfrm: %d\n", stats.txdnlfrm); 11462306a36Sopenharmony_ci seq_printf(s, "txbcnfrm: %d\n", stats.txbcnfrm); 11562306a36Sopenharmony_ci seq_printf(s, "txfunfl[8]:"); 11662306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(stats.txfunfl); i++) 11762306a36Sopenharmony_ci seq_printf(s, " %d", stats.txfunfl[i]); 11862306a36Sopenharmony_ci seq_printf(s, "\ntxtplunfl: %d\n", stats.txtplunfl); 11962306a36Sopenharmony_ci seq_printf(s, "txphyerr: %d\n", stats.txphyerr); 12062306a36Sopenharmony_ci seq_printf(s, "pktengrxducast: %d\n", stats.pktengrxducast); 12162306a36Sopenharmony_ci seq_printf(s, "pktengrxdmcast: %d\n", stats.pktengrxdmcast); 12262306a36Sopenharmony_ci seq_printf(s, "rxfrmtoolong: %d\n", stats.rxfrmtoolong); 12362306a36Sopenharmony_ci seq_printf(s, "rxfrmtooshrt: %d\n", stats.rxfrmtooshrt); 12462306a36Sopenharmony_ci seq_printf(s, "rxinvmachdr: %d\n", stats.rxinvmachdr); 12562306a36Sopenharmony_ci seq_printf(s, "rxbadfcs: %d\n", stats.rxbadfcs); 12662306a36Sopenharmony_ci seq_printf(s, "rxbadplcp: %d\n", stats.rxbadplcp); 12762306a36Sopenharmony_ci seq_printf(s, "rxcrsglitch: %d\n", stats.rxcrsglitch); 12862306a36Sopenharmony_ci seq_printf(s, "rxstrt: %d\n", stats.rxstrt); 12962306a36Sopenharmony_ci seq_printf(s, "rxdfrmucastmbss: %d\n", stats.rxdfrmucastmbss); 13062306a36Sopenharmony_ci seq_printf(s, "rxmfrmucastmbss: %d\n", stats.rxmfrmucastmbss); 13162306a36Sopenharmony_ci seq_printf(s, "rxcfrmucast: %d\n", stats.rxcfrmucast); 13262306a36Sopenharmony_ci seq_printf(s, "rxrtsucast: %d\n", stats.rxrtsucast); 13362306a36Sopenharmony_ci seq_printf(s, "rxctsucast: %d\n", stats.rxctsucast); 13462306a36Sopenharmony_ci seq_printf(s, "rxackucast: %d\n", stats.rxackucast); 13562306a36Sopenharmony_ci seq_printf(s, "rxdfrmocast: %d\n", stats.rxdfrmocast); 13662306a36Sopenharmony_ci seq_printf(s, "rxmfrmocast: %d\n", stats.rxmfrmocast); 13762306a36Sopenharmony_ci seq_printf(s, "rxcfrmocast: %d\n", stats.rxcfrmocast); 13862306a36Sopenharmony_ci seq_printf(s, "rxrtsocast: %d\n", stats.rxrtsocast); 13962306a36Sopenharmony_ci seq_printf(s, "rxctsocast: %d\n", stats.rxctsocast); 14062306a36Sopenharmony_ci seq_printf(s, "rxdfrmmcast: %d\n", stats.rxdfrmmcast); 14162306a36Sopenharmony_ci seq_printf(s, "rxmfrmmcast: %d\n", stats.rxmfrmmcast); 14262306a36Sopenharmony_ci seq_printf(s, "rxcfrmmcast: %d\n", stats.rxcfrmmcast); 14362306a36Sopenharmony_ci seq_printf(s, "rxbeaconmbss: %d\n", stats.rxbeaconmbss); 14462306a36Sopenharmony_ci seq_printf(s, "rxdfrmucastobss: %d\n", stats.rxdfrmucastobss); 14562306a36Sopenharmony_ci seq_printf(s, "rxbeaconobss: %d\n", stats.rxbeaconobss); 14662306a36Sopenharmony_ci seq_printf(s, "rxrsptmout: %d\n", stats.rxrsptmout); 14762306a36Sopenharmony_ci seq_printf(s, "bcntxcancl: %d\n", stats.bcntxcancl); 14862306a36Sopenharmony_ci seq_printf(s, "rxf0ovfl: %d\n", stats.rxf0ovfl); 14962306a36Sopenharmony_ci seq_printf(s, "rxf1ovfl: %d\n", stats.rxf1ovfl); 15062306a36Sopenharmony_ci seq_printf(s, "rxf2ovfl: %d\n", stats.rxf2ovfl); 15162306a36Sopenharmony_ci seq_printf(s, "txsfovfl: %d\n", stats.txsfovfl); 15262306a36Sopenharmony_ci seq_printf(s, "pmqovfl: %d\n", stats.pmqovfl); 15362306a36Sopenharmony_ci seq_printf(s, "rxcgprqfrm: %d\n", stats.rxcgprqfrm); 15462306a36Sopenharmony_ci seq_printf(s, "rxcgprsqovfl: %d\n", stats.rxcgprsqovfl); 15562306a36Sopenharmony_ci seq_printf(s, "txcgprsfail: %d\n", stats.txcgprsfail); 15662306a36Sopenharmony_ci seq_printf(s, "txcgprssuc: %d\n", stats.txcgprssuc); 15762306a36Sopenharmony_ci seq_printf(s, "prs_timeout: %d\n", stats.prs_timeout); 15862306a36Sopenharmony_ci seq_printf(s, "rxnack: %d\n", stats.rxnack); 15962306a36Sopenharmony_ci seq_printf(s, "frmscons: %d\n", stats.frmscons); 16062306a36Sopenharmony_ci seq_printf(s, "txnack: %d\n", stats.txnack); 16162306a36Sopenharmony_ci seq_printf(s, "txglitch_nack: %d\n", stats.txglitch_nack); 16262306a36Sopenharmony_ci seq_printf(s, "txburst: %d\n", stats.txburst); 16362306a36Sopenharmony_ci seq_printf(s, "bphy_rxcrsglitch: %d\n", stats.bphy_rxcrsglitch); 16462306a36Sopenharmony_ci seq_printf(s, "phywatchdog: %d\n", stats.phywatchdog); 16562306a36Sopenharmony_ci seq_printf(s, "bphy_badplcp: %d\n", stats.bphy_badplcp); 16662306a36Sopenharmony_ci return 0; 16762306a36Sopenharmony_ci} 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistruct brcms_debugfs_entry { 17062306a36Sopenharmony_ci int (*read)(struct seq_file *seq, void *data); 17162306a36Sopenharmony_ci struct brcms_pub *drvr; 17262306a36Sopenharmony_ci}; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistatic int brcms_debugfs_entry_open(struct inode *inode, struct file *f) 17562306a36Sopenharmony_ci{ 17662306a36Sopenharmony_ci struct brcms_debugfs_entry *entry = inode->i_private; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci return single_open(f, entry->read, entry->drvr); 17962306a36Sopenharmony_ci} 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_cistatic const struct file_operations brcms_debugfs_def_ops = { 18262306a36Sopenharmony_ci .owner = THIS_MODULE, 18362306a36Sopenharmony_ci .open = brcms_debugfs_entry_open, 18462306a36Sopenharmony_ci .release = single_release, 18562306a36Sopenharmony_ci .read = seq_read, 18662306a36Sopenharmony_ci .llseek = seq_lseek 18762306a36Sopenharmony_ci}; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cistatic void 19062306a36Sopenharmony_cibrcms_debugfs_add_entry(struct brcms_pub *drvr, const char *fn, 19162306a36Sopenharmony_ci int (*read_fn)(struct seq_file *seq, void *data)) 19262306a36Sopenharmony_ci{ 19362306a36Sopenharmony_ci struct device *dev = &drvr->wlc->hw->d11core->dev; 19462306a36Sopenharmony_ci struct dentry *dentry = drvr->dbgfs_dir; 19562306a36Sopenharmony_ci struct brcms_debugfs_entry *entry; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci entry = devm_kzalloc(dev, sizeof(*entry), GFP_KERNEL); 19862306a36Sopenharmony_ci if (!entry) 19962306a36Sopenharmony_ci return; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci entry->read = read_fn; 20262306a36Sopenharmony_ci entry->drvr = drvr; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci debugfs_create_file(fn, 0444, dentry, entry, &brcms_debugfs_def_ops); 20562306a36Sopenharmony_ci} 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_civoid brcms_debugfs_create_files(struct brcms_pub *drvr) 20862306a36Sopenharmony_ci{ 20962306a36Sopenharmony_ci brcms_debugfs_add_entry(drvr, "hardware", brcms_debugfs_hardware_read); 21062306a36Sopenharmony_ci brcms_debugfs_add_entry(drvr, "macstat", brcms_debugfs_macstat_read); 21162306a36Sopenharmony_ci} 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci#define __brcms_fn(fn) \ 21462306a36Sopenharmony_civoid __brcms_ ##fn(struct device *dev, const char *fmt, ...) \ 21562306a36Sopenharmony_ci{ \ 21662306a36Sopenharmony_ci struct va_format vaf = { \ 21762306a36Sopenharmony_ci .fmt = fmt, \ 21862306a36Sopenharmony_ci }; \ 21962306a36Sopenharmony_ci va_list args; \ 22062306a36Sopenharmony_ci \ 22162306a36Sopenharmony_ci va_start(args, fmt); \ 22262306a36Sopenharmony_ci vaf.va = &args; \ 22362306a36Sopenharmony_ci dev_ ##fn(dev, "%pV", &vaf); \ 22462306a36Sopenharmony_ci trace_brcms_ ##fn(&vaf); \ 22562306a36Sopenharmony_ci va_end(args); \ 22662306a36Sopenharmony_ci} 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci__brcms_fn(info) 22962306a36Sopenharmony_ci__brcms_fn(warn) 23062306a36Sopenharmony_ci__brcms_fn(err) 23162306a36Sopenharmony_ci__brcms_fn(crit) 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING) 23462306a36Sopenharmony_civoid __brcms_dbg(struct device *dev, u32 level, const char *func, 23562306a36Sopenharmony_ci const char *fmt, ...) 23662306a36Sopenharmony_ci{ 23762306a36Sopenharmony_ci struct va_format vaf = { 23862306a36Sopenharmony_ci .fmt = fmt, 23962306a36Sopenharmony_ci }; 24062306a36Sopenharmony_ci va_list args; 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci va_start(args, fmt); 24362306a36Sopenharmony_ci vaf.va = &args; 24462306a36Sopenharmony_ci#ifdef CONFIG_BRCMDBG 24562306a36Sopenharmony_ci if ((brcm_msg_level & level) && net_ratelimit()) 24662306a36Sopenharmony_ci dev_err(dev, "%s %pV", func, &vaf); 24762306a36Sopenharmony_ci#endif 24862306a36Sopenharmony_ci trace_brcms_dbg(level, func, &vaf); 24962306a36Sopenharmony_ci va_end(args); 25062306a36Sopenharmony_ci} 25162306a36Sopenharmony_ci#endif 252