aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2014-07-12 02:49:36 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-07-15 16:00:11 -0400
commit82d957e09d4f0ff8091ca67e39b51ec6bdc672b1 (patch)
tree75ac4205f8f31b19de8abe4ae5d5d30ba9f3b99b
parent1b1e4e9e3abca01b7be6400db879ca8c475a2c96 (diff)
brcmfmac: rework debugfs functions in the driver
Reworked the debugfs functions in the driver making it easier for other driver parts to add a debugfs entry and keeping the information they want to expose in debugfs private, ie. not in a header. This is accomplished by providing the function brcmf_debugfs_add_entry() in which the caller provides a read function in which they provide the content. The debugfs function will take care of creating the debugfs entry and cleaning up upon removal. Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c179
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h74
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c89
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c100
4 files changed, 207 insertions, 235 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
index e1ac932a3154..be9f4f829192 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
@@ -43,37 +43,13 @@ void brcmf_debugfs_exit(void)
43 43
44static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data) 44static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data)
45{ 45{
46 struct brcmf_pub *drvr = seq->private; 46 struct brcmf_bus *bus = dev_get_drvdata(seq->private);
47 struct brcmf_bus *bus = drvr->bus_if;
48 47
49 seq_printf(seq, "chip: %x(%u) rev %u\n", 48 seq_printf(seq, "chip: %x(%u) rev %u\n",
50 bus->chip, bus->chip, bus->chiprev); 49 bus->chip, bus->chip, bus->chiprev);
51 return 0; 50 return 0;
52} 51}
53 52
54static int brcmf_debugfs_chipinfo_open(struct inode *inode, struct file *f)
55{
56 return single_open(f, brcmf_debugfs_chipinfo_read, inode->i_private);
57}
58
59static const struct file_operations brcmf_debugfs_chipinfo_ops = {
60 .owner = THIS_MODULE,
61 .open = brcmf_debugfs_chipinfo_open,
62 .release = single_release,
63 .read = seq_read,
64 .llseek = seq_lseek
65};
66
67static int brcmf_debugfs_create_chipinfo(struct brcmf_pub *drvr)
68{
69 struct dentry *dentry = drvr->dbgfs_dir;
70
71 if (!IS_ERR_OR_NULL(dentry))
72 debugfs_create_file("chipinfo", S_IRUGO, dentry, drvr,
73 &brcmf_debugfs_chipinfo_ops);
74 return 0;
75}
76
77int brcmf_debugfs_attach(struct brcmf_pub *drvr) 53int brcmf_debugfs_attach(struct brcmf_pub *drvr)
78{ 54{
79 struct device *dev = drvr->bus_if->dev; 55 struct device *dev = drvr->bus_if->dev;
@@ -82,7 +58,8 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr)
82 return -ENODEV; 58 return -ENODEV;
83 59
84 drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); 60 drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
85 brcmf_debugfs_create_chipinfo(drvr); 61 brcmf_debugfs_add_entry(drvr, "chipinfo", brcmf_debugfs_chipinfo_read);
62
86 return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); 63 return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
87} 64}
88 65
@@ -97,146 +74,44 @@ struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr)
97 return drvr->dbgfs_dir; 74 return drvr->dbgfs_dir;
98} 75}
99 76
100static int brcmf_debugfs_sdio_count_read(struct seq_file *seq, void *data) 77struct brcmf_debugfs_entry {
101{ 78 int (*read)(struct seq_file *seq, void *data);
102 struct brcmf_sdio_count *sdcnt = seq->private; 79 struct brcmf_pub *drvr;
103 80};
104 seq_printf(seq,
105 "intrcount: %u\nlastintrs: %u\n"
106 "pollcnt: %u\nregfails: %u\n"
107 "tx_sderrs: %u\nfcqueued: %u\n"
108 "rxrtx: %u\nrx_toolong: %u\n"
109 "rxc_errors: %u\nrx_hdrfail: %u\n"
110 "rx_badhdr: %u\nrx_badseq: %u\n"
111 "fc_rcvd: %u\nfc_xoff: %u\n"
112 "fc_xon: %u\nrxglomfail: %u\n"
113 "rxglomframes: %u\nrxglompkts: %u\n"
114 "f2rxhdrs: %u\nf2rxdata: %u\n"
115 "f2txdata: %u\nf1regdata: %u\n"
116 "tickcnt: %u\ntx_ctlerrs: %lu\n"
117 "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n"
118 "rx_ctlpkts: %lu\nrx_readahead: %lu\n",
119 sdcnt->intrcount, sdcnt->lastintrs,
120 sdcnt->pollcnt, sdcnt->regfails,
121 sdcnt->tx_sderrs, sdcnt->fcqueued,
122 sdcnt->rxrtx, sdcnt->rx_toolong,
123 sdcnt->rxc_errors, sdcnt->rx_hdrfail,
124 sdcnt->rx_badhdr, sdcnt->rx_badseq,
125 sdcnt->fc_rcvd, sdcnt->fc_xoff,
126 sdcnt->fc_xon, sdcnt->rxglomfail,
127 sdcnt->rxglomframes, sdcnt->rxglompkts,
128 sdcnt->f2rxhdrs, sdcnt->f2rxdata,
129 sdcnt->f2txdata, sdcnt->f1regdata,
130 sdcnt->tickcnt, sdcnt->tx_ctlerrs,
131 sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs,
132 sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt);
133
134 return 0;
135}
136 81
137static int brcmf_debugfs_sdio_count_open(struct inode *inode, struct file *f) 82static int brcmf_debugfs_entry_open(struct inode *inode, struct file *f)
138{ 83{
139 return single_open(f, brcmf_debugfs_sdio_count_read, inode->i_private); 84 struct brcmf_debugfs_entry *entry = inode->i_private;
85
86 return single_open(f, entry->read, entry->drvr->bus_if->dev);
140} 87}
141 88
142static const struct file_operations brcmf_debugfs_sdio_counter_ops = { 89static const struct file_operations brcmf_debugfs_def_ops = {
143 .owner = THIS_MODULE, 90 .owner = THIS_MODULE,
144 .open = brcmf_debugfs_sdio_count_open, 91 .open = brcmf_debugfs_entry_open,
145 .release = single_release, 92 .release = single_release,
146 .read = seq_read, 93 .read = seq_read,
147 .llseek = seq_lseek 94 .llseek = seq_lseek
148}; 95};
149 96
150void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, 97int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
151 struct brcmf_sdio_count *sdcnt) 98 int (*read_fn)(struct seq_file *seq, void *data))
152{ 99{
153 struct dentry *dentry = drvr->dbgfs_dir; 100 struct dentry *dentry = drvr->dbgfs_dir;
101 struct brcmf_debugfs_entry *entry;
154 102
155 if (!IS_ERR_OR_NULL(dentry)) 103 if (IS_ERR_OR_NULL(dentry))
156 debugfs_create_file("counters", S_IRUGO, dentry, 104 return -ENOENT;
157 sdcnt, &brcmf_debugfs_sdio_counter_ops);
158}
159 105
160static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data) 106 entry = devm_kzalloc(drvr->bus_if->dev, sizeof(*entry), GFP_KERNEL);
161{ 107 if (!entry)
162 struct brcmf_fws_stats *fwstats = seq->private; 108 return -ENOMEM;
163
164 seq_printf(seq,
165 "header_pulls: %u\n"
166 "header_only_pkt: %u\n"
167 "tlv_parse_failed: %u\n"
168 "tlv_invalid_type: %u\n"
169 "mac_update_fails: %u\n"
170 "ps_update_fails: %u\n"
171 "if_update_fails: %u\n"
172 "pkt2bus: %u\n"
173 "generic_error: %u\n"
174 "rollback_success: %u\n"
175 "rollback_failed: %u\n"
176 "delayq_full: %u\n"
177 "supprq_full: %u\n"
178 "txs_indicate: %u\n"
179 "txs_discard: %u\n"
180 "txs_suppr_core: %u\n"
181 "txs_suppr_ps: %u\n"
182 "txs_tossed: %u\n"
183 "txs_host_tossed: %u\n"
184 "bus_flow_block: %u\n"
185 "fws_flow_block: %u\n"
186 "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n"
187 "requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
188 fwstats->header_pulls,
189 fwstats->header_only_pkt,
190 fwstats->tlv_parse_failed,
191 fwstats->tlv_invalid_type,
192 fwstats->mac_update_failed,
193 fwstats->mac_ps_update_failed,
194 fwstats->if_update_failed,
195 fwstats->pkt2bus,
196 fwstats->generic_error,
197 fwstats->rollback_success,
198 fwstats->rollback_failed,
199 fwstats->delayq_full_error,
200 fwstats->supprq_full_error,
201 fwstats->txs_indicate,
202 fwstats->txs_discard,
203 fwstats->txs_supp_core,
204 fwstats->txs_supp_ps,
205 fwstats->txs_tossed,
206 fwstats->txs_host_tossed,
207 fwstats->bus_flow_block,
208 fwstats->fws_flow_block,
209 fwstats->send_pkts[0], fwstats->send_pkts[1],
210 fwstats->send_pkts[2], fwstats->send_pkts[3],
211 fwstats->send_pkts[4],
212 fwstats->requested_sent[0],
213 fwstats->requested_sent[1],
214 fwstats->requested_sent[2],
215 fwstats->requested_sent[3],
216 fwstats->requested_sent[4]);
217 109
218 return 0; 110 entry->read = read_fn;
219} 111 entry->drvr = drvr;
220 112
221static int brcmf_debugfs_fws_stats_open(struct inode *inode, struct file *f) 113 dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry,
222{ 114 &brcmf_debugfs_def_ops);
223 return single_open(f, brcmf_debugfs_fws_stats_read, inode->i_private);
224}
225
226static const struct file_operations brcmf_debugfs_fws_stats_ops = {
227 .owner = THIS_MODULE,
228 .open = brcmf_debugfs_fws_stats_open,
229 .release = single_release,
230 .read = seq_read,
231 .llseek = seq_lseek
232};
233
234void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
235 struct brcmf_fws_stats *stats)
236{
237 struct dentry *dentry = drvr->dbgfs_dir;
238 115
239 if (!IS_ERR_OR_NULL(dentry)) 116 return PTR_ERR_OR_ZERO(dentry);
240 debugfs_create_file("fws_stats", S_IRUGO, dentry,
241 stats, &brcmf_debugfs_fws_stats_ops);
242} 117}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index ef52ed7abc69..6eade7c60c63 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -100,68 +100,6 @@ do { \
100 100
101extern int brcmf_msg_level; 101extern int brcmf_msg_level;
102 102
103/*
104 * hold counter variables used in brcmfmac sdio driver.
105 */
106struct brcmf_sdio_count {
107 uint intrcount; /* Count of device interrupt callbacks */
108 uint lastintrs; /* Count as of last watchdog timer */
109 uint pollcnt; /* Count of active polls */
110 uint regfails; /* Count of R_REG failures */
111 uint tx_sderrs; /* Count of tx attempts with sd errors */
112 uint fcqueued; /* Tx packets that got queued */
113 uint rxrtx; /* Count of rtx requests (NAK to dongle) */
114 uint rx_toolong; /* Receive frames too long to receive */
115 uint rxc_errors; /* SDIO errors when reading control frames */
116 uint rx_hdrfail; /* SDIO errors on header reads */
117 uint rx_badhdr; /* Bad received headers (roosync?) */
118 uint rx_badseq; /* Mismatched rx sequence number */
119 uint fc_rcvd; /* Number of flow-control events received */
120 uint fc_xoff; /* Number which turned on flow-control */
121 uint fc_xon; /* Number which turned off flow-control */
122 uint rxglomfail; /* Failed deglom attempts */
123 uint rxglomframes; /* Number of glom frames (superframes) */
124 uint rxglompkts; /* Number of packets from glom frames */
125 uint f2rxhdrs; /* Number of header reads */
126 uint f2rxdata; /* Number of frame data reads */
127 uint f2txdata; /* Number of f2 frame writes */
128 uint f1regdata; /* Number of f1 register accesses */
129 uint tickcnt; /* Number of watchdog been schedule */
130 ulong tx_ctlerrs; /* Err of sending ctrl frames */
131 ulong tx_ctlpkts; /* Ctrl frames sent to dongle */
132 ulong rx_ctlerrs; /* Err of processing rx ctrl frames */
133 ulong rx_ctlpkts; /* Ctrl frames processed from dongle */
134 ulong rx_readahead_cnt; /* packets where header read-ahead was used */
135};
136
137struct brcmf_fws_stats {
138 u32 tlv_parse_failed;
139 u32 tlv_invalid_type;
140 u32 header_only_pkt;
141 u32 header_pulls;
142 u32 pkt2bus;
143 u32 send_pkts[5];
144 u32 requested_sent[5];
145 u32 generic_error;
146 u32 mac_update_failed;
147 u32 mac_ps_update_failed;
148 u32 if_update_failed;
149 u32 packet_request_failed;
150 u32 credit_request_failed;
151 u32 rollback_success;
152 u32 rollback_failed;
153 u32 delayq_full_error;
154 u32 supprq_full_error;
155 u32 txs_indicate;
156 u32 txs_discard;
157 u32 txs_supp_core;
158 u32 txs_supp_ps;
159 u32 txs_tossed;
160 u32 txs_host_tossed;
161 u32 bus_flow_block;
162 u32 fws_flow_block;
163};
164
165struct brcmf_pub; 103struct brcmf_pub;
166#ifdef DEBUG 104#ifdef DEBUG
167void brcmf_debugfs_init(void); 105void brcmf_debugfs_init(void);
@@ -169,10 +107,8 @@ void brcmf_debugfs_exit(void);
169int brcmf_debugfs_attach(struct brcmf_pub *drvr); 107int brcmf_debugfs_attach(struct brcmf_pub *drvr);
170void brcmf_debugfs_detach(struct brcmf_pub *drvr); 108void brcmf_debugfs_detach(struct brcmf_pub *drvr);
171struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr); 109struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
172void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, 110int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
173 struct brcmf_sdio_count *sdcnt); 111 int (*read_fn)(struct seq_file *seq, void *data));
174void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
175 struct brcmf_fws_stats *stats);
176#else 112#else
177static inline void brcmf_debugfs_init(void) 113static inline void brcmf_debugfs_init(void)
178{ 114{
@@ -187,9 +123,11 @@ static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr)
187static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr) 123static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr)
188{ 124{
189} 125}
190static inline void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr, 126static inline
191 struct brcmf_fws_stats *stats) 127int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
128 int (*read_fn)(struct seq_file *seq, void *data))
192{ 129{
130 return 0;
193} 131}
194#endif 132#endif
195 133
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 0c98a7942a0f..c0486329331b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -391,6 +391,40 @@ struct brcmf_sdio_hdrinfo {
391 u16 tail_pad; 391 u16 tail_pad;
392}; 392};
393 393
394/*
395 * hold counter variables
396 */
397struct brcmf_sdio_count {
398 uint intrcount; /* Count of device interrupt callbacks */
399 uint lastintrs; /* Count as of last watchdog timer */
400 uint pollcnt; /* Count of active polls */
401 uint regfails; /* Count of R_REG failures */
402 uint tx_sderrs; /* Count of tx attempts with sd errors */
403 uint fcqueued; /* Tx packets that got queued */
404 uint rxrtx; /* Count of rtx requests (NAK to dongle) */
405 uint rx_toolong; /* Receive frames too long to receive */
406 uint rxc_errors; /* SDIO errors when reading control frames */
407 uint rx_hdrfail; /* SDIO errors on header reads */
408 uint rx_badhdr; /* Bad received headers (roosync?) */
409 uint rx_badseq; /* Mismatched rx sequence number */
410 uint fc_rcvd; /* Number of flow-control events received */
411 uint fc_xoff; /* Number which turned on flow-control */
412 uint fc_xon; /* Number which turned off flow-control */
413 uint rxglomfail; /* Failed deglom attempts */
414 uint rxglomframes; /* Number of glom frames (superframes) */
415 uint rxglompkts; /* Number of packets from glom frames */
416 uint f2rxhdrs; /* Number of header reads */
417 uint f2rxdata; /* Number of frame data reads */
418 uint f2txdata; /* Number of f2 frame writes */
419 uint f1regdata; /* Number of f1 register accesses */
420 uint tickcnt; /* Number of watchdog been schedule */
421 ulong tx_ctlerrs; /* Err of sending ctrl frames */
422 ulong tx_ctlpkts; /* Ctrl frames sent to dongle */
423 ulong rx_ctlerrs; /* Err of processing rx ctrl frames */
424 ulong rx_ctlpkts; /* Ctrl frames processed from dongle */
425 ulong rx_readahead_cnt; /* packets where header read-ahead was used */
426};
427
394/* misc chip info needed by some of the routines */ 428/* misc chip info needed by some of the routines */
395/* Private data for SDIO bus interaction */ 429/* Private data for SDIO bus interaction */
396struct brcmf_sdio { 430struct brcmf_sdio {
@@ -3070,23 +3104,50 @@ done:
3070 3104
3071static int brcmf_sdio_forensic_read(struct seq_file *seq, void *data) 3105static int brcmf_sdio_forensic_read(struct seq_file *seq, void *data)
3072{ 3106{
3073 struct brcmf_sdio *bus = seq->private; 3107 struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
3108 struct brcmf_sdio *bus = bus_if->bus_priv.sdio->bus;
3074 3109
3075 return brcmf_sdio_died_dump(seq, bus); 3110 return brcmf_sdio_died_dump(seq, bus);
3076} 3111}
3077 3112
3078static int brcmf_sdio_forensic_open(struct inode *inode, struct file *f) 3113static int brcmf_debugfs_sdio_count_read(struct seq_file *seq, void *data)
3079{ 3114{
3080 return single_open(f, brcmf_sdio_forensic_read, inode->i_private); 3115 struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
3081} 3116 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
3117 struct brcmf_sdio_count *sdcnt = &sdiodev->bus->sdcnt;
3082 3118
3083static const struct file_operations brcmf_sdio_forensic_ops = { 3119 seq_printf(seq,
3084 .owner = THIS_MODULE, 3120 "intrcount: %u\nlastintrs: %u\n"
3085 .open = brcmf_sdio_forensic_open, 3121 "pollcnt: %u\nregfails: %u\n"
3086 .release = single_release, 3122 "tx_sderrs: %u\nfcqueued: %u\n"
3087 .read = seq_read, 3123 "rxrtx: %u\nrx_toolong: %u\n"
3088 .llseek = seq_lseek 3124 "rxc_errors: %u\nrx_hdrfail: %u\n"
3089}; 3125 "rx_badhdr: %u\nrx_badseq: %u\n"
3126 "fc_rcvd: %u\nfc_xoff: %u\n"
3127 "fc_xon: %u\nrxglomfail: %u\n"
3128 "rxglomframes: %u\nrxglompkts: %u\n"
3129 "f2rxhdrs: %u\nf2rxdata: %u\n"
3130 "f2txdata: %u\nf1regdata: %u\n"
3131 "tickcnt: %u\ntx_ctlerrs: %lu\n"
3132 "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n"
3133 "rx_ctlpkts: %lu\nrx_readahead: %lu\n",
3134 sdcnt->intrcount, sdcnt->lastintrs,
3135 sdcnt->pollcnt, sdcnt->regfails,
3136 sdcnt->tx_sderrs, sdcnt->fcqueued,
3137 sdcnt->rxrtx, sdcnt->rx_toolong,
3138 sdcnt->rxc_errors, sdcnt->rx_hdrfail,
3139 sdcnt->rx_badhdr, sdcnt->rx_badseq,
3140 sdcnt->fc_rcvd, sdcnt->fc_xoff,
3141 sdcnt->fc_xon, sdcnt->rxglomfail,
3142 sdcnt->rxglomframes, sdcnt->rxglompkts,
3143 sdcnt->f2rxhdrs, sdcnt->f2rxdata,
3144 sdcnt->f2txdata, sdcnt->f1regdata,
3145 sdcnt->tickcnt, sdcnt->tx_ctlerrs,
3146 sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs,
3147 sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt);
3148
3149 return 0;
3150}
3090 3151
3091static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) 3152static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
3092{ 3153{
@@ -3096,9 +3157,9 @@ static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
3096 if (IS_ERR_OR_NULL(dentry)) 3157 if (IS_ERR_OR_NULL(dentry))
3097 return; 3158 return;
3098 3159
3099 debugfs_create_file("forensics", S_IRUGO, dentry, bus, 3160 brcmf_debugfs_add_entry(drvr, "forensics", brcmf_sdio_forensic_read);
3100 &brcmf_sdio_forensic_ops); 3161 brcmf_debugfs_add_entry(drvr, "counters",
3101 brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt); 3162 brcmf_debugfs_sdio_count_read);
3102 debugfs_create_u32("console_interval", 0644, dentry, 3163 debugfs_create_u32("console_interval", 0644, dentry,
3103 &bus->console_interval); 3164 &bus->console_interval);
3104} 3165}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 699908de314a..d42f7d04b65f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -454,6 +454,34 @@ struct brcmf_fws_macdesc_table {
454 struct brcmf_fws_mac_descriptor other; 454 struct brcmf_fws_mac_descriptor other;
455}; 455};
456 456
457struct brcmf_fws_stats {
458 u32 tlv_parse_failed;
459 u32 tlv_invalid_type;
460 u32 header_only_pkt;
461 u32 header_pulls;
462 u32 pkt2bus;
463 u32 send_pkts[5];
464 u32 requested_sent[5];
465 u32 generic_error;
466 u32 mac_update_failed;
467 u32 mac_ps_update_failed;
468 u32 if_update_failed;
469 u32 packet_request_failed;
470 u32 credit_request_failed;
471 u32 rollback_success;
472 u32 rollback_failed;
473 u32 delayq_full_error;
474 u32 supprq_full_error;
475 u32 txs_indicate;
476 u32 txs_discard;
477 u32 txs_supp_core;
478 u32 txs_supp_ps;
479 u32 txs_tossed;
480 u32 txs_host_tossed;
481 u32 bus_flow_block;
482 u32 fws_flow_block;
483};
484
457struct brcmf_fws_info { 485struct brcmf_fws_info {
458 struct brcmf_pub *drvr; 486 struct brcmf_pub *drvr;
459 spinlock_t spinlock; 487 spinlock_t spinlock;
@@ -2017,6 +2045,75 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
2017 brcmf_fws_unlock(fws); 2045 brcmf_fws_unlock(fws);
2018} 2046}
2019 2047
2048#ifdef DEBUG
2049static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data)
2050{
2051 struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
2052 struct brcmf_fws_stats *fwstats = &bus_if->drvr->fws->stats;
2053
2054 seq_printf(seq,
2055 "header_pulls: %u\n"
2056 "header_only_pkt: %u\n"
2057 "tlv_parse_failed: %u\n"
2058 "tlv_invalid_type: %u\n"
2059 "mac_update_fails: %u\n"
2060 "ps_update_fails: %u\n"
2061 "if_update_fails: %u\n"
2062 "pkt2bus: %u\n"
2063 "generic_error: %u\n"
2064 "rollback_success: %u\n"
2065 "rollback_failed: %u\n"
2066 "delayq_full: %u\n"
2067 "supprq_full: %u\n"
2068 "txs_indicate: %u\n"
2069 "txs_discard: %u\n"
2070 "txs_suppr_core: %u\n"
2071 "txs_suppr_ps: %u\n"
2072 "txs_tossed: %u\n"
2073 "txs_host_tossed: %u\n"
2074 "bus_flow_block: %u\n"
2075 "fws_flow_block: %u\n"
2076 "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n"
2077 "requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
2078 fwstats->header_pulls,
2079 fwstats->header_only_pkt,
2080 fwstats->tlv_parse_failed,
2081 fwstats->tlv_invalid_type,
2082 fwstats->mac_update_failed,
2083 fwstats->mac_ps_update_failed,
2084 fwstats->if_update_failed,
2085 fwstats->pkt2bus,
2086 fwstats->generic_error,
2087 fwstats->rollback_success,
2088 fwstats->rollback_failed,
2089 fwstats->delayq_full_error,
2090 fwstats->supprq_full_error,
2091 fwstats->txs_indicate,
2092 fwstats->txs_discard,
2093 fwstats->txs_supp_core,
2094 fwstats->txs_supp_ps,
2095 fwstats->txs_tossed,
2096 fwstats->txs_host_tossed,
2097 fwstats->bus_flow_block,
2098 fwstats->fws_flow_block,
2099 fwstats->send_pkts[0], fwstats->send_pkts[1],
2100 fwstats->send_pkts[2], fwstats->send_pkts[3],
2101 fwstats->send_pkts[4],
2102 fwstats->requested_sent[0],
2103 fwstats->requested_sent[1],
2104 fwstats->requested_sent[2],
2105 fwstats->requested_sent[3],
2106 fwstats->requested_sent[4]);
2107
2108 return 0;
2109}
2110#else
2111static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data)
2112{
2113 return 0;
2114}
2115#endif
2116
2020int brcmf_fws_init(struct brcmf_pub *drvr) 2117int brcmf_fws_init(struct brcmf_pub *drvr)
2021{ 2118{
2022 struct brcmf_fws_info *fws; 2119 struct brcmf_fws_info *fws;
@@ -2107,7 +2204,8 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
2107 BRCMF_FWS_PSQ_LEN); 2204 BRCMF_FWS_PSQ_LEN);
2108 2205
2109 /* create debugfs file for statistics */ 2206 /* create debugfs file for statistics */
2110 brcmf_debugfs_create_fws_stats(drvr, &fws->stats); 2207 brcmf_debugfs_add_entry(drvr, "fws_stats",
2208 brcmf_debugfs_fws_stats_read);
2111 2209
2112 brcmf_dbg(INFO, "%s bdcv2 tlv signaling [%x]\n", 2210 brcmf_dbg(INFO, "%s bdcv2 tlv signaling [%x]\n",
2113 fws->fw_signals ? "enabled" : "disabled", tlv); 2211 fws->fw_signals ? "enabled" : "disabled", tlv);