/[linux-patches]/genpatches-2.6/tags/2.6.18-9/1000_linux-2.6.18.1.patch
Gentoo

Contents of /genpatches-2.6/tags/2.6.18-9/1000_linux-2.6.18.1.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 802 - (show annotations) (download)
Wed Jan 10 14:47:23 2007 UTC (11 years, 8 months ago) by dsd
File size: 256813 byte(s)
2.6.18-9 release
1 diff --git a/Documentation/dontdiff b/Documentation/dontdiff
2 index 24adfe9..63c2d0c 100644
3 --- a/Documentation/dontdiff
4 +++ b/Documentation/dontdiff
5 @@ -135,6 +135,7 @@ tags
6 times.h*
7 tkparse
8 trix_boot.h
9 +utsrelease.h*
10 version.h*
11 vmlinux
12 vmlinux-*
13 diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
14 index 7cee902..20d0d79 100644
15 --- a/Documentation/sysctl/vm.txt
16 +++ b/Documentation/sysctl/vm.txt
17 @@ -29,6 +29,7 @@ Currently, these files are in /proc/sys/
18 - drop-caches
19 - zone_reclaim_mode
20 - min_unmapped_ratio
21 +- min_slab_ratio
22 - panic_on_oom
23
24 ==============================================================
25 @@ -138,7 +139,6 @@ This is value ORed together of
26 1 = Zone reclaim on
27 2 = Zone reclaim writes dirty pages out
28 4 = Zone reclaim swaps pages
29 -8 = Also do a global slab reclaim pass
30
31 zone_reclaim_mode is set during bootup to 1 if it is determined that pages
32 from remote zones will cause a measurable performance reduction. The
33 @@ -162,18 +162,13 @@ Allowing regular swap effectively restri
34 node unless explicitly overridden by memory policies or cpuset
35 configurations.
36
37 -It may be advisable to allow slab reclaim if the system makes heavy
38 -use of files and builds up large slab caches. However, the slab
39 -shrink operation is global, may take a long time and free slabs
40 -in all nodes of the system.
41 -
42 =============================================================
43
44 min_unmapped_ratio:
45
46 This is available only on NUMA kernels.
47
48 -A percentage of the file backed pages in each zone. Zone reclaim will only
49 +A percentage of the total pages in each zone. Zone reclaim will only
50 occur if more than this percentage of pages are file backed and unmapped.
51 This is to insure that a minimal amount of local pages is still available for
52 file I/O even if the node is overallocated.
53 @@ -182,6 +177,24 @@ The default is 1 percent.
54
55 =============================================================
56
57 +min_slab_ratio:
58 +
59 +This is available only on NUMA kernels.
60 +
61 +A percentage of the total pages in each zone. On Zone reclaim
62 +(fallback from the local zone occurs) slabs will be reclaimed if more
63 +than this percentage of pages in a zone are reclaimable slab pages.
64 +This insures that the slab growth stays under control even in NUMA
65 +systems that rarely perform global reclaim.
66 +
67 +The default is 5 percent.
68 +
69 +Note that slab reclaim is triggered in a per zone / node fashion.
70 +The process of reclaiming slab memory is currently not node specific
71 +and may not be fast.
72 +
73 +=============================================================
74 +
75 panic_on_oom
76
77 This enables or disables panic on out-of-memory feature. If this is set to 1,
78 diff --git a/Makefile b/Makefile
79 index edfc2fd..b803595 100644
80 --- a/Makefile
81 +++ b/Makefile
82 @@ -894,6 +894,9 @@ export INSTALL_HDR_PATH
83
84 PHONY += headers_install
85 headers_install: include/linux/version.h
86 + @if [ ! -r include/asm-$(ARCH)/Kbuild ]; then \
87 + echo '*** Error: Headers not exportable for this architecture ($(ARCH))'; \
88 + exit 1 ; fi
89 $(Q)unifdef -Ux /dev/null
90 $(Q)rm -rf $(INSTALL_HDR_PATH)/include
91 $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.headersinst obj=include
92 @@ -1076,13 +1079,17 @@ help:
93 @echo ' cscope - Generate cscope index'
94 @echo ' kernelrelease - Output the release version string'
95 @echo ' kernelversion - Output the version stored in Makefile'
96 - @echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'
97 + @if [ -r include/asm-$(ARCH)/Kbuild ]; then \
98 + echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \
99 + fi
100 @echo ' (default: $(INSTALL_HDR_PATH))'
101 @echo ''
102 @echo 'Static analysers'
103 @echo ' checkstack - Generate a list of stack hogs'
104 @echo ' namespacecheck - Name space analysis on compiled kernel'
105 - @echo ' headers_check - Sanity check on exported headers'
106 + @if [ -r include/asm-$(ARCH)/Kbuild ]; then \
107 + echo ' headers_check - Sanity check on exported headers'; \
108 + fi
109 @echo ''
110 @echo 'Kernel packaging:'
111 @$(MAKE) $(build)=$(package-dir) help
112 diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
113 index f948419..efe0799 100644
114 --- a/arch/i386/kernel/smpboot.c
115 +++ b/arch/i386/kernel/smpboot.c
116 @@ -642,9 +642,13 @@ static void map_cpu_to_logical_apicid(vo
117 {
118 int cpu = smp_processor_id();
119 int apicid = logical_smp_processor_id();
120 + int node = apicid_to_node(apicid);
121 +
122 + if (!node_online(node))
123 + node = first_online_node;
124
125 cpu_2_logical_apicid[cpu] = apicid;
126 - map_cpu_to_node(cpu, apicid_to_node(apicid));
127 + map_cpu_to_node(cpu, node);
128 }
129
130 static void unmap_cpu_to_logical_apicid(int cpu)
131 diff --git a/arch/i386/mm/boot_ioremap.c b/arch/i386/mm/boot_ioremap.c
132 index 5d44f4f..5cf739a 100644
133 --- a/arch/i386/mm/boot_ioremap.c
134 +++ b/arch/i386/mm/boot_ioremap.c
135 @@ -29,8 +29,11 @@ #include <linux/stddef.h>
136 */
137
138 #define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
139 -#define boot_pte_index(address) \
140 - (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1))
141 +
142 +static unsigned long boot_pte_index(unsigned long vaddr)
143 +{
144 + return __pa(vaddr) >> PAGE_SHIFT;
145 +}
146
147 static inline boot_pte_t* boot_vaddr_to_pte(void *address)
148 {
149 diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
150 index 0176556..32c3abe 100644
151 --- a/arch/ia64/kernel/acpi.c
152 +++ b/arch/ia64/kernel/acpi.c
153 @@ -771,16 +771,19 @@ int acpi_map_cpu2node(acpi_handle handle
154 {
155 #ifdef CONFIG_ACPI_NUMA
156 int pxm_id;
157 + int nid;
158
159 pxm_id = acpi_get_pxm(handle);
160 -
161 /*
162 - * Assuming that the container driver would have set the proximity
163 - * domain and would have initialized pxm_to_node(pxm_id) && pxm_flag
164 + * We don't have cpu-only-node hotadd. But if the system equips
165 + * SRAT table, pxm is already found and node is ready.
166 + * So, just pxm_to_nid(pxm) is OK.
167 + * This code here is for the system which doesn't have full SRAT
168 + * table for possible cpus.
169 */
170 - node_cpuid[cpu].nid = (pxm_id < 0) ? 0 : pxm_to_node(pxm_id);
171 -
172 + nid = acpi_map_pxm_to_node(pxm_id);
173 node_cpuid[cpu].phys_id = physid;
174 + node_cpuid[cpu].nid = nid;
175 #endif
176 return (0);
177 }
178 diff --git a/arch/ia64/kernel/numa.c b/arch/ia64/kernel/numa.c
179 index 1cc360c..2034063 100644
180 --- a/arch/ia64/kernel/numa.c
181 +++ b/arch/ia64/kernel/numa.c
182 @@ -29,6 +29,36 @@ EXPORT_SYMBOL(cpu_to_node_map);
183
184 cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
185
186 +void __cpuinit map_cpu_to_node(int cpu, int nid)
187 +{
188 + int oldnid;
189 + if (nid < 0) { /* just initialize by zero */
190 + cpu_to_node_map[cpu] = 0;
191 + return;
192 + }
193 + /* sanity check first */
194 + oldnid = cpu_to_node_map[cpu];
195 + if (cpu_isset(cpu, node_to_cpu_mask[oldnid])) {
196 + return; /* nothing to do */
197 + }
198 + /* we don't have cpu-driven node hot add yet...
199 + In usual case, node is created from SRAT at boot time. */
200 + if (!node_online(nid))
201 + nid = first_online_node;
202 + cpu_to_node_map[cpu] = nid;
203 + cpu_set(cpu, node_to_cpu_mask[nid]);
204 + return;
205 +}
206 +
207 +void __cpuinit unmap_cpu_from_node(int cpu, int nid)
208 +{
209 + WARN_ON(!cpu_isset(cpu, node_to_cpu_mask[nid]));
210 + WARN_ON(cpu_to_node_map[cpu] != nid);
211 + cpu_to_node_map[cpu] = 0;
212 + cpu_clear(cpu, node_to_cpu_mask[nid]);
213 +}
214 +
215 +
216 /**
217 * build_cpu_to_node_map - setup cpu to node and node to cpumask arrays
218 *
219 @@ -49,8 +79,6 @@ void __init build_cpu_to_node_map(void)
220 node = node_cpuid[i].nid;
221 break;
222 }
223 - cpu_to_node_map[cpu] = (node >= 0) ? node : 0;
224 - if (node >= 0)
225 - cpu_set(cpu, node_to_cpu_mask[node]);
226 + map_cpu_to_node(cpu, node);
227 }
228 }
229 diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
230 index f648c61..5629b45 100644
231 --- a/arch/ia64/kernel/topology.c
232 +++ b/arch/ia64/kernel/topology.c
233 @@ -36,6 +36,7 @@ #if defined (CONFIG_ACPI) && defined (CO
234 */
235 if (!can_cpei_retarget() && is_cpu_cpei_target(num))
236 sysfs_cpus[num].cpu.no_control = 1;
237 + map_cpu_to_node(num, node_cpuid[num].nid);
238 #endif
239
240 return register_cpu(&sysfs_cpus[num].cpu, num);
241 @@ -45,7 +46,8 @@ #ifdef CONFIG_HOTPLUG_CPU
242
243 void arch_unregister_cpu(int num)
244 {
245 - return unregister_cpu(&sysfs_cpus[num].cpu);
246 + unregister_cpu(&sysfs_cpus[num].cpu);
247 + unmap_cpu_from_node(num, cpu_to_node(num));
248 }
249 EXPORT_SYMBOL(arch_register_cpu);
250 EXPORT_SYMBOL(arch_unregister_cpu);
251 diff --git a/arch/s390/lib/uaccess.S b/arch/s390/lib/uaccess.S
252 index 8372752..3f5511d 100644
253 --- a/arch/s390/lib/uaccess.S
254 +++ b/arch/s390/lib/uaccess.S
255 @@ -40,7 +40,17 @@ __copy_from_user_asm:
256 # move with the reduced length which is < 256
257 5: mvcp 0(%r5,%r2),0(%r4),%r0
258 slr %r3,%r5
259 -6: lr %r2,%r3
260 + alr %r2,%r5
261 +6: lgr %r5,%r3 # copy remaining size
262 + ahi %r5,-1 # subtract 1 for xc loop
263 + bras %r4,8f
264 + xc 0(1,%2),0(%2)
265 +7: xc 0(256,%2),0(%2)
266 + la %r2,256(%r2)
267 +8: ahji %r5,-256
268 + jnm 7b
269 + ex %r5,0(%r2)
270 +9: lr %r2,%r3
271 br %r14
272 .section __ex_table,"a"
273 .long 0b,4b
274 diff --git a/arch/s390/lib/uaccess64.S b/arch/s390/lib/uaccess64.S
275 index 1f755be..9376df0 100644
276 --- a/arch/s390/lib/uaccess64.S
277 +++ b/arch/s390/lib/uaccess64.S
278 @@ -40,7 +40,17 @@ __copy_from_user_asm:
279 # move with the reduced length which is < 256
280 5: mvcp 0(%r5,%r2),0(%r4),%r0
281 slgr %r3,%r5
282 -6: lgr %r2,%r3
283 + algr %r2,%r5
284 +6: lgr %r5,%r3 # copy remaining size
285 + aghi %r5,-1 # subtract 1 for xc loop
286 + bras %r4,8f
287 + xc 0(1,%r2),0(%r2)
288 +7: xc 0(256,%r2),0(%r2)
289 + la %r2,256(%r2)
290 +8: aghi %r5,-256
291 + jnm 7b
292 + ex %r5,0(%r2)
293 +9: lgr %r2,%r3
294 br %r14
295 .section __ex_table,"a"
296 .quad 0b,4b
297 diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
298 index 22dc9c2..f203131 100644
299 --- a/arch/sh/kernel/process.c
300 +++ b/arch/sh/kernel/process.c
301 @@ -26,6 +26,7 @@ #include <asm/io.h>
302 #include <asm/uaccess.h>
303 #include <asm/mmu_context.h>
304 #include <asm/elf.h>
305 +#include <asm/ubc.h>
306
307 static int hlt_counter=0;
308
309 diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
310 index 094d3e3..b0b4fee 100644
311 --- a/arch/sparc64/kernel/time.c
312 +++ b/arch/sparc64/kernel/time.c
313 @@ -983,7 +983,7 @@ static struct time_interpolator sparc64_
314 };
315
316 /* The quotient formula is taken from the IA64 port. */
317 -#define SPARC64_NSEC_PER_CYC_SHIFT 30UL
318 +#define SPARC64_NSEC_PER_CYC_SHIFT 10UL
319 void __init time_init(void)
320 {
321 unsigned long clock = sparc64_init_timers();
322 diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
323 index dcba4e6..09cb7fc 100644
324 --- a/arch/sparc64/mm/init.c
325 +++ b/arch/sparc64/mm/init.c
326 @@ -920,8 +920,7 @@ #ifdef CONFIG_BLK_DEV_INITRD
327 if (sparc_ramdisk_image || sparc_ramdisk_image64) {
328 unsigned long ramdisk_image = sparc_ramdisk_image ?
329 sparc_ramdisk_image : sparc_ramdisk_image64;
330 - if (ramdisk_image >= (unsigned long)_end - 2 * PAGE_SIZE)
331 - ramdisk_image -= KERNBASE;
332 + ramdisk_image -= KERNBASE;
333 initrd_start = ramdisk_image + phys_base;
334 initrd_end = initrd_start + sparc_ramdisk_size;
335 if (initrd_end > end_of_phys_memory) {
336 diff --git a/arch/um/Kconfig b/arch/um/Kconfig
337 index 76e85bb..a8dbc61 100644
338 --- a/arch/um/Kconfig
339 +++ b/arch/um/Kconfig
340 @@ -1,3 +1,8 @@
341 +config DEFCONFIG_LIST
342 + string
343 + option defconfig_list
344 + default "arch/$ARCH/defconfig"
345 +
346 # UML uses the generic IRQ sugsystem
347 config GENERIC_HARDIRQS
348 bool
349 diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
350 index 9558a7c..3e9b347 100644
351 --- a/arch/um/Makefile-x86_64
352 +++ b/arch/um/Makefile-x86_64
353 @@ -1,7 +1,7 @@
354 # Copyright 2003 - 2004 Pathscale, Inc
355 # Released under the GPL
356
357 -core-y += arch/um/sys-x86_64/
358 +core-y += arch/um/sys-x86_64/ arch/x86_64/crypto/
359 START := 0x60000000
360
361 #We #undef __x86_64__ for kernelspace, not for userspace where
362 diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
363 index 356390d..39bb210 100644
364 --- a/arch/um/include/common-offsets.h
365 +++ b/arch/um/include/common-offsets.h
366 @@ -15,3 +15,4 @@ DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
367 DEFINE(UM_ELF_CLASS, ELF_CLASS);
368 DEFINE(UM_ELFCLASS32, ELFCLASS32);
369 DEFINE(UM_ELFCLASS64, ELFCLASS64);
370 +DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
371 diff --git a/arch/um/include/sysdep-i386/kernel-offsets.h b/arch/um/include/sysdep-i386/kernel-offsets.h
372 index 2c13de3..2e58c4c 100644
373 --- a/arch/um/include/sysdep-i386/kernel-offsets.h
374 +++ b/arch/um/include/sysdep-i386/kernel-offsets.h
375 @@ -1,6 +1,7 @@
376 #include <linux/stddef.h>
377 #include <linux/sched.h>
378 #include <linux/elf.h>
379 +#include <linux/crypto.h>
380 #include <asm/mman.h>
381
382 #define DEFINE(sym, val) \
383 diff --git a/arch/um/include/sysdep-x86_64/kernel-offsets.h b/arch/um/include/sysdep-x86_64/kernel-offsets.h
384 index 91d129f..4cbfbb9 100644
385 --- a/arch/um/include/sysdep-x86_64/kernel-offsets.h
386 +++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h
387 @@ -2,6 +2,7 @@ #include <linux/stddef.h>
388 #include <linux/sched.h>
389 #include <linux/time.h>
390 #include <linux/elf.h>
391 +#include <linux/crypto.h>
392 #include <asm/page.h>
393 #include <asm/mman.h>
394
395 diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
396 index b98d3ca..c8bf772 100644
397 --- a/arch/um/os-Linux/process.c
398 +++ b/arch/um/os-Linux/process.c
399 @@ -141,11 +141,9 @@ void os_usr1_process(int pid)
400 * syscalls, and also breaks with clone(), which does not unshare the TLS.
401 */
402
403 -inline _syscall0(pid_t, getpid)
404 -
405 int os_getpid(void)
406 {
407 - return(getpid());
408 + return syscall(__NR_getpid);
409 }
410
411 int os_getpgrp(void)
412 diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c
413 index 120abbe..64f547f 100644
414 --- a/arch/um/os-Linux/sys-i386/tls.c
415 +++ b/arch/um/os-Linux/sys-i386/tls.c
416 @@ -3,8 +3,6 @@ #include <linux/unistd.h>
417 #include "sysdep/tls.h"
418 #include "user_util.h"
419
420 -static _syscall1(int, get_thread_area, user_desc_t *, u_info);
421 -
422 /* Checks whether host supports TLS, and sets *tls_min according to the value
423 * valid on the host.
424 * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */
425 @@ -17,7 +15,7 @@ void check_host_supports_tls(int *suppor
426 user_desc_t info;
427 info.entry_number = val[i];
428
429 - if (get_thread_area(&info) == 0) {
430 + if(syscall(__NR_get_thread_area, &info) == 0){
431 *tls_min = val[i];
432 *supports_tls = 1;
433 return;
434 diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c
435 index 9cb09a4..297f263 100644
436 --- a/arch/um/os-Linux/tls.c
437 +++ b/arch/um/os-Linux/tls.c
438 @@ -48,14 +48,11 @@ #endif
439 #ifdef UML_CONFIG_MODE_TT
440 #include "linux/unistd.h"
441
442 -static _syscall1(int, get_thread_area, user_desc_t *, u_info);
443 -static _syscall1(int, set_thread_area, user_desc_t *, u_info);
444 -
445 int do_set_thread_area_tt(user_desc_t *info)
446 {
447 int ret;
448
449 - ret = set_thread_area(info);
450 + ret = syscall(__NR_set_thread_area, info);
451 if (ret < 0) {
452 ret = -errno;
453 }
454 @@ -66,7 +63,7 @@ int do_get_thread_area_tt(user_desc_t *i
455 {
456 int ret;
457
458 - ret = get_thread_area(info);
459 + ret = syscall(__NR_get_thread_area, info);
460 if (ret < 0) {
461 ret = -errno;
462 }
463 diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
464 index 146924b..53747fb 100644
465 --- a/arch/x86_64/kernel/pci-calgary.c
466 +++ b/arch/x86_64/kernel/pci-calgary.c
467 @@ -759,7 +759,16 @@ static inline unsigned int __init locate
468 int rionodeid;
469 u32 address;
470
471 - rionodeid = (dev->bus->number % 15 > 4) ? 3 : 2;
472 + /*
473 + * Each Calgary has four busses. The first four busses (first Calgary)
474 + * have RIO node ID 2, then the next four (second Calgary) have RIO
475 + * node ID 3, the next four (third Calgary) have node ID 2 again, etc.
476 + * We use a gross hack - relying on the dev->bus->number ordering,
477 + * modulo 14 - to decide which Calgary a given bus is on. Busses 0, 1,
478 + * 2 and 4 are on the first Calgary (id 2), 6, 8, a and c are on the
479 + * second (id 3), and then it repeats modulo 14.
480 + */
481 + rionodeid = (dev->bus->number % 14 > 4) ? 3 : 2;
482 /*
483 * register space address calculation as follows:
484 * FE0MB-8MB*OneBasedChassisNumber+1MB*(RioNodeId-ChassisBase)
485 @@ -767,7 +776,7 @@ static inline unsigned int __init locate
486 * RioNodeId is 2 for first Calgary, 3 for second Calgary
487 */
488 address = START_ADDRESS -
489 - (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 15)) +
490 + (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 14)) +
491 (0x100000) * (rionodeid - CHASSIS_BASE);
492 return address;
493 }
494 diff --git a/block/elevator.c b/block/elevator.c
495 index 9b72dc7..8ed2846 100644
496 --- a/block/elevator.c
497 +++ b/block/elevator.c
498 @@ -892,7 +892,7 @@ ssize_t elv_iosched_show(request_queue_t
499 struct list_head *entry;
500 int len = 0;
501
502 - spin_lock_irq(q->queue_lock);
503 + spin_lock_irq(&elv_list_lock);
504 list_for_each(entry, &elv_list) {
505 struct elevator_type *__e;
506
507 @@ -902,7 +902,7 @@ ssize_t elv_iosched_show(request_queue_t
508 else
509 len += sprintf(name+len, "%s ", __e->elevator_name);
510 }
511 - spin_unlock_irq(q->queue_lock);
512 + spin_unlock_irq(&elv_list_lock);
513
514 len += sprintf(len+name, "\n");
515 return len;
516 diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
517 index 6e6a7c7..ab6429b 100644
518 --- a/drivers/char/rtc.c
519 +++ b/drivers/char/rtc.c
520 @@ -209,11 +209,12 @@ static const unsigned char days_in_mo[]
521 */
522 static inline unsigned char rtc_is_updating(void)
523 {
524 + unsigned long flags;
525 unsigned char uip;
526
527 - spin_lock_irq(&rtc_lock);
528 + spin_lock_irqsave(&rtc_lock, flags);
529 uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
530 - spin_unlock_irq(&rtc_lock);
531 + spin_unlock_irqrestore(&rtc_lock, flags);
532 return uip;
533 }
534
535 diff --git a/drivers/clocksource/scx200_hrt.c b/drivers/clocksource/scx200_hrt.c
536 index d418b82..22915cc 100644
537 --- a/drivers/clocksource/scx200_hrt.c
538 +++ b/drivers/clocksource/scx200_hrt.c
539 @@ -63,7 +63,7 @@ static struct clocksource cs_hrt = {
540
541 static int __init init_hrt_clocksource(void)
542 {
543 - /* Make sure scx200 has initializedd the configuration block */
544 + /* Make sure scx200 has initialized the configuration block */
545 if (!scx200_cb_present())
546 return -ENODEV;
547
548 @@ -76,7 +76,7 @@ static int __init init_hrt_clocksource(v
549 }
550
551 /* write timer config */
552 - outb(HR_TMEN | (mhz27) ? HR_TMCLKSEL : 0,
553 + outb(HR_TMEN | (mhz27 ? HR_TMCLKSEL : 0),
554 scx200_cb_base + SCx200_TMCNFG_OFFSET);
555
556 if (mhz27) {
557 diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
558 index 25eee53..c2ecc59 100644
559 --- a/drivers/cpufreq/cpufreq_stats.c
560 +++ b/drivers/cpufreq/cpufreq_stats.c
561 @@ -350,12 +350,10 @@ __init cpufreq_stats_init(void)
562 }
563
564 register_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
565 - lock_cpu_hotplug();
566 for_each_online_cpu(cpu) {
567 cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_ONLINE,
568 (void *)(long)cpu);
569 }
570 - unlock_cpu_hotplug();
571 return 0;
572 }
573 static void
574 diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
575 index 78810ba..6a1ddad 100644
576 --- a/drivers/ide/pci/generic.c
577 +++ b/drivers/ide/pci/generic.c
578 @@ -245,10 +245,12 @@ static int __devinit generic_init_one(st
579 if (dev->vendor == PCI_VENDOR_ID_JMICRON && PCI_FUNC(dev->devfn) != 1)
580 goto out;
581
582 - pci_read_config_word(dev, PCI_COMMAND, &command);
583 - if (!(command & PCI_COMMAND_IO)) {
584 - printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name);
585 - goto out;
586 + if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
587 + pci_read_config_word(dev, PCI_COMMAND, &command);
588 + if (!(command & PCI_COMMAND_IO)) {
589 + printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name);
590 + goto out;
591 + }
592 }
593 ret = ide_setup_pci_device(dev, d);
594 out:
595 diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
596 index ebf961f..15b89e8 100644
597 --- a/drivers/ide/ppc/pmac.c
598 +++ b/drivers/ide/ppc/pmac.c
599 @@ -1326,7 +1326,7 @@ pmac_ide_macio_attach(struct macio_dev *
600 if (macio_irq_count(mdev) == 0) {
601 printk(KERN_WARNING "ide%d: no intrs for device %s, using 13\n",
602 i, mdev->ofdev.node->full_name);
603 - irq = 13;
604 + irq = irq_create_mapping(NULL, 13);
605 } else
606 irq = macio_irq(mdev, 0);
607
608 diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
609 index d9bc030..45e106f 100644
610 --- a/drivers/infiniband/hw/mthca/mthca_mad.c
611 +++ b/drivers/infiniband/hw/mthca/mthca_mad.c
612 @@ -119,7 +119,7 @@ static void smp_snoop(struct ib_device *
613
614 mthca_update_rate(to_mdev(ibdev), port_num);
615 update_sm_ah(to_mdev(ibdev), port_num,
616 - be16_to_cpu(pinfo->lid),
617 + be16_to_cpu(pinfo->sm_lid),
618 pinfo->neighbormtu_mastersmsl & 0xf);
619
620 event.device = ibdev;
621 diff --git a/drivers/md/md.c b/drivers/md/md.c
622 index 8dbab2e..c9d2919 100644
623 --- a/drivers/md/md.c
624 +++ b/drivers/md/md.c
625 @@ -3867,6 +3867,7 @@ static int hot_add_disk(mddev_t * mddev,
626 }
627 clear_bit(In_sync, &rdev->flags);
628 rdev->desc_nr = -1;
629 + rdev->saved_raid_disk = -1;
630 err = bind_rdev_to_array(rdev, mddev);
631 if (err)
632 goto abort_export;
633 diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
634 index 274a87b..1e7e790 100644
635 --- a/drivers/media/dvb/frontends/cx24123.c
636 +++ b/drivers/media/dvb/frontends/cx24123.c
637 @@ -549,8 +549,8 @@ static int cx24123_pll_calculate(struct
638 ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff;
639 adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f;
640
641 - if (adiv == 0)
642 - ndiv++;
643 + if (adiv == 0 && ndiv > 0)
644 + ndiv--;
645
646 /* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */
647 state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv;
648 diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
649 index 56246b8..cf43df3 100644
650 --- a/drivers/media/video/msp3400-driver.c
651 +++ b/drivers/media/video/msp3400-driver.c
652 @@ -904,6 +904,8 @@ static int msp_attach(struct i2c_adapter
653 state->has_virtual_dolby_surround = msp_revision == 'G' && msp_prod_lo == 1;
654 /* Has Virtual Dolby Surround & Dolby Pro Logic: only in msp34x2 */
655 state->has_dolby_pro_logic = msp_revision == 'G' && msp_prod_lo == 2;
656 + /* The msp343xG supports BTSC only and cannot do Automatic Standard Detection. */
657 + state->force_btsc = msp_family == 3 && msp_revision == 'G' && msp_prod_hi == 3;
658
659 state->opmode = opmode;
660 if (state->opmode == OPMODE_AUTO) {
661 diff --git a/drivers/media/video/msp3400-driver.h b/drivers/media/video/msp3400-driver.h
662 index 545e4ac..7531efa 100644
663 --- a/drivers/media/video/msp3400-driver.h
664 +++ b/drivers/media/video/msp3400-driver.h
665 @@ -64,6 +64,7 @@ struct msp_state {
666 u8 has_sound_processing;
667 u8 has_virtual_dolby_surround;
668 u8 has_dolby_pro_logic;
669 + u8 force_btsc;
670
671 int radio;
672 int opmode;
673 diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
674 index ed02ff8..4c7f85b 100644
675 --- a/drivers/media/video/msp3400-kthreads.c
676 +++ b/drivers/media/video/msp3400-kthreads.c
677 @@ -960,9 +960,10 @@ int msp34xxg_thread(void *data)
678
679 /* setup the chip*/
680 msp34xxg_reset(client);
681 - state->std = state->radio ? 0x40 : msp_standard;
682 - /* start autodetect */
683 + state->std = state->radio ? 0x40 :
684 + (state->force_btsc && msp_standard == 1) ? 32 : msp_standard;
685 msp_write_dem(client, 0x20, state->std);
686 + /* start autodetect */
687 if (state->std != 1)
688 goto unmute;
689
690 diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
691 index 7e727fe..e43a979 100644
692 --- a/drivers/media/video/pvrusb2/Kconfig
693 +++ b/drivers/media/video/pvrusb2/Kconfig
694 @@ -25,14 +25,9 @@ config VIDEO_PVRUSB2_24XXX
695 form "24xxx" (leading prefix of "24" followed by 3 digits).
696 To see if you may need this option, examine the white
697 sticker on the underside of your device. Enabling this
698 - option will not harm support for older devices, however it
699 - is a separate option because of the experimental nature of
700 - this new feature.
701 + option will not harm support for older devices.
702
703 - If you are in doubt, say N.
704 -
705 - Note: This feature is _very_ experimental. You have been
706 - warned.
707 + If you are in doubt, say Y.
708
709 config VIDEO_PVRUSB2_SYSFS
710 bool "pvrusb2 sysfs support (EXPERIMENTAL)"
711 diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
712 index fb6198f..c77de85 100644
713 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
714 +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
715 @@ -43,12 +43,17 @@ int pvr2_ctrl_set_mask_value(struct pvr2
716 if (cptr->info->type == pvr2_ctl_bitmask) {
717 mask &= cptr->info->def.type_bitmask.valid_bits;
718 } else if (cptr->info->type == pvr2_ctl_int) {
719 - if (val < cptr->info->def.type_int.min_value) {
720 - break;
721 + int lim;
722 + lim = cptr->info->def.type_int.min_value;
723 + if (cptr->info->get_min_value) {
724 + cptr->info->get_min_value(cptr,&lim);
725 }
726 - if (val > cptr->info->def.type_int.max_value) {
727 - break;
728 + if (val < lim) break;
729 + lim = cptr->info->def.type_int.max_value;
730 + if (cptr->info->get_max_value) {
731 + cptr->info->get_max_value(cptr,&lim);
732 }
733 + if (val > lim) break;
734 } else if (cptr->info->type == pvr2_ctl_enum) {
735 if (val >= cptr->info->def.type_enum.count) {
736 break;
737 @@ -91,7 +96,9 @@ int pvr2_ctrl_get_max(struct pvr2_ctrl *
738 int ret = 0;
739 if (!cptr) return 0;
740 LOCK_TAKE(cptr->hdw->big_lock); do {
741 - if (cptr->info->type == pvr2_ctl_int) {
742 + if (cptr->info->get_max_value) {
743 + cptr->info->get_max_value(cptr,&ret);
744 + } else if (cptr->info->type == pvr2_ctl_int) {
745 ret = cptr->info->def.type_int.max_value;
746 }
747 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
748 @@ -105,7 +112,9 @@ int pvr2_ctrl_get_min(struct pvr2_ctrl *
749 int ret = 0;
750 if (!cptr) return 0;
751 LOCK_TAKE(cptr->hdw->big_lock); do {
752 - if (cptr->info->type == pvr2_ctl_int) {
753 + if (cptr->info->get_min_value) {
754 + cptr->info->get_min_value(cptr,&ret);
755 + } else if (cptr->info->type == pvr2_ctl_int) {
756 ret = cptr->info->def.type_int.min_value;
757 }
758 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
759 diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
760 index 0d6dc33..9a72e6a 100644
761 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
762 +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
763 @@ -107,6 +107,8 @@ struct pvr2_ctl_info {
764
765 /* Control's implementation */
766 pvr2_ctlf_get_value get_value; /* Get its value */
767 + pvr2_ctlf_get_value get_min_value; /* Get minimum allowed value */
768 + pvr2_ctlf_get_value get_max_value; /* Get maximum allowed value */
769 pvr2_ctlf_set_value set_value; /* Set its value */
770 pvr2_ctlf_val_to_sym val_to_sym; /* Custom convert value->symbol */
771 pvr2_ctlf_sym_to_val sym_to_val; /* Custom convert symbol->value */
772 diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
773 index be1e5cc..a36a69d 100644
774 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
775 +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
776 @@ -362,6 +362,30 @@ static int ctrl_freq_set(struct pvr2_ctr
777 return 0;
778 }
779
780 +#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
781 +static int ctrl_hres_max_get(struct pvr2_ctrl *cptr,int *vp)
782 +{
783 + /* If we're dealing with a 24xxx device, force the horizontal
784 + maximum to be 720 no matter what, since we can't get the device
785 + to work properly with any other value. Otherwise just return
786 + the normal value. */
787 + *vp = cptr->info->def.type_int.max_value;
788 + if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720;
789 + return 0;
790 +}
791 +
792 +static int ctrl_hres_min_get(struct pvr2_ctrl *cptr,int *vp)
793 +{
794 + /* If we're dealing with a 24xxx device, force the horizontal
795 + minimum to be 720 no matter what, since we can't get the device
796 + to work properly with any other value. Otherwise just return
797 + the normal value. */
798 + *vp = cptr->info->def.type_int.min_value;
799 + if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720;
800 + return 0;
801 +}
802 +#endif
803 +
804 static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
805 {
806 return cptr->hdw->enc_stale != 0;
807 @@ -720,6 +744,12 @@ static const struct pvr2_ctl_info contro
808 .default_value = 720,
809 DEFREF(res_hor),
810 DEFINT(320,720),
811 +#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
812 + /* Hook in check for clamp on horizontal resolution in
813 + order to avoid unsolved problem involving cx25840. */
814 + .get_max_value = ctrl_hres_max_get,
815 + .get_min_value = ctrl_hres_min_get,
816 +#endif
817 },{
818 .desc = "Vertical capture resolution",
819 .name = "resolution_ver",
820 diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
821 index 0caf70b..72f444c 100644
822 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
823 +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
824 @@ -22,6 +22,7 @@
825
826 #include <linux/kernel.h>
827 #include <linux/version.h>
828 +#include <linux/videodev.h>
829 #include "pvrusb2-context.h"
830 #include "pvrusb2-hdw.h"
831 #include "pvrusb2.h"
832 @@ -31,25 +32,21 @@ #include "pvrusb2-ioread.h"
833 #include <linux/videodev2.h>
834 #include <media/v4l2-common.h>
835
836 +/* Mike Isely <isely@pobox.com> 23-Sep-2006 - This function is prototyped
837 + * only for V4L1 but is implemented regardless of the V4L1 compatibility
838 + * option state. V4L2 has no replacement for this and we need it. For now
839 + * copy the prototype here so we can avoid the compiler warning. */
840 +extern struct video_device* video_devdata(struct file*);
841 +
842 struct pvr2_v4l2_dev;
843 struct pvr2_v4l2_fh;
844 struct pvr2_v4l2;
845
846 -/* V4L no longer provide the ability to set / get a private context pointer
847 - (i.e. video_get_drvdata / video_set_drvdata), which means we have to
848 - concoct our own context locating mechanism. Supposedly this is intended
849 - to simplify driver implementation. It's not clear to me how that can
850 - possibly be true. Our solution here is to maintain a lookup table of
851 - our context instances, indexed by the minor device number of the V4L
852 - device. See pvr2_v4l2_open() for some implications of this approach. */
853 -static struct pvr2_v4l2_dev *devices[256];
854 -static DEFINE_MUTEX(device_lock);
855
856 struct pvr2_v4l2_dev {
857 struct pvr2_v4l2 *v4lp;
858 struct video_device *vdev;
859 struct pvr2_context_stream *stream;
860 - int ctxt_idx;
861 enum pvr2_config config;
862 };
863
864 @@ -459,18 +456,26 @@ static int pvr2_v4l2_do_ioctl(struct ino
865 ret = 0;
866 switch(vf->type) {
867 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
868 + int lmin,lmax;
869 + struct pvr2_ctrl *hcp,*vcp;
870 int h = vf->fmt.pix.height;
871 int w = vf->fmt.pix.width;
872 -
873 - if (h < 200) {
874 - h = 200;
875 - } else if (h > 625) {
876 - h = 625;
877 + hcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES);
878 + vcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES);
879 +
880 + lmin = pvr2_ctrl_get_min(hcp);
881 + lmax = pvr2_ctrl_get_max(hcp);
882 + if (w < lmin) {
883 + w = lmin;
884 + } else if (w > lmax) {
885 + w = lmax;
886 }
887 - if (w < 320) {
888 - w = 320;
889 - } else if (w > 720) {
890 - w = 720;
891 + lmin = pvr2_ctrl_get_min(vcp);
892 + lmax = pvr2_ctrl_get_max(vcp);
893 + if (h < lmin) {
894 + h = lmin;
895 + } else if (h > lmax) {
896 + h = lmax;
897 }
898
899 memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
900 @@ -479,14 +484,8 @@ static int pvr2_v4l2_do_ioctl(struct ino
901 vf->fmt.pix.height = h;
902
903 if (cmd == VIDIOC_S_FMT) {
904 - pvr2_ctrl_set_value(
905 - pvr2_hdw_get_ctrl_by_id(hdw,
906 - PVR2_CID_HRES),
907 - vf->fmt.pix.width);
908 - pvr2_ctrl_set_value(
909 - pvr2_hdw_get_ctrl_by_id(hdw,
910 - PVR2_CID_VRES),
911 - vf->fmt.pix.height);
912 + pvr2_ctrl_set_value(hcp,vf->fmt.pix.width);
913 + pvr2_ctrl_set_value(vcp,vf->fmt.pix.height);
914 }
915 } break;
916 case V4L2_BUF_TYPE_VBI_CAPTURE:
917 @@ -703,12 +702,6 @@ static void pvr2_v4l2_dev_destroy(struct
918 {
919 printk(KERN_INFO "pvrusb2: unregistering device video%d [%s]\n",
920 dip->vdev->minor,pvr2_config_get_name(dip->config));
921 - if (dip->ctxt_idx >= 0) {
922 - mutex_lock(&device_lock);
923 - devices[dip->ctxt_idx] = NULL;
924 - dip->ctxt_idx = -1;
925 - mutex_unlock(&device_lock);
926 - }
927 video_unregister_device(dip->vdev);
928 }
929
930 @@ -800,33 +793,10 @@ static int pvr2_v4l2_open(struct inode *
931 struct pvr2_v4l2 *vp;
932 struct pvr2_hdw *hdw;
933
934 - mutex_lock(&device_lock);
935 - /* MCI 7-Jun-2006 Even though we're just doing what amounts to an
936 - atomic read of the device mapping array here, we still need the
937 - mutex. The problem is that there is a tiny race possible when
938 - we register the device. We can't update the device mapping
939 - array until after the device has been registered, owing to the
940 - fact that we can't know the minor device number until after the
941 - registration succeeds. And if another thread tries to open the
942 - device in the window of time after registration but before the
943 - map is updated, then it will get back an erroneous null pointer
944 - and the open will result in a spurious failure. The only way to
945 - prevent that is to (a) be inside the mutex here before we access
946 - the array, and (b) cover the entire registration process later
947 - on with this same mutex. Thus if we get inside the mutex here,
948 - then we can be assured that the registration process actually
949 - completed correctly. This is an unhappy complication from the
950 - use of global data in a driver that lives in a preemptible
951 - environment. It sure would be nice if the video device itself
952 - had a means for storing and retrieving a local context pointer.
953 - Oh wait. It did. But now it's gone. Silly me. */
954 {
955 - unsigned int midx = iminor(file->f_dentry->d_inode);
956 - if (midx < sizeof(devices)/sizeof(devices[0])) {
957 - dip = devices[midx];
958 - }
959 + struct video_device *vdev = video_devdata(file);
960 + dip = (struct pvr2_v4l2_dev *)video_get_drvdata(vdev);
961 }
962 - mutex_unlock(&device_lock);
963
964 if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */
965
966 @@ -1066,7 +1036,7 @@ static void pvr2_v4l2_dev_init(struct pv
967
968 memcpy(dip->vdev,&vdev_template,sizeof(vdev_template));
969 dip->vdev->release = video_device_release;
970 - mutex_lock(&device_lock);
971 + video_set_drvdata(dip->vdev,dip);
972
973 mindevnum = -1;
974 unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw);
975 @@ -1081,12 +1051,6 @@ static void pvr2_v4l2_dev_init(struct pv
976 dip->vdev->minor,pvr2_config_get_name(dip->config));
977 }
978
979 - if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) &&
980 - (devices[dip->vdev->minor] == NULL)) {
981 - dip->ctxt_idx = dip->vdev->minor;
982 - devices[dip->ctxt_idx] = dip;
983 - }
984 - mutex_unlock(&device_lock);
985
986 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
987 dip->vdev->minor);
988 @@ -1100,7 +1064,6 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struc
989 vp = kmalloc(sizeof(*vp),GFP_KERNEL);
990 if (!vp) return vp;
991 memset(vp,0,sizeof(*vp));
992 - vp->video_dev.ctxt_idx = -1;
993 pvr2_channel_init(&vp->channel,mnp);
994 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
995
996 diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
997 index 88bf2af..2299e29 100644
998 --- a/drivers/media/video/videodev.c
999 +++ b/drivers/media/video/videodev.c
1000 @@ -739,13 +739,13 @@ static int __video_do_ioctl(struct inode
1001 case VIDIOC_DQBUF:
1002 {
1003 struct v4l2_buffer *p=arg;
1004 - if (!vfd->vidioc_qbuf)
1005 + if (!vfd->vidioc_dqbuf)
1006 break;
1007 ret = check_fmt (vfd, p->type);
1008 if (ret)
1009 break;
1010
1011 - ret=vfd->vidioc_qbuf(file, fh, p);
1012 + ret=vfd->vidioc_dqbuf(file, fh, p);
1013 if (!ret)
1014 dbgbuf(cmd,vfd,p);
1015 break;
1016 @@ -836,7 +836,7 @@ #endif
1017 break;
1018 }
1019
1020 - if (index<=0 || index >= vfd->tvnormsize) {
1021 + if (index < 0 || index >= vfd->tvnormsize) {
1022 ret=-EINVAL;
1023 break;
1024 }
1025 diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c
1026 index b783a69..393aba9 100644
1027 --- a/drivers/net/lp486e.c
1028 +++ b/drivers/net/lp486e.c
1029 @@ -442,16 +442,16 @@ #if 0
1030 if (rbd) {
1031 rbd->pad = 0;
1032 rbd->count = 0;
1033 - rbd->skb = dev_alloc_skb(RX_SKB_SIZE);
1034 + rbd->skb = dev_alloc_skb(RX_SKBSIZE);
1035 if (!rbd->skb) {
1036 printk("dev_alloc_skb failed");
1037 }
1038 rbd->next = rfd->rbd;
1039 if (i) {
1040 rfd->rbd->prev = rbd;
1041 - rbd->size = RX_SKB_SIZE;
1042 + rbd->size = RX_SKBSIZE;
1043 } else {
1044 - rbd->size = (RX_SKB_SIZE | RBD_EL);
1045 + rbd->size = (RX_SKBSIZE | RBD_EL);
1046 lp->rbd_tail = rbd;
1047 }
1048
1049 diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
1050 index eeab1df..59de3e7 100644
1051 --- a/drivers/net/mv643xx_eth.c
1052 +++ b/drivers/net/mv643xx_eth.c
1053 @@ -385,7 +385,7 @@ static int mv643xx_eth_receive_queue(str
1054 struct pkt_info pkt_info;
1055
1056 while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) {
1057 - dma_unmap_single(NULL, pkt_info.buf_ptr, RX_SKB_SIZE,
1058 + dma_unmap_single(NULL, pkt_info.buf_ptr, ETH_RX_SKB_SIZE,
1059 DMA_FROM_DEVICE);
1060 mp->rx_desc_count--;
1061 received_packets++;
1062 diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
1063 index 933e87f..c590c2d 100644
1064 --- a/drivers/net/sky2.c
1065 +++ b/drivers/net/sky2.c
1066 @@ -106,6 +106,7 @@ static const struct pci_device_id sky2_i
1067 { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
1068 { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
1069 { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */
1070 + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4001) }, /* DGE-550SX */
1071 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
1072 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
1073 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
1074 @@ -117,10 +118,17 @@ static const struct pci_device_id sky2_i
1075 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) },
1076 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) },
1077 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) },
1078 + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) },
1079 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) },
1080 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) },
1081 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) },
1082 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) },
1083 + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) },
1084 + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4365) },
1085 + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) },
1086 + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) },
1087 + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) },
1088 + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) },
1089 { 0 }
1090 };
1091
1092 diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
1093 index 2db8d19..ac5248b 100644
1094 --- a/drivers/net/sky2.h
1095 +++ b/drivers/net/sky2.h
1096 @@ -1566,7 +1566,7 @@ enum {
1097
1098 GMR_FS_ANY_ERR = GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR |
1099 GMR_FS_FRAGMENT | GMR_FS_LONG_ERR |
1100 - GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
1101 + GMR_FS_MII_ERR | GMR_FS_BAD_FC |
1102 GMR_FS_UN_SIZE | GMR_FS_JABBER,
1103 };
1104
1105 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
1106 index 17a5682..6d4ea36 100644
1107 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h
1108 +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
1109 @@ -33,14 +33,18 @@ #define BCM43xx_PCICFG_SPROMCTL 0x88
1110 #define BCM43xx_PCICFG_ICR 0x94
1111
1112 /* MMIO offsets */
1113 -#define BCM43xx_MMIO_DMA1_REASON 0x20
1114 -#define BCM43xx_MMIO_DMA1_IRQ_MASK 0x24
1115 -#define BCM43xx_MMIO_DMA2_REASON 0x28
1116 -#define BCM43xx_MMIO_DMA2_IRQ_MASK 0x2C
1117 -#define BCM43xx_MMIO_DMA3_REASON 0x30
1118 -#define BCM43xx_MMIO_DMA3_IRQ_MASK 0x34
1119 -#define BCM43xx_MMIO_DMA4_REASON 0x38
1120 -#define BCM43xx_MMIO_DMA4_IRQ_MASK 0x3C
1121 +#define BCM43xx_MMIO_DMA0_REASON 0x20
1122 +#define BCM43xx_MMIO_DMA0_IRQ_MASK 0x24
1123 +#define BCM43xx_MMIO_DMA1_REASON 0x28
1124 +#define BCM43xx_MMIO_DMA1_IRQ_MASK 0x2C
1125 +#define BCM43xx_MMIO_DMA2_REASON 0x30
1126 +#define BCM43xx_MMIO_DMA2_IRQ_MASK 0x34
1127 +#define BCM43xx_MMIO_DMA3_REASON 0x38
1128 +#define BCM43xx_MMIO_DMA3_IRQ_MASK 0x3C
1129 +#define BCM43xx_MMIO_DMA4_REASON 0x40
1130 +#define BCM43xx_MMIO_DMA4_IRQ_MASK 0x44
1131 +#define BCM43xx_MMIO_DMA5_REASON 0x48
1132 +#define BCM43xx_MMIO_DMA5_IRQ_MASK 0x4C
1133 #define BCM43xx_MMIO_STATUS_BITFIELD 0x120
1134 #define BCM43xx_MMIO_STATUS2_BITFIELD 0x124
1135 #define BCM43xx_MMIO_GEN_IRQ_REASON 0x128
1136 @@ -56,14 +60,27 @@ #define BCM43xx_MMIO_XMITSTAT_0 0x170
1137 #define BCM43xx_MMIO_XMITSTAT_1 0x174
1138 #define BCM43xx_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */
1139 #define BCM43xx_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */
1140 -#define BCM43xx_MMIO_DMA1_BASE 0x200
1141 -#define BCM43xx_MMIO_DMA2_BASE 0x220
1142 -#define BCM43xx_MMIO_DMA3_BASE 0x240
1143 -#define BCM43xx_MMIO_DMA4_BASE 0x260
1144 +
1145 +/* 32-bit DMA */
1146 +#define BCM43xx_MMIO_DMA32_BASE0 0x200
1147 +#define BCM43xx_MMIO_DMA32_BASE1 0x220
1148 +#define BCM43xx_MMIO_DMA32_BASE2 0x240
1149 +#define BCM43xx_MMIO_DMA32_BASE3 0x260
1150 +#define BCM43xx_MMIO_DMA32_BASE4 0x280
1151 +#define BCM43xx_MMIO_DMA32_BASE5 0x2A0
1152 +/* 64-bit DMA */
1153 +#define BCM43xx_MMIO_DMA64_BASE0 0x200
1154 +#define BCM43xx_MMIO_DMA64_BASE1 0x240
1155 +#define BCM43xx_MMIO_DMA64_BASE2 0x280
1156 +#define BCM43xx_MMIO_DMA64_BASE3 0x2C0
1157 +#define BCM43xx_MMIO_DMA64_BASE4 0x300
1158 +#define BCM43xx_MMIO_DMA64_BASE5 0x340
1159 +/* PIO */
1160 #define BCM43xx_MMIO_PIO1_BASE 0x300
1161 #define BCM43xx_MMIO_PIO2_BASE 0x310
1162 #define BCM43xx_MMIO_PIO3_BASE 0x320
1163 #define BCM43xx_MMIO_PIO4_BASE 0x330
1164 +
1165 #define BCM43xx_MMIO_PHY_VER 0x3E0
1166 #define BCM43xx_MMIO_PHY_RADIO 0x3E2
1167 #define BCM43xx_MMIO_ANTENNA 0x3E8
1168 @@ -233,8 +250,14 @@ #define BCM43xx_SBTMSTATELOW_CLOCK 0x10
1169 #define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK 0x20000
1170
1171 /* sbtmstatehigh state flags */
1172 -#define BCM43xx_SBTMSTATEHIGH_SERROR 0x1
1173 -#define BCM43xx_SBTMSTATEHIGH_BUSY 0x4
1174 +#define BCM43xx_SBTMSTATEHIGH_SERROR 0x00000001
1175 +#define BCM43xx_SBTMSTATEHIGH_BUSY 0x00000004
1176 +#define BCM43xx_SBTMSTATEHIGH_TIMEOUT 0x00000020
1177 +#define BCM43xx_SBTMSTATEHIGH_COREFLAGS 0x1FFF0000
1178 +#define BCM43xx_SBTMSTATEHIGH_DMA64BIT 0x10000000
1179 +#define BCM43xx_SBTMSTATEHIGH_GATEDCLK 0x20000000
1180 +#define BCM43xx_SBTMSTATEHIGH_BISTFAILED 0x40000000
1181 +#define BCM43xx_SBTMSTATEHIGH_BISTCOMPLETE 0x80000000
1182
1183 /* sbimstate flags */
1184 #define BCM43xx_SBIMSTATE_IB_ERROR 0x20000
1185 @@ -283,6 +306,13 @@ #define BCM43xx_SBF_NO_SSID_BCAST 0x0800
1186 #define BCM43xx_SBF_TIME_UPDATE 0x10000000
1187 #define BCM43xx_SBF_80000000 0x80000000 /*FIXME: fix name*/
1188
1189 +/* Microcode */
1190 +#define BCM43xx_UCODE_REVISION 0x0000
1191 +#define BCM43xx_UCODE_PATCHLEVEL 0x0002
1192 +#define BCM43xx_UCODE_DATE 0x0004
1193 +#define BCM43xx_UCODE_TIME 0x0006
1194 +#define BCM43xx_UCODE_STATUS 0x0040
1195 +
1196 /* MicrocodeFlagsBitfield (addr + lo-word values?)*/
1197 #define BCM43xx_UCODEFLAGS_OFFSET 0x005E
1198
1199 @@ -504,6 +534,12 @@ struct bcm43xx_phyinfo {
1200 * This lock is only used by bcm43xx_phy_{un}lock()
1201 */
1202 spinlock_t lock;
1203 +
1204 + /* Firmware. */
1205 + const struct firmware *ucode;
1206 + const struct firmware *pcm;
1207 + const struct firmware *initvals0;
1208 + const struct firmware *initvals1;
1209 };
1210
1211
1212 @@ -568,8 +604,11 @@ struct bcm43xx_dma {
1213 struct bcm43xx_dmaring *tx_ring1;
1214 struct bcm43xx_dmaring *tx_ring2;
1215 struct bcm43xx_dmaring *tx_ring3;
1216 + struct bcm43xx_dmaring *tx_ring4;
1217 + struct bcm43xx_dmaring *tx_ring5;
1218 +
1219 struct bcm43xx_dmaring *rx_ring0;
1220 - struct bcm43xx_dmaring *rx_ring1; /* only available on core.rev < 5 */
1221 + struct bcm43xx_dmaring *rx_ring3; /* only available on core.rev < 5 */
1222 };
1223
1224 /* Data structures for PIO transmission, per 80211 core. */
1225 @@ -593,12 +632,14 @@ struct bcm43xx_coreinfo {
1226 u8 available:1,
1227 enabled:1,
1228 initialized:1;
1229 - /** core_id ID number */
1230 - u16 id;
1231 /** core_rev revision number */
1232 u8 rev;
1233 /** Index number for _switch_core() */
1234 u8 index;
1235 + /** core_id ID number */
1236 + u16 id;
1237 + /** Core-specific data. */
1238 + void *priv;
1239 };
1240
1241 /* Additional information for each 80211 core. */
1242 @@ -647,7 +688,23 @@ enum {
1243 BCM43xx_STAT_RESTARTING, /* controller_restart() called. */
1244 };
1245 #define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status)
1246 -#define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat))
1247 +#define bcm43xx_set_status(bcm, stat) do { \
1248 + atomic_set(&(bcm)->init_status, (stat)); \
1249 + smp_wmb(); \
1250 + } while (0)
1251 +
1252 +/* *** THEORY OF LOCKING ***
1253 + *
1254 + * We have two different locks in the bcm43xx driver.
1255 + * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private
1256 + * and the device registers. This mutex does _not_ protect
1257 + * against concurrency from the IRQ handler.
1258 + * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
1259 + *
1260 + * Please note that, if you only take the irq_lock, you are not protected
1261 + * against concurrency from the periodic work handlers.
1262 + * Most times you want to take _both_ locks.
1263 + */
1264
1265 struct bcm43xx_private {
1266 struct ieee80211_device *ieee;
1267 @@ -659,7 +716,6 @@ struct bcm43xx_private {
1268
1269 void __iomem *mmio_addr;
1270
1271 - /* Locking, see "theory of locking" text below. */
1272 spinlock_t irq_lock;
1273 struct mutex mutex;
1274
1275 @@ -691,6 +747,7 @@ struct bcm43xx_private {
1276 struct bcm43xx_sprominfo sprom;
1277 #define BCM43xx_NR_LEDS 4
1278 struct bcm43xx_led leds[BCM43xx_NR_LEDS];
1279 + spinlock_t leds_lock;
1280
1281 /* The currently active core. */
1282 struct bcm43xx_coreinfo *current_core;
1283 @@ -708,10 +765,6 @@ #endif
1284 struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ];
1285 /* Additional information, specific to the 80211 cores. */
1286 struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ];
1287 - /* Index of the current 80211 core. If current_core is not
1288 - * an 80211 core, this is -1.
1289 - */
1290 - int current_80211_core_idx;
1291 /* Number of available 80211 cores. */
1292 int nr_80211_available;
1293
1294 @@ -719,11 +772,13 @@ #endif
1295
1296 /* Reason code of the last interrupt. */
1297 u32 irq_reason;
1298 - u32 dma_reason[4];
1299 + u32 dma_reason[6];
1300 /* saved irq enable/disable state bitfield. */
1301 u32 irq_savedstate;
1302 /* Link Quality calculation context. */
1303 struct bcm43xx_noise_calculation noisecalc;
1304 + /* if > 0 MAC is suspended. if == 0 MAC is enabled. */
1305 + int mac_suspended;
1306
1307 /* Threshold values. */
1308 //TODO: The RTS thr has to be _used_. Currently, it is only set via WX.
1309 @@ -746,12 +801,6 @@ #endif
1310 struct bcm43xx_key key[54];
1311 u8 default_key_idx;
1312
1313 - /* Firmware. */
1314 - const struct firmware *ucode;
1315 - const struct firmware *pcm;
1316 - const struct firmware *initvals0;
1317 - const struct firmware *initvals1;
1318 -
1319 /* Random Number Generator. */
1320 struct hwrng rng;
1321 char rng_name[20 + 1];
1322 @@ -763,55 +812,6 @@ #endif
1323 };
1324
1325
1326 -/* *** THEORY OF LOCKING ***
1327 - *
1328 - * We have two different locks in the bcm43xx driver.
1329 - * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private
1330 - * and the device registers.
1331 - * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
1332 - *
1333 - * We have three types of helper function pairs to utilize these locks.
1334 - * (Always use the helper functions.)
1335 - * 1) bcm43xx_{un}lock_noirq():
1336 - * Takes bcm->mutex. Does _not_ protect against IRQ concurrency,
1337 - * so it is almost always unsafe, if device IRQs are enabled.
1338 - * So only use this, if device IRQs are masked.
1339 - * Locking may sleep.
1340 - * You can sleep within the critical section.
1341 - * 2) bcm43xx_{un}lock_irqonly():
1342 - * Takes bcm->irq_lock. Does _not_ protect against
1343 - * bcm43xx_lock_noirq() critical sections.
1344 - * Does only protect against the IRQ handler path and other
1345 - * irqonly() critical sections.
1346 - * Locking does not sleep.
1347 - * You must not sleep within the critical section.
1348 - * 3) bcm43xx_{un}lock_irqsafe():
1349 - * This is the cummulative lock and takes both, mutex and irq_lock.
1350 - * Protects against noirq() and irqonly() critical sections (and
1351 - * the IRQ handler path).
1352 - * Locking may sleep.
1353 - * You must not sleep within the critical section.
1354 - */
1355 -
1356 -/* Lock type 1 */
1357 -#define bcm43xx_lock_noirq(bcm) mutex_lock(&(bcm)->mutex)
1358 -#define bcm43xx_unlock_noirq(bcm) mutex_unlock(&(bcm)->mutex)
1359 -/* Lock type 2 */
1360 -#define bcm43xx_lock_irqonly(bcm, flags) \
1361 - spin_lock_irqsave(&(bcm)->irq_lock, flags)
1362 -#define bcm43xx_unlock_irqonly(bcm, flags) \
1363 - spin_unlock_irqrestore(&(bcm)->irq_lock, flags)
1364 -/* Lock type 3 */
1365 -#define bcm43xx_lock_irqsafe(bcm, flags) do { \
1366 - bcm43xx_lock_noirq(bcm); \
1367 - bcm43xx_lock_irqonly(bcm, flags); \
1368 - } while (0)
1369 -#define bcm43xx_unlock_irqsafe(bcm, flags) do { \
1370 - bcm43xx_unlock_irqonly(bcm, flags); \
1371 - bcm43xx_unlock_noirq(bcm); \
1372 - } while (0)
1373 -
1374 -
1375 static inline
1376 struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
1377 {
1378 @@ -863,34 +863,33 @@ #endif
1379 * any of these functions.
1380 */
1381 static inline
1382 +struct bcm43xx_coreinfo_80211 *
1383 +bcm43xx_current_80211_priv(struct bcm43xx_private *bcm)
1384 +{
1385 + assert(bcm->current_core->id == BCM43xx_COREID_80211);
1386 + return bcm->current_core->priv;
1387 +}
1388 +static inline
1389 struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm)
1390 {
1391 assert(bcm43xx_using_pio(bcm));
1392 - assert(bcm->current_80211_core_idx >= 0);
1393 - assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
1394 - return &(bcm->core_80211_ext[bcm->current_80211_core_idx].pio);
1395 + return &(bcm43xx_current_80211_priv(bcm)->pio);
1396 }
1397 static inline
1398 struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm)
1399 {
1400 assert(!bcm43xx_using_pio(bcm));
1401 - assert(bcm->current_80211_core_idx >= 0);
1402 - assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
1403 - return &(bcm->core_80211_ext[bcm->current_80211_core_idx].dma);
1404 + return &(bcm43xx_current_80211_priv(bcm)->dma);
1405 }
1406 static inline
1407 struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm)
1408 {
1409 - assert(bcm->current_80211_core_idx >= 0);
1410 - assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
1411 - return &(bcm->core_80211_ext[bcm->current_80211_core_idx].phy);
1412 + return &(bcm43xx_current_80211_priv(bcm)->phy);
1413 }
1414 static inline
1415 struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
1416 {
1417 - assert(bcm->current_80211_core_idx >= 0);
1418 - assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
1419 - return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio);
1420 + return &(bcm43xx_current_80211_priv(bcm)->radio);
1421 }
1422
1423
1424 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
1425 index ce2e40b..923275e 100644
1426 --- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
1427 +++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
1428 @@ -77,7 +77,8 @@ static ssize_t devinfo_read_file(struct
1429
1430 down(&big_buffer_sem);
1431
1432 - bcm43xx_lock_irqsafe(bcm, flags);
1433 + mutex_lock(&bcm->mutex);
1434 + spin_lock_irqsave(&bcm->irq_lock, flags);
1435 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
1436 fappend("Board not initialized.\n");
1437 goto out;
1438 @@ -121,7 +122,8 @@ #undef fappend_core
1439 fappend("\n");
1440
1441 out:
1442 - bcm43xx_unlock_irqsafe(bcm, flags);
1443 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
1444 + mutex_unlock(&bcm->mutex);
1445 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1446 up(&big_buffer_sem);
1447 return res;
1448 @@ -159,7 +161,8 @@ static ssize_t spromdump_read_file(struc
1449 unsigned long flags;
1450
1451 down(&big_buffer_sem);
1452 - bcm43xx_lock_irqsafe(bcm, flags);
1453 + mutex_lock(&bcm->mutex);
1454 + spin_lock_irqsave(&bcm->irq_lock, flags);
1455 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
1456 fappend("Board not initialized.\n");
1457 goto out;
1458 @@ -169,7 +172,8 @@ static ssize_t spromdump_read_file(struc
1459 fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);
1460
1461 out:
1462 - bcm43xx_unlock_irqsafe(bcm, flags);
1463 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
1464 + mutex_unlock(&bcm->mutex);
1465 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1466 up(&big_buffer_sem);
1467 return res;
1468 @@ -188,7 +192,8 @@ static ssize_t tsf_read_file(struct file
1469 u64 tsf;
1470
1471 down(&big_buffer_sem);
1472 - bcm43xx_lock_irqsafe(bcm, flags);
1473 + mutex_lock(&bcm->mutex);
1474 + spin_lock_irqsave(&bcm->irq_lock, flags);
1475 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
1476 fappend("Board not initialized.\n");
1477 goto out;
1478 @@ -199,7 +204,8 @@ static ssize_t tsf_read_file(struct file
1479 (unsigned int)(tsf & 0xFFFFFFFFULL));
1480
1481 out:
1482 - bcm43xx_unlock_irqsafe(bcm, flags);
1483 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
1484 + mutex_unlock(&bcm->mutex);
1485 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1486 up(&big_buffer_sem);
1487 return res;
1488 @@ -221,7 +227,8 @@ static ssize_t tsf_write_file(struct fil
1489 res = -EFAULT;
1490 goto out_up;
1491 }
1492 - bcm43xx_lock_irqsafe(bcm, flags);
1493 + mutex_lock(&bcm->mutex);
1494 + spin_lock_irqsave(&bcm->irq_lock, flags);
1495 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
1496 printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
1497 res = -EFAULT;
1498 @@ -237,7 +244,8 @@ static ssize_t tsf_write_file(struct fil
1499 res = buf_size;
1500
1501 out_unlock:
1502 - bcm43xx_unlock_irqsafe(bcm, flags);
1503 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
1504 + mutex_unlock(&bcm->mutex);
1505 out_up:
1506 up(&big_buffer_sem);
1507 return res;
1508 @@ -258,7 +266,8 @@ static ssize_t txstat_read_file(struct f
1509 int i, cnt, j = 0;
1510
1511 down(&big_buffer_sem);
1512 - bcm43xx_lock_irqsafe(bcm, flags);
1513 + mutex_lock(&bcm->mutex);
1514 + spin_lock_irqsave(&bcm->irq_lock, flags);
1515
1516 fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
1517 BCM43xx_NR_LOGGED_XMITSTATUS);
1518 @@ -294,14 +303,51 @@ static ssize_t txstat_read_file(struct f
1519 i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
1520 }
1521
1522 - bcm43xx_unlock_irqsafe(bcm, flags);
1523 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
1524 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1525 - bcm43xx_lock_irqsafe(bcm, flags);
1526 + spin_lock_irqsave(&bcm->irq_lock, flags);
1527 if (*ppos == pos) {
1528 /* Done. Drop the copied data. */
1529 e->xmitstatus_printing = 0;
1530 }
1531 - bcm43xx_unlock_irqsafe(bcm, flags);
1532 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
1533 + mutex_unlock(&bcm->mutex);
1534 + up(&big_buffer_sem);
1535 + return res;
1536 +}
1537 +
1538 +static ssize_t restart_write_file(struct file *file, const char __user *user_buf,
1539 + size_t count, loff_t *ppos)
1540 +{
1541 + struct bcm43xx_private *bcm = file->private_data;
1542 + char *buf = really_big_buffer;
1543 + ssize_t buf_size;
1544 + ssize_t res;
1545 + unsigned long flags;
1546 +
1547 + buf_size = min(count, sizeof (really_big_buffer) - 1);
1548 + down(&big_buffer_sem);
1549 + if (copy_from_user(buf, user_buf, buf_size)) {
1550 + res = -EFAULT;
1551 + goto out_up;
1552 + }
1553 + mutex_lock(&(bcm)->mutex);
1554 + spin_lock_irqsave(&(bcm)->irq_lock, flags);
1555 + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
1556 + printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
1557 + res = -EFAULT;
1558 + goto out_unlock;
1559 + }
1560 + if (count > 0 && buf[0] == '1') {
1561 + bcm43xx_controller_restart(bcm, "manually restarted");
1562 + res = count;
1563 + } else
1564 + res = -EINVAL;
1565 +
1566 +out_unlock:
1567 + spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
1568 + mutex_unlock(&(bcm)->mutex);
1569 +out_up:
1570 up(&big_buffer_sem);
1571 return res;
1572 }
1573 @@ -339,6 +385,11 @@ static struct file_operations txstat_fop
1574 .open = open_file_generic,
1575 };
1576
1577 +static struct file_operations restart_fops = {
1578 + .write = restart_write_file,
1579 + .open = open_file_generic,
1580 +};
1581 +
1582
1583 void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm)
1584 {
1585 @@ -390,6 +441,10 @@ void bcm43xx_debugfs_add_device(struct b
1586 bcm, &txstat_fops);
1587 if (!e->dentry_txstat)
1588 printk(KERN_ERR PFX "debugfs: creating \"tx_status\" for \"%s\" failed!\n", devdir);
1589 + e->dentry_restart = debugfs_create_file("restart", 0222, e->subdir,
1590 + bcm, &restart_fops);
1591 + if (!e->dentry_restart)
1592 + printk(KERN_ERR PFX "debugfs: creating \"restart\" for \"%s\" failed!\n", devdir);
1593 }
1594
1595 void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm)
1596 @@ -405,6 +460,7 @@ void bcm43xx_debugfs_remove_device(struc
1597 debugfs_remove(e->dentry_devinfo);
1598 debugfs_remove(e->dentry_tsf);
1599 debugfs_remove(e->dentry_txstat);
1600 + debugfs_remove(e->dentry_restart);
1601 debugfs_remove(e->subdir);
1602 kfree(e->xmitstatus_buffer);
1603 kfree(e->xmitstatus_print_buffer);
1604 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
1605 index 50ce267..a40d1af 100644
1606 --- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
1607 +++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
1608 @@ -20,6 +20,7 @@ struct bcm43xx_dfsentry {
1609 struct dentry *dentry_spromdump;
1610 struct dentry *dentry_tsf;
1611 struct dentry *dentry_txstat;
1612 + struct dentry *dentry_restart;
1613
1614 struct bcm43xx_private *bcm;
1615
1616 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
1617 index d0318e5..76e3aed 100644
1618 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
1619 +++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
1620 @@ -4,7 +4,7 @@
1621
1622 DMA ringbuffer and descriptor allocation/management
1623
1624 - Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de>
1625 + Copyright (c) 2005, 2006 Michael Buesch <mbuesch@freenet.de>
1626
1627 Some code in this file is derived from the b44.c driver
1628 Copyright (C) 2002 David S. Miller
1629 @@ -109,6 +109,35 @@ void return_slot(struct bcm43xx_dmaring
1630 }
1631 }
1632
1633 +u16 bcm43xx_dmacontroller_base(int dma64bit, int controller_idx)
1634 +{
1635 + static const u16 map64[] = {
1636 + BCM43xx_MMIO_DMA64_BASE0,
1637 + BCM43xx_MMIO_DMA64_BASE1,
1638 + BCM43xx_MMIO_DMA64_BASE2,
1639 + BCM43xx_MMIO_DMA64_BASE3,
1640 + BCM43xx_MMIO_DMA64_BASE4,
1641 + BCM43xx_MMIO_DMA64_BASE5,
1642 + };
1643 + static const u16 map32[] = {
1644 + BCM43xx_MMIO_DMA32_BASE0,
1645 + BCM43xx_MMIO_DMA32_BASE1,
1646 + BCM43xx_MMIO_DMA32_BASE2,
1647 + BCM43xx_MMIO_DMA32_BASE3,
1648 + BCM43xx_MMIO_DMA32_BASE4,
1649 + BCM43xx_MMIO_DMA32_BASE5,
1650 + };
1651 +
1652 + if (dma64bit) {
1653 + assert(controller_idx >= 0 &&
1654 + controller_idx < ARRAY_SIZE(map64));
1655 + return map64[controller_idx];
1656 + }
1657 + assert(controller_idx >= 0 &&
1658 + controller_idx < ARRAY_SIZE(map32));
1659 + return map32[controller_idx];
1660 +}
1661 +
1662 static inline
1663 dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,
1664 unsigned char *buf,
1665 @@ -172,7 +201,6 @@ void sync_descbuffer_for_device(struct b
1666 /* Unmap and free a descriptor buffer. */
1667 static inline
1668 void free_descriptor_buffer(struct bcm43xx_dmaring *ring,
1669 - struct bcm43xx_dmadesc *desc,
1670 struct bcm43xx_dmadesc_meta *meta,
1671 int irq_context)
1672 {
1673 @@ -188,23 +216,13 @@ static int alloc_ringmemory(struct bcm43
1674 {
1675 struct device *dev = &(ring->bcm->pci_dev->dev);
1676
1677 - ring->vbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
1678 - &(ring->dmabase), GFP_KERNEL);
1679 - if (!ring->vbase) {
1680 + ring->descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
1681 + &(ring->dmabase), GFP_KERNEL);
1682 + if (!ring->descbase) {
1683 printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
1684 return -ENOMEM;
1685 }
1686 - if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) {
1687 - printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G "
1688 - "(0x%llx, len: %lu)\n",
1689 - (unsigned long long)ring->dmabase,
1690 - BCM43xx_DMA_RINGMEMSIZE);
1691 - dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
1692 - ring->vbase, ring->dmabase);
1693 - return -ENOMEM;
1694 - }
1695 - assert(!(ring->dmabase & 0x000003FF));
1696 - memset(ring->vbase, 0, BCM43xx_DMA_RINGMEMSIZE);
1697 + memset(ring->descbase, 0, BCM43xx_DMA_RINGMEMSIZE);
1698
1699 return 0;
1700 }
1701 @@ -214,26 +232,34 @@ static void free_ringmemory(struct bcm43
1702 struct device *dev = &(ring->bcm->pci_dev->dev);
1703
1704 dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
1705 - ring->vbase, ring->dmabase);
1706 + ring->descbase, ring->dmabase);
1707 }
1708
1709 /* Reset the RX DMA channel */
1710 int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
1711 - u16 mmio_base)
1712 + u16 mmio_base, int dma64)
1713 {
1714 int i;
1715 u32 value;
1716 + u16 offset;
1717
1718 - bcm43xx_write32(bcm,
1719 - mmio_base + BCM43xx_DMA_RX_CONTROL,
1720 - 0x00000000);
1721 + offset = dma64 ? BCM43xx_DMA64_RXCTL : BCM43xx_DMA32_RXCTL;
1722 + bcm43xx_write32(bcm, mmio_base + offset, 0);
1723 for (i = 0; i < 1000; i++) {
1724 - value = bcm43xx_read32(bcm,
1725 - mmio_base + BCM43xx_DMA_RX_STATUS);
1726 - value &= BCM43xx_DMA_RXSTAT_STAT_MASK;
1727 - if (value == BCM43xx_DMA_RXSTAT_STAT_DISABLED) {
1728 - i = -1;
1729 - break;
1730 + offset = dma64 ? BCM43xx_DMA64_RXSTATUS : BCM43xx_DMA32_RXSTATUS;
1731 + value = bcm43xx_read32(bcm, mmio_base + offset);
1732 + if (dma64) {
1733 + value &= BCM43xx_DMA64_RXSTAT;
1734 + if (value == BCM43xx_DMA64_RXSTAT_DISABLED) {
1735 + i = -1;
1736 + break;
1737 + }
1738 + } else {
1739 + value &= BCM43xx_DMA32_RXSTATE;
1740 + if (value == BCM43xx_DMA32_RXSTAT_DISABLED) {
1741 + i = -1;
1742 + break;
1743 + }
1744 }
1745 udelay(10);
1746 }
1747 @@ -247,31 +273,47 @@ int bcm43xx_dmacontroller_rx_reset(struc
1748
1749 /* Reset the RX DMA channel */
1750 int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
1751 - u16 mmio_base)
1752 + u16 mmio_base, int dma64)
1753 {
1754 int i;
1755 u32 value;
1756 + u16 offset;
1757
1758 for (i = 0; i < 1000; i++) {
1759 - value = bcm43xx_read32(bcm,
1760 - mmio_base + BCM43xx_DMA_TX_STATUS);
1761 - value &= BCM43xx_DMA_TXSTAT_STAT_MASK;
1762 - if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED ||
1763 - value == BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT ||
1764 - value == BCM43xx_DMA_TXSTAT_STAT_STOPPED)
1765 - break;
1766 + offset = dma64 ? BCM43xx_DMA64_TXSTATUS : BCM43xx_DMA32_TXSTATUS;
1767 + value = bcm43xx_read32(bcm, mmio_base + offset);
1768 + if (dma64) {
1769 + value &= BCM43xx_DMA64_TXSTAT;
1770 + if (value == BCM43xx_DMA64_TXSTAT_DISABLED ||
1771 + value == BCM43xx_DMA64_TXSTAT_IDLEWAIT ||
1772 + value == BCM43xx_DMA64_TXSTAT_STOPPED)
1773 + break;
1774 + } else {
1775 + value &= BCM43xx_DMA32_TXSTATE;
1776 + if (value == BCM43xx_DMA32_TXSTAT_DISABLED ||
1777 + value == BCM43xx_DMA32_TXSTAT_IDLEWAIT ||
1778 + value == BCM43xx_DMA32_TXSTAT_STOPPED)
1779 + break;
1780 + }
1781 udelay(10);
1782 }
1783 - bcm43xx_write32(bcm,
1784 - mmio_base + BCM43xx_DMA_TX_CONTROL,
1785 - 0x00000000);
1786 + offset = dma64 ? BCM43xx_DMA64_TXCTL : BCM43xx_DMA32_TXCTL;
1787 + bcm43xx_write32(bcm, mmio_base + offset, 0);
1788 for (i = 0; i < 1000; i++) {
1789 - value = bcm43xx_read32(bcm,
1790 - mmio_base + BCM43xx_DMA_TX_STATUS);
1791 - value &= BCM43xx_DMA_TXSTAT_STAT_MASK;
1792 - if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED) {
1793 - i = -1;
1794 - break;
1795 + offset = dma64 ? BCM43xx_DMA64_TXSTATUS : BCM43xx_DMA32_TXSTATUS;
1796 + value = bcm43xx_read32(bcm, mmio_base + offset);
1797 + if (dma64) {
1798 + value &= BCM43xx_DMA64_TXSTAT;
1799 + if (value == BCM43xx_DMA64_TXSTAT_DISABLED) {
1800 + i = -1;
1801 + break;
1802 + }
1803 + } else {
1804 + value &= BCM43xx_DMA32_TXSTATE;
1805 + if (value == BCM43xx_DMA32_TXSTAT_DISABLED) {
1806 + i = -1;
1807 + break;
1808 + }
1809 }
1810 udelay(10);
1811 }
1812 @@ -285,47 +327,98 @@ int bcm43xx_dmacontroller_tx_reset(struc
1813 return 0;
1814 }
1815
1816 +static void fill_descriptor(struct bcm43xx_dmaring *ring,
1817 + struct bcm43xx_dmadesc_generic *desc,
1818 + dma_addr_t dmaaddr,
1819 + u16 bufsize,
1820 + int start, int end, int irq)
1821 +{
1822 + int slot;
1823 +
1824 + slot = bcm43xx_dma_desc2idx(ring, desc);
1825 + assert(slot >= 0 && slot < ring->nr_slots);
1826 +
1827 + if (ring->dma64) {
1828 + u32 ctl0 = 0, ctl1 = 0;
1829 + u32 addrlo, addrhi;
1830 + u32 addrext;
1831 +
1832 + addrlo = (u32)(dmaaddr & 0xFFFFFFFF);
1833 + addrhi = (((u64)dmaaddr >> 32) & ~BCM43xx_DMA64_ROUTING);
1834 + addrext = (((u64)dmaaddr >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
1835 + addrhi |= ring->routing;
1836 + if (slot == ring->nr_slots - 1)
1837 + ctl0 |= BCM43xx_DMA64_DCTL0_DTABLEEND;
1838 + if (start)
1839 + ctl0 |= BCM43xx_DMA64_DCTL0_FRAMESTART;
1840 + if (end)
1841 + ctl0 |= BCM43xx_DMA64_DCTL0_FRAMEEND;
1842 + if (irq)
1843 + ctl0 |= BCM43xx_DMA64_DCTL0_IRQ;
1844 + ctl1 |= (bufsize - ring->frameoffset)
1845 + & BCM43xx_DMA64_DCTL1_BYTECNT;
1846 + ctl1 |= (addrext << BCM43xx_DMA64_DCTL1_ADDREXT_SHIFT)
1847 + & BCM43xx_DMA64_DCTL1_ADDREXT_MASK;
1848 +
1849 + desc->dma64.control0 = cpu_to_le32(ctl0);
1850 + desc->dma64.control1 = cpu_to_le32(ctl1);
1851 + desc->dma64.address_low = cpu_to_le32(addrlo);
1852 + desc->dma64.address_high = cpu_to_le32(addrhi);
1853 + } else {
1854 + u32 ctl;
1855 + u32 addr;
1856 + u32 addrext;
1857 +
1858 + addr = (u32)(dmaaddr & ~BCM43xx_DMA32_ROUTING);
1859 + addrext = (u32)(dmaaddr & BCM43xx_DMA32_ROUTING)
1860 + >> BCM43xx_DMA32_ROUTING_SHIFT;
1861 + addr |= ring->routing;
1862 + ctl = (bufsize - ring->frameoffset)
1863 + & BCM43xx_DMA32_DCTL_BYTECNT;
1864 + if (slot == ring->nr_slots - 1)
1865 + ctl |= BCM43xx_DMA32_DCTL_DTABLEEND;
1866 + if (start)
1867 + ctl |= BCM43xx_DMA32_DCTL_FRAMESTART;
1868 + if (end)
1869 + ctl |= BCM43xx_DMA32_DCTL_FRAMEEND;
1870 + if (irq)
1871 + ctl |= BCM43xx_DMA32_DCTL_IRQ;
1872 + ctl |= (addrext << BCM43xx_DMA32_DCTL_ADDREXT_SHIFT)
1873 + & BCM43xx_DMA32_DCTL_ADDREXT_MASK;
1874 +
1875 + desc->dma32.control = cpu_to_le32(ctl);
1876 + desc->dma32.address = cpu_to_le32(addr);
1877 + }
1878 +}
1879 +
1880 static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
1881 - struct bcm43xx_dmadesc *desc,
1882 + struct bcm43xx_dmadesc_generic *desc,
1883 struct bcm43xx_dmadesc_meta *meta,
1884 gfp_t gfp_flags)
1885 {
1886 struct bcm43xx_rxhdr *rxhdr;
1887 + struct bcm43xx_hwxmitstatus *xmitstat;
1888 dma_addr_t dmaaddr;
1889 - u32 desc_addr;
1890 - u32 desc_ctl;
1891 - const int slot = (int)(desc - ring->vbase);
1892 struct sk_buff *skb;
1893
1894 - assert(slot >= 0 && slot < ring->nr_slots);
1895 assert(!ring->tx);
1896
1897 skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
1898 if (unlikely(!skb))
1899 return -ENOMEM;
1900 dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
1901 - if (unlikely(dmaaddr + ring->rx_buffersize > BCM43xx_DMA_BUSADDRMAX)) {
1902 - unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
1903 - dev_kfree_skb_any(skb);
1904 - printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G "
1905 - "(0x%llx, len: %u)\n",
1906 - (unsigned long long)dmaaddr, ring->rx_buffersize);
1907 - return -ENOMEM;
1908 - }
1909 meta->skb = skb;
1910 meta->dmaaddr = dmaaddr;
1911 skb->dev = ring->bcm->net_dev;
1912 - desc_addr = (u32)(dmaaddr + ring->memoffset);
1913 - desc_ctl = (BCM43xx_DMADTOR_BYTECNT_MASK &
1914 - (u32)(ring->rx_buffersize - ring->frameoffset));
1915 - if (slot == ring->nr_slots - 1)
1916 - desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
1917 - set_desc_addr(desc, desc_addr);
1918 - set_desc_ctl(desc, desc_ctl);
1919 +
1920 + fill_descriptor(ring, desc, dmaaddr,
1921 + ring->rx_buffersize, 0, 0, 0);
1922
1923 rxhdr = (struct bcm43xx_rxhdr *)(skb->data);
1924 rxhdr->frame_length = 0;
1925 rxhdr->flags1 = 0;
1926 + xmitstat = (struct bcm43xx_hwxmitstatus *)(skb->data);
1927 + xmitstat->cookie = 0;
1928
1929 return 0;
1930 }
1931 @@ -336,17 +429,17 @@ static int setup_rx_descbuffer(struct bc
1932 static int alloc_initial_descbuffers(struct bcm43xx_dmaring *ring)
1933 {
1934 int i, err = -ENOMEM;
1935 - struct bcm43xx_dmadesc *desc;
1936 + struct bcm43xx_dmadesc_generic *desc;
1937 struct bcm43xx_dmadesc_meta *meta;
1938
1939 for (i = 0; i < ring->nr_slots; i++) {
1940 - desc = ring->vbase + i;
1941 - meta = ring->meta + i;
1942 + desc = bcm43xx_dma_idx2desc(ring, i, &meta);
1943
1944 err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
1945 if (err)
1946 goto err_unwind;
1947 }
1948 + mb();
1949 ring->used_slots = ring->nr_slots;
1950 err = 0;
1951 out:
1952 @@ -354,8 +447,7 @@ out:
1953
1954 err_unwind:
1955 for (i--; i >= 0; i--) {
1956 - desc = ring->vbase + i;
1957 - meta = ring->meta + i;
1958 + desc = bcm43xx_dma_idx2desc(ring, i, &meta);
1959
1960 unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0);
1961 dev_kfree_skb(meta->skb);
1962 @@ -371,27 +463,67 @@ static int dmacontroller_setup(struct bc
1963 {
1964 int err = 0;
1965 u32 value;
1966 + u32 addrext;
1967
1968 if (ring->tx) {
1969 - /* Set Transmit Control register to "transmit enable" */
1970 - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
1971 - BCM43xx_DMA_TXCTRL_ENABLE);
1972 - /* Set Transmit Descriptor ring address. */
1973 - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING,
1974 - ring->dmabase + ring->memoffset);
1975 + if (ring->dma64) {
1976 + u64 ringbase = (u64)(ring->dmabase);
1977 +
1978 + addrext = ((ringbase >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
1979 + value = BCM43xx_DMA64_TXENABLE;
1980 + value |= (addrext << BCM43xx_DMA64_TXADDREXT_SHIFT)
1981 + & BCM43xx_DMA64_TXADDREXT_MASK;
1982 + bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL, value);
1983 + bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGLO,
1984 + (ringbase & 0xFFFFFFFF));
1985 + bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGHI,
1986 + ((ringbase >> 32) & ~BCM43xx_DMA64_ROUTING)
1987 + | ring->routing);
1988 + } else {
1989 + u32 ringbase = (u32)(ring->dmabase);
1990 +
1991 + addrext = (ringbase >> BCM43xx_DMA32_ROUTING_SHIFT);
1992 + value = BCM43xx_DMA32_TXENABLE;
1993 + value |= (addrext << BCM43xx_DMA32_TXADDREXT_SHIFT)
1994 + & BCM43xx_DMA32_TXADDREXT_MASK;
1995 + bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL, value);
1996 + bcm43xx_dma_write(ring, BCM43xx_DMA32_TXRING,
1997 + (ringbase & ~BCM43xx_DMA32_ROUTING)
1998 + | ring->routing);
1999 + }
2000 } else {
2001 err = alloc_initial_descbuffers(ring);
2002 if (err)
2003 goto out;
2004 - /* Set Receive Control "receive enable" and frame offset */
2005 - value = (ring->frameoffset << BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT);
2006 - value |= BCM43xx_DMA_RXCTRL_ENABLE;
2007 - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_CONTROL, value);
2008 - /* Set Receive Descriptor ring address. */
2009 - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING,
2010 - ring->dmabase + ring->memoffset);
2011 - /* Init the descriptor pointer. */
2012 - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX, 200);
2013 + if (ring->dma64) {
2014 + u64 ringbase = (u64)(ring->dmabase);
2015 +
2016 + addrext = ((ringbase >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
2017 + value = (ring->frameoffset << BCM43xx_DMA64_RXFROFF_SHIFT);
2018 + value |= BCM43xx_DMA64_RXENABLE;
2019 + value |= (addrext << BCM43xx_DMA64_RXADDREXT_SHIFT)
2020 + & BCM43xx_DMA64_RXADDREXT_MASK;
2021 + bcm43xx_dma_write(ring, BCM43xx_DMA64_RXCTL, value);
2022 + bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGLO,
2023 + (ringbase & 0xFFFFFFFF));
2024 + bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGHI,
2025 + ((ringbase >> 32) & ~BCM43xx_DMA64_ROUTING)
2026 + | ring->routing);
2027 + bcm43xx_dma_write(ring, BCM43xx_DMA64_RXINDEX, 200);
2028 + } else {
2029 + u32 ringbase = (u32)(ring->dmabase);
2030 +
2031 + addrext = (ringbase >> BCM43xx_DMA32_ROUTING_SHIFT);
2032 + value = (ring->frameoffset << BCM43xx_DMA32_RXFROFF_SHIFT);
2033 + value |= BCM43xx_DMA32_RXENABLE;
2034 + value |= (addrext << BCM43xx_DMA32_RXADDREXT_SHIFT)
2035 + & BCM43xx_DMA32_RXADDREXT_MASK;
2036 + bcm43xx_dma_write(ring, BCM43xx_DMA32_RXCTL, value);
2037 + bcm43xx_dma_write(ring, BCM43xx_DMA32_RXRING,
2038 + (ringbase & ~BCM43xx_DMA32_ROUTING)
2039 + | ring->routing);
2040 + bcm43xx_dma_write(ring, BCM43xx_DMA32_RXINDEX, 200);
2041 + }
2042 }
2043
2044 out:
2045 @@ -402,27 +534,32 @@ out:
2046 static void dmacontroller_cleanup(struct bcm43xx_dmaring *ring)
2047 {
2048 if (ring->tx) {
2049 - bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base);
2050 - /* Zero out Transmit Descriptor ring address. */
2051 - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING, 0);
2052 + bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base, ring->dma64);
2053 + if (ring->dma64) {
2054 + bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGLO, 0);
2055 + bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGHI, 0);
2056 + } else
2057 + bcm43xx_dma_write(ring, BCM43xx_DMA32_TXRING, 0);
2058 } else {
2059 - bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base);
2060 - /* Zero out Receive Descriptor ring address. */
2061 - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING, 0);
2062 + bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base, ring->dma64);
2063 + if (ring->dma64) {
2064 + bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGLO, 0);
2065 + bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGHI, 0);
2066 + } else
2067 + bcm43xx_dma_write(ring, BCM43xx_DMA32_RXRING, 0);
2068 }
2069 }
2070
2071 static void free_all_descbuffers(struct bcm43xx_dmaring *ring)
2072 {
2073 - struct bcm43xx_dmadesc *desc;
2074 + struct bcm43xx_dmadesc_generic *desc;
2075 struct bcm43xx_dmadesc_meta *meta;
2076 int i;
2077
2078 if (!ring->used_slots)
2079 return;
2080 for (i = 0; i < ring->nr_slots; i++) {
2081 - desc = ring->vbase + i;
2082 - meta = ring->meta + i;
2083 + desc = bcm43xx_dma_idx2desc(ring, i, &meta);
2084
2085 if (!meta->skb) {
2086 assert(ring->tx);
2087 @@ -430,62 +567,67 @@ static void free_all_descbuffers(struct
2088 }
2089 if (ring->tx) {
2090 unmap_descbuffer(ring, meta->dmaaddr,
2091 - meta->skb->len, 1);
2092 + meta->skb->len, 1);
2093 } else {
2094 unmap_descbuffer(ring, meta->dmaaddr,
2095 - ring->rx_buffersize, 0);
2096 + ring->rx_buffersize, 0);
2097 }
2098 - free_descriptor_buffer(ring, desc, meta, 0);
2099 + free_descriptor_buffer(ring, meta, 0);
2100 }
2101 }
2102
2103 /* Main initialization function. */
2104 static
2105 struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm,
2106 - u16 dma_controller_base,
2107 - int nr_descriptor_slots,
2108 - int tx)
2109 + int controller_index,
2110 + int for_tx,
2111 + int dma64)
2112 {
2113 struct bcm43xx_dmaring *ring;
2114 int err;
2115 + int nr_slots;
2116
2117 ring = kzalloc(sizeof(*ring), GFP_KERNEL);
2118 if (!ring)
2119 goto out;
2120
2121 - ring->meta = kzalloc(sizeof(*ring->meta) * nr_descriptor_slots,
2122 + nr_slots = BCM43xx_RXRING_SLOTS;
2123 + if (for_tx)
2124 + nr_slots = BCM43xx_TXRING_SLOTS;
2125 +
2126 + ring->meta = kcalloc(nr_slots, sizeof(struct bcm43xx_dmadesc_meta),
2127 GFP_KERNEL);
2128 if (!ring->meta)
2129 goto err_kfree_ring;
2130
2131 - ring->memoffset = BCM43xx_DMA_DMABUSADDROFFSET;
2132 + ring->routing = BCM43xx_DMA32_CLIENTTRANS;
2133 + if (dma64)
2134 + ring->routing = BCM43xx_DMA64_CLIENTTRANS;
2135 #ifdef CONFIG_BCM947XX
2136 if (bcm->pci_dev->bus->number == 0)
2137 - ring->memoffset = 0;
2138 + ring->routing = dma64 ? BCM43xx_DMA64_NOTRANS : BCM43xx_DMA32_NOTRANS;
2139 #endif
2140
2141 ring->bcm = bcm;
2142 - ring->nr_slots = nr_descriptor_slots;
2143 + ring->nr_slots = nr_slots;
2144 ring->suspend_mark = ring->nr_slots * BCM43xx_TXSUSPEND_PERCENT / 100;
2145 ring->resume_mark = ring->nr_slots * BCM43xx_TXRESUME_PERCENT / 100;
2146 assert(ring->suspend_mark < ring->resume_mark);
2147 - ring->mmio_base = dma_controller_base;
2148 - if (tx) {
2149 + ring->mmio_base = bcm43xx_dmacontroller_base(dma64, controller_index);
2150 + ring->index = controller_index;
2151 + ring->dma64 = !!dma64;
2152 + if (for_tx) {
2153 ring->tx = 1;
2154 ring->current_slot = -1;
2155 } else {
2156 - switch (dma_controller_base) {
2157 - case BCM43xx_MMIO_DMA1_BASE:
2158 - ring->rx_buffersize = BCM43xx_DMA1_RXBUFFERSIZE;
2159 - ring->frameoffset = BCM43xx_DMA1_RX_FRAMEOFFSET;
2160 - break;
2161 - case BCM43xx_MMIO_DMA4_BASE:
2162 - ring->rx_buffersize = BCM43xx_DMA4_RXBUFFERSIZE;
2163 - ring->frameoffset = BCM43xx_DMA4_RX_FRAMEOFFSET;
2164 - break;
2165 - default:
2166 + if (ring->index == 0) {
2167 + ring->rx_buffersize = BCM43xx_DMA0_RX_BUFFERSIZE;
2168 + ring->frameoffset = BCM43xx_DMA0_RX_FRAMEOFFSET;
2169 + } else if (ring->index == 3) {
2170 + ring->rx_buffersize = BCM43xx_DMA3_RX_BUFFERSIZE;
2171 + ring->frameoffset = BCM43xx_DMA3_RX_FRAMEOFFSET;
2172 + } else
2173 assert(0);
2174 - }
2175 }
2176
2177 err = alloc_ringmemory(ring);
2178 @@ -514,7 +656,8 @@ static void bcm43xx_destroy_dmaring(stru
2179 if (!ring)
2180 return;
2181
2182 - dprintk(KERN_INFO PFX "DMA 0x%04x (%s) max used slots: %d/%d\n",
2183 + dprintk(KERN_INFO PFX "DMA-%s 0x%04X (%s) max used slots: %d/%d\n",
2184 + (ring->dma64) ? "64" : "32",
2185 ring->mmio_base,
2186 (ring->tx) ? "TX" : "RX",
2187 ring->max_used_slots, ring->nr_slots);
2188 @@ -537,10 +680,15 @@ void bcm43xx_dma_free(struct bcm43xx_pri
2189 return;
2190 dma = bcm43xx_current_dma(bcm);
2191
2192 - bcm43xx_destroy_dmaring(dma->rx_ring1);
2193 - dma->rx_ring1 = NULL;
2194 + bcm43xx_destroy_dmaring(dma->rx_ring3);
2195 + dma->rx_ring3 = NULL;
2196 bcm43xx_destroy_dmaring(dma->rx_ring0);
2197 dma->rx_ring0 = NULL;
2198 +
2199 + bcm43xx_destroy_dmaring(dma->tx_ring5);
2200 + dma->tx_ring5 = NULL;
2201 + bcm43xx_destroy_dmaring(dma->tx_ring4);
2202 + dma->tx_ring4 = NULL;
2203 bcm43xx_destroy_dmaring(dma->tx_ring3);
2204 dma->tx_ring3 = NULL;
2205 bcm43xx_destroy_dmaring(dma->tx_ring2);
2206 @@ -556,48 +704,59 @@ int bcm43xx_dma_init(struct bcm43xx_priv
2207 struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
2208 struct bcm43xx_dmaring *ring;
2209 int err = -ENOMEM;
2210 + int dma64 = 0;
2211 + u32 sbtmstatehi;
2212 +
2213 + sbtmstatehi = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
2214 + if (sbtmstatehi & BCM43xx_SBTMSTATEHIGH_DMA64BIT)
2215 + dma64 = 1;
2216
2217 /* setup TX DMA channels. */
2218 - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
2219 - BCM43xx_TXRING_SLOTS, 1);
2220 + ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
2221 if (!ring)
2222 goto out;
2223 dma->tx_ring0 = ring;
2224
2225 - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA2_BASE,
2226 - BCM43xx_TXRING_SLOTS, 1);
2227 + ring = bcm43xx_setup_dmaring(bcm, 1, 1, dma64);
2228 if (!ring)
2229 goto err_destroy_tx0;
2230 dma->tx_ring1 = ring;
2231
2232 - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA3_BASE,
2233 - BCM43xx_TXRING_SLOTS, 1);
2234 + ring = bcm43xx_setup_dmaring(bcm, 2, 1, dma64);
2235 if (!ring)
2236 goto err_destroy_tx1;
2237 dma->tx_ring2 = ring;
2238
2239 - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
2240 - BCM43xx_TXRING_SLOTS, 1);
2241 + ring = bcm43xx_setup_dmaring(bcm, 3, 1, dma64);
2242 if (!ring)
2243 goto err_destroy_tx2;
2244 dma->tx_ring3 = ring;
2245
2246 - /* setup RX DMA channels. */
2247 - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
2248 - BCM43xx_RXRING_SLOTS, 0);
2249 + ring = bcm43xx_setup_dmaring(bcm, 4, 1, dma64);
2250 if (!ring)
2251 goto err_destroy_tx3;
2252 + dma->tx_ring4 = ring;
2253 +
2254 + ring = bcm43xx_setup_dmaring(bcm, 5, 1, dma64);
2255 + if (!ring)
2256 + goto err_destroy_tx4;
2257 + dma->tx_ring5 = ring;
2258 +
2259 + /* setup RX DMA channels. */
2260 + ring = bcm43xx_setup_dmaring(bcm, 0, 0, dma64);
2261 + if (!ring)
2262 + goto err_destroy_tx5;
2263 dma->rx_ring0 = ring;
2264
2265 if (bcm->current_core->rev < 5) {
2266 - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
2267 - BCM43xx_RXRING_SLOTS, 0);
2268 + ring = bcm43xx_setup_dmaring(bcm, 3, 0, dma64);
2269 if (!ring)
2270 goto err_destroy_rx0;
2271 - dma->rx_ring1 = ring;
2272 + dma->rx_ring3 = ring;
2273 }
2274
2275 - dprintk(KERN_INFO PFX "DMA initialized\n");
2276 + dprintk(KERN_INFO PFX "%s DMA initialized\n",
2277 + dma64 ? "64-bit" : "32-bit");
2278 err = 0;
2279 out:
2280 return err;
2281 @@ -605,6 +764,12 @@ out:
2282 err_destroy_rx0:
2283 bcm43xx_destroy_dmaring(dma->rx_ring0);
2284 dma->rx_ring0 = NULL;
2285 +err_destroy_tx5:
2286 + bcm43xx_destroy_dmaring(dma->tx_ring5);
2287 + dma->tx_ring5 = NULL;
2288 +err_destroy_tx4:
2289 + bcm43xx_destroy_dmaring(dma->tx_ring4);
2290 + dma->tx_ring4 = NULL;
2291 err_destroy_tx3:
2292 bcm43xx_destroy_dmaring(dma->tx_ring3);
2293 dma->tx_ring3 = NULL;
2294 @@ -624,7 +789,7 @@ err_destroy_tx0:
2295 static u16 generate_cookie(struct bcm43xx_dmaring *ring,
2296 int slot)
2297 {
2298 - u16 cookie = 0xF000;
2299 + u16 cookie = 0x1000;
2300
2301 /* Use the upper 4 bits of the cookie as
2302 * DMA controller ID and store the slot number
2303 @@ -632,21 +797,25 @@ static u16 generate_cookie(struct bcm43x
2304 * Note that the cookie must never be 0, as this
2305 * is a special value used in RX path.
2306 */
2307 - switch (ring->mmio_base) {
2308 - default:
2309 - assert(0);
2310 - case BCM43xx_MMIO_DMA1_BASE:
2311 + switch (ring->index) {
2312 + case 0:
2313 cookie = 0xA000;
2314 break;
2315 - case BCM43xx_MMIO_DMA2_BASE:
2316 + case 1:
2317 cookie = 0xB000;
2318 break;
2319 - case BCM43xx_MMIO_DMA3_BASE:
2320 + case 2:
2321 cookie = 0xC000;
2322 break;
2323 - case BCM43xx_MMIO_DMA4_BASE:
2324 + case 3:
2325 cookie = 0xD000;
2326 break;
2327 + case 4:
2328 + cookie = 0xE000;
2329 + break;
2330 + case 5:
2331 + cookie = 0xF000;
2332 + break;
2333 }
2334 assert(((u16)slot & 0xF000) == 0x0000);
2335 cookie |= (u16)slot;
2336 @@ -675,6 +844,12 @@ struct bcm43xx_dmaring * parse_cookie(st
2337 case 0xD000:
2338 ring = dma->tx_ring3;
2339 break;
2340 + case 0xE000:
2341 + ring = dma->tx_ring4;
2342 + break;
2343 + case 0xF000:
2344 + ring = dma->tx_ring5;
2345 + break;
2346 default:
2347 assert(0);
2348 }
2349 @@ -687,6 +862,9 @@ struct bcm43xx_dmaring * parse_cookie(st
2350 static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring,
2351 int slot)
2352 {
2353 + u16 offset;
2354 + int descsize;
2355 +
2356 /* Everything is ready to start. Buffers are DMA mapped and
2357 * associated with slots.
2358 * "slot" is the last slot of the new frame we want to transmit.
2359 @@ -694,25 +872,26 @@ static void dmacontroller_poke_tx(struct
2360 */
2361 wmb();
2362 slot = next_slot(ring, slot);
2363 - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_INDEX,
2364 - (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
2365 + offset = (ring->dma64) ? BCM43xx_DMA64_TXINDEX : BCM43xx_DMA32_TXINDEX;
2366 + descsize = (ring->dma64) ? sizeof(struct bcm43xx_dmadesc64)
2367 + : sizeof(struct bcm43xx_dmadesc32);
2368 + bcm43xx_dma_write(ring, offset,
2369 + (u32)(slot * descsize));
2370 }
2371
2372 -static int dma_tx_fragment(struct bcm43xx_dmaring *ring,
2373 - struct sk_buff *skb,
2374 - u8 cur_frag)
2375 +static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
2376 + struct sk_buff *skb,
2377 + u8 cur_frag)
2378 {
2379 int slot;
2380 - struct bcm43xx_dmadesc *desc;
2381 + struct bcm43xx_dmadesc_generic *desc;
2382 struct bcm43xx_dmadesc_meta *meta;
2383 - u32 desc_ctl;
2384 - u32 desc_addr;
2385 + dma_addr_t dmaaddr;
2386
2387 assert(skb_shinfo(skb)->nr_frags == 0);
2388
2389 slot = request_slot(ring);
2390 - desc = ring->vbase + slot;
2391 - meta = ring->meta + slot;
2392 + desc = bcm43xx_dma_idx2desc(ring, slot, &meta);
2393
2394 /* Add a device specific TX header. */
2395 assert(skb_headroom(skb) >= sizeof(struct bcm43xx_txhdr));
2396 @@ -729,29 +908,14 @@ static int dma_tx_fragment(struct bcm43x
2397 generate_cookie(ring, slot));
2398
2399 meta->skb = skb;
2400 - meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
2401 - if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) {
2402 - return_slot(ring, slot);
2403 - printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G "
2404 - "(0x%llx, len: %u)\n",
2405 - (unsigned long long)meta->dmaaddr, skb->len);
2406 - return -ENOMEM;
2407 - }
2408 + dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
2409 + meta->dmaaddr = dmaaddr;
2410
2411 - desc_addr = (u32)(meta->dmaaddr + ring->memoffset);
2412 - desc_ctl = BCM43xx_DMADTOR_FRAMESTART | BCM43xx_DMADTOR_FRAMEEND;
2413 - desc_ctl |= BCM43xx_DMADTOR_COMPIRQ;
2414 - desc_ctl |= (BCM43xx_DMADTOR_BYTECNT_MASK &
2415 - (u32)(meta->skb->len - ring->frameoffset));
2416 - if (slot == ring->nr_slots - 1)
2417 - desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
2418 + fill_descriptor(ring, desc, dmaaddr,
2419 + skb->len, 1, 1, 1);
2420
2421 - set_desc_ctl(desc, desc_ctl);
2422 - set_desc_addr(desc, desc_addr);
2423 /* Now transfer the whole frame. */
2424 dmacontroller_poke_tx(ring, slot);
2425 -
2426 - return 0;
2427 }
2428
2429 int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
2430 @@ -781,7 +945,6 @@ int bcm43xx_dma_tx(struct bcm43xx_privat
2431 /* Take skb from ieee80211_txb_free */
2432 txb->fragments[i] = NULL;
2433 dma_tx_fragment(ring, skb, i);
2434 - //TODO: handle failure of dma_tx_fragment
2435 }
2436 ieee80211_txb_free(txb);
2437
2438 @@ -792,23 +955,28 @@ void bcm43xx_dma_handle_xmitstatus(struc
2439 struct bcm43xx_xmitstatus *status)
2440 {
2441 struct bcm43xx_dmaring *ring;
2442 - struct bcm43xx_dmadesc *desc;
2443 + struct bcm43xx_dmadesc_generic *desc;
2444 struct bcm43xx_dmadesc_meta *meta;
2445 int is_last_fragment;
2446 int slot;
2447 + u32 tmp;
2448
2449 ring = parse_cookie(bcm, status->cookie, &slot);
2450 assert(ring);
2451 assert(ring->tx);
2452 - assert(get_desc_ctl(ring->vbase + slot) & BCM43xx_DMADTOR_FRAMESTART);
2453 while (1) {
2454 assert(slot >= 0 && slot < ring->nr_slots);
2455 - desc = ring->vbase + slot;
2456 - meta = ring->meta + slot;
2457 + desc = bcm43xx_dma_idx2desc(ring, slot, &meta);
2458
2459 - is_last_fragment = !!(get_desc_ctl(desc) & BCM43xx_DMADTOR_FRAMEEND);
2460 + if (ring->dma64) {
2461 + tmp = le32_to_cpu(desc->dma64.control0);
2462 + is_last_fragment = !!(tmp & BCM43xx_DMA64_DCTL0_FRAMEEND);
2463 + } else {
2464 + tmp = le32_to_cpu(desc->dma32.control);
2465 + is_last_fragment = !!(tmp & BCM43xx_DMA32_DCTL_FRAMEEND);
2466 + }
2467 unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
2468 - free_descriptor_buffer(ring, desc, meta, 1);
2469 + free_descriptor_buffer(ring, meta, 1);
2470 /* Everything belonging to the slot is unmapped
2471 * and freed, so we can return it.
2472 */
2473 @@ -824,7 +992,7 @@ void bcm43xx_dma_handle_xmitstatus(struc
2474 static void dma_rx(struct bcm43xx_dmaring *ring,
2475 int *slot)
2476 {
2477 - struct bcm43xx_dmadesc *desc;
2478 + struct bcm43xx_dmadesc_generic *desc;
2479 struct bcm43xx_dmadesc_meta *meta;
2480 struct bcm43xx_rxhdr *rxhdr;
2481 struct sk_buff *skb;
2482 @@ -832,13 +1000,12 @@ static void dma_rx(struct bcm43xx_dmarin
2483 int err;
2484 dma_addr_t dmaaddr;
2485
2486 - desc = ring->vbase + *slot;
2487 - meta = ring->meta + *slot;
2488 + desc = bcm43xx_dma_idx2desc(ring, *slot, &meta);
2489
2490 sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
2491 skb = meta->skb;
2492
2493 - if (ring->mmio_base == BCM43xx_MMIO_DMA4_BASE) {
2494 + if (ring->index == 3) {
2495 /* We received an xmit status. */
2496 struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data;
2497 struct bcm43xx_xmitstatus stat;
2498 @@ -894,8 +1061,7 @@ static void dma_rx(struct bcm43xx_dmarin
2499 s32 tmp = len;
2500
2501 while (1) {
2502 - desc = ring->vbase + *slot;
2503 - meta = ring->meta + *slot;
2504 + desc = bcm43xx_dma_idx2desc(ring, *slot, &meta);
2505 /* recycle the descriptor buffer. */
2506 sync_descbuffer_for_device(ring, meta->dmaaddr,
2507 ring->rx_buffersize);
2508 @@ -906,8 +1072,8 @@ static void dma_rx(struct bcm43xx_dmarin
2509 break;
2510 }
2511 printkl(KERN_ERR PFX "DMA RX buffer too small "
2512 - "(len: %u, buffer: %u, nr-dropped: %d)\n",
2513 - len, ring->rx_buffersize, cnt);
2514 + "(len: %u, buffer: %u, nr-dropped: %d)\n",
2515 + len, ring->rx_buffersize, cnt);
2516 goto drop;
2517 }
2518 len -= IEEE80211_FCS_LEN;
2519 @@ -945,9 +1111,15 @@ #ifdef CONFIG_BCM43XX_DEBUG
2520 #endif
2521
2522 assert(!ring->tx);
2523 - status = bcm43xx_dma_read(ring, BCM43xx_DMA_RX_STATUS);
2524 - descptr = (status & BCM43xx_DMA_RXSTAT_DPTR_MASK);
2525 - current_slot = descptr / sizeof(struct bcm43xx_dmadesc);
2526 + if (ring->dma64) {
2527 + status = bcm43xx_dma_read(ring, BCM43xx_DMA64_RXSTATUS);
2528 + descptr = (status & BCM43xx_DMA64_RXSTATDPTR);
2529 + current_slot = descptr / sizeof(struct bcm43xx_dmadesc64);
2530 + } else {
2531 + status = bcm43xx_dma_read(ring, BCM43xx_DMA32_RXSTATUS);
2532 + descptr = (status & BCM43xx_DMA32_RXDPTR);
2533 + current_slot = descptr / sizeof(struct bcm43xx_dmadesc32);
2534 + }
2535 assert(current_slot >= 0 && current_slot < ring->nr_slots);
2536
2537 slot = ring->current_slot;
2538 @@ -958,8 +1130,13 @@ #ifdef CONFIG_BCM43XX_DEBUG
2539 ring->max_used_slots = used_slots;
2540 #endif
2541 }
2542 - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX,
2543 - (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
2544 + if (ring->dma64) {
2545 + bcm43xx_dma_write(ring, BCM43xx_DMA64_RXINDEX,
2546 + (u32)(slot * sizeof(struct bcm43xx_dmadesc64)));
2547 + } else {
2548 + bcm43xx_dma_write(ring, BCM43xx_DMA32_RXINDEX,
2549 + (u32)(slot * sizeof(struct bcm43xx_dmadesc32)));
2550 + }
2551 ring->current_slot = slot;
2552 }
2553
2554 @@ -967,16 +1144,28 @@ void bcm43xx_dma_tx_suspend(struct bcm43
2555 {
2556 assert(ring->tx);
2557 bcm43xx_power_saving_ctl_bits(ring->bcm, -1, 1);
2558 - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
2559 - bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL)
2560 - | BCM43xx_DMA_TXCTRL_SUSPEND);
2561 + if (ring->dma64) {
2562 + bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL,
2563 + bcm43xx_dma_read(ring, BCM43xx_DMA64_TXCTL)
2564 + | BCM43xx_DMA64_TXSUSPEND);
2565 + } else {
2566 + bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL,
2567 + bcm43xx_dma_read(ring, BCM43xx_DMA32_TXCTL)
2568 + | BCM43xx_DMA32_TXSUSPEND);
2569 + }
2570 }
2571
2572 void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring)
2573 {
2574 assert(ring->tx);
2575 - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
2576 - bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL)
2577 - & ~BCM43xx_DMA_TXCTRL_SUSPEND);
2578 + if (ring->dma64) {
2579 + bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL,
2580 + bcm43xx_dma_read(ring, BCM43xx_DMA64_TXCTL)
2581 + & ~BCM43xx_DMA64_TXSUSPEND);
2582 + } else {
2583 + bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL,
2584 + bcm43xx_dma_read(ring, BCM43xx_DMA32_TXCTL)
2585 + & ~BCM43xx_DMA32_TXSUSPEND);
2586 + }
2587 bcm43xx_power_saving_ctl_bits(ring->bcm, -1, -1);
2588 }
2589 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
2590 index b7d7763..e04bcad 100644
2591 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
2592 +++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
2593 @@ -14,63 +14,179 @@ #define BCM43xx_DMAIRQ_FATALMASK ((1 <<
2594 #define BCM43xx_DMAIRQ_NONFATALMASK (1 << 13)
2595 #define BCM43xx_DMAIRQ_RX_DONE (1 << 16)
2596
2597 -/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */
2598 -#define BCM43xx_DMA_TX_CONTROL 0x00
2599 -#define BCM43xx_DMA_TX_DESC_RING 0x04
2600 -#define BCM43xx_DMA_TX_DESC_INDEX 0x08
2601 -#define BCM43xx_DMA_TX_STATUS 0x0c
2602 -#define BCM43xx_DMA_RX_CONTROL 0x10
2603 -#define BCM43xx_DMA_RX_DESC_RING 0x14
2604 -#define BCM43xx_DMA_RX_DESC_INDEX 0x18
2605 -#define BCM43xx_DMA_RX_STATUS 0x1c
2606 -
2607 -/* DMA controller channel control word values. */
2608 -#define BCM43xx_DMA_TXCTRL_ENABLE (1 << 0)
2609 -#define BCM43xx_DMA_TXCTRL_SUSPEND (1 << 1)
2610 -#define BCM43xx_DMA_TXCTRL_LOOPBACK (1 << 2)
2611 -#define BCM43xx_DMA_TXCTRL_FLUSH (1 << 4)
2612 -#define BCM43xx_DMA_RXCTRL_ENABLE (1 << 0)
2613 -#define BCM43xx_DMA_RXCTRL_FRAMEOFF_MASK 0x000000fe
2614 -#define BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT 1
2615 -#define BCM43xx_DMA_RXCTRL_PIO (1 << 8)
2616 -/* DMA controller channel status word values. */
2617 -#define BCM43xx_DMA_TXSTAT_DPTR_MASK 0x00000fff
2618 -#define BCM43xx_DMA_TXSTAT_STAT_MASK 0x0000f000
2619 -#define BCM43xx_DMA_TXSTAT_STAT_DISABLED 0x00000000
2620 -#define BCM43xx_DMA_TXSTAT_STAT_ACTIVE 0x00001000
2621 -#define BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT 0x00002000
2622 -#define BCM43xx_DMA_TXSTAT_STAT_STOPPED 0x00003000
2623 -#define BCM43xx_DMA_TXSTAT_STAT_SUSP 0x00004000
2624 -#define BCM43xx_DMA_TXSTAT_ERROR_MASK 0x000f0000
2625 -#define BCM43xx_DMA_TXSTAT_FLUSHED (1 << 20)
2626 -#define BCM43xx_DMA_RXSTAT_DPTR_MASK 0x00000fff
2627 -#define BCM43xx_DMA_RXSTAT_STAT_MASK 0x0000f000
2628 -#define BCM43xx_DMA_RXSTAT_STAT_DISABLED 0x00000000
2629 -#define BCM43xx_DMA_RXSTAT_STAT_ACTIVE 0x00001000
2630 -#define BCM43xx_DMA_RXSTAT_STAT_IDLEWAIT 0x00002000
2631 -#define BCM43xx_DMA_RXSTAT_STAT_RESERVED 0x00003000
2632 -#define BCM43xx_DMA_RXSTAT_STAT_ERRORS 0x00004000
2633 -#define BCM43xx_DMA_RXSTAT_ERROR_MASK 0x000f0000
2634 -
2635 -/* DMA descriptor control field values. */
2636 -#define BCM43xx_DMADTOR_BYTECNT_MASK 0x00001fff
2637 -#define BCM43xx_DMADTOR_DTABLEEND (1 << 28) /* End of descriptor table */
2638 -#define BCM43xx_DMADTOR_COMPIRQ (1 << 29) /* IRQ on completion request */
2639 -#define BCM43xx_DMADTOR_FRAMEEND (1 << 30)
2640 -#define BCM43xx_DMADTOR_FRAMESTART (1 << 31)
2641 +
2642 +/*** 32-bit DMA Engine. ***/
2643 +
2644 +/* 32-bit DMA controller registers. */
2645 +#define BCM43xx_DMA32_TXCTL 0x00
2646 +#define BCM43xx_DMA32_TXENABLE 0x00000001
2647 +#define BCM43xx_DMA32_TXSUSPEND 0x00000002
2648 +#define BCM43xx_DMA32_TXLOOPBACK 0x00000004
2649 +#define BCM43xx_DMA32_TXFLUSH 0x00000010
2650 +#define BCM43xx_DMA32_TXADDREXT_MASK 0x00030000
2651 +#define BCM43xx_DMA32_TXADDREXT_SHIFT 16
2652 +#define BCM43xx_DMA32_TXRING 0x04
2653 +#define BCM43xx_DMA32_TXINDEX 0x08
2654 +#define BCM43xx_DMA32_TXSTATUS 0x0C
2655 +#define BCM43xx_DMA32_TXDPTR 0x00000FFF
2656 +#define BCM43xx_DMA32_TXSTATE 0x0000F000
2657 +#define BCM43xx_DMA32_TXSTAT_DISABLED 0x00000000
2658 +#define BCM43xx_DMA32_TXSTAT_ACTIVE 0x00001000
2659 +#define BCM43xx_DMA32_TXSTAT_IDLEWAIT 0x00002000
2660 +#define BCM43xx_DMA32_TXSTAT_STOPPED 0x00003000
2661 +#define BCM43xx_DMA32_TXSTAT_SUSP 0x00004000
2662 +#define BCM43xx_DMA32_TXERROR 0x000F0000
2663 +#define BCM43xx_DMA32_TXERR_NOERR 0x00000000
2664 +#define BCM43xx_DMA32_TXERR_PROT 0x00010000
2665 +#define BCM43xx_DMA32_TXERR_UNDERRUN 0x00020000
2666 +#define BCM43xx_DMA32_TXERR_BUFREAD 0x00030000
2667 +#define BCM43xx_DMA32_TXERR_DESCREAD 0x00040000
2668 +#define BCM43xx_DMA32_TXACTIVE 0xFFF00000
2669 +#define BCM43xx_DMA32_RXCTL 0x10
2670 +#define BCM43xx_DMA32_RXENABLE 0x00000001
2671 +#define BCM43xx_DMA32_RXFROFF_MASK 0x000000FE
2672 +#define BCM43xx_DMA32_RXFROFF_SHIFT 1
2673 +#define BCM43xx_DMA32_RXDIRECTFIFO 0x00000100
2674 +#define BCM43xx_DMA32_RXADDREXT_MASK 0x00030000
2675 +#define BCM43xx_DMA32_RXADDREXT_SHIFT 16
2676 +#define BCM43xx_DMA32_RXRING 0x14
2677 +#define BCM43xx_DMA32_RXINDEX 0x18
2678 +#define BCM43xx_DMA32_RXSTATUS 0x1C
2679 +#define BCM43xx_DMA32_RXDPTR 0x00000FFF
2680 +#define BCM43xx_DMA32_RXSTATE 0x0000F000
2681 +#define BCM43xx_DMA32_RXSTAT_DISABLED 0x00000000
2682 +#define BCM43xx_DMA32_RXSTAT_ACTIVE 0x00001000
2683 +#define BCM43xx_DMA32_RXSTAT_IDLEWAIT 0x00002000
2684 +#define BCM43xx_DMA32_RXSTAT_STOPPED 0x00003000
2685 +#define BCM43xx_DMA32_RXERROR 0x000F0000
2686 +#define BCM43xx_DMA32_RXERR_NOERR 0x00000000
2687 +#define BCM43xx_DMA32_RXERR_PROT 0x00010000
2688 +#define BCM43xx_DMA32_RXERR_OVERFLOW 0x00020000
2689 +#define BCM43xx_DMA32_RXERR_BUFWRITE 0x00030000
2690 +#define BCM43xx_DMA32_RXERR_DESCREAD 0x00040000
2691 +#define BCM43xx_DMA32_RXACTIVE 0xFFF00000
2692 +
2693 +/* 32-bit DMA descriptor. */
2694 +struct bcm43xx_dmadesc32 {
2695 + __le32 control;
2696 + __le32 address;
2697 +} __attribute__((__packed__));
2698 +#define BCM43xx_DMA32_DCTL_BYTECNT 0x00001FFF
2699 +#define BCM43xx_DMA32_DCTL_ADDREXT_MASK 0x00030000
2700 +#define BCM43xx_DMA32_DCTL_ADDREXT_SHIFT 16
2701 +#define BCM43xx_DMA32_DCTL_DTABLEEND 0x10000000
2702 +#define BCM43xx_DMA32_DCTL_IRQ 0x20000000
2703 +#define BCM43xx_DMA32_DCTL_FRAMEEND 0x40000000
2704 +#define BCM43xx_DMA32_DCTL_FRAMESTART 0x80000000
2705 +
2706 +/* Address field Routing value. */
2707 +#define BCM43xx_DMA32_ROUTING 0xC0000000
2708 +#define BCM43xx_DMA32_ROUTING_SHIFT 30
2709 +#define BCM43xx_DMA32_NOTRANS 0x00000000
2710 +#define BCM43xx_DMA32_CLIENTTRANS 0x40000000
2711 +
2712 +
2713 +
2714 +/*** 64-bit DMA Engine. ***/
2715 +
2716 +/* 64-bit DMA controller registers. */
2717 +#define BCM43xx_DMA64_TXCTL 0x00
2718 +#define BCM43xx_DMA64_TXENABLE 0x00000001
2719 +#define BCM43xx_DMA64_TXSUSPEND 0x00000002
2720 +#define BCM43xx_DMA64_TXLOOPBACK 0x00000004
2721 +#define BCM43xx_DMA64_TXFLUSH 0x00000010
2722 +#define BCM43xx_DMA64_TXADDREXT_MASK 0x00030000
2723 +#define BCM43xx_DMA64_TXADDREXT_SHIFT 16
2724 +#define BCM43xx_DMA64_TXINDEX 0x04
2725 +#define BCM43xx_DMA64_TXRINGLO 0x08
2726 +#define BCM43xx_DMA64_TXRINGHI 0x0C
2727 +#define BCM43xx_DMA64_TXSTATUS 0x10
2728 +#define BCM43xx_DMA64_TXSTATDPTR 0x00001FFF
2729 +#define BCM43xx_DMA64_TXSTAT 0xF0000000
2730 +#define BCM43xx_DMA64_TXSTAT_DISABLED 0x00000000
2731 +#define BCM43xx_DMA64_TXSTAT_ACTIVE 0x10000000
2732 +#define BCM43xx_DMA64_TXSTAT_IDLEWAIT 0x20000000
2733 +#define BCM43xx_DMA64_TXSTAT_STOPPED 0x30000000
2734 +#define BCM43xx_DMA64_TXSTAT_SUSP 0x40000000
2735 +#define BCM43xx_DMA64_TXERROR 0x14
2736 +#define BCM43xx_DMA64_TXERRDPTR 0x0001FFFF
2737 +#define BCM43xx_DMA64_TXERR 0xF0000000
2738 +#define BCM43xx_DMA64_TXERR_NOERR 0x00000000
2739 +#define BCM43xx_DMA64_TXERR_PROT 0x10000000
2740 +#define BCM43xx_DMA64_TXERR_UNDERRUN 0x20000000
2741 +#define BCM43xx_DMA64_TXERR_TRANSFER 0x30000000
2742 +#define BCM43xx_DMA64_TXERR_DESCREAD 0x40000000
2743 +#define BCM43xx_DMA64_TXERR_CORE 0x50000000
2744 +#define BCM43xx_DMA64_RXCTL 0x20
2745 +#define BCM43xx_DMA64_RXENABLE 0x00000001
2746 +#define BCM43xx_DMA64_RXFROFF_MASK 0x000000FE
2747 +#define BCM43xx_DMA64_RXFROFF_SHIFT 1
2748 +#define BCM43xx_DMA64_RXDIRECTFIFO 0x00000100
2749 +#define BCM43xx_DMA64_RXADDREXT_MASK 0x00030000
2750 +#define BCM43xx_DMA64_RXADDREXT_SHIFT 16
2751 +#define BCM43xx_DMA64_RXINDEX 0x24
2752 +#define BCM43xx_DMA64_RXRINGLO 0x28
2753 +#define BCM43xx_DMA64_RXRINGHI 0x2C
2754 +#define BCM43xx_DMA64_RXSTATUS 0x30
2755 +#define BCM43xx_DMA64_RXSTATDPTR 0x00001FFF
2756 +#define BCM43xx_DMA64_RXSTAT 0xF0000000
2757 +#define BCM43xx_DMA64_RXSTAT_DISABLED 0x00000000
2758 +#define BCM43xx_DMA64_RXSTAT_ACTIVE 0x10000000
2759 +#define BCM43xx_DMA64_RXSTAT_IDLEWAIT 0x20000000
2760 +#define BCM43xx_DMA64_RXSTAT_STOPPED 0x30000000
2761 +#define BCM43xx_DMA64_RXSTAT_SUSP 0x40000000
2762 +#define BCM43xx_DMA64_RXERROR 0x34
2763 +#define BCM43xx_DMA64_RXERRDPTR 0x0001FFFF
2764 +#define BCM43xx_DMA64_RXERR 0xF0000000
2765 +#define BCM43xx_DMA64_RXERR_NOERR 0x00000000
2766 +#define BCM43xx_DMA64_RXERR_PROT 0x10000000
2767 +#define BCM43xx_DMA64_RXERR_UNDERRUN 0x20000000
2768 +#define BCM43xx_DMA64_RXERR_TRANSFER 0x30000000
2769 +#define BCM43xx_DMA64_RXERR_DESCREAD 0x40000000
2770 +#define BCM43xx_DMA64_RXERR_CORE 0x50000000
2771 +
2772 +/* 64-bit DMA descriptor. */
2773 +struct bcm43xx_dmadesc64 {
2774 + __le32 control0;
2775 + __le32 control1;
2776 + __le32 address_low;
2777 + __le32 address_high;
2778 +} __attribute__((__packed__));
2779 +#define BCM43xx_DMA64_DCTL0_DTABLEEND 0x10000000
2780 +#define BCM43xx_DMA64_DCTL0_IRQ 0x20000000
2781 +#define BCM43xx_DMA64_DCTL0_FRAMEEND 0x40000000
2782 +#define BCM43xx_DMA64_DCTL0_FRAMESTART 0x80000000
2783 +#define BCM43xx_DMA64_DCTL1_BYTECNT 0x00001FFF
2784 +#define BCM43xx_DMA64_DCTL1_ADDREXT_MASK 0x00030000
2785 +#define BCM43xx_DMA64_DCTL1_ADDREXT_SHIFT 16
2786 +
2787 +/* Address field Routing value. */
2788 +#define BCM43xx_DMA64_ROUTING 0xC0000000
2789 +#define BCM43xx_DMA64_ROUTING_SHIFT 30
2790 +#define BCM43xx_DMA64_NOTRANS 0x00000000
2791 +#define BCM43xx_DMA64_CLIENTTRANS 0x80000000
2792 +
2793 +
2794 +
2795 +struct bcm43xx_dmadesc_generic {
2796 + union {
2797 + struct bcm43xx_dmadesc32 dma32;
2798 + struct bcm43xx_dmadesc64 dma64;
2799 + } __attribute__((__packed__));
2800 +} __attribute__((__packed__));
2801 +
2802
2803 /* Misc DMA constants */
2804 #define BCM43xx_DMA_RINGMEMSIZE PAGE_SIZE
2805 -#define BCM43xx_DMA_BUSADDRMAX 0x3FFFFFFF
2806 -#define BCM43xx_DMA_DMABUSADDROFFSET (1 << 30)
2807 -#define BCM43xx_DMA1_RX_FRAMEOFFSET 30
2808 -#define BCM43xx_DMA4_RX_FRAMEOFFSET 0
2809 +#define BCM43xx_DMA0_RX_FRAMEOFFSET 30
2810 +#define BCM43xx_DMA3_RX_FRAMEOFFSET 0
2811 +
2812
2813 /* DMA engine tuning knobs */
2814 #define BCM43xx_TXRING_SLOTS 512
2815 #define BCM43xx_RXRING_SLOTS 64
2816 -#define BCM43xx_DMA1_RXBUFFERSIZE (2304 + 100)
2817 -#define BCM43xx_DMA4_RXBUFFERSIZE 16
2818 +#define BCM43xx_DMA0_RX_BUFFERSIZE (2304 + 100)
2819 +#define BCM43xx_DMA3_RX_BUFFERSIZE 16
2820 /* Suspend the tx queue, if less than this percent slots are free. */
2821 #define BCM43xx_TXSUSPEND_PERCENT 20
2822 /* Resume the tx queue, if more than this percent slots are free. */
2823 @@ -86,17 +202,6 @@ struct bcm43xx_private;
2824 struct bcm43xx_xmitstatus;
2825
2826
2827 -struct bcm43xx_dmadesc {
2828 - __le32 _control;
2829 - __le32 _address;
2830 -} __attribute__((__packed__));
2831 -
2832 -/* Macros to access the bcm43xx_dmadesc struct */
2833 -#define get_desc_ctl(desc) le32_to_cpu((desc)->_control)
2834 -#define set_desc_ctl(desc, ctl) do { (desc)->_control = cpu_to_le32(ctl); } while (0)
2835 -#define get_desc_addr(desc) le32_to_cpu((desc)->_address)
2836 -#define set_desc_addr(desc, addr) do { (desc)->_address = cpu_to_le32(addr); } while (0)
2837 -
2838 struct bcm43xx_dmadesc_meta {
2839 /* The kernel DMA-able buffer. */
2840 struct sk_buff *skb;
2841 @@ -105,15 +210,14 @@ struct bcm43xx_dmadesc_meta {
2842 };
2843
2844 struct bcm43xx_dmaring {
2845 - struct bcm43xx_private *bcm;
2846 /* Kernel virtual base address of the ring memory. */
2847 - struct bcm43xx_dmadesc *vbase;
2848 - /* DMA memory offset */
2849 - dma_addr_t memoffset;
2850 - /* (Unadjusted) DMA base bus-address of the ring memory. */
2851 - dma_addr_t dmabase;
2852 + void *descbase;
2853 /* Meta data about all descriptors. */
2854 struct bcm43xx_dmadesc_meta *meta;
2855 + /* DMA Routing value. */
2856 + u32 routing;
2857 + /* (Unadjusted) DMA base bus-address of the ring memory. */
2858 + dma_addr_t dmabase;
2859 /* Number of descriptor slots in the ring. */
2860 int nr_slots;
2861 /* Number of used descriptor slots. */
2862 @@ -127,12 +231,17 @@ struct bcm43xx_dmaring {
2863 u32 frameoffset;
2864 /* Descriptor buffer size. */
2865 u16 rx_buffersize;
2866 - /* The MMIO base register of the DMA controller, this
2867 - * ring is posted to.
2868 - */
2869 + /* The MMIO base register of the DMA controller. */
2870 u16 mmio_base;
2871 - u8 tx:1, /* TRUE, if this is a TX ring. */
2872 - suspended:1; /* TRUE, if transfers are suspended on this ring. */
2873 + /* DMA controller index number (0-5). */
2874 + int index;
2875 + /* Boolean. Is this a TX ring? */
2876 + u8 tx;
2877 + /* Boolean. 64bit DMA if true, 32bit DMA otherwise. */
2878 + u8 dma64;
2879 + /* Boolean. Are transfers suspended on this ring? */
2880 + u8 suspended;
2881 + struct bcm43xx_private *bcm;
2882 #ifdef CONFIG_BCM43XX_DEBUG
2883 /* Maximum number of used slots. */
2884 int max_used_slots;
2885 @@ -141,6 +250,34 @@ #endif /* CONFIG_BCM43XX_DEBUG*/
2886
2887
2888 static inline
2889 +int bcm43xx_dma_desc2idx(struct bcm43xx_dmaring *ring,
2890 + struct bcm43xx_dmadesc_generic *desc)
2891 +{
2892 + if (ring->dma64) {
2893 + struct bcm43xx_dmadesc64 *dd64 = ring->descbase;
2894 + return (int)(&(desc->dma64) - dd64);
2895 + } else {
2896 + struct bcm43xx_dmadesc32 *dd32 = ring->descbase;
2897 + return (int)(&(desc->dma32) - dd32);
2898 + }
2899 +}
2900 +
2901 +static inline
2902 +struct bcm43xx_dmadesc_generic * bcm43xx_dma_idx2desc(struct bcm43xx_dmaring *ring,
2903 + int slot,
2904 + struct bcm43xx_dmadesc_meta **meta)
2905 +{
2906 + *meta = &(ring->meta[slot]);
2907 + if (ring->dma64) {
2908 + struct bcm43xx_dmadesc64 *dd64 = ring->descbase;
2909 + return (struct bcm43xx_dmadesc_generic *)(&(dd64[slot]));
2910 + } else {
2911 + struct bcm43xx_dmadesc32 *dd32 = ring->descbase;
2912 + return (struct bcm43xx_dmadesc_generic *)(&(dd32[slot]));
2913 + }
2914 +}
2915 +
2916 +static inline
2917 u32 bcm43xx_dma_read(struct bcm43xx_dmaring *ring,
2918 u16 offset)
2919 {
2920 @@ -159,9 +296,13 @@ int bcm43xx_dma_init(struct bcm43xx_priv
2921 void bcm43xx_dma_free(struct bcm43xx_private *bcm);
2922
2923 int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
2924 - u16 dmacontroller_mmio_base);
2925 + u16 dmacontroller_mmio_base,
2926 + int dma64);
2927 int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
2928 - u16 dmacontroller_mmio_base);
2929 + u16 dmacontroller_mmio_base,
2930 + int dma64);
2931 +
2932 +u16 bcm43xx_dmacontroller_base(int dma64bit, int dmacontroller_idx);
2933
2934 void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring);
2935 void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring);
2936 @@ -173,7 +314,6 @@ int bcm43xx_dma_tx(struct bcm43xx_privat
2937 struct ieee80211_txb *txb);
2938 void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
2939
2940 -
2941 #else /* CONFIG_BCM43XX_DMA */
2942
2943
2944 @@ -188,13 +328,15 @@ void bcm43xx_dma_free(struct bcm43xx_pri
2945 }
2946 static inline
2947 int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
2948 - u16 dmacontroller_mmio_base)
2949 + u16 dmacontroller_mmio_base,
2950 + int dma64)
2951 {
2952 return 0;
2953 }
2954 static inline
2955 int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
2956 - u16 dmacontroller_mmio_base)
2957 + u16 dmacontroller_mmio_base,
2958 + int dma64)
2959 {
2960 return 0;
2961 }
2962 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
2963 index ec80692..c3f90c8 100644
2964 --- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
2965 +++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
2966 @@ -51,12 +51,12 @@ static void bcm43xx_led_blink(unsigned l
2967 struct bcm43xx_private *bcm = led->bcm;
2968 unsigned long flags;
2969
2970 - bcm43xx_lock_irqonly(bcm, flags);
2971 + spin_lock_irqsave(&bcm->leds_lock, flags);
2972 if (led->blink_interval) {
2973 bcm43xx_led_changestate(led);
2974 mod_timer(&led->blink_timer, jiffies + led->blink_interval);
2975 }
2976 - bcm43xx_unlock_irqonly(bcm, flags);
2977 + spin_unlock_irqrestore(&bcm->leds_lock, flags);
2978 }
2979
2980 static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
2981 @@ -177,7 +177,9 @@ void bcm43xx_leds_update(struct bcm43xx_
2982 int i, turn_on;
2983 unsigned long interval = 0;
2984 u16 ledctl;
2985 + unsigned long flags;
2986
2987 + spin_lock_irqsave(&bcm->leds_lock, flags);
2988 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
2989 for (i = 0; i < BCM43xx_NR_LEDS; i++) {
2990 led = &(bcm->leds[i]);
2991 @@ -266,6 +268,7 @@ #endif /* CONFIG_BCM43XX_DEBUG */
2992 ledctl &= ~(1 << i);
2993 }
2994 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
2995 + spin_unlock_irqrestore(&bcm->leds_lock, flags);
2996 }
2997
2998 void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
2999 @@ -274,7 +277,9 @@ void bcm43xx_leds_switch_all(struct bcm4
3000 u16 ledctl;
3001 int i;
3002 int bit_on;
3003 + unsigned long flags;
3004
3005 + spin_lock_irqsave(&bcm->leds_lock, flags);
3006 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
3007 for (i = 0; i < BCM43xx_NR_LEDS; i++) {
3008 led = &(bcm->leds[i]);
3009 @@ -290,4 +295,5 @@ void bcm43xx_leds_switch_all(struct bcm4
3010 ledctl &= ~(1 << i);
3011 }
3012 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
3013 + spin_unlock_irqrestore(&bcm->leds_lock, flags);
3014 }
3015 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
3016 index df317c1..3a73d89 100644
3017 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
3018 +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
3019 @@ -509,23 +509,20 @@ static void bcm43xx_synchronize_irq(stru
3020 }
3021
3022 /* Make sure we don't receive more data from the device. */
3023 -static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *oldstate)
3024 +static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm)
3025 {
3026 unsigned long flags;
3027 - u32 old;
3028
3029 - bcm43xx_lock_irqonly(bcm, flags);
3030 + spin_lock_irqsave(&bcm->irq_lock, flags);
3031 if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) {
3032 - bcm43xx_unlock_irqonly(bcm, flags);
3033 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
3034 return -EBUSY;
3035 }
3036 - old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3037 - bcm43xx_unlock_irqonly(bcm, flags);
3038 + bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3039 + bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); /* flush */
3040 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
3041 bcm43xx_synchronize_irq(bcm);
3042
3043 - if (oldstate)
3044 - *oldstate = old;
3045 -
3046 return 0;
3047 }
3048
3049 @@ -537,7 +534,6 @@ static int bcm43xx_read_radioinfo(struct
3050 u16 manufact;
3051 u16 version;
3052 u8 revision;
3053 - s8 i;
3054
3055 if (bcm->chip_id == 0x4317) {
3056 if (bcm->chip_rev == 0x00)
3057 @@ -580,20 +576,11 @@ static int bcm43xx_read_radioinfo(struct
3058 radio->version = version;
3059 radio->revision = revision;
3060
3061 - /* Set default attenuation values. */
3062 - radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
3063 - radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
3064 - radio->txctl1 = bcm43xx_default_txctl1(bcm);
3065 - radio->txctl2 = 0xFFFF;
3066 if (phy->type == BCM43xx_PHYTYPE_A)
3067 radio->txpower_desired = bcm->sprom.maxpower_aphy;
3068 else
3069 radio->txpower_desired = bcm->sprom.maxpower_bgphy;
3070
3071 - /* Initialize the in-memory nrssi Lookup Table. */
3072 - for (i = 0; i < 64; i++)
3073 - radio->nrssi_lt[i] = i;
3074 -
3075 return 0;
3076
3077 err_unsupported_radio:
3078 @@ -1250,10 +1237,6 @@ int bcm43xx_switch_core(struct bcm43xx_p
3079 goto out;
3080
3081 bcm->current_core = new_core;
3082 - bcm->current_80211_core_idx = -1;
3083 - if (new_core->id == BCM43xx_COREID_80211)
3084 - bcm->current_80211_core_idx = (int)(new_core - &(bcm->core_80211[0]));
3085 -
3086 out:
3087 return err;
3088 }
3089 @@ -1389,6 +1372,7 @@ void bcm43xx_wireless_core_reset(struct
3090 if ((bcm43xx_core_enabled(bcm)) &&
3091 !bcm43xx_using_pio(bcm)) {
3092 //FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here?
3093 +#if 0
3094 #ifndef CONFIG_BCM947XX
3095 /* reset all used DMA controllers. */
3096 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
3097 @@ -1399,6 +1383,7 @@ #ifndef CONFIG_BCM947XX
3098 if (bcm->current_core->rev < 5)
3099 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
3100 #endif
3101 +#endif
3102 }
3103 if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) {
3104 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
3105 @@ -1423,43 +1408,23 @@ static void bcm43xx_wireless_core_disabl
3106 bcm43xx_core_disable(bcm, 0);
3107 }
3108
3109 -/* Mark the current 80211 core inactive.
3110 - * "active_80211_core" is the other 80211 core, which is used.
3111 - */
3112 -static int bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm,
3113 - struct bcm43xx_coreinfo *active_80211_core)
3114 +/* Mark the current 80211 core inactive. */
3115 +static void bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm)
3116 {
3117 u32 sbtmstatelow;
3118 - struct bcm43xx_coreinfo *old_core;
3119 - int err = 0;
3120
3121 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3122 bcm43xx_radio_turn_off(bcm);
3123 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
3124 - sbtmstatelow &= ~0x200a0000;
3125 - sbtmstatelow |= 0xa0000;
3126 + sbtmstatelow &= 0xDFF5FFFF;
3127 + sbtmstatelow |= 0x000A0000;
3128 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
3129 udelay(1);
3130 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
3131 - sbtmstatelow &= ~0xa0000;
3132 - sbtmstatelow |= 0x80000;
3133 + sbtmstatelow &= 0xFFF5FFFF;
3134 + sbtmstatelow |= 0x00080000;
3135 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
3136 udelay(1);
3137 -
3138 - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G) {
3139 - old_core = bcm->current_core;
3140 - err = bcm43xx_switch_core(bcm, active_80211_core);
3141 - if (err)
3142 - goto out;
3143 - sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
3144 - sbtmstatelow &= ~0x20000000;
3145 - sbtmstatelow |= 0x20000000;
3146 - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
3147 - err = bcm43xx_switch_core(bcm, old_core);
3148 - }
3149 -
3150 -out:
3151 - return err;
3152 }
3153
3154 static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
3155 @@ -1581,17 +1546,7 @@ static void handle_irq_noise(struct bcm4
3156 else
3157 average -= 48;
3158
3159 -/* FIXME: This is wrong, but people want fancy stats. well... */
3160 -bcm->stats.noise = average;
3161 - if (average > -65)
3162 - bcm->stats.link_quality = 0;
3163 - else if (average > -75)
3164 - bcm->stats.link_quality = 1;
3165 - else if (average > -85)
3166 - bcm->stats.link_quality = 2;
3167 - else
3168 - bcm->stats.link_quality = 3;
3169 -// dprintk(KERN_INFO PFX "Link Quality: %u (avg was %d)\n", bcm->stats.link_quality, average);
3170 + bcm->stats.noise = average;
3171 drop_calculation:
3172 bcm->noisecalc.calculation_running = 0;
3173 return;
3174 @@ -1709,8 +1664,9 @@ static void handle_irq_beacon(struct bcm
3175 static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
3176 {
3177 u32 reason;
3178 - u32 dma_reason[4];
3179 - int activity = 0;
3180 + u32 dma_reason[6];
3181 + u32 merged_dma_reason = 0;
3182 + int i, activity = 0;
3183 unsigned long flags;
3184
3185 #ifdef CONFIG_BCM43XX_DEBUG
3186 @@ -1720,12 +1676,12 @@ #else
3187 # define bcmirq_handled(irq) do { /* nothing */ } while (0)
3188 #endif /* CONFIG_BCM43XX_DEBUG*/
3189
3190 - bcm43xx_lock_irqonly(bcm, flags);
3191 + spin_lock_irqsave(&bcm->irq_lock, flags);
3192 reason = bcm->irq_reason;
3193 - dma_reason[0] = bcm->dma_reason[0];
3194 - dma_reason[1] = bcm->dma_reason[1];
3195 - dma_reason[2] = bcm->dma_reason[2];
3196 - dma_reason[3] = bcm->dma_reason[3];
3197 + for (i = 5; i >= 0; i--) {
3198 + dma_reason[i] = bcm->dma_reason[i];
3199 + merged_dma_reason |= dma_reason[i];
3200 + }
3201
3202 if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) {
3203 /* TX error. We get this when Template Ram is written in wrong endianess
3204 @@ -1736,27 +1692,25 @@ #endif /* CONFIG_BCM43XX_DEBUG*/
3205 printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
3206 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
3207 }
3208 - if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) |
3209 - (dma_reason[1] & BCM43xx_DMAIRQ_FATALMASK) |
3210 - (dma_reason[2] & BCM43xx_DMAIRQ_FATALMASK) |
3211 - (dma_reason[3] & BCM43xx_DMAIRQ_FATALMASK))) {
3212 + if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_FATALMASK)) {
3213 printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
3214 - "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
3215 + "0x%08X, 0x%08X, 0x%08X, "
3216 + "0x%08X, 0x%08X, 0x%08X\n",
3217 dma_reason[0], dma_reason[1],
3218 - dma_reason[2], dma_reason[3]);
3219 + dma_reason[2], dma_reason[3],
3220 + dma_reason[4], dma_reason[5]);
3221 bcm43xx_controller_restart(bcm, "DMA error");
3222 mmiowb();
3223 - bcm43xx_unlock_irqonly(bcm, flags);
3224 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
3225 return;
3226 }
3227 - if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) |
3228 - (dma_reason[1] & BCM43xx_DMAIRQ_NONFATALMASK) |
3229 - (dma_reason[2] & BCM43xx_DMAIRQ_NONFATALMASK) |
3230 - (dma_reason[3] & BCM43xx_DMAIRQ_NONFATALMASK))) {
3231 + if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_NONFATALMASK)) {
3232 printkl(KERN_ERR PFX "DMA error: "
3233 - "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
3234 + "0x%08X, 0x%08X, 0x%08X, "
3235 + "0x%08X, 0x%08X, 0x%08X\n",
3236 dma_reason[0], dma_reason[1],
3237 - dma_reason[2], dma_reason[3]);
3238 + dma_reason[2], dma_reason[3],
3239 + dma_reason[4], dma_reason[5]);
3240 }
3241
3242 if (reason & BCM43xx_IRQ_PS) {
3243 @@ -1791,8 +1745,6 @@ #endif /* CONFIG_BCM43XX_DEBUG*/
3244 }
3245
3246 /* Check the DMA reason registers for received data. */
3247 - assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
3248 - assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
3249 if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) {
3250 if (bcm43xx_using_pio(bcm))
3251 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0);
3252 @@ -1800,13 +1752,17 @@ #endif /* CONFIG_BCM43XX_DEBUG*/
3253 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0);
3254 /* We intentionally don't set "activity" to 1, here. */
3255 }
3256 + assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
3257 + assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
3258 if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
3259 if (bcm43xx_using_pio(bcm))
3260 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3);
3261 else
3262 - bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring1);
3263 + bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring3);
3264 activity = 1;
3265 }
3266 + assert(!(dma_reason[4] & BCM43xx_DMAIRQ_RX_DONE));
3267 + assert(!(dma_reason[5] & BCM43xx_DMAIRQ_RX_DONE));
3268 bcmirq_handled(BCM43xx_IRQ_RX);
3269
3270 if (reason & BCM43xx_IRQ_XMIT_STATUS) {
3271 @@ -1834,7 +1790,7 @@ #undef bcmirq_handled
3272 bcm43xx_leds_update(bcm, activity);
3273 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
3274 mmiowb();
3275 - bcm43xx_unlock_irqonly(bcm, flags);
3276 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
3277 }
3278
3279 static void pio_irq_workaround(struct bcm43xx_private *bcm,
3280 @@ -1863,14 +1819,18 @@ static void bcm43xx_interrupt_ack(struct
3281
3282 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
3283
3284 - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
3285 + bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_REASON,
3286 bcm->dma_reason[0]);
3287 - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
3288 + bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
3289 bcm->dma_reason[1]);
3290 - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
3291 + bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
3292 bcm->dma_reason[2]);
3293 - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
3294 + bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
3295 bcm->dma_reason[3]);
3296 + bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
3297 + bcm->dma_reason[4]);
3298 + bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_REASON,
3299 + bcm->dma_reason[5]);
3300 }
3301
3302 /* Interrupt handler top-half */
3303 @@ -1885,14 +1845,8 @@ static irqreturn_t bcm43xx_interrupt_han
3304
3305 spin_lock(&bcm->irq_lock);
3306
3307 - /* Only accept IRQs, if we are initialized properly.
3308 - * This avoids an RX race while initializing.
3309 - * We should probably not enable IRQs before we are initialized
3310 - * completely, but some careful work is needed to fix this. I think it
3311 - * is best to stay with this cheap workaround for now... .
3312 - */
3313 - if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED))
3314 - goto out;
3315 + assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
3316 + assert(bcm->current_core->id == BCM43xx_COREID_80211);
3317
3318 reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
3319 if (reason == 0xffffffff) {
3320 @@ -1904,14 +1858,18 @@ static irqreturn_t bcm43xx_interrupt_han
3321 if (!reason)
3322 goto out;
3323
3324 - bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
3325 - & 0x0001dc00;
3326 - bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
3327 - & 0x0000dc00;
3328 - bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
3329 - & 0x0000dc00;
3330 - bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
3331 - & 0x0001dc00;
3332 + bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA0_REASON)
3333 + & 0x0001DC00;
3334 + bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
3335 + & 0x0000DC00;
3336 + bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
3337 + & 0x0000DC00;
3338 + bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
3339 + & 0x0001DC00;
3340 + bcm->dma_reason[4] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
3341 + & 0x0000DC00;
3342 + bcm->dma_reason[5] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA5_REASON)
3343 + & 0x0000DC00;
3344
3345 bcm43xx_interrupt_ack(bcm, reason);
3346
3347 @@ -1930,16 +1888,18 @@ out:
3348
3349 static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force)
3350 {
3351 + struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3352 +
3353 if (bcm->firmware_norelease && !force)
3354 return; /* Suspending or controller reset. */
3355 - release_firmware(bcm->ucode);
3356 - bcm->ucode = NULL;
3357 - release_firmware(bcm->pcm);
3358 - bcm->pcm = NULL;
3359 - release_firmware(bcm->initvals0);
3360 - bcm->initvals0 = NULL;
3361 - release_firmware(bcm->initvals1);
3362 - bcm->initvals1 = NULL;
3363 + release_firmware(phy->ucode);
3364 + phy->ucode = NULL;
3365 + release_firmware(phy->pcm);
3366 + phy->pcm = NULL;
3367 + release_firmware(phy->initvals0);
3368 + phy->initvals0 = NULL;
3369 + release_firmware(phy->initvals1);
3370 + phy->initvals1 = NULL;
3371 }
3372
3373 static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
3374 @@ -1950,11 +1910,11 @@ static int bcm43xx_request_firmware(stru
3375 int nr;
3376 char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 };
3377
3378 - if (!bcm->ucode) {
3379 + if (!phy->ucode) {
3380 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw",
3381 (rev >= 5 ? 5 : rev),
3382 modparam_fwpostfix);
3383 - err = request_firmware(&bcm->ucode, buf, &bcm->pci_dev->dev);
3384 + err = request_firmware(&phy->ucode, buf, &bcm->pci_dev->dev);
3385 if (err) {
3386 printk(KERN_ERR PFX
3387 "Error: Microcode \"%s\" not available or load failed.\n",
3388 @@ -1963,12 +1923,12 @@ static int bcm43xx_request_firmware(stru
3389 }
3390 }
3391
3392 - if (!bcm->pcm) {
3393 + if (!phy->pcm) {
3394 snprintf(buf, ARRAY_SIZE(buf),
3395 "bcm43xx_pcm%d%s.fw",
3396 (rev < 5 ? 4 : 5),
3397 modparam_fwpostfix);
3398 - err = request_firmware(&bcm->pcm, buf, &bcm->pci_dev->dev);
3399 + err = request_firmware(&phy->pcm, buf, &bcm->pci_dev->dev);
3400 if (err) {
3401 printk(KERN_ERR PFX
3402 "Error: PCM \"%s\" not available or load failed.\n",
3403 @@ -1977,7 +1937,7 @@ static int bcm43xx_request_firmware(stru
3404 }
3405 }
3406
3407 - if (!bcm->initvals0) {
3408 + if (!phy->initvals0) {
3409 if (rev == 2 || rev == 4) {
3410 switch (phy->type) {
3411 case BCM43xx_PHYTYPE_A:
3412 @@ -2008,20 +1968,20 @@ static int bcm43xx_request_firmware(stru
3413 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
3414 nr, modparam_fwpostfix);
3415
3416 - err = request_firmware(&bcm->initvals0, buf, &bcm->pci_dev->dev);
3417 + err = request_firmware(&phy->initvals0, buf, &bcm->pci_dev->dev);
3418 if (err) {
3419 printk(KERN_ERR PFX
3420 "Error: InitVals \"%s\" not available or load failed.\n",
3421 buf);
3422 goto error;
3423 }
3424 - if (bcm->initvals0->size % sizeof(struct bcm43xx_initval)) {
3425 + if (phy->initvals0->size % sizeof(struct bcm43xx_initval)) {
3426 printk(KERN_ERR PFX "InitVals fileformat error.\n");
3427 goto error;
3428 }
3429 }
3430
3431 - if (!bcm->initvals1) {
3432 + if (!phy->initvals1) {
3433 if (rev >= 5) {
3434 u32 sbtmstatehigh;
3435
3436 @@ -2043,14 +2003,14 @@ static int bcm43xx_request_firmware(stru
3437 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
3438 nr, modparam_fwpostfix);
3439
3440 - err = request_firmware(&bcm->initvals1, buf, &bcm->pci_dev->dev);
3441 + err = request_firmware(&phy->initvals1, buf, &bcm->pci_dev->dev);
3442 if (err) {
3443 printk(KERN_ERR PFX
3444 "Error: InitVals \"%s\" not available or load failed.\n",
3445 buf);
3446 goto error;
3447 }
3448 - if (bcm->initvals1->size % sizeof(struct bcm43xx_initval)) {
3449 + if (phy->initvals1->size % sizeof(struct bcm43xx_initval)) {
3450 printk(KERN_ERR PFX "InitVals fileformat error.\n");
3451 goto error;
3452 }
3453 @@ -2070,12 +2030,13 @@ err_noinitval:
3454
3455 static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
3456 {
3457 + struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3458 const u32 *data;
3459 unsigned int i, len;
3460
3461 /* Upload Microcode. */
3462 - data = (u32 *)(bcm->ucode->data);
3463 - len = bcm->ucode->size / sizeof(u32);
3464 + data = (u32 *)(phy->ucode->data);
3465 + len = phy->ucode->size / sizeof(u32);
3466 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000);
3467 for (i = 0; i < len; i++) {
3468 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
3469 @@ -2084,8 +2045,8 @@ static void bcm43xx_upload_microcode(str
3470 }
3471
3472 /* Upload PCM data. */
3473 - data = (u32 *)(bcm->pcm->data);
3474 - len = bcm->pcm->size / sizeof(u32);
3475 + data = (u32 *)(phy->pcm->data);
3476 + len = phy->pcm->size / sizeof(u32);
3477 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea);
3478 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000);
3479 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb);
3480 @@ -2131,15 +2092,16 @@ err_format:
3481
3482 static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm)
3483 {
3484 + struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3485 int err;
3486
3487 - err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals0->data,
3488 - bcm->initvals0->size / sizeof(struct bcm43xx_initval));
3489 + err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)phy->initvals0->data,
3490 + phy->initvals0->size / sizeof(struct bcm43xx_initval));
3491 if (err)
3492 goto out;
3493 - if (bcm->initvals1) {
3494 - err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals1->data,
3495 - bcm->initvals1->size / sizeof(struct bcm43xx_initval));
3496 + if (phy->initvals1) {
3497 + err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)phy->initvals1->data,
3498 + phy->initvals1->size / sizeof(struct bcm43xx_initval));
3499 if (err)
3500 goto out;
3501 }
3502 @@ -2156,9 +2118,7 @@ #endif
3503
3504 static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
3505 {
3506 - int res;
3507 - unsigned int i;
3508 - u32 data;
3509 + int err;
3510
3511 bcm->irq = bcm->pci_dev->irq;
3512 #ifdef CONFIG_BCM947XX
3513 @@ -2175,32 +2135,12 @@ #ifdef CONFIG_BCM947XX
3514 }
3515 }
3516 #endif
3517 - res = request_irq(bcm->irq, bcm43xx_interrupt_handler,
3518 + err = request_irq(bcm->irq, bcm43xx_interrupt_handler,
3519 IRQF_SHARED, KBUILD_MODNAME, bcm);
3520 - if (res) {
3521 + if (err)
3522 printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq);
3523 - return -ENODEV;
3524 - }
3525 - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xffffffff);
3526 - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
3527 - i = 0;
3528 - while (1) {
3529 - data = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
3530 - if (data == BCM43xx_IRQ_READY)
3531 - break;
3532 - i++;
3533 - if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
3534 - printk(KERN_ERR PFX "Card IRQ register not responding. "
3535 - "Giving up.\n");
3536 - free_irq(bcm->irq, bcm);
3537 - return -ENODEV;
3538 - }
3539 - udelay(10);
3540 - }
3541 - // dummy read
3542 - bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
3543
3544 - return 0;
3545 + return err;
3546 }
3547
3548 /* Switch to the core used to write the GPIO register.
3549 @@ -2298,13 +2238,17 @@ static int bcm43xx_gpio_cleanup(struct b
3550 /* http://bcm-specs.sipsolutions.net/EnableMac */
3551 void bcm43xx_mac_enable(struct bcm43xx_private *bcm)
3552 {
3553 - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
3554 - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
3555 - | BCM43xx_SBF_MAC_ENABLED);
3556 - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY);
3557 - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
3558 - bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
3559 - bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
3560 + bcm->mac_suspended--;
3561 + assert(bcm->mac_suspended >= 0);
3562 + if (bcm->mac_suspended == 0) {
3563 + bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
3564 + bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
3565 + | BCM43xx_SBF_MAC_ENABLED);
3566 + bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY);
3567 + bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
3568 + bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
3569 + bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
3570 + }
3571 }
3572
3573 /* http://bcm-specs.sipsolutions.net/SuspendMAC */
3574 @@ -2313,18 +2257,23 @@ void bcm43xx_mac_suspend(struct bcm43xx_
3575 int i;
3576 u32 tmp;
3577
3578 - bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
3579 - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
3580 - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
3581 - & ~BCM43xx_SBF_MAC_ENABLED);
3582 - bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
3583 - for (i = 100000; i; i--) {
3584 - tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
3585 - if (tmp & BCM43xx_IRQ_READY)
3586 - return;
3587 - udelay(10);
3588 + assert(bcm->mac_suspended >= 0);
3589 + if (bcm->mac_suspended == 0) {
3590 + bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
3591 + bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
3592 + bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
3593 + & ~BCM43xx_SBF_MAC_ENABLED);
3594 + bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
3595 + for (i = 10000; i; i--) {
3596 + tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
3597 + if (tmp & BCM43xx_IRQ_READY)
3598 + goto out;
3599 + udelay(1);
3600 + }
3601 + printkl(KERN_ERR PFX "MAC suspend failed\n");
3602 }
3603 - printkl(KERN_ERR PFX "MAC suspend failed\n");
3604 +out:
3605 + bcm->mac_suspended++;
3606 }
3607
3608 void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
3609 @@ -2394,7 +2343,6 @@ static void bcm43xx_chip_cleanup(struct
3610 if (!modparam_noleds)
3611 bcm43xx_leds_exit(bcm);
3612 bcm43xx_gpio_cleanup(bcm);
3613 - free_irq(bcm->irq, bcm);
3614 bcm43xx_release_firmware(bcm, 0);
3615 }
3616
3617 @@ -2406,7 +2354,7 @@ static int bcm43xx_chip_init(struct bcm4
3618 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
3619 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3620 int err;
3621 - int tmp;
3622 + int i, tmp;
3623 u32 value32;
3624 u16 value16;
3625
3626 @@ -2419,13 +2367,53 @@ static int bcm43xx_chip_init(struct bcm4
3627 goto out;
3628 bcm43xx_upload_microcode(bcm);
3629
3630 - err = bcm43xx_initialize_irq(bcm);
3631 - if (err)
3632 + bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xFFFFFFFF);
3633 + bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
3634 + i = 0;
3635 + while (1) {
3636 + value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
3637 + if (value32 == BCM43xx_IRQ_READY)
3638 + break;
3639 + i++;
3640 + if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
3641 + printk(KERN_ERR PFX "IRQ_READY timeout\n");
3642 + err = -ENODEV;
3643 + goto err_release_fw;
3644 + }
3645 + udelay(10);
3646 + }
3647 + bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
3648 +
3649 + value16 = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3650 + BCM43xx_UCODE_REVISION);
3651 +
3652 + dprintk(KERN_INFO PFX "Microcode rev 0x%x, pl 0x%x "
3653 + "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", value16,
3654 + bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3655 + BCM43xx_UCODE_PATCHLEVEL),
3656 + (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3657 + BCM43xx_UCODE_DATE) >> 12) & 0xf,
3658 + (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3659 + BCM43xx_UCODE_DATE) >> 8) & 0xf,
3660 + bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3661 + BCM43xx_UCODE_DATE) & 0xff,
3662 + (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3663 + BCM43xx_UCODE_TIME) >> 11) & 0x1f,
3664 + (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3665 + BCM43xx_UCODE_TIME) >> 5) & 0x3f,
3666 + bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3667 + BCM43xx_UCODE_TIME) & 0x1f);
3668 +
3669 + if ( value16 > 0x128 ) {
3670 + dprintk(KERN_ERR PFX
3671 + "Firmware: no support for microcode rev > 0x128\n");
3672 + err = -1;
3673 goto err_release_fw;
3674 + }
3675
3676 err = bcm43xx_gpio_init(bcm);
3677 if (err)
3678 - goto err_free_irq;
3679 + goto err_release_fw;
3680
3681 err = bcm43xx_upload_initvals(bcm);
3682 if (err)
3683 @@ -2489,10 +2477,12 @@ static int bcm43xx_chip_init(struct bcm4
3684 bcm43xx_write32(bcm, 0x018C, 0x02000000);
3685 }
3686 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000);
3687 - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0001DC00);
3688 + bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_IRQ_MASK, 0x0001DC00);
3689 + bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
3690 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
3691 - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0000DC00);
3692 - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0001DC00);
3693 + bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
3694 + bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
3695 + bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
3696
3697 value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
3698 value32 |= 0x00100000;
3699 @@ -2509,8 +2499,6 @@ err_radio_off:
3700 bcm43xx_radio_turn_off(bcm);
3701 err_gpio_cleanup:
3702 bcm43xx_gpio_cleanup(bcm);
3703 -err_free_irq:
3704 - free_irq(bcm->irq, bcm);
3705 err_release_fw:
3706 bcm43xx_release_firmware(bcm, 1);
3707 goto out;
3708 @@ -2550,11 +2538,9 @@ static void bcm43xx_init_struct_phyinfo(
3709 {
3710 /* Initialize a "phyinfo" structure. The structure is already
3711 * zeroed out.
3712 + * This is called on insmod time to initialize members.
3713 */
3714 - phy->antenna_diversity = 0xFFFF;
3715 phy->savedpctlreg = 0xFFFF;
3716 - phy->minlowsig[0] = 0xFFFF;
3717 - phy->minlowsig[1] = 0xFFFF;
3718 spin_lock_init(&phy->lock);
3719 }
3720
3721 @@ -2562,14 +2548,11 @@ static void bcm43xx_init_struct_radioinf
3722 {
3723 /* Initialize a "radioinfo" structure. The structure is already
3724 * zeroed out.
3725 + * This is called on insmod time to initialize members.
3726 */
3727 radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
3728 radio->channel = 0xFF;
3729 radio->initial_channel = 0xFF;
3730 - radio->lofcal = 0xFFFF;
3731 - radio->initval = 0xFFFF;
3732 - radio->nrssi[0] = -1000;
3733 - radio->nrssi[1] = -1000;
3734 }
3735
3736 static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
3737 @@ -2587,7 +2570,6 @@ static int bcm43xx_probe_cores(struct bc
3738 * BCM43xx_MAX_80211_CORES);
3739 memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211)
3740 * BCM43xx_MAX_80211_CORES);
3741 - bcm->current_80211_core_idx = -1;
3742 bcm->nr_80211_available = 0;
3743 bcm->current_core = NULL;
3744 bcm->active_80211_core = NULL;
3745 @@ -2757,6 +2739,7 @@ #endif
3746 goto out;
3747 }
3748 bcm->nr_80211_available++;
3749 + core->priv = ext_80211;
3750 bcm43xx_init_struct_phyinfo(&ext_80211->phy);
3751 bcm43xx_init_struct_radioinfo(&ext_80211->radio);
3752 break;
3753 @@ -2857,7 +2840,8 @@ static void bcm43xx_wireless_core_cleanu
3754 }
3755
3756 /* http://bcm-specs.sipsolutions.net/80211Init */
3757 -static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm)
3758 +static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
3759 + int active_wlcore)
3760 {
3761 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3762 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
3763 @@ -2939,19 +2923,26 @@ static int bcm43xx_wireless_core_init(st
3764 if (bcm->current_core->rev >= 5)
3765 bcm43xx_write16(bcm, 0x043C, 0x000C);
3766
3767 - if (bcm43xx_using_pio(bcm))
3768 - err = bcm43xx_pio_init(bcm);
3769 - else
3770 - err = bcm43xx_dma_init(bcm);
3771 - if (err)
3772 - goto err_chip_cleanup;
3773 + if (active_wlcore) {
3774 + if (bcm43xx_using_pio(bcm))
3775 + err = bcm43xx_pio_init(bcm);
3776 + else
3777 + err = bcm43xx_dma_init(bcm);
3778 + if (err)
3779 + goto err_chip_cleanup;
3780 + }
3781 bcm43xx_write16(bcm, 0x0612, 0x0050);
3782 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050);
3783 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4);
3784
3785 - bcm43xx_mac_enable(bcm);
3786 - bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
3787 + if (active_wlcore) {
3788 + if (radio->initial_channel != 0xFF)
3789 + bcm43xx_radio_selectchannel(bcm, radio->initial_channel, 0);
3790 + }
3791
3792 + /* Don't enable MAC/IRQ here, as it will race with the IRQ handler.
3793 + * We enable it later.
3794 + */
3795 bcm->current_core->initialized = 1;
3796 out:
3797 return err;
3798 @@ -3066,11 +3057,6 @@ out:
3799 return err;
3800 }
3801
3802 -static void bcm43xx_softmac_init(struct bcm43xx_private *bcm)
3803 -{
3804 - ieee80211softmac_start(bcm->net_dev);
3805 -}
3806 -
3807 static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm)
3808 {
3809 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3810 @@ -3178,51 +3164,43 @@ static void bcm43xx_periodic_work_handle
3811 int badness;
3812
3813 badness = estimate_periodic_work_badness(bcm->periodic_state);
3814 + mutex_lock(&bcm->mutex);
3815 + netif_tx_disable(bcm->net_dev);
3816 + spin_lock_irqsave(&bcm->irq_lock, flags);
3817 if (badness > BADNESS_LIMIT) {
3818 /* Periodic work will take a long time, so we want it to
3819 * be preemtible.
3820 */
3821 - bcm43xx_lock_irqonly(bcm, flags);
3822 - netif_stop_queue(bcm->net_dev);
3823 + bcm43xx_mac_suspend(bcm);
3824 if (bcm43xx_using_pio(bcm))
3825 bcm43xx_pio_freeze_txqueues(bcm);
3826 savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3827 - bcm43xx_unlock_irqonly(bcm, flags);
3828 - bcm43xx_lock_noirq(bcm);
3829 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
3830 bcm43xx_synchronize_irq(bcm);
3831 - } else {
3832 - /* Periodic work should take short time, so we want low
3833 - * locking overhead.
3834 - */
3835 - bcm43xx_lock_irqsafe(bcm, flags);
3836 }
3837
3838 do_periodic_work(bcm);
3839
3840 if (badness > BADNESS_LIMIT) {
3841 - bcm43xx_lock_irqonly(bcm, flags);
3842 - if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) {
3843 - tasklet_enable(&bcm->isr_tasklet);
3844 - bcm43xx_interrupt_enable(bcm, savedirqs);
3845 - if (bcm43xx_using_pio(bcm))
3846 - bcm43xx_pio_thaw_txqueues(bcm);
3847 - }
3848 - netif_wake_queue(bcm->net_dev);
3849 - mmiowb();
3850 - bcm43xx_unlock_irqonly(bcm, flags);
3851 - bcm43xx_unlock_noirq(bcm);
3852 - } else {
3853 - mmiowb();
3854 - bcm43xx_unlock_irqsafe(bcm, flags);
3855 + spin_lock_irqsave(&bcm->irq_lock, flags);
3856 + tasklet_enable(&bcm->isr_tasklet);
3857 + bcm43xx_interrupt_enable(bcm, savedirqs);
3858 + if (bcm43xx_using_pio(bcm))
3859 + bcm43xx_pio_thaw_txqueues(bcm);
3860 + bcm43xx_mac_enable(bcm);
3861 }
3862 + mmiowb();
3863 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
3864 + netif_wake_queue(bcm->net_dev);
3865 + mutex_unlock(&bcm->mutex);
3866 }
3867
3868 -static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
3869 +void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
3870 {
3871 cancel_rearming_delayed_work(&bcm->periodic_work);
3872 }
3873
3874 -static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
3875 +void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
3876 {
3877 struct work_struct *work = &(bcm->periodic_work);
3878
3879 @@ -3243,9 +3221,9 @@ static int bcm43xx_rng_read(struct hwrng
3880 struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv;
3881 unsigned long flags;
3882
3883 - bcm43xx_lock_irqonly(bcm, flags);
3884 + spin_lock_irqsave(&(bcm)->irq_lock, flags);
3885 *data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG);
3886 - bcm43xx_unlock_irqonly(bcm, flags);
3887 + spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
3888
3889 return (sizeof(u16));
3890 }
3891 @@ -3271,139 +3249,329 @@ static int bcm43xx_rng_init(struct bcm43
3892 return err;
3893 }
3894
3895 -/* This is the opposite of bcm43xx_init_board() */
3896 -static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3897 +static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm)
3898 {
3899 + int ret = 0;
3900 int i, err;
3901 + struct bcm43xx_coreinfo *core;
3902
3903 - bcm43xx_lock_noirq(bcm);
3904 + bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
3905 + for (i = 0; i < bcm->nr_80211_available; i++) {
3906 + core = &(bcm->core_80211[i]);
3907 + assert(core->available);
3908 + if (!core->initialized)
3909 + continue;
3910 + err = bcm43xx_switch_core(bcm, core);
3911 + if (err) {
3912 + dprintk(KERN_ERR PFX "shutdown_all_wireless_cores "
3913 + "switch_core failed (%d)\n", err);
3914 + ret = err;
3915 + continue;
3916 + }
3917 + bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3918 + bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
3919 + bcm43xx_wireless_core_cleanup(bcm);
3920 + if (core == bcm->active_80211_core)
3921 + bcm->active_80211_core = NULL;
3922 + }
3923 + free_irq(bcm->irq, bcm);
3924 + bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3925 +
3926 + return ret;
3927 +}
3928 +
3929 +/* This is the opposite of bcm43xx_init_board() */
3930 +static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3931 +{
3932 + bcm43xx_rng_exit(bcm);
3933 bcm43xx_sysfs_unregister(bcm);
3934 bcm43xx_periodic_tasks_delete(bcm);
3935
3936 - bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
3937 + mutex_lock(&(bcm)->mutex);
3938 + bcm43xx_shutdown_all_wireless_cores(bcm);
3939 + bcm43xx_pctl_set_crystal(bcm, 0);
3940 + mutex_unlock(&(bcm)->mutex);
3941 +}
3942
3943 - bcm43xx_rng_exit(bcm);
3944 +static void prepare_phydata_for_init(struct bcm43xx_phyinfo *phy)
3945 +{
3946 + phy->antenna_diversity = 0xFFFF;
3947 + memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
3948 + memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
3949 +
3950 + /* Flags */
3951 + phy->calibrated = 0;
3952 + phy->is_locked = 0;
3953 +
3954 + if (phy->_lo_pairs) {
3955 + memset(phy->_lo_pairs, 0,
3956 + sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT);
3957 + }
3958 + memset(phy->loopback_gain, 0, sizeof(phy->loopback_gain));
3959 +}
3960 +
3961 +static void prepare_radiodata_for_init(struct bcm43xx_private *bcm,
3962 + struct bcm43xx_radioinfo *radio)
3963 +{
3964 + int i;
3965 +
3966 + /* Set default attenuation values. */
3967 + radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
3968 + radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
3969 + radio->txctl1 = bcm43xx_default_txctl1(bcm);
3970 + radio->txctl2 = 0xFFFF;
3971 + radio->txpwr_offset = 0;
3972 +
3973 + /* NRSSI */
3974 + radio->nrssislope = 0;
3975 + for (i = 0; i < ARRAY_SIZE(radio->nrssi); i++)
3976 + radio->nrssi[i] = -1000;
3977 + for (i = 0; i < ARRAY_SIZE(radio->nrssi_lt); i++)
3978 + radio->nrssi_lt[i] = i;
3979 +
3980 + radio->lofcal = 0xFFFF;
3981 + radio->initval = 0xFFFF;
3982 +
3983 + radio->aci_enable = 0;
3984 + radio->aci_wlan_automatic = 0;
3985 + radio->aci_hw_rssi = 0;
3986 +}
3987 +
3988 +static void prepare_priv_for_init(struct bcm43xx_private *bcm)
3989 +{
3990 + int i;
3991 + struct bcm43xx_coreinfo *core;
3992 + struct bcm43xx_coreinfo_80211 *wlext;
3993 +
3994 + assert(!bcm->active_80211_core);
3995 +
3996 + bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
3997 +
3998 + /* Flags */
3999 + bcm->was_initialized = 0;
4000 + bcm->reg124_set_0x4 = 0;
4001 +
4002 + /* Stats */
4003 + memset(&bcm->stats, 0, sizeof(bcm->stats));
4004 +
4005 + /* Wireless core data */
4006 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
4007 - if (!bcm->core_80211[i].available)
4008 - continue;
4009 - if (!bcm->core_80211[i].initialized)
4010 + core = &(bcm->core_80211[i]);
4011 + wlext = core->priv;
4012 +
4013 + if (!core->available)
4014 continue;
4015 + assert(wlext == &(bcm->core_80211_ext[i]));
4016
4017 - err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
4018 - assert(err == 0);
4019 - bcm43xx_wireless_core_cleanup(bcm);
4020 + prepare_phydata_for_init(&wlext->phy);
4021 + prepare_radiodata_for_init(bcm, &wlext->radio);
4022 }
4023
4024 - bcm43xx_pctl_set_crystal(bcm, 0);
4025 + /* IRQ related flags */
4026 + bcm->irq_reason = 0;
4027 + memset(bcm->dma_reason, 0, sizeof(bcm->dma_reason));
4028 + bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
4029
4030 - bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
4031 - bcm43xx_unlock_noirq(bcm);
4032 + bcm->mac_suspended = 1;
4033 +
4034 + /* Noise calculation context */
4035 + memset(&bcm->noisecalc, 0, sizeof(bcm->noisecalc));
4036 +
4037 + /* Periodic work context */
4038 + bcm->periodic_state = 0;
4039 }
4040
4041 -static int bcm43xx_init_board(struct bcm43xx_private *bcm)
4042 +static int wireless_core_up(struct bcm43xx_private *bcm,
4043 + int active_wlcore)
4044 +{
4045 + int err;
4046 +
4047 + if (!bcm43xx_core_enabled(bcm))
4048 + bcm43xx_wireless_core_reset(bcm, 1);
4049 + if (!active_wlcore)
4050 + bcm43xx_wireless_core_mark_inactive(bcm);
4051 + err = bcm43xx_wireless_core_init(bcm, active_wlcore);
4052 + if (err)
4053 + goto out;
4054 + if (!active_wlcore)
4055 + bcm43xx_radio_turn_off(bcm);
4056 +out:
4057 + return err;
4058 +}
4059 +
4060 +/* Select and enable the "to be used" wireless core.
4061 + * Locking: bcm->mutex must be aquired before calling this.
4062 + * bcm->irq_lock must not be aquired.
4063 + */
4064 +int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
4065 + int phytype)
4066 {
4067 int i, err;
4068 - int connect_phy;
4069 + struct bcm43xx_coreinfo *active_core = NULL;
4070 + struct bcm43xx_coreinfo_80211 *active_wlext = NULL;
4071 + struct bcm43xx_coreinfo *core;
4072 + struct bcm43xx_coreinfo_80211 *wlext;
4073 + int adjust_active_sbtmstatelow = 0;
4074
4075 might_sleep();
4076
4077 - bcm43xx_lock_noirq(bcm);
4078 - bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
4079 + if (phytype < 0) {
4080 + /* If no phytype is requested, select the first core. */
4081 + assert(bcm->core_80211[0].available);
4082 + wlext = bcm->core_80211[0].priv;
4083 + phytype = wlext->phy.type;
4084 + }
4085 + /* Find the requested core. */
4086 + for (i = 0; i < bcm->nr_80211_available; i++) {
4087 + core = &(bcm->core_80211[i]);
4088 + wlext = core->priv;
4089 + if (wlext->phy.type == phytype) {
4090 + active_core = core;
4091 + active_wlext = wlext;
4092 + break;
4093 + }
4094 + }
4095 + if (!active_core)
4096 + return -ESRCH; /* No such PHYTYPE on this board. */
4097 +
4098 + if (bcm->active_80211_core) {
4099 + /* We already selected a wl core in the past.
4100 + * So first clean up everything.
4101 + */
4102 + dprintk(KERN_INFO PFX "select_wireless_core: cleanup\n");
4103 + ieee80211softmac_stop(bcm->net_dev);
4104 + bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
4105 + err = bcm43xx_disable_interrupts_sync(bcm);
4106 + assert(!err);
4107 + tasklet_enable(&bcm->isr_tasklet);
4108 + err = bcm43xx_shutdown_all_wireless_cores(bcm);
4109 + if (err)
4110 + goto error;
4111 + /* Ok, everything down, continue to re-initialize. */
4112 + bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
4113 + }
4114 +
4115 + /* Reset all data structures. */
4116 + prepare_priv_for_init(bcm);
4117
4118 - err = bcm43xx_pctl_set_crystal(bcm, 1);
4119 - if (err)
4120 - goto out;
4121 - err = bcm43xx_pctl_init(bcm);
4122 - if (err)
4123 - goto err_crystal_off;
4124 err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
4125 if (err)
4126 - goto err_crystal_off;
4127 + goto error;
4128
4129 - tasklet_enable(&bcm->isr_tasklet);
4130 + /* Mark all unused cores "inactive". */
4131 for (i = 0; i < bcm->nr_80211_available; i++) {
4132 - err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
4133 - assert(err != -ENODEV);
4134 - if (err)
4135 - goto err_80211_unwind;
4136 + core = &(bcm->core_80211[i]);
4137 + wlext = core->priv;
4138
4139 - /* Enable the selected wireless core.
4140 - * Connect PHY only on the first core.
4141 - */
4142 - if (!bcm43xx_core_enabled(bcm)) {
4143 - if (bcm->nr_80211_available == 1) {
4144 - connect_phy = bcm43xx_current_phy(bcm)->connected;
4145 - } else {
4146 - if (i == 0)
4147 - connect_phy = 1;
4148 - else
4149 - connect_phy = 0;
4150 - }
4151 - bcm43xx_wireless_core_reset(bcm, connect_phy);
4152 + if (core == active_core)
4153 + continue;
4154 + err = bcm43xx_switch_core(bcm, core);
4155 + if (err) {
4156 + dprintk(KERN_ERR PFX "Could not switch to inactive "
4157 + "802.11 core (%d)\n", err);
4158 + goto error;
4159 }
4160 + err = wireless_core_up(bcm, 0);
4161 + if (err) {
4162 + dprintk(KERN_ERR PFX "core_up for inactive 802.11 core "
4163 + "failed (%d)\n", err);
4164 + goto error;
4165 + }
4166 + adjust_active_sbtmstatelow = 1;
4167 + }
4168
4169 - if (i != 0)
4170 - bcm43xx_wireless_core_mark_inactive(bcm, &bcm->core_80211[0]);
4171 -
4172 - err = bcm43xx_wireless_core_init(bcm);
4173 - if (err)
4174 - goto err_80211_unwind;
4175 + /* Now initialize the active 802.11 core. */
4176 + err = bcm43xx_switch_core(bcm, active_core);
4177 + if (err) {
4178 + dprintk(KERN_ERR PFX "Could not switch to active "
4179 + "802.11 core (%d)\n", err);
4180 + goto error;
4181 + }
4182 + if (adjust_active_sbtmstatelow &&
4183 + active_wlext->phy.type == BCM43xx_PHYTYPE_G) {
4184 + u32 sbtmstatelow;
4185
4186 - if (i != 0) {
4187 - bcm43xx_mac_suspend(bcm);
4188 - bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
4189 - bcm43xx_radio_turn_off(bcm);
4190 - }
4191 + sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
4192 + sbtmstatelow |= 0x20000000;
4193 + bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
4194 }
4195 - bcm->active_80211_core = &bcm->core_80211[0];
4196 - if (bcm->nr_80211_available >= 2) {
4197 - bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
4198 - bcm43xx_mac_enable(bcm);
4199 + err = wireless_core_up(bcm, 1);
4200 + if (err) {
4201 + dprintk(KERN_ERR PFX "core_up for active 802.11 core "
4202 + "failed (%d)\n", err);
4203 + goto error;
4204 }
4205 - err = bcm43xx_rng_init(bcm);
4206 + err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
4207 if (err)
4208 - goto err_80211_unwind;
4209 + goto error;
4210 + bcm->active_80211_core = active_core;
4211 +
4212 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
4213 bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
4214 - dprintk(KERN_INFO PFX "80211 cores initialized\n");
4215 bcm43xx_security_init(bcm);
4216 - bcm43xx_softmac_init(bcm);
4217 + ieee80211softmac_start(bcm->net_dev);
4218
4219 - bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
4220 + /* Let's go! Be careful after enabling the IRQs.
4221 + * Don't switch cores, for example.
4222 + */
4223 + bcm43xx_mac_enable(bcm);
4224 + bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
4225 + err = bcm43xx_initialize_irq(bcm);
4226 + if (err)
4227 + goto error;
4228 + bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
4229
4230 - if (bcm43xx_current_radio(bcm)->initial_channel != 0xFF) {
4231 - bcm43xx_mac_suspend(bcm);
4232 - bcm43xx_radio_selectchannel(bcm, bcm43xx_current_radio(bcm)->initial_channel, 0);
4233 - bcm43xx_mac_enable(bcm);
4234 - }
4235 + dprintk(KERN_INFO PFX "Selected 802.11 core (phytype %d)\n",
4236 + active_wlext->phy.type);
4237
4238 - /* Initialization of the board is done. Flag it as such. */
4239 - bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
4240 + return 0;
4241 +
4242 +error:
4243 + bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
4244 + bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
4245 + return err;
4246 +}
4247
4248 +static int bcm43xx_init_board(struct bcm43xx_private *bcm)
4249 +{
4250 + int err;
4251 +
4252 + mutex_lock(&(bcm)->mutex);
4253 +
4254 + tasklet_enable(&bcm->isr_tasklet);
4255 + err = bcm43xx_pctl_set_crystal(bcm, 1);
4256 + if (err)
4257 + goto err_tasklet;
4258 + err = bcm43xx_pctl_init(bcm);
4259 + if (err)
4260 + goto err_crystal_off;
4261 + err = bcm43xx_select_wireless_core(bcm, -1);
4262 + if (err)
4263 + goto err_crystal_off;
4264 + err = bcm43xx_sysfs_register(bcm);
4265 + if (err)
4266 + goto err_wlshutdown;
4267 + err = bcm43xx_rng_init(bcm);
4268 + if (err)
4269 + goto err_sysfs_unreg;
4270 bcm43xx_periodic_tasks_setup(bcm);
4271 - bcm43xx_sysfs_register(bcm);
4272 - //FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though...
4273
4274 /*FIXME: This should be handled by softmac instead. */
4275 schedule_work(&bcm->softmac->associnfo.work);
4276
4277 - assert(err == 0);
4278 out:
4279 - bcm43xx_unlock_noirq(bcm);
4280 + mutex_unlock(&(bcm)->mutex);
4281
4282 return err;
4283
4284 -err_80211_unwind:
4285 - tasklet_disable(&bcm->isr_tasklet);
4286 - /* unwind all 80211 initialization */
4287 - for (i = 0; i < bcm->nr_80211_available; i++) {
4288 - if (!bcm->core_80211[i].initialized)
4289 - continue;
4290 - bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
4291 - bcm43xx_wireless_core_cleanup(bcm);
4292 - }
4293 +err_sysfs_unreg:
4294 + bcm43xx_sysfs_unregister(bcm);
4295 +err_wlshutdown:
4296 + bcm43xx_shutdown_all_wireless_cores(bcm);
4297 err_crystal_off:
4298 bcm43xx_pctl_set_crystal(bcm, 0);
4299 +err_tasklet:
4300 + tasklet_disable(&bcm->isr_tasklet);
4301 goto out;
4302 }
4303
4304 @@ -3647,7 +3815,8 @@ static void bcm43xx_ieee80211_set_chan(s
4305 struct bcm43xx_radioinfo *radio;
4306 unsigned long flags;
4307
4308 - bcm43xx_lock_irqsafe(bcm, flags);
4309 + mutex_lock(&bcm->mutex);
4310 + spin_lock_irqsave(&bcm->irq_lock, flags);
4311 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
4312 bcm43xx_mac_suspend(bcm);
4313 bcm43xx_radio_selectchannel(bcm, channel, 0);
4314 @@ -3656,7 +3825,8 @@ static void bcm43xx_ieee80211_set_chan(s
4315 radio = bcm43xx_current_radio(bcm);
4316 radio->initial_channel = channel;
4317 }
4318 - bcm43xx_unlock_irqsafe(bcm, flags);
4319 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
4320 + mutex_unlock(&bcm->mutex);
4321 }
4322
4323 /* set_security() callback in struct ieee80211_device */
4324 @@ -3670,7 +3840,8 @@ static void bcm43xx_ieee80211_set_securi
4325
4326 dprintk(KERN_INFO PFX "set security called");
4327
4328 - bcm43xx_lock_irqsafe(bcm, flags);
4329 + mutex_lock(&bcm->mutex);
4330 + spin_lock_irqsave(&bcm->irq_lock, flags);
4331
4332 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
4333 if (sec->flags & (1<<keyidx)) {
4334 @@ -3739,7 +3910,8 @@ static void bcm43xx_ieee80211_set_securi
4335 } else
4336 bcm43xx_clear_keys(bcm);
4337 }
4338 - bcm43xx_unlock_irqsafe(bcm, flags);
4339 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
4340 + mutex_unlock(&bcm->mutex);
4341 }
4342
4343 /* hard_start_xmit() callback in struct ieee80211_device */
4344 @@ -3751,12 +3923,14 @@ static int bcm43xx_ieee80211_hard_start_
4345 int err = -ENODEV;
4346 unsigned long flags;
4347
4348 - bcm43xx_lock_irqonly(bcm, flags);
4349 + spin_lock_irqsave(&bcm->irq_lock, flags);
4350 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED))
4351 err = bcm43xx_tx(bcm, txb);
4352 - bcm43xx_unlock_irqonly(bcm, flags);
4353 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
4354
4355 - return err;
4356 + if (unlikely(err))
4357 + return NETDEV_TX_BUSY;
4358 + return NETDEV_TX_OK;
4359 }
4360
4361 static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev)
4362 @@ -3769,9 +3943,9 @@ static void bcm43xx_net_tx_timeout(struc
4363 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4364 unsigned long flags;
4365
4366 - bcm43xx_lock_irqonly(bcm, flags);
4367 + spin_lock_irqsave(&bcm->irq_lock, flags);
4368 bcm43xx_controller_restart(bcm, "TX timeout");
4369 - bcm43xx_unlock_irqonly(bcm, flags);
4370 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
4371 }
4372
4373 #ifdef CONFIG_NET_POLL_CONTROLLER
4374 @@ -3781,7 +3955,8 @@ static void bcm43xx_net_poll_controller(
4375 unsigned long flags;
4376
4377 local_irq_save(flags);
4378 - bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
4379 + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
4380 + bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
4381 local_irq_restore(flags);
4382 }
4383 #endif /* CONFIG_NET_POLL_CONTROLLER */
4384 @@ -3799,9 +3974,10 @@ static int bcm43xx_net_stop(struct net_d
4385 int err;
4386
4387 ieee80211softmac_stop(net_dev);
4388 - err = bcm43xx_disable_interrupts_sync(bcm, NULL);
4389 + err = bcm43xx_disable_interrupts_sync(bcm);
4390 assert(!err);
4391 bcm43xx_free_board(bcm);
4392 + flush_scheduled_work();
4393
4394 return 0;
4395 }
4396 @@ -3818,10 +3994,12 @@ static int bcm43xx_init_private(struct b
4397 bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
4398
4399 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
4400 + bcm->mac_suspended = 1;
4401 bcm->pci_dev = pci_dev;
4402 bcm->net_dev = net_dev;
4403 bcm->bad_frames_preempt = modparam_bad_frames_preempt;
4404 spin_lock_init(&bcm->irq_lock);
4405 + spin_lock_init(&bcm->leds_lock);
4406 mutex_init(&bcm->mutex);
4407 tasklet_init(&bcm->isr_tasklet,
4408 (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
4409 @@ -3940,7 +4118,6 @@ static void __devexit bcm43xx_remove_one
4410 bcm43xx_debugfs_remove_device(bcm);
4411 unregister_netdev(net_dev);
4412 bcm43xx_detach_board(bcm);
4413 - assert(bcm->ucode == NULL);
4414 free_ieee80211softmac(net_dev);
4415 }
4416
4417 @@ -3950,47 +4127,31 @@ static void __devexit bcm43xx_remove_one
4418 static void bcm43xx_chip_reset(void *_bcm)
4419 {
4420 struct bcm43xx_private *bcm = _bcm;
4421 - struct net_device *net_dev = bcm->net_dev;
4422 - struct pci_dev *pci_dev = bcm->pci_dev;
4423 - int err;
4424 - int was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
4425 -
4426 - netif_stop_queue(bcm->net_dev);
4427 - tasklet_disable(&bcm->isr_tasklet);
4428 + struct bcm43xx_phyinfo *phy;
4429 + int err = -ENODEV;
4430
4431 - bcm->firmware_norelease = 1;
4432 - if (was_initialized)
4433 - bcm43xx_free_board(bcm);
4434 - bcm->firmware_norelease = 0;
4435 - bcm43xx_detach_board(bcm);
4436 - err = bcm43xx_init_private(bcm, net_dev, pci_dev);
4437 - if (err)
4438 - goto failure;
4439 - err = bcm43xx_attach_board(bcm);
4440 - if (err)
4441 - goto failure;
4442 - if (was_initialized) {
4443 - err = bcm43xx_init_board(bcm);
4444 - if (err)
4445 - goto failure;
4446 + mutex_lock(&(bcm)->mutex);
4447 + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
4448 + bcm43xx_periodic_tasks_delete(bcm);
4449 + phy = bcm43xx_current_phy(bcm);
4450 + err = bcm43xx_select_wireless_core(bcm, phy->type);
4451 + if (!err)
4452 + bcm43xx_periodic_tasks_setup(bcm);
4453 }
4454 - netif_wake_queue(bcm->net_dev);
4455 - printk(KERN_INFO PFX "Controller restarted\n");
4456 + mutex_unlock(&(bcm)->mutex);
4457
4458 - return;
4459 -failure:
4460 - printk(KERN_ERR PFX "Controller restart failed\n");
4461 + printk(KERN_ERR PFX "Controller restart%s\n",
4462 + (err == 0) ? "ed" : " failed");
4463 }
4464
4465 /* Hard-reset the chip.
4466 * This can be called from interrupt or process context.
4467 - * Make sure to _not_ re-enable device interrupts after this has been called.
4468 -*/
4469 + * bcm->irq_lock must be locked.
4470 + */
4471 void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
4472 {
4473 - bcm43xx_set_status(bcm, BCM43xx_STAT_RESTARTING);
4474 - bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
4475 - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
4476 + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
4477 + return;
4478 printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
4479 INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
4480 schedule_work(&bcm->restart_work);
4481 @@ -4002,21 +4163,16 @@ static int bcm43xx_suspend(struct pci_de
4482 {
4483 struct net_device *net_dev = pci_get_drvdata(pdev);
4484 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4485 - unsigned long flags;
4486 - int try_to_shutdown = 0, err;
4487 + int err;
4488
4489 dprintk(KERN_INFO PFX "Suspending...\n");
4490
4491 - bcm43xx_lock_irqsafe(bcm, flags);
4492 - bcm->was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
4493 - if (bcm->was_initialized)
4494 - try_to_shutdown = 1;
4495 - bcm43xx_unlock_irqsafe(bcm, flags);
4496 -
4497 netif_device_detach(net_dev);
4498 - if (try_to_shutdown) {
4499 + bcm->was_initialized = 0;
4500 + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
4501 + bcm->was_initialized = 1;
4502 ieee80211softmac_stop(net_dev);
4503 - err = bcm43xx_disable_interrupts_sync(bcm, &bcm->irq_savedstate);
4504 + err = bcm43xx_disable_interrupts_sync(bcm);
4505 if (unlikely(err)) {
4506 dprintk(KERN_ERR PFX "Suspend failed.\n");
4507 return -EAGAIN;
4508 @@ -4049,17 +4205,14 @@ static int bcm43xx_resume(struct pci_dev
4509 pci_restore_state(pdev);
4510
4511 bcm43xx_chipset_attach(bcm);
4512 - if (bcm->was_initialized) {
4513 - bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
4514 + if (bcm->was_initialized)
4515 err = bcm43xx_init_board(bcm);
4516 - }
4517 if (err) {
4518 printk(KERN_ERR PFX "Resume failed!\n");
4519 return err;
4520 }
4521 -
4522 netif_device_attach(net_dev);
4523 -
4524 +
4525 dprintk(KERN_INFO PFX "Device resumed.\n");
4526
4527 return 0;
4528 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.h b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
4529 index 1164936..f763571 100644
4530 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.h
4531 +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
4532 @@ -133,11 +133,17 @@ void bcm43xx_dummy_transmission(struct b
4533
4534 int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core);
4535
4536 +int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
4537 + int phytype);
4538 +
4539 void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy);
4540
4541 void bcm43xx_mac_suspend(struct bcm43xx_private *bcm);
4542 void bcm43xx_mac_enable(struct bcm43xx_private *bcm);
4543
4544 +void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm);
4545 +void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm);
4546 +
4547 void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason);
4548
4549 int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom);
4550 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
4551 index f8200de..52ce2a9 100644
4552 --- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
4553 +++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
4554 @@ -81,6 +81,16 @@ static const s8 bcm43xx_tssi2dbm_g_table
4555 static void bcm43xx_phy_initg(struct bcm43xx_private *bcm);
4556
4557
4558 +static inline
4559 +void bcm43xx_voluntary_preempt(void)
4560 +{
4561 + assert(!in_atomic() && !in_irq() &&
4562 + !in_interrupt() && !irqs_disabled());
4563 +#ifndef CONFIG_PREEMPT
4564 + cond_resched();
4565 +#endif /* CONFIG_PREEMPT */
4566 +}
4567 +
4568 void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm)
4569 {
4570 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
4571 @@ -133,22 +143,14 @@ void bcm43xx_phy_write(struct bcm43xx_pr
4572 void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm)
4573 {
4574 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
4575 - unsigned long flags;
4576
4577 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* Dummy read. */
4578 if (phy->calibrated)
4579 return;
4580 if (phy->type == BCM43xx_PHYTYPE_G && phy->rev == 1) {
4581 - /* We do not want to be preempted while calibrating
4582 - * the hardware.
4583 - */
4584 - local_irq_save(flags);
4585 -
4586 bcm43xx_wireless_core_reset(bcm, 0);
4587 bcm43xx_phy_initg(bcm);
4588 bcm43xx_wireless_core_reset(bcm, 1);
4589 -
4590 - local_irq_restore(flags);
4591 }
4592 phy->calibrated = 1;
4593 }
4594 @@ -359,7 +361,7 @@ static void bcm43xx_phy_setupg(struct bc
4595 if (phy->rev <= 2)
4596 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
4597 bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]);
4598 - else if ((phy->rev == 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200))
4599 + else if ((phy->rev >= 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200))
4600 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
4601 bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]);
4602 else
4603 @@ -369,7 +371,7 @@ static void bcm43xx_phy_setupg(struct bc
4604 if (phy->rev == 2)
4605 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
4606 bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]);
4607 - else if ((phy->rev > 2) && (phy->rev <= 7))
4608 + else if ((phy->rev > 2) && (phy->rev <= 8))
4609 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
4610 bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]);
4611
4612 @@ -1195,7 +1197,7 @@ static void bcm43xx_phy_initg(struct bcm
4613
4614 if (phy->rev == 1)
4615 bcm43xx_phy_initb5(bcm);
4616 - else if (phy->rev >= 2 && phy->rev <= 7)
4617 + else
4618 bcm43xx_phy_initb6(bcm);
4619 if (phy->rev >= 2 || phy->connected)
4620 bcm43xx_phy_inita(bcm);
4621 @@ -1239,23 +1241,22 @@ static void bcm43xx_phy_initg(struct bcm
4622 bcm43xx_phy_lo_g_measure(bcm);
4623 } else {
4624 if (radio->version == 0x2050 && radio->revision == 8) {
4625 - //FIXME
4626 + bcm43xx_radio_write16(bcm, 0x0052,
4627 + (radio->txctl1 << 4) | radio->txctl2);
4628 } else {
4629 bcm43xx_radio_write16(bcm, 0x0052,
4630 (bcm43xx_radio_read16(bcm, 0x0052)
4631 & 0xFFF0) | radio->txctl1);
4632 }
4633 if (phy->rev >= 6) {
4634 - /*
4635 bcm43xx_phy_write(bcm, 0x0036,
4636 (bcm43xx_phy_read(bcm, 0x0036)
4637 - & 0xF000) | (FIXME << 12));
4638 - */
4639 + & 0xF000) | (radio->txctl2 << 12));
4640 }
4641 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
4642 bcm43xx_phy_write(bcm, 0x002E, 0x8075);
4643 else
4644 - bcm43xx_phy_write(bcm, 0x003E, 0x807F);
4645 + bcm43xx_phy_write(bcm, 0x002E, 0x807F);
4646 if (phy->rev < 2)
4647 bcm43xx_phy_write(bcm, 0x002F, 0x0101);
4648 else
4649 @@ -1299,7 +1300,9 @@ static u16 bcm43xx_phy_lo_b_r15_loop(str
4650 {
4651 int i;
4652 u16 ret = 0;
4653 + unsigned long flags;
4654
4655 + local_irq_save(flags);
4656 for (i = 0; i < 10; i++){
4657 bcm43xx_phy_write(bcm, 0x0015, 0xAFA0);
4658 udelay(1);
4659 @@ -1309,6 +1312,8 @@ static u16 bcm43xx_phy_lo_b_r15_loop(str
4660 udelay(40);
4661 ret += bcm43xx_phy_read(bcm, 0x002C);
4662 }
4663 + local_irq_restore(flags);
4664 + bcm43xx_voluntary_preempt();
4665
4666 return ret;
4667 }
4668 @@ -1435,6 +1440,7 @@ u16 bcm43xx_phy_lo_g_deviation_subval(st
4669 }
4670 ret = bcm43xx_phy_read(bcm, 0x002D);
4671 local_irq_restore(flags);
4672 + bcm43xx_voluntary_preempt();
4673
4674 return ret;
4675 }
4676 @@ -1760,6 +1766,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm
4677 bcm43xx_radio_write16(bcm, 0x43, i);
4678 bcm43xx_radio_write16(bcm, 0x52, radio->txctl2);
4679 udelay(10);
4680 + bcm43xx_voluntary_preempt();
4681
4682 bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
4683
4684 @@ -1803,6 +1810,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm
4685 radio->txctl2
4686 | (3/*txctl1*/ << 4));//FIXME: shouldn't txctl1 be zero here and 3 in the loop above?
4687 udelay(10);
4688 + bcm43xx_voluntary_preempt();
4689
4690 bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
4691
4692 @@ -1824,6 +1832,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm
4693 bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA2);
4694 udelay(2);
4695 bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA3);
4696 + bcm43xx_voluntary_preempt();
4697 } else
4698 bcm43xx_phy_write(bcm, 0x0015, r27 | 0xEFA0);
4699 bcm43xx_phy_lo_adjust(bcm, is_initializing);
4700 @@ -2188,12 +2197,6 @@ int bcm43xx_phy_init(struct bcm43xx_priv
4701 {
4702 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
4703 int err = -ENODEV;
4704 - unsigned long flags;
4705 -
4706 - /* We do not want to be preempted while calibrating
4707 - * the hardware.
4708 - */
4709 - local_irq_save(flags);
4710
4711 switch (phy->type) {
4712 case BCM43xx_PHYTYPE_A:
4713 @@ -2227,7 +2230,6 @@ int bcm43xx_phy_init(struct bcm43xx_priv
4714 err = 0;
4715 break;
4716 }
4717 - local_irq_restore(flags);
4718 if (err)
4719 printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n");
4720
4721 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
4722 index 574085c..c60c174 100644
4723 --- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
4724 +++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
4725 @@ -262,7 +262,7 @@ static void tx_tasklet(unsigned long d)
4726 int err;
4727 u16 txctl;
4728
4729 - bcm43xx_lock_irqonly(bcm, flags);
4730 + spin_lock_irqsave(&bcm->irq_lock, flags);
4731
4732 if (queue->tx_frozen)
4733 goto out_unlock;
4734 @@ -300,7 +300,7 @@ static void tx_tasklet(unsigned long d)
4735 continue;
4736 }
4737 out_unlock:
4738 - bcm43xx_unlock_irqonly(bcm, flags);
4739 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
4740 }
4741
4742 static void setup_txqueues(struct bcm43xx_pioqueue *queue)
4743 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
4744 index 6a23bdc..f41d9e7 100644
4745 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
4746 +++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
4747 @@ -120,12 +120,14 @@ static ssize_t bcm43xx_attr_sprom_show(s
4748 GFP_KERNEL);
4749 if (!sprom)
4750 return -ENOMEM;
4751 - bcm43xx_lock_irqsafe(bcm, flags);
4752 + mutex_lock(&bcm->mutex);
4753 + spin_lock_irqsave(&bcm->irq_lock, flags);
4754 err = bcm43xx_sprom_read(bcm, sprom);
4755 if (!err)
4756 err = sprom2hex(sprom, buf, PAGE_SIZE);
4757 mmiowb();
4758 - bcm43xx_unlock_irqsafe(bcm, flags);
4759 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
4760 + mutex_unlock(&bcm->mutex);
4761 kfree(sprom);
4762
4763 return err;
4764 @@ -150,10 +152,14 @@ static ssize_t bcm43xx_attr_sprom_store(
4765 err = hex2sprom(sprom, buf, count);
4766 if (err)
4767 goto out_kfree;
4768 - bcm43xx_lock_irqsafe(bcm, flags);
4769 + mutex_lock(&bcm->mutex);
4770 + spin_lock_irqsave(&bcm->irq_lock, flags);
4771 + spin_lock(&bcm->leds_lock);
4772 err = bcm43xx_sprom_write(bcm, sprom);
4773 mmiowb();
4774 - bcm43xx_unlock_irqsafe(bcm, flags);
4775 + spin_unlock(&bcm->leds_lock);
4776 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
4777 + mutex_unlock(&bcm->mutex);
4778 out_kfree:
4779 kfree(sprom);
4780
4781 @@ -170,13 +176,12 @@ static ssize_t bcm43xx_attr_interfmode_s
4782 char *buf)
4783 {
4784 struct bcm43xx_private *bcm = dev_to_bcm(dev);
4785 - int err;
4786 ssize_t count = 0;
4787
4788 if (!capable(CAP_NET_ADMIN))
4789 return -EPERM;
4790
4791 - bcm43xx_lock_noirq(bcm);
4792 + mutex_lock(&bcm->mutex);
4793
4794 switch (bcm43xx_current_radio(bcm)->interfmode) {
4795 case BCM43xx_RADIO_INTERFMODE_NONE:
4796 @@ -191,11 +196,10 @@ static ssize_t bcm43xx_attr_interfmode_s
4797 default:
4798 assert(0);
4799 }
4800 - err = 0;
4801
4802 - bcm43xx_unlock_noirq(bcm);
4803 + mutex_unlock(&bcm->mutex);
4804
4805 - return err ? err : count;
4806 + return count;
4807
4808 }
4809
4810 @@ -229,7 +233,8 @@ static ssize_t bcm43xx_attr_interfmode_s
4811 return -EINVAL;
4812 }
4813
4814 - bcm43xx_lock_irqsafe(bcm, flags);
4815 + mutex_lock(&bcm->mutex);
4816 + spin_lock_irqsave(&bcm->irq_lock, flags);
4817
4818 err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
4819 if (err) {
4820 @@ -237,7 +242,8 @@ static ssize_t bcm43xx_attr_interfmode_s
4821 "supported by device\n");
4822 }
4823 mmiowb();
4824 - bcm43xx_unlock_irqsafe(bcm, flags);
4825 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
4826 + mutex_unlock(&bcm->mutex);
4827
4828 return err ? err : count;
4829 }
4830 @@ -251,23 +257,21 @@ static ssize_t bcm43xx_attr_preamble_sho
4831 char *buf)
4832 {
4833 struct bcm43xx_private *bcm = dev_to_bcm(dev);
4834 - int err;
4835 ssize_t count;
4836
4837 if (!capable(CAP_NET_ADMIN))
4838 return -EPERM;
4839
4840 - bcm43xx_lock_noirq(bcm);
4841 + mutex_lock(&bcm->mutex);
4842
4843 if (bcm->short_preamble)
4844 count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n");
4845 else
4846 count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n");
4847
4848 - err = 0;
4849 - bcm43xx_unlock_noirq(bcm);
4850 + mutex_unlock(&bcm->mutex);
4851
4852 - return err ? err : count;
4853 + return count;
4854 }
4855
4856 static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
4857 @@ -276,7 +280,6 @@ static ssize_t bcm43xx_attr_preamble_sto
4858 {
4859 struct bcm43xx_private *bcm = dev_to_bcm(dev);
4860 unsigned long flags;
4861 - int err;
4862 int value;
4863
4864 if (!capable(CAP_NET_ADMIN))
4865 @@ -285,14 +288,15 @@ static ssize_t bcm43xx_attr_preamble_sto
4866 value = get_boolean(buf, count);
4867 if (value < 0)
4868 return value;
4869 - bcm43xx_lock_irqsafe(bcm, flags);
4870 + mutex_lock(&bcm->mutex);
4871 + spin_lock_irqsave(&bcm->irq_lock, flags);
4872
4873 bcm->short_preamble = !!value;
4874
4875 - err = 0;
4876 - bcm43xx_unlock_irqsafe(bcm, flags);
4877 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
4878 + mutex_unlock(&bcm->mutex);
4879
4880 - return err ? err : count;
4881 + return count;
4882 }
4883
4884 static DEVICE_ATTR(shortpreamble, 0644,
4885 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
4886 index 5c36e29..ebe2a84 100644
4887 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
4888 +++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
4889 @@ -56,12 +56,11 @@ static int bcm43xx_wx_get_name(struct ne
4890 {
4891 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4892 int i;
4893 - unsigned long flags;
4894 struct bcm43xx_phyinfo *phy;
4895 char suffix[7] = { 0 };
4896 int have_a = 0, have_b = 0, have_g = 0;
4897
4898 - bcm43xx_lock_irqsafe(bcm, flags);
4899 + mutex_lock(&bcm->mutex);
4900 for (i = 0; i < bcm->nr_80211_available; i++) {
4901 phy = &(bcm->core_80211_ext[i].phy);
4902 switch (phy->type) {
4903 @@ -77,7 +76,7 @@ static int bcm43xx_wx_get_name(struct ne
4904 assert(0);
4905 }
4906 }
4907 - bcm43xx_unlock_irqsafe(bcm, flags);
4908 + mutex_unlock(&bcm->mutex);
4909
4910 i = 0;
4911 if (have_a) {
4912 @@ -111,7 +110,9 @@ static int bcm43xx_wx_set_channelfreq(st
4913 int freq;
4914 int err = -EINVAL;
4915
4916 - bcm43xx_lock_irqsafe(bcm, flags);
4917 + mutex_lock(&bcm->mutex);
4918 + spin_lock_irqsave(&bcm->irq_lock, flags);
4919 +
4920 if ((data->freq.m >= 0) && (data->freq.m <= 1000)) {
4921 channel = data->freq.m;
4922 freq = bcm43xx_channel_to_freq(bcm, channel);
4923 @@ -131,7 +132,8 @@ static int bcm43xx_wx_set_channelfreq(st
4924 err = 0;
4925 }
4926 out_unlock:
4927 - bcm43xx_unlock_irqsafe(bcm, flags);
4928 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
4929 + mutex_unlock(&bcm->mutex);
4930
4931 return err;
4932 }
4933 @@ -143,11 +145,10 @@ static int bcm43xx_wx_get_channelfreq(st
4934 {
4935 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4936 struct bcm43xx_radioinfo *radio;
4937 - unsigned long flags;
4938 int err = -ENODEV;
4939 u16 channel;
4940
4941 - bcm43xx_lock_irqsafe(bcm, flags);
4942 + mutex_lock(&bcm->mutex);
4943 radio = bcm43xx_current_radio(bcm);
4944 channel = radio->channel;
4945 if (channel == 0xFF) {
4946 @@ -162,7 +163,7 @@ static int bcm43xx_wx_get_channelfreq(st
4947
4948 err = 0;
4949 out_unlock:
4950 - bcm43xx_unlock_irqsafe(bcm, flags);
4951 + mutex_unlock(&bcm->mutex);
4952
4953 return err;
4954 }
4955 @@ -180,13 +181,15 @@ static int bcm43xx_wx_set_mode(struct ne
4956 if (mode == IW_MODE_AUTO)
4957 mode = BCM43xx_INITIAL_IWMODE;
4958
4959 - bcm43xx_lock_irqsafe(bcm, flags);
4960 + mutex_lock(&bcm->mutex);
4961 + spin_lock_irqsave(&bcm->irq_lock, flags);
4962 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
4963 if (bcm->ieee->iw_mode != mode)
4964 bcm43xx_set_iwmode(bcm, mode);
4965 } else
4966 bcm->ieee->iw_mode = mode;
4967 - bcm43xx_unlock_irqsafe(bcm, flags);
4968 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
4969 + mutex_unlock(&bcm->mutex);
4970
4971 return 0;
4972 }
4973 @@ -197,11 +200,10 @@ static int bcm43xx_wx_get_mode(struct ne
4974 char *extra)
4975 {
4976 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4977 - unsigned long flags;
4978
4979 - bcm43xx_lock_irqsafe(bcm, flags);
4980 + mutex_lock(&bcm->mutex);
4981 data->mode = bcm->ieee->iw_mode;
4982 - bcm43xx_unlock_irqsafe(bcm, flags);
4983 + mutex_unlock(&bcm->mutex);
4984
4985 return 0;
4986 }
4987 @@ -214,7 +216,6 @@ static int bcm43xx_wx_get_rangeparams(st
4988 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4989 struct iw_range *range = (struct iw_range *)extra;
4990 const struct ieee80211_geo *geo;
4991 - unsigned long flags;
4992 int i, j;
4993 struct bcm43xx_phyinfo *phy;
4994
4995 @@ -254,7 +255,7 @@ static int bcm43xx_wx_get_rangeparams(st
4996 IW_ENC_CAPA_CIPHER_TKIP |
4997 IW_ENC_CAPA_CIPHER_CCMP;
4998
4999 - bcm43xx_lock_irqsafe(bcm, flags);
5000 + mutex_lock(&bcm->mutex);
5001 phy = bcm43xx_current_phy(bcm);
5002
5003 range->num_bitrates = 0;
5004 @@ -301,7 +302,7 @@ static int bcm43xx_wx_get_rangeparams(st
5005 }
5006 range->num_frequency = j;
5007
5008 - bcm43xx_unlock_irqsafe(bcm, flags);
5009 + mutex_unlock(&bcm->mutex);
5010
5011 return 0;
5012 }
5013 @@ -314,11 +315,11 @@ static int bcm43xx_wx_set_nick(struct ne
5014 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
5015 size_t len;
5016
5017 - bcm43xx_lock_noirq(bcm);
5018 + mutex_lock(&bcm->mutex);
5019 len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE);
5020 memcpy(bcm->nick, extra, len);
5021 bcm->nick[len] = '\0';
5022 - bcm43xx_unlock_noirq(bcm);
5023 + mutex_unlock(&bcm->mutex);
5024
5025 return 0;
5026 }
5027 @@ -331,12 +332,12 @@ static int bcm43xx_wx_get_nick(struct ne
5028 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
5029 size_t len;
5030
5031 - bcm43xx_lock_noirq(bcm);
5032 + mutex_lock(&bcm->mutex);
5033 len = strlen(bcm->nick) + 1;
5034 memcpy(extra, bcm->nick, len);
5035 data->data.length = (__u16)len;
5036 data->data.flags = 1;
5037 - bcm43xx_unlock_noirq(bcm);
5038 + mutex_unlock(&bcm->mutex);
5039
5040 return 0;
5041 }
5042 @@ -350,7 +351,8 @@ static int bcm43xx_wx_set_rts(struct net
5043 unsigned long flags;
5044 int err = -EINVAL;
5045
5046 - bcm43xx_lock_irqsafe(bcm, flags);
5047 + mutex_lock(&bcm->mutex);
5048 + spin_lock_irqsave(&bcm->irq_lock, flags);
5049 if (data->rts.disabled) {
5050 bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD;
5051 err = 0;
5052 @@ -361,7 +363,8 @@ static int bcm43xx_wx_set_rts(struct net
5053 err = 0;
5054 }
5055 }
5056 - bcm43xx_unlock_irqsafe(bcm, flags);
5057 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
5058 + mutex_unlock(&bcm->mutex);
5059
5060 return err;
5061 }
5062 @@ -372,13 +375,12 @@ static int bcm43xx_wx_get_rts(struct net
5063 char *extra)
5064 {
5065 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
5066 - unsigned long flags;
5067
5068 - bcm43xx_lock_irqsafe(bcm, flags);
5069 + mutex_lock(&bcm->mutex);
5070 data->rts.value = bcm->rts_threshold;
5071 data->rts.fixed = 0;
5072 data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD);
5073 - bcm43xx_unlock_irqsafe(bcm, flags);
5074 + mutex_unlock(&bcm->mutex);
5075
5076 return 0;
5077 }
5078 @@ -392,7 +394,8 @@ static int bcm43xx_wx_set_frag(struct ne
5079 unsigned long flags;
5080 int err = -EINVAL;
5081
5082 - bcm43xx_lock_irqsafe(bcm, flags);
5083 + mutex_lock(&bcm->mutex);
5084 + spin_lock_irqsave(&bcm->irq_lock, flags);
5085 if (data->frag.disabled) {
5086 bcm->ieee->fts = MAX_FRAG_THRESHOLD;
5087 err = 0;
5088 @@ -403,7 +406,8 @@ static int bcm43xx_wx_set_frag(struct ne
5089 err = 0;
5090 }
5091 }
5092 - bcm43xx_unlock_irqsafe(bcm, flags);
5093 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
5094 + mutex_unlock(&bcm->mutex);
5095
5096 return err;
5097 }
5098 @@ -414,13 +418,12 @@ static int bcm43xx_wx_get_frag(struct ne
5099 char *extra)
5100 {
5101 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
5102 - unsigned long flags;
5103
5104 - bcm43xx_lock_irqsafe(bcm, flags);
5105 + mutex_lock(&bcm->mutex);
5106 data->frag.value = bcm->ieee->fts;
5107 data->frag.fixed = 0;
5108 data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD);
5109 - bcm43xx_unlock_irqsafe(bcm, flags);
5110 + mutex_unlock(&bcm->mutex);
5111
5112 return 0;
5113 }
5114 @@ -442,7 +445,8 @@ static int bcm43xx_wx_set_xmitpower(stru
5115 return -EOPNOTSUPP;
5116 }
5117
5118 - bcm43xx_lock_irqsafe(bcm, flags);
5119 + mutex_lock(&bcm->mutex);
5120 + spin_lock_irqsave(&bcm->irq_lock, flags);
5121 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
5122 goto out_unlock;
5123 radio = bcm43xx_current_radio(bcm);
5124 @@ -466,7 +470,8 @@ static int bcm43xx_wx_set_xmitpower(stru
5125 err = 0;
5126
5127 out_unlock:
5128 - bcm43xx_unlock_irqsafe(bcm, flags);
5129 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
5130 + mutex_unlock(&bcm->mutex);
5131
5132 return err;
5133 }
5134 @@ -478,10 +483,9 @@ static int bcm43xx_wx_get_xmitpower(stru
5135 {
5136 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
5137 struct bcm43xx_radioinfo *radio;
5138 - unsigned long flags;
5139 int err = -ENODEV;
5140
5141 - bcm43xx_lock_irqsafe(bcm, flags);
5142 + mutex_lock(&bcm->mutex);
5143 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
5144 goto out_unlock;
5145 radio = bcm43xx_current_radio(bcm);
5146 @@ -493,7 +497,7 @@ static int bcm43xx_wx_get_xmitpower(stru
5147
5148 err = 0;
5149 out_unlock:
5150 - bcm43xx_unlock_irqsafe(bcm, flags);
5151 + mutex_unlock(&bcm->mutex);
5152
5153 return err;
5154 }
5155 @@ -580,7 +584,8 @@ static int bcm43xx_wx_set_interfmode(str
5156 return -EINVAL;
5157 }
5158
5159 - bcm43xx_lock_irqsafe(bcm, flags);
5160 + mutex_lock(&bcm->mutex);
5161 + spin_lock_irqsave(&bcm->irq_lock, flags);
5162 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
5163 err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
5164 if (err) {
5165 @@ -595,7 +600,8 @@ static int bcm43xx_wx_set_interfmode(str
5166 } else
5167 bcm43xx_current_radio(bcm)->interfmode = mode;
5168 }
5169 - bcm43xx_unlock_irqsafe(bcm, flags);
5170 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
5171 + mutex_unlock(&bcm->mutex);
5172
5173 return err;
5174 }
5175 @@ -606,12 +612,11 @@ static int bcm43xx_wx_get_interfmode(str
5176 char *extra)
5177 {
5178 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
5179 - unsigned long flags;
5180 int mode;
5181
5182 - bcm43xx_lock_irqsafe(bcm, flags);
5183 + mutex_lock(&bcm->mutex);
5184 mode = bcm43xx_current_radio(bcm)->interfmode;
5185 - bcm43xx_unlock_irqsafe(bcm, flags);
5186 + mutex_unlock(&bcm->mutex);
5187
5188 switch (mode) {
5189 case BCM43xx_RADIO_INTERFMODE_NONE:
5190 @@ -641,9 +646,11 @@ static int bcm43xx_wx_set_shortpreamble(
5191 int on;
5192
5193 on = *((int *)extra);
5194 - bcm43xx_lock_irqsafe(bcm, flags);
5195 + mutex_lock(&bcm->mutex);
5196 + spin_lock_irqsave(&bcm->irq_lock, flags);
5197 bcm->short_preamble = !!on;
5198 - bcm43xx_unlock_irqsafe(bcm, flags);
5199 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
5200 + mutex_unlock(&bcm->mutex);
5201
5202 return 0;
5203 }
5204 @@ -654,12 +661,11 @@ static int bcm43xx_wx_get_shortpreamble(
5205 char *extra)
5206 {
5207 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
5208 - unsigned long flags;
5209 int on;
5210
5211 - bcm43xx_lock_irqsafe(bcm, flags);
5212 + mutex_lock(&bcm->mutex);
5213 on = bcm->short_preamble;
5214 - bcm43xx_unlock_irqsafe(bcm, flags);
5215 + mutex_unlock(&bcm->mutex);
5216
5217 if (on)
5218 strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING);
5219 @@ -681,11 +687,13 @@ static int bcm43xx_wx_set_swencryption(s
5220
5221 on = *((int *)extra);
5222
5223 - bcm43xx_lock_irqsafe(bcm, flags);
5224 + mutex_lock(&bcm->mutex);
5225 + spin_lock_irqsave(&bcm->irq_lock, flags);
5226 bcm->ieee->host_encrypt = !!on;
5227 bcm->ieee->host_decrypt = !!on;
5228 bcm->ieee->host_build_iv = !on;
5229 - bcm43xx_unlock_irqsafe(bcm, flags);
5230 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
5231 + mutex_unlock(&bcm->mutex);
5232
5233 return 0;
5234 }
5235 @@ -696,12 +704,11 @@ static int bcm43xx_wx_get_swencryption(s
5236 char *extra)
5237 {
5238 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
5239 - unsigned long flags;
5240 int on;
5241
5242 - bcm43xx_lock_irqsafe(bcm, flags);
5243 + mutex_lock(&bcm->mutex);
5244 on = bcm->ieee->host_encrypt;
5245 - bcm43xx_unlock_irqsafe(bcm, flags);
5246 + mutex_unlock(&bcm->mutex);
5247
5248 if (on)
5249 strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING);
5250 @@ -764,11 +771,13 @@ static int bcm43xx_wx_sprom_read(struct
5251 if (!sprom)
5252 goto out;
5253
5254 - bcm43xx_lock_irqsafe(bcm, flags);
5255 + mutex_lock(&bcm->mutex);
5256 + spin_lock_irqsave(&bcm->irq_lock, flags);
5257 err = -ENODEV;
5258 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
5259 err = bcm43xx_sprom_read(bcm, sprom);
5260 - bcm43xx_unlock_irqsafe(bcm, flags);
5261 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
5262 + mutex_unlock(&bcm->mutex);
5263 if (!err)
5264 data->data.length = sprom2hex(sprom, extra);
5265 kfree(sprom);
5266 @@ -809,11 +818,15 @@ static int bcm43xx_wx_sprom_write(struct
5267 if (err)
5268 goto out_kfree;
5269
5270 - bcm43xx_lock_irqsafe(bcm, flags);
5271 + mutex_lock(&bcm->mutex);
5272 + spin_lock_irqsave(&bcm->irq_lock, flags);
5273 + spin_lock(&bcm->leds_lock);
5274 err = -ENODEV;
5275 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
5276 err = bcm43xx_sprom_write(bcm, sprom);
5277 - bcm43xx_unlock_irqsafe(bcm, flags);
5278 + spin_unlock(&bcm->leds_lock);
5279 + spin_unlock_irqrestore(&bcm->irq_lock, flags);
5280 + mutex_unlock(&bcm->mutex);
5281 out_kfree:
5282 kfree(sprom);
5283 out:
5284 diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
5285 index aa79282..4b971a9 100644
5286 --- a/drivers/net/wireless/zd1211rw/zd_chip.c
5287 +++ b/drivers/net/wireless/zd1211rw/zd_chip.c
5288 @@ -717,7 +717,7 @@ static int zd1211b_hw_reset_phy(struct z
5289 { CR21, 0x0e }, { CR22, 0x23 }, { CR23, 0x90 },
5290 { CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 },
5291 { CR27, 0x10 }, { CR28, 0x7f }, { CR29, 0x80 },
5292 - { CR30, 0x49 }, /* jointly decoder, no ASIC */
5293 + { CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */
5294 { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 },
5295 { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 },
5296 { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },
5297 diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
5298 index ba9a583..bd43106 100644
5299 --- a/drivers/rtc/rtc-pcf8563.c
5300 +++ b/drivers/rtc/rtc-pcf8563.c
5301 @@ -95,7 +95,7 @@ static int pcf8563_get_datetime(struct i
5302 tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
5303 tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
5304 tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR])
5305 - + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 100 : 0);
5306 + + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 0 : 100);
5307
5308 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
5309 "mday=%d, mon=%d, year=%d, wday=%d\n",
5310 @@ -135,7 +135,7 @@ static int pcf8563_set_datetime(struct i
5311
5312 /* year and century */
5313 buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100);
5314 - if (tm->tm_year / 100)
5315 + if (tm->tm_year < 100)
5316 buf[PCF8563_REG_MO] |= PCF8563_MO_C;
5317
5318 buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
5319 diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
5320 index fa38a41..39ace4c 100644
5321 --- a/drivers/scsi/sata_mv.c
5322 +++ b/drivers/scsi/sata_mv.c
5323 @@ -463,6 +463,7 @@ static const struct ata_port_operations
5324
5325 .qc_prep = mv_qc_prep_iie,
5326 .qc_issue = mv_qc_issue,
5327 + .data_xfer = ata_mmio_data_xfer,
5328
5329 .eng_timeout = mv_eng_timeout,
5330
5331 diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
5332 index 30299c6..fed484d 100644
5333 --- a/drivers/usb/gadget/ether.c
5334 +++ b/drivers/usb/gadget/ether.c
5335 @@ -262,7 +262,7 @@ #ifdef CONFIG_USB_GADGET_MUSBHSFC
5336 #define DEV_CONFIG_CDC
5337 #endif
5338
5339 -#ifdef CONFIG_USB_GADGET_MUSBHDRC
5340 +#ifdef CONFIG_USB_GADGET_MUSB_HDRC
5341 #define DEV_CONFIG_CDC
5342 #endif
5343
5344 @@ -2564,7 +2564,7 @@ static struct usb_gadget_driver eth_driv
5345
5346 .function = (char *) driver_desc,
5347 .bind = eth_bind,
5348 - .unbind = __exit_p(eth_unbind),
5349 + .unbind = eth_unbind,
5350
5351 .setup = eth_setup,
5352 .disconnect = eth_disconnect,
5353 diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
5354 index 17961e3..93ffcdd 100644
5355 --- a/drivers/video/fbmem.c
5356 +++ b/drivers/video/fbmem.c
5357 @@ -554,7 +554,8 @@ static int fbmem_read_proc(char *buf, ch
5358 int clen;
5359
5360 clen = 0;
5361 - for (fi = registered_fb; fi < &registered_fb[FB_MAX] && len < 4000; fi++)
5362 + for (fi = registered_fb; fi < &registered_fb[FB_MAX] && clen < 4000;
5363 + fi++)
5364 if (*fi)
5365 clen += sprintf(buf + clen, "%d %s\n",
5366 (*fi)->node,
5367 diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
5368 index 4f78f23..c151dcf 100644
5369 --- a/drivers/video/fbsysfs.c
5370 +++ b/drivers/video/fbsysfs.c
5371 @@ -397,6 +397,12 @@ static ssize_t store_bl_curve(struct cla
5372 u8 tmp_curve[FB_BACKLIGHT_LEVELS];
5373 unsigned int i;
5374
5375 + /* Some drivers don't use framebuffer_alloc(), but those also
5376 + * don't have backlights.
5377 + */
5378 + if (!fb_info || !fb_info->bl_dev)
5379 + return -ENODEV;
5380 +
5381 if (count != (FB_BACKLIGHT_LEVELS / 8 * 24))
5382 return -EINVAL;
5383
5384 @@ -430,6 +436,12 @@ static ssize_t show_bl_curve(struct clas
5385 ssize_t len = 0;
5386 unsigned int i;
5387
5388 + /* Some drivers don't use framebuffer_alloc(), but those also
5389 + * don't have backlights.
5390 + */
5391 + if (!fb_info || !fb_info->bl_dev)
5392 + return -ENODEV;
5393 +
5394 mutex_lock(&fb_info->bl_mutex);
5395 for (i = 0; i < FB_BACKLIGHT_LEVELS; i += 8)
5396 len += snprintf(&buf[len], PAGE_SIZE,
5397 diff --git a/fs/buffer.c b/fs/buffer.c
5398 index 71649ef..5b329f0 100644
5399 --- a/fs/buffer.c
5400 +++ b/fs/buffer.c
5401 @@ -838,7 +838,10 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode);
5402 */
5403 int __set_page_dirty_buffers(struct page *page)
5404 {
5405 - struct address_space * const mapping = page->mapping;
5406 + struct address_space * const mapping = page_mapping(page);
5407 +
5408 + if (unlikely(!mapping))
5409 + return !TestSetPageDirty(page);
5410
5411 spin_lock(&mapping->private_lock);
5412 if (page_has_buffers(page)) {
5413 diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
5414 index 42da607..e998a60 100644
5415 --- a/fs/jbd/commit.c
5416 +++ b/fs/jbd/commit.c
5417 @@ -160,6 +160,117 @@ static int journal_write_commit_record(j
5418 return (ret == -EIO);
5419 }
5420
5421 +void journal_do_submit_data(struct buffer_head **wbuf, int bufs)
5422 +{
5423 + int i;
5424 +
5425 + for (i = 0; i < bufs; i++) {
5426 + wbuf[i]->b_end_io = end_buffer_write_sync;
5427 + /* We use-up our safety reference in submit_bh() */
5428 + submit_bh(WRITE, wbuf[i]);
5429 + }
5430 +}
5431 +
5432 +/*
5433 + * Submit all the data buffers to disk
5434 + */
5435 +static void journal_submit_data_buffers(journal_t *journal,
5436 + transaction_t *commit_transaction)
5437 +{
5438 + struct journal_head *jh;
5439 + struct buffer_head *bh;
5440 + int locked;
5441 + int bufs = 0;
5442 + struct buffer_head **wbuf = journal->j_wbuf;
5443 +
5444 + /*
5445 + * Whenever we unlock the journal and sleep, things can get added
5446 + * onto ->t_sync_datalist, so we have to keep looping back to
5447 + * write_out_data until we *know* that the list is empty.
5448 + *
5449 + * Cleanup any flushed data buffers from the data list. Even in
5450 + * abort mode, we want to flush this out as soon as possible.
5451 + */
5452 +write_out_data:
5453 + cond_resched();
5454 + spin_lock(&journal->j_list_lock);
5455 +
5456 + while (commit_transaction->t_sync_datalist) {
5457 + jh = commit_transaction->t_sync_datalist;
5458 + bh = jh2bh(jh);
5459 + locked = 0;
5460 +
5461 + /* Get reference just to make sure buffer does not disappear
5462 + * when we are forced to drop various locks */
5463 + get_bh(bh);
5464 + /* If the buffer is dirty, we need to submit IO and hence
5465 + * we need the buffer lock. We try to lock the buffer without
5466 + * blocking. If we fail, we need to drop j_list_lock and do
5467 + * blocking lock_buffer().
5468 + */
5469 + if (buffer_dirty(bh)) {
5470 + if (test_set_buffer_locked(bh)) {
5471 + BUFFER_TRACE(bh, "needs blocking lock");
5472 + spin_unlock(&journal->j_list_lock);
5473 + /* Write out all data to prevent deadlocks */
5474 + journal_do_submit_data(wbuf, bufs);
5475 + bufs = 0;
5476 + lock_buffer(bh);
5477 + spin_lock(&journal->j_list_lock);
5478 + }
5479 + locked = 1;
5480 + }
5481 + /* We have to get bh_state lock. Again out of order, sigh. */
5482 + if (!inverted_lock(journal, bh)) {
5483 + jbd_lock_bh_state(bh);
5484 + spin_lock(&journal->j_list_lock);
5485 + }
5486 + /* Someone already cleaned up the buffer? */
5487 + if (!buffer_jbd(bh)
5488 + || jh->b_transaction != commit_transaction
5489 + || jh->b_jlist != BJ_SyncData) {
5490 + jbd_unlock_bh_state(bh);
5491 + if (locked)
5492 + unlock_buffer(bh);
5493 + BUFFER_TRACE(bh, "already cleaned up");
5494 + put_bh(bh);
5495 + continue;
5496 + }
5497 + if (locked && test_clear_buffer_dirty(bh)) {
5498 + BUFFER_TRACE(bh, "needs writeout, adding to array");
5499 + wbuf[bufs++] = bh;
5500 + __journal_file_buffer(jh, commit_transaction,
5501 + BJ_Locked);
5502 + jbd_unlock_bh_state(bh);
5503 + if (bufs == journal->j_wbufsize) {
5504 + spin_unlock(&journal->j_list_lock);
5505 + journal_do_submit_data(wbuf, bufs);
5506 + bufs = 0;
5507 + goto write_out_data;
5508 + }
5509 + }
5510 + else {
5511 + BUFFER_TRACE(bh, "writeout complete: unfile");
5512 + __journal_unfile_buffer(jh);
5513 + jbd_unlock_bh_state(bh);
5514 + if (locked)
5515 + unlock_buffer(bh);
5516 + journal_remove_journal_head(bh);
5517 + /* Once for our safety reference, once for
5518 + * journal_remove_journal_head() */
5519 + put_bh(bh);
5520 + put_bh(bh);
5521 + }
5522 +
5523 + if (lock_need_resched(&journal->j_list_lock)) {
5524 + spin_unlock(&journal->j_list_lock);
5525 + goto write_out_data;
5526 + }
5527 + }
5528 + spin_unlock(&journal->j_list_lock);
5529 + journal_do_submit_data(wbuf, bufs);
5530 +}
5531 +
5532 /*
5533 * journal_commit_transaction
5534 *
5535 @@ -313,80 +424,13 @@ #endif
5536 * Now start flushing things to disk, in the order they appear
5537 * on the transaction lists. Data blocks go first.
5538 */
5539 -
5540 err = 0;
5541 - /*
5542 - * Whenever we unlock the journal and sleep, things can get added
5543 - * onto ->t_sync_datalist, so we have to keep looping back to
5544 - * write_out_data until we *know* that the list is empty.
5545 - */
5546 - bufs = 0;
5547 - /*
5548 - * Cleanup any flushed data buffers from the data list. Even in
5549 - * abort mode, we want to flush this out as soon as possible.
5550 - */
5551 -write_out_data:
5552 - cond_resched();
5553 - spin_lock(&journal->j_list_lock);
5554 -
5555 - while (commit_transaction->t_sync_datalist) {
5556 - struct buffer_head *bh;
5557 -
5558 - jh = commit_transaction->t_sync_datalist;
5559 - commit_transaction->t_sync_datalist = jh->b_tnext;
5560 - bh = jh2bh(jh);
5561 - if (buffer_locked(bh)) {
5562 - BUFFER_TRACE(bh, "locked");
5563 - if (!inverted_lock(journal, bh))
5564 - goto write_out_data;
5565 - __journal_temp_unlink_buffer(jh);
5566 - __journal_file_buffer(jh, commit_transaction,
5567 - BJ_Locked);
5568 - jbd_unlock_bh_state(bh);
5569 - if (lock_need_resched(&journal->j_list_lock)) {
5570 - spin_unlock(&journal->j_list_lock);
5571 - goto write_out_data;
5572 - }
5573 - } else {
5574 - if (buffer_dirty(bh)) {
5575 - BUFFER_TRACE(bh, "start journal writeout");
5576 - get_bh(bh);
5577 - wbuf[bufs++] = bh;
5578 - if (bufs == journal->j_wbufsize) {
5579 - jbd_debug(2, "submit %d writes\n",
5580 - bufs);
5581 - spin_unlock(&journal->j_list_lock);
5582 - ll_rw_block(SWRITE, bufs, wbuf);
5583 - journal_brelse_array(wbuf, bufs);
5584 - bufs = 0;
5585 - goto write_out_data;
5586 - }
5587 - } else {
5588 - BUFFER_TRACE(bh, "writeout complete: unfile");
5589 - if (!inverted_lock(journal, bh))
5590 - goto write_out_data;
5591 - __journal_unfile_buffer(jh);
5592 - jbd_unlock_bh_state(bh);
5593 - journal_remove_journal_head(bh);
5594 - put_bh(bh);
5595 - if (lock_need_resched(&journal->j_list_lock)) {
5596 - spin_unlock(&journal->j_list_lock);
5597 - goto write_out_data;
5598 - }
5599 - }
5600 - }
5601 - }
5602 -
5603 - if (bufs) {
5604 - spin_unlock(&journal->j_list_lock);
5605 - ll_rw_block(SWRITE, bufs, wbuf);
5606 - journal_brelse_array(wbuf, bufs);
5607 - spin_lock(&journal->j_list_lock);
5608 - }
5609 + journal_submit_data_buffers(journal, commit_transaction);
5610
5611 /*
5612 * Wait for all previously submitted IO to complete.
5613 */
5614 + spin_lock(&journal->j_list_lock);
5615 while (commit_transaction->t_locked_list) {
5616 struct buffer_head *bh;
5617
5618 diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
5619 index cf37866..5bb3e17 100644
5620 --- a/fs/sysfs/file.c
5621 +++ b/fs/sysfs/file.c
5622 @@ -483,11 +483,6 @@ int sysfs_update_file(struct kobject * k
5623 (victim->d_parent->d_inode == dir->d_inode)) {
5624 victim->d_inode->i_mtime = CURRENT_TIME;
5625 fsnotify_modify(victim);
5626 -
5627 - /**
5628 - * Drop reference from initial sysfs_get_dentry().
5629 - */
5630 - dput(victim);
5631 res = 0;
5632 } else
5633 d_drop(victim);
5634 diff --git a/include/Kbuild b/include/Kbuild
5635 index cb25348..2d03f99 100644
5636 --- a/include/Kbuild
5637 +++ b/include/Kbuild
5638 @@ -1,2 +1,9 @@
5639 -header-y += asm-generic/ linux/ scsi/ sound/ mtd/ rdma/ video/
5640 -header-y += asm-$(ARCH)/
5641 +header-y += asm-generic/
5642 +header-y += linux/
5643 +header-y += scsi/
5644 +header-y += sound/
5645 +header-y += mtd/
5646 +header-y += rdma/
5647 +header-y += video/
5648 +
5649 +header-y += asm-$(ARCH)/
5650 diff --git a/include/asm-alpha/Kbuild b/include/asm-alpha/Kbuild
5651 index 2b06b3b..b7c8f18 100644
5652 --- a/include/asm-alpha/Kbuild
5653 +++ b/include/asm-alpha/Kbuild
5654 @@ -1,5 +1,11 @@
5655 include include/asm-generic/Kbuild.asm
5656
5657 -unifdef-y += console.h fpu.h sysinfo.h compiler.h
5658 +header-y += gentrap.h
5659 +header-y += regdef.h
5660 +header-y += pal.h
5661 +header-y += reg.h
5662
5663 -header-y += gentrap.h regdef.h pal.h reg.h
5664 +unifdef-y += console.h
5665 +unifdef-y += fpu.h
5666 +unifdef-y += sysinfo.h
5667 +unifdef-y += compiler.h
5668 diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h
5669 index ae7baa6..17f0c65 100644
5670 --- a/include/asm-arm/elf.h
5671 +++ b/include/asm-arm/elf.h
5672 @@ -8,9 +8,6 @@ #define __ASMARM_ELF_H
5673
5674 #include <asm/ptrace.h>
5675 #include <asm/user.h>
5676 -#ifdef __KERNEL
5677 -#include <asm/procinfo.h>
5678 -#endif
5679
5680 typedef unsigned long elf_greg_t;
5681 typedef unsigned long elf_freg_t[3];
5682 @@ -32,11 +29,6 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
5683 typedef struct user_fp elf_fpregset_t;
5684
5685 /*
5686 - * This is used to ensure we don't load something for the wrong architecture.
5687 - */