aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-06-19 13:33:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-26 16:49:18 -0400
commit6bbc321a96d4d3533eb136b981baba6c8248d635 (patch)
tree6458968538ebe0c1cf3f65adab9fd9b0ea4e3439
parent8bd463f4f913db12a1b7374f84304631289a1e0b (diff)
b43: Add debugfs files for random SHM access
This adds debugfs files for random SHM access. This is needed in order to implement firmware and driver debugging scripts in userspace. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/b43/debugfs.c178
-rw-r--r--drivers/net/wireless/b43/debugfs.h11
-rw-r--r--drivers/net/wireless/b43/main.c58
-rw-r--r--drivers/net/wireless/b43/main.h4
4 files changed, 234 insertions, 17 deletions
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index 9cdd9eca0822..dd40ad826c78 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -74,6 +74,168 @@ struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev,
74 } while (0) 74 } while (0)
75 75
76 76
77/* The biggest address values for SHM access from the debugfs files. */
78#define B43_MAX_SHM_ROUTING 4
79#define B43_MAX_SHM_ADDR 0xFFFF
80
81static ssize_t shm16read__read_file(struct b43_wldev *dev,
82 char *buf, size_t bufsize)
83{
84 ssize_t count = 0;
85 unsigned int routing, addr;
86 u16 val;
87
88 routing = dev->dfsentry->shm16read_routing_next;
89 addr = dev->dfsentry->shm16read_addr_next;
90 if ((routing > B43_MAX_SHM_ROUTING) ||
91 (addr > B43_MAX_SHM_ADDR))
92 return -EDESTADDRREQ;
93
94 val = b43_shm_read16(dev, routing, addr);
95 fappend("0x%04X\n", val);
96
97 return count;
98}
99
100static int shm16read__write_file(struct b43_wldev *dev,
101 const char *buf, size_t count)
102{
103 unsigned int routing, addr;
104 int res;
105
106 res = sscanf(buf, "0x%X 0x%X", &routing, &addr);
107 if (res != 2)
108 return -EINVAL;
109 if (routing > B43_MAX_SHM_ROUTING)
110 return -EADDRNOTAVAIL;
111 if (addr > B43_MAX_SHM_ADDR)
112 return -EADDRNOTAVAIL;
113 if (routing == B43_SHM_SHARED) {
114 if ((addr % 2) != 0)
115 return -EADDRNOTAVAIL;
116 }
117
118 dev->dfsentry->shm16read_routing_next = routing;
119 dev->dfsentry->shm16read_addr_next = addr;
120
121 return 0;
122}
123
124static int shm16write__write_file(struct b43_wldev *dev,
125 const char *buf, size_t count)
126{
127 unsigned int routing, addr, mask, set;
128 u16 val;
129 int res;
130 unsigned long flags;
131
132 res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
133 &routing, &addr, &mask, &set);
134 if (res != 4)
135 return -EINVAL;
136 if (routing > B43_MAX_SHM_ROUTING)
137 return -EADDRNOTAVAIL;
138 if (addr > B43_MAX_SHM_ADDR)
139 return -EADDRNOTAVAIL;
140 if (routing == B43_SHM_SHARED) {
141 if ((addr % 2) != 0)
142 return -EADDRNOTAVAIL;
143 }
144 if ((mask > 0xFFFF) || (set > 0xFFFF))
145 return -E2BIG;
146
147 spin_lock_irqsave(&dev->wl->shm_lock, flags);
148 if (mask == 0)
149 val = 0;
150 else
151 val = __b43_shm_read16(dev, routing, addr);
152 val &= mask;
153 val |= set;
154 __b43_shm_write16(dev, routing, addr, val);
155 spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
156
157 return 0;
158}
159
160static ssize_t shm32read__read_file(struct b43_wldev *dev,
161 char *buf, size_t bufsize)
162{
163 ssize_t count = 0;
164 unsigned int routing, addr;
165 u32 val;
166
167 routing = dev->dfsentry->shm32read_routing_next;
168 addr = dev->dfsentry->shm32read_addr_next;
169 if ((routing > B43_MAX_SHM_ROUTING) ||
170 (addr > B43_MAX_SHM_ADDR))
171 return -EDESTADDRREQ;
172
173 val = b43_shm_read32(dev, routing, addr);
174 fappend("0x%08X\n", val);
175
176 return count;
177}
178
179static int shm32read__write_file(struct b43_wldev *dev,
180 const char *buf, size_t count)
181{
182 unsigned int routing, addr;
183 int res;
184
185 res = sscanf(buf, "0x%X 0x%X", &routing, &addr);
186 if (res != 2)
187 return -EINVAL;
188 if (routing > B43_MAX_SHM_ROUTING)
189 return -EADDRNOTAVAIL;
190 if (addr > B43_MAX_SHM_ADDR)
191 return -EADDRNOTAVAIL;
192 if (routing == B43_SHM_SHARED) {
193 if ((addr % 2) != 0)
194 return -EADDRNOTAVAIL;
195 }
196
197 dev->dfsentry->shm32read_routing_next = routing;
198 dev->dfsentry->shm32read_addr_next = addr;
199
200 return 0;
201}
202
203static int shm32write__write_file(struct b43_wldev *dev,
204 const char *buf, size_t count)
205{
206 unsigned int routing, addr, mask, set;
207 u32 val;
208 int res;
209 unsigned long flags;
210
211 res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
212 &routing, &addr, &mask, &set);
213 if (res != 4)
214 return -EINVAL;
215 if (routing > B43_MAX_SHM_ROUTING)
216 return -EADDRNOTAVAIL;
217 if (addr > B43_MAX_SHM_ADDR)
218 return -EADDRNOTAVAIL;
219 if (routing == B43_SHM_SHARED) {
220 if ((addr % 2) != 0)
221 return -EADDRNOTAVAIL;
222 }
223 if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF))
224 return -E2BIG;
225
226 spin_lock_irqsave(&dev->wl->shm_lock, flags);
227 if (mask == 0)
228 val = 0;
229 else
230 val = __b43_shm_read32(dev, routing, addr);
231 val &= mask;
232 val |= set;
233 __b43_shm_write32(dev, routing, addr, val);
234 spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
235
236 return 0;
237}
238
77/* The biggest MMIO address that we allow access to from the debugfs files. */ 239/* The biggest MMIO address that we allow access to from the debugfs files. */
78#define B43_MAX_MMIO_ACCESS (0xF00 - 1) 240#define B43_MAX_MMIO_ACCESS (0xF00 - 1)
79 241
@@ -605,6 +767,10 @@ out_unlock:
605 .take_irqlock = _take_irqlock, \ 767 .take_irqlock = _take_irqlock, \
606 } 768 }
607 769
770B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file, 1);
771B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file, 1);
772B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file, 1);
773B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file, 1);
608B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1); 774B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1);
609B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1); 775B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
610B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1); 776B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
@@ -699,6 +865,10 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
699 865
700 e->mmio16read_next = 0xFFFF; /* invalid address */ 866 e->mmio16read_next = 0xFFFF; /* invalid address */
701 e->mmio32read_next = 0xFFFF; /* invalid address */ 867 e->mmio32read_next = 0xFFFF; /* invalid address */
868 e->shm16read_routing_next = 0xFFFFFFFF; /* invalid routing */
869 e->shm16read_addr_next = 0xFFFFFFFF; /* invalid address */
870 e->shm32read_routing_next = 0xFFFFFFFF; /* invalid routing */
871 e->shm32read_addr_next = 0xFFFFFFFF; /* invalid address */
702 872
703#define ADD_FILE(name, mode) \ 873#define ADD_FILE(name, mode) \
704 do { \ 874 do { \
@@ -712,6 +882,10 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
712 } while (0) 882 } while (0)
713 883
714 884
885 ADD_FILE(shm16read, 0600);
886 ADD_FILE(shm16write, 0200);
887 ADD_FILE(shm32read, 0600);
888 ADD_FILE(shm32write, 0200);
715 ADD_FILE(mmio16read, 0600); 889 ADD_FILE(mmio16read, 0600);
716 ADD_FILE(mmio16write, 0200); 890 ADD_FILE(mmio16write, 0200);
717 ADD_FILE(mmio32read, 0600); 891 ADD_FILE(mmio32read, 0600);
@@ -740,6 +914,10 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
740 return; 914 return;
741 b43_remove_dynamic_debug(dev); 915 b43_remove_dynamic_debug(dev);
742 916
917 debugfs_remove(e->file_shm16read.dentry);
918 debugfs_remove(e->file_shm16write.dentry);
919 debugfs_remove(e->file_shm32read.dentry);
920 debugfs_remove(e->file_shm32write.dentry);
743 debugfs_remove(e->file_mmio16read.dentry); 921 debugfs_remove(e->file_mmio16read.dentry);
744 debugfs_remove(e->file_mmio16write.dentry); 922 debugfs_remove(e->file_mmio16write.dentry);
745 debugfs_remove(e->file_mmio32read.dentry); 923 debugfs_remove(e->file_mmio32read.dentry);
diff --git a/drivers/net/wireless/b43/debugfs.h b/drivers/net/wireless/b43/debugfs.h
index d6848696cee0..f06f7bc1edce 100644
--- a/drivers/net/wireless/b43/debugfs.h
+++ b/drivers/net/wireless/b43/debugfs.h
@@ -36,6 +36,10 @@ struct b43_dfsentry {
36 struct b43_wldev *dev; 36 struct b43_wldev *dev;
37 struct dentry *subdir; 37 struct dentry *subdir;
38 38
39 struct b43_dfs_file file_shm16read;
40 struct b43_dfs_file file_shm16write;
41 struct b43_dfs_file file_shm32read;
42 struct b43_dfs_file file_shm32write;
39 struct b43_dfs_file file_mmio16read; 43 struct b43_dfs_file file_mmio16read;
40 struct b43_dfs_file file_mmio16write; 44 struct b43_dfs_file file_mmio16write;
41 struct b43_dfs_file file_mmio32read; 45 struct b43_dfs_file file_mmio32read;
@@ -55,6 +59,13 @@ struct b43_dfsentry {
55 /* The cached address for the next mmio32read file read */ 59 /* The cached address for the next mmio32read file read */
56 u16 mmio32read_next; 60 u16 mmio32read_next;
57 61
62 /* The cached address for the next shm16read file read */
63 u32 shm16read_routing_next;
64 u32 shm16read_addr_next;
65 /* The cached address for the next shm32read file read */
66 u32 shm32read_routing_next;
67 u32 shm32read_addr_next;
68
58 /* Enabled/Disabled list for the dynamic debugging features. */ 69 /* Enabled/Disabled list for the dynamic debugging features. */
59 u32 dyn_debug[__B43_NR_DYNDBG]; 70 u32 dyn_debug[__B43_NR_DYNDBG];
60 /* Dentries for the dynamic debugging entries. */ 71 /* Dentries for the dynamic debugging entries. */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 7bca8e981512..69272b9bdb69 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -373,13 +373,10 @@ static inline void b43_shm_control_word(struct b43_wldev *dev,
373 b43_write32(dev, B43_MMIO_SHM_CONTROL, control); 373 b43_write32(dev, B43_MMIO_SHM_CONTROL, control);
374} 374}
375 375
376u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) 376u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
377{ 377{
378 struct b43_wl *wl = dev->wl;
379 unsigned long flags;
380 u32 ret; 378 u32 ret;
381 379
382 spin_lock_irqsave(&wl->shm_lock, flags);
383 if (routing == B43_SHM_SHARED) { 380 if (routing == B43_SHM_SHARED) {
384 B43_WARN_ON(offset & 0x0001); 381 B43_WARN_ON(offset & 0x0001);
385 if (offset & 0x0003) { 382 if (offset & 0x0003) {
@@ -397,18 +394,26 @@ u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
397 b43_shm_control_word(dev, routing, offset); 394 b43_shm_control_word(dev, routing, offset);
398 ret = b43_read32(dev, B43_MMIO_SHM_DATA); 395 ret = b43_read32(dev, B43_MMIO_SHM_DATA);
399out: 396out:
400 spin_unlock_irqrestore(&wl->shm_lock, flags);
401
402 return ret; 397 return ret;
403} 398}
404 399
405u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset) 400u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
406{ 401{
407 struct b43_wl *wl = dev->wl; 402 struct b43_wl *wl = dev->wl;
408 unsigned long flags; 403 unsigned long flags;
409 u16 ret; 404 u32 ret;
410 405
411 spin_lock_irqsave(&wl->shm_lock, flags); 406 spin_lock_irqsave(&wl->shm_lock, flags);
407 ret = __b43_shm_read32(dev, routing, offset);
408 spin_unlock_irqrestore(&wl->shm_lock, flags);
409
410 return ret;
411}
412
413u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
414{
415 u16 ret;
416
412 if (routing == B43_SHM_SHARED) { 417 if (routing == B43_SHM_SHARED) {
413 B43_WARN_ON(offset & 0x0001); 418 B43_WARN_ON(offset & 0x0001);
414 if (offset & 0x0003) { 419 if (offset & 0x0003) {
@@ -423,17 +428,24 @@ u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset)
423 b43_shm_control_word(dev, routing, offset); 428 b43_shm_control_word(dev, routing, offset);
424 ret = b43_read16(dev, B43_MMIO_SHM_DATA); 429 ret = b43_read16(dev, B43_MMIO_SHM_DATA);
425out: 430out:
426 spin_unlock_irqrestore(&wl->shm_lock, flags);
427
428 return ret; 431 return ret;
429} 432}
430 433
431void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) 434u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
432{ 435{
433 struct b43_wl *wl = dev->wl; 436 struct b43_wl *wl = dev->wl;
434 unsigned long flags; 437 unsigned long flags;
438 u16 ret;
435 439
436 spin_lock_irqsave(&wl->shm_lock, flags); 440 spin_lock_irqsave(&wl->shm_lock, flags);
441 ret = __b43_shm_read16(dev, routing, offset);
442 spin_unlock_irqrestore(&wl->shm_lock, flags);
443
444 return ret;
445}
446
447void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
448{
437 if (routing == B43_SHM_SHARED) { 449 if (routing == B43_SHM_SHARED) {
438 B43_WARN_ON(offset & 0x0001); 450 B43_WARN_ON(offset & 0x0001);
439 if (offset & 0x0003) { 451 if (offset & 0x0003) {
@@ -443,35 +455,47 @@ void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
443 (value >> 16) & 0xffff); 455 (value >> 16) & 0xffff);
444 b43_shm_control_word(dev, routing, (offset >> 2) + 1); 456 b43_shm_control_word(dev, routing, (offset >> 2) + 1);
445 b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff); 457 b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff);
446 goto out; 458 return;
447 } 459 }
448 offset >>= 2; 460 offset >>= 2;
449 } 461 }
450 b43_shm_control_word(dev, routing, offset); 462 b43_shm_control_word(dev, routing, offset);
451 b43_write32(dev, B43_MMIO_SHM_DATA, value); 463 b43_write32(dev, B43_MMIO_SHM_DATA, value);
452out:
453 spin_unlock_irqrestore(&wl->shm_lock, flags);
454} 464}
455 465
456void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value) 466void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
457{ 467{
458 struct b43_wl *wl = dev->wl; 468 struct b43_wl *wl = dev->wl;
459 unsigned long flags; 469 unsigned long flags;
460 470
461 spin_lock_irqsave(&wl->shm_lock, flags); 471 spin_lock_irqsave(&wl->shm_lock, flags);
472 __b43_shm_write32(dev, routing, offset, value);
473 spin_unlock_irqrestore(&wl->shm_lock, flags);
474}
475
476void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
477{
462 if (routing == B43_SHM_SHARED) { 478 if (routing == B43_SHM_SHARED) {
463 B43_WARN_ON(offset & 0x0001); 479 B43_WARN_ON(offset & 0x0001);
464 if (offset & 0x0003) { 480 if (offset & 0x0003) {
465 /* Unaligned access */ 481 /* Unaligned access */
466 b43_shm_control_word(dev, routing, offset >> 2); 482 b43_shm_control_word(dev, routing, offset >> 2);
467 b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value); 483 b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value);
468 goto out; 484 return;
469 } 485 }
470 offset >>= 2; 486 offset >>= 2;
471 } 487 }
472 b43_shm_control_word(dev, routing, offset); 488 b43_shm_control_word(dev, routing, offset);
473 b43_write16(dev, B43_MMIO_SHM_DATA, value); 489 b43_write16(dev, B43_MMIO_SHM_DATA, value);
474out: 490}
491
492void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
493{
494 struct b43_wl *wl = dev->wl;
495 unsigned long flags;
496
497 spin_lock_irqsave(&wl->shm_lock, flags);
498 __b43_shm_write16(dev, routing, offset, value);
475 spin_unlock_irqrestore(&wl->shm_lock, flags); 499 spin_unlock_irqrestore(&wl->shm_lock, flags);
476} 500}
477 501
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index dad23c42b422..f871a252cb55 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -95,9 +95,13 @@ void b43_tsf_read(struct b43_wldev *dev, u64 * tsf);
95void b43_tsf_write(struct b43_wldev *dev, u64 tsf); 95void b43_tsf_write(struct b43_wldev *dev, u64 tsf);
96 96
97u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset); 97u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
98u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
98u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset); 99u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
100u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
99void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value); 101void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
102void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
100void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value); 103void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
104void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
101 105
102u64 b43_hf_read(struct b43_wldev *dev); 106u64 b43_hf_read(struct b43_wldev *dev);
103void b43_hf_write(struct b43_wldev *dev, u64 value); 107void b43_hf_write(struct b43_wldev *dev, u64 value);