aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKalle Valo <kvalo@qca.qualcomm.com>2011-09-27 16:33:28 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2011-09-28 12:03:47 -0400
commit9a7308341b71f3c5e88e6a30f9d6a1cfb3bc2b4f (patch)
treedda46b7616fe1866d1efa07fc5cee5330be7e783 /drivers
parent1b4304da0adcc31727da3ee7f89dd180f4e65473 (diff)
ath6kl: silence "invalid rate" warning
For some reason firmware is sending invalid rates when we try to query current bitrate from ath6kl_get_station() and a warning is issued: [ 3810.415720] ath6kl: invalid rate: 1935633515 [ 3811.105493] ath6kl: invalid rate: 1935633515 [ 3811.556063] ath6kl: invalid rate: 1935633515 As the warning happens way too often, convert the warning to a debug message once we have a proper fix. But to make it easy to follow how often the problem appears, add a debugfs to print various statistics about workarounds and make this issue the first WAR. Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c4
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h4
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.c48
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.h9
4 files changed, 64 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index c84f53d6523b..8d9fbd4a62b7 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1365,7 +1365,9 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1365 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 1365 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1366 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; 1366 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1367 } else { 1367 } else {
1368 ath6kl_warn("invalid rate: %d\n", rate); 1368 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1369 "invalid rate from stats: %d\n", rate);
1370 ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1369 return 0; 1371 return 0;
1370 } 1372 }
1371 1373
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 9ecf22bd4fc9..6d8a4845baaf 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -525,6 +525,10 @@ struct ath6kl {
525 unsigned int dbgfs_diag_reg; 525 unsigned int dbgfs_diag_reg;
526 u32 diag_reg_addr_wr; 526 u32 diag_reg_addr_wr;
527 u32 diag_reg_val_wr; 527 u32 diag_reg_val_wr;
528
529 struct {
530 unsigned int invalid_rate;
531 } war_stats;
528 } debug; 532 } debug;
529#endif /* CONFIG_ATH6KL_DEBUG */ 533#endif /* CONFIG_ATH6KL_DEBUG */
530}; 534};
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 4fc83ccbf8bd..5237369cd521 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -192,6 +192,51 @@ static int ath6kl_debugfs_open(struct inode *inode, struct file *file)
192 return 0; 192 return 0;
193} 193}
194 194
195void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war)
196{
197 switch (war) {
198 case ATH6KL_WAR_INVALID_RATE:
199 ar->debug.war_stats.invalid_rate++;
200 break;
201 }
202}
203
204static ssize_t read_file_war_stats(struct file *file, char __user *user_buf,
205 size_t count, loff_t *ppos)
206{
207 struct ath6kl *ar = file->private_data;
208 char *buf;
209 unsigned int len = 0, buf_len = 1500;
210 ssize_t ret_cnt;
211
212 buf = kzalloc(buf_len, GFP_KERNEL);
213 if (!buf)
214 return -ENOMEM;
215
216 len += scnprintf(buf + len, buf_len - len, "\n");
217 len += scnprintf(buf + len, buf_len - len, "%25s\n",
218 "Workaround stats");
219 len += scnprintf(buf + len, buf_len - len, "%25s\n\n",
220 "=================");
221 len += scnprintf(buf + len, buf_len - len, "%20s %10u\n",
222 "Invalid rates", ar->debug.war_stats.invalid_rate);
223
224 if (WARN_ON(len > buf_len))
225 len = buf_len;
226
227 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
228
229 kfree(buf);
230 return ret_cnt;
231}
232
233static const struct file_operations fops_war_stats = {
234 .read = read_file_war_stats,
235 .open = ath6kl_debugfs_open,
236 .owner = THIS_MODULE,
237 .llseek = default_llseek,
238};
239
195static void ath6kl_debug_fwlog_add(struct ath6kl *ar, const void *buf, 240static void ath6kl_debug_fwlog_add(struct ath6kl *ar, const void *buf,
196 size_t buf_len) 241 size_t buf_len)
197{ 242{
@@ -873,6 +918,9 @@ int ath6kl_debug_init(struct ath6kl *ar)
873 debugfs_create_file("reg_write", S_IRUSR | S_IWUSR, 918 debugfs_create_file("reg_write", S_IRUSR | S_IWUSR,
874 ar->debugfs_phy, ar, &fops_diag_reg_write); 919 ar->debugfs_phy, ar, &fops_diag_reg_write);
875 920
921 debugfs_create_file("war_stats", S_IRUSR, ar->debugfs_phy, ar,
922 &fops_war_stats);
923
876 return 0; 924 return 0;
877} 925}
878 926
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index 89bf8e1138a3..91f4bc35f968 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -52,6 +52,10 @@ extern int ath6kl_printk(const char *level, const char *fmt, ...)
52 52
53#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask) 53#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask)
54 54
55enum ath6kl_war {
56 ATH6KL_WAR_INVALID_RATE,
57};
58
55#ifdef CONFIG_ATH6KL_DEBUG 59#ifdef CONFIG_ATH6KL_DEBUG
56#define ath6kl_dbg(mask, fmt, ...) \ 60#define ath6kl_dbg(mask, fmt, ...) \
57 ({ \ 61 ({ \
@@ -79,6 +83,7 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
79 struct ath6kl_irq_enable_reg *irq_en_reg); 83 struct ath6kl_irq_enable_reg *irq_en_reg);
80void dump_cred_dist_stats(struct htc_target *target); 84void dump_cred_dist_stats(struct htc_target *target);
81void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len); 85void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len);
86void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war);
82int ath6kl_debug_init(struct ath6kl *ar); 87int ath6kl_debug_init(struct ath6kl *ar);
83void ath6kl_debug_cleanup(struct ath6kl *ar); 88void ath6kl_debug_cleanup(struct ath6kl *ar);
84 89
@@ -110,6 +115,10 @@ static inline void ath6kl_debug_fwlog_event(struct ath6kl *ar,
110{ 115{
111} 116}
112 117
118static inline void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war)
119{
120}
121
113static inline int ath6kl_debug_init(struct ath6kl *ar) 122static inline int ath6kl_debug_init(struct ath6kl *ar)
114{ 123{
115 return 0; 124 return 0;